Hacking Super Robot Wars MX Portable - Tips for using ASM to shrink the font/change the font encoding?

virsago

Member
OP
Newcomer
Joined
Jun 18, 2019
Messages
19
Trophies
0
Age
33
XP
97
Country
Japan
Hi everyone,

Lately I've been playing around with Super Robot Wars MX Portable for a potential translation. I managed to find the game's script and other text using MadEdit and used Cartographer to dump them. Playing with the game's files, I discovered it only supports full width Shift-JIS encoding. I learned a bit about ASM from the scant amount of PSP hacking documentation available and have been playing around with PPSSPP's disassembly and GE debugger to see how I might go about changing the width of the in-game font so it could support a thinner English font.

ULJS00041_00000.jpg
This is how the game's text normally looks.

01.PNG
I used the GE debugger to find out where the width of each character is written and set a breakpoint accordingly, which is at 08806618. The width of the first character, as shown in the memory view, is 66. At 0x08806614, the game takes the value of t2, adds it to a1, and stores it in t0. From playing around with the RAM, I found out that adding 8 bytes to 08806618 shrinks the font width by half, so my goal is to find out how to achieve this.

02.PNG

Just to play around and see what would happen if hardcoded this increase in myself, I changed the opcode from addu to addiu and changed t2 to 0x8.

ULJS00041_00001.png
This was the result. The characters shrink in width, but the spacing is the same. I thought it was a good start, until I entered battle to see if anything broke because of what I changed.

ULJS00041_00002.png
ULJS00041_00003.png
Sure enough, unit health bars are busted and the portrait and text boxes at the bottom suddenly shift to the left.

If you couldn't tell, I'm a total beginner with ASM and only really understand playing around which values to change, not so much where to appropriately change them. I was wondering if anyone had some tips on where to go from here. Obviously I need to nail down where the change in spacing of characters occurs, but more importantly I want to be able to shrink the text without breaking health bars and other textures. I have a feel confident about the actual translation part, but I don't want to move forward with that until I square this away. Any help would be appreciated!
 

JamRules

.....
Member
Joined
Jan 9, 2014
Messages
527
Trophies
1
XP
2,204
Country
United States
I guess you might be able to find some use out of where other variable width font hacks have been discussed e.g.

https://gbatemp.net/threads/psp-asm-hacking-for-variable-width-font.374967/

https://gbatemp.net/threads/queens-...nslation-project-hackers-needed.383510/page-2

Of course, every game is different.

Edit: My initial advice would be that instead of adjusting the width of each character, you’ll want to adjust the offset that is being applied to the x position.
You may also want to edit the font sheet itself, e.g. so that the characters align to the left. From the text in the examples it’s hard to tell but I assume that standard a-z are not using variable width already since you’re asking.
 
Last edited by JamRules,

virsago

Member
OP
Newcomer
Joined
Jun 18, 2019
Messages
19
Trophies
0
Age
33
XP
97
Country
Japan
I guess you might be able to find some use out of where other variable width font hacks have been discussed e.g.

links removed because the site thinks i'm spamming!

Of course, every game is different.
I've had that first link open in a tab for days now actually, but I'm reading the second now. Coincidentally, I've also been using flame1234's ASM tutorial for Blaze Union. Those two links have basically gotten me to where I am now.

Edit: My initial advice would be that instead of adjusting the width of each character, you’ll want to adjust the offset that is being applied to the x position.
You may also want to edit the font sheet itself, e.g. so that the characters align to the left. From the text in the examples it’s hard to tell but I assume that standard a-z are not using variable width already since you’re asking.
Currently, the game only supports 2 byte Shift-JIS characters. The game's script is not compressed, so it's easy to go in and change the text, but it won't show anything besides full-width Shift-JIS.

For example:
ULJS00041_00004.png
The game also doesn't use a full font sheet to draw text. It's segmented like this:

font.png

As you can see, the bottom of the bottom characters are all cut off. It looks like the game loads the necessary segments of a single font sheet texture file in order to draw text. I'm actually not sure how to pull the full thing out of the game.

Either way, I still have more work to do. Thanks for taking the time to look and provide some help!
 
  • Like
Reactions: JamRules

virsago

Member
OP
Newcomer
Joined
Jun 18, 2019
Messages
19
Trophies
0
Age
33
XP
97
Country
Japan
I wanted to show how the game determines vertices for text before heading to bed.

06.PNG
The routine.

03.PNG
04.PNG
05.PNG
It takes the second x-coordinate and uses it as the first x-coordinate in the proceeding rectangle and so on. Gotta play around with it more in the morning.
 

virsago

