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

Author Topic: Final Fantasy I (NES) - Sprite Editing  (Read 19252 times)

dougeff

  • Sr. Member
  • ****
  • Posts: 358
    • View Profile
Re: Final Fantasy I (NES) - Sprite Editing
« Reply #40 on: September 29, 2015, 08:51:51 am »
Quote
it seems the hex numbers have to be at the right place

Yes. Or, you locate the pointer to the text and adjust it to the new start location of the new text.

It would be a bit easier if you were working from the disassembly, as length changes would automatically adjust the pointer to the text.

Since German words are usually much longer than English, you will eventually run out of space if you keep adjusting all the texts forward. The easiest plan would be to try to fit nearly all translations in the same space as the English.

Edit: here's how to change the pointer(if you aren't using the disassembly)... In FCEUX, when the correct bank is loaded, create a save state just before the game uses the text, search for the text with hex editor in 'RAM' view, find the text location in the memory (somewhere between 8000 and ffff), open the debugger tool, set a breakpoint for reads from that address, reload the save state, when it stops, you can see the code that accesses the text, write down some of the hex numbers around that code, switch hex editor tool to 'ROM', search for those hex numbers, adjust the address numbers to the new start location, reload the save state, see if it worked.
« Last Edit: September 29, 2015, 09:27:42 am by dougeff »
nesdoug.com -- blog/tutorial on programming for the NES

Bregalad

  • Hero Member
  • *****
  • Posts: 2751
    • View Profile
Re: Final Fantasy I (NES) - Sprite Editing
« Reply #41 on: September 29, 2015, 10:07:49 am »
If you haven't already, it is crutial to adapt the DTE tables to the german language, so that your script is reduced in size. If such a thing is possible, it would be be possible to hack the DTE decompression algorithm to support recursivity. My own experience has proven that a text usually compress to 60% of it's size if only normal DTE is used, but can compress down to 30% of it's size if DTE-within a DTE is allowed.

For example you could have "di", "e ", and then have the 4-letter sequence "die " take only one byte instead of 4, resulting in very significant space savings for the game's script.

Another trick is that you could use the same data for "Kaufen" and "Verkaufen" by tricking the pointers

Code: [Select]
VerKaufen
^  ^
|  +--------- Pointer 2
+------------ Pointer 1
Of course we have a problem with the casing, so only do this if you really are short of room.

Quote
But as Disch said, if you're not happy with how it looks, you could take a look at other games to see if there's a font you may like. Or create your own, even.
If the font should be changed I'd suggest using the regular Squaresoft fond they used in FF4 (SNES) and all other SNES and Gameboy-area games they translated in english, that font was slightly improved in the FF3 (NES) english translation.

Before the german defeat in the great war in 1918 the german language was exclusively written using gothic letters that looks super cool but are super annoying to read, you could try to do add this in option if you feel funky.
« Last Edit: September 29, 2015, 02:50:57 pm by Bregalad »

Shokupanda

  • Jr. Member
  • **
  • Posts: 36
    • View Profile
Re: Final Fantasy I (NES) - Sprite Editing
« Reply #42 on: September 29, 2015, 10:23:16 am »
Quote
Edit: here's how to change the pointer(if you aren't using the disassembly)... In FCEUX, when the correct bank is loaded, create a save state just before the game uses the text, search for the text with hex editor in 'RAM' view, find the text location in the memory (somewhere between 8000 and ffff), open the debugger tool, set a breakpoint for reads from that address, reload the save state, when it stops, you can see the code that accesses the text, write down some of the hex numbers around that code, switch hex editor tool to 'ROM', search for those hex numbers, adjust the address numbers to the new start location, reload the save state, see if it worked.



So the game stopped but where exactly can I see the code that accesses the text?

Quote
If you haven't already, it is crutial to adapt the DTE tables to the german language, so that your script is reduced in size. If such a thing is possible, it would be be possible to hack the DTE decompression algorithm to support recursivity. My own experience has proven that a text usually compress to 60% of it's size if only normal DTE is used, but can compress down to 30% of it's size if DTE-within a DTE is allowed.

I actually adapted them already! I made sure that letter combinations which occure often in german language are stored in DTE. I use DTE's like 90% of the time.  :)

Quote
If the font should be changed I'd suggest using the regular Squaresoft fond they used in FF4 (SNES) and all other SNES and Gameboy-area games they translated in english, that font was slightly improved in the FF3 (NES) english translation.

