Script for First Person View areas that draws a minimap showing:
- the map blocks (with relative ID for warp zones and computers),
- the player position,
- the player hitbox,
- the player facing direction.
Now displays the correct position in all maps.
-- SNES Jurassic Park - FPS OoB view v1.1 by ThunderAxe31
local addr_player_x = 0x000096
local addr_player_y = 0x000099
local addr_player_a = 0x00007A
local addr_map_x_size = 0x010000
local addr_map_y_size = 0x010001
local addr_map_begin = 0x010002
local x_end = 32
local y_end = 32
local block_size_real = 64
local block_size_draw = 8
local view_win = gui.createcanvas(255, 255)
view_win.SetTitle("FPS Out of Bounds viewer")
while true do
local map_x_size = memory.read_u8(addr_map_x_size, "WRAM")
local map_y_size = memory.read_u8(addr_map_y_size, "WRAM")
local x_pos = memory.read_s16_le(addr_player_x, "WRAM") +(-math.ceil(map_x_size/2)+(x_end/2)) *block_size_real
local y_pos = memory.read_s16_le(addr_player_y, "WRAM") +( math.ceil(map_y_size/2)-(y_end/2)) *block_size_real
local x_mod = -(x_pos%block_size_real)/block_size_draw
local y_mod = (y_pos%block_size_real)/block_size_draw
local x_pos_floor = math.floor(x_pos/block_size_real)
local y_pos_floor = math.floor(y_pos/block_size_real)
view_win.Clear(0xFFFFFFFF)
for y=0, y_end do
for x=-1, x_end+1 do
local block_addr = (-x_pos_floor +x) + (y_pos_floor +y) *map_x_size
local block_type = memory.read_u8(addr_map_begin +block_addr, "WRAM")
local x_block = x *block_size_draw -x_mod
local y_block = y *block_size_draw -y_mod
if (block_type == 0x40) then -- wall block, black color
view_win.DrawRectangle(x_block, y_block, 7, 7, 0xFF404040, 0xFFA0A0A0)
elseif (block_type >= 0x41) and (block_type <= 0x4E) then -- door blocks, grey color
view_win.DrawRectangle(x_block, y_block, 7, 7, 0xFF404040)
elseif (block_type == 0x0A) then -- dino gets mad, yellow color
view_win.DrawRectangle(x_block, y_block, 7, 7, 0xFFC0C000)
elseif (block_type == 0x01) then -- night goggles block, solid black color
view_win.DrawRectangle(x_block, y_block, 7, 7, 0xFF000000, 0xFF000000)
elseif (block_type == 0x0C) then -- elevator block, green color
view_win.DrawRectangle(x_block, y_block, 7, 7, 0xFF00C000)
elseif (block_type == 0xEF) then -- generator block, blue color
view_win.DrawRectangle(x_block, y_block, 7, 7, 0xFF0000C0)
elseif (block_type >= 0xF0) then -- exit blocks, pink color, also with ID
view_win.DrawRectangle(x_block, y_block, 7, 7, 0xFFF000F0)
view_win.DrawText(x_block-1, y_block-2, string.format("%X", bit.band(0xF, block_type)), 0xFF000000, 0x00FFFFFF, 9)
elseif (block_type >= 0xE0) then -- computer blocks, cyan color, also with ID
view_win.DrawRectangle(x_block, y_block, 7, 7, 0xFF00E0E0)
view_win.DrawText(x_block-2, y_block-2, string.format("%X", bit.band(0xF, block_type)), 0xFF000000, 0x00FFFFFF, 9)
elseif (block_type > 0x0E) then -- unknown blocks, just show their hex value
view_win.DrawText(x_block-1, y_block, string.format("%X", block_type), 0xFF000000, 0x00FFFFFF, 8)
end
end
end
view_win.DrawAxis(127,127,6) -- draws the exact block on which you're stepping on
view_win.DrawRectangle(116, 116, 22, 22, 0xFF000000) -- draws the player hitbox
--the following code is necessary for drawing the direction arrow
local direction = memory.read_u16_le(addr_player_a, "WRAM")
local angle = direction * 2*math.pi / (2^11) -- Rotation in game is stored using the range of 11bits (from 0 to 2^11-1)
local x1 = 127+math.sin(angle)*10
local y1 = 127-math.cos(angle)*10
local x2 = x1 -math.sin(angle-math.pi/4)*4
local y2 = y1 +math.sin(angle+math.pi/4)*4
-- local x3 = --need more math
-- local y3 = --need more math
view_win.DrawLine(x1,y1,127,127)
view_win.DrawLine(x1,y1,x2,y2)
-- view_win.DrawLine(x1,y1,x3,y3) --need more math
view_win.Refresh()
emu.frameadvance()
end