1
0
Fork 0
mirror of https://github.com/notwa/mm synced 2024-11-05 01:29:03 -08:00

big refactor

This commit is contained in:
Connor Olding 2015-05-01 20:36:02 -07:00
parent d098b237f1
commit 9bc0df3033

View file

@ -2,10 +2,9 @@ require "boilerplate"
require "addrs.init" require "addrs.init"
-- check for errors in the actor linked lists -- check for errors in the actor linked lists
local validate = true local validate = false
-- bizhawk lua has some nasty memory leaks at the moment, -- creating an object every time is a bit slow, so
-- so instead of creating an object every time,
-- using a template to offset from will do for now. -- using a template to offset from will do for now.
local actor_t = Actor(0) local actor_t = Actor(0)
@ -13,6 +12,9 @@ local suffix = oot and " oot" or ""
local actor_names = require("data.actor names"..suffix) local actor_names = require("data.actor names"..suffix)
local damage_names = require("data.damage names"..suffix) local damage_names = require("data.damage names"..suffix)
-- hack to avoid N64 logo spitting errors
local stupid = addrs.actor_counts[0].addr - 0x8
function sort_by_key(t) function sort_by_key(t)
local sorted = {} local sorted = {}
local i = 1 local i = 1
@ -109,78 +111,51 @@ function iter_actors(counts)
return iterate return iterate
end end
local ctrl function focus(actor, dump)
local pressed = {} local color = actor.name:sub(1,1) == "?" and "red" or "orange"
local old_ctrl = {} T_BL(0, 7, color, actor.name)
function update_input() T_BL(0, 6, nil, 'HP: %02X', actor.hp)
local j = joypad.getimmediate() T_BL(0, 5, 'cyan', 'No.: %03X', actor.num)
T_BL(0, 4, nil, 'Var: %04X', actor.var)
T_BL(0, 3, nil, '80%06X', actor.addr)
T_BL(0, 2, nil, 'type: %3i', actor.at)
T_BL(0, 1, nil, 'index: %3i', actor.ai)
T_BL(0, 0, nil, 'count: %3i', actor.type_count)
ctrl = { local dmg = deref(R4(actor.addr + actor_t.damage_table.addr))
enter = j["P1 L"], if dmg then
up = j["P1 DPad U"], for i = 0, 31 do
down = j["P1 DPad D"], local name = damage_names[i]
left = j["P1 DPad L"], local str = ('%9s: %02X'):format(name, R1(dmg + i))
right = j["P1 DPad R"],
}
for k, v in pairs(ctrl) do if i >= 16 then
pressed[k] = ctrl[k] and not old_ctrl[k] T_TR(0, i - 16, nil, str)
else
T_TL(0, i, nil, str)
end
end
end end
old_ctrl = ctrl if dump then
console.clear()
s = ("%04X\t%02X\t%02X"):format(actor.num, actor.at, actor.hp)
if dmg then
for i = 0, 31 do
s = s..("\t%02X"):format(R1(dmg + i))
end
end
print(s)
end
end end
local focus_at = 2 function collect_actors()
local focus_ai = 0 local game_counts = count_actors()
-- hack to avoid N64 logo spitting errors
local stupid = addrs.actor_counts[0].addr - 0x8
local seen_once = {}
local seen_strs = {}
local seen_strs_sorted = {}
local before = 0
local wait = 0
function wipe()
if #seen_strs_sorted > 0 then
print()
print("# actors wiped #")
print()
end
seen_once = {}
seen_strs = {}
seen_strs_sorted = {}
end
local function run(now)
local game_counts = nil
local seen = {}
local cursor, target
update_input()
if pressed.left then focus_ai = focus_ai - 1 end
if pressed.right then focus_ai = focus_ai + 1 end
if pressed.down then
-- follow Link again
focus_at = 2
focus_ai = 0
end
if R4(stupid) ~= 0 then
T_BR(0, 0, "red", "stupid")
return
end
game_counts = count_actors()
local any = 0 local any = 0
for i = 0, 11 do for i = 0, 11 do
any = any + game_counts[i] any = any + game_counts[i]
T_BR(0, 13 - i, nil, "#%2i: %2i", i, game_counts[i]) --FIXME: T_BR(0, 13 - i, nil, "#%2i: %2i", i, game_counts[i])
end end
T_BR(0, 1, nil, "sum:%3i", any) --FIXME: T_BR(0, 1, nil, "sum:%3i", any)
local actors_by_type = {[0]={},{},{},{},{},{},{},{},{},{},{},{}} -- 12 local actors_by_type = {[0]={},{},{},{},{},{},{},{},{},{},{},{}} -- 12
local new_counts = {[0]=0,0,0,0,0,0,0,0,0,0,0,0} -- 12 local new_counts = {[0]=0,0,0,0,0,0,0,0,0,0,0,0} -- 12
@ -192,30 +167,106 @@ local function run(now)
any = any + 1 any = any + 1
end end
end end
return any > 0, actors_by_type, new_counts
end
if any == 0 then InputHandler = Class()
wipe() function InputHandler:init(binds)
self.binds = binds
self.old_ctrl = {}
end
function InputHandler:update()
local ctrl = {}
local pressed = {}
local j = joypad.getimmediate()
for k, v in pairs(self.binds) do
ctrl[k] = j[v]
end
for k, v in pairs(ctrl) do
pressed[k] = ctrl[k] and not self.old_ctrl[k]
end
self.old_ctrl = ctrl
return ctrl, pressed
end
ActorLister = Class()
function ActorLister:init()
self.before = 0
self.wait = 0
self.focus_at = 2
self.focus_ai = 0
self.seen_once = {}
self.seen_strs = {}
self.seen_strs_sorted = {}
self.input = InputHandler{
enter = "P1 L",
up = "P1 DPad U",
down = "P1 DPad D",
left = "P1 DPad L",
right = "P1 DPad R",
}
end
function ActorLister:wipe()
if #self.seen_strs_sorted > 0 then
print()
print("# actors wiped #")
print()
end
self.seen_once = {}
self.seen_strs = {}
self.seen_strs_sorted = {}
end
function ActorLister:run(now)
local game_counts = nil
local seen = {}
local cursor, target
local ctrl, pressed = self.input:update()
if pressed.left then self.focus_ai = self.focus_ai - 1 end
if pressed.right then self.focus_ai = self.focus_ai + 1 end
if pressed.down then
-- follow Link again
self.focus_at = 2
self.focus_ai = 0
end
if R4(stupid) ~= 0 then
T_BR(0, 0, "red", "stupid")
return
end
local any, actors_by_type, new_counts = collect_actors()
if not any then
self:wipe()
else else
while focus_ai < 0 do while self.focus_ai < 0 do
focus_at = (focus_at - 1) % 12 self.focus_at = (self.focus_at - 1) % 12
focus_ai = new_counts[focus_at] - 1 self.focus_ai = new_counts[self.focus_at] - 1
end end
while focus_ai >= new_counts[focus_at] do while self.focus_ai >= new_counts[self.focus_at] do
focus_at = (focus_at + 1) % 12 self.focus_at = (self.focus_at + 1) % 12
focus_ai = 0 self.focus_ai = 0
end end
cursor = deref(addrs.z_cursor_actor()) cursor = deref(addrs.z_cursor_actor())
target = deref(addrs.z_target_actor()) target = deref(addrs.z_target_actor())
end end
local focus_link = focus_at == 2 and focus_ai == 0 local focus_link = self.focus_at == 2 and self.focus_ai == 0
local needs_update = false local needs_update = false
for at, actors in pairs(actors_by_type) do for at, actors in pairs(actors_by_type) do
for ai, addr in pairs(actors) do -- FIXME: sorry for this pseudo-indent for ai, addr in pairs(actors) do -- FIXME: sorry for this pseudo-indent
local var = R2(addr + actor_t.var.addr)
local hp = R1(addr + actor_t.hp.addr)
local num = R2(addr + actor_t.num.addr) local num = R2(addr + actor_t.num.addr)
local name = actor_names[num] local name = actor_names[num]
local focus_this = at == focus_at and ai == focus_ai
local focus_this = at == self.focus_at and ai == self.focus_ai
seen[num] = true seen[num] = true
@ -225,8 +276,8 @@ local function run(now)
print(("\t[0x%03X]=\"NEW\","):format(num)) print(("\t[0x%03X]=\"NEW\","):format(num))
end end
if not seen_once[num] then if not self.seen_once[num] then
seen_once[num] = now self.seen_once[num] = now
needs_update = true needs_update = true
local str local str
if name:sub(1,1) == "?" then if name:sub(1,1) == "?" then
@ -234,49 +285,22 @@ local function run(now)
else else
str = ("%s"):format(name) str = ("%s"):format(name)
end end
seen_strs[num] = str self.seen_strs[num] = str
print(str) print(str)
end end
if (focus_this and not focus_link) or addr == target then if (focus_this and not focus_link) or addr == target then
T_BL(0, 2, nil, 'type: %3i', at) local actor = {
T_BL(0, 1, nil, 'index: %3i', ai) addr = addr,
T_BL(0, 0, nil, 'count: %3i', new_counts[at]) at = at,
ai = ai,
local var = R2(addr + actor_t.var.addr) type_count = new_counts[at],
local hp = R1(addr + actor_t.hp.addr) name = name,
T_BL(0, 3, nil, '80%06X', addr) hp = hp,
T_BL(0, 5, 'cyan', 'No.: %03X', num) var = var,
T_BL(0, 4, nil, 'Var: %04X', var) num = num,
T_BL(0, 6, nil, 'HP: %02X', hp) }
focus(actor, pressed.up)
local color = name:sub(1,1) == "?" and "red" or "orange"
T_BL(0, 7, color, name)
local dmg = deref(R4(addr + actor_t.damage_table.addr))
if dmg then
for i = 0, 31 do
local name = damage_names[i]
local str = ('%9s: %02X'):format(name, R1(dmg + i))
if i >= 16 then
T_TR(0, i - 16, nil, str)
else
T_TL(0, i, nil, str)
end
end
end
if pressed.up then
console.clear()
s = ("%04X\t%02X\t%02X"):format(num, at, hp)
if dmg then
for i = 0, 31 do
s = s..("\t%02X"):format(R1(dmg + i))
end
end
print(s)
end
end end
if focus_this then if focus_this then
@ -287,13 +311,13 @@ local function run(now)
end end
if needs_update then if needs_update then
seen_strs_sorted = sort_by_key(seen_strs) self.seen_strs_sorted = sort_by_key(self.seen_strs)
end end
if focus_link and not target then if focus_link and not target then
for i, t in ipairs(seen_strs_sorted) do for i, t in ipairs(self.seen_strs_sorted) do
local color = 'white' local color = 'white'
if seen_once[t.k] and now - 60 <= seen_once[t.k] then if self.seen_once[t.k] and now - 60 <= self.seen_once[t.k] then
color = 'lime' color = 'lime'
end end
if not seen[t.k] then if not seen[t.k] then
@ -303,32 +327,34 @@ local function run(now)
end end
end end
T_BR(0, 0, nil, "unique:%3i", #seen_strs_sorted) T_BR(0, 0, nil, "unique:%3i", #self.seen_strs_sorted)
if any > 0 then if any then
local z = target or cursor local z = target or cursor
if z then if z then
local num = R2(z) local num = R2(z)
T_TR(0, 0, nil, seen_strs[num]) T_TR(0, 0, nil, self.seen_strs[num])
end end
end end
end end
local function runwrap(now) -- TODO: abstract to wrapper class or something
if now < before then wait = 2 end function ActorLister:runwrap(now)
before = now if now < self.before then self.wait = 2 end
if wait > 0 then self.before = now
if self.wait > 0 then
-- prevent script from lagging reversing -- prevent script from lagging reversing
wait = wait - 1 self.wait = self.wait - 1
if wait == 0 then wipe() end if self.wait == 0 then self:wipe() end
else else
run(now) self:run(now)
end end
end end
event.onloadstate(wipe, 'actor wipe') al = ActorLister()
event.onloadstate(al.wipe, 'actor wipe')
while oot or mm do while oot or mm do
local now = emu.framecount() local now = emu.framecount()
runwrap(now) al:runwrap(now)
emu.frameadvance() emu.frameadvance()
end end