so that it fills out the struct fields from the actuar actor; we then put a
```C
EnJj* this = THIS;
```
in the declarations as before. From now on, the process is rather different from the decompilation process used for the other functions. Here is the output of mips2c after sorting out the actor struct from Init, and with the arguments set back to `Actor* thisx`:
(This is a particularly simple example, since there's only one of these blocks. We will give a more involved example later.)
Each of these blocks converts into a graphics macro. They are usually (but not always) straightforward, but manually converting them is a pain, and there are sometimes special cases. To deal with them easily, we will use a tool from glank's N64 tools. To install these, follow the instructions [here](https://practicerom.com/public/packages/debian/howto.txt).
For our purposes, we only need one of the programs this provides: `gfxdis.f3dex2`.
Graphics are actually 64-bit on the Nintendo 64. This code block is a result of instructions telling the processor what to do with the graphics pointer. There are two types of graphics pointer,
- polyOpa for solid textures
- polyXlu for translucent textures
Our example is polyOpa, not surprisingly since Jabu is solid.
`words.w0` and `words.w1` contain the actual graphics instruction, in hex format. Usually, `w0` is constant and `w1` contains the arguments. To find out what sort of macro we are dealing with, we use `gfxdis.f3dex2`. `w1` is variable, but we need to give the program a constant placeholder. A common word to use is 12345678, so in this case we run
-`-x` uses hex instead of the default qu macros (never mind what those are, OoT doesn't have them)
-`-g` is used to specify which graphics pointer macro to use
-`-d` is for the graphics dword
Our standard now is to use decimal colors. If you have a constant second argument rather than a variable one, you can also use `-dc` to get decimal colors instead of the default hex.
The output looks like
```
gSPSegment(POLY_OPA_DISP++, 0x08, 0x12345678);
```
We can now replace the `0x12345678` by the actual second word. Or we could, if we had worked out what it was.
Firstly, `*(&D_80A88CFC + (this->unk_30E * 4))` is referring to a piece of data we haven't externed yet. It looks like
The first three words look like pointers to assets in the actor segment, which would make sense if we're looking for textures to draw. The last two words are 0, which is strange. A check in the rest of the actor file shows that `unk_30E` only takes the values `0,1,2`. We conclude that the last two words are just padding, and can be removed. Because this data is used in a graphics macro, it will be either a displaylist or a texture. We therefore set it up to be an array of unknown pointers for now:
It goes through further processing before it is used in the macro: `(temp_a0 & 0xFFFFFF) + gSegments[(u32) (temp_a0 * 0x10) >> 0x1C] + 0x80000000` is a conversion of a segmented address into a VRAM address. We have a macro for this too: `SEGMENTED_TO_VIRTUAL`. So after all this, the second word is
The contents of a desegmentation macro used like this are almost always textures in this context, so we can replace `UNK_PTR` by `u64*`, the type for textures.
You repeat this for every block in the function.
We also have macros for Graph_OpenDisps and Graph_CloseDisps: you can replace
Once you've replaced all the blocks and the open and close with macros, you proceed with the function as usual.
Two last things: the last argument of the matrix functions tells the compiler whether to use the previously stored matrix or not, so we have the enums `MTXMODE_NEW` and `MTXMODE_APPLY` for these. And the rather weird-looking float `0.076624215f` is, of all things, `(M_PI/41.0f)` (try Wolfram Alpha for these things, and if that doesn't produce anything sensible, ask in Discord).
(The actual reason is probably that the animation is 41 frames long, but you won't necessarily spot this sort of thing for most floats)
matches apart from a couple of stack differences. This can be resolved by giving it `PlayState* play = play2;` at the top of the function and changing the second argument to `play2` as usual.
We have enums for the last argument of the matrix functions: `0` is `MTXMODE_NEW`, `1` is `MTXMODE_APPLY`.
Lastly, the penultimate and antepenultimate arguments of `SkelAnime_DrawFlexOpa` are actually pointers to functions, so they should be `NULL` instead of `0`.
## More examples: OverrideLimbDraw and PostLimbDraw
For more examples of graphics macros and the structure of Draw functions, we look at a function from `EnDntNormal`, which is some Deku Scrubs used in the minigame stuff in Lost Woods. This has a good selection of macros, and two functions that are commonly combined with Draw, namely OverrideLimbDraw and PostLimbDraw.
Worse, this is being accessed with pointer subtraction in the second word. `temp_v1 = (thisx->unk26A * 4) + &D_809F5E4C;` tells us that the array has elements of size 4 bytes, and the graphics macro implies the elements are colors. Colors of size 4 bytes are `Color_RGBA8`. Usually, we write colors in decimal, so `D_809F5E4C` becomes
Now, we have two things to worry about: how to implement the negative pointer access, and how the second word is built. Negative accesses can be done by just subtracting 1, so that
The last thing to worry about is how to put this word into the macro. Let's think about what the word actually is in a concrete case; it is easiest to see what is going on in hex, so suppose we are in the case
and so all this calculation is doing is turning `temp_v1` back into a word, with the last byte replaced by `0xFF` (that all the elements of `D_809F5E4C` have `0xFF` as their last element anyway is irrelevant here). Looking back at the output of gfxdis, we see that this actually means that the r,g,b just slot into the penultimate three arguments, the last being `0xFF`, leaving
and so `D_06001B00` is a displaylist, so the type in the externed data at the top of the file can be changed to `Gfx D_06001B00[]`. Arrays act like pointers, so we don't need the `&` in the macro:
Some more general tidying up can be done here (`sp60` and so `D_809F5E94` are `Vec3f`, for example, and under normal circumstances we'd know that ), but the big remaining issue is
If we look at the definition of `SkelAnime_DrawOpa`, we find that it's missing the last argument. This is mips2c not noticing why `this` has been put on the stack: this code should actually be
mips2c doing this is not especially unusual, so bear it in mind.
The other thing this tells us is that `func_809F58E4` is of type `OverrideLimbDraw`, and `func_809F59E4` of type `PostLimbDraw`. Their names are fairly self-explanatory. Filling in the prototypes as
This structure is pretty typical: both edit what certain limbs do. Both also usually need a `ActorName *this = THIS;` at the top. We have seen both of the macros in the former before: applying the usual procedure, we find that it becomes