summaryrefslogtreecommitdiff
path: root/VP-indexwork.lua
diff options
context:
space:
mode:
Diffstat (limited to 'VP-indexwork.lua')
-rw-r--r--VP-indexwork.lua240
1 files changed, 240 insertions, 0 deletions
diff --git a/VP-indexwork.lua b/VP-indexwork.lua
new file mode 100644
index 0000000..a6bc08c
--- /dev/null
+++ b/VP-indexwork.lua
@@ -0,0 +1,240 @@
+local makepfs_sig = {
+ 0x4d, 0x61, 0x6b, 0x65, 0x50, 0x66, 0x73, 0x20,
+ 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x31,
+ 0x2e, 0x32, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+}
+
+function load_psp_index(cdutil)
+ local pspval1_ent = cdutil:findpath "/PSP_GAME/USRDIR/PSPVAL1.PFS"
+ if not pspval1_ent then error "VP-PSP iso seems wrong..." end
+ local pspval1 = cdutil:cdfile(pspval1_ent)
+
+ for k, v in ipairs(makepfs_sig) do
+ if pspval1:readU8() ~= v then error "Wrong MakePfs signature." end
+ end
+ num_entries = pspval1:readU32()
+ num_files = num_entries
+
+ local idx_pos = pspval1:readU32()
+ local index = {}
+
+ pspval1:seek(2048 * idx_pos + 4)
+ local last_sector = 1
+ for i = 1, num_entries - 1 do
+ local sector = pspval1:readU32()
+ local abssector = pspval1_ent.Sector + sector
+ index[i] = { sector = abssector, cd = cdutil }
+ if i ~= 1 then
+ index[i - 1].size = sector - last_sector
+ end
+ last_sector = sector
+ end
+ index[num_entries - 1].size = idx_pos - last_sector
+
+ for i = 1, num_entries - 1 do
+ if index[i].size == 0 then index[i] = nil else log("Entry " .. i .. ", sector " .. index[i].sector .. ", nsectors = " .. index[i].size) end
+ end
+
+ return index
+end
+
+function load_index(cdutil)
+ if got_psp then return load_psp_index(cdutil) end
+ local vp_sec, cfat, csiz, fat, siz, fkey, skey, fkey_pos, skey_pos
+
+ vp_sec = 150
+ cfat = cdutil:cdfile(vp_sec, num_entries * 4)
+ csiz = cdutil:cdfile(vp_sec + num_entries * 4 / 2048, num_entries)
+ fat = Buffer(true)
+ siz = Buffer(true)
+ fkey = Buffer(true)
+ skey = Buffer(true)
+ cfat:seek(num_entries * 4 - fkey_size)
+ csiz:seek(num_entries - skey_size)
+ fkey:copyfrom(cfat, fkey_size)
+ skey:copyfrom(csiz, skey_size)
+ cfat:seek(0)
+ csiz:seek(0)
+
+ fkey_pos = 0
+ skey_pos = 0
+
+ print "Decrypting index..."
+ for i = 0, (num_entries * 4 - 1) do
+ fat:writeU8(xorB(cfat:readU8(), fkey:readU8()))
+ fkey_pos = fkey_pos + 1
+ if fkey_pos == fkey_size then
+ fkey_pos = 0
+ fkey:seek(0)
+ end
+ end
+
+ for i = 0, (num_entries - 1) do
+ siz:writeU8(xorB(csiz:readU8(), skey:readU8()))
+ skey_pos = skey_pos + 1
+ if skey_pos == skey_size then
+ skey_pos = 0
+ skey:seek(0)
+ end
+ end
+
+ cfat:destroy()
+ csiz:destroy()
+ fkey:seek(0)
+ skey:seek(0)
+
+ print "Done."
+
+ local o, m, s, f, size_high, size
+
+ local fr = fat:readU32()
+ local sr = siz:readU8()
+ local index = {}
+ for i = 1, (num_entries - 1) do
+ m = fat:readU8()
+ s = fat:readU8()
+ f = fat:readU8()
+ size_high = fat:readU8()
+ sector = from_MSF(m, s, f)
+ size = siz:readU8() + size_high * 256
+ if (sector ~= 4294967146) then
+ log("Entry " .. i .. ", sector " .. sector .. ", nsectors = " .. size)
+ index[i] = { sector = sector, size = size, cd = cdutil }
+ end
+ end
+ fat:destroy()
+ siz:destroy()
+
+ return index, fkey, skey, fr, sr
+end
+
+function add_file(cindex, iso, file, i)
+ local size_full = math.ceil(file:getsize() / 2048)
+ local dest_sector = iso:putfile(file)
+ local _, m, s, f = to_MSF(dest_sector)
+ local size_high = math.floor(size_full / 256)
+ local size = size_full - size_high * 256
+ log("Putting file " .. i .. " at " .. dest_sector .. " - size = " .. size_full)
+ cindex.fat:wseek(i * 4)
+ cindex.siz:wseek(i)
+ cindex.fat:writeU8(m)
+ cindex.fat:writeU8(s)
+ cindex.fat:writeU8(f)
+ cindex.fat:writeU8(size_high)
+ cindex.siz:writeU8(size)
+end
+
+function close_index(cindex, iso)
+ for i = cindex.fat:getsize(), (num_entries * 4 - 1) do
+ cindex.fat:writeU8(0)
+ end
+
+ for i = cindex.siz:getsize(), (num_entries - 1) do
+ cindex.siz:writeU8(0)
+ end
+
+ local fkey_pos = 0
+ local skey_pos = 0
+ local cfat = Buffer(true)
+ local csiz = Buffer(true)
+ cindex.fat:seek(0)
+ cindex.siz:seek(0)
+ cindex.fkey:seek(0)
+ cindex.skey:seek(0)
+
+ for i = 0, (num_entries * 4 - 1) do
+ cfat:writeU8(xorB(cindex.fat:readU8(), cindex.fkey:readU8()))
+ fkey_pos = fkey_pos + 1
+ if fkey_pos == fkey_size then
+ fkey_pos = 0
+ cindex.fkey:seek(0)
+ end
+ end
+
+ for i = 0, (num_entries - 1) do
+ csiz:writeU8(xorB(cindex.siz:readU8(), cindex.skey:readU8()))
+ skey_pos = skey_pos + 1
+ if skey_pos == skey_size then
+ skey_pos = 0
+ cindex.skey:seek(0)
+ end
+ end
+
+ iso:putfile(cfat, -1, 150)
+ iso:putfile(csiz, -1, 160)
+
+ cfat:destroy()
+ csiz:destroy()
+end
+
+function psp_add_file(cindex, iso, file, i)
+ local size_full = math.ceil(file:getsize() / 2048)
+ local dest_sector = iso:putfile(file)
+ cindex.index[i] = { size = size_fill, sector = dest_sector }
+ log("Putting file " .. i .. " at " .. dest_sector .. " - size = " .. size_full)
+end
+
+function copyfile(path, name, dirtree, iso, cdutil)
+ local dirent = cdutil:findpath(path .. "/" .. name)
+ if not dirent then error("Failing finding path " .. path .. "/" .. name) end
+ iso:createfile(dirtree, name, cdutil:cdfile(dirent), dirent):setbasicsxa()
+end
+
+function psp_close_index(cindex, iso, cdutil)
+ local index_sec = iso:getdispsect()
+ local indexfile = Buffer(true)
+ local indexhead = Buffer(true)
+ indexhead:write "MakePfs Version1.20"
+ indexhead:writeU8(0)
+ indexhead:writeU32(0)
+ indexhead:writeU32(0)
+ indexhead:writeU32(0)
+ indexhead:writeU32(num_files)
+ indexhead:writeU32(index_sec - pspval1_sec)
+ indexhead:writeU32(0)
+ for i = indexhead:getsize(), 2047 do
+ indexhead:writeU8(0x98)
+ end
+ iso:putfile(indexhead, -1, pspval1_sec)
+ indexfile:writeU32(1)
+ local last_entry = nil
+ for i = 1, num_files - 1 do
+ if cindex.index[i] then
+ last_entry = cindex.index[i].sector - pspval1_sec
+ indexfile:writeU32(last_entry)
+ else
+ indexfile:writeU32(last_entry)
+ end
+ end
+ local more_bytes = alignment(indexfile:getsize(), 2048)
+ for i = 1, more_bytes do
+ indexfile:writeU8(0x98)
+ end
+ iso:putfile(indexfile)
+ psp_dirtrees.PSPVAL1.size = (iso:getdispsect() - pspval1_sec) * 2048
+
+ indexfile:destroy()
+ indexhead:destroy()
+
+ local cp = function(path, name, dirtree) copyfile(path, name, dirtree, iso, cdutil) end
+ for _, f in ipairs { "Field_master.prx", "Camp_master.prx", "MiniMap_master.prx", "WldMap_master.prx", "GodCamp_master.prx", "moviepac.dat" } do
+ cp("/PSP_GAME/USRDIR", f, psp_dirtrees.USRDIR)
+ end
+end
+
+function prepare_index(iso, fkey, skey, fr, sr)
+ if got_psp then
+ return { add_file = psp_add_file, close_index = psp_close_index, index = { } }
+ end
+
+ local false_sect = {}
+ for i = 1, 13 do
+ iso:createsector(false_sect, MODE2_FORM1)
+ end
+ local ret = { fat = Buffer(true), siz = Buffer(true), fkey = fkey, skey = skey, add_file = add_file, close_index = close_index }
+ ret.fat:writeU32(fr)
+ ret.siz:writeU8(sr)
+
+ return ret
+end