Naturally, you need to share your amazing Gameduino screenshots with the world at the highest possible quality.
No problem - the hardware has a built-in screenshot system. To use it, add a line like this in your code:
Serial.begin(1000000); GD.screenshot(0);
here is the whole sketch:
#include <SPI.h>
#include <GD.h>
#define RED RGB(255,0,0)
#define GREEN RGB(0,255,0)
void setup()
{
int i;
GD.begin();
GD.ascii();
GD.putstr(20, 0, "Screenshot");
GD.wr16(RAM_PAL + (8 * 127), RED); // char 127: 0=red, 3=green
GD.wr16(RAM_PAL + (8 * 127) + 6, GREEN);
static PROGMEM prog_uchar box[] = {
0xff, 0xff,
0xc0, 0x03,
0xc0, 0x03,
0xc0, 0x03,
0xc0, 0x03,
0xc0, 0x03,
0xc0, 0x03,
0xff, 0xff };
GD.copy(RAM_CHR + (16 * 127), box, sizeof(box));
for (i = 0; i < 64; i++) {
GD.wr(64 * i + i, 127); // diagonal boxes
char msg[20];
sprintf(msg, "Line %d", i);
GD.putstr(i + 2, i, msg);
GD.wr(64 * i + 49, 127); // boxes on right
}
Serial.begin(1000000);
long started = millis();
GD.screenshot(0);
}
void loop()
{
}
This will dump an image of the current screen to the host computer. Meanwhile on the host, have this Python script running on the Arduino's serial connection, as described in Arduino and Python:
#!/usr/bin/env python
import sys
import struct
import serial
import Image
def main():
speed = 1000000
im = Image.new("RGB", (400,300))
pix = im.load()
print "listening for screenshot on", sys.argv[1]
ser = serial.Serial(sys.argv[1], speed)
while True:
s = ser.read(1)
chk = ord(s)
if chk != 0xa5:
sys.stdout.write(s)
else:
(frame,) = struct.unpack("<H", ser.read(2))
filename = "screenshot%05d.png" % frame
for yi in range(300):
(y,) = struct.unpack("H", ser.read(2))
x = 0
while x < 400:
(v,) = struct.unpack("H", ser.read(2))
if v & 0x8000:
for i in range(v & 0x7fff):
pix[x, y] = 0;
x += 1
else:
r = (v >> 10) & 31
g = (v >> 5) & 31
b = v & 31
pix[x, y] = (r * 8, g * 8, b * 8)
x += 1
im.save(filename)
print "captured screenshot to", filename
if __name__ == "__main__":
main()
Launch your sketch, then run the script to collect the image from the serial line, e.g. /dev/ttyUSB0:
$ python screenshot.py /dev/ttyUSB0 listening for screenshot on /dev/ttyUSB0 captured screenshot to screenshot00000.png
the file screenshot00000.png will contain the 400x300 image from the Gameduino screen. Dumping a screenshot over USB takes about 3 seconds. You can create movies one frame at a time by giving incrementing numbers to GD.screenshot().
How does this all work? The Gameduino has a one-line RAM that captures the pixels sent to the video stream. Using the SCREENSHOT_Y register and SCREENSHOT RAM, the Arduino reads these pixels and sends them over the serial line. This is what GD.screenshot() does. A small script on the host computer reconstructs the screen image and saves it.