summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--VP-disasm.lua48
-rw-r--r--VP-miscwork.lua6
-rw-r--r--VP-roomwork.lua150
3 files changed, 164 insertions, 40 deletions
diff --git a/VP-disasm.lua b/VP-disasm.lua
index 204b280..0fb82fb 100644
--- a/VP-disasm.lua
+++ b/VP-disasm.lua
@@ -138,6 +138,10 @@ local opcodes_fromstack = {
false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, -- f
}
+local function disasm_write(self, ...)
+ if self.out then self.out:write(...) end
+end
+
local function disasm_opcode(self)
self.oPC = self.PC
self.opcode = self:rdn()
@@ -151,27 +155,27 @@ local function disasm_opcode(self)
self.flags.is_local = andB(self.opcode, 0x800000) ~= 0
self.flags.from_stack = andB(self.opcode, 0x100000) ~= 0
- self.out:write(string.format("%08X %08X ", self.oPC, self.opcode))
+ self:write(string.format("%08X %08X ", self.oPC, self.opcode))
if self.code == 0 then
- self.out:write("OPCODE00?!")
+ self:write("OPCODE00?!")
return
end
local name = opcodes_names[self.code]
if name then
- self.out:write(string.format("%-8s", name))
+ self:write(string.format("%-8s", name))
elseif opcodes_known[self.code] then
- self.out:write(string.format("OP_%02X ", self.code))
+ self:write(string.format("OP_%02X ", self.code))
else
- self.out:write(string.format("UNK%02X ", self.code))
+ self:write(string.format("UNK%02X ", self.code))
end
if self.flags.from_stack and opcodes_fromstack[self.code] then
for i = 1, opcodes_nparams[self.code] do
- self.out:write("POP()")
- if i ~= opcodes_nparams[self.code] then self.out:write(", ") end
+ self:write("POP()")
+ if i ~= opcodes_nparams[self.code] then self:write(", ") end
end
else
local nargs = opcodes_nparams[self.code]
@@ -186,42 +190,42 @@ local function disasm_opcode(self)
-- 6 = var_idx2
-- 7 = low8 + high8
elseif sv == 1 then
- self.out:write(string.format("%02X", self.imm8))
+ self:write(string.format("%02X", self.imm8))
nargs = nargs - 1
elseif sv == 2 then
- self.out:write(string.format("%04X", self.imm16))
+ self:write(string.format("%04X", self.imm16))
nargs = nargs - 1
elseif sv == 3 then
- self.out:write(string.format("%08X", self.imm23))
+ self:write(string.format("%08X", self.imm23))
nargs = nargs - 1
elseif sv == 4 then
- self.out:write(string.format("%02X", self.high8))
+ self:write(string.format("%02X", self.high8))
nargs = nargs - 1
elseif sv == 5 then
- self.out:write(string.format("%s[%04X]", self.flags.is_local and "locl" or "glbl", self.imm16))
+ self:write(string.format("%s[%04X]", self.flags.is_local and "locl" or "glbl", self.imm16))
nargs = nargs - 1
elseif sv == 6 then
- self.out:write(string.format("%s[%04X]", self.flags.is_local and "locl" or "glbl", self.idx2))
+ self:write(string.format("%s[%04X]", self.flags.is_local and "locl" or "glbl", self.idx2))
nargs = nargs - 1
elseif sv == 7 then
- self.out:write(string.format("%02X, %02X", self.imm8, self.high8))
+ self:write(string.format("%02X, %02X", self.imm8, self.high8))
nargs = nargs - 2
end
if sv ~= 0 and nargs ~= 0 then
- self.out:write(", ")
+ self:write(", ")
end
for i = 1, opcodes_imms[self.code] do
- self.out:write(string.format("%08X", self:rdn()))
- if i ~= opcodes_imms[self.code] then self.out:write(", ") end
+ self:write(string.format("%08X", self:rdn()))
+ if i ~= opcodes_imms[self.code] then self:write(", ") end
nargs = nargs - 1
end
if not opcodes_fromstack[self.code] then
for i = 1, nargs do
- self.out:write("POP()")
- if i ~= nargs then self.out:write(", ") end
+ self:write("POP()")
+ if i ~= nargs then self:write(", ") end
end
end
end
@@ -232,14 +236,14 @@ end
local function disasm(self)
while self.PC ~= self.EPC do
self:disasm_opcode()
- self.out:write("\n")
+ self:write("\n")
for padPC = self.oPC + 1, self.PC - 1 do
- self.out:write(string.format(" %08X\n", self:rd(padPC)))
+ self:write(string.format(" %08X\n", self:rd(padPC)))
end
end
end
function logic_disasm(logic, o, hooks)
- local dobj = { rd = rd, rdn = rdn, disasm_opcode = disasm_opcode, disasm = disasm, PC = 0, fin = logic, out = o, EPC = logic:getsize() / 4, hooks = hooks }
+ local dobj = { rd = rd, rdn = rdn, disasm_opcode = disasm_opcode, disasm = disasm, PC = 0, fin = logic, out = o, EPC = logic:getsize() / 4, hooks = hooks, write = disasm_write }
dobj:disasm()
end
diff --git a/VP-miscwork.lua b/VP-miscwork.lua
index 1a5bc14..2fec7b9 100644
--- a/VP-miscwork.lua
+++ b/VP-miscwork.lua
@@ -64,9 +64,11 @@ function process_arcgfx(fname, h, size, ext)
counter = counter + 1
end
elseif not dump_mode and f1 == 0x00300900 then
- error "Not written yet"
+-- error "Not written yet"
+ handler = nil
elseif not dump_mode and f1 == 0x00300800 then
- error "Not written yet"
+-- error "Not written yet"
+ handler = nil
end
outfile[i] = process_single_file(fname .. string.format("/%04i-%08X", i, index[i].extra), h, index[i].size, ext, handler)
diff --git a/VP-roomwork.lua b/VP-roomwork.lua
index 9bb590b..d17fb33 100644
--- a/VP-roomwork.lua
+++ b/VP-roomwork.lua
@@ -1,5 +1,121 @@
+function patch_logic(logic, windows, activate_debug)
+ local ptr_start = 3
+ local rd_opcode = function(PC)
+ logic:seek(PC * 4)
+ return logic:readU32()
+ end
+ local patch_opcode = function(PC, newcode)
+ logic:bseek(PC * 4)
+ logic:writeU32(newcode)
+ end
+ local txt_process = function(PC)
+ local opcode = rd_opcode(PC)
+ local txtptr
+ local x, y, width, height
+ if andB(opcode, 0x00100000) ~= 0 then
+ local psh1 = rd_opcode(PC - 1)
+ local psh2 = rd_opcode(PC - 2)
+ local psh3 = rd_opcode(PC - 3)
+ local psh4 = rd_opcode(PC - 4)
+ local psh5 = rd_opcode(PC - 5)
+ local psh6 = rd_opcode(PC - 6)
+
+ if andB(psh1, 0xff000000) ~= 0x12000000 then return end
+ if andB(psh2, 0xff000000) ~= 0x12000000 then return end
+ if andB(psh3, 0xff000000) ~= 0x12000000 then return end
+ if andB(psh4, 0xff000000) ~= 0x12000000 then return end
+ if andB(psh5, 0xff000000) ~= 0x12000000 then return end
+ if andB(psh6, 0xff000000) ~= 0x12000000 then return end
+
+ local arg1 = andB(psh1, 0x7fffff)
+ local arg2 = andB(psh2, 0x7fffff)
+ local arg3 = andB(psh3, 0x7fffff)
+ local arg4 = andB(psh4, 0x7fffff)
+ local arg5 = andB(psh5, 0x7fffff)
+ local arg6 = andB(psh6, 0x7fffff)
+
+ txtptr = arg6 + 1 - ptr_start
+
+ if txtptr < 0 then return end
+
+ local window = windows[txtptr + ptr_start]
+
+ if not window then return end
+
+ psh5 = orB(andB(psh5, 0xff800000), window.x)
+ psh4 = orB(andB(psh4, 0xff800000), window.y)
+ psh3 = orB(andB(psh3, 0xff800000), window.width)
+ psh2 = orB(andB(psh2, 0xff800000), window.height)
+
+ patch_opcode(PC - 2, psh2)
+ patch_opcode(PC - 3, psh3)
+ patch_opcode(PC - 4, psh4)
+ patch_opcode(PC - 5, psh5)
+ else
+ txtptr = andB(opcode, 0xff) + 1 - ptr_start
+ if txtptr < 0 then return end
+ local window = windows[txtptr + ptr_start]
+ local arg1 = orB(window.x, shl(window.y, 16))
+ local arg2 = orB(window.width, shl(window.height, 16))
+ patch_opcode(PC + 1, arg1)
+ patch_opcode(PC + 2, arg2)
+ end
+ end
+ local process_subtxt = function(PC)
+ local psh1 = rd_opcode(PC - 1)
+ local psh2 = rd_opcode(PC - 2)
+ local psh3 = rd_opcode(PC - 3)
+ local psh4 = rd_opcode(PC - 4)
+ local psh5 = rd_opcode(PC - 5)
+ local psh6 = rd_opcode(PC - 6)
+
+ if andB(psh1, 0xff000000) ~= 0x12000000 and andB(psh1, 0xff000000) ~= 0x0B000000 then return end
+ if andB(psh2, 0xff000000) ~= 0x12000000 then return end
+ if andB(psh3, 0xff000000) ~= 0x12000000 and andB(psh3, 0xff000000) ~= 0x0B000000 then return end
+ if andB(psh4, 0xff000000) ~= 0x12000000 and andB(psh4, 0xff000000) ~= 0x0B000000 then return end
+ if andB(psh5, 0xff000000) ~= 0x12000000 and andB(psh5, 0xff000000) ~= 0x0B000000 then return end
+ if andB(psh6, 0xff000000) ~= 0x12000000 and andB(psh6, 0xff000000) ~= 0x0B000000 then return end
+
+ local arg2 = andB(psh2, 0x7fffff)
+
+ local txtptr = arg2 + 1 - ptr_start
+ if txtptr < 0 then return end
+
+ local window = windows[txtptr + ptr_start]
+ if not window then return end
+
+ if andB(psh3, 0xff000000) ~= 0x0B000000 and window.height then psh3 = orB(andB(psh3, 0xff800000), window.height) end
+ if andB(psh4, 0xff000000) ~= 0x0B000000 and window.width then psh4 = orB(andB(psh4, 0xff800000), window.width) end
+ if andB(psh5, 0xff000000) ~= 0x0B000000 and window.y then psh5 = orB(andB(psh5, 0xff800000), window.y) end
+ if andB(psh6, 0xff000000) ~= 0x0B000000 and window.x then psh6 = orB(andB(psh6, 0xff800000), window.x) end
+
+ patch_opcode(PC - 3, psh3)
+ patch_opcode(PC - 4, psh4)
+ patch_opcode(PC - 5, psh5)
+ patch_opcode(PC - 6, psh6)
+ end
+ local call_process = function(PC)
+ local opcode = rd_opcode(PC)
+ if opcode == 0x1400033C or opcode == 0x140003E2 or opcode == 0x140003F5 or opcode == 0x14000408 then process_subtxt(PC) end
+ end
+ check_logic(logic)
+ if activate_debug then patch_opcode(0x1158, 0x9e000000) end
+ logic_disasm(logic, nil, {
+ -- txtbox1
+ [0x92] = txt_process,
+ -- txtbox2
+ [0x93] = txt_process,
+ -- txtbox3
+ [0x94] = txt_process,
+ -- txtbox4
+ [0x98] = txt_process,
+ -- *sigh*
+ [0x14] = call_process,
+ } )
+end
+
function process_current_room_script()
- local script, font, scriptfile, fontfile, nptrs
+ local script, font, scriptfile, fontfile, nptrs, windows
room_idx = current_file - 3610
if not rooms_lookup[room_idx] then return nil, nil end
@@ -16,9 +132,11 @@ function process_current_room_script()
scriptfile:writeU16(0)
scriptfile:writeU16(3)
nptrs = 0
+ windows = {}
for pidx, pval in ipairs(rooms_lookup[room_idx]) do
nptrs = nptrs + 1
local ptr = rooms_txts[pval]
+ windows[nptrs] = windows_data[pval]
scriptfile:writeU16(script:getsize())
for k, v in ipairs(ptr) do
if type(v) == "string" then
@@ -75,11 +193,11 @@ function process_current_room_script()
for j = 1, 6 do fontfile:writeU32(0) end
end
- return scriptfile, fontfile, nptrs + 2
+ return scriptfile, fontfile, nptrs + 2, windows
end
-function insert_script(old, new, nptrs)
- local size_1 = old:readU32()
+function insert_script(old, new, nptrs, windows)
+ local size_logic = old:readU32()
local u1 = old:readU32()
local u2 = old:readU32()
local n_ptrs = old:readU32()
@@ -97,14 +215,11 @@ function insert_script(old, new, nptrs)
ret:writeU32(u3)
ret:writeU32(u4)
ret:writeU32(u5)
- if got_us and current_file == (3610 + 125) and activate_debug_room then
- ret:copyfrom(old, 0x1158 * 4)
- ret:writeU32(0x9e000000)
- old:readU32()
- ret:copyfrom(old, size_1 - 0x1159 * 4)
- else
- ret:copyfrom(old, size_1)
- end
+ local logic = Buffer(true)
+ logic:copyfrom(old, size_logic)
+ patch_logic(logic, windows, got_us and current_file == (3610 + 125) and activate_debug_room)
+ logic:seek(0)
+ ret:copyfrom(logic)
ret:copyfrom(new)
return ret
@@ -150,8 +265,9 @@ function process_arcroom(fname, h, size, ext)
local script = nil
local font = nil
local nptrs
+ local windows = {}
if not dump_mode then
- script, font, nptrs = process_current_room_script()
+ script, font, nptrs, windows = process_current_room_script()
end
for i = 1, nfiles do
tell = h:tell()
@@ -179,7 +295,7 @@ function process_arcroom(fname, h, size, ext)
local ret
if counter == 1 then
log("Putting script...")
- ret = insert_script(h, script, nptrs)
+ ret = insert_script(h, script, nptrs, windows)
elseif counter == 2 then
log("Putting font...")
ret = Buffer(true)
@@ -220,9 +336,11 @@ function process_arcroom(fname, h, size, ext)
counter = counter + 1
end
elseif not dump_mode and ext == "sarc" and index[i].ftype == 4 then
- error "Not written yet"
+-- error "Not written yet"
+ handler = nil
elseif not dump_mode and ext == "sarc" and index[i].ftype == 7 then
- error "Not written yet"
+-- error "Not written yet"
+ handler = nil
end
outfile[i] = process_single_file(fname .. string.format("/%04i-%08X", i, index[i].ftype), h, index[i].size, "room", handler)
if handler and script and font then