After some more trace-crawling I found the throw boxes for kof96 through 2002. There's a slot for the grab area and another for the grabbable area near the end of an object's memory space. I made them yellow and white respectively, same as in prior scripts. Press hotkey 5 to show them. Failed throws that turn into normal attacks do show up this way.
It's worth pointing out that regular ground and air throws are direction + one-button, like SF2, but they take some time to come out. The direction isn't checked until two frames after pressing the button, and the stick must be held for at least two frames. This made it hard to nail down the exact time that the decision is made, and I ended up using Daimon's instant hcb,f+P to experiment instead.
These are very similar to the SFA3 throwboxes. Unlike other boxes which are computed every frame (with a status byte indicating which ones are active, in the case of KOF) a throw is attempted only when a certain subroutine gets run. The box data gets loaded at that time but doesn't get cleared. There's no on/off indicator and you can't tell if a throw is happening by looking at the memory. The yellow box won't go away without resolving this somehow. I dealt with it in SFA3 by zeroing out the throw ID byte every frame, and the script won't draw it if the ID is zero.
There is a throw ID byte in KOF, and it can be set to zero to tell the script to stop drawing the box, but there's another problem. The script data has to be updated in an emu.registerbefore loop because of a lag between player 1 and 2 if run in emu.registerafter. Since registerbefore gets tripped multiple times per frame (five in MAME-rr for NeoGeo), the evidence of the throw gets erased on the first pass and then a zero is read on subsequent passes. So no box gets drawn. The solution is to force the update to occur only once per frame.
Before:
emu.registerbefore( function()
update_neogeo_hitboxes()
end)
And after:
emu.registerbefore( function()
globals.register_count = globals.register_count + 1
if globals.register_count == 1 then
update_neogeo_hitboxes()
end
if globals.last_frame < emu.framecount() then
globals.register_count = 0
end
globals.last_frame = emu.framecount()
end)
This is good to do anyways to prevent the script from doing needless work. FBA-rr only runs registerbefore once per frame but it doesn't hurt to add this check.
So throwboxes work now, just like SFA3. Still, it's hackish to alter the memory. It would be better to tell the script to watch out for when the throw subroutine gets run. This would also enable them in games that don't load the dimensions of the throwbox into RAM at all, like SFA2 and apparently kof94 & 95 as well. That would require the memory.register or memory.registerexec functions like Gens-rr has. They never got added to MAME-rr or FBA-rr. The concern is that, in order to apply to any game, it would require inserting the Lua functionality into the source for every CPU device in MAME. That would be too much to implement and maintain. However, MAME's debugger can already set watchpoints and breakpoints, and it works on all games. Maybe the general solution is to make the Lua memory functions use the debugger functions.
Concerning the white boxes: It looks like every character has the same throwable area. I was going to look into when they should be removed, but when can't you be thrown? You can connect A xx dp+K or close C xx hcb,f+P with Daimon for example. (Comboing into command throw is sick.) So they are drawn at all times for now.
Another observation: For some reason everything was drawn 8 pixels too far to the right in FBA-rr. I put in a spot fix but I have no idea what's causing that.
Recent Comments