At this point we have a choice to make. Either we could follow the main function flow and decompile `func_80C10148`, or take a look at `Destroy`, which for smaller actors can often be done straight after Init, since it usually just removes colliders and deallocates dynapoly.
## Destroy
Destroy will be a dead end, but we might as well do it now. Usually we would regenerate the context first and apply it to mips2c as with `Init`, but if we look at the assembly...
so it really does do nothing. It is worth staying on this briefly to understand what is is doing, though. Even with no context, mips2c knows it takes two arguments because it does two saves onto the stack: the calling convention the N64 uses requires the first four arguments be saved from the registers onto the stack, since the registers are expected to be cleared when a function call happens. It's done a bad job of guessing what they are, but that's to be expected: the assembly only tells us they're words. Thankfully we already know in this case, so we can just replace the `GLOBAL_ASM` by
We don't really have a choice now, we have to look at this function. Remake the context (no need to change the function type this time), and run mips2c on the function's assembly file:
This gives us some information immediately: `D_0600AD98` is an `AnimationHeader`, and `func_80C1019C` is set as the action function. This means that we know its type, even though mips2c does not: looking in the header, we see the typedef is
at the top (were it above the function we're currently working on, the prototype could eventually be replaced by the function definition itself, but since it isn't, it goes at the top with the others).
This is a common type of function called a setup (action) function. It runs once and prepares the ground for its corresponding actionfunction to run, whereas the actionfunction is usually run every frame by `Update` (but more on that later). Running `make`, we get OK again.
Again we have only one way to go
## `func_80C1019C`
Remake the context and run mips2c on this function's assembly file. We get
-`sp24` does nothing, so is almost certainly fake.
-`temp_a0` is used in 3 different places, but they're all right next to one another and are unlikely to be required since there's no nontrivial calculation or anything happening. Let's remove it too and see what happens.
- We've got another reversed comparison, `&D_0600A280 == this->skelAnime.animation`.
-`D_0600A280` is an `AnimationHeader`.
-`(Actor *) this` should be replaced by `&this->actor`.
- `Flags_GetSwitch is a boolean and we don't need to cast the argument, as we have discussed before. (We don't know about the other functions in the conditions, so leave them for now.)
- Prototype `func_80C10290`: it is reasonable to guess it's another setup function, so `void func_80C10290(EnRecepgirl* this);`.
Here, it's debatable whether to keep the first, since `func_80C10290` is likely a setup function. The latter two should be changed to elses, though. For now, let's replace all of them. This leaves us with
Well, this is a big one! We get one more extern, for `D_06000968`. A lot of the temps used in the conditionals look fake, with the exception of `temp_v0_2`: because the function is only called once but the temp is used twice, the temp must be real. Removing the others and switching the `animation` conditionals,
There remains one thing we need to fix before trying to compile it, namely `*(&gSaveContext + 0xF37) & 0x80`. This is really a funny way of writing an array access, because mips2c will get confused about arrays in structs. Opening up `z64save.h`, we find in the `SaveContext` struct that
so it's somewhere in `weekEventReg`. `0xF37 - 0xEF8 = 0x3F = 63`, and it's a byte array, so the access is actually `gSaveContext.save.saveInfo.weekEventReg[63] & 0x80`. Now it will compile. We also don't use `!= 0` for flag comparisons: just `if (gSaveContext.save.saveInfo.weekEventReg[63] & 0x80)` will do.
Running `./diff.py -mwo3 func_80C102D4` and scrolling down, we discover that this doesn't match!

The yellow shows registers that don't match, the different colours on the registers help you to estimate where the problems are. Usually it's best to start at the top and work down if possible: any regalloc problems at the top tend to propagate most of the way down. In our case, the first problem is
somehow we skipped over `t0`. Where is this in the code? The `153` in the middle is the line number in the C file (the `3f0`s are the offsets into the assembly file), we have `--source` if you want to see the code explicitly, or you can do it the old-fashioned way, and work it out from nearby function calls. In this case, `func_80C10148` is run straight after, and the only place that is called is
If you look at the conditionals and the declaration of `temp_v0_2`, you may notice something odd: `temp_v0_2` is a `u8`. Therefore the `& 0xFF` does nothing! It's surprisingly common for this to happen, be it leaving out a `& 0xFF` or adding an extraneous one. If we remove it, we get a match:

Notice that indeed the subsequent regalloc, which might have looked like a bigger problem than the initial part, was also fixed: skipping a register in one place will throw the registers off below too.
And now we've run out of functions. Time for `Update`.
## Update
Update runs every frame and usually is responsible for the actor's common logic updates: for example, updating timers, blinking, updating collision, running the `actionFunc`, and so on, either directly or through other functions it calls. A lot of subsidiary functions that are not common to every state (e.g. updating position, or the text when talking, etc.) are carried out by one of the action functions we have already decomped.
If we search for `func_80C100DC`, we find that this is the only time it is used. Hence we can be almost certain that its prototype is `void func_80C100DC(EnRecepgirl* this);`. This function occurs above `Update`, so you can put the prototype next to the `GLOBAL_ASM` and remove it when we decompile that function.
Change the function and the prototype back to `Actor* thisx`, and add the casting temp:
Now, our problem is `Actor_TrackPlayer`. The arguments all look terrible! Indeed, if we look at the actual function in `src/code/code_800E8EA0.c` (found by searching), we find that it should be
It's entirely possible that `unk_2AD` is not real, and is just padding: see [Types, structs, and padding](types_structs_padding.md) for the details. We'll find out once we've finished all the functions. If we look at the diff, we find that one line is different:
So `sp30` is in the wrong place: it's `4` too high on the stack in ours. This is because the main four functions do not actually take `PlayState`: they really take `Gamestate` and recast it with a temp, just like `EnRecepgirl* this = THIS;`. We haven't implemented this in the repo yet, though, so for now, it suffices to put a pad on the stack where it would go instead: experience has shown when it matters, it goes above the actor recast, so we end up with
(Feel free to skip this if you'd rather finish the actor first.)
The (function) stack is used to store variables. It has rather more space and is somewhat less volatile than registers (it still can't be used outside a function, except by a called function accessing its arguments). The stack a function sets up for itself to use is called its *stack frame* or *function frame* (or just *function stack* or *the stack*, although strictly speaking the frame itself is not a stack, since not just the top variable is accessed), and the function frames themselves form an (genuine) stack called the *call stack*. In MIPS this stack grows downwards, and its size is always a multiple of 0x8 (in case you want to put a 64-bit value on it, although almost no N64 game functions do this). The compiler uses the stack in a single function frame in the following way:
| user-defined variables |
| compiler-defined varibles |
| saved registers |
| argument registers/stack |
where sp is at the very bottom of this table, and the function that called the current function would have its frame above this one. We have seen a couple of aspects of this stack behaviour already: saving the function arguments onto it in [`EnRecepgirl_Destroy`](#destroy), and here, requiring an extre user stack variable to be the correct size.
Anyway, back to EnRecepgirl. 4 functions to go...
## `func_80C100DC`
This is the final non-draw function. You know what to do now: remake the context and run mips2c:
// Duplicate return node #5. Try simplifying control flow for better match
return;
}
if(Rand_ZeroOne()<0.02f){
this->unk_2AC+=1;
}
}
```
Well, hmm. It's pretty hard to tell what's going on here. Finally it's time to really use `diff.py`. this function is a bit more typical of what to expect: this actor has been very easy so far!

Well, it's still *pretty* close. But the registers are all wrong. Firstly, `temp_t6` is already `u8`, so the `& 0xFF` is again ineffective, so let's try removing it...

It's not obvious that did much: it even looks a bit worse.
Even though this matches, it is not quite according to our style: remember what was said earlier about early returns. Here, both of them can be removed and replaced by a single else without affecting matching:
With that, the last remaining function is `EnJj_Draw`. Draw functions have an extra layer of macroing that is required, so we shall cover them separately.