==========I FIGURED IT OUT, SCROLL DOWN TO SEE SOLUTION==========
Linda Cube Again [SCPS-10039] is a Japanese PSX port of Linda Cube, a TurboCD game, that was never released outside of Japan. There's also a Saturn port that came later but I only care about the PSX version. I don't have the [SCPS-45118] or "PlayStation the Best" [SCPS-91142] versions either so I don't know if they are different.
I've played through the game a couple of times, different scenarios to try, and finally decided I'd give translating it a try.
The game disc uses a couple of package files to store its data. I poked around, decompiled them, and found that the text is kept in the LINDA.MIC file in SJIS.
Naturally I jumped for joy when I found that on top of the data not being encrypted when I edited the text in RAM while the game was running I could even throw in half-width (JIS) roman characters and they would display just fine. This means English strings can potentially have double the characters (provided there is text-box space).
Next step was to edit the LINDA.MIC file and reinsert it into the image. So I edited the main menu text and then booted the game. Nothing, the game just hung.
I reverted my changes, reinserted the file, game worked fine.
I looked around for checksums because I figured the game might be checking for file integrity. I found some data that looked promising but when I edited those to zeros and then booted the game it worked just fine.
I've spent days trying different emulators with debug options but have gotten nowhere. Help? Any suggestions would be welcome too.
Even just someone pointing in the right direction to figuring out what the problem is would be of great help. :thumbsup:
===============================
====Test info====
To reproduce a failed load simply extract the LINDA.MIC file somewhere. (Make a backup of your image unless you want to re-rip later or keep a clean LINDA.MIC file somewhere)
0x000C70FF is where the "Menu Options" text is stored. It is between two zeros and the hex is: 83 81 83 6A 83 85 81 5B 91 49 91 F0.
In-game it looks like: メニューé¸æŠž
Editing this will cause a failure to load the game at all since this data is loaded at the start, before any logos or trademarks display. A black screen is all you'll get.
0x020388D2 is where the first text for a new game of Scenario A (Merry Christmas) is stored. The entry is 77 bytes long and is also sandwiched by zeros like the menu string. Unlike the menu text this one also includes non SJIS bytes that are used for text formatting.
After the first 6 bytes is the first word: 83 50 83 93. ケン in-game, "Ken" the main character's name. Changing this string will cause the game to hang when loading Scenario A. The menu and other scenarios will work perfectly fine.
====Technical data====
LINDA.MIC has a table at the start of the file where it stores entries (like files) for the data that follows so the game can load chunks of data at a time using IDs.
The chunks contain more than just string data but for now I'm focusing on the text.
The first 12288 bytes make up the table. With each entry being 16 bytes there are 768 potential entries. Many are left blank however and only 413 slots seem to be used.
Example Entry: 810100004500000067011822C6933C96
The first four bytes are the segment offset (mutiple by 0x800). The second four are the segment length (also mutiply by 0x800). The last four bytes change drastically and seemingly randomly between entries so they are what I had at first assumed to be checksum values. Changing them didn't affect the game at all.
8101 is the Main Menu strings segment ID.
6740 is the first Scenario A strings segment ID.
After the table entries is the strangest part of the file at 0x00003000. Segment byte lengths are represented by the amount of 01 values sandwiched between 03 and 05. 03 signals the start of a length and 05 indicates the end. Even though the table has empty entries in-between the lengths are simply linear without breaks. Since the table entries don't seem to have pointers to their corresponding lengths you have to parse through the 03[01 x ?]05 set from the beginning or build up a separate table of values. In any case, you count up the 01s and multiply the result by 2048 (0x800) to get the segment length in bytes. These are not in the entry orders but rather in the order of the archive itself... unknown purpose.
The real data starts at 0x00011800. Each segment is also itself a package with a look-up table. Thankfully though the look-up method is much simpler. This is less relevant but it seems that the text is stored in the PROG.BIN subfiles.
==================
=====ADDENDUM=====
==================
Haha! Fruition! Apparently I was on the right track thinking that those four final bytes in the entries were checksums. I haven't figured out how to recreate them but I have the next best thing, a way around them. If you zero out ALL of the entry checksums for modified files then any modifications to the text will go undetected. Apparently the ones I was zeroing out before weren't the right ones. Of course, if the data truly were corrupted the game wouldn't notice and try to run it anyways but I don't much care about that right now.
If you want to test the solution it's pretty simple to do with the main menu's text.
0x000C7144 is the location of the main menu's 難易度調整 option.
A literal translation about adjusting difficulty is too cumbersome so lets go with a simple solution: SETUP
Since the text needs to be in SJIS replace 93EF88D5937892B290AE with 8272826482738274826F
Now we need to zero out the checksum at 0x00002B7C
Replace C6933C96 with 00000000 and then insert the modified LINDA.MIC into the disc image.
When you get to the menu you should notice that the option has been modified!
More things I found out are that 8101 controls the main menu and intro stuff but removing it will throw the game into BE42.
EF00 and 0B01 (which come right after 8101) can't be removed, the game won't run without them. They are the in-game menu texts and such.
6740 is the starter for Scenario A. 6842 is the starter for Scenario B. 4144 is the starter for Scenario C.
Removing a starter will cause it to try and find the next available one when starting a new scenario, or skipping to BE42 if none are found.
BE42 is also pretty much essential, the game won't run without it. This is the home town map, outside.
In any case, it works now. If only I could figure out how to get variable width characters
===
Table
===
http://pastebin.com/U0MP2aj1
A nice table of values relevant to LINDA.MIC
EO = Entry Offset
E = The entry in its entirety
FO = File offset
FS = File size
I made a program to create the table for easier testing but it serves a lot of purposes and since siryoink had asked for a table here it is.
http://pastebin.com/B64Hy8TM
Here's another table with the file entries organized by the file order in the archive.
This comes with the bonus of the BSO, the offset for the 0x03 0x01 0x05 sets which also indicate the file size.
===
Decompiler
===
Here's the decompiler program I wrote for LCA, it's not perfect nor optimized but it does the job. MVC++
It handles the MIC file, the PAC file, and a LINDA.SPK file you get when you decompile the PAC file.
The program runs depending on file names, so make sure they are set to their defaults.
http://pastebin.com/pgDmHCxy
--New version, cleaned up the file a little and made sure it works
--Newer version, MIC subfiles now have .DAT extensions so they too can be identified and extracted
----Folders will be created for .DAT subfiles because there are overlapping filenames (PROG.BIN)
The code to make the above table is in there, but it's commented out because the decompile code is currently active.
Just comment one function out and uncomment the other.