xx: move lights at offset x BC000002 80000040 03860010 09000008 03880010 09000000 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15: setcombine FC121824 FF33FFFF 16: setcombine FC127E24 FFFFF3F9 17: setcombine FCFFFFFF FFFE793C 18: setothermode_low B900031D 00552078 19: setothermode_low B900031D 00553078 xx.ss.tt: tilesync, settile, settilesize E8000000 00000000 F5100000 00000000 F2000000 00000000 1A.ss.tt c16 32x32 image 1B.ss.tt c16 32x64 image 1C.ss.tt c16 64x32 image 1D.ss.tt ia16 32x32 image 1E.ss.tt ia16 32x64 image 1F.ss.tt ia16 64x32 image 2C.ss.tt c16 32x32 image to tmem 0x100 (256 color palette) 2000 clamp s 1000 mirror s 0F00 mask s 0020 clamp t 0010 mirror t 000F mask t xx.ii.tt: settextureimage, loadsync, settile, tilesync, loadblock FD100000 05000000 E8000000 00000000 F5100000 00000000 E6000000 00000000 F3000000 00000000 20.ii.tt c16 32x32 image 21.ii.tt c16 32x64 image 22.ii.tt c16 64x32 image 23.ii.tt ia16 32x32 image 24.ii.tt ia16 32x64 image 25.ii.tt ia16 64x32 image FF00 image index; multiply by 0x800 for actual 00F0 tile# 000F tmem offset for settile 26: texture: on, s = -1, t = -1 BB000001 FFFFFFFF 27: texture: off, s = 1, t = 1 BB000000 00010001 28.xxxx.ss.nn: loadvertices 04000000 04000000 FFFF0000 vertex offset, little-endian; multiply by 0x10 for actual 00003F00 byte size of data loaded 0000003F offset in vertex bank to start at 29.xxxx: tri; reversed if 800DC604 nonzero BF000000 00000000 1F00 vtx1 E003 vtx2 007C vtx3 2A: endDL B8000000 00000000 2B.xxxx: DLbranch within generated file 06000000 07000000 FFFF DW offset to display list target, little-endian; << 3 for actual 2D: cullDL BE000000 00000140 2E: setcombine FC127E24 FFFFF3F9 2F: setothermode_low B900031D 005049D8 30.xxxxxx: quad; reversed if 800DC604 nonzero B5000000 00000000 1F0000 vtx1 E00300 vtx2 007C00 vtx3 00800F vtx4 31: NOP 32: NOP cmd.xxxx: loadvertices 04000000 04000000 33.xxxx 1 vertex 34.xxxx 2 vertices 34.xxxx 3 vertices 35.xxxx 4 vertices 36.xxxx 5 vertices 37.xxxx 6 vertices 38.xxxx 7 vertices 39.xxxx 8 vertices 3A.xxxx 9 vertices 3B.xxxx 10 vertices 3C.xxxx 11 vertices 3D.xxxx 12 vertices 3E.xxxx 13 vertices 3F.xxxx 14 vertices 40.xxxx 15 vertices 41.xxxx 16 vertices 42.xxxx 17 vertices 43.xxxx 18 vertices 44.xxxx 19 vertices 45.xxxx 20 vertices 46.xxxx 21 vertices 47.xxxx 22 vertices 48.xxxx 23 vertices 49.xxxx 24 vertices 4A.xxxx 25 vertices 4B.xxxx 26 vertices 4C.xxxx 27 vertices 4D.xxxx 28 vertices 4E.xxxx 29 vertices 4F.xxxx 30 vertices 50.xxxx 31 vertices 51.xxxx 32 vertices 52.xxxx 33 vertices FFFF vertex offset, little-endian; multiply by 0x10 for actual 53: setcombine FCFFFFFF FFFCF279 54: setothermode_low B900031D 00442D58 55: setothermode_low B900031D 00404DD8 56: setgeometrymode: cull back B7000000 00002000 57: cleargeometrymode: cull back B6000000 00002000 58.xxxx.yyyy: tri2; reversed if 800DC604 nonzero B1000000 00000000 1F000000 tri1, vtx1 E0030000 tri1, vtx2 007C0000 tri1, vtx3 00001F00 tri2, vtx1 0000E003 tri2, vtx2 0000007C tri2, vtx3 FF: end command list +_+ def geo2dl(data, flip=False): from array import array out = array("L") sizes = {0:(0,32,32,0), 1:(0,32,64,0), 2:(0,64,32,0), 3:(3,32,32,0), 4:(3,32,64,0), 5:(3,64,32,0), 0x12:(0,32,32,0x100)} geo = iter(data) c = next(geo) while c != 0xFF: if c in range(0, 0x15): c *= 0x18 out.append(0xBC000002) out.append(0x80000040) out.append(0x03860010) out.append(0x09000008 | c) out.append(0x03880010) out.append(0x09000000 | c) elif c == 0x15: out.append(0xFC121824) out.append(0xFF33FFFF) elif c == 0x16: out.append(0xFC127E24) out.append(0xFFFFF3F9) elif c == 0x17: out.append(0xFCFFFFFF) out.append(0xFFFE793C) elif c == 0x18: out.append(0xB900031D) out.append(0x00552078) elif c == 0x19: out.append(0xB900031D) out.append(0x00553078) elif c in range(0x1A, 0x20) or c == 0x2C: e = sizes.get(c-0x1A) s_mask = next(geo) s_flags = s_mask >> 4 s_mask &= 0xF t_mask = next(geo) t_flags = t_mask >> 4 t_mask &= 0xF line = (e[2] << 1) + 7 line >>= 3 w = e[1] - 1 h = e[2] - 1 out.append(0xE8000000) out.append(0) out.append(0xF5100000 | (e[0] << 0x15) | (line << 9) | e[3]) out.append((t_mask << 0x12) | (t_flags << 0xE) | (s_mask << 8) | (s_flags << 4)) out.append(0xF2000000) out.append((h << 0xE) | (w << 2)) elif c in range(0x20, 0x26): e = sizes.get(c-0x20) index = next(geo) index |= next(geo) << 8 index <<= 11 tile = next(geo) tmem = tile & 0xF tile >>= 4 tile <<= 0x18 lrs = min((e[1] * e[2]) - 1, 0x7FF) lrt = max((e[2] << 1) >> 3, 1) lrt = (0x7FF + lrt) // max(lrt, 1) out.append(0xFD100000 | (e[0] << 0x15)) out.append(0x05000000 | index) out.append(0xE8000000) out.append(0) out.append(0xF5100000 | (e[0] << 0x15) | tmem) out.append(tile) out.append(0xE6000000) out.append(0) out.append(0xF3000000) out.append(tile | (lrs << 12) | lrt) elif c == 0x26: out.append(0xBB000001) out.append(0xFFFFFFFF) elif c == 0x27: out.append(0xBB000000) out.append(0x00010001) elif c == 0x28: offset = next(geo) offset |= next(geo) << 8 s = next(geo) & 0x3F n = next(geo) & 0x3F s = (s << 10) + (s << 4) - 1 out.append(0x04000000 | (n << 17) | s) out.append(0x04000000 | (offset << 4)) elif c == 0x29: x = next(geo) x |= next(geo) << 8 y = x & 0x1F x >>= 5 v2 = x & 0x1F x >>= 5 z = x & 0x1F if flip: v1, v3 = y, z else: v3, v1 = y, z out.append(0xBF000000) out.append((v3 << 17) | (v2 << 9) | (v1 << 1)) elif c == 0x2A: out.append(0xB8000000) out.append(0) elif c == 0x2B: offset = next(geo) offset |= next(geo) << 8 out.append(0x06000000) out.append(0x07000000 | (offset << 3)) elif c == 0x2D: out.append(0xBE000000) out.append(0x00000140) elif c == 0x2E: out.append(0xFC127E24) out.append(0xFFFFF3F9) elif c == 0x2F: out.append(0xB900031D) out.append(0x005049D8) elif c == 0x30: x = next(geo) x |= next(geo) << 8 x |= next(geo) << 16 v1 = x & 0x1F x >>= 5 v2 = x & 0x1F x >>= 5 v3 = x & 0x1F x >>= 5 v4 = x & 0x1F if flip: ul, ur, ll, lr = v1, v4, v3, v2 else: ul, ur, ll, lr = v4, v1, v2, v3 out.append(0xB5000000) out.append((ul << 25) | (ur << 17) | (ll << 9) | (lr << 1)) elif c == 0x31: pass elif c == 0x32: pass elif c in range(0x33, 0x53): offset = next(geo) offset |= next(geo) << 8 s = c - 0x32 s = (s << 10) + (s << 4) - 1 out.append(0x04000000 | s) out.append(0x04000000 | (offset << 4)) elif c == 0x53: out.append(0xFCFFFFFF) out.append(0xFFFCF279) elif c == 0x54: out.append(0xB900031D) out.append(0x00442D58) elif c == 0x55: out.append(0xB900031D) out.append(0x00404DD8) elif c == 0x56: out.append(0xB7000000) out.append(0x00002000) elif c == 0x57: out.append(0xB6000000) out.append(0x00002000) elif c == 0x58: x = next(geo) x |= next(geo) << 8 v1 = x & 0x1F x >>= 5 v2 = x & 0x1F x >>= 5 v3 = x & 0x1F if flip: t11, t12, t13 = v1, v2, v3 else: t11, t12, t13 = v3, v2, v1 x = next(geo) x |= next(geo) << 8 v1 = x & 0x1F x >>= 5 v2 = x & 0x1F x >>= 5 v3 = x & 0x1F if flip: t21, t22, t23 = v1, v2, v3 else: t21, t22, t23 = v3, v2, v1 out.append(0xB1000000 | (t13 << 17) | (t12 << 9) | (t11 << 1)) out.append((t23 << 17) | (t22 << 9) | (t21 << 1)) else: raise ValueError("0x{:02X} is not a valid command.") c = next(geo) out.byteswap() return out.tobytes()