Ah, thank you very much! I'll have a look on them! Sounds great!  :)
Quote
Before the german defeat in the great war in 1918 the german language was exclusively written using gothic letters that looks super cool but are super annoying to read, you could try to do add this in option if you feel funky.

Haha, sounds cool! Although I'm not quite sure if it's possible to make good gothic letters with a space of 16x16px.  :laugh: I'll keep it in mind, though!


Disch

  • Hero Member
  • *****
  • Posts: 2814
  • NES Junkie
    • View Profile
Re: Final Fantasy I (NES) - Sprite Editing
« Reply #43 on: September 29, 2015, 10:59:47 am »
dougeff's advice for tracing where the pointers exist is good -- but really there's no need for it as the entire game has already been disassembled.   :P

Regardless... as with most text in FF1, the pointers for the shop text are immediately before the text itself.

Offsets 0x38010 - 0x3805B are pointers... each 2 bytes pointing to a string used in shop dialogue.

Shokupanda

  • Jr. Member
  • **
  • Posts: 36
    • View Profile
Re: Final Fantasy I (NES) - Sprite Editing
« Reply #44 on: September 29, 2015, 11:16:05 am »
Quote
dougeff's advice for tracing where the pointers exist is good -- but really there's no need for it as the entire game has already been disassembled.

I don't really get the thing with the assembly though... I mean, I can change the source code and compile it with the bat, but it's not like I can open the source code of the .nes
file I'm working on, can I? Since I've done a lot already I don't really want to start over again.

Quote
Offsets 0x38010 - 0x3805B are pointers... each 2 bytes pointing to a string used in shop dialogue.

Thank you very much! Now that I've changed the value, it works!  :)

Disch

  • Hero Member
  • *****
  • Posts: 2814
  • NES Junkie
    • View Profile
Re: Final Fantasy I (NES) - Sprite Editing
« Reply #45 on: September 29, 2015, 11:24:46 am »
I don't really get the thing with the assembly though... I mean, I can change the source code and compile it with the bat, but it's not like I can open the source code of the .nes file

You don't necessarily have to use the disassembly as something to directly modify -- like you don't have to build it with the bat file... you can just use it as a reference to search for things and see how they work.  That's effectively what I've been doing this entire time when I've been feeding you offsets.  All the offsets are in the disassembly.

Quote
It's "Kaufen" in the weapon/armor shop, so why is it "kaufen" in the Item shop? Any idea?

Item shops use a different string.

Item shops have "Buy[line]Exit"
whereas Weapon/Armor shops have "Buy[line]Sell[line]Exit"

They're listed separately in that block of text.  You must have changed one to have uppercase K but the other still has lowercase.

Shokupanda

  • Jr. Member
  • **
  • Posts: 36
    • View Profile
Re: Final Fantasy I (NES) - Sprite Editing
« Reply #46 on: September 29, 2015, 11:42:34 am »
Quote
Item shops use a different string.

Item shops have "Buy[line]Exit"
whereas Weapon/Armor shops have "Buy[line]Sell[line]Exit"

They're listed separately in that block of text.  You must have changed one to have uppercase K but the other still has lowercase.

I already figured it out. It was something different though. I just put a wrong number to the pointer. So it started at kaufen from "Ver[kaufen]", haha. I corrected it, it's fine now.

Quote
You don't necessarily have to use the disassembly as something to directly modify -- like you don't have to build it with the bat file... you can just use it as a reference to search for things and see how they work.  That's effectively what I've been doing this entire time when I've been feeding you offsets.  All the offsets are in the disassembly.

Ah okay. I actually use it as a reference too! For example, I wanted to find out where it sets the box sizes of the shop. I found the offset in the assembly.  :)
I made the box 2 tiles bigger so that "Verkaufen" fits in, but there's this green thing from the gold box...



Any ideas how to get rid of it without moving the whole option box 1 tile to the left?
I'd like to let it stay where it is, if possible. If that's not possible, I'll move it to the left.


KingMike

  • Forum Moderator
  • Hero Member
  • *****
  • Posts: 7088
  • *sigh* A changed avatar. Big deal.
    • View Profile
