Files
ac-decomp/tools/converters/gfxdis.py
T
2025-08-01 17:33:13 -04:00

1931 lines
58 KiB
Python

from argparse import ArgumentParser
from dataclasses import dataclass
def SEGMENT_ADDR(num, off): return (((num) << 24) + (off))
SHOW_CODE = False
SOFTSPRITE_MTX_SEG = 0x07
ANIME_1_TXT_SEG = 0x08
ANIME_2_TXT_SEG = 0x09
ANIME_3_TXT_SEG = 0x0A
ANIME_4_TXT_SEG = 0x0B
ANIME_5_TXT_SEG = 0x0C
ANIME_6_TXT_SEG = 0x0D
anime_1_txt = SEGMENT_ADDR(ANIME_1_TXT_SEG, 0)
anime_1_model = SEGMENT_ADDR(ANIME_1_TXT_SEG, 0)
anime_2_txt = SEGMENT_ADDR(ANIME_2_TXT_SEG, 0)
anime_2_model = SEGMENT_ADDR(ANIME_2_TXT_SEG, 0)
anime_3_txt = SEGMENT_ADDR(ANIME_3_TXT_SEG, 0)
anime_3_model = SEGMENT_ADDR(ANIME_3_TXT_SEG, 0)
anime_4_txt = SEGMENT_ADDR(ANIME_4_TXT_SEG, 0)
anime_4_model = SEGMENT_ADDR(ANIME_4_TXT_SEG, 0)
anime_5_txt = SEGMENT_ADDR(ANIME_5_TXT_SEG, 0)
anime_5_model = SEGMENT_ADDR(ANIME_5_TXT_SEG, 0)
anime_6_txt = SEGMENT_ADDR(ANIME_6_TXT_SEG, 0)
anime_6_model = SEGMENT_ADDR(ANIME_6_TXT_SEG, 0)
def strarg_animesegment(v):
return {
anime_1_txt: "anime_1_txt",
anime_2_txt: "anime_2_txt",
anime_3_txt: "anime_3_txt",
anime_4_txt: "anime_4_txt",
anime_5_txt: "anime_5_txt",
anime_6_txt: "anime_6_mdl"
}.get(v, str(v))
symbol_stack: list[str] = []
def symbol_lookup(addr):
global symbol_stack
if (addr == 0):
if len(symbol_stack) > 0:
return symbol_stack.pop(0)
else:
return "UnknownSymbol"
else:
seg = f"{strarg_animesegment(addr & 0xff000000)}"
if (addr & 0x00ffffff):
if seg == "anime_6_mdl":
seg = f"&anime_6_mdl[{(addr & 0x00ffffff) // 0x40}]"
else:
seg += f" + 0x{addr & 0x00ffffff:X}"
return seg
GFX_INSTR_SIZE = 8
GFX_SYMBOL = None
BOWTIE_VAL = 0
DATA_LOWER = 0
DATA_UPPER = 1
DATA_SPREAD = 2
DL = DATA_LOWER
DU = DATA_UPPER
DS = DATA_SPREAD
G_ACMUX_COMBINED = 0
G_ACMUX_TEXEL0 = 1
G_ACMUX_TEXEL1 = 2
G_ACMUX_PRIMITIVE = 3
G_ACMUX_SHADE = 4
G_ACMUX_ENVIRONMENT = 5
G_ACMUX_LOD_FRACTION = 0
G_ACMUX_PRIM_LOD_FRAC = 6
G_ACMUX_1 = 6
G_ACMUX_0 = 7
G_MTX_MODELVIEW = 0x00 # /* matrix types */
G_MTX_PROJECTION = 0x04
G_MTX_MUL = 0x00 # /* concat or load */
G_MTX_LOAD = 0x02
G_MTX_NOPUSH = 0x00 # /* push or not */
G_MTX_PUSH = 0x01
G_IM_FMT_RGBA = 0
G_IM_FMT_YUV = 1
G_IM_FMT_CI = 2
G_IM_FMT_IA = 3
G_IM_FMT_I = 4
G_IM_SIZ_4b = 0
G_IM_SIZ_8b = 1
G_IM_SIZ_16b = 2
G_IM_SIZ_32b = 3
G_IM_SIZ_DD = 5
G_CCMUX_COMBINED = 0
G_CCMUX_TEXEL0 = 1
G_CCMUX_TEXEL1 = 2
G_CCMUX_PRIMITIVE = 3
G_CCMUX_SHADE = 4
G_CCMUX_ENVIRONMENT = 5
G_CCMUX_CENTER = 6
G_CCMUX_SCALE = 6
G_CCMUX_COMBINED_ALPHA = 7
G_CCMUX_TEXEL0_ALPHA = 8
G_CCMUX_TEXEL1_ALPHA = 9
G_CCMUX_PRIMITIVE_ALPHA = 10
G_CCMUX_SHADE_ALPHA = 11
G_CCMUX_ENV_ALPHA = 12
G_CCMUX_LOD_FRACTION = 13
G_CCMUX_PRIM_LOD_FRAC = 14
G_CCMUX_NOISE = 7
G_CCMUX_K4 = 7
G_CCMUX_K5 = 15
G_CCMUX_1 = 6
G_CCMUX_0 = 31
G_TX_LOADTILE = 7
G_TX_RENDERTILE = 0
G_ON = 1
G_OFF = 0
G_TX_NOMIRROR = 0
G_TX_WRAP = 0
G_TX_MIRROR = 0x1
G_TX_CLAMP = 0x2
G_TX_NOMASK = 0
G_TX_NOLOD = 0
G_TEXTURE_ENABLE = (0 << 0)
G_CULL_FRONT = (1 << 9)
G_CULL_BACK = (1 << 10)
G_SHADING_SMOOTH = (1 << 21)
G_ZBUFFER = (1 << 0)
G_SHADE = (1 << 2)
G_CULL_BOTH = (G_CULL_FRONT | G_CULL_BACK)
G_FOG = (1 << 16)
G_LIGHTING = (1 << 17)
G_TEXTURE_GEN = (1 << 18)
G_TEXTURE_GEN_LINEAR = (1 << 19)
G_LOD = (1 << 20)
G_CLIPPING = 0x00800000
G_LIGHTING_POSITIONAL = 0x400000
G_DECAL_LEQUAL = 0x00
G_DECAL_GEQUAL = 0x10
G_DECAL_EQUAL = 0x20
G_DECAL_ALWAYS = 0x30
G_DECAL_SPECIAL = 0x40
G_DECAL_ALL = (G_DECAL_ALWAYS | G_DECAL_SPECIAL)
G_LIGHTING_GC = 0x00800000
G_MDSFT_ALPHADITHER = 4
G_MDSFT_RGBDITHER = 6
G_MDSFT_COMBKEY = 8
G_MDSFT_TEXTCONV = 9
G_MDSFT_TEXTFILT = 12
G_MDSFT_TEXTLUT = 14
G_MDSFT_TEXTLOD = 16
G_MDSFT_TEXTDETAIL = 17
G_MDSFT_TEXTPERSP = 19
G_MDSFT_CYCLETYPE = 20
G_MDSFT_PIPELINE = 23
G_MDSIZ_ALPHADITHER = 2
G_MDSIZ_RGBDITHER = 2
G_MDSIZ_COMBKEY = 1
G_MDSIZ_TEXTCONV = 3
G_MDSIZ_TEXTFILT = 2
G_MDSIZ_TEXTLUT = 2
G_MDSIZ_TEXTLOD = 1
G_MDSIZ_TEXTDETAIL = 2
G_MDSIZ_TEXTPERSP = 1
G_MDSIZ_CYCLETYPE = 2
G_MDSIZ_PIPELINE = 1
G_MDSFT_ALPHACOMPARE = 0
G_MDSFT_ZSRCSEL = 2
G_MDSFT_RENDERMODE = 3
G_MDSIZ_ALPHACOMPARE = 2
G_MDSIZ_ZSRCSEL = 1
G_MDSIZ_RENDERMODE = 29
G_NOOP = 0x00
G_RDPHALF_2 = 0xf1
G_SETOTHERMODE_H = 0xe3
G_SETOTHERMODE_L = 0xe2
G_RDPHALF_1 = 0xe1
G_SPNOOP = 0xe0
G_ENDDL = 0xdf
G_DL = 0xde
G_LOAD_UCODE = 0xdd
G_MOVEMEM = 0xdc
G_MOVEWORD = 0xdb
G_MTX = 0xda
G_GEOMETRYMODE = 0xd9
G_POPMTX = 0xd8
G_TEXTURE = 0xd7
G_DMA_IO = 0xd6
G_SPECIAL_1 = 0xd5
G_SPECIAL_2 = 0xd4
G_SPECIAL_3 = 0xd3
G_VTX = 0x01
G_MODIFYVTX = 0x02
G_CULLDL = 0x03
G_BRANCH_Z = 0x04
G_TRI1 = 0x05
G_TRI2 = 0x06
G_QUAD = 0x07
G_LINE3D = 0x08
G_SETCIMG = 0xff
G_SETZIMG = 0xfe
G_SETTIMG = 0xfd
G_SETCOMBINE = 0xfc
G_SETENVCOLOR = 0xfb
G_SETPRIMCOLOR = 0xfa
G_SETBLENDCOLOR = 0xf9
G_SETFOGCOLOR = 0xf8
G_SETFILLCOLOR = 0xf7
G_FILLRECT = 0xf6
G_SETTILE = 0xf5
G_LOADTILE = 0xf4
G_LOADBLOCK = 0xf3
G_SETTILESIZE = 0xf2
G_LOADTLUT = 0xf0
G_RDPSETOTHERMODE = 0xef
G_SETPRIMDEPTH = 0xee
G_SETSCISSOR = 0xed
G_SETCONVERT = 0xec
G_SETKEYR = 0xeb
G_SETKEYGB = 0xea
G_RDPFULLSYNC = 0xe9
G_RDPTILESYNC = 0xe8
G_RDPPIPESYNC = 0xe7
G_RDPLOADSYNC = 0xe6
G_TEXRECTFLIP = 0xe5
G_TEXRECT = 0xe4
G_TRIN = 0x09
G_TRIN_INDEPEND = 0x0A
G_SETTEXEDGEALPHA = 0xCE
G_SETCOMBINE_NOTEV = 0xCF
G_SETCOMBINE_TEV = 0xD0
G_SETTILE_DOLPHIN = 0xD2
G_DOLPHIN_TLUT_DEFAULT_MODE = 15
GX_CLAMP = 0
GX_REPEAT = 1
GX_MIRROR = 2
GX_MAX_TEXWRAPMODE = 3
AA_EN = 0x8
Z_CMP = 0x10
Z_UPD = 0x20
IM_RD = 0x40
CLR_ON_CVG = 0x80
CVG_DST_CLAMP = 0
CVG_DST_WRAP = 0x100
CVG_DST_FULL = 0x200
CVG_DST_SAVE = 0x300
ZMODE_OPA = 0
ZMODE_INTER = 0x400
ZMODE_XLU = 0x800
ZMODE_DEC = 0xc00
CVG_X_ALPHA = 0x1000
ALPHA_CVG_SEL = 0x2000
FORCE_BL = 0x4000
TEX_EDGE = 0x0000 # /* used to be 0x8000 */
G_BL_CLR_IN = 0
G_BL_CLR_MEM = 1
G_BL_CLR_BL = 2
G_BL_CLR_FOG = 3
G_BL_1MA = 0
G_BL_A_MEM = 1
G_BL_A_IN = 0
G_BL_A_FOG = 1
G_BL_A_SHADE = 2
G_BL_1 = 2
G_BL_0 = 3
G_AC_NONE = (0 << G_MDSFT_ALPHACOMPARE)
G_AC_THRESHOLD = (1 << G_MDSFT_ALPHACOMPARE)
G_AC_DITHER = (3 << G_MDSFT_ALPHACOMPARE)
G_TT_NONE = (0 << G_MDSFT_TEXTLUT)
G_TT_RGBA16 = (2 << G_MDSFT_TEXTLUT)
G_TT_IA16 = (3 << G_MDSFT_TEXTLUT)
G_AD_PATTERN = (0 << G_MDSFT_ALPHADITHER)
G_AD_NOTPATTERN = (1 << G_MDSFT_ALPHADITHER)
G_AD_NOISE = (2 << G_MDSFT_ALPHADITHER)
G_AD_DISABLE = (3 << G_MDSFT_ALPHADITHER)
G_CD_MAGICSQ = (0 << G_MDSFT_RGBDITHER)
G_CD_BAYER = (1 << G_MDSFT_RGBDITHER)
G_CD_NOISE = (2 << G_MDSFT_RGBDITHER)
G_CD_DISABLE = (3 << G_MDSFT_RGBDITHER)
G_CD_ENABLE = G_CD_NOISE
G_CK_NONE = (0 << G_MDSFT_COMBKEY)
G_CK_KEY = (1 << G_MDSFT_COMBKEY)
G_TC_CONV = (0 << G_MDSFT_TEXTCONV)
G_TC_FILTCONV = (5 << G_MDSFT_TEXTCONV)
G_TC_FILT = (6 << G_MDSFT_TEXTCONV)
G_TF_POINT = (0 << G_MDSFT_TEXTFILT)
G_TF_AVERAGE = (3 << G_MDSFT_TEXTFILT)
G_TF_BILERP = (2 << G_MDSFT_TEXTFILT)
G_TL_TILE = (0 << G_MDSFT_TEXTLOD)
G_TL_LOD = (1 << G_MDSFT_TEXTLOD)
G_TD_CLAMP = (0 << G_MDSFT_TEXTDETAIL)
G_TD_SHARPEN = (1 << G_MDSFT_TEXTDETAIL)
G_TD_DETAIL = (2 << G_MDSFT_TEXTDETAIL)
G_TP_NONE = (0 << G_MDSFT_TEXTPERSP)
G_TP_PERSP = (1 << G_MDSFT_TEXTPERSP)
G_CYC_1CYCLE = (0 << G_MDSFT_CYCLETYPE)
G_CYC_2CYCLE = (1 << G_MDSFT_CYCLETYPE)
G_CYC_COPY = (2 << G_MDSFT_CYCLETYPE)
G_CYC_FILL = (3 << G_MDSFT_CYCLETYPE)
G_PM_1PRIMITIVE = (1 << G_MDSFT_PIPELINE)
G_PM_NPRIMITIVE = (0 << G_MDSFT_PIPELINE)
G_TLUT_DOLPHIN = 2
def GBL_c1(m1a, m1b, m2a, m2b): return (m1a) << 30 | (
m1b) << 26 | (m2a) << 22 | (m2b) << 18
def GBL_c2(m1a, m1b, m2a, m2b): return (m1a) << 28 | (
m1b) << 24 | (m2a) << 20 | (m2b) << 16
GBL_c = [None, GBL_c1, GBL_c2]
def RM_AA_ZB_OPA_SURF(clk): return AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | ALPHA_CVG_SEL | GBL_c[clk](
G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
def RM_RA_ZB_OPA_SURF(clk): return AA_EN | Z_CMP | Z_UPD | CVG_DST_CLAMP | ZMODE_OPA | ALPHA_CVG_SEL | GBL_c[clk](
G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
def RM_AA_ZB_XLU_SURF(clk): return AA_EN | Z_CMP | IM_RD | CVG_DST_WRAP | CLR_ON_CVG | FORCE_BL | ZMODE_XLU | GBL_c[clk](
G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
def RM_AA_ZB_OPA_DECAL(clk): return AA_EN | Z_CMP | IM_RD | CVG_DST_WRAP | ALPHA_CVG_SEL | ZMODE_DEC | GBL_c[clk](
G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
def RM_RA_ZB_OPA_DECAL(clk): return AA_EN | Z_CMP | CVG_DST_WRAP | ALPHA_CVG_SEL | ZMODE_DEC | GBL_c[clk](
G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
def RM_AA_ZB_XLU_DECAL(clk): return AA_EN | Z_CMP | IM_RD | CVG_DST_WRAP | CLR_ON_CVG | FORCE_BL | ZMODE_DEC | GBL_c[clk](
G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
def RM_AA_ZB_OPA_INTER(clk): return AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | ALPHA_CVG_SEL | ZMODE_INTER | GBL_c[clk](
G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
def RM_RA_ZB_OPA_INTER(clk): return AA_EN | Z_CMP | Z_UPD | CVG_DST_CLAMP | ALPHA_CVG_SEL | ZMODE_INTER | GBL_c[clk](
G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
def RM_AA_ZB_XLU_INTER(clk): return AA_EN | Z_CMP | IM_RD | CVG_DST_WRAP | CLR_ON_CVG | FORCE_BL | ZMODE_INTER | GBL_c[clk](
G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
def RM_AA_ZB_XLU_LINE(clk): return AA_EN | Z_CMP | IM_RD | CVG_DST_CLAMP | CVG_X_ALPHA | ALPHA_CVG_SEL | FORCE_BL | ZMODE_XLU | GBL_c[clk](
G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
def RM_AA_ZB_DEC_LINE(clk): return AA_EN | Z_CMP | IM_RD | CVG_DST_SAVE | CVG_X_ALPHA | ALPHA_CVG_SEL | FORCE_BL | ZMODE_DEC | GBL_c[clk](
G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
def RM_AA_ZB_TEX_EDGE(clk): return AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | CVG_X_ALPHA | ALPHA_CVG_SEL | ZMODE_OPA | TEX_EDGE | GBL_c[clk](
G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
def RM_AA_ZB_TEX_INTER(clk): return AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | CVG_X_ALPHA | ALPHA_CVG_SEL | ZMODE_INTER | TEX_EDGE | GBL_c[clk](
G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
def RM_AA_ZB_SUB_SURF(clk): return AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_FULL | ZMODE_OPA | ALPHA_CVG_SEL | GBL_c[clk](
G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
def RM_AA_ZB_PCL_SURF(clk): return AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | G_AC_DITHER | GBL_c[clk](
G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
def RM_AA_ZB_OPA_TERR(clk): return AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | ALPHA_CVG_SEL | GBL_c[clk](
G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
def RM_AA_ZB_TEX_TERR(clk): return AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | CVG_X_ALPHA | ALPHA_CVG_SEL | ZMODE_OPA | TEX_EDGE | GBL_c[clk](
G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
def RM_AA_ZB_SUB_TERR(clk): return AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_FULL | ZMODE_OPA | ALPHA_CVG_SEL | GBL_c[clk](
G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
def RM_AA_OPA_SURF(clk): return AA_EN | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | ALPHA_CVG_SEL | GBL_c[clk](
G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
def RM_RA_OPA_SURF(clk): return AA_EN | CVG_DST_CLAMP | ZMODE_OPA | ALPHA_CVG_SEL | GBL_c[clk](
G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
def RM_AA_XLU_SURF(clk): return AA_EN | IM_RD | CVG_DST_WRAP | CLR_ON_CVG | FORCE_BL | ZMODE_OPA | GBL_c[clk](
G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
def RM_AA_XLU_LINE(clk): return AA_EN | IM_RD | CVG_DST_CLAMP | CVG_X_ALPHA | ALPHA_CVG_SEL | FORCE_BL | ZMODE_OPA | GBL_c[clk](
G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
def RM_AA_DEC_LINE(clk): return AA_EN | IM_RD | CVG_DST_FULL | CVG_X_ALPHA | ALPHA_CVG_SEL | FORCE_BL | ZMODE_OPA | GBL_c[clk](
G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
def RM_AA_TEX_EDGE(clk): return AA_EN | IM_RD | CVG_DST_CLAMP | CVG_X_ALPHA | ALPHA_CVG_SEL | ZMODE_OPA | TEX_EDGE | GBL_c[clk](
G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
def RM_AA_SUB_SURF(clk): return AA_EN | IM_RD | CVG_DST_FULL | ZMODE_OPA | ALPHA_CVG_SEL | GBL_c[clk](
G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
def RM_AA_PCL_SURF(clk): return AA_EN | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | G_AC_DITHER | GBL_c[clk](
G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
def RM_AA_OPA_TERR(clk): return AA_EN | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | ALPHA_CVG_SEL | GBL_c[clk](
G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
def RM_AA_TEX_TERR(clk): return AA_EN | IM_RD | CVG_DST_CLAMP | CVG_X_ALPHA | ALPHA_CVG_SEL | ZMODE_OPA | TEX_EDGE | GBL_c[clk](
G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
def RM_AA_SUB_TERR(clk): return AA_EN | IM_RD | CVG_DST_FULL | ZMODE_OPA | ALPHA_CVG_SEL | GBL_c[clk](
G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
def RM_ZB_OPA_SURF(clk): return Z_CMP | Z_UPD | CVG_DST_FULL | ALPHA_CVG_SEL | ZMODE_OPA | GBL_c[clk](
G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
def RM_ZB_XLU_SURF(clk): return Z_CMP | IM_RD | CVG_DST_FULL | FORCE_BL | ZMODE_XLU | GBL_c[clk](
G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
def RM_ZB_OPA_DECAL(clk): return Z_CMP | CVG_DST_FULL | ALPHA_CVG_SEL | ZMODE_DEC | GBL_c[clk](
G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
def RM_ZB_XLU_DECAL(clk): return Z_CMP | IM_RD | CVG_DST_FULL | FORCE_BL | ZMODE_DEC | GBL_c[clk](
G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
def RM_ZB_CLD_SURF(clk): return Z_CMP | IM_RD | CVG_DST_SAVE | FORCE_BL | ZMODE_XLU | GBL_c[clk](
G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
def RM_ZB_OVL_SURF(clk): return Z_CMP | IM_RD | CVG_DST_SAVE | FORCE_BL | ZMODE_DEC | GBL_c[clk](
G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
def RM_ZB_PCL_SURF(clk): return Z_CMP | Z_UPD | CVG_DST_FULL | ZMODE_OPA | G_AC_DITHER | GBL_c[clk](
G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1)
def RM_OPA_SURF(clk): return CVG_DST_CLAMP | FORCE_BL | ZMODE_OPA | GBL_c[clk](
G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1)
def RM_XLU_SURF(clk): return IM_RD | CVG_DST_FULL | FORCE_BL | ZMODE_OPA | GBL_c[clk](
G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
def RM_TEX_EDGE(clk): return CVG_DST_CLAMP | CVG_X_ALPHA | ALPHA_CVG_SEL | FORCE_BL | ZMODE_OPA | TEX_EDGE | AA_EN | GBL_c[clk](
G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1)
def RM_CLD_SURF(clk): return IM_RD | CVG_DST_SAVE | FORCE_BL | ZMODE_OPA | GBL_c[clk](
G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
def RM_PCL_SURF(clk): return CVG_DST_FULL | FORCE_BL | ZMODE_OPA | G_AC_DITHER | GBL_c[clk](
G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1)
def RM_ADD(clk): return IM_RD | CVG_DST_SAVE | FORCE_BL | ZMODE_OPA | GBL_c[clk](
G_BL_CLR_IN, G_BL_A_FOG, G_BL_CLR_MEM, G_BL_1)
def RM_NOOP(clk): return GBL_c[clk](0, 0, 0, 0)
def RM_VISCVG(clk): return IM_RD | FORCE_BL | GBL_c[clk](
G_BL_CLR_IN, G_BL_0, G_BL_CLR_BL, G_BL_A_MEM)
# /* for rendering to an 8-bit framebuffer */
def RM_OPA_CI(clk: int): return CVG_DST_CLAMP | ZMODE_OPA | GBL_c[clk](
G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1)
G_RM_AA_ZB_OPA_SURF = RM_AA_ZB_OPA_SURF(1)
G_RM_AA_ZB_OPA_SURF2 = RM_AA_ZB_OPA_SURF(2)
G_RM_AA_ZB_XLU_SURF = RM_AA_ZB_XLU_SURF(1)
G_RM_AA_ZB_XLU_SURF2 = RM_AA_ZB_XLU_SURF(2)
G_RM_AA_ZB_OPA_DECAL = RM_AA_ZB_OPA_DECAL(1)
G_RM_AA_ZB_OPA_DECAL2 = RM_AA_ZB_OPA_DECAL(2)
G_RM_AA_ZB_XLU_DECAL = RM_AA_ZB_XLU_DECAL(1)
G_RM_AA_ZB_XLU_DECAL2 = RM_AA_ZB_XLU_DECAL(2)
G_RM_AA_ZB_OPA_INTER = RM_AA_ZB_OPA_INTER(1)
G_RM_AA_ZB_OPA_INTER2 = RM_AA_ZB_OPA_INTER(2)
G_RM_AA_ZB_XLU_INTER = RM_AA_ZB_XLU_INTER(1)
G_RM_AA_ZB_XLU_INTER2 = RM_AA_ZB_XLU_INTER(2)
G_RM_AA_ZB_XLU_LINE = RM_AA_ZB_XLU_LINE(1)
G_RM_AA_ZB_XLU_LINE2 = RM_AA_ZB_XLU_LINE(2)
G_RM_AA_ZB_DEC_LINE = RM_AA_ZB_DEC_LINE(1)
G_RM_AA_ZB_DEC_LINE2 = RM_AA_ZB_DEC_LINE(2)
G_RM_AA_ZB_TEX_EDGE = RM_AA_ZB_TEX_EDGE(1)
G_RM_AA_ZB_TEX_EDGE2 = RM_AA_ZB_TEX_EDGE(2)
G_RM_AA_ZB_TEX_INTER = RM_AA_ZB_TEX_INTER(1)
G_RM_AA_ZB_TEX_INTER2 = RM_AA_ZB_TEX_INTER(2)
G_RM_AA_ZB_SUB_SURF = RM_AA_ZB_SUB_SURF(1)
G_RM_AA_ZB_SUB_SURF2 = RM_AA_ZB_SUB_SURF(2)
G_RM_AA_ZB_PCL_SURF = RM_AA_ZB_PCL_SURF(1)
G_RM_AA_ZB_PCL_SURF2 = RM_AA_ZB_PCL_SURF(2)
G_RM_AA_ZB_OPA_TERR = RM_AA_ZB_OPA_TERR(1)
G_RM_AA_ZB_OPA_TERR2 = RM_AA_ZB_OPA_TERR(2)
G_RM_AA_ZB_TEX_TERR = RM_AA_ZB_TEX_TERR(1)
G_RM_AA_ZB_TEX_TERR2 = RM_AA_ZB_TEX_TERR(2)
G_RM_AA_ZB_SUB_TERR = RM_AA_ZB_SUB_TERR(1)
G_RM_AA_ZB_SUB_TERR2 = RM_AA_ZB_SUB_TERR(2)
G_RM_RA_ZB_OPA_SURF = RM_RA_ZB_OPA_SURF(1)
G_RM_RA_ZB_OPA_SURF2 = RM_RA_ZB_OPA_SURF(2)
G_RM_RA_ZB_OPA_DECAL = RM_RA_ZB_OPA_DECAL(1)
G_RM_RA_ZB_OPA_DECAL2 = RM_RA_ZB_OPA_DECAL(2)
G_RM_RA_ZB_OPA_INTER = RM_RA_ZB_OPA_INTER(1)
G_RM_RA_ZB_OPA_INTER2 = RM_RA_ZB_OPA_INTER(2)
G_RM_AA_OPA_SURF = RM_AA_OPA_SURF(1)
G_RM_AA_OPA_SURF2 = RM_AA_OPA_SURF(2)
G_RM_AA_XLU_SURF = RM_AA_XLU_SURF(1)
G_RM_AA_XLU_SURF2 = RM_AA_XLU_SURF(2)
G_RM_AA_XLU_LINE = RM_AA_XLU_LINE(1)
G_RM_AA_XLU_LINE2 = RM_AA_XLU_LINE(2)
G_RM_AA_DEC_LINE = RM_AA_DEC_LINE(1)
G_RM_AA_DEC_LINE2 = RM_AA_DEC_LINE(2)
G_RM_AA_TEX_EDGE = RM_AA_TEX_EDGE(1)
G_RM_AA_TEX_EDGE2 = RM_AA_TEX_EDGE(2)
G_RM_AA_SUB_SURF = RM_AA_SUB_SURF(1)
G_RM_AA_SUB_SURF2 = RM_AA_SUB_SURF(2)
G_RM_AA_PCL_SURF = RM_AA_PCL_SURF(1)
G_RM_AA_PCL_SURF2 = RM_AA_PCL_SURF(2)
G_RM_AA_OPA_TERR = RM_AA_OPA_TERR(1)
G_RM_AA_OPA_TERR2 = RM_AA_OPA_TERR(2)
G_RM_AA_TEX_TERR = RM_AA_TEX_TERR(1)
G_RM_AA_TEX_TERR2 = RM_AA_TEX_TERR(2)
G_RM_AA_SUB_TERR = RM_AA_SUB_TERR(1)
G_RM_AA_SUB_TERR2 = RM_AA_SUB_TERR(2)
G_RM_RA_OPA_SURF = RM_RA_OPA_SURF(1)
G_RM_RA_OPA_SURF2 = RM_RA_OPA_SURF(2)
G_RM_ZB_OPA_SURF = RM_ZB_OPA_SURF(1)
G_RM_ZB_OPA_SURF2 = RM_ZB_OPA_SURF(2)
G_RM_ZB_XLU_SURF = RM_ZB_XLU_SURF(1)
G_RM_ZB_XLU_SURF2 = RM_ZB_XLU_SURF(2)
G_RM_ZB_OPA_DECAL = RM_ZB_OPA_DECAL(1)
G_RM_ZB_OPA_DECAL2 = RM_ZB_OPA_DECAL(2)
G_RM_ZB_XLU_DECAL = RM_ZB_XLU_DECAL(1)
G_RM_ZB_XLU_DECAL2 = RM_ZB_XLU_DECAL(2)
G_RM_ZB_CLD_SURF = RM_ZB_CLD_SURF(1)
G_RM_ZB_CLD_SURF2 = RM_ZB_CLD_SURF(2)
G_RM_ZB_OVL_SURF = RM_ZB_OVL_SURF(1)
G_RM_ZB_OVL_SURF2 = RM_ZB_OVL_SURF(2)
G_RM_ZB_PCL_SURF = RM_ZB_PCL_SURF(1)
G_RM_ZB_PCL_SURF2 = RM_ZB_PCL_SURF(2)
G_RM_OPA_SURF = RM_OPA_SURF(1)
G_RM_OPA_SURF2 = RM_OPA_SURF(2)
G_RM_XLU_SURF = RM_XLU_SURF(1)
G_RM_XLU_SURF2 = RM_XLU_SURF(2)
G_RM_CLD_SURF = RM_CLD_SURF(1)
G_RM_CLD_SURF2 = RM_CLD_SURF(2)
G_RM_TEX_EDGE = RM_TEX_EDGE(1)
G_RM_TEX_EDGE2 = RM_TEX_EDGE(2)
G_RM_PCL_SURF = RM_PCL_SURF(1)
G_RM_PCL_SURF2 = RM_PCL_SURF(2)
G_RM_ADD = RM_ADD(1)
G_RM_ADD2 = RM_ADD(2)
G_RM_NOOP = RM_NOOP(1)
G_RM_NOOP2 = RM_NOOP(2)
G_RM_VISCVG = RM_VISCVG(1)
G_RM_VISCVG2 = RM_VISCVG(2)
G_RM_OPA_CI = RM_OPA_CI(1)
G_RM_OPA_CI2 = RM_OPA_CI(2)
G_RM_FOG_SHADE_A = GBL_c1(G_BL_CLR_FOG, G_BL_A_SHADE, G_BL_CLR_IN, G_BL_1MA)
G_RM_FOG_PRIM_A = GBL_c1(G_BL_CLR_FOG, G_BL_A_FOG, G_BL_CLR_IN, G_BL_1MA)
G_RM_PASS = GBL_c1(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1)
G_RM_RA_SPRITE = (AA_EN | CVG_DST_CLAMP | ZMODE_OPA | CVG_X_ALPHA | ALPHA_CVG_SEL | GBL_c1(
G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA))
G_RM_RA_SPRITE2 = (AA_EN | CVG_DST_CLAMP | ZMODE_OPA | CVG_X_ALPHA | ALPHA_CVG_SEL | GBL_c2(
G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA))
G_ZS_PIXEL = (0 << G_MDSFT_ZSRCSEL)
G_ZS_PRIM = (1 << G_MDSFT_ZSRCSEL)
@dataclass
class rm_preset:
rm: int
name: str
rm_presets = [
rm_preset(G_RM_OPA_SURF, "G_RM_OPA_SURF"),
rm_preset(G_RM_OPA_SURF2, "G_RM_OPA_SURF2"),
rm_preset(G_RM_AA_OPA_SURF, "G_RM_AA_OPA_SURF"),
rm_preset(G_RM_AA_OPA_SURF2, "G_RM_AA_OPA_SURF2"),
rm_preset(G_RM_RA_OPA_SURF, "G_RM_RA_OPA_SURF"),
rm_preset(G_RM_RA_OPA_SURF2, "G_RM_RA_OPA_SURF2"),
rm_preset(G_RM_ZB_OPA_SURF, "G_RM_ZB_OPA_SURF"),
rm_preset(G_RM_ZB_OPA_SURF2, "G_RM_ZB_OPA_SURF2"),
rm_preset(G_RM_AA_ZB_OPA_SURF, "G_RM_AA_ZB_OPA_SURF"),
rm_preset(G_RM_AA_ZB_OPA_SURF2, "G_RM_AA_ZB_OPA_SURF2"),
rm_preset(G_RM_RA_ZB_OPA_SURF, "G_RM_RA_ZB_OPA_SURF"),
rm_preset(G_RM_RA_ZB_OPA_SURF2, "G_RM_RA_ZB_OPA_SURF2"),
rm_preset(G_RM_XLU_SURF, "G_RM_XLU_SURF"),
rm_preset(G_RM_XLU_SURF2, "G_RM_XLU_SURF2"),
rm_preset(G_RM_AA_XLU_SURF, "G_RM_AA_XLU_SURF"),
rm_preset(G_RM_AA_XLU_SURF2, "G_RM_AA_XLU_SURF2"),
rm_preset(G_RM_ZB_XLU_SURF, "G_RM_ZB_XLU_SURF"),
rm_preset(G_RM_ZB_XLU_SURF2, "G_RM_ZB_XLU_SURF2"),
rm_preset(G_RM_AA_ZB_XLU_SURF, "G_RM_AA_ZB_XLU_SURF"),
rm_preset(G_RM_AA_ZB_XLU_SURF2, "G_RM_AA_ZB_XLU_SURF2"),
rm_preset(G_RM_ZB_OPA_DECAL, "G_RM_ZB_OPA_DECAL"),
rm_preset(G_RM_ZB_OPA_DECAL2, "G_RM_ZB_OPA_DECAL2"),
rm_preset(G_RM_AA_ZB_OPA_DECAL, "G_RM_AA_ZB_OPA_DECAL"),
rm_preset(G_RM_AA_ZB_OPA_DECAL2, "G_RM_AA_ZB_OPA_DECAL2"),
rm_preset(G_RM_RA_ZB_OPA_DECAL, "G_RM_RA_ZB_OPA_DECAL"),
rm_preset(G_RM_RA_ZB_OPA_DECAL2, "G_RM_RA_ZB_OPA_DECAL2"),
rm_preset(G_RM_ZB_XLU_DECAL, "G_RM_ZB_XLU_DECAL"),
rm_preset(G_RM_ZB_XLU_DECAL2, "G_RM_ZB_XLU_DECAL2"),
rm_preset(G_RM_AA_ZB_XLU_DECAL, "G_RM_AA_ZB_XLU_DECAL"),
rm_preset(G_RM_AA_ZB_XLU_DECAL2, "G_RM_AA_ZB_XLU_DECAL2"),
rm_preset(G_RM_AA_ZB_OPA_INTER, "G_RM_AA_ZB_OPA_INTER"),
rm_preset(G_RM_AA_ZB_OPA_INTER2, "G_RM_AA_ZB_OPA_INTER2"),
rm_preset(G_RM_RA_ZB_OPA_INTER, "G_RM_RA_ZB_OPA_INTER"),
rm_preset(G_RM_RA_ZB_OPA_INTER2, "G_RM_RA_ZB_OPA_INTER2"),
rm_preset(G_RM_AA_ZB_XLU_INTER, "G_RM_AA_ZB_XLU_INTER"),
rm_preset(G_RM_AA_ZB_XLU_INTER2, "G_RM_AA_ZB_XLU_INTER2"),
rm_preset(G_RM_AA_XLU_LINE, "G_RM_AA_XLU_LINE"),
rm_preset(G_RM_AA_XLU_LINE2, "G_RM_AA_XLU_LINE2"),
rm_preset(G_RM_AA_ZB_XLU_LINE, "G_RM_AA_ZB_XLU_LINE"),
rm_preset(G_RM_AA_ZB_XLU_LINE2, "G_RM_AA_ZB_XLU_LINE2"),
rm_preset(G_RM_AA_DEC_LINE, "G_RM_AA_DEC_LINE"),
rm_preset(G_RM_AA_DEC_LINE2, "G_RM_AA_DEC_LINE2"),
rm_preset(G_RM_AA_ZB_DEC_LINE, "G_RM_AA_ZB_DEC_LINE"),
rm_preset(G_RM_AA_ZB_DEC_LINE2, "G_RM_AA_ZB_DEC_LINE2"),
rm_preset(G_RM_TEX_EDGE, "G_RM_TEX_EDGE"),
rm_preset(G_RM_TEX_EDGE2, "G_RM_TEX_EDGE2"),
rm_preset(G_RM_AA_TEX_EDGE, "G_RM_AA_TEX_EDGE"),
rm_preset(G_RM_AA_TEX_EDGE2, "G_RM_AA_TEX_EDGE2"),
rm_preset(G_RM_AA_ZB_TEX_EDGE, "G_RM_AA_ZB_TEX_EDGE"),
rm_preset(G_RM_AA_ZB_TEX_EDGE2, "G_RM_AA_ZB_TEX_EDGE2"),
rm_preset(G_RM_AA_ZB_TEX_INTER, "G_RM_AA_ZB_TEX_INTER"),
rm_preset(G_RM_AA_ZB_TEX_INTER2, "G_RM_AA_ZB_TEX_INTER2"),
rm_preset(G_RM_AA_SUB_SURF, "G_RM_AA_SUB_SURF"),
rm_preset(G_RM_AA_SUB_SURF2, "G_RM_AA_SUB_SURF2"),
rm_preset(G_RM_AA_ZB_SUB_SURF, "G_RM_AA_ZB_SUB_SURF"),
rm_preset(G_RM_AA_ZB_SUB_SURF2, "G_RM_AA_ZB_SUB_SURF2"),
rm_preset(G_RM_PCL_SURF, "G_RM_PCL_SURF"),
rm_preset(G_RM_PCL_SURF2, "G_RM_PCL_SURF2"),
rm_preset(G_RM_AA_PCL_SURF, "G_RM_AA_PCL_SURF"),
rm_preset(G_RM_AA_PCL_SURF2, "G_RM_AA_PCL_SURF2"),
rm_preset(G_RM_ZB_PCL_SURF, "G_RM_ZB_PCL_SURF"),
rm_preset(G_RM_ZB_PCL_SURF2, "G_RM_ZB_PCL_SURF2"),
rm_preset(G_RM_AA_ZB_PCL_SURF, "G_RM_AA_ZB_PCL_SURF"),
rm_preset(G_RM_AA_ZB_PCL_SURF2, "G_RM_AA_ZB_PCL_SURF2"),
rm_preset(G_RM_AA_OPA_TERR, "G_RM_AA_OPA_TERR"),
rm_preset(G_RM_AA_OPA_TERR2, "G_RM_AA_OPA_TERR2"),
rm_preset(G_RM_AA_ZB_OPA_TERR, "G_RM_AA_ZB_OPA_TERR"),
rm_preset(G_RM_AA_ZB_OPA_TERR2, "G_RM_AA_ZB_OPA_TERR2"),
rm_preset(G_RM_AA_TEX_TERR, "G_RM_AA_TEX_TERR"),
rm_preset(G_RM_AA_TEX_TERR2, "G_RM_AA_TEX_TERR2"),
rm_preset(G_RM_AA_ZB_TEX_TERR, "G_RM_AA_ZB_TEX_TERR"),
rm_preset(G_RM_AA_ZB_TEX_TERR2, "G_RM_AA_ZB_TEX_TERR2"),
rm_preset(G_RM_AA_SUB_TERR, "G_RM_AA_SUB_TERR"),
rm_preset(G_RM_AA_SUB_TERR2, "G_RM_AA_SUB_TERR2"),
rm_preset(G_RM_AA_ZB_SUB_TERR, "G_RM_AA_ZB_SUB_TERR"),
rm_preset(G_RM_AA_ZB_SUB_TERR2, "G_RM_AA_ZB_SUB_TERR2"),
rm_preset(G_RM_CLD_SURF, "G_RM_CLD_SURF"),
rm_preset(G_RM_CLD_SURF2, "G_RM_CLD_SURF2"),
rm_preset(G_RM_ZB_CLD_SURF, "G_RM_ZB_CLD_SURF"),
rm_preset(G_RM_ZB_CLD_SURF2, "G_RM_ZB_CLD_SURF2"),
rm_preset(G_RM_ZB_OVL_SURF, "G_RM_ZB_OVL_SURF"),
rm_preset(G_RM_ZB_OVL_SURF2, "G_RM_ZB_OVL_SURF2"),
rm_preset(G_RM_ADD, "G_RM_ADD"),
rm_preset(G_RM_ADD2, "G_RM_ADD2"),
rm_preset(G_RM_VISCVG, "G_RM_VISCVG"),
rm_preset(G_RM_VISCVG2, "G_RM_VISCVG2"),
rm_preset(G_RM_OPA_CI, "G_RM_OPA_CI"),
rm_preset(G_RM_OPA_CI2, "G_RM_OPA_CI2"),
rm_preset(G_RM_RA_SPRITE, "G_RM_RA_SPRITE"),
rm_preset(G_RM_RA_SPRITE2, "G_RM_RA_SPRITE2"),
]
bl1_presets = [
rm_preset(G_RM_FOG_SHADE_A, "G_RM_FOG_SHADE_A"),
rm_preset(G_RM_FOG_PRIM_A, "G_RM_FOG_PRIM_A"),
rm_preset(G_RM_PASS, "G_RM_PASS"),
rm_preset(G_RM_NOOP, "G_RM_NOOP"),
]
bl2_presets = [
rm_preset(G_RM_NOOP2, "G_RM_NOOP2")
]
def strarg_acmuxc(v):
return {
G_ACMUX_LOD_FRACTION: "LOD_FRACTION",
G_ACMUX_TEXEL0: "TEXEL0",
G_ACMUX_TEXEL1: "TEXEL1",
G_ACMUX_PRIMITIVE: "PRIMITIVE",
G_ACMUX_SHADE: "SHADE",
G_ACMUX_ENVIRONMENT: "ENVIRONMENT",
G_ACMUX_PRIM_LOD_FRAC: "PRIM_LOD_FRAC",
}.get(v, "0")
def strarg_ccmuxa(v):
return {
G_CCMUX_COMBINED: "COMBINED",
G_CCMUX_TEXEL0: "TEXEL0",
G_CCMUX_TEXEL1: "TEXEL1",
G_CCMUX_PRIMITIVE: "PRIMITIVE",
G_CCMUX_SHADE: "SHADE",
G_CCMUX_ENVIRONMENT: "ENVIRONMENT",
G_CCMUX_1: "1",
G_CCMUX_NOISE: "NOISE",
}.get(v, "0")
def strarg_ccmuxb(v):
return {
G_CCMUX_COMBINED: "COMBINED",
G_CCMUX_TEXEL0: "TEXEL0",
G_CCMUX_TEXEL1: "TEXEL1",
G_CCMUX_PRIMITIVE: "PRIMITIVE",
G_CCMUX_SHADE: "SHADE",
G_CCMUX_ENVIRONMENT: "ENVIRONMENT",
G_CCMUX_CENTER: "CENTER",
G_CCMUX_K4: "K4",
}.get(v, "0")
def strarg_ccmuxc(v):
return {
G_CCMUX_COMBINED: "COMBINED",
G_CCMUX_TEXEL0: "TEXEL0",
G_CCMUX_TEXEL1: "TEXEL1",
G_CCMUX_PRIMITIVE: "PRIMITIVE",
G_CCMUX_SHADE: "SHADE",
G_CCMUX_ENVIRONMENT: "ENVIRONMENT",
G_CCMUX_SCALE: "SCALE",
G_CCMUX_COMBINED_ALPHA: "COMBINED_ALPHA",
G_CCMUX_TEXEL0_ALPHA: "TEXEL0_ALPHA",
G_CCMUX_TEXEL1_ALPHA: "TEXEL1_ALPHA",
G_CCMUX_PRIMITIVE_ALPHA: "PRIMITIVE_ALPHA",
G_CCMUX_SHADE_ALPHA: "SHADE_ALPHA",
G_CCMUX_ENV_ALPHA: "ENV_ALPHA",
G_CCMUX_LOD_FRACTION: "LOD_FRACTION",
G_CCMUX_PRIM_LOD_FRAC: "PRIM_LOD_FRAC",
G_CCMUX_K5: "K5",
}.get(v, "0")
def strarg_ccmuxd(v):
return {
G_CCMUX_COMBINED: "COMBINED",
G_CCMUX_TEXEL0: "TEXEL0",
G_CCMUX_TEXEL1: "TEXEL1",
G_CCMUX_PRIMITIVE: "PRIMITIVE",
G_CCMUX_SHADE: "SHADE",
G_CCMUX_ENVIRONMENT: "ENVIRONMENT",
G_CCMUX_1: "1",
}.get(v, "0")
def strarg_acmuxabd(v):
return {
G_ACMUX_COMBINED: "COMBINED",
G_ACMUX_TEXEL0: "TEXEL0",
G_ACMUX_TEXEL1: "TEXEL1",
G_ACMUX_PRIMITIVE: "PRIMITIVE",
G_ACMUX_SHADE: "SHADE",
G_ACMUX_ENVIRONMENT: "ENVIRONMENT",
G_ACMUX_1: "1",
}.get(v, "0")
def strarg_acmuxc(v):
return {
G_ACMUX_LOD_FRACTION: "LOD_FRACTION",
G_ACMUX_TEXEL0: "TEXEL0",
G_ACMUX_TEXEL1: "TEXEL1",
G_ACMUX_PRIMITIVE: "PRIMITIVE",
G_ACMUX_SHADE: "SHADE",
G_ACMUX_ENVIRONMENT: "ENVIRONMENT",
G_ACMUX_PRIM_LOD_FRAC: "PRIM_LOD_FRAC",
}.get(v, "0")
def strarg_tile(v):
return {
G_TX_LOADTILE: "G_TX_LOADTILE",
G_TX_RENDERTILE: "G_TX_RENDERTILE",
}.get(v, str(v))
def strarg_switch(v):
return {
G_ON: "G_ON",
G_OFF: "G_OFF",
}.get(v, str(v))
def strarg_fmt(v):
return {
G_IM_FMT_RGBA: "G_IM_FMT_RGBA",
G_IM_FMT_YUV: "G_IM_FMT_YUV",
G_IM_FMT_CI: "G_IM_FMT_CI",
G_IM_FMT_IA: "G_IM_FMT_IA",
G_IM_FMT_I: "G_IM_FMT_I",
}.get(v, str(v))
def strarg_siz(v):
return {
G_IM_SIZ_4b: "G_IM_SIZ_4b",
G_IM_SIZ_8b: "G_IM_SIZ_8b",
G_IM_SIZ_16b: "G_IM_SIZ_16b",
G_IM_SIZ_32b: "G_IM_SIZ_32b",
}.get(v, str(v))
def strarg_cm(v):
return {
G_TX_MIRROR | G_TX_WRAP: "G_TX_MIRROR | G_TX_WRAP",
G_TX_NOMIRROR | G_TX_WRAP: "G_TX_NOMIRROR | G_TX_WRAP",
G_TX_MIRROR | G_TX_CLAMP: "G_TX_MIRROR | G_TX_CLAMP",
G_TX_NOMIRROR | G_TX_CLAMP: "G_TX_NOMIRROR | G_TX_CLAMP",
}.get(v, str(v))
def strarg_tm(v):
return {
G_TX_NOMASK: "G_TX_NOMASK",
}.get(v, str(v))
def strarg_ts(v):
return {
G_TX_NOLOD: "G_TX_NOLOD",
}.get(v, str(v))
MDMASK_RM_C1 = 0xCCCC0000
MDMASK_RM_C2 = 0x33330000
MDMASK_RM_LO = 0x0000FFF8
def MDMASK(siz, ft): return (((1 << siz)-1) << ft)
MDMASK_ALPHACOMPARE = MDMASK(G_MDSIZ_ALPHACOMPARE, G_MDSFT_ALPHACOMPARE)
MDMASK_ZSRCSEL = MDMASK(G_MDSIZ_ZSRCSEL, G_MDSFT_ZSRCSEL)
MDMASK_ALPHADITHER = MDMASK(G_MDSIZ_ALPHADITHER, G_MDSFT_ALPHADITHER)
MDMASK_RGBDITHER = MDMASK(G_MDSIZ_RGBDITHER, G_MDSFT_RGBDITHER)
MDMASK_COMBKEY = MDMASK(G_MDSIZ_COMBKEY, G_MDSFT_COMBKEY)
MDMASK_TEXTCONV = MDMASK(G_MDSIZ_TEXTCONV, G_MDSFT_TEXTCONV)
MDMASK_TEXTFILT = MDMASK(G_MDSIZ_TEXTFILT, G_MDSFT_TEXTFILT)
MDMASK_TEXTLUT = MDMASK(G_MDSIZ_TEXTLUT, G_MDSFT_TEXTLUT)
MDMASK_TEXTLOD = MDMASK(G_MDSIZ_TEXTLOD, G_MDSFT_TEXTLOD)
MDMASK_TEXTDETAIL = MDMASK(G_MDSIZ_TEXTDETAIL, G_MDSFT_TEXTDETAIL)
MDMASK_TEXTPERSP = MDMASK(G_MDSIZ_TEXTPERSP, G_MDSFT_TEXTPERSP)
MDMASK_CYCLETYPE = MDMASK(G_MDSIZ_CYCLETYPE, G_MDSFT_CYCLETYPE)
MDMASK_PIPELINE = MDMASK(G_MDSIZ_PIPELINE, G_MDSFT_PIPELINE)
def rm_mode_str(buf, arg):
if (arg & AA_EN):
buf += ("AA_EN")
if (arg & Z_CMP):
if (len(buf) > 0):
buf += (" | ")
buf += ("Z_CMP")
if (arg & Z_UPD):
if (len(buf) > 0):
buf += (" | ")
buf += ("Z_UPD")
if (arg & IM_RD):
if (len(buf) > 0):
buf += (" | ")
buf += ("IM_RD")
if (arg & CLR_ON_CVG):
if (len(buf) > 0):
buf += (" | ")
buf += ("CLR_ON_CVG")
if (len(buf) > 0):
buf += (" | ")
cvg = arg & 0x00000300
if cvg == CVG_DST_CLAMP:
buf += "CVG_DST_CLAMP"
elif cvg == CVG_DST_WRAP:
buf += "CVG_DST_WRAP"
elif cvg == CVG_DST_FULL:
buf += "CVG_DST_FULL"
elif cvg == CVG_DST_SAVE:
buf += "CVG_DST_SAVE"
zmode = arg & 0x00000C00
if zmode == ZMODE_OPA:
buf += " | ZMODE_OPA"
elif zmode == ZMODE_INTER:
buf += " | ZMODE_INTER"
elif zmode == ZMODE_XLU:
buf += " | ZMODE_XLU"
elif zmode == ZMODE_DEC:
buf += " | ZMODE_DEC"
if (arg & CVG_X_ALPHA):
buf += (" | CVG_X_ALPHA")
if (arg & ALPHA_CVG_SEL):
buf += (" | ALPHA_CVG_SEL")
if (arg & FORCE_BL):
buf += (" | FORCE_BL")
return buf
def rm_cbl_str(buf, arg, c):
if (c == 2):
arg <<= 2
bp = (arg >> 30) & 0b11
if bp == G_BL_CLR_IN:
buf += f"GBL_c{c}(G_BL_CLR_IN"
elif bp == G_BL_CLR_MEM:
buf += f"GBL_c{c}(G_BL_CLR_MEM"
elif bp == G_BL_CLR_BL:
buf += f"GBL_c{c}(G_BL_CLR_BL"
elif bp == G_BL_CLR_FOG:
buf += f"GBL_c{c}(G_BL_CLR_FOG"
ba = (arg >> 26) & 0b11
if ba == G_BL_A_IN:
buf += ", G_BL_A_IN"
if ba == G_BL_A_FOG:
buf += ", G_BL_A_FOG"
if ba == G_BL_A_SHADE:
buf += ", G_BL_A_SHADE"
if ba == G_BL_0:
buf += ", G_BL_0"
bm = (arg >> 22) & 0b11
if bm == G_BL_CLR_IN:
buf += ", G_BL_CLR_IN"
elif bm == G_BL_CLR_MEM:
buf += ", G_BL_CLR_MEM"
elif bm == G_BL_CLR_BL:
buf += ", G_BL_CLR_BL"
elif bm == G_BL_CLR_FOG:
buf += ", G_BL_CLR_FOG"
bb = (arg >> 18) & 0b11
if bb == G_BL_1MA:
buf += ", G_BL_1MA)"
elif bb == G_BL_A_MEM:
buf += ", G_BL_A_MEM)"
elif bb == G_BL_1:
buf += ", G_BL_1)"
elif bb == G_BL_0:
buf += ", G_BL_0)"
return buf
def othermodehi_str(arg, which):
buf = ""
ad_mask = MDMASK_ALPHADITHER
if ((arg | which) & ad_mask):
ad = arg & ad_mask
if ad == G_AD_PATTERN:
buf += ("G_AD_PATTERN")
elif ad == G_AD_NOTPATTERN:
buf += ("G_AD_NOTPATTERN")
elif ad == G_AD_NOISE:
buf += ("G_AD_NOISE")
elif ad == G_AD_DISABLE:
buf += ("G_AD_DISABLE")
else:
buf += hex(ad)
cd_mask = MDMASK_RGBDITHER
if ((arg | which) & cd_mask):
if (len(buf) > 0):
buf += (" | ")
cd = arg & cd_mask
if cd == G_CD_MAGICSQ:
buf += ("G_CD_MAGICSQ")
elif cd == G_CD_BAYER:
buf += ("G_CD_BAYER")
elif cd == G_CD_NOISE:
buf += ("G_CD_NOISE")
elif cd == G_CD_DISABLE:
buf += ("G_CD_DISABLE")
else:
buf += hex(cd)
ck_mask = MDMASK_COMBKEY
if ((arg | which) & ck_mask):
if (len(buf) > 0):
buf += (" | ")
ck = arg & ck_mask
if ck == G_CK_NONE:
buf += ("G_CK_NONE")
elif ck == G_CK_KEY:
buf += ("G_CK_KEY")
else:
buf += hex(ck)
tc_mask = MDMASK_TEXTCONV
if ((arg | which) & tc_mask):
if (len(buf) > 0):
buf += (" | ")
tc = arg & tc_mask
if tc == G_TC_CONV:
buf += ("G_TC_CONV")
elif tc == G_TC_FILTCONV:
buf += ("G_TC_FILTCONV")
elif tc == G_TC_FILT:
buf += ("G_TC_FILT")
else:
buf += hex(tc)
tf_mask = MDMASK_TEXTFILT
if ((arg | which) & tf_mask):
if (len(buf) > 0):
buf += (" | ")
tf = arg & tf_mask
if tf == G_TF_POINT:
buf += ("G_TF_POINT")
elif tf == G_TF_BILERP:
buf += ("G_TF_BILERP")
elif tf == G_TF_AVERAGE:
buf += ("G_TF_AVERAGE")
else:
buf += hex(tf)
tt_mask = MDMASK_TEXTLUT
if ((arg | which) & tt_mask):
if (len(buf) > 0):
buf += (" | ")
tt = arg & tt_mask
if tt == G_TT_NONE:
buf += ("G_TT_NONE")
elif tt == G_TT_RGBA16:
buf += ("G_TT_RGBA16")
elif tt == G_TT_IA16:
buf += ("G_TT_IA16")
else:
buf += hex(tt)
tl_mask = MDMASK_TEXTLOD
if ((arg | which) & tl_mask):
if (len(buf) > 0):
buf += (" | ")
tl = arg & tl_mask
if tl == G_TL_TILE:
buf += ("G_TL_TILE")
elif tl == G_TL_LOD:
buf += ("G_TL_LOD")
else:
buf += hex(tl)
td_mask = MDMASK_TEXTDETAIL
if ((arg | which) & td_mask):
if (len(buf) > 0):
buf += (" | ")
td = arg & td_mask
if td == G_TD_CLAMP:
buf += ("G_TD_CLAMP")
elif td == G_TD_SHARPEN:
buf += ("G_TD_SHARPEN")
elif td == G_TD_DETAIL:
buf += ("G_TD_DETAIL")
else:
buf += hex(td)
tp_mask = MDMASK_TEXTPERSP
if ((arg | which) & tp_mask):
if (len(buf) > 0):
buf += (" | ")
tp = arg & tp_mask
if tp == G_TP_NONE:
buf += ("G_TP_NONE")
elif tp == G_TP_PERSP:
buf += ("G_TP_PERSP")
else:
buf += hex(tp)
cyc_mask = MDMASK_CYCLETYPE
if ((arg | which) & cyc_mask):
if (len(buf) > 0):
buf += (" | ")
cyc = arg & cyc_mask
if cyc == G_CYC_1CYCLE:
buf += ("G_CYC_1CYCLE")
elif cyc == G_CYC_2CYCLE:
buf += ("G_CYC_2CYCLE")
elif cyc == G_CYC_COPY:
buf += ("G_CYC_COPY")
elif cyc == G_CYC_FILL:
buf += ("G_CYC_FILL")
else:
buf += hex(cyc)
pm_mask = MDMASK_PIPELINE
if ((arg | which) & pm_mask):
if (len(buf) > 0):
buf += (" | ")
pm = arg & pm_mask
if pm == G_PM_NPRIMITIVE:
buf += ("G_PM_NPRIMITIVE")
elif pm == G_PM_1PRIMITIVE:
buf += ("G_PM_1PRIMITIVE")
else:
buf += hex(pm)
unk_mask = ~(ad_mask | cd_mask | ck_mask | tc_mask | tf_mask |
tt_mask | tl_mask | td_mask | tp_mask | cyc_mask |
pm_mask)
if (arg & unk_mask):
if (len(buf) > 0):
buf += (" | ")
unk = arg & unk_mask
buf += hex(unk)
return buf
def strarg_ad(arg):
return othermodehi_str(arg, (MDMASK_ALPHADITHER))
def strarg_cd(arg):
return othermodehi_str(arg, (MDMASK_RGBDITHER))
def strarg_ck(arg):
return othermodehi_str(arg, (MDMASK_COMBKEY))
def strarg_tc(arg):
return othermodehi_str(arg, (MDMASK_TEXTCONV))
def strarg_tf(arg):
return othermodehi_str(arg, (MDMASK_TEXTFILT))
def strarg_tt(arg):
return othermodehi_str(arg, (MDMASK_TEXTLUT))
def strarg_tl(arg):
return othermodehi_str(arg, (MDMASK_TEXTLOD))
def strarg_td(arg):
return othermodehi_str(arg, (MDMASK_TEXTDETAIL))
def strarg_tp(arg):
return othermodehi_str(arg, (MDMASK_TEXTPERSP))
def strarg_cyc(arg):
return othermodehi_str(arg, (MDMASK_CYCLETYPE))
def strarg_pm(arg):
return othermodehi_str(arg, (MDMASK_PIPELINE))
def strarg_othermodehi(arg):
mask = (MDMASK_ALPHADITHER) | (MDMASK_RGBDITHER) | (MDMASK_COMBKEY) | (MDMASK_TEXTCONV) | (MDMASK_TEXTFILT) | (
MDMASK_TEXTLUT) | (MDMASK_TEXTLOD) | (MDMASK_TEXTDETAIL) | (MDMASK_TEXTPERSP) | (MDMASK_CYCLETYPE) | (MDMASK_PIPELINE)
return othermodehi_str(arg, mask)
def othermodelo_str(arg, which):
buf = ""
rm_c1_mask = MDMASK_RM_C1
rm_c2_mask = MDMASK_RM_C2
rm_mode_lo = MDMASK_RM_LO
rm_mask = rm_c1_mask | rm_c2_mask | rm_mode_lo
pre_c1: rm_preset = None
pre_c2: rm_preset = None
pre_c1_ind = -2
pre_c1_ind = -2
for i, pre in enumerate(rm_presets):
rm_c1 = arg & (rm_c1_mask | rm_mode_lo | (pre.rm & ~rm_mask))
if (pre_c1 == None and rm_c1 == pre.rm):
pre_c1 = pre
pre_c1_ind = i
rm_c2 = arg & (rm_c2_mask | rm_mode_lo | (pre.rm & ~rm_mask))
if (pre_c2 == None and rm_c2 == pre.rm):
pre_c2 = pre
pre_c2_ind = i
if (pre_c1 == None or pre_c2 == None or pre_c1_ind + 1 != pre_c2_ind):
for i, pre in enumerate(bl1_presets):
rm_c1 = arg & (rm_c1_mask | (pre.rm & ~rm_mask))
if (rm_c1 == pre.rm):
pre_c1 = pre
break
for i, pre in enumerate(bl2_presets):
rm_c2 = arg & (rm_c2_mask | (pre.rm & ~rm_mask))
if (rm_c2 == pre.rm):
pre_c2 = pre
break
pre_rm = 0
if (pre_c1 != None):
pre_rm |= pre_c1.rm
if (pre_c2 != None):
pre_rm |= pre_c2.rm
ac_mask = MDMASK_ALPHACOMPARE
if (((arg & ~pre_rm) | which) & ac_mask):
ac = arg & ac_mask
if (ac == G_AC_NONE):
buf += "G_AC_NONE"
elif (ac == G_AC_THRESHOLD):
buf += "G_AC_THRESHOLD"
elif (ac == G_AC_DITHER):
buf += "G_AC_DITHER"
else:
buf += f"{ac:04x}"
zs_mask = MDMASK_ZSRCSEL
if (((arg & ~pre_rm) | which) & zs_mask):
if (len(buf) > 0):
buf += " | "
zs = arg & zs_mask
if (zs == G_ZS_PIXEL):
buf += "G_ZS_PIXEL"
elif (zs == G_ZS_PRIM):
buf += "G_ZS_PRIM"
else:
buf += f"{ac:04x}"
rm = arg & (rm_mask | pre_rm)
if (((arg & ~pre_rm) | which) & rm_mode_lo):
if (len(buf) > 0):
buf += " | "
buf = rm_mode_str(buf, rm)
c = 0
if (which & rm_c1_mask):
c |= 1
if (which & rm_c2_mask):
c |= 2
if (c & 1 or (c == 0 and arg & rm_c1_mask)):
if (len(buf) > 0):
buf += " | "
if (pre_c1):
buf += pre_c1.name
else:
buf = rm_cbl_str(buf, rm, 1)
if (c & 2 or (c == 0 and arg & rm_c2_mask)):
if (len(buf) > 0):
buf += " | "
if (pre_c2):
buf += pre_c2.name
else:
buf = rm_cbl_str(buf, rm, 2)
unk_mask = ~(rm_mask | ac_mask | zs_mask)
if (arg & unk_mask):
if (len(buf) > 0):
buf += " | "
unk = arg & unk_mask
buf += unk
return buf
def strarg_rm1(v):
return othermodelo_str(v, MDMASK_RM_C1)
def strarg_rm2(v):
return othermodelo_str(v, MDMASK_RM_C2)
def strarg_ac(v):
return othermodelo_str(v, MDMASK_ALPHACOMPARE)
def strarg_zs(v):
return othermodelo_str(v, MDMASK_ZSRCSEL)
def strarg_othermodelo(v):
return othermodelo_str(v, MDMASK_ALPHACOMPARE | MDMASK_ZSRCSEL | MDMASK_RM_C1 | MDMASK_RM_C2)
def strarg_texwrap(v):
return {
GX_CLAMP: "GX_CLAMP",
GX_REPEAT: "GX_REPEAT",
GX_MIRROR: "GX_MIRROR",
GX_MAX_TEXWRAPMODE: "GX_MAX_TEXWRAPMODE",
}.get(v, str(v))
def strarg_dolphintile(v):
return {
G_DOLPHIN_TLUT_DEFAULT_MODE: "G_DOLPHIN_TLUT_DEFAULT_MODE"
}.get(v, str(v))
def strarg_gm(arg):
buf = ""
if (arg == 0):
buf += ("0")
return buf
if (arg & G_ZBUFFER):
buf += ("G_ZBUFFER")
if (arg & G_TEXTURE_ENABLE):
if (len(buf) > 0):
buf += (" | ")
buf += ("G_TEXTURE_ENABLE")
if (arg & G_SHADE):
if (len(buf) > 0):
buf += (" | ")
buf += ("G_SHADE")
if ((arg & G_CULL_BOTH) == G_CULL_BOTH):
if (len(buf) > 0):
buf += (" | ")
buf += ("G_CULL_BOTH")
else:
if (arg & G_CULL_FRONT):
if (len(buf) > 0):
buf += (" | ")
buf += ("G_CULL_FRONT")
if (arg & G_CULL_BACK):
if (len(buf) > 0):
buf += (" | ")
buf += ("G_CULL_BACK")
if (arg & G_FOG):
if (len(buf) > 0):
buf += (" | ")
buf += ("G_FOG")
if (arg & G_LIGHTING):
if (len(buf) > 0):
buf += (" | ")
buf += ("G_LIGHTING")
if (arg & G_TEXTURE_GEN):
if (len(buf) > 0):
buf += (" | ")
buf += ("G_TEXTURE_GEN")
if (arg & G_TEXTURE_GEN_LINEAR):
if (len(buf) > 0):
buf += (" | ")
buf += ("G_TEXTURE_GEN_LINEAR")
if (arg & G_LOD):
if (len(buf) > 0):
buf += (" | ")
buf += ("G_LOD")
if (arg & G_SHADING_SMOOTH):
if (len(buf) > 0):
buf += (" | ")
buf += ("G_SHADING_SMOOTH")
if (arg & G_CLIPPING):
if (len(buf) > 0):
buf += (" | ")
buf += ("G_CLIPPING")
if (arg & G_LIGHTING_POSITIONAL):
if (len(buf) > 0):
buf += (" | ")
buf += ("G_LIGHTING_POSITIONAL")
if (arg & G_DECAL_ALL == G_DECAL_ALL):
if (len(buf) > 0):
buf += (" | ")
buf += ("G_DECAL_ALL")
elif (arg & G_DECAL_ALWAYS == G_DECAL_ALWAYS):
if (len(buf) > 0):
buf += (" | ")
buf += ("G_DECAL_ALWAYS")
elif (arg & G_DECAL_EQUAL):
if (len(buf) > 0):
buf += (" | ")
buf += ("G_DECAL_EQUAL")
elif (arg & G_DECAL_GEQUAL):
if (len(buf) > 0):
buf += (" | ")
buf += ("G_DECAL_GEQUAL")
else:
if (len(buf) > 0):
buf += (" | ")
buf += ("G_DECAL_LEQUAL")
if (arg & G_DECAL_SPECIAL and arg & G_DECAL_ALWAYS == 0):
if (len(buf) > 0):
buf += (" | ")
buf += ("G_DECAL_SPECIAL")
if (arg & G_LIGHTING_GC):
if (len(buf) > 0):
buf += (" | ")
buf += ("G_LIGHTING_GC")
arg = arg & ~(G_ZBUFFER | G_TEXTURE_ENABLE | G_SHADE | G_CULL_BOTH | G_FOG |
G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD |
G_SHADING_SMOOTH | G_CLIPPING | G_LIGHTING_GC | G_DECAL_SPECIAL |
G_DECAL_ALWAYS | G_LIGHTING_POSITIONAL)
if (arg):
if (len(buf) > 0):
buf += (" | ")
buf += f"0x{arg:08x}"
return buf
def strarg_mp(arg):
buf = ""
if (arg & G_MTX_PUSH):
buf += ("G_MTX_PUSH")
else:
buf += ("G_MTX_NOPUSH")
if (arg & G_MTX_LOAD):
buf += (" | G_MTX_LOAD")
else:
buf += (" | G_MTX_MUL")
if (arg & G_MTX_PROJECTION):
buf += (" | G_MTX_PROJECTION")
else:
buf += (" | G_MTX_MODELVIEW")
for i in range(3, 8):
if (arg & (1 << i)):
buf += (" | 0x%02x" % (1 << i))
return buf
@dataclass
class BitToArgs:
offset: int
size: int
data_location: int
to_str: callable = (lambda x: str(x))
B2A = BitToArgs
def extract_data(buff, offs, size): return (buff >> offs) & ((1 << size) - 1)
def extract_data_upper(buff, offs=0, size=32): return extract_data(
int.from_bytes(buff[0:4], 'big'), offs, size)
def extract_data_lower(buff, offs=0, size=32): return extract_data(
int.from_bytes(buff[4:8], 'big'), offs, size)
def gf_call(name: str, data: bytes, *offs: BitToArgs) -> str:
upper_data = extract_data_upper(data)
lower_data = extract_data_lower(data)
datas = [lower_data, upper_data, (upper_data << 32) | lower_data]
strs_out = []
for bitArgs in offs:
if bitArgs == GFX_SYMBOL:
strs_out.append(symbol_lookup(lower_data))
else:
strs_out.append(bitArgs.to_str(extract_data(
datas[bitArgs.data_location], bitArgs.offset, bitArgs.size)))
if SHOW_CODE:
return f"/* {upper_data:08x} {lower_data:08x} */ {name}({', '.join(strs_out)})"
else:
return f"{name}({', '.join(strs_out)})"
def unsupported_gfx_call(data):
out = ""
if SHOW_CODE:
out += f"/* {extract_data_upper(data):08x} {extract_data_lower(data):08x} */ "
return out + f"UNSUPPORTED_CALL({', '.join(f'0x{a:02x}' for a in data)})"
# return out + f"{{0x{int.from_bytes(data[0:4]):08x}, 0x{int.from_bytes(data[4:8]):08x}}}"
def gfx_gsSPTexture(data):
if (extract_data_upper(data, 16, 8) == BOWTIE_VAL):
return gf_call("gsSPTexture", data, B2A(16, 16, DL), B2A(0, 16, DL), B2A(11, 3, DU), B2A(8, 3, DU, strarg_tile), B2A(1, 7, DU, strarg_switch))
else:
return gf_call("gsSPTextureL", data, B2A(16, 16, DL), B2A(0, 16, DL), B2A(11, 3, DU), B2A(16, 8, DU), B2A(8, 3, DU, strarg_tile), B2A(1, 7, DU, strarg_switch))
def gfx_gsDPSetRenderMode(data):
return gf_call("gsDPSetRenderMode", data, B2A(0, 32, DL, strarg_rm1), B2A(0, 32, DL, strarg_rm2))
def gfx_gsSPSetOther_Lo(data):
length = extract_data_upper(data, 0, 8) + 1
shift = 32 - (extract_data_upper(data, 8, 8) + length)
return {
(G_MDSFT_ALPHACOMPARE, G_MDSIZ_ALPHACOMPARE): None,
(G_MDSFT_ZSRCSEL, G_MDSIZ_ZSRCSEL): None,
(G_MDSFT_RENDERMODE, G_MDSIZ_RENDERMODE): gfx_gsDPSetRenderMode
}.get((shift, length), unsupported_gfx_call)(data)
def gfx_gsDPSetTextureLUT(data):
return gf_call("gsDPSetTextureLUT", data,
B2A(0, 32, DL, strarg_tt))
def gfx_gsDPSetCycleType(data):
return gf_call("gsDPSetCycleType", data,
B2A(0, 32, DL, strarg_cyc))
def gfx_gsSPSetOther_Hi(data):
length = extract_data_upper(data, 0, 8) + 1
shift = 32 - (extract_data_upper(data, 8, 8) + length)
return {
# (G_MDSFT_ALPHADITHER, G_MDSIZ_ALPHADITHER): None,
# (G_MDSFT_RGBDITHER, G_MDSIZ_RGBDITHER): None,
# (G_MDSFT_COMBKEY, G_MDSIZ_COMBKEY): None,
# (G_MDSFT_TEXTCONV, G_MDSIZ_TEXTCONV): None,
# (G_MDSFT_TEXTFILT, G_MDSIZ_TEXTFILT): None,
(G_MDSFT_TEXTLUT, G_MDSIZ_TEXTLUT): gfx_gsDPSetTextureLUT,
# (G_MDSFT_TEXTLOD, G_MDSIZ_TEXTLOD): None,
# (G_MDSFT_TEXTDETAIL, G_MDSIZ_TEXTDETAIL): None,
# (G_MDSFT_TEXTPERSP, G_MDSIZ_TEXTPERSP): None,
(G_MDSFT_CYCLETYPE, G_MDSIZ_CYCLETYPE): gfx_gsDPSetCycleType,
# (G_MDSFT_PIPELINE, G_MDSIZ_PIPELINE): None,
}.get((shift, length), unsupported_gfx_call)(data)
def gfx_gsSPSettImg(data):
if extract_data_upper(data, 18, 1) == 1:
return gf_call("gsDPSetTextureImage_Dolphin", data,
B2A(21, 3, DU, strarg_fmt),
B2A(19, 2, DU, strarg_siz),
B2A(0, 10, DU, lambda x: str(x+1)),
B2A(10, 8, DU, lambda x: str((x+1)*4)),
GFX_SYMBOL)
else:
return gf_call("gsDPSetTextureImage", data,
B2A(21, 3, DU, strarg_fmt),
B2A(19, 2, DU, strarg_siz),
B2A(0, 12, DU, lambda x: str(x+1)),
GFX_SYMBOL)
def gfx_gsDPPipeSync(data):
return gf_call("gsDPPipeSync", data)
def gfx_gsDPTileSync(data):
return gf_call("gsDPTileSync", data)
def gfx_gsDPLoadSync(data):
return gf_call("gsDPLoadSync", data)
def gfx_gsDPLoadTLUTCmd(data):
if extract_data_upper(data, 22, 2) == G_TLUT_DOLPHIN:
return gf_call("gsDPLoadTLUT_Dolphin", data, B2A(16, 4, DU), B2A(0, 14, DU), B2A(14, 2, DU), GFX_SYMBOL)
else:
return gf_call("gsDPLoadTLUTCmd", data, B2A(24, 3, DL, strarg_tile), B2A(14, 10, DL))
def gfx_SetCombineLERP(data):
return gf_call("gsDPSetCombineLERP", data,
B2A(20, 4, DU, strarg_ccmuxa),
B2A(28, 4, DL, strarg_ccmuxb),
B2A(15, 5, DU, strarg_ccmuxc),
B2A(15, 3, DL, strarg_ccmuxd),
B2A(12, 3, DU, strarg_acmuxabd),
B2A(12, 3, DL, strarg_acmuxabd),
B2A(9, 3, DU, strarg_acmuxc),
B2A(9, 3, DL, strarg_acmuxabd),
B2A(5, 4, DU, strarg_ccmuxa),
B2A(24, 4, DL, strarg_ccmuxb),
B2A(0, 5, DU, strarg_ccmuxc),
B2A(6, 3, DL, strarg_ccmuxd),
B2A(21, 3, DL, strarg_acmuxabd),
B2A(3, 3, DL, strarg_acmuxabd),
B2A(18, 3, DL, strarg_acmuxc),
B2A(0, 3, DL, strarg_acmuxabd))
def gfx_gsDPSetTile(data):
return gf_call("gsDPSetTile", data,
B2A(21, 3, DU, strarg_fmt),
B2A(19, 2, DU, strarg_siz),
B2A(9, 9, DU),
B2A(0, 9, DU),
B2A(24, 3, DL, strarg_tile),
B2A(20, 4, DL),
B2A(18, 2, DL, strarg_cm),
B2A(14, 4, DL, strarg_tm),
B2A(10, 4, DL, strarg_ts),
B2A(8, 2, DL, strarg_cm),
B2A(4, 4, DL, strarg_tm),
B2A(0, 4, DL, strarg_ts),
)
def gfx_gsDPLoadBlock(data):
return gf_call("gsDPLoadBlock", data,
B2A(24, 3, DL, strarg_tile),
B2A(12, 12, DU),
B2A(0, 12, DU),
B2A(12, 12, DL),
B2A(0, 12, DL),
)
def gfx_gsDPSetTileSize(data):
return gf_call("gsDPSetTileSize", data,
B2A(24, 3, DL, strarg_tile),
B2A(12, 12, DU),
B2A(0, 12, DU),
B2A(12, 12, DL),
B2A(0, 12, DL),
)
def gfx_gsSp1Triangle(data):
def _C(v):
return str(v//2)
return gf_call("gsSP1Triangle", data,
B2A(16, 8, DU, _C),
B2A(8, 8, DU, _C),
B2A(0, 8, DU, _C),
B2A(0, 1, DU, lambda _: "0")
)
def gfx_gsDPSetEnvColor(data):
return gf_call("gsDPSetEnvColor", data,
B2A(24, 8, DL),
B2A(16, 8, DL),
B2A(8, 8, DL),
B2A(0, 8, DL))
def gfx_gsDPSetOtherMode(data):
return gf_call("gsDPSetOtherMode", data,
B2A(0, 24, DU, strarg_othermodehi),
B2A(0, 32, DL, strarg_othermodelo))
def gfx_gsSPNTriangles(data):
global triangle_count, extended_func
count = extract_data_upper(data, 17, 7) + 1 - 3
if count > 0:
triangle_count = count
extended_func = gfx_gsSPNTriangles_5b
return gf_call("gsSPNTriangles", data,
B2A(17, 7, DU, lambda x: str(x+1)),
B2A(4, 5, DL), B2A(9, 5, DL), B2A(14, 5, DL),
B2A(19, 5, DL), B2A(24, 5, DL), B2A(29, 5, DS),
B2A(2, 5, DU), B2A(7, 5, DU), B2A(12, 5, DU),
)
def gfx_gsSPCullDisplayList(data):
return gf_call("gsSPCullDisplayList", data,
B2A(0, 16, DU, lambda x: str(x//2)),
B2A(0, 16, DL, lambda x: str(x//2))
)
def gfx_gsDPSetTile_Dolphin(data):
return gf_call("gsDPSetTile_Dolphin", data, B2A(20, 4, DU, strarg_dolphintile), B2A(16, 3, DU), B2A(12, 4, DU), B2A(10, 2, DU, strarg_texwrap), B2A(8, 2, DU, strarg_texwrap), B2A(4, 4, DU), B2A(0, 4, DU))
def gfx_dl(data):
if extract_data_upper(data, 16, 8) == 0:
return gf_call("gsSPDisplayList", data, GFX_SYMBOL)
else:
return gf_call("gsSPBranchList", data, GFX_SYMBOL)
def gfx_gsSPEndDisplayList(data):
return gf_call("gsSPEndDisplayList", data)
def gfx_gsSPGeometryMode(data):
clear_bits = ~extract_data_upper(data, 0, 24) & 0xffffff
set_bits = extract_data_lower(data)
if (clear_bits == 0xffffff):
return gf_call("gsSPLoadGeometryMode", data, B2A(0, 32, DL, strarg_gm))
elif clear_bits == 0:
return gf_call("gsSPSetGeometryMode", data, B2A(0, 32, DL, strarg_gm))
elif set_bits == 0:
return gf_call("gsSPClearGeometryMode", data, B2A(0, 24, DU, lambda x: strarg_gm(~x & 0xffffff)))
else:
return gf_call("gsSPGeometryMode", data, B2A(0, 24, DU, lambda x: strarg_gm(~x & 0xffffff)), B2A(0, 32, DL, strarg_gm))
def gfx_gsSPVertex(data):
global triangle_count, extended_func
n = extract_data_upper(data, 12, 8)
return gf_call("gsSPVertex", data, GFX_SYMBOL, B2A(12, 8, DU), B2A(1, 7, DU, lambda x: str(x-n)))
def gfx_gsSP2Triangles(data):
def _C(v):
return str(v//2)
return gf_call("gsSP2Triangles", data,
B2A(16, 8, DU, _C),
B2A(8, 8, DU, _C),
B2A(0, 8, DU, _C),
B2A(0, 1, DU, lambda _: "0"),
B2A(16, 8, DL, _C),
B2A(8, 8, DL, _C),
B2A(0, 8, DL, _C),
B2A(0, 1, DL, lambda _: "0"))
triangle_count = 0
extended_func = None
def gfx_gsSPNTrianglesInit(data):
global triangle_count, extended_func
assert (extract_data_lower(data, 0, 1) == 0)
# if extract_data_lower(data, 0, 1) == 0:
# count = extract_data_upper(data, 17, 7) + 1
# outs = gf_call("gsSPNTrianglesInit_7b", data, B2A(17, 7, DU, lambda x: str(x+1)),
# B2A(4, 5, DL), B2A(9, 5, DL), B2A(14, 5, DL),
# B2A(19, 5, DL), B2A(24, 5, DL), B2A(29, 5, DS),
# B2A(2, 5, DU), B2A(7, 5, DU), B2A(12, 5, DU),
# )
# this_extended_func = gfx_gsSPNTriangles_7b
# else:
# count = extract_data_upper(data, 17, 7) + 1
# outs = gf_call("gsSPNTrianglesInit_5b", data, B2A(17, 7, DU, lambda x: str(x+1)),
# B2A(4, 5, DL), B2A(9, 5, DL), B2A(14, 5, DL),
# B2A(19, 5, DL), B2A(24, 5, DL), B2A(29, 5, DS),
# B2A(2, 5, DU), B2A(7, 5, DU), B2A(12, 5, DU),
# )
# this_extended_func = gfx_gsSPNTriangles_5b
count = extract_data_upper(data, 17, 7) + 1
outs = gf_call("gsSPNTrianglesInit_5b", data, B2A(17, 7, DU, lambda x: str(x+1)),
B2A(4, 5, DL), B2A(9, 5, DL), B2A(14, 5, DL),
B2A(19, 5, DL), B2A(24, 5, DL), B2A(29, 5, DS),
B2A(2, 5, DU), B2A(7, 5, DU), B2A(12, 5, DU),
)
this_extended_func = gfx_gsSPNTriangles_5b
triangle_count = count - 3
if triangle_count > 0:
extended_func = this_extended_func
return outs
def gfx_gsSPNTriangles_5b(data):
global triangle_count, extended_func
triangle_count -= 4
if triangle_count <= 0:
extended_func = None
return gf_call("gsSPNTriangles_5b", data,
B2A(4, 5, DL), B2A(9, 5, DL), B2A(14, 5, DL),
B2A(19, 5, DL), B2A(24, 5, DL), B2A(29, 5, DS),
B2A(2, 5, DU), B2A(7, 5, DU), B2A(12, 5, DU),
B2A(17, 5, DU), B2A(22, 5, DU), B2A(27, 5, DU))
def gfx_gsSPMatrix(data):
return gf_call("gsSPMatrix", data,
GFX_SYMBOL, B2A(0, 8, DU, lambda x: strarg_mp(x ^ G_MTX_PUSH)))
def gfx_gsDPSetPrimColor(data):
return gf_call("gsDPSetPrimColor", data,
B2A(8, 8, DU), B2A(0, 8, DU),
B2A(24, 8, DL), B2A(16, 8, DL),
B2A(8, 8, DL), B2A(0, 8, DL))
# main
GFX_LOOKUP = {
G_TEXTURE: gfx_gsSPTexture,
G_SETCOMBINE: gfx_SetCombineLERP,
G_SETOTHERMODE_L: gfx_gsSPSetOther_Lo,
G_SETOTHERMODE_H: gfx_gsSPSetOther_Hi,
G_SETTIMG: gfx_gsSPSettImg,
G_SETTILE_DOLPHIN: gfx_gsDPSetTile_Dolphin,
G_DL: gfx_dl,
G_ENDDL: gfx_gsSPEndDisplayList,
G_GEOMETRYMODE: gfx_gsSPGeometryMode,
G_VTX: gfx_gsSPVertex,
G_TRIN_INDEPEND: gfx_gsSPNTrianglesInit,
G_MTX: gfx_gsSPMatrix,
G_SETPRIMCOLOR: gfx_gsDPSetPrimColor,
G_RDPPIPESYNC: gfx_gsDPPipeSync,
G_RDPTILESYNC: gfx_gsDPTileSync,
G_RDPLOADSYNC: gfx_gsDPLoadSync,
G_TRI2: gfx_gsSP2Triangles,
G_LOADTLUT: gfx_gsDPLoadTLUTCmd,
G_SETTILE: gfx_gsDPSetTile,
G_LOADBLOCK: gfx_gsDPLoadBlock,
G_SETTILESIZE: gfx_gsDPSetTileSize,
G_TRI1: gfx_gsSp1Triangle,
G_SETENVCOLOR: gfx_gsDPSetEnvColor,
G_RDPSETOTHERMODE: gfx_gsDPSetOtherMode,
G_TRIN: gfx_gsSPNTriangles,
G_CULLDL: gfx_gsSPCullDisplayList
}
def convert_binary_to_gfx(b: bytes, symbol_names: list[str]):
global symbol_stack
symbol_stack = symbol_names
i = 0
out = []
while True:
chunk = b[i: i + 8]
i += 8
if len(chunk) < 8:
break
if extended_func:
a = extended_func(chunk)
else:
a = GFX_LOOKUP.get(chunk[0], unsupported_gfx_call)(chunk)
out.append(a)
return ",\n".join(out)
def convert_binary_to_gfx_c_source(src_path, dest_path):
global extended_func
# Load data
with open(src_path, "rb") as binary_file, open(dest_path, "w") as c_file:
while True:
chunk = binary_file.read(8)
if len(chunk) < 8:
break
if extended_func:
a = extended_func(chunk)
else:
a = GFX_LOOKUP.get(chunk[0], unsupported_gfx_call)(chunk)
c_file.write(a)
def main():
parser = ArgumentParser(
description="Converts a binary file into gfx calls"
)
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")
args = parser.parse_args()
convert_binary_to_gfx_c_source(args.src_path, args.dest_path)
if __name__ == "__main__":
main()