Interesting discussion going on here, maybe I can answer some of the questions:
As you've already found out, it is possible to call game functions from a Gecko code, but it can be tricky. You have no idea where in RAM your code is, so you need to load the function address into CTR (or LR) and then use bctrl or blrl to execute the function. Of course, while doing that, you need to make sure you save and restore any registers that shouldn't be overwritten. If necessary, that means writing your own ASM to save/restore registers on the stack (which requires your own ASM code, so, C0 or C2 instead of the "easier" code types. This is explained in the Link (
https://mariokartwii.com/showthread.php?tid=1052 ) that was posted a while ago.
As for the if-else-endif construct behaving weird / unexpected on the Wii, Wiimm and me have encountered that years ago, too, that's why we first switched to only using C0 and C2 code and writing all the custom behaviour ourselves in Assembly.
A C0 code will be executed every time the Gecko handler runs - so, by default, every time a frame has been rendered. A C2 code will be *parsed* every time the Gecko handler runs, and will be executed whenever the game execution reaches the address it patches.
Your Gecko cheat code didn't run immediately at game boot, because the default Gecko hook is the VBI hook - this means, the gecko handler and all your gecko codes are executed each time a frame has been rendered. That's too late to modify video initialization apparently, so you had to perform your workaround of branching back to the game's entrypoint. Which, to be honest, I was surprised that that even worked without issues.
If you are having issues with the if/else/endif construct in the Gecko code, I would suggest implementing it yourself. Meaning, do not use the Gecko if/endif statements at all, just write one huge C0 gecko code and do all the comparisons and checks yourself in native ASM.