Splitted opcodes into f3d/ex and f3dex2 (#557)

* Splitted opcodes into f3dex and f3dex2

* Fixed tidy

* Fixed ucode_attr_handlers for f3d

* Added f3dHandlers and fixed headers

* Removed duplicated gbi commands

* Removed wrong cases on switch

* Fixed wrong type on G_SETGEOMETRYMODE

* Fixed mtx_push
This commit is contained in:
Lywx
2024-05-06 18:11:31 -04:00
committed by GitHub
parent 5b7164ea38
commit 17ee2dbc36
7 changed files with 517 additions and 357 deletions
+7 -1
View File
@@ -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
+152
View File
@@ -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);
+149
View File
@@ -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);
+136 -61
View File
@@ -147,7 +147,27 @@ struct MaskedTextureEntry {
static map<string, MaskedTextureEntry> masked_textures;
static UcodeHandlers ucode_handler_index = UcodeHandlers::ucode_f3dex2;
static UcodeHandlers ucode_handler_index = ucode_f3dex2;
const static std::unordered_map<Attribute, int8_t> 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<Attribute, int8_t> 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<const std::unordered_map<Attribute, int8_t>*, 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<int8_t, const std::pair<const char*, GfxOpcodeHa
{ OTR_G_MARKER, { "G_MARKER", gfx_marker_handler_otr } }, // G_MARKER (0X33)
{ OTR_G_INVALTEXCACHE, { "G_INVALTEXCACHE", gfx_invalidate_tex_cache_handler_f3dex2 } }, // G_INVALTEXCACHE (0X34)
{ OTR_G_BRANCH_Z_OTR, { "G_BRANCH_Z_OTR", gfx_branch_z_otr_handler_f3dex2 } }, // G_BRANCH_Z_OTR (0x35)
#ifdef F3DEX_GBI_2
{ OTR_G_MTX_OTR, { "G_MTX_OTR", gfx_mtx_otr_handler_custom_f3dex2 } }, // G_MTX_OTR (0x36)
#else
{ OTR_G_MTX_OTR2, { "G_MTX_OTR2", gfx_mtx_otr_handler_custom_f3d } }, // G_MTX_OTR2 (0x29) Is this the right code?
#endif
{ OTR_G_TEXRECT_WIDE, { "G_TEXRECT_WIDE", gfx_tex_rect_wide_handler_custom } }, // G_TEXRECT_WIDE (0x37)
{ OTR_G_FILLWIDERECT, { "G_FILLWIDERECT", gfx_fill_wide_rect_handler_custom } }, // G_FILLWIDERECT (0x38)
{ OTR_G_SETGRAYSCALE, { "G_SETGRAYSCALE", gfx_set_grayscale_handler_custom } }, // G_SETGRAYSCALE (0x39)
{ OTR_G_TEXRECT_WIDE, { "G_TEXRECT_WIDE", gfx_tex_rect_wide_handler_custom } }, // G_TEXRECT_WIDE (0x37)
{ OTR_G_FILLWIDERECT, { "G_FILLWIDERECT", gfx_fill_wide_rect_handler_custom } }, // G_FILLWIDERECT (0x38)
{ OTR_G_SETGRAYSCALE, { "G_SETGRAYSCALE", gfx_set_grayscale_handler_custom } }, // G_SETGRAYSCALE (0x39)
{ OTR_G_EXTRAGEOMETRYMODE,
{ "G_EXTRAGEOMETRYMODE", gfx_extra_geometry_mode_handler_custom } }, // G_EXTRAGEOMETRYMODE (0x3a)
{ OTR_G_COPYFB, { "G_COPYFB", gfx_copy_fb_handler_custom } }, // G_COPYFB (0x3b)
@@ -3646,30 +3682,65 @@ const static std::unordered_map<int8_t, const std::pair<const char*, GfxOpcodeHa
{ F3DEX2_G_CULLDL, { "G_CULLDL", gfx_cull_dl_handler_f3dex2 } },
{ F3DEX2_G_MTX, { "G_MTX", gfx_mtx_handler_f3dex2 } },
{ F3DEX2_G_POPMTX, { "G_POPMTX", gfx_pop_mtx_handler_f3dex2 } },
#ifdef F3DEX_GBI_2
{ F3DEX2_G_MOVEMEM, { "G_MOVEMEM", gfx_movemem_handler_f3dex2 } },
{ F3DEX2_G_MOVEWORD, { "G_MOVEWORD", gfx_moveword_handler_f3dex2 } },
#else
{ G_MOVEMEM, { "G_MOVEMEM", gfx_movemem_handler_f3d } },
{ G_MOVEWORD, { "G_MOVEWORD", gfx_moveword_handler_f3d } },
#endif
{ F3DEX2_G_TEXTURE, { "G_TEXTURE", gfx_texture_handler_f3dex2 } },
{ F3DEX2_G_VTX, { "G_VTX", gfx_vtx_handler_f3dex2 } },
{ F3DEX2_G_MODIFYVTX, { "G_MODIFYVTX", gfx_modify_vtx_handler_f3dex2 } },
{ F3DEX2_G_DL, { "G_DL", gfx_dl_handler_common } },
{ F3DEX2_G_ENDDL, { "G_ENDDL", gfx_end_dl_handler_common } },
#ifdef F3DEX_GBI_2
{ F3DEX2_G_GEOMETRYMODE, { "G_GEOMETRYMODE", gfx_geometry_mode_handler_f3dex2 } },
#else
{ G_SETGEOMETRYMODE, { "G_SETGEOMETRYMODE", gfx_set_geometry_mode_handler_f3d } },
{ G_CLEARGEOMETRYMODE, { "G_CLEARGEOMETRYMODE", gfx_clear_geometry_mode_handler_f3d } },
#endif
{ F3DEX2_G_TRI1, { "G_TRI1", gfx_tri1_handler_f3dex2 } },
{ F3DEX2_G_TRI2, { "G_TRI2", gfx_tri2_handler_f3dex } },
{ F3DEX2_G_QUAD, { "G_QUAD", gfx_quad_handler_f3dex2 } },
{ F3DEX2_G_SETOTHERMODE_L, { "G_SETOTHERMODE_L", gfx_othermode_l_handler_f3dex2 } },
{ F3DEX2_G_SETOTHERMODE_H, { "G_SETOTHERMODE_H", gfx_othermode_h_handler_f3dex2 } },
// Commands to implement
{ OTR_G_MTX_OTR, { "G_MTX_OTR", gfx_mtx_otr_handler_custom_f3dex2 } },
};
const static std::unordered_map<int8_t, const std::pair<const char*, GfxOpcodeHandlerFunc>> 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<int8_t, const std::pair<const char*, GfxOpcodeHandlerFunc>> 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<int8_t, const std::pair<const char*, GfxOpcodeHa
{ F3DEX2_G_ENDDL, { "G_ENDDL", gfx_end_dl_handler_common } },
};
const static std::array<const std::unordered_map<int8_t, const std::pair<const char*, GfxOpcodeHandlerFunc>>*,
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;
+12
View File
@@ -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;
+59 -295
View File
@@ -1,157 +1,69 @@
#pragma once
#include <stdint.h>
/* 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
+2
View File
@@ -8,6 +8,8 @@ extern "C" {
#endif
typedef enum UcodeHandlers {
ucode_f3d,
ucode_f3dex,
ucode_f3dex2,
ucode_s2dex,
ucode_max,