News: 11 March 2016 - Forum Rules
Current Moderators - DarkSol, KingMike, MathOnNapkins, Azkadellia, Danke

Author Topic: Editing text in Shadowrun (SNES)  (Read 3201 times)

the_E_y_Es

  • Jr. Member
  • **
  • Posts: 57
    • View Profile
Editing text in Shadowrun (SNES)
« on: January 18, 2021, 10:54:00 am »
I'm using the BSnes debugger to try and understand how text works in Shadowrun(USA) for the SNES. I thought I'd find text strings in the ROM like in other games, but here it looks like the words and sentences are pieced together on the spot which is really confusing. Example:



In the debugger:



I downloaded the text dumper for Shadowrun SNES available on this site, but all it tells is this:

Quote
[0x0F1136][Dances with Clams does not work for money. He merely requires a donation of 2,000 nuyen to the Tribal Balldance Fund. I sense great need. Do you wish to make a donation?]

Is 0x0F1136 an offset in the ROM, or something else? Because I looked at it in the hex editor, and it doesn't seem like anything to me.

I'm at a loss here. Help?

Jorpho

  • Hero Member
  • *****
  • Posts: 4763
  • The cat screams with the voice of a man.
    • View Profile
Re: Editing text in Shadowrun (SNES)
« Reply #1 on: January 18, 2021, 12:57:29 pm »
I thought I'd find text strings in the ROM like in other games
I don't know what made you think that since it says right on the text dumper page:
Quote
The script is compressed using the Huffman algorithm, using 16-bits codeworks to store 1-2 characters (each character used has the upper bit active), and 0×0A is the end of line character.

Quote
Is 0x0F1136 an offset in the ROM, or something else?
Something else, I guess? The shadowtxt.c source code calls it the "codework", which suggests it is related to Huffman codewords.
https://en.wikipedia.org/wiki/Huffman_coding
This signature is an illusion and is a trap devised by Satan. Go ahead dauntlessly! Make rapid progres!

the_E_y_Es

  • Jr. Member
  • **
  • Posts: 57
    • View Profile
Re: Editing text in Shadowrun (SNES)
« Reply #2 on: January 19, 2021, 09:04:45 pm »
compressed

I see, that's why I didn't recognize the string in the ROM.



^Turns out that 0x0F1136 is the offset for that string after all. I changed a few bytes in it and it produced changes in-game. Of course, the resulting text was just gibberish. The logic of Huffman compression seems simple, but if I don't have the "tree" with the codewords for that string how can I effect the changes I desire? All I want is to change the "2,000" into "1,500", like so:



I edited the uncompressed characters in the RAM to display the above image in-game. That was easy. How do I edit the compressed text in the ROM to display that?
« Last Edit: January 19, 2021, 09:37:35 pm by the_E_y_Es »

phonymike

  • Jr. Member
  • **
  • Posts: 51
    • View Profile
Re: Editing text in Shadowrun (SNES)
« Reply #3 on: January 20, 2021, 12:44:45 am »
The way I would do it, is dump the entire script to plain text, and then change the decompression routine to simply copy the uncompressed text to RAM. If the script dumper could create a file compatible with atlas, you could reinsert the uncompressed script into space at the end of the ROM (expand it) and atlas would update the pointers.

update: There seems to be lots of effort into editing the script to this game but no actual hacks to show for it. This post by RetroHelix links to a zip file with tons of info.

I looked into the code a little bit but couldn't find a pointer table. If you update the script, but your text is longer than what the game already contains, then it will throw off all the text after that. So you recalculate the pointer table. Unless this game somehow works differently than that.

Also on datacrystal there's a ton of information, as well as a python script compressor.
« Last Edit: January 20, 2021, 05:22:21 pm by phonymike »

the_E_y_Es

  • Jr. Member
  • **
  • Posts: 57
    • View Profile
Re: Editing text in Shadowrun (SNES)
« Reply #4 on: January 20, 2021, 10:11:30 pm »
Hello there, I looked into the datacrystal and found this in the "ROM Map" section:

Quote
E8000 to  E8577 = Huffman-coding tree

That should contain the codewords I assume. Don't know exactly how to go about deciphering them but I will look into it tomorrow.

update: There seems to be lots of effort into editing the script to this game but no actual hacks to show for it. This post by RetroHelix links to a zip file with tons of info.
Ah yes, I'm familiar with those files and the persons who provided them (The Admiral and DragoonZero from gamefaqs). There's a lot of useful info in those.

I looked into the code a little bit but couldn't find a pointer table. If you update the script, but your text is longer than what the game already contains, then it will throw off all the text after that. So you recalculate the pointer table. Unless this game somehow works differently than that.

