Hacking God Eater 2 Translation (Looking for translators!)

DevAlpha

Member
Newcomer
Joined
Nov 11, 2016
Messages
9
Trophies
0
Age
28
Location
Schleswig-Holstein
XP
65
Country
Gambia, The
I'm still watching these threads... to see if the original team is indeed OK with someone else taking over (so far I've only see fans looking for extra help). At this point I could import texts from the officially localized PC game into its PSP version... But it's not like I'm gonna hijack their project or anything... Specially after years of hard work. Still, no need to cancel anything, I guess... XD

~Sky
still watching?
 

YamatoNag

Well-Known Member
Newcomer
Joined
Feb 6, 2022
Messages
54
Trophies
0
Location
cheese
XP
382
Country
Philippines
@SkyBladeCloud , probably you aren't active to this kind of stuff anymore. but do you still have the knowledge to share PRES file structure and how they can be extracted into a proper directory/files and can be repacked?, i know about the blz2 stuff (zlib compression i believe). and i'm planning to dissect and repack god eater 2, at least on the 1.40 ISO + DLC side
 

SkyBladeCloud

Well-Known Member
Member
Joined
Oct 7, 2010
Messages
454
Trophies
1
Age
34
XP
1,448
Country
@SkyBladeCloud , probably you aren't active to this kind of stuff anymore. but do you still have the knowledge to share PRES file structure and how they can be extracted into a proper directory/files and can be repacked?, i know about the blz2 stuff (zlib compression i believe). and i'm planning to dissect and repack god eater 2, at least on the 1.40 ISO + DLC side

Oh, I'm still very much active, though mostly under other handles in different communities. I thought a translation of this version of the game was released late last year. I don't have at hand the codes I developed (7 years ago!) for this game, but if you're curious, I've drafted a few quick C# classes that might give you an idea of how PRES files are structured. But please, do take them just as reference (if at all!), since I've really done them in 20 minutes and hardly tested that they do what they are supposed to with a couple of files... If I recover the (much better developed) code I made back them, I'll give an update!

using System.IO; using System.Collections.Generic; namespace GE2 { class FileInfo { int[] offsets; string[] infos; public FileInfo(BinaryReader reader, int infoCount) { List<int> offsetList = new List<int>(); for(int i = 0; i < infoCount; ++i) offsetList.Add(reader.ReadInt32()); offsets = offsetList.ToArray(); List<string> infoList = new List<string>(); for(int i = 0; i < infoCount; ++i) { reader.BaseStream.Position = offsets[i]; string info = ""; char c = reader.ReadChar(); while(c != '\0') { info += c; c = reader.ReadChar(); } infoList.Add(info); } infos = infoList.ToArray(); } public string getName() { if(infos.Length == 0) return ""; return infos[0]; } public string getType() { if(infos.Length < 2) return ""; return infos[1]; } } }

using System; using System.IO; namespace GE2 { class FileData { string fileName; string fileType; string fullName; BinaryReader binaryReader; long offset; int size; int decSize; public FileData(BinaryReader reader, int compressedSize, int decompressedSize, string name, string type) { fileName = name; fileType = type; fullName = fileName; if(fileType != "") fullName += '.' + fileType; binaryReader = reader; offset = binaryReader.BaseStream.Position; size = compressedSize; decSize = decompressedSize; } public void extract(string outDirectory) { Console.WriteLine("Processing File: " + fullName); binaryReader.BaseStream.Position = offset; byte[] data = binaryReader.ReadBytes(size); if(decSize != 0 && size != 0 && size < decSize) { data = BLZ2.decompress(data); if(data.Length != decSize) throw new Exception("Error in decompression?"); } switch(fileType) { case "res": { Directory.CreateDirectory(outDirectory + '/' + fullName); Pres extracted = new Pres(data); extracted.extract(outDirectory + '/' + fullName); break; } case "tr2": { try { TR2 tr2 = new TR2(data); StreamWriter writer = new StreamWriter(outDirectory + '/' + fullName + ".txt"); tr2.extract(writer); writer.Flush(); writer.Close(); } catch(Exception) { } goto default; } default: { File.WriteAllBytes(outDirectory + '/' + fullName, data); break; } } } } }

using System.IO; namespace GE2 { class FileEntry { enum AddressMode { Package = 0x4, Data = 0x5 }; int dataSector; AddressMode addressMode; int compressedSize; int infoOffset; int infoCount; byte[] zeroes; public int decompressedSize; FileInfo info; FileData data; public FileEntry(BinaryReader reader) { int datum = reader.ReadInt32(); dataSector = datum & 0x0fffffff; addressMode = (AddressMode)((datum & 0xf0000000) >> 28); compressedSize = reader.ReadInt32(); infoOffset = reader.ReadInt32(); infoCount = reader.ReadInt32(); zeroes = reader.ReadBytes(0x0C); decompressedSize = reader.ReadInt32(); if(datum == 0) return; long currentOffset = reader.BaseStream.Position; reader.BaseStream.Position = infoOffset; info = new FileInfo(reader, infoCount); int dataOffset; BinaryReader dataReader; switch(addressMode) { case AddressMode.Package: dataOffset = dataSector * 0x800; dataReader = Program.package; break; case AddressMode.Data: dataOffset = dataSector * 0x800; dataReader = Program.data; break; default: dataOffset = dataSector; dataReader = reader; break; } dataReader.BaseStream.Position = dataOffset; data = new FileData(dataReader, compressedSize, decompressedSize, info.getName(), info.getType()); reader.BaseStream.Position = currentOffset; } public void extract(string outDirectory) { if(data != null) data.extract(outDirectory); } } }

