[Tutorial] - JAP Games Font Size Hacking ( Nakoruru - SEGAGAGA - Vermillion Desert - Puyo Puyo 4 )
Posted: Mon Apr 11, 2022 3:33 pm
Thanking everyone in DC scene who helped me out in the past, I'd love to take this chance to give back to the community! 
Special credits to Nanashi for introducing and teaching VFW concept / SH4 assemblers, Exant for bitflag ops, Mr.Neo, Ian Micheal and Derek for providing help on DC tools, sharing their HW and RE knowledge!
This tutorial is intended exclusively for educational purposes, it does not have any intention to damage SEGA and/or any other third party developers who owns the rights.
If this does cause any issue, please feel free to remove it anytime.
Preface:
Anyone getting into JP games translation will sooner or later get into a common roadblock.
Let's say our game letters are usually 24x24 px in size ( Wide ), but we need 12x24 px ( Half-width) to efficiently use western characters and optimize text area.

--------------------
How does this method work?
It is based on the assumption that our game adds one letter at a time.

Our target is tracking a RAM variable (character count or offset), leading us to text-drawing function parameters.
In the end we'll alter original function to reduce distance between each letter:

This method advantages are:
[list][*]You can draw a smaller font than the original without resizing the texture
[*]Words can use any custom size, smaller than wide.
[*]It's variable font width-ready[/list]
--------------------
Click Here for "NAKORURU - Ano Hito Kara no Okurimono (JP)"
Click Here for "SEGAGAGA (JP)"
Click Here for "VERMILLION DESERT (JP)"
Click Here for "PUYO PUYO 4 (JP)"
What you will need:
[list][*]Ghidra 10.0.2 or higher
[*]Basic SH-4 asm knowledge
[*]Demul 0.7
[*]Cheat Engine 7.2[/list]
--------------------
DC Font Width Size Hacking Tutorial by VincentNL:
[list]
Index
[*]PART 1-1: SETUP - Ghidra
[*]PART 1-2: SETUP - Cheat Engine
[*]PART 2-1: SEARCH RAM VARIABLE
[*]PART 2-2: LOCK THE VARIABLE
[*]PART 2-3: LOCATE PARAMETERS
[*]PART 2-4: WREAK HAVOC!
[*]PART 3: BREAKPOINTS
[*]PART 4: GHIDRA!
[*]PART 5: HACKING!
[*]PART 6: TESTING![/list]
-------------
[list][*]PART 1-1: SETUP - Ghidra[/list]
1) Let's open Ghidra and drag game executable (1ST_READ.bin, in this case) in the program window.
2) Choose language processor as SuperH4 32 LE, click on OPTIONS button to specify base address 8C010000

3) Once Ghidra loads the file, click on "Auto Analyze".

[list][*]PART 1-2: SETUP - Cheat Engine[/list]
1) Let's open Demul and load the game.
2) Open Cheat Engine, and click on "Open Process" icon:
3) Select Demul with game name, and click Open button:

--------------
[list][*]PART 2-1: SEARCH RAM VARIABLE[/list]
1) Choose any part of the game where text is rendered one letter at a time:

2) Make a savestate before text is shown
3) Switch to Cheat Engine window when text start to show up,If done correctly, Demul will freeze.
4) Let's search for an "Unknown inital value", and hit "First Scan" button:

5) Go back to Demul, and let it continue to draw a few more letters then go back to Cheat Engine.
6) From this time on we will choose "Increased Value" and hit "Next Scan":

