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

Author Topic: Ao no Kiseki - Modify Font [Solved]  (Read 2521 times)

flame

  • Full Member
  • ***
  • Posts: 120
    • View Profile
Ao no Kiseki - Modify Font [Solved]
« on: December 30, 2016, 10:36:17 pm »
I found this information but it isn't a full solution and I'm not sure how to develop it further.
http://www.heroesoflegend.org/forums/viewtopic.php?t=146

I was able to do it for Zero no Kiseki.
There is a file sfont.itp and regular English letters are loaded from there. I think Japanese letters are loaded from a different file pspfont.dat, but I don't know how to really tell.

The draw goes off and...


This is what the frame looks like when it's done.


Draws of Japanese text don't hit the texture that's in sfont.itp.

In Ao no Kiseki, draws don't hit the letter portion of sfont.itp at all. sfont.itp is still used for those character tags that appear in various game menus. I can change those, that's outside the scope of this.



How can I edit pspfont.dat? The basic idea is the same as in the previous game. We want to replace some letters were are not using, like $@\^_`{|}, with some that we would like to use, like ëéŁíäōüūö.
I am not sure how to begin my investigation of this. pspfont.dat has a header but I can't make sense of it. It looks like that first tile (with the exclamation mark) starts at 0xF3C0. There's a header with what look like pointers, but the targets point past the end of the file. This looks like a variable-width font. Letters like { can't be replaced easily because there's not enough space for its replacement.

pspfont.dat as per CrystalTile: (you can find the CrystalTile settings at the link above)


If it can't be solved we will use just standard letters.
The game's routines will read ascii and SJIS; letters not supported by those won't be usable.

I looked into this more. In pspfont.dat, pixel data is stored in 2bpp format. It is just stored in straight rows that make an enormous image, from left to right.
I wrote code that will convert it to a png image: http://pastebin.com/CU6UqzA5
It's Python 3 and you need the pypng module (and pspfont.dat, of course).

I also made a version that just has all the pixel columns lined up, the image is 16 pixels high by 30,000 long: https://drive.google.com/file/d/0B-My4raeX4wGbEZTNHBtSGJWcWs/view?usp=sharing


So I guess the strategy then is to:
1) find unused letters that match up with widths of those letters we want to use and will show up in-game
2) edit them
3) find a way to convert outputted images back into the 2bpp by pixel columns format

---
OK so at the end of that giant table of what look like pointers, there is a word with the size of the rest of the data.
After that word is the start of the pixel data.
All those numbers that look like pointers are an index into the pixel column that has the start of the letter. It isn't known which letter it is... you need to look at the dump for that.
There are four-byte entries. The least-significant 3 bytes are used to specify the pixel column. The most-significant byte specifies the letter width.
-------------
I have a new extractor:
pspfont.dat extract to png v2: http://pastebin.com/bMFi4mzY

Run extractor.
Convert to indexed color in GIMP, then edit as needed and export to .bmp.
Rename your original pspfont.dat to pspfont.orig
Then run this: pspfont.dat convert back: http://pastebin.com/d80A875X

You can adjust leftmost position and width for each character. Find the leftmost x-position in the image of your character, convert to little endian and search for that value in the table at the front. The first 3 bytes are the x-position and the last byte is the width.

So what is going on here?
That huge table is a list of x-offsets and widths. I did end up modifying them because the result looks nicer when you do.
There's no way of telling which entry is for which character. For the letters we are changing (halfwidth katakana), I figured it out by extracting the image, making a note of the leftmost pixel x-position in that character, and then searching for that value in the table at the front.

At the end of the table there is a word with the size of the rest of the data in the file. The word after that is the start of the pixel data.

« Last Edit: January 01, 2017, 09:33:44 am by flame »