Gotta go faster.

Why do this?

I recently watched a presentation on PSP Homebrew Developer Conference by Precise Museum. In the presentation, they talked about their new translation patch for PSP game Puyo Puyo!! 20th anniversary, and a problem they came across while making this patch: If a non full-width character (ie. a character narrower than the font grid) appears in any row other than the first row in the font file, it will not display properly. They worked around this strange bug by shrinking the size of the font and re-arranging the characters.

This raised my interest, because 5 years ago, when I started tinkering around the Wii version of this game in order to make a Chinese translation patch, I came across this bug too. It was not so much of a problem for me, as Chinese characters are all full-width, and I can easily fit a few other characters in the first row. (The Chinese patch was later stalled, because I couldn’t find translators in Chinese Puyo fandom.)

I happened to have Ghidra and some spare time at hand, so I decided to dig into this bug, to find out its cause and potentially a fix. I don’t have much experience in reverse engineering, and I only have did anything to two Unity games (which are very easy to analyze, as they are not obfuscated and their symbols are there in plain sight). Let’s see if I can learn anything this time.

Background: Text formats used by the game

Before we begin, I need to introduce the file formats used by this game to display texts. There are already tools made to edit them: Puyo tools and Puyo text editor. By reading their source code, I can learn about the formats. Let me borrow a image from the presentation:

fnt file structure

The image shows the FNT file, which the game uses to store its font. The file header defines the grid size and character count, and a table follows, describing each character’s UTF-16 encoding and width. After the list is a texture file (GIM on PSP, or GVR on Wii) storing the graphics for each character. Note that the placements of the characters are aligned in the grid defined by the file header, and are not affected by the width written in the table.

There is an MTX file for each FNT file. MTX files store the string data used by the game, and each character in the string are encoded by a 2-byte index in the FNT table. For example, is encoded as 0000 in the font file shown in the image.

The real work

Read More
post @ 2023-10-24

Hello! This is my blog. As you can see, it is a retro-themed blog site, though still using somewhat modern technology. Maybe I’ll make one with vanilla html later.

My posts are written in Chinese first and then some of them will be translated to English by myself. I seperate the 2 sites for now because I couldn’t figure out how to do i18n with Hexo properly.

Read More
⬆︎TOP