7) Now, repeat steps 5-6 until you get a number of results below 500.
Please note, the "Next Scan" is relative to the number of text words rendered!
In case you have exhausted all words and results are still over 500, you can reload the savestate
but you will have to choose "Decreased value" since the value has reset to a lower number.
8) Select results over 0x2c010000 range and ignore those before. Right-click "Add selected..." to put them into Cheat Engine main window.
Why ignore the rest?
Demul allocates executable program memory at 0x2c010000 instead of 0x8c010000!
So yeah, keep this in mind when looking at 0x2c.. in Cheat Engine. Those will be 0x8c.. in Ghidra!
[list][*]PART 2-2: LOCK THE VARIABLE[/list]
Ok now that we have a range of variables, we need to find out which one is handling text offset.
1) On Demul, wait until a couple of letters are rendered in game, then jump to Cheat Engine:
2) Lock all values in main window, by selecting them all and press spacebar. A red X will show up near each address.
3) Reload your savestate
[list][*]PART 2-3: LOCATE PARAMETERS[/list]
*Case A*
If you are lucky, one of those variables will cause text to clutter on the very same spot.
enable/disable locked values until you figure which one is our target, then proceed on this guide step 2-4.
*Case B*
No changes found. We will have to start looking into those address and repeat the process until we find the correct parameters.
Usually RAM values are stored outside of game executable memory, if you check in Ghidra 0x8c0da3dc is where game executable ends.
So let's choose the next one: 0x2C4176D8
[list][*]PART 2-4: WREAK HAVOC![/list]
1) Right click on the value and choose "Browse this memory region":

Usually this present as a set of values, short, long, byte or floats arrays.

2) Now, start messing with them during text rendering will lead you to actually reverse engineer their purpose.
Remember, our target is to have all letters clutter in the same offset! So yeah just "00" each parameter or lock them with "0" value.

Bingo!
We can notice that altering the address 0x2C4176E8 value, affects space between each letter.
The more we reverse engineer now, the easier will be to read the original function in Ghidra.
(keep note of every parameter effect / memory address)
--------------
[list][*]PART 3: BREAKPOINTS[/list]
1) First of all we know 0x8C4176E8 (0x2C4176E8 in Cheat Engine), is a RAM parameter produced by a function inside game executable.
2) We need to track down WHICH function is writing to 0x8C4176E8 and we'll need a breakpoint.
3) Reload the game when that value has not been written yet. (at the beginning of scene)
4) Immediately jump in Cheat Engine Memory window, right click on the value then, --> data breakpoint / break on Write:

5) Now, go back in Demul until game will stop and write down the address in EBX register:

--------------------
[list][*]PART 4: GHIDRA[/list]
You can use any similar tool, but Ghidra is my personal fave. It's free and perfect for the purpose.
1) Go to the address found in EBX register:

Cheat Engine debugs the emulator layer, so it won't work like a proper debugger. But that's fine.
1) That address is a long value, accessed by multiple functions so let's inspect them to find a 0x8C4176E8 write.
(double click on more)

2) Let's follow the first write
3) scroll down the function carefully until you notice a write to 0x8C4176E8:

4) Label it (click on address in red, and press L) as "ram_character_spacing" so it's easier to refer.
--------------
[list][*]PART 5: HACKING![/list]
Let's inspect how this works:
[code]8c019388 c2 62 mov.l @r12=>DAT_8c0637d4,r2 = 0000002Ch
8c01938a 2a 1d mov.l r2,@(0x28,r13)=>ram_character_spacing[/code]
Basically whatever we found in EBX register, were an actual value that gets copied in "r2".
What interest us is that r2 will be finally passed to r13 for being written.
It would be ideal to rewrite the function since it may have different use of that same parameter, but it might not be necessary.
We'll just check the instructions below:

1) As you can see r2 parameter isn't reused until 0x8c01939e, where a new function is stored having a different purpose.
So yeah we may proceed to change r2 value (character spacing), to our likings.
2) We'll use 0x10 as size, so: mov #0x10,r2.
Right click on 0x8c019388 in Ghidra and click on "Patch instruction", we will change:
[code]mov.l @r12,r2 --> mov #0x10,r2[/code]
--------------
[list][*]PART 6: TESTING![/list]
You can now choose to rebuild your game or test it live.
To preview changes, just go back to Cheat Engine at 0x8c01938a and replace 2A1D --> 10E2
Boom!
Please note this method will help you to track down progressive text rendering.
Even if it won't magically patch all different text functions of the game, it should provide a huge boost in RE hopefully making your life easier.


