diff options
Diffstat (limited to 'VP-indexwork.lua')
-rw-r--r-- | VP-indexwork.lua | 240 |
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 |