I found a Brazilian-Portuguese translation and the author does mention pointers for the text. What he did was expand the rom and build his own text separately because he could not adapt the original to the translated one.

Also on datacrystal there's a ton of information, as well as a python script compressor.
I downloaded that compressor but could not run it (using the command prompt). I must be doing something wrong. I wonder if it can compress text data? That would be great...

Jorpho

  • Hero Member
  • *****
  • Posts: 4763
  • The cat screams with the voice of a man.
    • View Profile
Re: Editing text in Shadowrun (SNES)
« Reply #5 on: January 20, 2021, 10:53:11 pm »
I downloaded that compressor but could not run it (using the command prompt). I must be doing something wrong.
Well, y'know, if you want someone to suggest what you're doing wrong, you're going to have to give some more details about what you did and what happened.
This signature is an illusion and is a trap devised by Satan. Go ahead dauntlessly! Make rapid progres!

phonymike

  • Jr. Member
  • **
  • Posts: 51
    • View Profile
Re: Editing text in Shadowrun (SNES)
« Reply #6 on: January 22, 2021, 11:12:38 pm »
I did a little searching around in the ROM, and it seems at $80:947A (0x147A unheadered ROM file) there's a pointer table to the conversations. The pointer table is 0x116 bytes in length, and 2 bytes per pointer. You need to take the pointer, and add bank $8D to get the snes memory address. For example, the third pointer 0x6F 0x90 gets byteswapped, and add 0x8D resulting in snes mem pointer $8D:906F (0x6906F unheadered ROM file).

The conversations are shown in conversedump.txt. The conversations have a structure you can see in shadowconverse.c, with a pointer to the character photo, and pointers to possible dialog strings. At least I think this is how it works.

So there's a pointer table for the conversations, and each conversation contains pointers to compressed text strings.

Keep in mind these script dump files may show ROM file locations with an extra 0x200 byte header.
Code: [Select]
66      42     E8966    Tread carefully whelp, you have much to overcome.
This is location 0xE8766 (snes mem $9D:8766) using an unheadered ROM.

the_E_y_Es

  • Jr. Member
  • **
  • Posts: 57
    • View Profile
Re: Editing text in Shadowrun (SNES)
« Reply #7 on: January 25, 2021, 05:09:33 am »
So there's a pointer table for the conversations, and each conversation contains pointers to compressed text strings.
I looked more closely at the Datacrystal ROM map. Could this be it?

Quote
5980 to   5E47 = Text pointers (Lines 1000-1605, mostly)

And looking at the script dump:

Quote
1342     53E     F1336    Dances with Clams does not work for money. He merely requires a donation of 2,000 nuyen to the Tribal Balldance Fund. I sense great need. Do you wish to make a donation?

I think the F1136 offset is for an unheadered rom because when I change any bytes in that location it effects that exact dialogue line.

So if this line is number 1342, its pointer should in that range (5980 to 5E47), correct? I'll look both at 5980 and 5780 just in case and see if I can find the pointer for that specific line.

I appreciate the detailed explanation, thanks man. It's starting to make sense to me now.

phonymike

  • Jr. Member
  • **
  • Posts: 51
    • View Profile
Re: Editing text in Shadowrun (SNES)
« Reply #8 on: January 27, 2021, 11:22:56 pm »
I modified one of the programs to dump these lines, I count 612 of them from the pointer table.

Download it in my next post.

Code: [Select]
[348] 0xF1136
Dances with Clams does not work for money. He merely requires a donation of 2,000 nuyen to the Tribal Balldance Fund. I sense great need. Do you wish to make a donation?

I show it as line 348 (decimal) in the pointer table. Since each pointer is 2 bytes, multiply 348 x 2, and add it to the start of the pointer table 0x5980 and you get pointer 0x5C38. The values at that location are 0x36 0x91. Byteswap them and add 0xE8000 to get the rom location 0xF1336.



The script dump tells us the location 0xF1336 and that's really helpful to know, but you're only allowed to change that line as long as it's shorter than the original text. The pointer table gives us a lot more control. You could make this line longer, and the next line shorter, and just change the pointer to the second line to be farther than it was originally.

The only problem with this pointer table is that it only allows text to be located within a certain range. This might be a different routine than the conversation routine. Maybe these lines could be inserted uncompressed and the routine changed to point to expanded rom space.
« Last Edit: January 29, 2021, 11:23:29 pm by phonymike »

the_E_y_Es

  • Jr. Member
  • **
  • Posts: 57
    • View Profile