Special credits to Nanashi for introducing and teaching VFW concept / SH4 assemblers, Exant for bitflag ops, Mr.Neo, Ian Micheal and Derek for providing help on DC tools, sharing their HW and RE knowledge!
This tutorial is intended exclusively for educational purposes, it does not have any intention to damage SEGA and/or any other third party developers who owns the rights.
If this does cause any issue, please feel free to remove it anytime.
Preface:
Anyone getting into JP games translation will sooner or later get into a common roadblock.
Let's say our game letters are usually 24x24 px in size ( Wide ), but we need 12x24 px ( Half-width) to efficiently use western characters and optimize text area.

--------------------
How does this method work?
It is based on the assumption that our game adds one letter at a time.

Our target is tracking a RAM variable (character count or offset), leading us to text-drawing function parameters.
In the end we'll alter original function to reduce distance between each letter:

This method advantages are:
[list][*]You can draw a smaller font than the original without resizing the texture
[*]Words can use any custom size, smaller than wide.
[*]It's variable font width-ready[/list]
--------------------
Click Here for "NAKORURU - Ano Hito Kara no Okurimono (JP)"
Click Here for "SEGAGAGA (JP)"
Click Here for "VERMILLION DESERT (JP)"
Click Here for "PUYO PUYO 4 (JP)"
What you will need:
[list][*]Ghidra 10.0.2 or higher
[*]Basic SH-4 asm knowledge
[*]Demul 0.7
[*]Cheat Engine 7.2[/list]
--------------------
DC Font Width Size Hacking Tutorial by VincentNL:
[list]
Index
[*]PART 1-1: SETUP - Ghidra
[*]PART 1-2: SETUP - Cheat Engine
[*]PART 2-1: SEARCH RAM VARIABLE
[*]PART 2-2: LOCK THE VARIABLE
[*]PART 2-3: LOCATE PARAMETERS
[*]PART 2-4: WREAK HAVOC!
[*]PART 3: BREAKPOINTS
[*]PART 4: GHIDRA!
[*]PART 5: HACKING!
[*]PART 6: TESTING![/list]
-------------
[list][*]PART 1-1: SETUP - Ghidra[/list]
1) Let's open Ghidra and drag game executable (1ST_READ.bin, in this case) in the program window.
2) Choose language processor as SuperH4 32 LE, click on OPTIONS button to specify base address 8C010000

3) Once Ghidra loads the file, click on "Auto Analyze".

[list][*]PART 1-2: SETUP - Cheat Engine[/list]
1) Let's open Demul and load the game.
2) Open Cheat Engine, and click on "Open Process" icon:
3) Select Demul with game name, and click Open button:

--------------
[list][*]PART 2-1: SEARCH RAM VARIABLE[/list]
1) Choose any part of the game where text is rendered one letter at a time:

2) Make a savestate before text is shown
3) Switch to Cheat Engine window when text start to show up,If done correctly, Demul will freeze.
4) Let's search for an "Unknown inital value", and hit "First Scan" button:

5) Go back to Demul, and let it continue to draw a few more letters then go back to Cheat Engine.
6) From this time on we will choose "Increased Value" and hit "Next Scan":

7) Now, repeat steps 5-6 until you get a number of results below 500.
Please note, the "Next Scan" is relative to the number of text words rendered!
In case you have exhausted all words and results are still over 500, you can reload the savestate
but you will have to choose "Decreased value" since the value has reset to a lower number.
8) Select results over 0x2c010000 range and ignore those before. Right-click "Add selected..." to put them into Cheat Engine main window.
Why ignore the rest?
Demul allocates executable program memory at 0x2c010000 instead of 0x8c010000!
So yeah, keep this in mind when looking at 0x2c.. in Cheat Engine. Those will be 0x8c.. in Ghidra!

