----------------------------------------------
-----Contra III hitbox viewer script SNES-----
----------------------------------------------
--Player Colors:
--Gold = Invuln
--Blue = Vulnerable
--Enemy colors:
--Red = Can be touched and hit with projectiles
--Green = Can be hit with projectiles but has no collision
--Yellow = Can touch you, cannot be hit with player projectiles
--White Axis in middle of box = Box is invulnerable
function findbit(p)
return 2 ^ (p - 1)
end
function hasbit(x, p)
return x % (p + p) >= p
end
local function check_offscreen(pos,val)
if val ~= 0 then
if val == 1 then
pos = 255 + pos
elseif val == 255 then
pos = 0 -(255 - pos)
end
end
return pos
end
local function draw_invuln(x,y,xrad,yrad)
gui.drawLine(x + (xrad / 2), y, x + (xrad / 2), y + yrad,0xFFFFFFFF)
gui.drawLine(x, y + (yrad / 2), x + xrad, y + (yrad / 2),0xFFFFFFFF)
end
local function Player()
local pbase = 0x200
for i = 0,1,1 do
pbase = pbase + (i * 0x40)
local x = mainmemory.read_u8(pbase + 6)
local y = mainmemory.read_u8(pbase + 0x10)
local x2 = mainmemory.read_u8(pbase + 0x28)
local y2 = mainmemory.read_u8(pbase + 0x2A)
local x_offscreen = mainmemory.read_u8(pbase + 0x7)
local y_offscreen = mainmemory.read_u8(pbase + 0x11)
local x2_offscreen = mainmemory.read_u8(pbase + 0x29)
local y2_offscreen = mainmemory.read_u8(pbase + 0x2B)
local active = mainmemory.read_u8(pbase + 0x16)
-- Checks if the box went off screen and adjusts
x = check_offscreen(x,x_offscreen)
x2 = check_offscreen(x2,x2_offscreen)
y = check_offscreen(y,y_offscreen)
y2 = check_offscreen(y2,y2_offscreen)
if active > 0 then
if hasbit(active,findbit(2)) == true or mainmemory.read_u16_le(0x1F88 + (i * 0x40)) > 0 then
gui.drawBox(x,y,x2,y2,0xFFFDD017,0x35FDD017)
else
gui.drawBox(x,y,x2,y2,0xFF0000FF,0x350000FF)
end
end
end
end
local function Enemies()
local start = 0x280
local base = 0
local oend = 32
local x
local x_offscreen
local y
local y_offscreen
local xrad
local yrad
local active
local touch
local projectile
local invuln
local hp
for i = 0,oend,1 do
base = start + (i * 0x40)
active = mainmemory.read_u8(base + 0x16)
hp = mainmemory.read_s16_le(base + 6)
if active > 0 then
touch = hasbit(active,findbit(4))
projectile = hasbit(active,findbit(5))
invuln = hasbit(active,findbit(6))
x = mainmemory.read_u8(base + 0xa)
x_offscreen = mainmemory.read_u8(base + 0xb)
y = mainmemory.read_u8(base + 0xe)
y_offscreen = mainmemory.read_u8(base + 0xf)
xrad = mainmemory.read_s16_le(base+0x28)
yrad = mainmemory.read_s16_le(base+0x2A)
-- Checks if the box went off screen and adjusts
x = check_offscreen(x,x_offscreen)
y = check_offscreen(y,y_offscreen)
if projectile and touch then
gui.drawBox(x,y,x+ xrad,y+yrad,0xFFFF0000,0x35FF0000)
elseif projectile then
gui.drawBox(x,y,x + xrad,y+yrad,0xFF00FF00,0x3500FF00)
elseif touch then
gui.drawBox(x,y,x + xrad,y + yrad,0xFFFFFF00,0x35FFFF00)
end
if hp > 0 and invuln == false then
gui.text((x-5),(y-5),"HP: " .. hp)
end
if invuln then
draw_invuln(x,y,xrad,yrad)
end
end
end
end
local function player_projectiles()
--local xreg = emu.getregister("X")
local yreg = emu.getregister("Y")
local x = mainmemory.read_u8(0x000A + yreg)
local y = mainmemory.read_u8(0x000E + yreg)
local x2 = mainmemory.read_u8(0x0000)
local y2 = mainmemory.read_u8(0x0002)
if math.abs(x2 - x) < 128 and math.abs(x - x2) < 128 and math.abs(y - y2) < 128 and math.abs(y2 - y) < 128 then
gui.drawBox(x,y,x2,y2)
end
end
event.onmemoryexecute(player_projectiles,0x00E25A)
while true do
local stage = mainmemory.read_u8(0x000086)
if stage ~= 2 and stage ~= 5 then
Player()
Enemies()
end
emu.frameadvance()
end