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

virsago Jun 18, 2019.

  1. virsago
    OP

    virsago Member

    Newcomer
    1
    Jun 18, 2019
    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.
    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.
    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.
    ULJS00041_00003.
    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!
     
  2. JamRules

    JamRules .....

    Member
    7
    Jan 9, 2014
    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, Jun 19, 2019
    HoaiTrung97 and virsago like this.
  3. virsago
    OP

    virsago Member

    Newcomer
    1
    Jun 18, 2019
    Japan
    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.

    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.
    The game also doesn't use a full font sheet to draw text. It's segmented like this:

    font.
    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!
     
    JamRules likes this.
  4. virsago
    OP

    virsago Member

    Newcomer
    1
    Jun 18, 2019
    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.
     
    HoaiTrung97 and JamRules like this.
  5. virsago
    OP

    virsago Member

    Newcomer
    1
    Jun 18, 2019
    Japan
    I managed to change the spacing between values:

    09.PNG
    From this...

    10.PNG
    ...to this.

    The change in action:
    ULJS00041_00006.
    Before.

    ULJS00041_00007.
    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?
     
    JamRules and HoaiTrung97 like this.
  6. Kitsu-neechan

    Kitsu-neechan Coffee makes your kokoro go doki doki

    Member
    6
    Apr 9, 2015
    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
     
    JamRules and HoaiTrung97 like this.
  7. virsago
    OP

    virsago Member

    Newcomer
    1
    Jun 18, 2019
    Japan
    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...
     
    JamRules likes this.
  8. virsago
    OP

    virsago Member

    Newcomer
    1
    Jun 18, 2019
    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.
    Before.

    ULJS00041_00008.
    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.
    Before.

    ULJS00041_00011.
    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?
     
  9. JamRules

    JamRules .....

    Member
    7
    Jan 9, 2014
    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, Jun 21, 2019
    virsago likes this.
  10. virsago
    OP

    virsago Member

    Newcomer
    1
    Jun 18, 2019
    Japan
    ...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?
     
  11. JamRules

    JamRules .....

    Member
    7
    Jan 9, 2014
    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, Jun 21, 2019
  12. virsago
    OP

    virsago Member

    Newcomer
    1
    Jun 18, 2019
    Japan
    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!
     
  13. JamRules

    JamRules .....

    Member
    7
    Jan 9, 2014
    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?
     
  14. virsago
    OP

    virsago Member

    Newcomer
    1
    Jun 18, 2019
    Japan
    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.
     
  15. JamRules

    JamRules .....

    Member
    7
    Jan 9, 2014
    United States
    It’ll be loading a float, so s5+0x8 is where the float will be (4 bytes)
     
  16. virsago
    OP

    virsago Member

    Newcomer
    1
    Jun 18, 2019
    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.
     
  17. Kitsu-neechan

    Kitsu-neechan Coffee makes your kokoro go doki doki

    Member
    6
    Apr 9, 2015
    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.
     
    virsago likes this.
  18. virsago
    OP

    virsago Member

    Newcomer
    1
    Jun 18, 2019
    Japan
    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...
     
  19. JamRules

    JamRules .....

    Member
    7
    Jan 9, 2014
    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
     
    virsago likes this.
  20. virsago
    OP

    virsago Member

    Newcomer
    1
    Jun 18, 2019
    Japan
    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.
     
Quick Reply
Draft saved Draft deleted
Loading...