Re: Final Fantasy I (NES) - Sprite Editing
« Reply #47 on: September 29, 2015, 12:09:04 pm »
That is because of NES' Attribute Tales (the part of VRAM that defines which palette each 16x16 pixel block of the screen uses. (that basically means every 2 tile x 2 tile square on the screen must use the same colors due to hardware limitation)
That is the green that is used in the Gold box.
You can either find where the AT for the Gold menu is (it is stored in PPU RAM at $23C0-23FF, most likely, or $27C0-27FF. You'd have to trace back to find it, or I'm sure Disch will reply soon with a disassembly answer. :) ).
"My watch says 30 chickens" Google, 2018

Disch

  • Hero Member
  • *****
  • Posts: 2814
  • NES Junkie
    • View Profile
Re: Final Fantasy I (NES) - Sprite Editing
« Reply #48 on: September 29, 2015, 12:10:38 pm »
Aye ya... that's the attribute table.

Attribute tables are a mess and really hard to wrap your head around.  Basically the NES splits the screen into a series of 16x16 blocks and assigns a palette to each of those blocks.  Which is fine... but it CRAMS all that information into a 64-byte block of memory which makes it difficult to comprehend.

Details (if interested) are here:
http://wiki.nesdev.com/w/index.php/PPU_attribute_tables

Fortunately the attributes for the shop screens are easily modifiable (offset 0x3AC6C):

Code: [Select]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;  Shop Attribute Table LUT  [$AC5C :: 0x3AC6C]
;;
;;    This is a copy of the attribute table to be used for the shop screen.
;;  This is a full $40 bytes that is copied IN FULL to the attribute table
;;  for the shop.

lut_ShopAttributes:
  .BYTE $FF,$FF,$FF,$55,$55,$FF,$FF,$FF
  .BYTE $FF,$FF,$3F,$05,$05,$CF,$FF,$FF
  .BYTE $FF,$FF,$33,$00,$00,$CC,$FF,$FF
  .BYTE $FF,$FF,$33,$00,$00,$CC,$FF,$FF
  .BYTE $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
  .BYTE $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
  .BYTE $FF,$FF,$FF,$FF,$AA,$AA,$AA,$AA
  .BYTE $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF

That block of 'AA's near the bottom is the green for the GP box.  Each byte represents a 32x32 pixel region.  We want to modify a 16x32 region... so I think the proper change would be to change that first 'AA' to 'BB' -- but I didn't test that.

Shokupanda

  • Jr. Member
  • **
  • Posts: 36
    • View Profile
Re: Final Fantasy I (NES) - Sprite Editing
« Reply #49 on: September 29, 2015, 12:30:40 pm »
Quote
That is because of NES' Attribute Tales (the part of VRAM that defines which palette each 16x16 pixel block of the screen uses. (that basically means every 2 tile x 2 tile square on the screen must use the same colors due to hardware limitation)

Quote
Attribute tables are a mess and really hard to wrap your head around.  Basically the NES splits the screen into a series of 16x16 blocks and assigns a palette to each of those blocks.  Which is fine... but it CRAMS all that information into a 64-byte block of memory which makes it difficult to comprehend.

Details (if interested) are here:
http://wiki.nesdev.com/w/index.php/PPU_attribute_tables

Thank you very much guys! I've learned something new. This information is really helpful whenever I encounter this kind of problem again.  :)
Also thanks for the link! I'll read it!

Quote
That block of 'AA's near the bottom is the green for the GP box.  Each byte represents a 32x32 pixel region.  We want to modify a 16x32 region... so I think the proper change would be to change that first 'AA' to 'BB' -- but I didn't test that.

Thanks! This worked perfectly fine for me.  :)

dougeff

  • Sr. Member
  • ****
  • Posts: 358
    • View Profile
Re: Final Fantasy I (NES) - Sprite Editing
« Reply #50 on: September 29, 2015, 01:14:33 pm »
My example of finding the pointers was a roundabout way of saying 'use the disassembly', since it's a long and complicated process. But, I see you are, so...good. Actually, now that I look at the disassembly, I don't find it very easy to find all the text or pointers either.

I guess 'look at the code to see where the pointer is' was a terrible explanation also...I'm sure you don't need this now, but for a game that doesn't have a disassembly...

