+  RHDN Forum Archive
|-+  Romhacking
| |-+  ROM Hacking Discussion
| | |-+  Linda Cube Again (PSX - J) Hacking Help Needed [GOT IT]
Pages: [1]
Author Topic: Linda Cube Again (PSX - J) Hacking Help Needed [GOT IT]  (Read 1 times)
ZeikJT
Guest
« on: March 21, 2011, 04:26:07 pm »

==========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 Cheesy

===
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.
« Last Edit: March 26, 2011, 03:52:37 pm by ZeikJT »
KM
Guest
« Reply #1 on: March 22, 2011, 06:43:35 pm »

Do you have a translator for the game yet?
siryoink
Guest
« Reply #2 on: March 22, 2011, 07:05:11 pm »

Quote from: ZeikJT on March 21, 2011, 04:26:07 pm
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 50. ケン 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.

Not sure what else is going on here, but it's almost impossible for 83 50 83 50 to show up as ケン in-game.  Do you have a table file built for this, and what program are you using to make the changes?
ZeikJT
Guest
« Reply #3 on: March 22, 2011, 07:05:26 pm »

Quote from: KM on March 22, 2011, 06:43:35 pm
Do you have a translator for the game yet?
This is more of a hobby project that I was going to do for fun on my own.
Of course, if I figure out how to get editing the game resources to work I wouldn't mind sharing that information.

Quote from: siryoink on March 22, 2011, 07:05:11 pm
Quote from: ZeikJT on March 21, 2011, 04:26:07 pm
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 50. ケン 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.

Not sure what else is going on here, but it's almost impossible for 83 50 83 50 to show up as ケン in-game.  Do you have a table file built for this, and what program are you using to make the changes?

Whoops, accidentally copied my testing "ケケ" SJIS data. Fixed the first post.
I'm just using a hex editor for now and I haven't built a table, I just extracted the segments. I don't want to write a program if I can't figure out why re-insertion doesn't work.
Ryusui
Guest
« Reply #4 on: March 22, 2011, 11:24:00 pm »

There's probably a checksum in there if changing a single byte causes the game to hang. It should still be hackable; you'll just need to do a bit more homework (and code your own extractor/inserter).
ZeikJT
Guest
« Reply #5 on: March 22, 2011, 11:53:28 pm »

Quote from: Ryusui on March 22, 2011, 11:24:00 pm
There's probably a checksum in there if changing a single byte causes the game to hang. It should still be hackable; you'll just need to do a bit more homework (and code your own extractor/inserter).

Yeah, I also think there must be some checksum somewhere that I haven't tracked down yet... I'm just seeing if anyone can help.

I wrote some decompilers for the game's storage files (PAC, MIC, and SPK) but I haven't needed to re-insert yet.
There were some TIM files in the PAC file that I converted to PNG which was a nice and easy find.
The music was also in there in SEQ/VH/VB combos that I transcoded to PSFs and then into MP3s.
The movie and audio streams (voices and sound effects) were easy enough to rip off the disc too.

Editing-wise, so far I've just edited LINDA.MIC and then re-insert it into the disc image with CDMage for testing.
So far the problem persists.

I've got PCSXTrace to output the opcodes being run, trying to pin down the error/checksum calculation isn't easy.
I've tried to look for the checksum code in the ELF file with PS2Dis, found nothing... but it was a lot of code and I was scanning.
PSXJin was nice for memory searching... but nothing really came out of it except finding out that JIS characters work.
pSX has the realtime debugging but I've never been able to isolate the problem this way either.

I haven't given up, oh no. I'm chugging along trying to track down the source of the problem. If anyone happens upon the answer first though, do tell  :angel:
Are there any specific tools I should be using to track down a problem like this?
gadesx
Guest
« Reply #6 on: March 23, 2011, 01:15:28 pm »

hi, my friend CUE made a program for this game, he says that the script have a checksum system
and its neccesary to hack for translate any text:
http://romxhack.esforos.com/proyectos-de-traduccion-a-ingles-para-hablar-del-tema-t43
ZeikJT
Guest
« Reply #7 on: March 23, 2011, 02:56:38 pm »

Quote from: gadesx on March 23, 2011, 01:15:28 pm
hi, my friend CUE made a program for this game, he says that the script have a checksum system
and its neccesary to hack for translate any text:
http://romxhack.esforos.com/proyectos-de-traduccion-a-ingles-para-hablar-del-tema-t43