[list][*]PART 2-2: LOCK THE VARIABLE[/list]
Ok now that we have a range of variables, we need to find out which one is handling text offset.
1) On Demul, wait until a couple of letters are rendered in game, then jump to Cheat Engine:
2) Lock all values in main window, by selecting them all and press spacebar. A red X will show up near each address.
3) Reload your savestate
[list][*]PART 2-3: LOCATE PARAMETERS[/list]
*Case A*
If you are lucky, one of those variables will cause text to clutter on the very same spot.
enable/disable locked values until you figure which one is our target, then proceed on this guide step 2-4.
*Case B*
No changes found. We will have to start looking into those address and repeat the process until we find the correct parameters.
Usually RAM values are stored outside of game executable memory, if you check in Ghidra 0x8c0da3dc is where game executable ends.
So let's choose the next one: 0x2C4176D8
[list][*]PART 2-4: WREAK HAVOC![/list]
1) Right click on the value and choose "Browse this memory region":

Usually this present as a set of values, short, long, byte or floats arrays.

2) Now, start messing with them during text rendering will lead you to actually reverse engineer their purpose.
Remember, our target is to have all letters clutter in the same offset! So yeah just "00" each parameter or lock them with "0" value.

Bingo!
We can notice that altering the address 0x2C4176E8 value, affects space between each letter.
The more we reverse engineer now, the easier will be to read the original function in Ghidra.
(keep note of every parameter effect / memory address)
--------------
[list][*]PART 3: BREAKPOINTS[/list]
1) First of all we know 0x8C4176E8 (0x2C4176E8 in Cheat Engine), is a RAM parameter produced by a function inside game executable.
2) We need to track down WHICH function is writing to 0x8C4176E8 and we'll need a breakpoint.
3) Reload the game when that value has not been written yet. (at the beginning of scene)
4) Immediately jump in Cheat Engine Memory window, right click on the value then, --> data breakpoint / break on Write:

5) Now, go back in Demul until game will stop and write down the address in EBX register:

--------------------
[list][*]PART 4: GHIDRA[/list]
You can use any similar tool, but Ghidra is my personal fave. It's free and perfect for the purpose.
1) Go to the address found in EBX register:

Cheat Engine debugs the emulator layer, so it won't work like a proper debugger. But that's fine.
1) That address is a long value, accessed by multiple functions so let's inspect them to find a 0x8C4176E8 write.
(double click on more)

2) Let's follow the first write
3) scroll down the function carefully until you notice a write to 0x8C4176E8:

4) Label it (click on address in red, and press L) as "ram_character_spacing" so it's easier to refer.
--------------
[list][*]PART 5: HACKING![/list]
Let's inspect how this works:
[code]8c019388 c2 62 mov.l @r12=>DAT_8c0637d4,r2 = 0000002Ch
8c01938a 2a 1d mov.l r2,@(0x28,r13)=>ram_character_spacing[/code]
Basically whatever we found in EBX register, were an actual value that gets copied in "r2".
What interest us is that r2 will be finally passed to r13 for being written.
It would be ideal to rewrite the function since it may have different use of that same parameter, but it might not be necessary.
We'll just check the instructions below:

1) As you can see r2 parameter isn't reused until 0x8c01939e, where a new function is stored having a different purpose.
So yeah we may proceed to change r2 value (character spacing), to our likings.
2) We'll use 0x10 as size, so: mov #0x10,r2.
Right click on 0x8c019388 in Ghidra and click on "Patch instruction", we will change:
[code]mov.l @r12,r2 --> mov #0x10,r2[/code]
--------------
[list][*]PART 6: TESTING![/list]
You can now choose to rebuild your game or test it live.
To preview changes, just go back to Cheat Engine at 0x8c01938a and replace 2A1D --> 10E2
Boom!
Please note this method will help you to track down progressive text rendering.
Even if it won't magically patch all different text functions of the game, it should provide a huge boost in RE hopefully making your life easier.
