diff options
author | Pixel <pixel@nobis-crew.org> | 2013-06-22 18:23:03 -0700 |
---|---|---|
committer | Pixel <pixel@nobis-crew.org> | 2013-06-22 18:23:03 -0700 |
commit | 8f8d2164a7605b60d2efc9cd0f46ee70a0706d8e (patch) | |
tree | 806eebd420b1c00d7e5c1a6b0c16c39a6a3d0d37 | |
parent | ad728683a0f8896508bcf24dadf9161b158573af (diff) |
First pass at reinsertion; window computation should now work.
-rw-r--r-- | VP-disasm.lua | 48 | ||||
-rw-r--r-- | VP-miscwork.lua | 6 | ||||
-rw-r--r-- | VP-roomwork.lua | 150 |
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 |