First of all, thanks for spreading the word to another forum! Getting help should be easier if more people know.
CUE seems to have gotten as far as I have. There must be some checksum routine, but where it is or how it works is unknown.
It's cool that he too wrote a decompiler. Mine is much less elegant, no error checking because I assume I'm decompiling the correct file  Tongue
Oh and don't worry, I know Spanish so reading the thread was not a problem.
Tom
Guest
« Reply #8 on: March 25, 2011, 10:09:36 pm »

Good luck! :thumbsup:

Heck, I wanted to translate this myself, but I didn't know anybody was willing to hack it... And yet you're going to hack AND translate it. That's awesome. I will definitely give it a try when you're done.
ZeikJT
Guest
« Reply #9 on: March 25, 2011, 10:32:44 pm »

Quote from: Tom on March 25, 2011, 10:09:36 pm
Good luck! :thumbsup:

Heck, I wanted to translate this myself, but I didn't know anybody was willing to hack it... And yet you're going to hack AND translate it. That's awesome. I will definitely give it a try when you're done.

Hmm... honestly, the hacking is really the part I wanted to do. Translating is the tedious and less fun aspect. If I can figure out a reliable way to get the text out of the progbin files I would be happy to provide it for others to translate. The hard part is the space limitations of the text box and finding out more about the progbin files. If I can get those problems out of the way and make it easy for translators to get to work then I will. I'm working on it though! If you'd be willing to translate at some point then it'd be welcome.
siryoink
Guest
« Reply #10 on: March 25, 2011, 11:03:20 pm »

I think zeroing out the checksums may be the best you can hope for in this case.  I'm fairly certain almost all hacked games come up with a bad checksum on them.

I ran across this one a while ago and it really looks like an interesting game.  Take 2 parts Monster Rancher, add 1 part Silent Hill, and set blender to "Dragon Quest".  Good work so far!   :thumbsup:
Auryn
Guest
« Reply #11 on: March 26, 2011, 01:24:26 am »

I admit that I didn't read all the thread but just your first post till the 0x020388D2 paragraph that made 75% that i know where your problem is.
U said u have a 2bytes = 1 character (in japanese) and u just overwrote this with the standart ASCII 1byte ) 1 character...right??
In the paragraph 0x020388D2 u say that the text is a mix of 1byte for format and 2 bytes for the text.
This make me think of conflicts with the ASCII u are inserting and the format bytes.
I have the same problem with my project where the game crashed if i used Z, z, J,j or Q but all other letters are fine.
I even got a problem at one point where i translated a text and the game freezed by clicking on a point on screen that wasn't related with that text, when i then changed some other text that was already in english but 2 bytes encoding to 1byte encoding, the game didn't freeze anymore.

So my idea is that u check letter by letter if they crash your game. If none (upper and lower case) freeze your game, i would continue with the checksum theory but there is only one playstation game where i am positive that there is a checksum of some sort and that is a Resident evil game.
ZeikJT
Guest
« Reply #12 on: March 26, 2011, 01:38:47 am »

Quote from: Auryn on March 26, 2011, 01:24:26 am
I admit that I didn't read all the thread but just your first post till the 0x020388D2 paragraph that made 75% that i know where your problem is.
U said u have a 2bytes = 1 character (in japanese) and u just overwrote this with the standart ASCII 1byte ) 1 character...right??
In the paragraph 0x020388D2 u say that the text is a mix of 1byte for format and 2 bytes for the text.
This make me think of conflicts with the ASCII u are inserting and the format bytes.
I have the same problem with my project where the game crashed if i used Z, z, J,j or Q but all other letters are fine.
I even got a problem at one point where i translated a text and the game freezed by clicking on a point on screen that wasn't related with that text, when i then changed some other text that was already in english but 2 bytes encoding to 1byte encoding, the game didn't freeze anymore.

So my idea is that u check letter by letter if they crash your game. If none (upper and lower case) freeze your game, i would continue with the checksum theory but there is only one playstation game where i am positive that there is a checksum of some sort and that is a Resident evil game.

No worries dude, I guess I should have made it more explicit in my post but I figured it out. (Just edited my first post to make it more apparent)
LCA actually allows you to use a mix of 1 byte and 2 byte characters as long as you stick to SJIS and JIS. The formatting is outside that range.
Pages: [1]  


Powered by SMF 1.1.4 | SMF © 2006-2007, Simple Machines LLC