I opened FFI and went into the first Weapon shop, and decided to try to edit the pointer for 'Welcome'. I see the tiles for W e l = A0 A8 Af. A quick search of the memory shows them at 0x8085. Set breakpoint for reads from 8085, [the second break] gets this line of code 'LDA (3e), y'. So I set a breakpoint for writes to 3e with condition 'A==#85'. reload savestate. enter. break near this line of code 'LDA 8000,x @ 8012 = 85' [a line before the break of STA 3e]. So I look again at the memory at 8012, write down a string of numbers around it 85 80 8c 80 98 etc. Search the Rom for that string. Change the 85 to 86. Reload and re-enter, and he now says 'elcome'. And, this method is way too slow to do for the entire game.

Also, didn't realize that Disch did the disassembly. :)

I found this particular thing in the disassembly in 0E_8000_shopstrings.bin as raw hex...I don't think it's any easier to work with the disassembly. But, apparently pointers to the text are going to be right next to the text, so hopefully it won't be too hard to figure out.
« Last Edit: September 29, 2015, 02:58:45 pm by dougeff »
nesdoug.com -- blog/tutorial on programming for the NES

Bregalad

  • Hero Member
  • *****
  • Posts: 2751
    • View Profile
Re: Final Fantasy I (NES) - Sprite Editing
« Reply #51 on: September 29, 2015, 02:56:19 pm »
Haha, sounds cool! Although I'm not quite sure if it's possible to make good gothic letters with a space of 16x16px.  :laugh: I'll keep it in mind, though!
I do not know if they are accurate to real gothic fonts used in Germany 100 years ago (very likely not), but Castlevania III managed to do that. An existing FF1 hack already uses this font for it's upper case letters. I do not mean in anyway that you shoukd use it or anything I'm just mentionning it because it made me wondering.

Quote
Also, didn't realize that Disch did the disassembly. :)
It is more likely that a disassembler did the disassembly, and that Dish spent a lot of time to comment and analyze the results.

Disch

  • Hero Member
  • *****
  • Posts: 2814
  • NES Junkie
    • View Profile
Re: Final Fantasy I (NES) - Sprite Editing
« Reply #52 on: September 29, 2015, 02:58:10 pm »
Quote
Actually, now that I look at the disassembly, I don't find it very easy to find all the text or pointers either.

You can typically Ctrl+F for things -- but I guess I do have an advantage that I kind of know what to search for.  :-\


Quote
I found this particular thing in the disassembly in 0E_8000_shopstrings.bin as raw hex...so I don't see an easy way to locate all the text with the disassembly. Any thoughts, Disch?

My process was this:

1)  Ctrl+F for "DrawShop".  Turns out there's actually a routine that is called "DrawShop" in bank E.

2) That routine has this code:
Code: [Select]
    LDA #$01
    JSR DrawShopBox              ; draw shop box ID=1  (the title box)

    LDA shop_type                ; get the shop type
    JSR DrawShopString           ; and draw that string (the shop title string)

Indicating that 'DrawShopString' is where shop text is drawn from.

3)  DrawShopString loads pointers like so:

Code: [Select]
DrawShopString:
    ASL A              ; double the ID (2 bytes per pointer)
    TAX                ; put it in X

    LDA lut_ShopStrings, X  ; load the pointer from the shop string LUT
    STA text_ptr
    LDA lut_ShopStrings+1, X
    STA text_ptr+1     ;  ... then draw it....
                       ; no JMP or RTS -- code seamlessly flows into DrawShopComplexString

4)  Ctrl+F for 'lut_ShopStrings' to find this:

Code: [Select]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;  LUT containing stock shop text  [$8000 :: 0x38010]

lut_ShopStrings:
  .INCBIN "bin/0E_8000_shopstrings.bin"

5)  The comment indicates offset 0x38010  :    [$AAAA :: 0xOOOOO] where A=cpu address and O=Rom offset

dougeff

  • Sr. Member
  • ****
  • Posts: 358
    • View Profile
Re: Final Fantasy I (NES) - Sprite Editing
« Reply #53 on: September 29, 2015, 03:46:47 pm »
I did this for a different game, so this took only a slight modification...but I made you a file. This is what I would do to find the text in the game. I wrote a very short program to convert every text hex value to the correct ascii value (and all other values to 0), so that you can read the english in a hex editor - and know where each text string starts.

file removed, link no longer active

Text starts about 0x28210. Not all of the texts are coming through clearly, maybe there is some compression algorithm in the game. I don't know.

« Last Edit: October 06, 2015, 09:54:08 pm by dougeff »
nesdoug.com -- blog/tutorial on programming for the NES

Disch

  • Hero Member
  • *****
  • Posts: 2814
  • NES Junkie
    • View Profile
