Yeah, pure C so far, but in order to maintain speed, some things are deliberately written long. It would be super easy to do things with arrays but of course, HuC monkeys those all up so that doesn't fly too well. What I do to maintain speed in straight C is to use groups of individual variables and if() blocks. It's far faster than using arrays and switch() blocks. Also, to maintain genericism in the state machines, I have "upload" and "download" functions which copy the individual variable sets into and out of one "base" set, which the state machines work with. HuC does all of this very quickly.
I use center point collision for just about everything. For each collision check, I take the center point of the source object and compare it against the four points of the target object plus the box size of the source object. So like... if I have a 16x16 shot sprite against a 32x32 enemy, I take 8,8 into the shot sprite and compare it against -8,40 of the target sprite. Minimal calculations, and allows for an infinite variety of bounding box sizes. Also, since player shot collision is handled inside the enemy state machines themselves rather than in the player shot handler, using multiple bounding boxes is a breeze... all of that is hardcoded into the state machine so there is no table lookup or anything like that to waste time. Doing it like this tends to take more code but the speed advantage is more than worth it. Little things like this are why I can pull this all off in straight C.