From 8f8d2164a7605b60d2efc9cd0f46ee70a0706d8e Mon Sep 17 00:00:00 2001 From: Pixel Date: Sat, 22 Jun 2013 18:23:03 -0700 Subject: First pass at reinsertion; window computation should now work. --- VP-roomwork.lua | 150 ++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 134 insertions(+), 16 deletions(-) (limited to 'VP-roomwork.lua') 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 -- cgit v1.2.3