Our team didn't finish, but here are some notes about our findings:
Small Mode
Horizontal movement is based on the formula x += 0x80 - ($17), where ($17) is the value of RAM address 0x17. Positive values move to the right and negative to the left. The value of 0x17 itself depends on player input (two bytes at 0x0A08 are the speed) and damage boosting (two bytes at 0xB7 are the speed and two bytes at 0xB9 are acceleration). Movement via controller input increases the speed by 1/16 of a pixel per frame (ppf) every frame, up to a max of 2 ppf. Damage boosting seems to depend on the type of enemy. The following code is relevant:
02:D050: 20 JSR $CEE1
02:CEE1: DF BBS5 $C9,26 ; Branch to CEFE if bit 5 of $C9 is set
02:CEE4: B9 LDA $CF18,Y
02:CEE7: 85 STA $B7 ; x_subspeed
02:CEE9: B9 LDA $CF1B,Y
02:CEEC: 85 STA $B8 ; x_speed
02:CEEE: B9 LDA $CF1E,Y
02:CEF1: 85 STA $B9 ; x_subspeed_delta
02:CEF3: B9 LDA $CF21,Y
02:CEF6: 85 STA $BA ; x_speed_delta
02:CEF8: B9 LDA $CF30,Y
02:CEFB: 85 STA $BB
02:CEFD: 60 RTS
02:CEFE: B9 LDA $CF24,Y
02:CF01: 85 STA $B7 ; x_subspeed
02:CF03: B9 LDA $CF27,Y
02:CF06: 85 STA $B8 ; x_speed
02:CF08: B9 LDA $CF2A,Y
02:CF0B: 85 STA $B9 ; x_subspeed_delta
02:CF0D: B9 LDA $CF2D,Y
02:CF10: 85 STA $BA ; x_speed_delta
02:CF12: B9 LDA $CF30,Y
02:CF15: 85 STA $BB
02:CF17: 60 RTS
I don't have any notes about the significance of bit 5, but $CF18 corresponds to 0x4F18 in the ROM file. You can see that the addresses are 3 bytes apart, which suggests that there are three types of enemies with regard to damage boosting.
Big Mode
x += ($1145) - A, where A is 0x40 if facing to the right and 0xC0 if facing to the left. Movement via controller input is at a constant speed of 2, while damage boosting is the same as in Small Mode.
Hitboxes
The following Lua script displays hitboxes for a number of things--enemies, barriers, player--as well as HP for enemies that have HP. I didn't figure out the hitboxes for some things, however, such as boss weapons.
Language: lua
memory.usememorydomain("Main Memory")
-- RAM
local addr_pc_x_hb_l = 0xA0
local addr_pc_x_hb_r = 0xA1
local addr_pc_y_hb_u = 0xA2
local addr_pc_y_hb_d = 0xA3
local addr_en_num = 0x001D
local addr_en_actv = 0x0980
local addr_en_y_lo = 0x0FEA
local addr_en_y_hi = 0x1060
local addr_en_x_lo = 0x10D6
local addr_en_x_hi = 0x114C
local addr_en_type = 0x131D
local addr_en_hp = 0x14D6
-- ROM
local addr_en_y_len = 0x57A9
local addr_en_x_len = 0x56D3
local function draw_en_hitbox()
local num_en = memory.readbyte(addr_en_num)
for i = 0, num_en - 1 do
local en_actv = memory.readbyte(addr_en_actv + i)
local e = memory.readbyte(addr_en_type + en_actv)
local e_y = memory.read_s8(addr_en_y_hi + en_actv) * 0x100 + memory.read_u8(addr_en_y_lo + en_actv)
local e_y_len = memory.readbyte(addr_en_y_len + e, "ROM")
local e_x = memory.read_s8(addr_en_x_hi + en_actv) * 0x100 + memory.read_u8(addr_en_x_lo + en_actv)
local e_x_len = memory.readbyte(addr_en_x_len + e, "ROM")
gui.drawBox(e_x - e_x_len, e_y - e_y_len, e_x + e_x_len, e_y + e_y_len)
local en_hp = memory.readbyte(addr_en_hp + en_actv)
if en_hp > 0 then
gui.drawText(e_x, e_y, string.format("%2x", en_hp))
end
end
end
local function draw_pc_hitbox()
local x_hb_l = memory.readbyte(addr_pc_x_hb_l)
local x_hb_r = memory.readbyte(addr_pc_x_hb_r)
local y_hb_u = memory.readbyte(addr_pc_y_hb_u)
local y_hb_d = memory.readbyte(addr_pc_y_hb_d)
gui.drawBox(x_hb_l, y_hb_u, x_hb_r, y_hb_d)
end
while true do
draw_pc_hitbox()
draw_en_hitbox()
emu.frameadvance()
end