| name | decompile-microcode |
| description | Use this skill if you need to decompile a function that uses F3DEX. The presence of the Gfx type or gRegionAllocPtr are strongly indicative of an F3DEX or S2DEX microcode function. |
Decompiling F3DEX code
gRegionAllocPtr is indicative of a dynamically constructed F3DEX display list. F3DEX display list commands are microcode that are passed to the RSP for rendering. They are all 8 bytes long.
Special care needs to be taken with functions constructing display lists as the original developer likely used specific macros from include/PR/gbi.h (compiled with -DF3DEX_GBI). These macro calls need to be replicated in order for the function to match.
The first step is to identify the commands in question, for example a naive decompilation might produce:
temp_v1 = gRegionAllocPtr;
temp_a1 = (s32)arg0->unk30;
temp_v1->words.w0 = 0x01020040;
temp_v1->words.w1 = temp_a1;
Here there is a single F3DEX command. Its w0 starts with 0x01 — the F3DEX G_MTX opcode (F3DEX2's G_MTX is 0xDA; do not confuse the two). We can use gfxdis.f3dex to identify it:
gfxdis.f3dex -d 0102004000000000
Which gives us:
gsSPMatrix(0x00000000, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
This is close to what we want. But it needs a few improvements:
- We need the variant of this macro that also accepts a display list pointer:
gSPMatrix.
- We need to replace 0x00000000 with our actual variable: arg0->unk30.
This ultimately will give us:
gSPMatrix(gRegionAllocPtr++, (Mtx*)arg0->unk30, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
Note the inline increment of gRegionAllocPtr, this is very common in commands dealing with F3DEX microcode.
The mapping may not always be this clear, however. You can consult @f3dex-microcode-reference.md for a full list of F3DEX commands and include/PR/gbi.h for suitable macros to use.
Aggregate macros
Be aware that some macros in gbi.h aggregate a number of regular F3DEX commands. You should always look for patterns of commands that could translate into one of these macros. The use of which is very likely to increase your match percentage. Common examples of this include:
- gDPLoadTLUT (and its variations gDPLoadTLUT*)
- gDPLoadTextureBlock (and its variations gDPLoadTextureBlock*)
But there are many others.