I identified one problem of the Persona 3 Calculator to be that entering the Persona you have and their levels is very cumbersome. One idea of course comes to mind – just read this whole information from the save games!
There are two ways to getting to the necessary files.
The emulator way
One possibility is the way via an emulator such as PCSX2. After saving in the emulator, files for the two memory cards are created. To get the files out of the larger files, use mymc to get a single file. From this file, the actual save game data can be exported using PS2 Save Builder. The end result should have a name like “BESLES-55354Save14” and weigh in around 36 KB.
The memory card way
Unless you’re playing the whole game on an emulator, the much more interesting way to get to the save games is from the memory card. If you have a chip in your PS2 you should be able to get homebrew running on your machine to get the data off, but I have no idea how you would do it. The safest way I found to get saves off a PS2 requires a PS3 as well (you can skip the next part in case you play your game on a PS3 with backwards compatibility).
Using the Memory Card Adaptor sold by Sony, you can upload the files from the Memory Card to a virtual memory card on the PS3 (using the “Memory Card Utility” under the “Game” menu of the PS3). This can then be copied to a USB stick (select the virtual MC, select your save game and press Triangle, choose copy and a USB stick as destination). This results in a folder PS3/EXPORT/PSV with your saves to be created on your USB stick. To get to the saves from there, use the PSV Exporter tool, which will allow you to eport the actual save files. The result should again be a file named similar to “BESLES-55354Save14” and be around 36 KB large. I can confirm that this works even on a PS3 without backwards compatibility.
Btw, using this approach you won’t even be tempted to cheat using the hex editor, since saving as PSV again is not supported by the tool…
The first info
One of the first ways in which save games can differ is in the name you enter, so this seems like a natural way of starting things off. I created two save games: One in which I gave the protagonist the great name “77777777 AAAAAAAA” (to find repetitions) and one with the even better name “01234567 ABCDEFGH” (to see if ascending characters end up in an ascending way). Here’s the output of comparing the two files in Hex Workshop (I switched to Unicode representation to make it easier to see the patterns in the text part):
As you can see, we find a very interesting pattern: at offsets 0x10 and 0x22 in the first file we find a two sequences of length 8 with a trailing 0, which are also repeated a bit below. In the second file, these sequences are in an ascending order – just what we expected, it’s just not ASCII or Unicode. But looking at the sequences gave me another idea: We can deduce that the sequence 80A1 stands for “A”, and 8090 stands for “0” (zero). Subtracting the larger from the smaller yields a difference of 17. Looking at an ASCII chart, we see that the difference between a large “A” (0x41) and a zero “0” (0x30) is just that: 17!
The next idea then is that these characters are just ASCII characters with an offset. In that case, the offset would be the difference between the original ASCII “A” and our “A”, which is 96. This works out for names with mostly regular characters, however, some other characters don’t have the value 80 in the first byte but 82. I’m not sure how names can be entered in the original, but maybe the input in the original is not limited to Romanji and therefore needing Unicode, and during the conversion, the character mapping was changed.
The player level can be found at offset 0xC as a uint16.
This is where my hex editing skills failed me. I haven’t been able to find the played time in the save game not matter what theory I make about the encoding, even though between two saves where only the time should differ no large difference can be found. If anyone knows the location and encoding of the time, I’d love to hear about it.
The amout of money of the protagonist is saved at offset 0x5D60 as a uint32.