diff --git a/include/libultraship/libultra/types.h b/include/libultraship/libultra/types.h index 0a36c28..bbe6f24 100644 --- a/include/libultraship/libultra/types.h +++ b/include/libultraship/libultra/types.h @@ -40,7 +40,7 @@ typedef union { u16 fracPart[4][4]; }; long long int forc_structure_alignment; -} Mtx; +} MtxS; typedef float MtxF_t[4][4]; typedef union { @@ -50,4 +50,10 @@ typedef union { }; } MtxF; +#ifndef GBI_FLOATS +typedef MtxS Mtx; +#else +typedef MtxF Mtx; +#endif + #endif diff --git a/src/graphic/Fast3D/f3dex.h b/src/graphic/Fast3D/f3dex.h new file mode 100644 index 0000000..0b9eb6b --- /dev/null +++ b/src/graphic/Fast3D/f3dex.h @@ -0,0 +1,152 @@ +#pragma once + +#define G_IMMFIRST -65 + +constexpr int8_t F3DEX_G_SPNOOP = OPCODE(0x0); +constexpr int8_t F3DEX_G_MTX = OPCODE(0x1); +constexpr int8_t F3DEX_G_RESERVED0 = OPCODE(0x2); +constexpr int8_t F3DEX_G_MOVEMEM = OPCODE(0x3); +constexpr int8_t F3DEX_G_VTX = OPCODE(0x4); +constexpr int8_t F3DEX_G_RESERVED1 = OPCODE(0x5); +constexpr int8_t F3DEX_G_DL = OPCODE(0x6); +constexpr int8_t F3DEX_G_RESERVED2 = OPCODE(0x7); +constexpr int8_t F3DEX_G_RESERVED3 = OPCODE(0x8); +constexpr int8_t F3DEX_G_TRI1 = OPCODE(G_IMMFIRST - 0); +constexpr int8_t F3DEX_G_CULLDL = OPCODE(G_IMMFIRST - 1); +constexpr int8_t F3DEX_G_POPMTX = OPCODE(G_IMMFIRST - 2); +constexpr int8_t F3DEX_G_MOVEWORD = OPCODE(G_IMMFIRST - 3); +constexpr int8_t F3DEX_G_TEXTURE = OPCODE(G_IMMFIRST - 4); +constexpr int8_t F3DEX_G_SETOTHERMODE_H = OPCODE(G_IMMFIRST - 5); +constexpr int8_t F3DEX_G_SETOTHERMODE_L = OPCODE(G_IMMFIRST - 6); +constexpr int8_t F3DEX_G_ENDDL = OPCODE(G_IMMFIRST - 7); +constexpr int8_t F3DEX_G_SETGEOMETRYMODE = OPCODE(G_IMMFIRST - 8); +constexpr int8_t F3DEX_G_CLEARGEOMETRYMODE = OPCODE(G_IMMFIRST - 9); +constexpr int8_t F3DEX_G_LINE3D = OPCODE(G_IMMFIRST - 10); +constexpr int8_t F3DEX_G_RDPHALF_1 = OPCODE(G_IMMFIRST - 11); +constexpr int8_t F3DEX_G_RDPHALF_2 = OPCODE(G_IMMFIRST - 12); +constexpr int8_t F3DEX_G_MODIFYVTX = OPCODE(G_IMMFIRST - 13); +constexpr int8_t F3DEX_G_RDPHALF_CONT = OPCODE(G_IMMFIRST - 13); +constexpr int8_t F3DEX_G_TRI2 = OPCODE(G_IMMFIRST - 14); +constexpr int8_t F3DEX_G_BRANCH_Z = OPCODE(G_IMMFIRST - 15); +constexpr int8_t F3DEX_G_LOAD_UCODE = OPCODE(G_IMMFIRST - 16); + +// S2DEX +constexpr int8_t F3DEX_G_SPRITE2D_BASE = OPCODE(9); +constexpr int8_t F3DEX_G_SPRITE2D_SCALEFLIP = OPCODE(G_IMMFIRST - 1); +constexpr int8_t F3DEX_G_SPRITE2D_DRAW = OPCODE(G_IMMFIRST - 2); +constexpr int8_t F3DEX_G_NOOP = OPCODE(0xc0); + +/* + * G_MTX: parameter flags + */ +constexpr int8_t F3DEX_G_MTX_MODELVIEW = 0x00; +constexpr int8_t F3DEX_G_MTX_PROJECTION = 0x01; +constexpr int8_t F3DEX_G_MTX_MUL = 0x00; +constexpr int8_t F3DEX_G_MTX_LOAD = 0x02; +constexpr int8_t F3DEX_G_MTX_NOPUSH = 0x00; +constexpr int8_t F3DEX_G_MTX_PUSH = 0x04; + +/* + * flags for G_SETGEOMETRYMODE + * (this rendering state is maintained in RSP) + * + * DO NOT USE THE LOW 8 BITS OF GEOMETRYMODE: + * The weird bit-ordering is for the micro-code: the lower byte + * can be OR'd in with G_TRI_SHADE (11001100) to construct + * the triangle command directly. Don't break it... + * + * DO NOT USE THE HIGH 8 BITS OF GEOMETRYMODE: + * The high byte is OR'd with 0x703 to form the clip code mask. + * If it is set to 0x04, this will cause near clipping to occur. + * If it is zero, near clipping will not occur. + * + * Further explanation: + * G_SHADE is necessary in order to see the color that you passed + * down with the vertex. If G_SHADE isn't set, you need to set the DP + * appropriately and use primcolor to see anything. + * + * G_SHADING_SMOOTH enabled means use all 3 colors of the triangle. + * If it is not set, then do 'flat shading', where only one vertex color + * is used (and all 3 vertices are set to that same color by the ucode) + * See the man page for gSP1Triangle(). + * + */ + +constexpr int32_t F3DEX_G_CLIPPING = 0x00800000; +constexpr int32_t F3DEX_G_TEXTURE_ENABLE = 0x00000002; +constexpr int32_t F3DEX_G_SHADING_SMOOTH = 0x00000200; +constexpr int32_t F3DEX_G_CULL_FRONT = 0x00001000; +constexpr int32_t F3DEX_G_CULL_BACK = 0x00002000; +constexpr int32_t F3DEX_G_CULL_BOTH = 0x00003000; + +/* + * MOVEMEM indices + * + * Each of these indexes an entry in a dmem table + * which points to a 1-4 word block of dmem in + * which to store a 1-4 word DMA. + * + */ +constexpr int8_t F3DEX_G_MV_VIEWPORT = 0x80; +constexpr int8_t F3DEX_G_MV_LOOKATY = 0x82; +constexpr int8_t F3DEX_G_MV_LOOKATX = 0x84; +constexpr int8_t F3DEX_G_MV_L0 = 0x86; +constexpr int8_t F3DEX_G_MV_L1 = 0x88; +constexpr int8_t F3DEX_G_MV_L2 = 0x8a; +constexpr int8_t F3DEX_G_MV_L3 = 0x8c; +constexpr int8_t F3DEX_G_MV_L4 = 0x8e; +constexpr int8_t F3DEX_G_MV_L5 = 0x90; +constexpr int8_t F3DEX_G_MV_L6 = 0x92; +constexpr int8_t F3DEX_G_MV_L7 = 0x94; +constexpr int8_t F3DEX_G_MV_TXTATT = 0x96; +constexpr int8_t F3DEX_G_MV_MATRIX_1 = 0x9e; +constexpr int8_t F3DEX_G_MV_MATRIX_2 = 0x98; +constexpr int8_t F3DEX_G_MV_MATRIX_3 = 0x9a; +constexpr int8_t F3DEX_G_MV_MATRIX_4 = 0x9c; + +/* + * MOVEWORD indices + * + * Each of these indexes an entry in a dmem table + * which points to a word in dmem in dmem where + * an immediate word will be stored. + * + */ +constexpr int8_t F3DEX_G_MW_POINTS = 0x0c; + +/* + * These are offsets from the address in the dmem table + */ + +constexpr int8_t F3DEX_G_MWO_aLIGHT_2 = 0x20; +constexpr int8_t F3DEX_G_MWO_bLIGHT_2 = 0x24; +constexpr int8_t F3DEX_G_MWO_aLIGHT_3 = 0x40; +constexpr int8_t F3DEX_G_MWO_bLIGHT_3 = 0x44; +constexpr int8_t F3DEX_G_MWO_aLIGHT_4 = 0x60; +constexpr int8_t F3DEX_G_MWO_bLIGHT_4 = 0x64; +constexpr int8_t F3DEX_G_MWO_aLIGHT_5 = 0x80; +constexpr int8_t F3DEX_G_MWO_bLIGHT_5 = 0x84; +constexpr int8_t F3DEX_G_MWO_aLIGHT_6 = 0xa0; +constexpr int8_t F3DEX_G_MWO_bLIGHT_6 = 0xa4; +constexpr int8_t F3DEX_G_MWO_aLIGHT_7 = 0xc0; +constexpr int8_t F3DEX_G_MWO_bLIGHT_7 = 0xc4; +constexpr int8_t F3DEX_G_MWO_aLIGHT_8 = 0xe0; +constexpr int8_t F3DEX_G_MWO_bLIGHT_8 = 0xe4; + +/*===========================================================================* + * GBI Commands for S2DEX microcode + *===========================================================================*/ +/* GBI Header */ +constexpr int8_t F3DEX_G_BG_1CYC = OPCODE(0x01); +constexpr int8_t F3DEX_G_BG_COPY = OPCODE(0x02); +constexpr int8_t F3DEX_G_OBJ_RECTANGLE = OPCODE(0x03); +constexpr int8_t F3DEX_G_OBJ_SPRITE = OPCODE(0x04); +constexpr int8_t F3DEX_G_OBJ_MOVEMEM = OPCODE(0x05); +constexpr int8_t F3DEX_G_SELECT_DL = OPCODE(0xb0); +constexpr int8_t F3DEX_G_OBJ_RENDERMODE = OPCODE(0xb1); +constexpr int8_t F3DEX_G_OBJ_RECTANGLE_R = OPCODE(0xb2); +constexpr int8_t F3DEX_G_OBJ_LOADTXTR = OPCODE(0xc1); +constexpr int8_t F3DEX_G_OBJ_LDTX_SPRITE = OPCODE(0xc2); +constexpr int8_t F3DEX_G_OBJ_LDTX_RECT = OPCODE(0xc3); +constexpr int8_t F3DEX_G_OBJ_LDTX_RECT_R = OPCODE(0xc4); +constexpr int8_t F3DEX_G_RDPHALF_0 = OPCODE(0xe4); \ No newline at end of file diff --git a/src/graphic/Fast3D/f3dex2.h b/src/graphic/Fast3D/f3dex2.h new file mode 100644 index 0000000..dd947ef --- /dev/null +++ b/src/graphic/Fast3D/f3dex2.h @@ -0,0 +1,149 @@ +#pragma once + +constexpr int8_t F3DEX2_G_NOOP = OPCODE(0x00); +constexpr int8_t F3DEX2_G_RDPHALF_2 = OPCODE(0xf1); +constexpr int8_t F3DEX2_G_SETOTHERMODE_H = OPCODE(0xe3); +constexpr int8_t F3DEX2_G_SETOTHERMODE_L = OPCODE(0xe2); +constexpr int8_t F3DEX2_G_RDPHALF_1 = OPCODE(0xe1); +constexpr int8_t F3DEX2_G_SPNOOP = OPCODE(0xe0); +constexpr int8_t F3DEX2_G_ENDDL = OPCODE(0xdf); +constexpr int8_t F3DEX2_G_DL = OPCODE(0xde); +constexpr int8_t F3DEX2_G_LOAD_UCODE = OPCODE(0xdd); +constexpr int8_t F3DEX2_G_MOVEMEM = OPCODE(0xdc); +constexpr int8_t F3DEX2_G_MOVEWORD = OPCODE(0xdb); +constexpr int8_t F3DEX2_G_MTX = OPCODE(0xda); +constexpr int8_t F3DEX2_G_GEOMETRYMODE = OPCODE(0xd9); +constexpr int8_t F3DEX2_G_POPMTX = OPCODE(0xd8); +constexpr int8_t F3DEX2_G_TEXTURE = OPCODE(0xd7); +constexpr int8_t F3DEX2_G_DMA_IO = OPCODE(0xd6); +constexpr int8_t F3DEX2_G_SPECIAL_1 = OPCODE(0xd5); +constexpr int8_t F3DEX2_G_SPECIAL_2 = OPCODE(0xd4); +constexpr int8_t F3DEX2_G_SPECIAL_3 = OPCODE(0xd3); + +constexpr int8_t F3DEX2_G_VTX = OPCODE(0x01); +constexpr int8_t F3DEX2_G_MODIFYVTX = OPCODE(0x02); +constexpr int8_t F3DEX2_G_CULLDL = OPCODE(0x03); +constexpr int8_t F3DEX2_G_BRANCH_Z = OPCODE(0x04); +constexpr int8_t F3DEX2_G_TRI1 = OPCODE(0x05); +constexpr int8_t F3DEX2_G_TRI2 = OPCODE(0x06); +constexpr int8_t F3DEX2_G_QUAD = OPCODE(0x07); +constexpr int8_t F3DEX2_G_LINE3D = OPCODE(0x08); + +/* + * G_MTX: parameter flags + */ +constexpr int8_t F3DEX2_G_MTX_MODELVIEW = 0x00; +constexpr int8_t F3DEX2_G_MTX_PROJECTION = 0x04; +constexpr int8_t F3DEX2_G_MTX_MUL = 0x00; +constexpr int8_t F3DEX2_G_MTX_LOAD = 0x02; +constexpr int8_t F3DEX2_G_MTX_NOPUSH = 0x00; +constexpr int8_t F3DEX2_G_MTX_PUSH = 0x01; + +/* + * flags for G_SETGEOMETRYMODE + * (this rendering state is maintained in RSP) + * + * DO NOT USE THE LOW 8 BITS OF GEOMETRYMODE: + * The weird bit-ordering is for the micro-code: the lower byte + * can be OR'd in with G_TRI_SHADE (11001100) to construct + * the triangle command directly. Don't break it... + * + * DO NOT USE THE HIGH 8 BITS OF GEOMETRYMODE: + * The high byte is OR'd with 0x703 to form the clip code mask. + * If it is set to 0x04, this will cause near clipping to occur. + * If it is zero, near clipping will not occur. + * + * Further explanation: + * G_SHADE is necessary in order to see the color that you passed + * down with the vertex. If G_SHADE isn't set, you need to set the DP + * appropriately and use primcolor to see anything. + * + * G_SHADING_SMOOTH enabled means use all 3 colors of the triangle. + * If it is not set, then do 'flat shading', where only one vertex color + * is used (and all 3 vertices are set to that same color by the ucode) + * See the man page for gSP1Triangle(). + * + */ +constexpr int32_t F3DEX2_G_CLIPPING = 0x00800000; +constexpr int32_t F3DEX2_G_TEXTURE_ENABLE = 0x00000000; +constexpr int32_t F3DEX2_G_SHADING_SMOOTH = 0x00200000; +constexpr int32_t F3DEX2_G_CULL_FRONT = 0x00000200; +constexpr int32_t F3DEX2_G_CULL_BACK = 0x00000400; +constexpr int32_t F3DEX2_G_CULL_BOTH = 0x00000600; + +/* + * MOVEMEM indices + * + * Each of these indexes an entry in a dmem table + * which points to a 1-4 word block of dmem in + * which to store a 1-4 word DMA. + * + */ +constexpr int8_t F3DEX2_G_MV_MMTX = 2; +constexpr int8_t F3DEX2_G_MV_PMTX = 6; +constexpr int8_t F3DEX2_G_MV_VIEWPORT = 8; +constexpr int8_t F3DEX2_G_MV_LIGHT = 10; +constexpr int8_t F3DEX2_G_MV_POINT = 12; +constexpr int8_t F3DEX2_G_MV_MATRIX = 14; +constexpr int8_t F3DEX2_G_MVO_LOOKATX = 0 * 24; +constexpr int8_t F3DEX2_G_MVO_LOOKATY = 1 * 24; +constexpr int8_t F3DEX2_G_MVO_L0 = 2 * 24; +constexpr int8_t F3DEX2_G_MVO_L1 = 3 * 24; +constexpr int8_t F3DEX2_G_MVO_L2 = 4 * 24; +constexpr int8_t F3DEX2_G_MVO_L3 = 5 * 24; +constexpr int8_t F3DEX2_G_MVO_L4 = 6 * 24; +constexpr int8_t F3DEX2_G_MVO_L5 = 7 * 24; +constexpr int8_t F3DEX2_G_MVO_L6 = 8 * 24; +constexpr int8_t F3DEX2_G_MVO_L7 = 9 * 24; + +/* + * MOVEWORD indices + * + * Each of these indexes an entry in a dmem table + * which points to a word in dmem in dmem where + * an immediate word will be stored. + * + */ +constexpr int8_t F3DEX2_G_MW_FORCEMTX = 0x0c; + +/* + * MOVEWORD indices + * + * Each of these indexes an entry in a dmem table + * which points to a word in dmem in dmem where + * an immediate word will be stored. + * + * These are offsets from the address in the dmem table + */ +constexpr int8_t F3DEX2_G_MWO_aLIGHT_2 = 0x18; +constexpr int8_t F3DEX2_G_MWO_bLIGHT_2 = 0x1c; +constexpr int8_t F3DEX2_G_MWO_aLIGHT_3 = 0x30; +constexpr int8_t F3DEX2_G_MWO_bLIGHT_3 = 0x34; +constexpr int8_t F3DEX2_G_MWO_aLIGHT_4 = 0x48; +constexpr int8_t F3DEX2_G_MWO_bLIGHT_4 = 0x4c; +constexpr int8_t F3DEX2_G_MWO_aLIGHT_5 = 0x60; +constexpr int8_t F3DEX2_G_MWO_bLIGHT_5 = 0x64; +constexpr int8_t F3DEX2_G_MWO_aLIGHT_6 = 0x78; +constexpr int8_t F3DEX2_G_MWO_bLIGHT_6 = 0x7c; +constexpr int8_t F3DEX2_G_MWO_aLIGHT_7 = 0x90; +constexpr int8_t F3DEX2_G_MWO_bLIGHT_7 = 0x94; +constexpr int8_t F3DEX2_G_MWO_aLIGHT_8 = 0xa8; +constexpr int8_t F3DEX2_G_MWO_bLIGHT_8 = 0xac; + +/*===========================================================================* + * GBI Commands for S2DEX microcode + *===========================================================================*/ +/* GBI Header */ +constexpr int8_t F3DEX2_G_OBJ_RECTANGLE_R = OPCODE(0xda); +constexpr int8_t F3DEX2_G_OBJ_MOVEMEM = OPCODE(0xdc); +constexpr int8_t F3DEX2_G_RDPHALF_0 = OPCODE(0xe4); +constexpr int8_t F3DEX2_G_OBJ_RECTANGLE = OPCODE(0x01); +constexpr int8_t F3DEX2_G_OBJ_SPRITE = OPCODE(0x02); +constexpr int8_t F3DEX2_G_SELECT_DL = OPCODE(0x04); +constexpr int8_t F3DEX2_G_OBJ_LOADTXTR = OPCODE(0x05); +constexpr int8_t F3DEX2_G_OBJ_LDTX_SPRITE = OPCODE(0x06); +constexpr int8_t F3DEX2_G_OBJ_LDTX_RECT = OPCODE(0x07); +constexpr int8_t F3DEX2_G_OBJ_LDTX_RECT_R = OPCODE(0x08); +constexpr int8_t F3DEX2_G_BG_1CYC = OPCODE(0x09); +constexpr int8_t F3DEX2_G_BG_COPY = OPCODE(0x0a); +constexpr int8_t F3DEX2_G_OBJ_RENDERMODE = OPCODE(0x0b); \ No newline at end of file diff --git a/src/graphic/Fast3D/gfx_pc.cpp b/src/graphic/Fast3D/gfx_pc.cpp index 07e861e..52aadf1 100644 --- a/src/graphic/Fast3D/gfx_pc.cpp +++ b/src/graphic/Fast3D/gfx_pc.cpp @@ -147,7 +147,27 @@ struct MaskedTextureEntry { static map masked_textures; -static UcodeHandlers ucode_handler_index = UcodeHandlers::ucode_f3dex2; +static UcodeHandlers ucode_handler_index = ucode_f3dex2; + +const static std::unordered_map f3dex2AttrHandler = { + { MTX_PROJECTION, F3DEX2_G_MTX_PROJECTION }, { MTX_LOAD, F3DEX2_G_MTX_LOAD }, { MTX_PUSH, F3DEX2_G_MTX_PUSH }, + { MTX_NOPUSH, F3DEX_G_MTX_NOPUSH }, { CULL_FRONT, F3DEX2_G_CULL_FRONT }, { CULL_BACK, F3DEX2_G_CULL_BACK }, + { CULL_BOTH, F3DEX2_G_CULL_BOTH }, { MV_VIEWPORT, F3DEX2_G_MOVEMEM }, { MV_LIGHT, F3DEX2_G_MOVEMEM } +}; + +const static std::unordered_map f3dexAttrHandler = { + { MTX_PROJECTION, F3DEX_G_MTX_PROJECTION }, { MTX_LOAD, F3DEX_G_MTX_LOAD }, { MTX_PUSH, F3DEX_G_MTX_PUSH }, + { MTX_NOPUSH, F3DEX_G_MTX_NOPUSH }, { CULL_FRONT, F3DEX_G_CULL_FRONT }, { CULL_BACK, F3DEX_G_CULL_BACK }, + { CULL_BOTH, F3DEX_G_CULL_BOTH }, { MV_VIEWPORT, F3DEX_G_MOVEMEM }, { MV_LIGHT, F3DEX_G_MOVEMEM } +}; + +static constexpr std::array*, ucode_max> ucode_attr_handlers = { + &f3dexAttrHandler, &f3dexAttrHandler, &f3dex2AttrHandler +}; + +static int8_t get_attr(Attribute attr) { + return ucode_attr_handlers[ucode_handler_index]->at(attr); +} static std::string GetPathWithoutFileName(char* filePath) { size_t len = strlen(filePath); @@ -1068,19 +1088,23 @@ static void gfx_sp_matrix(uint8_t parameters, const int32_t* addr) { #endif } - if (parameters & G_MTX_PROJECTION) { - if (parameters & G_MTX_LOAD) { + const int8_t mtx_projection = get_attr(MTX_PROJECTION); + const int8_t mtx_load = get_attr(MTX_LOAD); + const int8_t mtx_push = get_attr(MTX_PUSH); + + if (parameters & mtx_projection) { + if (parameters & mtx_load) { memcpy(g_rsp.P_matrix, matrix, sizeof(matrix)); } else { gfx_matrix_mul(g_rsp.P_matrix, matrix, g_rsp.P_matrix); } } else { // G_MTX_MODELVIEW - if ((parameters & G_MTX_PUSH) && g_rsp.modelview_matrix_stack_size < 11) { + if ((parameters & mtx_push) && g_rsp.modelview_matrix_stack_size < 11) { ++g_rsp.modelview_matrix_stack_size; memcpy(g_rsp.modelview_matrix_stack[g_rsp.modelview_matrix_stack_size - 1], g_rsp.modelview_matrix_stack[g_rsp.modelview_matrix_stack_size - 2], sizeof(matrix)); } - if (parameters & G_MTX_LOAD) { + if (parameters & mtx_load) { if (g_rsp.modelview_matrix_stack_size == 0) ++g_rsp.modelview_matrix_stack_size; memcpy(g_rsp.modelview_matrix_stack[g_rsp.modelview_matrix_stack_size - 1], matrix, sizeof(matrix)); @@ -1341,7 +1365,11 @@ static void gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t vtx3_idx, bo return; } - if ((g_rsp.geometry_mode & G_CULL_BOTH) != 0) { + const int32_t cull_both = get_attr(CULL_BOTH); + const int32_t cull_front = get_attr(CULL_FRONT); + const int32_t cull_back = get_attr(CULL_BACK); + + if ((g_rsp.geometry_mode & cull_both) != 0) { float dx1 = v1->x / (v1->w) - v2->x / (v2->w); float dy1 = v1->y / (v1->w) - v2->y / (v2->w); float dx2 = v3->x / (v3->w) - v2->x / (v2->w); @@ -1359,20 +1387,19 @@ static void gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t vtx3_idx, bo cross = -cross; } - switch (g_rsp.geometry_mode & G_CULL_BOTH) { - case G_CULL_FRONT: - if (cross <= 0) { - return; - } - break; - case G_CULL_BACK: - if (cross >= 0) { - return; - } - break; - case G_CULL_BOTH: - // Why is this even an option? + auto cull_type = g_rsp.geometry_mode & cull_both; + + if (cull_type == cull_front) { + if (cross <= 0) { return; + } + } else if (cull_type == cull_back) { + if (cross >= 0) { + return; + } + } else if (cull_type == cull_both) { + // Why is this even an option? + return; } } @@ -1795,10 +1822,10 @@ static void gfx_calc_and_set_viewport(const F3DVp_t* viewport) { static void gfx_sp_movemem_f3dex2(uint8_t index, uint8_t offset, const void* data) { switch (index) { - case G_MV_VIEWPORT: + case F3DEX2_G_MV_VIEWPORT: gfx_calc_and_set_viewport((const F3DVp_t*)data); break; - case G_MV_LIGHT: { + case F3DEX2_G_MV_LIGHT: { int lightidx = offset / 24 - 2; if (lightidx >= 0 && lightidx <= MAX_LIGHTS) { // skip lookat // NOTE: reads out of bounds if it is an ambient light @@ -1811,21 +1838,21 @@ static void gfx_sp_movemem_f3dex2(uint8_t index, uint8_t offset, const void* dat } } -// TODO remove these when headers are handled differently -#define G_MV_L0 0x86 -#define G_MV_L1 0x88 -#define G_MV_L2 0x8a - static void gfx_sp_movemem_f3d(uint8_t index, uint8_t offset, const void* data) { switch (index) { - case G_MV_VIEWPORT: + case F3DEX_G_MV_VIEWPORT: gfx_calc_and_set_viewport((const F3DVp_t*)data); break; - case G_MV_L0: - case G_MV_L1: - case G_MV_L2: + case F3DEX_G_MV_L0: + case F3DEX_G_MV_L1: + case F3DEX_G_MV_L2: + case F3DEX_G_MV_L3: + case F3DEX_G_MV_L4: + case F3DEX_G_MV_L5: + case F3DEX_G_MV_L6: + case F3DEX_G_MV_L7: // NOTE: reads out of bounds if it is an ambient light - memcpy(g_rsp.current_lights + (index - G_MV_L0) / 2, data, sizeof(F3DLight_t)); + memcpy(g_rsp.current_lights + (index - F3DEX_G_MV_L0) / 2, data, sizeof(F3DLight_t)); break; } } @@ -2699,7 +2726,7 @@ bool gfx_mtx_handler_f3dex2(F3DGfx** cmd0) { mtxAddr = clearMtx; } - gfx_sp_matrix(C0(0, 8) ^ G_MTX_PUSH, (const int32_t*)seg_addr(mtxAddr)); + gfx_sp_matrix(C0(0, 8) ^ F3DEX2_G_MTX_PUSH, (const int32_t*)seg_addr(mtxAddr)); return false; } @@ -2732,7 +2759,7 @@ bool gfx_mtx_otr_handler_custom_f3dex2(F3DGfx** cmd0) { if (mtx != NULL) { cmd--; - gfx_sp_matrix(C0(0, 8) ^ G_MTX_PUSH, mtx); + gfx_sp_matrix(C0(0, 8) ^ F3DEX2_G_MTX_PUSH, mtx); cmd++; } @@ -3120,6 +3147,20 @@ bool gfx_othermode_h_handler_f3dex2(F3DGfx** cmd0) { return false; } +// Only on F3DEX and older +bool gfx_set_geometry_mode_handler_f3dex(F3DGfx** cmd0) { + F3DGfx* cmd = *cmd0; + gfx_sp_geometry_mode(0, (uint32_t)cmd->words.w1); + return false; +} + +// Only on F3DEX and older +bool gfx_clear_geometry_mode_handler_f3dex(F3DGfx** cmd0) { + F3DGfx* cmd = *cmd0; + gfx_sp_geometry_mode((uint32_t)cmd->words.w1, 0); + return false; +} + bool gfx_othermode_h_handler_f3d(F3DGfx** cmd0) { F3DGfx* cmd = *cmd0; @@ -3624,14 +3665,9 @@ const static std::unordered_map> f3dexHandlers = { + { F3DEX_G_NOOP, { "G_NOOP", gfx_noop_handler_f3dex2 } }, + { F3DEX_G_CULLDL, { "G_CULLDL", gfx_cull_dl_handler_f3dex2 } }, + { F3DEX_G_MTX, { "G_MTX", gfx_mtx_handler_f3d } }, + { F3DEX_G_POPMTX, { "G_POPMTX", gfx_pop_mtx_handler_f3d } }, + { F3DEX_G_MOVEMEM, { "G_POPMEM", gfx_movemem_handler_f3d } }, + { F3DEX_G_MOVEWORD, { "G_MOVEWORD", gfx_moveword_handler_f3d } }, + { F3DEX_G_TEXTURE, { "G_TEXTURE", gfx_texture_handler_f3d } }, + { F3DEX_G_SETOTHERMODE_L, { "G_SETOTHERMODE_L", gfx_othermode_l_handler_f3d } }, + { F3DEX_G_SETOTHERMODE_H, { "G_SETOTHERMODE_H", gfx_othermode_h_handler_f3d } }, + { F3DEX_G_SETGEOMETRYMODE, { "G_SETGEOMETRYMODE", gfx_set_geometry_mode_handler_f3dex } }, + { F3DEX_G_CLEARGEOMETRYMODE, { "G_CLEARGEOMETRYMODE", gfx_clear_geometry_mode_handler_f3dex } }, + { F3DEX_G_VTX, { "G_VTX", gfx_vtx_handler_f3dex } }, + { F3DEX_G_TRI1, { "G_TRI1", gfx_tri1_handler_f3dex } }, + { F3DEX_G_MODIFYVTX, { "G_MODIFYVTX", gfx_modify_vtx_handler_f3dex2 } }, + { F3DEX_G_DL, { "G_DL", gfx_dl_handler_common } }, + { F3DEX_G_ENDDL, { "G_ENDDL", gfx_end_dl_handler_common } }, + { F3DEX_G_TRI2, { "G_TRI2", gfx_tri2_handler_f3dex } }, + { F3DEX_G_SPNOOP, { "G_SPNOOP", gfx_spnoop_command_handler_f3dex2 } }, + { F3DEX_G_RDPHALF_1, { "G_RDPHALF_1", gfx_stubbed_command_handler } }, + { OTR_G_MTX_OTR2, { "G_MTX_OTR2", gfx_mtx_otr_handler_custom_f3d } } // G_MTX_OTR2 (0x29) Is this the right code? +}; + +const static std::unordered_map> f3dHandlers = { + { F3DEX_G_NOOP, { "G_NOOP", gfx_noop_handler_f3dex2 } }, + { F3DEX_G_CULLDL, { "G_CULLDL", gfx_cull_dl_handler_f3dex2 } }, + { F3DEX_G_MTX, { "G_MTX", gfx_mtx_handler_f3d } }, + { F3DEX_G_POPMTX, { "G_POPMTX", gfx_pop_mtx_handler_f3d } }, + { F3DEX_G_MOVEMEM, { "G_POPMEM", gfx_movemem_handler_f3d } }, + { F3DEX_G_MOVEWORD, { "G_MOVEWORD", gfx_moveword_handler_f3d } }, + { F3DEX_G_TEXTURE, { "G_TEXTURE", gfx_texture_handler_f3d } }, + { F3DEX_G_SETOTHERMODE_L, { "G_SETOTHERMODE_L", gfx_othermode_l_handler_f3d } }, + { F3DEX_G_SETOTHERMODE_H, { "G_SETOTHERMODE_H", gfx_othermode_h_handler_f3d } }, + { F3DEX_G_SETGEOMETRYMODE, { "G_SETGEOMETRYMODE", gfx_set_geometry_mode_handler_f3dex } }, + { F3DEX_G_CLEARGEOMETRYMODE, { "G_CLEARGEOMETRYMODE", gfx_clear_geometry_mode_handler_f3dex } }, + { F3DEX_G_VTX, { "G_VTX", gfx_vtx_handler_f3d } }, + { F3DEX_G_TRI1, { "G_TRI1", gfx_tri1_handler_f3d } }, + { F3DEX_G_MODIFYVTX, { "G_MODIFYVTX", gfx_modify_vtx_handler_f3dex2 } }, + { F3DEX_G_DL, { "G_DL", gfx_dl_handler_common } }, + { F3DEX_G_ENDDL, { "G_ENDDL", gfx_end_dl_handler_common } }, + { F3DEX_G_TRI2, { "G_TRI2", gfx_tri2_handler_f3dex } }, + { F3DEX_G_SPNOOP, { "G_SPNOOP", gfx_spnoop_command_handler_f3dex2 } }, + { F3DEX_G_RDPHALF_1, { "G_RDPHALF_1", gfx_stubbed_command_handler } } }; // LUSTODO: These S2DEX commands have different opcode numbers on F3DEX2 vs other ucodes. More research needs to be done @@ -3684,19 +3755,23 @@ const static std::unordered_map>*, - UcodeHandlers::ucode_max> - ucode_handlers = { - &f3dex2Handlers, - &s2dexHandlers, - }; +static constexpr std::array ucode_handlers = { + &f3dHandlers, + &f3dexHandlers, + &f3dex2Handlers, + &s2dexHandlers, +}; const char* GfxGetOpcodeName(int8_t opcode) { if (otrHandlers.contains(opcode)) { return otrHandlers.at(opcode).first; - } else if (rdpHandlers.contains(opcode)) { + } + + if (rdpHandlers.contains(opcode)) { return rdpHandlers.at(opcode).first; - } else if (ucode_handler_index < ucode_handlers.size()) { + } + + if (ucode_handler_index < ucode_handlers.size()) { if (ucode_handlers[ucode_handler_index]->contains(opcode)) { return ucode_handlers[ucode_handler_index]->at(opcode).first; } else { @@ -3719,7 +3794,7 @@ static void gfx_step() { auto cmd0 = cmd; int8_t opcode = (int8_t)(cmd->words.w0 >> 24); - if (opcode == (int8_t)G_LOAD_UCODE) { + if (opcode == F3DEX2_G_LOAD_UCODE) { gfx_set_ucode_handler((UcodeHandlers)(cmd->words.w0 & 0xFFFFFF)); ++cmd; return; diff --git a/src/graphic/Fast3D/gfx_pc.h b/src/graphic/Fast3D/gfx_pc.h index 2ee9e10..6da74a6 100644 --- a/src/graphic/Fast3D/gfx_pc.h +++ b/src/graphic/Fast3D/gfx_pc.h @@ -193,6 +193,18 @@ struct RDP { void* color_image_address; }; +typedef enum Attribute { + MTX_PROJECTION, + MTX_LOAD, + MTX_PUSH, + MTX_NOPUSH, + CULL_FRONT, + CULL_BACK, + CULL_BOTH, + MV_VIEWPORT, + MV_LIGHT, +}; + extern RDP g_rdp; extern RSP g_rsp; diff --git a/src/graphic/Fast3D/lus_gbi.h b/src/graphic/Fast3D/lus_gbi.h index 25a4bbc..6c3ced1 100644 --- a/src/graphic/Fast3D/lus_gbi.h +++ b/src/graphic/Fast3D/lus_gbi.h @@ -1,157 +1,69 @@ #pragma once #include -/* To enable Fast3DEX grucode support, define F3DEX_GBI. */ +#define OPCODE(x) (int8_t)(x) -/* Types */ - -/* Private macro to wrap other macros in do {...} while (0) */ -#define _DW(macro) \ - do { \ - macro \ - } while (0) - -#define F3DEX_GBI_2 - -#ifdef F3DEX_GBI_2 -#ifndef F3DEX_GBI -#define F3DEX_GBI -#endif -constexpr int8_t F3DEX2_G_NOOP = (int8_t)0x00; -constexpr int8_t F3DEX2_G_RDPHALF_2 = (int8_t)0xf1; -constexpr int8_t F3DEX2_G_SETOTHERMODE_H = (int8_t)0xe3; -constexpr int8_t F3DEX2_G_SETOTHERMODE_L = (int8_t)0xe2; -constexpr int8_t F3DEX2_G_RDPHALF_1 = (int8_t)0xe1; -constexpr int8_t F3DEX2_G_SPNOOP = (int8_t)0xe0; -constexpr int8_t F3DEX2_G_ENDDL = (int8_t)0xdf; -constexpr int8_t F3DEX2_G_DL = (int8_t)0xde; -#define G_LOAD_UCODE 0xdd -constexpr int8_t F3DEX2_G_MOVEMEM = (int8_t)0xdc; -constexpr int8_t F3DEX2_G_MOVEWORD = (int8_t)0xdb; -constexpr int8_t F3DEX2_G_MTX = (int8_t)0xda; -constexpr int8_t F3DEX2_G_GEOMETRYMODE = (int8_t)0xd9; -constexpr int8_t F3DEX2_G_POPMTX = (int8_t)0xd8; -constexpr int8_t F3DEX2_G_TEXTURE = (int8_t)0xd7; -#define G_DMA_IO 0xd6 -#define G_SPECIAL_1 0xd5 -#define G_SPECIAL_2 0xd4 -#define G_SPECIAL_3 0xd3 - -constexpr int8_t F3DEX2_G_VTX = (int8_t)0x01; -constexpr int8_t F3DEX2_G_MODIFYVTX = (int8_t)0x02; -constexpr int8_t F3DEX2_G_CULLDL = (int8_t)0x03; -constexpr int8_t F3DEX2_G_BRANCH_Z = (int8_t)0x04; -constexpr int8_t F3DEX2_G_TRI1 = (int8_t)0x05; -constexpr int8_t F3DEX2_G_TRI2 = (int8_t)0x06; -constexpr int8_t F3DEX2_G_QUAD = (int8_t)0x07; -#define G_LINE3D 0x08 -#else /* F3DEX_GBI_2 */ - -/* DMA commands: */ -#define G_SPNOOP 0 /* handle 0 gracefully */ -#define G_MTX 1 -#define G_RESERVED0 2 /* not implemeted */ -constexpr int8_t G_MOVEMEM 3 /* move a block of memory (up to 4 words) to dmem */ -#define G_VTX 4 -#define G_RESERVED1 5 /* not implemeted */ -#define G_DL 6 -#define G_RESERVED2 7 /* not implemeted */ -#define G_RESERVED3 8 /* not implemeted */ -#define G_SPRITE2D_BASE 9 /* sprite command */ - -/* IMMEDIATE commands: */ -#define G_IMMFIRST -65 -#define G_TRI1 (G_IMMFIRST - 0) -#define G_CULLDL (G_IMMFIRST - 1) -#define G_POPMTX (G_IMMFIRST - 2) - constexpr int8_t G_MOVEWORD = (G_IMMFIRST - 3); -#define G_TEXTURE (G_IMMFIRST - 4) -#define G_SETOTHERMODE_H (G_IMMFIRST - 5) -#define G_SETOTHERMODE_L (G_IMMFIRST - 6) -#define G_ENDDL (G_IMMFIRST - 7) -constexpr int8_t G_SETGEOMETRYMODE = (G_IMMFIRST - 8); -constexpr int8_t G_CLEARGEOMETRYMODE - (G_IMMFIRST - 9); -#define G_LINE3D (G_IMMFIRST - 10) -#define G_RDPHALF_1 (G_IMMFIRST - 11) -#define G_RDPHALF_2 (G_IMMFIRST - 12) -#if (defined(F3DEX_GBI) || defined(F3DLP_GBI)) -#define G_MODIFYVTX (G_IMMFIRST - 13) -#define G_TRI2 (G_IMMFIRST - 14) -#define G_BRANCH_Z (G_IMMFIRST - 15) -#define G_LOAD_UCODE (G_IMMFIRST - 16) -#else -#define G_RDPHALF_CONT (G_IMMFIRST - 13) -#endif - -/* We are overloading 2 of the immediate commands - to keep the byte alignment of dmem the same */ - -#define G_SPRITE2D_SCALEFLIP (G_IMMFIRST - 1) -#define G_SPRITE2D_DRAW (G_IMMFIRST - 2) +#include "f3dex.h" +#include "f3dex2.h" /* RDP commands: */ -#define G_NOOP 0xc0 /* 0 */ - -#endif /* F3DEX_GBI_2 */ - -/* RDP commands: */ -constexpr int8_t RDP_G_SETCIMG = (int8_t)0xff; /* -1 */ -constexpr int8_t RDP_G_SETZIMG = (int8_t)0xfe; /* -2 */ -constexpr int8_t RDP_G_SETTIMG = (int8_t)0xfd; /* -3 */ -constexpr int8_t RDP_G_SETCOMBINE = (int8_t)0xfc; /* -4 */ -constexpr int8_t RDP_G_SETENVCOLOR = (int8_t)0xfb; /* -5 */ -constexpr int8_t RDP_G_SETPRIMCOLOR = (int8_t)0xfa; /* -6 */ -constexpr int8_t RDP_G_SETBLENDCOLOR = (int8_t)0xf9; /* -7 */ -constexpr int8_t RDP_G_SETFOGCOLOR = (int8_t)0xf8; /* -8 */ -constexpr int8_t RDP_G_SETFILLCOLOR = (int8_t)0xf7; /* -9 */ -constexpr int8_t RDP_G_FILLRECT = (int8_t)0xf6; /* -10 */ -constexpr int8_t RDP_G_SETTILE = (int8_t)0xf5; /* -11 */ -constexpr int8_t RDP_G_LOADTILE = (int8_t)0xf4; /* -12 */ -constexpr int8_t RDP_G_LOADBLOCK = (int8_t)0xf3; /* -13 */ -constexpr int8_t RDP_G_SETTILESIZE = (int8_t)0xf2; /* -14 */ -constexpr int8_t RDP_G_LOADTLUT = (int8_t)0xf0; /* -16 */ -constexpr int8_t RDP_G_RDPSETOTHERMODE = (int8_t)0xef; /* -17 */ -constexpr int8_t RDP_G_SETPRIMDEPTH = (int8_t)0xee; /* -18 */ -constexpr int8_t RDP_G_SETSCISSOR = (int8_t)0xed; /* -19 */ -constexpr int8_t RDP_G_SETCONVERT = (int8_t)0xec; /* -20 */ -constexpr int8_t RDP_G_SETKEYR = (int8_t)0xeb; /* -21 */ -constexpr int8_t RDP_G_SETKEYGB = (int8_t)0xea; /* -22 */ -constexpr int8_t RDP_G_RDPFULLSYNC = (int8_t)0xe9; /* -23 */ -constexpr int8_t RDP_G_RDPTILESYNC = (int8_t)0xe8; /* -24 */ -constexpr int8_t RDP_G_RDPPIPESYNC = (int8_t)0xe7; /* -25 */ -constexpr int8_t RDP_G_RDPLOADSYNC = (int8_t)0xe6; /* -26 */ -constexpr int8_t RDP_G_TEXRECTFLIP = (int8_t)0xe5; /* -27 */ -constexpr int8_t RDP_G_TEXRECT = (int8_t)0xe4; /* -28 */ +constexpr int8_t RDP_G_SETCIMG = OPCODE(0xff); /* -1 */ +constexpr int8_t RDP_G_SETZIMG = OPCODE(0xfe); /* -2 */ +constexpr int8_t RDP_G_SETTIMG = OPCODE(0xfd); /* -3 */ +constexpr int8_t RDP_G_SETCOMBINE = OPCODE(0xfc); /* -4 */ +constexpr int8_t RDP_G_SETENVCOLOR = OPCODE(0xfb); /* -5 */ +constexpr int8_t RDP_G_SETPRIMCOLOR = OPCODE(0xfa); /* -6 */ +constexpr int8_t RDP_G_SETBLENDCOLOR = OPCODE(0xf9); /* -7 */ +constexpr int8_t RDP_G_SETFOGCOLOR = OPCODE(0xf8); /* -8 */ +constexpr int8_t RDP_G_SETFILLCOLOR = OPCODE(0xf7); /* -9 */ +constexpr int8_t RDP_G_FILLRECT = OPCODE(0xf6); /* -10 */ +constexpr int8_t RDP_G_SETTILE = OPCODE(0xf5); /* -11 */ +constexpr int8_t RDP_G_LOADTILE = OPCODE(0xf4); /* -12 */ +constexpr int8_t RDP_G_LOADBLOCK = OPCODE(0xf3); /* -13 */ +constexpr int8_t RDP_G_SETTILESIZE = OPCODE(0xf2); /* -14 */ +constexpr int8_t RDP_G_LOADTLUT = OPCODE(0xf0); /* -16 */ +constexpr int8_t RDP_G_RDPSETOTHERMODE = OPCODE(0xef); /* -17 */ +constexpr int8_t RDP_G_SETPRIMDEPTH = OPCODE(0xee); /* -18 */ +constexpr int8_t RDP_G_SETSCISSOR = OPCODE(0xed); /* -19 */ +constexpr int8_t RDP_G_SETCONVERT = OPCODE(0xec); /* -20 */ +constexpr int8_t RDP_G_SETKEYR = OPCODE(0xeb); /* -21 */ +constexpr int8_t RDP_G_SETKEYGB = OPCODE(0xea); /* -22 */ +constexpr int8_t RDP_G_RDPFULLSYNC = OPCODE(0xe9); /* -23 */ +constexpr int8_t RDP_G_RDPTILESYNC = OPCODE(0xe8); /* -24 */ +constexpr int8_t RDP_G_RDPPIPESYNC = OPCODE(0xe7); /* -25 */ +constexpr int8_t RDP_G_RDPLOADSYNC = OPCODE(0xe6); /* -26 */ +constexpr int8_t RDP_G_TEXRECTFLIP = OPCODE(0xe5); /* -27 */ +constexpr int8_t RDP_G_TEXRECT = OPCODE(0xe4); /* -28 */ // CUSTOM OTR COMMANDS -constexpr int8_t OTR_G_SETTIMG_OTR_HASH = (int8_t)0x20; -constexpr int8_t OTR_G_SETFB = (int8_t)0x21; -constexpr int8_t OTR_G_RESETFB = (int8_t)0x22; -constexpr int8_t OTR_G_SETTIMG_FB = (int8_t)0x23; -constexpr int8_t OTR_G_VTX_OTR_FILEPATH = (int8_t)0x24; -constexpr int8_t OTR_G_SETTIMG_OTR_FILEPATH = (int8_t)0x25; -constexpr int8_t OTR_G_TRI1_OTR = (int8_t)0x26; -constexpr int8_t OTR_G_DL_OTR_FILEPATH = (int8_t)0x27; -constexpr int8_t OTR_G_PUSHCD = (int8_t)0x28; -constexpr int8_t OTR_G_MTX_OTR2 = (int8_t)0x29; -constexpr int8_t OTR_G_DL_OTR_HASH = (int8_t)0x31; -constexpr int8_t OTR_G_VTX_OTR_HASH = (int8_t)0x32; -constexpr int8_t OTR_G_MARKER = (int8_t)0x33; -constexpr int8_t OTR_G_INVALTEXCACHE = (int8_t)0x34; -constexpr int8_t OTR_G_BRANCH_Z_OTR = (int8_t)0x35; -constexpr int8_t OTR_G_MTX_OTR = (int8_t)0x36; -constexpr int8_t OTR_G_TEXRECT_WIDE = (int8_t)0x37; -constexpr int8_t OTR_G_FILLWIDERECT = (int8_t)0x38; +constexpr int8_t OTR_G_SETTIMG_OTR_HASH = OPCODE(0x20); +constexpr int8_t OTR_G_SETFB = OPCODE(0x21); +constexpr int8_t OTR_G_RESETFB = OPCODE(0x22); +constexpr int8_t OTR_G_SETTIMG_FB = OPCODE(0x23); +constexpr int8_t OTR_G_VTX_OTR_FILEPATH = OPCODE(0x24); +constexpr int8_t OTR_G_SETTIMG_OTR_FILEPATH = OPCODE(0x25); +constexpr int8_t OTR_G_TRI1_OTR = OPCODE(0x26); +constexpr int8_t OTR_G_DL_OTR_FILEPATH = OPCODE(0x27); +constexpr int8_t OTR_G_PUSHCD = OPCODE(0x28); +constexpr int8_t OTR_G_MTX_OTR2 = OPCODE(0x29); +constexpr int8_t OTR_G_DL_OTR_HASH = OPCODE(0x31); +constexpr int8_t OTR_G_VTX_OTR_HASH = OPCODE(0x32); +constexpr int8_t OTR_G_MARKER = OPCODE(0x33); +constexpr int8_t OTR_G_INVALTEXCACHE = OPCODE(0x34); +constexpr int8_t OTR_G_BRANCH_Z_OTR = OPCODE(0x35); +constexpr int8_t OTR_G_MTX_OTR = OPCODE(0x36); +constexpr int8_t OTR_G_TEXRECT_WIDE = OPCODE(0x37); +constexpr int8_t OTR_G_FILLWIDERECT = OPCODE(0x38); /* GFX Effects */ // RDP Cmd -constexpr int8_t OTR_G_SETGRAYSCALE = (int8_t)0x39; -constexpr int8_t OTR_G_EXTRAGEOMETRYMODE = (int8_t)0x3a; -constexpr int8_t OTR_G_COPYFB = (int8_t)0x3b; -constexpr int8_t OTR_G_IMAGERECT = (int8_t)0x3c; -constexpr int8_t OTR_G_DL_INDEX = (int8_t)0x3d; -constexpr int8_t OTR_G_READFB = (int8_t)0x3e; -constexpr int8_t OTR_G_SETINTENSITY = (int8_t)0x40; +constexpr int8_t OTR_G_SETGRAYSCALE = OPCODE(0x39); +constexpr int8_t OTR_G_EXTRAGEOMETRYMODE = OPCODE(0x3a); +constexpr int8_t OTR_G_COPYFB = OPCODE(0x3b); +constexpr int8_t OTR_G_IMAGERECT = OPCODE(0x3c); +constexpr int8_t OTR_G_DL_INDEX = OPCODE(0x3d); +constexpr int8_t OTR_G_READFB = OPCODE(0x3e); +constexpr int8_t OTR_G_SETINTENSITY = OPCODE(0x40); /* * The following commands are the "generated" RDP commands; the user @@ -212,7 +124,7 @@ constexpr int8_t OTR_G_SETINTENSITY = (int8_t)0x40; /* macros for command parsing: */ #define GDMACMD(x) (x) -#define GIMMCMD(x) (G_IMMFIRST - (x)) +#define GIMMCMD(x) = OPCODE(G_IMMFIRST - (x)) #define GRDPCMD(x) (0xff - (x)) #define G_DMACMDSIZ 128 @@ -245,25 +157,6 @@ constexpr int8_t OTR_G_SETINTENSITY = (int8_t)0x40; #define GPACK_RGBA5551(r, g, b, a) ((((r) << 8) & 0xf800) | (((g) << 3) & 0x7c0) | (((b) >> 2) & 0x3e) | ((a)&0x1)) #define GPACK_ZDZ(z, dz) ((z) << 2 | (dz)) -/* - * G_MTX: parameter flags - */ -#ifdef F3DEX_GBI_2 -#define G_MTX_MODELVIEW 0x00 /* matrix types */ -#define G_MTX_PROJECTION 0x04 -#define G_MTX_MUL 0x00 /* concat or load */ -#define G_MTX_LOAD 0x02 -#define G_MTX_NOPUSH 0x00 /* push or not */ -#define G_MTX_PUSH 0x01 -#else /* F3DEX_GBI_2 */ -#define G_MTX_MODELVIEW 0x00 /* matrix types */ -#define G_MTX_PROJECTION 0x01 -#define G_MTX_MUL 0x00 /* concat or load */ -#define G_MTX_LOAD 0x02 -#define G_MTX_NOPUSH 0x00 /* push or not */ -#define G_MTX_PUSH 0x04 -#endif /* F3DEX_GBI_2 */ - /* * flags for G_SETGEOMETRYMODE * (this rendering state is maintained in RSP) @@ -289,33 +182,15 @@ constexpr int8_t OTR_G_SETINTENSITY = (int8_t)0x40; * See the man page for gSP1Triangle(). * */ + #define G_ZBUFFER 0x00000001 -#define G_SHADE 0x00000004 /* enable Gouraud interp */ - /* rest of low byte reserved for setup ucode */ -#ifdef F3DEX_GBI_2 -#define G_TEXTURE_ENABLE 0x00000000 /* Ignored */ -#define G_SHADING_SMOOTH 0x00200000 /* flat or smooth shaded */ -#define G_CULL_FRONT 0x00000200 -#define G_CULL_BACK 0x00000400 -#define G_CULL_BOTH 0x00000600 /* To make code cleaner */ -#else -#define G_TEXTURE_ENABLE 0x00000002 /* Microcode use only */ -#define G_SHADING_SMOOTH 0x00000200 /* flat or smooth shaded */ -#define G_CULL_FRONT 0x00001000 -#define G_CULL_BACK 0x00002000 -#define G_CULL_BOTH 0x00003000 /* To make code cleaner */ -#endif +#define G_SHADE 0x00000004 #define G_FOG 0x00010000 #define G_LIGHTING 0x00020000 #define G_TEXTURE_GEN 0x00040000 #define G_TEXTURE_GEN_LINEAR 0x00080000 -#define G_LOD 0x00100000 /* NOT IMPLEMENTED */ +#define G_LOD 0x00100000 #define G_LIGHTING_POSITIONAL 0x00400000 -#if (defined(F3DEX_GBI) || defined(F3DLP_GBI)) -#define G_CLIPPING 0x00800000 -#else -#define G_CLIPPING 0x00000000 -#endif /* * G_EXTRAGEOMETRY flags: set extra custom geometry modes @@ -1066,51 +941,6 @@ typedef union { long long int force_structure_alignment; } F3DVp; -/* - * MOVEMEM indices - * - * Each of these indexes an entry in a dmem table - * which points to a 1-4 word block of dmem in - * which to store a 1-4 word DMA. - * - */ -#ifdef F3DEX_GBI_2 -/* 0,4 are reserved by G_MTX */ -#define G_MV_MMTX 2 -#define G_MV_PMTX 6 -#define G_MV_VIEWPORT 8 -#define G_MV_LIGHT 10 -#define G_MV_POINT 12 -#define G_MV_MATRIX 14 /* NOTE: this is in moveword table */ -#define G_MVO_LOOKATX (0 * 24) -#define G_MVO_LOOKATY (1 * 24) -#define G_MVO_L0 (2 * 24) -#define G_MVO_L1 (3 * 24) -#define G_MVO_L2 (4 * 24) -#define G_MVO_L3 (5 * 24) -#define G_MVO_L4 (6 * 24) -#define G_MVO_L5 (7 * 24) -#define G_MVO_L6 (8 * 24) -#define G_MVO_L7 (9 * 24) -#else /* F3DEX_GBI_2 */ -#define G_MV_VIEWPORT 0x80 -#define G_MV_LOOKATY 0x82 -#define G_MV_LOOKATX 0x84 -#define G_MV_L0 0x86 -#define G_MV_L1 0x88 -#define G_MV_L2 0x8a -#define G_MV_L3 0x8c -#define G_MV_L4 0x8e -#define G_MV_L5 0x90 -#define G_MV_L6 0x92 -#define G_MV_L7 0x94 -#define G_MV_TXTATT 0x96 -#define G_MV_MATRIX_1 0x9e /* NOTE: this is in moveword table */ -#define G_MV_MATRIX_2 0x98 -#define G_MV_MATRIX_3 0x9a -#define G_MV_MATRIX_4 0x9c -#endif /* F3DEX_GBI_2 */ - /* * MOVEWORD indices * @@ -1125,11 +955,6 @@ typedef union { #define G_MW_SEGMENT 0x06 #define G_MW_FOG 0x08 #define G_MW_LIGHTCOL 0x0a -#ifdef F3DEX_GBI_2 -#define G_MW_FORCEMTX 0x0c -#else /* F3DEX_GBI_2 */ -#define G_MW_POINTS 0x0c -#endif /* F3DEX_GBI_2 */ #define G_MW_PERSPNORM 0x0e /* @@ -1159,37 +984,6 @@ typedef union { #define G_MWO_FOG 0x00 #define G_MWO_aLIGHT_1 0x00 #define G_MWO_bLIGHT_1 0x04 -#ifdef F3DEX_GBI_2 -#define G_MWO_aLIGHT_2 0x18 -#define G_MWO_bLIGHT_2 0x1c -#define G_MWO_aLIGHT_3 0x30 -#define G_MWO_bLIGHT_3 0x34 -#define G_MWO_aLIGHT_4 0x48 -#define G_MWO_bLIGHT_4 0x4c -#define G_MWO_aLIGHT_5 0x60 -#define G_MWO_bLIGHT_5 0x64 -#define G_MWO_aLIGHT_6 0x78 -#define G_MWO_bLIGHT_6 0x7c -#define G_MWO_aLIGHT_7 0x90 -#define G_MWO_bLIGHT_7 0x94 -#define G_MWO_aLIGHT_8 0xa8 -#define G_MWO_bLIGHT_8 0xac -#else -#define G_MWO_aLIGHT_2 0x20 -#define G_MWO_bLIGHT_2 0x24 -#define G_MWO_aLIGHT_3 0x40 -#define G_MWO_bLIGHT_3 0x44 -#define G_MWO_aLIGHT_4 0x60 -#define G_MWO_bLIGHT_4 0x64 -#define G_MWO_aLIGHT_5 0x80 -#define G_MWO_bLIGHT_5 0x84 -#define G_MWO_aLIGHT_6 0xa0 -#define G_MWO_bLIGHT_6 0xa4 -#define G_MWO_aLIGHT_7 0xc0 -#define G_MWO_bLIGHT_7 0xc4 -#define G_MWO_aLIGHT_8 0xe0 -#define G_MWO_bLIGHT_8 0xe4 -#endif #define G_MWO_MATRIX_XX_XY_I 0x00 #define G_MWO_MATRIX_XZ_XW_I 0x04 #define G_MWO_MATRIX_YX_YY_I 0x08 @@ -1340,36 +1134,6 @@ typedef union F3DGfx { * GBI Commands for S2DEX microcode *===========================================================================*/ /* GBI Header */ -#ifdef F3DEX_GBI_2 -constexpr int8_t F3DEX2_G_OBJ_RECTANGLE_R = (int8_t)0xda; -#define G_OBJ_MOVEMEM 0xdc -#define G_RDPHALF_0 0xe4 -constexpr int8_t F3DEX2_G_OBJ_RECTANGLE = (int8_t)0x01; -#define G_OBJ_SPRITE 0x02 -#define G_SELECT_DL 0x04 -#define G_OBJ_LOADTXTR 0x05 -#define G_OBJ_LDTX_SPRITE 0x06 -#define G_OBJ_LDTX_RECT 0x07 -#define G_OBJ_LDTX_RECT_R 0x08 -constexpr int8_t F3DEX2_G_BG_1CYC = (int8_t)0x09; -constexpr int8_t F3DEX2_G_BG_COPY = (int8_t)0x0a; -constexpr int8_t F3DEX2_G_OBJ_RENDERMODE = (int8_t)0x0b; -#else -#define G_BG_1CYC 0x01 -#define G_BG_COPY 0x02 -#define G_OBJ_RECTANGLE 0x03 -#define G_OBJ_SPRITE 0x04 -#define G_OBJ_MOVEMEM 0x05 -#define G_SELECT_DL 0xb0 -#define G_OBJ_RENDERMODE 0xb1 -#define G_OBJ_RECTANGLE_R 0xb2 -#define G_OBJ_LOADTXTR 0xc1 -#define G_OBJ_LDTX_SPRITE 0xc2 -#define G_OBJ_LDTX_RECT 0xc3 -#define G_OBJ_LDTX_RECT_R 0xc4 -#define G_RDPHALF_0 0xe4 -#endif - #define G_BGLT_LOADBLOCK 0x0033 #define G_BGLT_LOADTILE 0xfff4 diff --git a/src/public/bridge/gfxbridge.h b/src/public/bridge/gfxbridge.h index 9b86bec..c21825f 100644 --- a/src/public/bridge/gfxbridge.h +++ b/src/public/bridge/gfxbridge.h @@ -8,6 +8,8 @@ extern "C" { #endif typedef enum UcodeHandlers { + ucode_f3d, + ucode_f3dex, ucode_f3dex2, ucode_s2dex, ucode_max,