Re: Editing text in Shadowrun (SNES)
« Reply #9 on: January 29, 2021, 08:08:41 am »
Your method makes perfect sense, I can find the pointers to any of those lines now. As you said, changing the pointer of the next line to a further address leaves more room for the line I want to edit. The problem is I'd have to rework the next line in a way that is functional and still makes sense in-game. So that's another can of worms...

In theory, if I can change the "2,000" to "1,500" while still keeping within the confines of the original pointers (equal or shorter than the original text, like you said), it would be the perfect solution. In that case, though, I'd still have to figure out what bytes of compressed text become "1,500" when uncompressed. To that end, I tried looking into other compressed text strings that contain "1,500" when uncompressed in-game. Example:

Code: [Select]
[363] 0xF142B
The power be with you for 1,500 nuyen!

I tried copying some of the bytes from that string, in hopes of getting that 1,500. None of them worked. It's like each string of compressed text uses its own codewords, I'm not sure...

Your other suggestion sounds more feasible, maybe I should expand the rom and write my own uncompressed text separately. If I were to change the routine that points to that original line (making it point to my custom line in the expanded space), would the other lines in the game still work normally? IOW, can I change the routine only in regards to that specific line?

Thanks so much for your help!

phonymike

  • Jr. Member
  • **
  • Posts: 51
    • View Profile
Re: Editing text in Shadowrun (SNES)
« Reply #10 on: January 29, 2021, 11:20:09 pm »
I made a lot of progress as far as these "lines" are concerned. The pointer table at 0x5980 points to 612 different lines of text. The "conversations" are different because they are more like chunks of pointers, that vary in size. So the conversations will be a little more difficult, but I hope atlas can deal with it.

I was able to decompress the "lines", and use atlas to insert them into the ROM at 0x101000, and update the pointer table at 0x5980. I also wrote some (messy) asm to copy the uncompressed strings into the memory location for text (0x7E21A0). The only problem is the game doesn't show the text. There looks to be a little more to the text decompression routine than just placing the text at 0x7E21A0, maybe as each letter is decompressed it updates some pointer for something.

I included everything except xkas.exe (v0.06), atlas.exe (1.11), and the Shadow Run ROM. Put those in the main folder, and run make.bat. To extract the script (it's already extracted), in the script_dump folder there's a dump_lines.bat. It puts the output in the previous main folder.

The cool thing is the code for the conversations and the lines come from different areas, so I'm able to filter the "lines" by setting the carry flag. The conversation text does not have the carry flag, so it is decompressed and displayed as normal. So my code can tell the difference. I haven't tested it much at all though, but it at least works for the first few text dialogs.



Hopefully I can get it working in the next several days. If I make more progress, I'll make a projects thread so more people can find this work and hopefully expand to a full Shadow Run script project. I've only seen the text for "lines" and "conversations". I don't see script triggers like giving the player 2,000. The script could say anything, but the game will still only give 2,000.

Download

the_E_y_Es

  • Jr. Member
  • **
  • Posts: 57
    • View Profile
Re: Editing text in Shadowrun (SNES)
« Reply #11 on: February 02, 2021, 05:31:22 am »
This is great!  I gathered the files in one folder like you said, and ran make.bat; but I forgot to expand the rom first, so that atlas can insert the lines at the new address 0x101000. I'm going to download a program to expand it, then try again.

I can't wait to edit some of the text in this game, this is going to be awesome.

I don't see script triggers like giving the player 2,000. The script could say anything, but the game will still only give 2,000.
Don't worry, I got that covered! In this case, the actual amount that is subtracted (2,000 nuyen) is in a different place in the ROM, at offset DD9BE, unheadered. There I can change it to 1,500. :)

phonymike

  • Jr. Member
  • **
  • Posts: 51
    • View Profile
Re: Editing text in Shadowrun (SNES)
« Reply #12 on: February 02, 2021, 11:02:30 pm »
The make.bat copies the original rom to "sr.sfc", so the original is unmodified. Then xkas does this:

Code: [Select]
org $BFFFFF ;pad to 16 mbit
db $00

which expands the sr.sfc by putting a 0x00 right at the 16 mbit position, file address 0x1FFFFF. No need to expand  :thumbsup:

the_E_y_Es

  • Jr. Member
  • **
  • Posts: 57
    • View Profile
Re: Editing text in Shadowrun (SNES)
« Reply #13 on: February 03, 2021, 08:08:35 pm »
Oh right, I got the sr.sfc file and it's 2MB. Looks like you were able to run it on bsnes; it just hangs on my end. It's weird because bsnes is supposed to support expanded roms.