summaryrefslogtreecommitdiff
path: root/VP-roomwork.lua
diff options
context:
space:
mode:
Diffstat (limited to 'VP-roomwork.lua')
-rw-r--r--VP-roomwork.lua150
1 files changed, 134 insertions, 16 deletions
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