Re: Final Fantasy I (NES) - Sprite Editing
« Reply #54 on: September 29, 2015, 04:00:25 pm »
Not all of the texts are coming through clearly, maybe there is some compression algorithm in the game. I don't know.

Most of the text uses DTE

Shokupanda

  • Jr. Member
  • **
  • Posts: 36
    • View Profile
Re: Final Fantasy I (NES) - Sprite Editing
« Reply #55 on: September 30, 2015, 06:00:42 pm »
Quote
I opened FFI and went into the first Weapon shop, and decided to try to edit the pointer for 'Welcome'. I see the tiles for W e l = A0 A8 Af. A quick search of the memory shows them at 0x8085. Set breakpoint for reads from 8085, [the second break] gets this line of code 'LDA (3e), y'. So I set a breakpoint for writes to 3e with condition 'A==#85'. reload savestate. enter. break near this line of code 'LDA 8000,x @ 8012 = 85' [a line before the break of STA 3e]. So I look again at the memory at 8012, write down a string of numbers around it 85 80 8c 80 98 etc. Search the Rom for that string. Change the 85 to 86. Reload and re-enter, and he now says 'elcome'. And, this method is way too slow to do for the entire game.

Thank you very much for the detailed instruction. If I shouldn't be able to find the pointers for some reason I'll go with this!  :)

Quote
Also, didn't realize that Disch did the disassembly. :)

I actually realized it when I downloaded it from this site. Man, all the information next to the codes... that must haven taken ages to write.

Quote
I do not know if they are accurate to real gothic fonts used in Germany 100 years ago (very likely not), but Castlevania III managed to do that. An existing FF1 hack already uses this font for it's upper case letters. I do not mean in anyway that you shoukd use it or anything I'm just mentionning it because it made me wondering.

Hey, they look awesome!! Thank you very much for the links!  :)

Quote
I did this for a different game, so this took only a slight modification...but I made you a file. This is what I would do to find the text in the game. I wrote a very short program to convert every text hex value to the correct ascii value (and all other values to 0), so that you can read the english in a hex editor - and know where each text string starts.

http://dl.dropboxusercontent.com/s/8e6ef6v4adhjdjt/FF1text.bin

Text starts about 0x28210. Not all of the texts are coming through clearly, maybe there is some compression algorithm in the game. I don't know.

Oh wow, man!! Thank you very much for the effort! I'm using FFHackster for Dialogue editing though. Or is your program better for editing texts?

Sooo hey guys, I'm back with another bug, haha.  :laugh:



It seems I'm not able to use DTE's in Battle... Or at least it doesn't display them correctly. Any guess why it is like that?
Like always, thank you very much in advance!!



dougeff

  • Sr. Member
  • ****
  • Posts: 358
    • View Profile
Re: Final Fantasy I (NES) - Sprite Editing
« Reply #56 on: September 30, 2015, 06:37:26 pm »
Quote
is your program better for editing texts?

Its not a program, its a .bin file. Open it in a hex editor, scroll down to 0x28210.

Quote
Is it better than FFHackster


Ive got to be honest, I didn't even know FFHackster existed until a few days ago.
nesdoug.com -- blog/tutorial on programming for the NES

KingMike

  • Forum Moderator
  • Hero Member
  • *****
  • Posts: 7088
  • *sigh* A changed avatar. Big deal.
    • View Profile
Re: Final Fantasy I (NES) - Sprite Editing
« Reply #57 on: September 30, 2015, 06:54:49 pm »
I thought DTE was not programmed into the battle text routine? (or was that FF2?)
I thought someone made a patch to fix that though.
"My watch says 30 chickens" Google, 2018

dougeff

  • Sr. Member
  • ****
  • Posts: 358
    • View Profile
Re: Final Fantasy I (NES) - Sprite Editing
« Reply #58 on: September 30, 2015, 07:16:12 pm »
I would agree. All the monster names and spell names look uncompressed.
nesdoug.com -- blog/tutorial on programming for the NES

Disch

  • Hero Member
  • *****
  • Posts: 2814
  • NES Junkie
    • View Profile
Re: Final Fantasy I (NES) - Sprite Editing
« Reply #59 on: September 30, 2015, 08:15:25 pm »
You both are correct -- DTE is not available in battle.  Battles use entirely different text drawing routines, and those routines don't bother checking for DTE.