fantastic 4 DTC7 script.
-- HOWTO:
-- For the level you want to highlight specific IDs
-- Create a line like this:
-- interesting_blocks[<level>] = { <block>[, <block>, ...] }
-- e.g.
-- interesting_blocks[2] = { 0x79, 0x1b }
local interesting_blocks = {}
interesting_blocks[1] = { 0x47, 0x1b }
interesting_blocks[2] = { 0x79, 0x1b }
interesting_blocks[3] = { 0x79, 0x1b }
interesting_blocks[4] = { 0x79 }
interesting_blocks[5] = { 0x38 }
-- HACKY: Emulator detection, global because a deeper namespace can't read
-- from a shallower namespace?
is_fceux = nil
if FCEU ~= nil then -- FCEU unique module, not available on BizHawk
is_fceux = true
else
is_fceux = false
end
local EAL = {}
do
local mem = nil
local ROM = nil
local GUI = nil
end
-- EAL Memory namespace functions
EAL.mem = {}
do
function EAL.mem.read_u8(addr)
if is_fceux then
return memory.readbyte(addr)
else
return memory.read_u8(addr)
end
end
function EAL.mem.read_s8(addr)
if is_fceux then
return memory.readbytesigned(addr)
else
return memory.read_s8(addr)
end
end
function EAL.mem.read_u16_be(addr)
if is_fceux then
return memory.readword(addr + 1, addr)
else
return memory.read_u16_be(addr)
end
end
function EAL.mem.read_s16_be(addr)
if is_fceux then
return memory.readwordsigned(addr + 1, addr)
else
return memory.read_s16_be(addr)
end
end
function EAL.mem.read_s16_be_scatter(hi, lo)
if is_fceux then
return memory.readwordsigned(lo, hi)
else
local val = memory.read_u8(hi)
val = bit.lshift(val, 8)
val = bit.bor(val, memory.read_u8(lo))
if val > 0x7FFF then
return val - 0x10000
else
return val
end
end
end
function EAL.mem.read_u16_le(addr)
if is_fceux then
return memory.readword(addr)
else
return memory.read_u16_le(addr)
end
end
end
EAL.ROM = {}
do
-- `addr` is the address as seen from the system bus
local function get_addr_in_bank(bank, addr)
local bank_addr = addr - 0x8000
if addr > 0xC000 then -- high region
bank_addr = bank_addr - 0x4000
end
return bank_addr
end
-- `addr` is the address as seen from the system bus
local function get_offset_in_prg(bank, addr)
local bank_addr = get_addr_in_bank(bank, addr)
local offset = (bank * 0x4000) + bank_addr
return offset
end
-- Usage note: `addr` is the address as seen from the system bus
function EAL.ROM.read_u8(bank, addr)
local offset = get_offset_in_prg(bank, addr)
if is_fceux then
offset = offset + 16 -- FCEUX includes the header
return rom.readbyte(offset)
else
return memory.read_u8(offset, "PRG ROM")
end
end
-- Usage note: `addr` is the address as seen from the system bus
function EAL.ROM.read_u16_be(bank, addr)
local offset = get_offset_in_prg(bank, addr)
if is_fceux then
offset = offset + 16 -- FCEUX includes the header
local val = rom.readbyteunsigned(offset)
val = bit.lshift(val, 8)
val = bit.bor(val, rom.readbyteunsigned(offset + 1))
return val
else
return memory.read_u16_be(offset, "PRG ROM")
end
end
function EAL.ROM.read_u16_le(bank, addr)
local offset = get_offset_in_prg(bank, addr)
if is_fceux then
offset = offset + 16 -- FCEUX includes the header
local val = rom.readbyteunsigned(offset + 1)
val = bit.lshift(val, 8)
val = bit.bor(val, rom.readbyteunsigned(offset))
return val
else
return memory.read_u16_le(offset, "PRG ROM")
end
end
end
EAL.GUI = {}
do
function EAL.GUI.box(x1, x2, y1, y2)
if is_fceux then
gui.box(x1, y1, x2, y2)
else
gui.drawBox(x1, y1, x2, y2)
end
end
end
function get_screen_x_coordinate()
return EAL.mem.read_u16_le(0x00CC)
end
function get_level_info()
local level = EAL.mem.read_u8(0x0051)
local section = EAL.mem.read_u8(0x0052)
return level, section
end
function get_block_id_addr(level)
local bank = 7
local lvl_bank = EAL.ROM.read_u8(bank, 0xC5AD + level)
local offset_table_addr = EAL.ROM.read_u16_le(bank, 0xD102 + (level * 2)) + 3
local data_table_addr = EAL.ROM.read_u16_le(bank, 0xCD9F + (level * 2))
return lvl_bank, offset_table_addr, data_table_addr
end
function get_column_addr(x_pos)
local ram_bank = math.floor(x_pos / 256) % 2
local ram_start = 0x240
if (ram_bank == 1) then
ram_start = 0x330
end
return ram_start + math.floor((x_pos % 256) / 16)
end
function draw_block_id_map(screenx)
local level, section = get_level_info()
if interesting_blocks[level] == nil then
return
end
local x_steps = 17
local x_offset = -(screenx % 16)
if (screenx % 16 == 0) then
x_steps = 16
x_offset = 0
end
for i=0,x_steps do
local desired_screen_x = screenx + (i * 16)
local column_addr = get_column_addr(desired_screen_x)
for y=0,13 do
local block_addr = column_addr + (y * 16)
local id = EAL.mem.read_u8(block_addr)
for k,v in ipairs(interesting_blocks[level]) do
if id == v then
local box_x = x_offset + (i * 16)
local box_y = 32 + (y * 16)
EAL.GUI.box(box_x, box_x + 16, box_y, box_y + 16)
end
end
end
end
end
while true do
local screenx = get_screen_x_coordinate()
emu.frameadvance()
draw_block_id_map(screenx)
end