Member
OP
Newcomer
Joined
Jun 18, 2019
Messages
19
Trophies
0
Age
33
XP
97
Country
Japan
I managed to change the spacing between values:

09.PNG

From this...

10.PNG

...to this.

The change in action:
ULJS00041_00006.png

Before.

ULJS00041_00007.png

After.

However, I learned that making this adjustment also affects how text is drawn on the attack menus... in a negative way. Meaning, the spacing on those menus increases instead of decreases.

08.PNG

Before.
07.PNG

After.

Reducing the value added at the offset fixes these, but squishes the text even further. I'm not even sure if this is a problem yet, honestly, but I was happy to see that I could control spacing between characters without breaking the health bars or other battle scenery. Any idea on where to go from here?
 

Kitsu-neechan

Coffee makes your kokoro go doki doki
Member
Joined
Apr 9, 2015
Messages
307
Trophies
0
Age
36
XP
1,830
Country
Finland
the original opcode uses register s1 for the spacing value, which you hardcoded into 0xF
next thing to do is to look into where the original value in register s1 comes from, then possibly modify the routines that control what that value is in different places of the game
 

virsago

Member
OP
Newcomer
Joined
Jun 18, 2019
Messages
19
Trophies
0
Age
33
XP
97
Country
Japan
the original opcode uses register s1 for the spacing value, which you hardcoded into 0xF
next thing to do is to look into where the original value in register s1 comes from, then possibly modify the routines that control what that value is in different places of the game
Yeah that's what I'm working on now. Obviously hardcoding is not the way to go about it, so I'm trying to work my way up to see where s1 gets its value from. The game actually does a lot of juggling of different registers when drawing and spacing text, so this might take a while...
 
  • Like
Reactions: JamRules

virsago

Member
OP
Newcomer
Joined
Jun 18, 2019
Messages
19
Trophies
0
Age
33
XP
97
Country
Japan
I worked my way up and found where s1 is getting that spacing value from.
11.PNG

$f0 is out of my understanding of MIPS, but 088B2DB4 is where the spacing value for the game's text is added to s1 and used throughout.

12.PNG

I replaced it with li just to see what would happen.

ULJS00041_00000.png

Before.

ULJS00041_00008.png

The result is I was able to reduce the spacing without ruining it for every screen! However, it does off-center certain characters on the attack select menu.

ULJS00041_00010.png

Before.

ULJS00041_00011.png

After.

This isn't so tragic to me, but now I'm wondering if there's a way to fix the way these particular characters are drawn without spoiling the rest of the game's text.

I'm pretty happy I finally found this, but I am concerned that it's still a bit of an arbitrary fix. I don't know where that $f0 value comes from and don't know much about it, other than it's a floating point register. It kind of just materializes in the disassembly out of nowhere. Can anyone shed some light on this?
 

JamRules

.....
Member
Joined
Jan 9, 2014
Messages
527
Trophies
1
XP
2,204
Country
United States
It looks like you’re adjusting the width of the characters, not the spacing.

f0 will be for holding a float value.
You can see above where it calls lwc1 where it is actually setting the value.
Trunc.w.s will then be changing it to an int I suppose.

Edit: looks like your making some good progress :yaypsp:

You should be able to see the fX values by tabbing the registers on the left of the disasm window
 
Last edited by JamRules,
  • Like
Reactions: virsago

virsago

Member
OP
Newcomer
Joined
Jun 18, 2019
Messages
19
Trophies
0
Age
33
XP
97
Country
Japan
It looks like you’re adjusting the width of the characters, not the spacing.

f0 will be for holding a float value.
You can see above where it calls lwc1 where it is actually setting the value.
Trunc.w.s will then be changing it to an int I suppose.

Edit: looks like your making some good progress :yaypsp:

You should be able to see the fX values by tabbing the registers on the left of the disasm window
...yeah that does look like width lol

lwc1 is indeed setting the value in f0, but strangely f0 is cleared after the trunc.w.s. offset. There has to be something in it though, since it gets loaded into s1 as the spacing value. Is there something I'm not getting about float registers/coprocessor instructions?
 

JamRules

.....
Member
Joined
Jan 9, 2014
Messages
527
Trophies
1
XP
2,204
Country
United States
It should appear like it is cleared because it is no longer a valid float but if you (double) click the value in the left hand registers panel to edit it you should be able to see the hex value, I think
 
Last edited by JamRules,

virsago

Member
OP
Newcomer
Joined
Jun 18, 2019
Messages
19
Trophies
0
Age
33
XP
97
Country
Japan
It should appear like it is cleared because it is no longer a valid float but if you (double) click the value in the left hand registers panel to edit it you should be able to see the hex value, I think
You were right, the value is still there even if it says 0. This presents a new problem though: the value in f0 is set to 00000010 even before this set of instructions we're looking at now, so it's getting that value from somewhere earlier...

