|
@@ -0,0 +1,207 @@
|
|
|
+import struct
|
|
|
+
|
|
|
+ascii_glyphs = [
|
|
|
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x00,
|
|
|
+0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x7f, 0x36, 0x7f, 0x36, 0x36, 0x00,
|
|
|
+0x0c, 0x3f, 0x68, 0x3e, 0x0b, 0x7e, 0x18, 0x00, 0x60, 0x66, 0x0c, 0x18, 0x30, 0x66, 0x06, 0x00,
|
|
|
+0x38, 0x6c, 0x6c, 0x38, 0x6d, 0x66, 0x3b, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
+0x0c, 0x18, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00,
|
|
|
+0x00, 0x18, 0x7e, 0x3c, 0x7e, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00,
|
|
|
+0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
|
|
|
+0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00,
|
|
|
+0x3c, 0x66, 0x6e, 0x7e, 0x76, 0x66, 0x3c, 0x00, 0x18, 0x38, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00,
|
|
|
+0x3c, 0x66, 0x06, 0x0c, 0x18, 0x30, 0x7e, 0x00, 0x3c, 0x66, 0x06, 0x1c, 0x06, 0x66, 0x3c, 0x00,
|
|
|
+0x0c, 0x1c, 0x3c, 0x6c, 0x7e, 0x0c, 0x0c, 0x00, 0x7e, 0x60, 0x7c, 0x06, 0x06, 0x66, 0x3c, 0x00,
|
|
|
+0x1c, 0x30, 0x60, 0x7c, 0x66, 0x66, 0x3c, 0x00, 0x7e, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x00,
|
|
|
+0x3c, 0x66, 0x66, 0x3c, 0x66, 0x66, 0x3c, 0x00, 0x3c, 0x66, 0x66, 0x3e, 0x06, 0x0c, 0x38, 0x00,
|
|
|
+0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x30,
|
|
|
+0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x7e, 0x00, 0x00, 0x00,
|
|
|
+0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x3c, 0x66, 0x0c, 0x18, 0x18, 0x00, 0x18, 0x00,
|
|
|
+
|
|
|
+0x3c, 0x66, 0x6e, 0x6a, 0x6e, 0x60, 0x3c, 0x00, 0x3c, 0x66, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x00,
|
|
|
+0x7c, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x7c, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x60, 0x66, 0x3c, 0x00,
|
|
|
+0x78, 0x6c, 0x66, 0x66, 0x66, 0x6c, 0x78, 0x00, 0x7e, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x7e, 0x00,
|
|
|
+0x7e, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x60, 0x00, 0x3c, 0x66, 0x60, 0x6e, 0x66, 0x66, 0x3c, 0x00,
|
|
|
+0x66, 0x66, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00,
|
|
|
+0x3e, 0x0c, 0x0c, 0x0c, 0x0c, 0x6c, 0x38, 0x00, 0x66, 0x6c, 0x78, 0x70, 0x78, 0x6c, 0x66, 0x00,
|
|
|
+0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7e, 0x00, 0x63, 0x77, 0x7f, 0x6b, 0x6b, 0x63, 0x63, 0x00,
|
|
|
+0x66, 0x66, 0x76, 0x7e, 0x6e, 0x66, 0x66, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
|
|
|
+0x7c, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x6a, 0x6c, 0x36, 0x00,
|
|
|
+0x7c, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0x00, 0x3c, 0x66, 0x60, 0x3c, 0x06, 0x66, 0x3c, 0x00,
|
|
|
+0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
|
|
|
+0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x63, 0x63, 0x6b, 0x6b, 0x7f, 0x77, 0x63, 0x00,
|
|
|
+0x66, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0x66, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x00,
|
|
|
+0x7e, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x7e, 0x00, 0x7c, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7c, 0x00,
|
|
|
+0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x3e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x3e, 0x00,
|
|
|
+0x18, 0x3c, 0x66, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
|
|
|
+
|
|
|
+0x1c, 0x36, 0x30, 0x7c, 0x30, 0x30, 0x7e, 0x00, 0x00, 0x00, 0x3c, 0x06, 0x3e, 0x66, 0x3e, 0x00,
|
|
|
+0x60, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x66, 0x3c, 0x00,
|
|
|
+0x06, 0x06, 0x3e, 0x66, 0x66, 0x66, 0x3e, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
|
|
|
+0x1c, 0x30, 0x30, 0x7c, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x3e, 0x66, 0x66, 0x3e, 0x06, 0x3c,
|
|
|
+0x60, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x00, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00,
|
|
|
+0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x70, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0x00,
|
|
|
+0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x36, 0x7f, 0x6b, 0x6b, 0x63, 0x00,
|
|
|
+0x00, 0x00, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x00,
|
|
|
+0x00, 0x00, 0x7c, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x00, 0x00, 0x3e, 0x66, 0x66, 0x3e, 0x06, 0x07,
|
|
|
+0x00, 0x00, 0x6c, 0x76, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0x3e, 0x60, 0x3c, 0x06, 0x7c, 0x00,
|
|
|
+0x30, 0x30, 0x7c, 0x30, 0x30, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x00,
|
|
|
+0x00, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x63, 0x6b, 0x6b, 0x7f, 0x36, 0x00,
|
|
|
+0x00, 0x00, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x3e, 0x06, 0x3c,
|
|
|
+0x00, 0x00, 0x7e, 0x0c, 0x18, 0x30, 0x7e, 0x00, 0x0c, 0x18, 0x18, 0x70, 0x18, 0x18, 0x0c, 0x00,
|
|
|
+0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, 0x30, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x30, 0x00,
|
|
|
+0x31, 0x6b, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
|
+]
|
|
|
+
|
|
|
+from gameduino.registers import *
|
|
|
+
|
|
|
+# BaseGameduino is the common base for the Gameduino objects in remote and sim
|
|
|
+
|
|
|
+class BaseGameduino(object):
|
|
|
+
|
|
|
+ def coldstart(self):
|
|
|
+ self.wr(J1_RESET, 1)
|
|
|
+ self.fill(RAM_PIC, 0, 10 * 1024)
|
|
|
+ for i in range(512):
|
|
|
+ self.sprite(i, 400, 400, 0, 0, 0)
|
|
|
+ self.wr16(SPR_DISABLE, 0)
|
|
|
+ self.wr16(SPR_PAGE, 0)
|
|
|
+ self.wr16(JK_MODE, 0)
|
|
|
+ self.wr16(SCROLL_X, 0)
|
|
|
+ self.wr16(SCROLL_Y, 0)
|
|
|
+ self.wr16(BG_COLOR, 0)
|
|
|
+ self.wr16(SAMPLE_L, 0)
|
|
|
+ self.wr16(SAMPLE_R, 0)
|
|
|
+ self.wr16(SCREENSHOT_Y, 0)
|
|
|
+
|
|
|
+ def dump(self, a, l):
|
|
|
+ """ Dump ``l`` bytes memory starting at address ``a`` """
|
|
|
+ for i in range(0, l, 16):
|
|
|
+ d16 = self.rdstr(a + i, 16)
|
|
|
+ print "%04x %s" % (a + i, " ".join(["%02x" % ord(c) for c in d16]))
|
|
|
+
|
|
|
+ def wr(self, a, v):
|
|
|
+ """ Write a single byte ``v`` to address ``a``. """
|
|
|
+ self.wrstr(a, chr(v))
|
|
|
+
|
|
|
+ def fill(self, a, v, c):
|
|
|
+ """ Fill ``c`` bytes of memory at address ``a`` with value ``v`` """
|
|
|
+ self.wrstr(a, chr(v) * c)
|
|
|
+
|
|
|
+ def putstr(self, x, y, v):
|
|
|
+ """ Write string ``v`` at screen position (x,y) """
|
|
|
+ a = y * 64 + x
|
|
|
+ self.wrstr(a, v)
|
|
|
+
|
|
|
+ def rd16(self, a):
|
|
|
+ return struct.unpack("<H", self.rdstr(a, 2))[0]
|
|
|
+
|
|
|
+ def rd32(self, a):
|
|
|
+ return struct.unpack("<L", self.rdstr(a, 4))[0]
|
|
|
+
|
|
|
+ def wr16(self, a, v):
|
|
|
+ """ Write 16-bit value ``v`` at to address ``a`` """
|
|
|
+ self.wrstr(a, struct.pack("<H", v))
|
|
|
+
|
|
|
+ def wr32(self, a, v):
|
|
|
+ """ Write 32-bit value ``v`` at to address ``a`` """
|
|
|
+ self.wrstr(a, struct.pack("<L", v))
|
|
|
+
|
|
|
+ def setpal(self, pal, rgb):
|
|
|
+ self.wr16(RAM_PAL + (pal << 1), rgb);
|
|
|
+
|
|
|
+ def ascii(self):
|
|
|
+ stretch = [
|
|
|
+ 0x00, 0x03, 0x0c, 0x0f,
|
|
|
+ 0x30, 0x33, 0x3c, 0x3f,
|
|
|
+ 0xc0, 0xc3, 0xcc, 0xcf,
|
|
|
+ 0xf0, 0xf3, 0xfc, 0xff ]
|
|
|
+ gstr = ""
|
|
|
+ for i in range(768):
|
|
|
+ b = ascii_glyphs[i]
|
|
|
+ h = stretch[b >> 4]
|
|
|
+ l = stretch[b & 0xf]
|
|
|
+ gstr += chr(h)
|
|
|
+ gstr += chr(l)
|
|
|
+ self.wrstr(0x1000 + (16 * ord(' ')), gstr)
|
|
|
+ for i in range(0x20, 0x80):
|
|
|
+ self.setpal(4 * i + 0, TRANSPARENT);
|
|
|
+ self.setpal(4 * i + 3, RGB(255,255,255));
|
|
|
+ self.fill(RAM_PIC, ord(' '), 4096);
|
|
|
+
|
|
|
+ def voice(self, v, wave, freq, lamp, ramp = None):
|
|
|
+ """
|
|
|
+ Set the state of a voice.
|
|
|
+
|
|
|
+ :param v: voice number 0-63
|
|
|
+ :type v: int
|
|
|
+ :param wave: wave type, 0 for sine 1 for noise
|
|
|
+ :type wave: int
|
|
|
+ :param freq: frequency control, in quarter-hertz
|
|
|
+ :type freq: int
|
|
|
+ :param lamp: left amplitude 0-255
|
|
|
+ :type lamp: int
|
|
|
+ :param ramp: right amplitude 0-255, defaults to same ``lamp``
|
|
|
+ :type ramp: int
|
|
|
+ """
|
|
|
+ if ramp is None:
|
|
|
+ ramp = lamp
|
|
|
+ self.wr32(VOICES + (4 * v), freq | (wave << 15) | (lamp << 16) | (ramp << 24))
|
|
|
+
|
|
|
+ def silence(self):
|
|
|
+ """ Switch all voices off """
|
|
|
+ for i in range(64):
|
|
|
+ self.voice(i, 0, 4 * 440, 0, 0)
|
|
|
+
|
|
|
+ def copy(self, a, v):
|
|
|
+ self.wrstr(a, v)
|
|
|
+
|
|
|
+ def microcode(self, src):
|
|
|
+ """
|
|
|
+ Halt coprocessor, load microprogram, restart coprocessor
|
|
|
+
|
|
|
+ :param src: the microprogram, as a string, expressed
|
|
|
+ :type src: string
|
|
|
+
|
|
|
+ The string is loaded into the Gameduino's microprogram area,
|
|
|
+ and can be up to 256 bytes. For example, to load the
|
|
|
+ :ref:`splitscreen` microprogram::
|
|
|
+
|
|
|
+ splitscreen_code = open("splitscreen.binle", "b").read()
|
|
|
+ gd.microcode(splitscreen_code)
|
|
|
+
|
|
|
+ """
|
|
|
+
|
|
|
+ self.wr(J1_RESET, 1)
|
|
|
+ self.copy(J1_CODE, src)
|
|
|
+ self.wr(J1_RESET, 0)
|
|
|
+
|
|
|
+ def sprite(self, spr, x, y, image, palette, rot, jk = 0):
|
|
|
+ """
|
|
|
+ Set the state of a hardware sprite
|
|
|
+
|
|
|
+ :param spr: sprite number 0-511
|
|
|
+ :param x: x coordinate
|
|
|
+ :param y: y coordinate
|
|
|
+ :param image: sprite source image 0-63
|
|
|
+ :param palette: sprite palette select, 0-15, see below
|
|
|
+ :param rot: sprite rotate control 0-7, see :ref:`rotate`
|
|
|
+ :param jk: collision class control, 0-1
|
|
|
+
|
|
|
+ Palette select controls the number of colors used for the sprite, the source palette, and which data bits
|
|
|
+ to use as source.
|
|
|
+
|
|
|
+ """
|
|
|
+
|
|
|
+ self.wr32(RAM_SPR + (4 * spr),
|
|
|
+ (x & 511) | ((rot & 7) << 9) | ((palette & 15) << 12) | ((y & 511) << 16) | ((image & 63) << 25) | ((jk & 1) << 31))
|
|
|
+
|
|
|
+ def im(self):
|
|
|
+ """
|
|
|
+ Return the current screen as a 400x300 RGB PIL Image::
|
|
|
+
|
|
|
+ >>> import gameduino.sim
|
|
|
+ >>> gd = gameduino.sim.Gameduino()
|
|
|
+ >>> gd.im().save("screenshot.png")
|
|
|
+ """
|
|
|
+ return self._im()
|