-- Parasite Eve's french patch -- $Id: pe-hack.lua,v 1.10 2004-01-26 15:31:55 pixel Exp $ function mainpatch() local dirent, slusdirent, pvd, root, is_cd1, is_cd2, slusname, fmvdir, systemcnfstring, inslus, slus, peimg, pesect, tim, startsect, slussect, fmvdirtree, xadirtree, falsesect, i, picts, pict -- slusdirent = cdutil:findpath "/SLUS_006.62;1" or cdutil:findpath "/SLUS_006.68;1" or error "Not a US Parasite Eve CD" slusdirent = cdutil:findpath "/SLUS_006.62;1" or cdutil:findpath "/SLUS_006.68;1" or error "Ce n'est pas un CD de Parasite Eve US" iso:foreword(cdutil) pvd = createpvd(cdutil) -- print "Identifying CD..." print "Identification du CD..." if (slusdirent.id == "SLUS_006.62;1") then -- print "CD is Parasite Eve CD1" print "CD1 de Parasite Eve" pvd.volid = "PE-FR-CD1" slusname = "PE-FR.CD1" fmvdir = "FMV1" is_cd1 = true is_cd2 = false else -- print "CD is Parasite Eve CD2" print "CD2 de Parasite Eve" pvd.volid = "PE-FR-CD2" slusname = "PE-FR.CD2" fmvdir = "FMV2" is_cd1 = false is_cd2 = true end root = iso:setbasics(pvd) systemcnfstring = "BOOT=cdrom:\\" .. slusname .. ";1\r\nTCB=4\r\nEVENT=16\r\nSTACK=801fff00\r\n" systemcnf = Buffer() systemcnf:write(systemcnfstring) dirent = cdutil:findpath("/SYSTEM.CNF;1") iso:createfile(root, "SYSTEM.CNF", systemcnf, slusdirent) -- print "Reading CD's slus file" print "Lecture du fichier slus" -- inslus = cdfile(cdutil, slusdirent) inslus = Input("PE-SLUS00662-patched-debug-room.exe") slus = Buffer(true) slus:copyfrom(inslus) apply_hacks(slus_hacks, slus) slussect = iso:getdispsect() -- print("Reserving space for SLUS file at sector " .. slussect) print("Reservation d'espace pour le SLUS au sector " .. slussect) slus:seek(0) iso:createfile(root, slusname, slus, slusdirent):setbasicsxa() slus:seek(0) dirent = cdutil:findpath "/" root:setbasicsxa() root:fromdir(dirent) dirent = cdutil:findpath "/PE.IMG;1" pesect = dirent.Sector peimg = cdfile(cdutil, dirent) tim = Buffer() peimg:copyto(tim, 0x23800) startsect = iso:createfile(root, "PE.TIM", tim, dirent).sector -- print "Compiling IMG file" print "Compilation du fichier IMG" do_img_file(slus, startsect, pesect) -- print "Writing final main file" print "Ecriture du fichier SLUS final" slus:seek(0) iso:putfile(slus, -1, slussect) -- print "Copying FMV directory" print "Copie du répertoire FMV..." dirent = cdutil:findpath("/" .. fmvdir) fmvdirtree = iso:createdir(root, fmvdir, 1, dirent) fmvdirtree:setbasicsxa() fmvdirtree.hardhide = true iso:copydir(fmvdirtree, cdutil, dirent) if (is_cd2) then -- print "Copying xastream directory" print "Copie du répertoire xastream..." dirent = cdutil:findpath("/XASTREAM") xadirtree = iso:createdir(root, "XASTREAM", 1, dirent) xadirtree:setbasicsxa() xadirtree.hardhide = true iso:copydir(xadirtree, cdutil, dirent) end -- print "Finalizing CD" print "Finalisation du CD" iso:createfile(root, "README.TXT", Input("readme.txt")):setbasicsxa() iso:createfile(root, "DIVERS.HTM", Input("divers.htm")):setbasicsxa() picts = iso:createdir(root, "PICTS") picts:setbasicsxa() for i, pict in ipairs(picts_files) do iso:createfile(picts, string.upper(pict), Input("picts/" .. pict)):setbasicsxa() end falsesect = {} for i = 1, 148, 1 do iso:createsector(falsesect, MODE2) end iso:close() end function do_img_file(slus, startsect, pesect) local i, j, sect1, tab1, sect2, tab2, sect3, tab3, sizes1, sizes2, sizes3, sect, file, file1, file2, file3, songsect, b1, b2, b3, b4, lastsect, s1, s2, s3, str = 0, 0, {}, {}, {}, {}, {}, {}, {}, {}, {} -- print "Putting various files" print "Fichiers divers..." slus:seek(0x838da) for i = 1, 80, 1 do sect1[i] = slus:readU16() + pesect end for i = 1, 79, 1 do if (files[i] ~= nil) then if (type(files[i]) == "string") then file = Input(files[i]) else file = files[i](sect1[i], (sect1[i + 1] - sect1[i]) * 2048) end else file = cdfile(cdutil, sect1[i], (sect1[i + 1] - sect1[i]) * 2048) end s1 = iso:putfile(file) tab1[i] = s1 - startsect -- print("Putting file " .. i .. " from sector " .. sect1[i] .. " to sector " .. s1) print("Ecriture du fichier " .. i .. "...") end tab1[80] = iso:getdispsect() - startsect songsect = tab1[80] -- print "Putting musics" print "Les musiques" slus:seek(0x83980) for i = 1, 251, 1 do sect2[i] = slus:readU16() + sect1[80] end for i = 1, 250, 1 do file = nil if ((sect2[i + 1] - sect2[i]) ~= 0) then file = cdfile(cdutil, sect2[i], (sect2[i + 1] - sect2[i]) * 2048) end if (file) then s1 = iso:putfile(file) end tab2[i] = s1 - startsect - songsect -- print("Putting music " .. i .. " from sector " .. sect2[i] .. " to sector " .. s1) print("Ecriture de la musique " .. i .. "...") end tab2[251] = iso:getdispsect() - startsect - songsect -- print "Putting rooms" print "Les rooms" slus:seek(0x83b78) for i = 1, 438, 1 do sect3[i] = slus:readU32() + pesect b1 = slus:readU8() b2 = slus:readU8() b3 = slus:readU8() b4 = slus:readU8() sizes1[i] = b1 sizes2[i] = orB(b2, (shl(andB(b3, 0x0f), 8))) sizes3[i] = orB(shr(b3, 4), shl(b4, 4)) end for i = 1, 438, 1 do file1 = nil file2 = nil file3 = nil if (sizes1[i] ~= 0) then file1 = cdfile(cdutil, sect3[i], sizes1[i] * 2048) end if (sizes2[i] ~= 0) then file2 = cdfile(cdutil, sect3[i] + sizes1[i], sizes2[i] * 2048) end if (sizes3[i] ~= 0) then file3 = cdfile(cdutil, sect3[i] + sizes1[i] + sizes2[i], sizes3[i] * 2048) end s1 = iso:getdispsect() - startsect if (file1) then iso:putfile(file1) end s2 = iso:getdispsect() - startsect if (file2) then iso:putfile(file2) end s3 = iso:getdispsect() - startsect if (file3) then if (groups[i] ~= nil) then str = string.format("%02i", groups[i]) file3 = patch_room(file3, Input("scripts/" .. str .. ".bin"), i) end iso:putfile(file3) end -- print("Putting room " .. i .. " from sector " .. sect3[i] .. " to sector " .. s1 + startsect) print("Ecriture de la room " .. i .. "...") tab3[i] = s1 sizes1[i] = s2 - s1 sizes2[i] = s3 - s2 sizes3[i] = iso:getdispsect() - s3 - startsect end slus:wseek(0x838da) for i = 1, 80, 1 do slus:writeU16(tab1[i]) end slus:writeU16(0) slus:writeU16(songsect) slus:writeU16(0) for i = 1, 251, 1 do slus:writeU16(tab2[i]) end slus:wseek(0x83b78) for i = 1, 438, 1 do s1 = sizes1[i] s2 = sizes2[i] s3 = sizes3[i] b1 = s1 b2 = andB(s2, 0xff) b3 = orB(shr(s2, 8), shl(andB(s3, 0x0f), 4)) b4 = shr(s3, 4) slus:writeU32(tab3[i]) slus:writeU8(b1) slus:writeU8(b2) slus:writeU8(b3) slus:writeU8(b4) end for i = 1, 11, 1 do slus:writeU32(iso:getdispsect()) slus:writeU32(0) end end function patch_menu(sector, size) local menu, bmenu, i, v, o menu = Input("menus.bin") bmenu = Buffer(true) bmenu:copyfrom(menu) bmenu:seek(0x28) o = bmenu:readU32() bmenu:seek(0) bmenu:wseek(0) for i = 78, 144 do v = slus_hacks[0x81ea1][i] if (v == 0) then break end bmenu[o + i - 1] = (v - 1) * 16 end return bmenu end function patch_map(sector, size) local map, font, names, buff font = Input("font.tim") names = Input("names.tim") buff = Buffer(true) buff:writeU32(8) buff:writeU32(font:getsize() + 8) buff:copyfrom(font) buff:copyfrom(names) return buff end function patch_day1(sector, size) local day1, buffs, offs, i, trad, r = nil, {}, {} day1 = cdfile(cdutil, sector, size) for i = 1, 4, 1 do buffs[i] = Buffer() offs[i] = day1:readU32() end day1:seek(offs[4]) offs[5] = offs[4] + day1:readU32() for i = 1, 4, 1 do day1:seek(offs[i]) buffs[i]:copyfrom(day1, offs[i + 1] - offs[i]) end trad = Input("map.bin") buffs[2] = Buffer(true) buffs[2]:copyfrom(trad) buffer_pad(buffs[2]) offs[1] = 0x10 offs[2] = offs[1] + buffs[1]:getsize() offs[3] = offs[2] + buffs[2]:getsize() offs[4] = offs[3] + buffs[3]:getsize() r = Buffer() for i = 1, 4, 1 do r:writeU32(offs[i]) end for i = 1, 4, 1 do r:copyfrom(buffs[i]) end return r end function patch_room(_room, _script, nb) local r, truescriptsize, scriptsize, enlargment, room, script, roomsize, ptrptrs, ptrscriptptrs, oldscriptsize, scriptptr, rest, t, i, nbptrs, add script = Buffer(true) script:copyfrom(_script) buffer_pad(script) r = Buffer() truescriptsize = _script:getsize() scriptsize = script:getsize() roomsize = _room:readU32() room = Buffer(true) ptrptrs = _room:readU32() _room:seek(0) room:copyfrom(_room, roomsize) room:seek(ptrptrs + 32) ptrscriptsptr = andB(room:readU32(), 0xfffff) add = andB(room:readU32(), 0xfffff) add = (andB(room:readU32(), 0xfffff) - add) / 4 room:seek(ptrscriptsptr + 8) oldscriptsize = room:readU32() scriptptr = andB(room:readU32(), 0xfffff) rest = 4 - andB(oldscriptsize, 3) if (rest == 4) then rest = 0 end enlargment = scriptsize - (oldscriptsize + rest) r:writeU32(roomsize + enlargment) r:writeU32(ptrptrs + enlargment) room:seek(8) r:copyfrom(room, scriptptr - 8) r:copyfrom(script) room:seek(scriptptr + oldscriptsize + rest) r:copyfrom(room, ptrptrs - (scriptptr + oldscriptsize + rest)) t = room:readU32() r:writeU32(t) for i = 1, 12, 1 do t = room:readU32() r:writeU32(orB(shl(shr(t, 20), 20), andB(t, 0xfffff) + enlargment)) end r:copyfrom(room, ptrscriptsptr - room:tell() + 8) r:writeU32(truescriptsize) room:readU32() r:writeU32(room:readU32()) for i = 1, add, 1 do r:writeU32(room:readU32()) end nbptrs = (roomsize - room:tell()) / 12 for i = 1, nbptrs, 1 do r:writeU32(room:readU32()) t = room:readU32() r:writeU32(orB(shl(shr(t, 20), 20), andB(t, 0xfffff) + enlargment)) r:writeU32(room:readU32()) end -- r:copyto(Output("output/room-" .. hex(nb, "%04i") .. ".bin")) -- r:seek(0) return r end function apply_hacks(hacks, file) local k, v, i, h for k, v in pairs(slus_hacks) do for i, h in ipairs(v) do file[k + i - 1] = h end end end function buffer_pad(buffer) local rest, i rest = 4 - andB(buffer:getsize(), 3) if (rest == 4) then return end buffer:wseek(0, SEEK_END) for i = 1, rest, 1 do buffer:writeU8(0) end end files = { [1] = "various.bin", [2] = patch_menu, [10] = "font.tim", [70] = "mainmenu.bin", [72] = patch_map, [76] = patch_day1, } slus_hacks = { -- ASM Ptr hack [0x1603c] = { 0xbc }, -- ASM Font hack [0x284e4] = { 0x21 }, [0x28540] = { 0x21, 0x18, 0x00, 0x00 }, [0x28fb8] = { 0x21, 0x18, 0x00, 0x00 }, [0x29074] = { 0x00, 0x00, 0x00 }, -- Text "Susceptible to poison" [0x81c96] = { 0x25, 0x34, 0x3d, 0x38, 0x3c, 0x34, 0x44, 0x47, 0xff }, -- Text "Susceptible to acid" [0x81cc0] = { 0x14, 0x3c, 0x3f, 0x3e, 0x38, 0x42, 0x3e, 0x3d, 0x3d, 0x34, 0x0f, 0x3f, 0x30, 0x41, 0x0f, 0x30, 0x32, 0x38, 0x33, 0x34, 0xff }, -- Text "Easily tranquilized" [0x81ce8] = { 0x22, 0x34, 0x3d, 0x42, 0x38, 0x31, 0x3b, 0x34, 0x0f, 0x30, 0x44, 0x47, 0x0f, 0x43, 0x41, 0x30, 0x3d, 0x40, 0x44, 0x38, 0x3b, 0x38, 0x42, 0x30, 0x3d, 0x43, 0x42, 0xff }, -- Text "Sensitive to heat" [0x81d0e] = { 0x22, 0x34, 0x3d, 0x42, 0x38, 0x31, 0x3b, 0x34, 0x0f, 0x51, 0x0f, 0x3b, 0x30, 0x0f, 0x32, 0x37, 0x30, 0x3b, 0x34, 0x44, 0x41, 0xff }, -- Text "Sensitive to cold" [0x81d32] = { 0x22, 0x34, 0x3d, 0x42, 0x38, 0x31, 0x3b, 0x34, 0x0f, 0x30, 0x44, 0x0f, 0x35, 0x41, 0x3e, 0x38, 0x33, 0xff }, -- Text "Objects easily stolen" [0x81d5a] = { 0x1f, 0x3e, 0x42, 0x42, 0x4e, 0x33, 0x34, 0x0f, 0x33, 0x34, 0x42, 0x0f, 0x3e, 0x31, 0x39, 0x34, 0x43, 0x42, 0x0f, 0x51, 0x0f, 0x45, 0x3e, 0x3b, 0x34, 0x41, 0xff }, -- Text "Gets confused easily" [0x81d85] = { 0x12, 0x3e, 0x3d, 0x35, 0x44, 0x42, 0x38, 0x3e, 0x3d, 0x0f, 0x3f, 0x3e, 0x42, 0x42, 0x38, 0x31, 0x3b, 0x34, 0x0f, 0x34, 0x43, 0x0f, 0x34, 0x35, 0x35, 0x38, 0x32, 0x30, 0x32, 0x34, 0xff }, -- Text "Failed to escape" [0x81dad] = { 0x15, 0x44, 0x38, 0x43, 0x34, 0x0f, 0x4d, 0x32, 0x37, 0x3e, 0x44, 0x4d, 0x34, 0xff }, -- Text "Can't escape!" [0x81dca] = { 0x15, 0x44, 0x38, 0x43, 0x34, 0x0f, 0x38, 0x3c, 0x3f, 0x3e, 0x42, 0x42, 0x38, 0x31, 0x3b, 0x34, 0x2b, 0xff }, -- Font width table [0x81ea1] = { 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 8, 11, 14, 9, 8, 7, 8, 7, 7, 8, 9, 6, 7, 9, 8, 11, 9, 7, 8, 7, 9, 7, 7, 9, 9, 11, 7, 9, 7, 9, 4, 7, 6, 4, 4, 8, 8, 7, 7, 7, 7, 8, 9, 5, 4, 8, 5, 11, 9, 7, 8, 8, 7, 6, 5, 9, 9, 11, 7, 9, 6, 4, 4, 7, -- new chars here 7, 7, 7, 7, 7, 7, 7, 5, 5, 7, 7, 9, 9, 9, 7, 11, 11, 5, 5, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, -- PE.BIN filename extension [0x01b4c] = { 0x54, 0x49, 0x4d }, -- savefile filename [0x016e5] = { 0x38 }, -- Debug room -- [0x2f888] = { }, } groups = { [1] = 1, [2] = 1, [3] = 1, [4] = 1, [5] = 1, [6] = 1, [9] = 1, [10] = 1, [11] = 1, [12] = 1, [13] = 1, [14] = 1, [16] = 1, [17] = 1, [18] = 1, [20] = 1, [21] = 1, [22] = 1, [23] = 1, [24] = 1, [25] = 1, [26] = 2, [27] = 2, [28] = 2, [29] = 2, [30] = 2, [31] = 2, [32] = 2, [33] = 2, [34] = 2, [35] = 3, [36] = 3, [37] = 3, [38] = 3, [39] = 3, [40] = 3, [41] = 4, [42] = 4, [43] = 4, [44] = 5, [45] = 4, [46] = 4, [47] = 4, [48] = 5, [49] = 1, [50] = 1, [51] = 4, [52] = 4, [53] = 4, [54] = 4, [55] = 4, [56] = 4, [57] = 6, [58] = 6, [59] = 6, [60] = 6, [61] = 6, [62] = 6, [63] = 6, [64] = 6, [65] = 6, [66] = 6, [67] = 6, [68] = 6, [69] = 6, [70] = 6, [71] = 6, [72] = 6, [73] = 6, [74] = 6, [75] = 6, [76] = 6, [77] = 6, [78] = 6, [79] = 6, [80] = 6, [81] = 7, [82] = 6, [83] = 6, [84] = 6, [85] = 6, [86] = 6, [87] = 6, [88] = 6, [89] = 6, [90] = 8, [91] = 8, [92] = 8, [93] = 8, [94] = 8, [95] = 8, [96] = 8, [97] = 8, [98] = 5, [99] = 5, [100] = 5, [102] = 5, [103] = 5, [104] = 5, [106] = 5, [107] = 5, [108] = 5, [109] = 5, [110] = 5, [111] = 5, [112] = 5, [113] = 5, [114] = 5, [115] = 5, [116] = 5, [117] = 5, [118] = 5, [120] = 5, [121] = 5, [122] = 5, [123] = 5, [124] = 5, [125] = 9, [126] = 9, [127] = 9, [128] = 9, [129] = 9, [130] = 9, [131] = 9, [132] = 9, [133] = 9, [134] = 9, [135] = 9, [136] = 9, [137] = 9, [138] = 9, [139] = 9, [140] = 9, [141] = 9, [142] = 9, [143] = 9, [144] = 9, [145] = 9, [146] = 9, [147] = 9, [148] = 9, [149] = 9, [150] = 9, [151] = 9, [152] = 9, [153] = 9, [154] = 9, [155] = 9, [156] = 9, [157] = 9, [158] = 9, [159] = 9, [160] = 9, [161] = 10, [162] = 10, [163] = 10, [164] = 10, [165] = 10, [166] = 11, [167] = 11, [168] = 11, [169] = 11, [170] = 11, [171] = 11, [172] = 11, [173] = 11, [174] = 11, [175] = 11, [176] = 11, [178] = 11, [179] = 11, [180] = 11, [181] = 11, [182] = 11, [183] = 11, [184] = 11, [185] = 11, [186] = 11, [187] = 11, [188] = 11, [189] = 11, [190] = 11, [191] = 12, [192] = 13, [193] = 13, [194] = 13, [195] = 12, [196] = 13, [197] = 13, [198] = 13, [199] = 13, [200] = 13, [201] = 13, [202] = 13, [203] = 13, [204] = 13, [205] = 13, [206] = 13, [207] = 13, [208] = 12, [209] = 13, [210] = 13, [211] = 13, [212] = 13, [213] = 13, [214] = 13, [215] = 13, [216] = 13, [217] = 13, [218] = 13, [219] = 13, [220] = 13, [221] = 12, [222] = 13, [223] = 13, [224] = 13, [225] = 13, [226] = 13, [227] = 13, [228] = 13, [229] = 13, [230] = 12, [231] = 13, [232] = 13, [233] = 12, [234] = 13, [235] = 13, [236] = 13, [237] = 13, [238] = 13, [239] = 12, [240] = 13, [241] = 13, [242] = 13, [243] = 13, [244] = 13, [245] = 13, [246] = 13, [247] = 13, [248] = 13, [249] = 13, [250] = 13, [251] = 13, [252] = 13, [253] = 13, [254] = 13, [255] = 13, [256] = 12, [257] = 13, [258] = 13, [259] = 3, [260] = 14, [262] = 14, [263] = 14, [265] = 14, [266] = 14, [267] = 14, [268] = 14, [269] = 14, [271] = 15, [272] = 15, [273] = 16, [275] = 17, [276] = 17, [278] = 17, [279] = 17, [280] = 17, [281] = 17, [282] = 17, [283] = 17, [284] = 17, [285] = 17, [286] = 17, [287] = 17, [288] = 18, [290] = 19, [291] = 19, [292] = 19, [293] = 19, [294] = 19, [295] = 19, [296] = 19, [297] = 19, [298] = 19, [299] = 19, [300] = 19, [301] = 19, [302] = 19, [303] = 19, [304] = 19, [305] = 19, [306] = 19, [307] = 19, [308] = 19, [309] = 19, [310] = 19, [311] = 19, [312] = 19, [313] = 19, [314] = 19, [315] = 19, [316] = 19, [317] = 19, [318] = 19, [319] = 1, [320] = 9, [321] = 9, [322] = 9, [323] = 9, [324] = 9, [325] = 9, [326] = 9, [327] = 9, [328] = 9, [329] = 9, [330] = 9, [331] = 9, [332] = 9, [333] = 14, [334] = 2, [335] = 19, [337] = 5, [339] = 9, [340] = 13, [341] = 13, [342] = 13, [343] = 13, [344] = 13, [345] = 13, [346] = 13, [347] = 20, [348] = 2, [349] = 12, [350] = 17, [351] = 3, [352] = 3, [358] = 6, [359] = 1, [360] = 3, [367] = 1, [371] = 13, [372] = 1, [373] = 1, [374] = 6, [377] = 1, [378] = 1, [379] = 13, [380] = 9, [381] = 9, [382] = 20, [383] = 19, [384] = 19, [385] = 19, [386] = 19, [388] = 19, [389] = 19, [390] = 19, [391] = 19, [392] = 19, [393] = 19, [394] = 19, [395] = 19, [396] = 19, [397] = 19, [398] = 19, [399] = 19, [400] = 19, [401] = 19, [402] = 19, [403] = 19, [404] = 19, [405] = 19, [406] = 19, [407] = 19, [408] = 19, [409] = 19, [410] = 19, [411] = 19, [412] = 19, [413] = 19, [414] = 19, [416] = 19, [417] = 19, [418] = 19, [419] = 19, [420] = 19, [421] = 19, [422] = 19, [423] = 19, [424] = 19, [425] = 17, [426] = 17, [427] = 17, [428] = 17, [429] = 17, [430] = 17, [431] = 1, [432] = 16, [433] = 11, [434] = 19, [435] = 19, [436] = 19, [437] = 19, } picts_files = { "foe.jpg", "tune-up1.jpg", "tune-up2.jpg", "tuto1.jpg", "tuto10.jpg", "tuto11.jpg", "tuto12.jpg", "tuto13.jpg", "tuto14.jpg", "tuto15.jpg", "tuto16.jpg", "tuto17.jpg", "tuto18.jpg", "tuto19.jpg", "tuto2.jpg", "tuto20.jpg", "tuto21.jpg", "tuto22.jpg", "tuto23.jpg", "tuto3.jpg", "tuto4.jpg", "tuto5.jpg", "tuto6.jpg", "tuto7.jpg", "tuto8.jpg", "tuto9.jpg", } mainpatch()