diff options
| author | LagoLunatic <LagoLunatic@users.noreply.github.com> | 2024-11-01 19:32:15 -0400 |
|---|---|---|
| committer | LagoLunatic <LagoLunatic@users.noreply.github.com> | 2024-11-01 19:32:15 -0400 |
| commit | e9f82ff359b9cffb9770ebab263770e207d6ee79 (patch) | |
| tree | 5a16c138f43b90035e307f9e08fdcbeab38eff7a /tools | |
| parent | a16d8cee02c7cd1410215f389ae69ac86eeb5e58 (diff) | |
Add custom build rule for material display lists with image addresses in them
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/converters/matDL_dis.py | 419 |
1 files changed, 419 insertions, 0 deletions
diff --git a/tools/converters/matDL_dis.py b/tools/converters/matDL_dis.py new file mode 100644 index 00000000..cd66b48b --- /dev/null +++ b/tools/converters/matDL_dis.py @@ -0,0 +1,419 @@ +from argparse import ArgumentParser +import struct +import os +from enum import Enum + + +class GXBPRegs(Enum): + GX_BP_REG_GENMODE = 0x0 + + GX_BP_REG_DISPCOPYFILTER0 = 0x1 + GX_BP_REG_DISPCOPYFILTER1 = 0x2 + GX_BP_REG_DISPCOPYFILTER2 = 0x3 + GX_BP_REG_DISPCOPYFILTER3 = 0x4 + + GX_BP_REG_INDMTX0A = 0x6 + GX_BP_REG_INDMTX0B = 0x7 + GX_BP_REG_INDMTX0C = 0x8 + GX_BP_REG_INDMTX1A = 0x9 + GX_BP_REG_INDMTX1B = 0xA + GX_BP_REG_INDMTX1C = 0xB + GX_BP_REG_INDMTX2A = 0xC + GX_BP_REG_INDMTX2B = 0xD + GX_BP_REG_INDMTX2C = 0xE + GX_BP_REG_INDIMASK = 0xF + + GX_BP_REG_INDTEVSTAGE0 = 0x10 + GX_BP_REG_INDTEVSTAGE1 = 0x11 + GX_BP_REG_INDTEVSTAGE2 = 0x12 + GX_BP_REG_INDTEVSTAGE3 = 0x13 + GX_BP_REG_INDTEVSTAGE4 = 0x14 + GX_BP_REG_INDTEVSTAGE5 = 0x15 + GX_BP_REG_INDTEVSTAGE6 = 0x16 + GX_BP_REG_INDTEVSTAGE7 = 0x17 + GX_BP_REG_INDTEVSTAGE8 = 0x18 + GX_BP_REG_INDTEVSTAGE9 = 0x19 + GX_BP_REG_INDTEVSTAGE10 = 0x1A + GX_BP_REG_INDTEVSTAGE11 = 0x1B + GX_BP_REG_INDTEVSTAGE12 = 0x1C + GX_BP_REG_INDTEVSTAGE13 = 0x1D + GX_BP_REG_INDTEVSTAGE14 = 0x1E + GX_BP_REG_INDTEVSTAGE15 = 0x1F + + GX_BP_REG_SCISSORTL = 0x20 + GX_BP_REG_SCISSORBR = 0x21 + GX_BP_REG_LINEPTWIDTH = 0x22 + GX_BP_REG_PERF0TRI = 0x23 + GX_BP_REG_PERF0QUAD = 0x24 + + GX_BP_REG_RAS1_SS0 = 0x25 + GX_BP_REG_RAS1_SS1 = 0x26 + GX_BP_REG_RAS1_IREF = 0x27 + GX_BP_REG_RAS1_TREF0 = 0x28 + GX_BP_REG_RAS1_TREF1 = 0x29 + GX_BP_REG_RAS1_TREF2 = 0x2A + GX_BP_REG_RAS1_TREF3 = 0x2B + GX_BP_REG_RAS1_TREF4 = 0x2C + GX_BP_REG_RAS1_TREF5 = 0x2D + GX_BP_REG_RAS1_TREF6 = 0x2E + GX_BP_REG_RAS1_TREF7 = 0x2F + + GX_BP_REG_SU_SSIZE0 = 0x30 + GX_BP_REG_SU_TSIZE0 = 0x31 + GX_BP_REG_SU_SSIZE1 = 0x32 + GX_BP_REG_SU_TSIZE1 = 0x33 + GX_BP_REG_SU_SSIZE2 = 0x34 + GX_BP_REG_SU_TSIZE2 = 0x35 + GX_BP_REG_SU_SSIZE3 = 0x36 + GX_BP_REG_SU_TSIZE3 = 0x37 + GX_BP_REG_SU_SSIZE4 = 0x38 + GX_BP_REG_SU_TSIZE4 = 0x39 + GX_BP_REG_SU_SSIZE5 = 0x3A + GX_BP_REG_SU_TSIZE5 = 0x3B + GX_BP_REG_SU_SSIZE6 = 0x3C + GX_BP_REG_SU_TSIZE6 = 0x3D + GX_BP_REG_SU_SSIZE7 = 0x3E + GX_BP_REG_SU_TSIZE7 = 0x3F + + GX_BP_REG_ZMODE = 0x40 + GX_BP_REG_BLENDMODE = 0x41 + GX_BP_REG_DSTALPHA = 0x42 + GX_BP_REG_ZCONTROL = 0x43 + GX_BP_REG_FIELDMASK = 0x44 + GX_BP_REG_DRAWDONE = 0x45 + GX_BP_REG_PETOKEN = 0x47 + GX_BP_REG_PETOKENINT = 0x48 + + GX_BP_REG_TEXCOPYSRCXY = 0x49 + GX_BP_REG_TEXCOPYSRCWH = 0x4A + GX_BP_REG_TEXCOPYDST = 0x4B + GX_BP_REG_DISPCOPYSTRIDE = 0x4D + GX_BP_REG_DISPCOPYSCALEY = 0x4E + GX_BP_REG_COPYCLEARAR = 0x4F + GX_BP_REG_COPYCLEARGB = 0x50 + GX_BP_REG_COPYCLEARZ = 0x51 + GX_BP_REG_COPYFILTER0 = 0x53 + GX_BP_REG_COPYFILTER1 = 0x54 + + GX_BP_REG_BOUNDINGBOX0 = 0x55 + GX_BP_REG_BOUNDINGBOX1 = 0x56 + + GX_BP_REG_SCISSOROFFSET = 0x59 + + GX_BP_REG_TMEMPRELOADADDR = 0x60 + GX_BP_REG_TMEMPRELOADEVEN = 0x61 + GX_BP_REG_TMEMPRELOADODD = 0x62 + GX_BP_REG_TMEMPRELOADMODE = 0x63 + GX_BP_REG_TMEMTLUTSRC = 0x64 + GX_BP_REG_TMEMTLUTDST = 0x65 + GX_BP_REG_TMEMTEXINVALIDATE = 0x66 + + GX_BP_REG_PERF1 = 0x67 + GX_BP_REG_FIELDMODE = 0x68 + + GX_BP_REG_SETMODE0_TEX0 = 0x80 + GX_BP_REG_SETMODE0_TEX1 = 0x81 + GX_BP_REG_SETMODE0_TEX2 = 0x82 + GX_BP_REG_SETMODE0_TEX3 = 0x83 + GX_BP_REG_SETMODE1_TEX0 = 0x84 + GX_BP_REG_SETMODE1_TEX1 = 0x85 + GX_BP_REG_SETMODE1_TEX2 = 0x86 + GX_BP_REG_SETMODE1_TEX3 = 0x87 + + GX_BP_REG_SETIMAGE0_TEX0 = 0x88 + GX_BP_REG_SETIMAGE0_TEX1 = 0x89 + GX_BP_REG_SETIMAGE0_TEX2 = 0x8A + GX_BP_REG_SETIMAGE0_TEX3 = 0x8B + GX_BP_REG_SETIMAGE1_TEX0 = 0x8C + GX_BP_REG_SETIMAGE1_TEX1 = 0x8D + GX_BP_REG_SETIMAGE1_TEX2 = 0x8E + GX_BP_REG_SETIMAGE1_TEX3 = 0x8F + GX_BP_REG_SETIMAGE2_TEX0 = 0x90 + GX_BP_REG_SETIMAGE2_TEX1 = 0x91 + GX_BP_REG_SETIMAGE2_TEX2 = 0x92 + GX_BP_REG_SETIMAGE2_TEX3 = 0x93 + GX_BP_REG_SETIMAGE3_TEX0 = 0x94 + GX_BP_REG_SETIMAGE3_TEX1 = 0x95 + GX_BP_REG_SETIMAGE3_TEX2 = 0x96 + GX_BP_REG_SETIMAGE3_TEX3 = 0x97 + + GX_BP_REG_SETTLUT_TEX0 = 0x98 + GX_BP_REG_SETTLUT_TEX1 = 0x99 + GX_BP_REG_SETTLUT_TEX2 = 0x9A + GX_BP_REG_SETTLUT_TEX3 = 0x9B + + GX_BP_REG_SETMODE0_TEX4 = 0xA0 + GX_BP_REG_SETMODE0_TEX5 = 0xA1 + GX_BP_REG_SETMODE0_TEX6 = 0xA2 + GX_BP_REG_SETMODE0_TEX7 = 0xA3 + GX_BP_REG_SETMODE1_TEX4 = 0xA4 + GX_BP_REG_SETMODE1_TEX5 = 0xA5 + GX_BP_REG_SETMODE1_TEX6 = 0xA6 + GX_BP_REG_SETMODE1_TEX7 = 0xA7 + + GX_BP_REG_SETIMAGE0_TEX4 = 0xA8 + GX_BP_REG_SETIMAGE0_TEX5 = 0xA9 + GX_BP_REG_SETIMAGE0_TEX6 = 0xAA + GX_BP_REG_SETIMAGE0_TEX7 = 0xAB + GX_BP_REG_SETIMAGE1_TEX4 = 0xAC + GX_BP_REG_SETIMAGE1_TEX5 = 0xAD + GX_BP_REG_SETIMAGE1_TEX6 = 0xAE + GX_BP_REG_SETIMAGE1_TEX7 = 0xAF + GX_BP_REG_SETIMAGE2_TEX4 = 0xB0 + GX_BP_REG_SETIMAGE2_TEX5 = 0xB1 + GX_BP_REG_SETIMAGE2_TEX6 = 0xB2 + GX_BP_REG_SETIMAGE2_TEX7 = 0xB3 + GX_BP_REG_SETIMAGE3_TEX4 = 0xB4 + GX_BP_REG_SETIMAGE3_TEX5 = 0xB5 + GX_BP_REG_SETIMAGE3_TEX6 = 0xB6 + GX_BP_REG_SETIMAGE3_TEX7 = 0xB7 + + GX_BP_REG_SETTLUT_TEX4 = 0xB8 + GX_BP_REG_SETTLUT_TEX5 = 0xB9 + GX_BP_REG_SETTLUT_TEX6 = 0xBA + GX_BP_REG_SETTLUT_TEX7 = 0xBB + + GX_BP_REG_TEVCOLORCOMBINER0 = 0xC0 + GX_BP_REG_TEVALPHACOMBINER0 = 0xC1 + GX_BP_REG_TEVCOLORCOMBINER1 = 0xC2 + GX_BP_REG_TEVALPHACOMBINER1 = 0xC3 + GX_BP_REG_TEVCOLORCOMBINER2 = 0xC4 + GX_BP_REG_TEVALPHACOMBINER2 = 0xC5 + GX_BP_REG_TEVCOLORCOMBINER3 = 0xC6 + GX_BP_REG_TEVALPHACOMBINER3 = 0xC7 + GX_BP_REG_TEVCOLORCOMBINER4 = 0xC8 + GX_BP_REG_TEVALPHACOMBINER4 = 0xC9 + GX_BP_REG_TEVCOLORCOMBINER5 = 0xCA + GX_BP_REG_TEVALPHACOMBINER5 = 0xCB + GX_BP_REG_TEVCOLORCOMBINER6 = 0xCC + GX_BP_REG_TEVALPHACOMBINER6 = 0xCD + GX_BP_REG_TEVCOLORCOMBINER7 = 0xCE + GX_BP_REG_TEVALPHACOMBINER7 = 0xCF + GX_BP_REG_TEVCOLORCOMBINER8 = 0xD0 + GX_BP_REG_TEVALPHACOMBINER8 = 0xD1 + GX_BP_REG_TEVCOLORCOMBINER9 = 0xD2 + GX_BP_REG_TEVALPHACOMBINER9 = 0xD3 + GX_BP_REG_TEVCOLORCOMBINER10 = 0xD4 + GX_BP_REG_TEVALPHACOMBINER10 = 0xD5 + GX_BP_REG_TEVCOLORCOMBINER11 = 0xD6 + GX_BP_REG_TEVALPHACOMBINER11 = 0xD7 + GX_BP_REG_TEVCOLORCOMBINER12 = 0xD8 + GX_BP_REG_TEVALPHACOMBINER12 = 0xD9 + GX_BP_REG_TEVCOLORCOMBINER13 = 0xDA + GX_BP_REG_TEVALPHACOMBINER13 = 0xDB + GX_BP_REG_TEVCOLORCOMBINER14 = 0xDC + GX_BP_REG_TEVALPHACOMBINER14 = 0xDD + GX_BP_REG_TEVCOLORCOMBINER15 = 0xDE + GX_BP_REG_TEVALPHACOMBINER15 = 0xDF + + GX_BP_REG_TEVREG0LO = 0xE0 + GX_BP_REG_TEVREG0HI = 0xE1 + GX_BP_REG_TEVREG1LO = 0xE2 + GX_BP_REG_TEVREG1HI = 0xE3 + GX_BP_REG_TEVREG2LO = 0xE4 + GX_BP_REG_TEVREG2HI = 0xE5 + GX_BP_REG_TEVREG3LO = 0xE6 + GX_BP_REG_TEVREG3HI = 0xE7 + + GX_BP_REG_FOGRANGE = 0xE8 + GX_BP_REG_FOGRANGEK0 = 0xE9 + GX_BP_REG_FOGRANGEK1 = 0xEA + GX_BP_REG_FOGRANGEK2 = 0xEB + GX_BP_REG_FOGRANGEK3 = 0xEC + GX_BP_REG_FOGRANGEK4 = 0xED + GX_BP_REG_FOGPARAM0 = 0xEE + GX_BP_REG_FOGPARAM1 = 0xEF + GX_BP_REG_FOGPARAM2 = 0xF0 + GX_BP_REG_FOGPARAM3 = 0xF1 + GX_BP_REG_FOGCOLOR = 0xF2 + + GX_BP_REG_ALPHACOMPARE = 0xF3 + GX_BP_REG_ZTEXTURE0 = 0xF4 + GX_BP_REG_ZTEXTURE1 = 0xF5 + + GX_BP_REG_TEVKSEL0 = 0xF6 + GX_BP_REG_TEVKSEL1 = 0xF7 + GX_BP_REG_TEVKSEL2 = 0xF8 + GX_BP_REG_TEVKSEL3 = 0xF9 + GX_BP_REG_TEVKSEL4 = 0xFA + GX_BP_REG_TEVKSEL5 = 0xFB + GX_BP_REG_TEVKSEL6 = 0xFC + GX_BP_REG_TEVKSEL7 = 0xFD + + GX_BP_REG_SSMASK = 0xFE + + +class GXXFRegs(Enum): + GX_XF_REG_ERROR = 0x1000 + GX_XF_REG_DIAGNOSTICS = 0x1001 + GX_XF_REG_STATE0 = 0x1002 + GX_XF_REG_STATE1 = 0x1003 + GX_XF_REG_CLOCK = 0x1004 + GX_XF_REG_CLIPDISABLE = 0x1005 + GX_XF_REG_PERF0 = 0x1006 + GX_XF_REG_PERF1 = 0x1007 + GX_XF_REG_INVERTEXSPEC = 0x1008 + GX_XF_REG_NUMCOLORS = 0x1009 + GX_XF_REG_AMBIENT0 = 0x100A + GX_XF_REG_AMBIENT1 = 0x100B + GX_XF_REG_MATERIAL0 = 0x100C + GX_XF_REG_MATERIAL1 = 0x100D + GX_XF_REG_COLOR0CNTRL = 0x100E + GX_XF_REG_COLOR1CNTRL = 0x100F + GX_XF_REG_ALPHA0CNTRL = 0x1010 + GX_XF_REG_ALPHA1CNTRL = 0x1011 + GX_XF_REG_DUALTEXTRAN = 0x1012 + GX_XF_REG_MATRIXINDEX0 = 0x1018 + GX_XF_REG_MATRIXINDEX1 = 0x1019 + GX_XF_REG_SCALEX = 0x101A + GX_XF_REG_SCALEY = 0x101B + GX_XF_REG_SCALEZ = 0x101C + GX_XF_REG_OFFSETX = 0x101D + GX_XF_REG_OFFSETY = 0x101E + GX_XF_REG_OFFSETZ = 0x101F + GX_XF_REG_PROJECTIONA = 0x1020 + GX_XF_REG_PROJECTIONB = 0x1021 + GX_XF_REG_PROJECTIONC = 0x1022 + GX_XF_REG_PROJECTIOND = 0x1023 + GX_XF_REG_PROJECTIONE = 0x1024 + GX_XF_REG_PROJECTIONF = 0x1025 + GX_XF_REG_PROJECTORTHO = 0x1026 + GX_XF_REG_NUMTEX = 0x103F + GX_XF_REG_TEX0 = 0x1040 + GX_XF_REG_TEX1 = 0x1041 + GX_XF_REG_TEX2 = 0x1042 + GX_XF_REG_TEX3 = 0x1043 + GX_XF_REG_TEX4 = 0x1044 + GX_XF_REG_TEX5 = 0x1045 + GX_XF_REG_TEX6 = 0x1046 + GX_XF_REG_TEX7 = 0x1047 + GX_XF_REG_DUALTEX0 = 0x1050 + GX_XF_REG_DUALTEX1 = 0x1051 + GX_XF_REG_DUALTEX2 = 0x1052 + GX_XF_REG_DUALTEX3 = 0x1053 + GX_XF_REG_DUALTEX4 = 0x1054 + GX_XF_REG_DUALTEX5 = 0x1055 + GX_XF_REG_DUALTEX6 = 0x1056 + GX_XF_REG_DUALTEX7 = 0x1057 + + +class GXCPRegs(Enum): + GX_CP_REG_MTXIDXA = 0x30 + GX_CP_REG_MTXIDXB = 0x40 + GX_CP_REG_VCD_LO = 0x50 + GX_CP_REG_VCD_HI = 0x60 + GX_CP_REG_VAT_GRP0 = 0x70 + GX_CP_REG_VAT_GRP1 = 0x80 + GX_CP_REG_VAT_GRP2 = 0x90 + GX_CP_REG_ARRAYBASE = 0xA0 + GX_CP_REG_ARRAYSTRIDE = 0xB0 + + +def read_u8(binary_file): + chunk = binary_file.read(1) + if len(chunk) < 1: + return None + return struct.unpack(">B", chunk)[0] + +def read_u16(binary_file): + chunk = binary_file.read(2) + if len(chunk) < 1: + return None + return struct.unpack(">H", chunk)[0] + + +def convert_binary_to_matDL_c_source(src_path, dest_path, symbol_name): + # Load data + macro_name = os.path.splitext(os.path.basename(src_path))[0] + with open(src_path, "rb") as binary_file, open(dest_path, "w") as c_file: + c_file.write("#ifndef LOAD_BP_REG\n") + c_file.write("#define U32_AS_U8(v) ((u8)((v) >> 24)), ((u8)((v) >> 16)), ((u8)((v) >> 8)), ((u8)((v) >> 0))\n") + c_file.write("#define U24_AS_U8(v) ((u8)((v) >> 16)), ((u8)((v) >> 8)), ((u8)((v) >> 0))\n") + c_file.write("#define U16_AS_U8(v) ((u8)((v) >> 8)), ((u8)((v) >> 0))\n") + c_file.write("#define IMAGE_ADDR(addr) (u32)(addr) >> 5\n") + c_file.write("#define LOAD_BP_REG(reg, value) GX_CMD_LOAD_BP_REG, reg, U24_AS_U8(value)\n") + c_file.write("#define LOAD_XF_REG(reg, num_args, ...) GX_CMD_LOAD_XF_REG, U16_AS_U8(num_args-1), U16_AS_U8(reg), __VA_ARGS__\n") + c_file.write("#define LOAD_CP_REG(reg, value) GX_CMD_LOAD_CP_REG, reg, U32_AS_U8(value)\n") + c_file.write("#endif\n\n") + + def write_macro_line(line): + line_with_escape = line + (" "*(99-len(line))) + "\\\n" + c_file.write(line_with_escape) + + write_macro_line(f"#define {macro_name}(TEX_NAME)") + write_macro_line(f"u8 {symbol_name}[] ALIGN_DECL(32) = {{") + + while True: + print(binary_file.tell()) + command_type = read_u8(binary_file) + if command_type is None: + break + + line_elements = [] + def add_byte_to_line(byte): + line_elements.append(f"0x{byte:02X}") + def add_string_to_line(string): + line_elements.append(string) + + if command_type == 0x61: + # BP Command + register = GXBPRegs(read_u8(binary_file)) + value = read_u8(binary_file) << 16 | read_u8(binary_file) << 8 | read_u8(binary_file) << 0 + if register == GXBPRegs.GX_BP_REG_SETIMAGE3_TEX0: + value_string = f"IMAGE_ADDR(TEX_NAME)" + elif register == GXBPRegs.GX_BP_REG_SU_SSIZE0: + value_string = f"TEX_NAME ## __width" + elif register == GXBPRegs.GX_BP_REG_SU_TSIZE0: + value_string = f"TEX_NAME ## __height" + else: + value_string = f"0x{value:06X}" + add_string_to_line(f"LOAD_BP_REG({register.name}, {value_string})") + + elif command_type == 0x10: + # XF Command + num_args = 1 + read_u16(binary_file) + assert num_args <= 0x10 + register = GXXFRegs(read_u16(binary_file)) + arg_bytes = [] + for i in range(4 * num_args): + arg_bytes.append(read_u8(binary_file)) + args_string = ", ".join(f"0x{byte:02X}" for byte in arg_bytes) + add_string_to_line(f"LOAD_XF_REG({register.name}, {num_args}, {args_string})") + + elif command_type == 0x08: + # CP Command + register = GXCPRegs(read_u8(binary_file)) + value = read_u8(binary_file) << 24 | read_u8(binary_file) << 16 | read_u8(binary_file) << 8 | read_u8(binary_file) << 0 + add_string_to_line(f"LOAD_CP_REG({register.name}, 0x{value:08X})") + + elif command_type == 0x00: + add_byte_to_line(command_type) + + while len(line_elements) < 0x10: + byte = read_u8(binary_file) + assert byte == 0x00 + add_byte_to_line(byte) + + else: + raise Exception(f"Unknown command type: {command_type:02X}") + + print(line_elements) + write_macro_line(" " + ", ".join(line_elements) + ",") + + c_file.write("};\n") + + +def main(): + parser = ArgumentParser( + description="Converts a binary file containing a material display list to a macro for defining an array of u8 type" + ) + parser.add_argument("src_path", type=str, help="Binary source file path") + parser.add_argument("dest_path", type=str, help="Destination C include file path") + parser.add_argument("--symbol", type=str, help="Symbol name") + + args = parser.parse_args() + convert_binary_to_matDL_c_source(args.src_path, args.dest_path, args.symbol) + + +if __name__ == "__main__": + main() |
