#include #include #include #include #include "cdutils.h" #define index 0x838da #define offset 0x83b78 CODE_BEGINS virtual int startup() throw (GeneralException) { Handle * ir; Handle * iw; cdutils * cd; verbosity = M_INFO; ir = new Input("PE1.bin"); iw = new Output("PE1.bin", 0, 0); cd = new cdutils(ir, iw); printm(M_INFO, "Patch du CD1\n"); patch_img(cd); delete cd; delete iw; delete ir; return 0; ir = new Input("PE2.bin"); iw = new Output("PE2.bin", 0, 0); cd = new cdutils(ir, iw); printm(M_INFO, "Patch du CD2\n"); patch_img(cd); delete cd; delete iw; delete ir; } int patch_img(cdutils * cd) { struct cdutils::DirEntry d_slus, d_pe1; unsigned char * slus; int i, c; String s; int groupes[100][20]; int counts[20]; verbosity = M_INFO; d_slus = cd->find_path("/SLUS_006.62;1"); if (!d_slus.Sector) d_slus = cd->find_path("/SLUS_006.68;1"); d_pe1 = cd->find_path("/PE.IMG;1"); slus = (unsigned char *) malloc(d_slus.Size); cd->read_datas(slus, GUESS, d_slus.Sector, d_slus.Size); int fontei = *((short *)(slus + index + 9 * 2)); Handle * fonte = new Input("fonte.tim"); printm(M_INFO, "Ecriture de la fonte...\n"); cd->write_file(fonte, GUESS, fontei + d_pe1.Sector); delete fonte; Handle * pslus = new Input("PE-SLUS00662-patched.exe"); printm(M_INFO, "Ecriture du SLUS...\n"); cd->write_file(pslus, GUESS, d_slus.Sector); delete pslus; int menui = *((short *)(slus + index + 69 * 2)); Handle * menu = new Input("69/0069.out"); printm(M_INFO, "Ecriture du menu...\n"); cd->write_file(menu, GUESS, menui + d_pe1.Sector); delete menu; int mapi = *((short *)(slus + index + 71 * 2)); int smap = *((short *)(slus + index + 72 * 2)) - mapi; smap *= 2048; Byte * map = (Byte *) malloc(smap); printm(M_INFO, "Ecriture de la carte...\n"); cd->read_datas(map, GUESS, mapi + d_pe1.Sector, smap); fonte = new Input("fonte.tim"); fonte->read(map + 8, fonte->GetSize()); delete fonte; cd->write_datas(map, GUESS, mapi + d_pe1.Sector, smap); free(map); #if 1 int jour1i = *((short *)(slus + index + 75 * 2)); int sjour1 = *((short *)(slus + index + 76 * 2)) - jour1i; sjour1 *= 2048; Byte * jour1 = (Byte *) malloc(sjour1); printm(M_INFO, "Ecriture de la fin du jour 1...\n"); cd->read_datas(jour1, GUESS, jour1i + d_pe1.Sector, sjour1); Handle * jour1text = new Input("scripts/c/map.out"); int sjour1text = jour1text->GetSize(); if (sjour1text & 3) sjour1text = (sjour1text & (~3)) + 4; int pjour1text = *((Uint32 *)(jour1 + 8)) - sjour1text; printf("sj1t = %08x, x = %08x, pj1t = %08x\n", sjour1text, *((Uint32 *)(jour1 + 8)), pjour1text); if (pjour1text < 0) throw GeneralException("Texte trop grand!\n"); *((Uint32 *)(jour1 + 4)) = pjour1text; jour1text->read(jour1 + pjour1text, jour1text->GetSize()); delete jour1text; cd->write_datas(jour1, GUESS, jour1i + d_pe1.Sector, sjour1); Handle * jout = new Output("75.out"); jout->write(jour1, sjour1); delete jout; free(jour1); #else int jour1i = *((short *)(slus + index + 75 * 2)); Handle * jour1 = new Input("75/0075.out"); printm(M_INFO, "Ecriture de la fin du jour 1...\n"); cd->write_file(jour1, GUESS, jour1i + d_pe1.Sector); delete jour1; #endif for (i = 1; i <= 20; i++) { Input groupe(String().set("groupe-%02i.txt", i)); c = 0; while (1) { groupe >> s; if (!s.strlen()) break; groupes[c++][i] = s.to_int(); } counts[i] = c; } for (i = 1; i <= 20; i++) { Handle * f = new Input(String().set("scripts/c/%02i.out", i)); unsigned char * script = (unsigned char *) malloc(f->GetSize()); f->read(script, f->GetSize()); printm(M_INFO, "Groupe %i...\n", i); for (c = 0; c < counts[i]; c++) { int sector, s1, s2, s3, r, size, size2, sizes[2], tptr, uptr, aptr, asiz, maxsize; r = groupes[c][i] - 1; unsigned char * room; sector = *((int *) (slus + offset + r * 8)); s1 = *(slus + offset + r * 8 + 4); s2 = *(slus + offset + r * 8 + 5) | ((*(slus + offset + r * 8 + 6) & 0x0f) << 8); s3 = ((*(slus + offset + r * 8 + 6) & 0xf0) >> 4) | (*(slus + offset + r * 8 + 7) << 4); cd->read_datas((unsigned char *) sizes, GUESS, d_pe1.Sector + sector + s1 + s2, 8); size = sizes[0]; size2 = sizes[1]; room = (unsigned char *) malloc(size); cd->read_datas(room, GUESS, d_pe1.Sector + sector + s1 + s2, size); printm(M_INFO, " Room %i\n", r + 1); tptr = *((int *) (room + size2 + 32)) & 0xfffff; uptr = *((int *) (room + tptr + 4)); aptr = *((int *) (room + tptr + 12)) & 0xfffff; asiz = *((int *) (room + tptr + 8)); maxsize = aptr - uptr + (asiz | 3); // printm(M_INFO, "size2 = 0x%08x\ntptr = 0x%08x\nuptr = 0x%08x\naptr = 0x%08x\nasiz = 0x%08x\nmaxsize = 0x%08x\nsize = 0x%08x\n", size2, tptr, uptr, aptr, asiz, maxsize, f->GetSize()); if (f->GetSize() > maxsize) { printm(M_WARNING, "Script trop grand (%i octets et %i libres)\n", f->GetSize(), maxsize); free(room); continue; } uptr = (uptr + maxsize - f->GetSize()) & (~3); memcpy(room + uptr, script, f->GetSize()); *((int *) (room + tptr + 12)) = uptr | 0x01000000; *((int *) (room + tptr + 8)) = f->GetSize(); cd->write_datas(room, GUESS, d_pe1.Sector + sector + s1 + s2, size); free(room); } delete f; free(script); } free(slus); return 0; } CODE_ENDS