Back in I go!
 

JamRules

.....
Member
Joined
Jan 9, 2014
Messages
527
Trophies
1
XP
2,204
Country
United States
Lwc1 should be loading the value from the location to f0, are you sure it’s not just that it has the same value before for something else?
 

virsago

Member
OP
Newcomer
Joined
Jun 18, 2019
Messages
19
Trophies
0
Age
33
XP
97
Country
Japan
Lwc1 should be loading the value from the location to f0, are you sure it’s not just that it has the same value before for something else?
I'm thinking it probably is for something else. the s5 that lwc1 is loading into f0 is set to 08D8C588. As for what that is or means... I have no idea. :unsure: Disassembly shows "wrpgpr ---unknown---" when I jump to that address, so I think I'm looking at the wrong thing completely.
 

virsago

Member
OP
Newcomer
Joined
Jun 18, 2019
Messages
19
Trophies
0
Age
33
XP
97
Country
Japan
Having played with the GE debugger for hours at this point, I'm not even sure if there's a way to adjust spacing between characters. If there is, it's out of my expertise. The aforementioned register juggling sees to that. The only thing I can think of is if there's a way to intercept what goes on between drawing characters instead of just chasing specific values and seeing what happens when I play with them. For now, I'm off.
 

Kitsu-neechan

Coffee makes your kokoro go doki doki
Member
Joined
Apr 9, 2015
Messages
307
Trophies
0
Age
36
XP
1,830
Country
Finland
it really depends on how the game actually handles crap like that.
i cant speak for this game since i have zero idea how the font structure and the text parser looks like, but for example, in zill o'll im working on, the font attribute table is built in a way that
each glyph has it's width, and it's "tile width" marked separately.
im not even sure where it uses the glyph width since the tiles are just drawn next to eachother and the spacing comes from the fact that there is an empty space defined into each glyph tile.

then again, zill o'll uses a variable width font so it has a fairly comprehensive table structure for drawing text. a constant width font doesnt need such a thing as it can just be hardcoded to increment the draw coordinate, which generally is the case.
 
  • Like
Reactions: virsago

virsago

Member
OP
Newcomer
Joined
Jun 18, 2019
Messages
19
Trophies
0
Age
33
XP
97
Country
Japan
it really depends on how the game actually handles crap like that.
i cant speak for this game since i have zero idea how the font structure and the text parser looks like, but for example, in zill o'll im working on, the font attribute table is built in a way that
each glyph has it's width, and it's "tile width" marked separately.
im not even sure where it uses the glyph width since the tiles are just drawn next to eachother and the spacing comes from the fact that there is an empty space defined into each glyph tile.

then again, zill o'll uses a variable width font so it has a fairly comprehensive table structure for drawing text. a constant width font doesnt need such a thing as it can just be hardcoded to increment the draw coordinate, which generally is the case.
The font is fixed width and the "spacing" between characters is baked into the font sheet. I can change spacing by messing with the rectangle draws in memory, but I haven't quite nailed how to do it in assembly. I think the problem is that because the font is fixed and incremented to draw the next rectangle, there's no way to set spacing in assembly without just shifting the text to the left or using a hardcoded solution. We'll see...
 

JamRules

.....
Member
Joined
Jan 9, 2014
Messages
527
Trophies
1
XP
2,204
Country
United States
Of course I don’t know the case for this particular game but I would expect that there would be somewhere that it loops per character as it needs to set the correct UV.
So I expect there should be a way to change the constant x offset based on the character just added. If the offset is not constant you could apply a scaler depending on the character e.g. m would be 1 but i might be 0.5
 
  • Like
Reactions: virsago

virsago

Member
OP
Newcomer
Joined
Jun 18, 2019
Messages
19
Trophies
0
Age
33
XP
97
Country
Japan
Of course I don’t know the case for this particular game but I would expect that there would be somewhere that it loops per character as it needs to set the correct UV.
So I expect there should be a way to change the constant x offset based on the character just added. If the offset is not constant you could apply a scaler depending on the character e.g. m would be 1 but i might be 0.5
That's where I'm at now (although doing my own scaler is way out of my expertise for now). I isolated the beginning of the text drawing routine and can see where the first x-coordinate is prepared. The main issue is that value ends up in up to 4 different registers before the next character is drawn, and apparently so does the spacing value.
 

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
  • No one is chatting at the moment.
    SylverReZ @ SylverReZ: Also nice. Never really watched Fallout on Prime, but sounds like a good show.