using System.IO; namespace GE2 { class EntryGroup { int offset; int entryCount; FileEntry[] entries; public EntryGroup(BinaryReader reader) { offset = reader.ReadInt32(); entryCount = reader.ReadInt32(); entries = new FileEntry[entryCount]; long currentOffset = reader.BaseStream.Position; reader.BaseStream.Position = offset; for(int i = 0; i < entryCount; ++i) entries[i] = new FileEntry(reader); reader.BaseStream.Position = currentOffset; } public void extract(string outDirectory) { for(int i = 0; i < entryCount; ++i) entries[i].extract(outDirectory); } } }

using System.IO; namespace GE2 { class Pres { int header; int groupOffset; byte groupCount; byte groupVersion; short unk; int version; int dataOffset; EntryGroup[] groups; public Pres(string file) { byte[] presData = File.ReadAllBytes(file); process(presData); } public Pres(byte[] presData) { process(presData); } void process(byte[] presData) { BinaryReader reader = new BinaryReader(new MemoryStream(presData)); header = reader.ReadInt32(); groupOffset = reader.ReadInt32(); groupCount = reader.ReadByte(); groupVersion = reader.ReadByte(); unk = reader.ReadInt16(); version = reader.ReadInt32(); reader.BaseStream.Position = groupOffset; //Only PSP version? groups = new EntryGroup[groupCount]; for(int i = 0; i < groupCount; ++i) groups[i] = new EntryGroup(reader); } public void extract(string outDirectory) { for(int i = 0; i < groupCount; ++i) groups[i].extract(outDirectory); } } }

EDIT: In the above code, you may ignore the RES/TR2/BLZ2 stuff (you seem to have figured some of them out already, and I'm running out of time for today :P).

Fun fact! This is one of 3 games (the other ones being Valkyrie Profile: CotP for DS, and Tales of Rebirth for PS2), that I had to cancel with virtually the full game translated and pending test (and image edition), due to the toxicity of their respective fanbases 🤦. Well, maybe it's not such a fun fact, but who knows, maybe in the future if I have time ;).

Regards,

~Sky
 
Last edited by SkyBladeCloud,

YamatoNag

Well-Known Member
Newcomer
Joined
Feb 6, 2022
Messages
54
Trophies
0
Location
cheese
XP
382
Country
Philippines
Thanks a Bunch Sky, this can be useful on future projects on mine, but my knowledge on blz2 is okay, and for tr2, there's already a existing TR2 Editor, and for the KST and RES file, im rusty about it. also as for the DLC counterparts might need its own code too?, since it has `PATCH.EDAT` (an rdp in disguise), and a `SYSTEM_UPDATE.EDAT` (which is system.res but updated for the DLCs?) and I dunno what's the AddressMode for it. And as for repack C# reference, we might need it
Post automatically merged:

back then with my old ass account before i forgot the password, i thought coldbird gave you the tools for GOD EATER 2, back then too i was scouring around some file structure or any documentation of this game but empty handed, but this'll help me for now. and i'll glad to receive any more of your documentations if you can still add more though, but for now this will guide me.
Post automatically merged:

even though it's translated, @SkyBladeCloud. the tools provided were not good at all and only extracts the text. (which the results of repacking can be bad too), and the version it supported is 1.30.
Post automatically merged:

also in my theory that the TR2 should extracted in its regular file state instead of extracting the text only parts inside of the TR2 file, dunno why it would act weird when only extracting the text. And for the text buffer limitations (during in missions) it limits the enemy text to 10 characters, above that it will crash the game, so decompiling `EBOOT.BIN` is necessary to relocate this (which my brain can't find for no reason at all)
 
Last edited by YamatoNag,

YamatoNag

Well-Known Member
Newcomer
Joined
Feb 6, 2022
Messages
54
Trophies
0
Location
cheese
XP
382
Country
Philippines
Got any updates so far @SkyBladeCloud?


Although I'm in no rush, I'm still try to disassemble properly God Eater 2's EBOOT.BIN since each time I do disassembly on Ghidra with the Allegrex CPU from kotcrab, it seems to show multiple errors. So mostly im on dead end. Considering translating the enemy texts limits me to 10 characters

:)
 

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
    SpookyBaker @ SpookyBaker: What the hell