Jump to content

FE6 Localization Patch v1.2.1 - Full localization with new features, including Support Conversation reader


Recommended Posts

  • Replies 1.9k
  • Created
  • Last Reply

Top Posters In This Topic

On this day, we have learned The Strongest One's Name, and it is tabachanker.

are you jesus

Hey thanks for the compliments guys! Not sure about Jesus but I may be Santa with a lot of time on his hands til the next holidays season!

Seriously, I'm just a programmer with assembly expertise. I work as a programmer and it's also one of my main hobby. I may have known nothing technical about the GBA before doing these hacks, but I always say that, once you know the basics of any programming language (conditions, loops, subroutine calls, etc.), you can easily learn any language without any problems.

I made a couple of games in assembly on the Colecovision, which is a lot smaller than the GBA (Z80, 1kb of RAM, 16kb of video RAM, games can be 32kb max). The GBA is just a lot more of everything. Like I said, the basics are still all there. I just needed to adapt to the way ARM assembly is written.

Edited by tabachanker
Link to comment
Share on other sites

I completed another hack here... I found out how to fix the level up screen with animations on. Now all stat labels are the same as with animations off.

This problem was twofold:

  • The stat labels were written with 2 letters each in the cart. (HP, ST, SK, etc.)
  • If you tried to change the length of those labels, weird characters appeared on screen. This was because each time a stat label was written, the game recalculated the offset to the label of the next stat. It did this by adding the base offset + (5 * stat#). So each stat label could only be 5 bytes (2 * 2 bytes for both letters and a null byte ($00) to end the label).

If you're interested in how I solve these problems, read on!

There are two versions of the stat labels. A "strength" version and a "magic" one. These two can be found at offsets $1C9FEC and $1CA014 respectively. I changed their locations to $08355FB0 and $08355FF0. I couldn't use the old locations because I would have overwritten other important data there (since the labels are now longer, they take more space). The new locations were used by the Japanese characters I removed when I did the class names intro hack. So I didn't overwrote anything important. I put the new stat labels there and changed the pointers to the labels (at offsets: $05D384 for strength, $05D4B8 for magic).

Now for the second problem, I had to reprogram the code where it calculates the next label offset. Often times, when you have to do something like this, you don't have enough space to add what you want to the existing code. The solution: write a new subroutine somewhere else that does what you want, then just place a call at the correct spot in the original code. That call will overwrite 1 or 2 instructions in the original code, but you can put those back AT THE END of your new subroutine, if they're still needed. In this case, they weren't. The overwritten instructions were the old "next offset calculation" that my new subroutine replaced.

So that's what I did. I created a new subroutine that calculates the new offset by searching for the null bytes (00) at the end of each labels. I do this "stat#" times and that's how I find the offset. With that done, you can put as many letters as 24x16 pixels will hold. Yeah, that's another limit! Fortunately, it doesn't have to be changed, so we're good to go!

I included 3 patches in the .zip file. You only have to use one of them (depending if you already patched the game with my earlier patch in this thread page).

  • Patch engprologue + lvlup screen.ups (both English prologue + level up screen patches)
  • Patch engprologue only.ups (English prologue patch only)
  • Patch lvlup screen only.ups (Level up screen patch only)

Patches.zip

Edited by tabachanker
Link to comment
Share on other sites

All hail tabachanker the hack lord!

A minor bug report: In Chapter 16, there's a line in Douglas-Lalum conversation (triggered with Talk option) that has no pause afterward:

(Douglas) "I just wish there had been another way."

Link to comment
Share on other sites

Can you talk more about how you rewrote the label-fetching code? I'm aware of the whole "ldr r0->bx r0->lr works perfectly because it's just a GOTO" trick, but i've had little success myself in trying to fool with graphics and th elike to the extent that you have

Link to comment
Share on other sites

Can you talk more about how you rewrote the label-fetching code? I'm aware of the whole "ldr r0->bx r0->lr works perfectly because it's just a GOTO" trick, but i've had little success myself in trying to fool with graphics and th elike to the extent that you have

To write the stat labels on screen, the game uses a loop. There is 2 important registers in the loop which help keeping track of the stat being currently displayed:

  • R7 = The current stat# (it goes 0 for HP, 1 for ST/MG, 2 for SK, 3 for SP, etc.)
  • R8 = The number added to the base offset to find the current stat label. 5 is added to this register each loop iteration (so it goes 0 for HL, 5 for ST/MG, 10 for SK, 15 for SP, etc.)

The loop goes something like this (I wrote only the relevant actions in pseudo-code, it actually does more things than this) :

  • R7 = 0
  • R8 = 0
  • Do {
    • R0 = The base offset for the stat labels. Here, R0 always points to the label HP.
    • R5 = R0 + R8. The register R5 now points to the current label stat.
    • Write the label pointed to by R5 on screen
    • R8 = R8 + 5.
    • R7 = R7 + 1.
  • Loop while R7 < 8

As you can see here, on each iteration, the game uses the base offset (which always points to "HP") and adds the R8 register, which is incremented by 5 each times. That way, the labels must all be 5 bytes wide, no more, no less. Each letter is 2 bytes and the label needs a terminating null byte ("00"), which gives the 5 bytes needed. Now to let the translation use a different amount of letters for each stats, I had to reprogram the "R5=R0+R8" part.

I replaced that instruction with a call to my new subroutine. Here it is in assembly (with comments!):

08355F50
	mov	r2,r7           ; R2 = Copy current stat # (don't want to change value in R7)
CheckLabel:
	sub	r2,r2,1
	bpl	NextCharCode    ; Current stat # not reached yet, advance text offset until next "00" is found
	mov	r5,r0           ; Current stat # reached!  R5 now points to current stat label
	mov	r15,r14         ; Exit subroutine
NextCharCode
	ldrb	r1,[r0]
	add	r0,1		; Advance 1st byte of char code (we mustn't advance 2 bytes yet cause of possibility of a single "00")
	cmp	r1,0
	beq	CheckLabel	; This is a "00" (end of label), check if that's the label we want
	add	r0,1		; This is a true char code, advance 2nd byte of char code
	b	NextCharCode	; Check next char until "00" is found.

So this new subroutine looks for the null bytes (00) at the end of each stat label. It does that R7 times. If R7 = 00, it doesn't do anything since the pointer is already on the HP stat.

I hope that answers your question!

Edit: When writing this, I realized I could have just changed the R8 = R8 + 5 part to R8 = R8 + 11. Each stat label would now have to be 5 letters (2 bytes per letters + 1 terminating byte = 11). But, since the "draw label on screen" routine stops as soon as a null byte (00) is read, I could have padded the smaller labels with 0s. Something like this : H/P/null/0/0/0, S/t/r/null/0/0, S/k/i/l/l/null, S/p/d/null/0/0, etc. (all chars between // are 2 bytes, except "null" is only 1 byte). There's a lot of ways to approach a problem!

Edited by tabachanker
Link to comment
Share on other sites

Just got back from my trip to Tokyo and found this great surprise waiting!

Thanks again, tabachanker! I'll fix the reported errors and implement these new changes and get a new version out ASAP.

Link to comment
Share on other sites

Tabachanker, can you specify how you found where the routine you had to change was located? This is always the hardest part for me when trying to ASM hack, and the only way I have managed to find the routines i was looking for was when I knew a location in the memory that was either read or written during the routine, and would just set a read/write break on that location. I don't imagine how I could have used that technique for this problem however.

Link to comment
Share on other sites

Tabachanker, can you specify how you found where the routine you had to change was located? This is always the hardest part for me when trying to ASM hack, and the only way I have managed to find the routines i was looking for was when I knew a location in the memory that was either read or written during the routine, and would just set a read/write break on that location. I don't imagine how I could have used that technique for this problem however.

I had to find where the stat labels were defined first. I searched through out the code for the char codes of "HP" (which are 82 AD 82 BD). I found a lot of in game phrases with HP inside like "Restores a unit HP". But at one point, I found those 2 char codes followed by a 00 and preceded by something other than a normal char code. After the 0, there were 2 other char codes + another 00. Then 2 other char codes + a 0. This was looking good! I checked the other char codes and they were the other stat labels alright (St, Sk, Sp, etc.)

I then used the disassembly listing I made from the original ROM and searched for a pointer to that memory area. I found offset $05D384. Reading the disassembled code around that offset, I surmised that that was exactly what I was searching for. I found the loop for each stat labels and started working on understanding the code inside the loop. After that I programmed the solution described in my previous post.

Just got back from my trip to Tokyo and found this great surprise waiting!

Thanks again, tabachanker! I'll fix the reported errors and implement these new changes and get a new version out ASAP.

Hope your trip was enjoyable! And I hope everything's to your liking!

Edited by tabachanker
Link to comment
Share on other sites

First off, I wanted to sincerely thank everyone involved with this patch, the level of detail and polish that has been achieved is far greater than anything I could have ever hoped for; you are all truly legends. While playing, however, I discovered a few minor issues that I thought you would appreciate knowing about:

  1. When first starting the Link Arena, the following incomplete line appears on the initial screen: "You must create a ".
  2. In Chapter 1, the Villager in one of the first set of houses says "If you wanna do well in battle you'd better use terrain wisely"; the word "wanna" seems a little out of place for this time period, no?
Lastly, now that master hacker tabachanker is on board, are there any plans to revisit and rename the trimmed menu entries (ie Trd / Discd / Suspnd), or to clean up the dots on the "2002 Nintendo Presents ***" screen?


That's all I have, thanks again for all the amazing work you guys have done!

Link to comment
Share on other sites

Lastly, now that master hacker tabachanker is on board, are there any plans to revisit and rename the trimmed menu entries (ie Trd / Discd / Suspnd), or to clean up the dots on the "2002 Nintendo Presents ***" screen?

I already cleaned up the trailing dots on the intro screen in the latest patch I made. It will probably be included in the next official version of the translation patch. As for the trimmed words, I can probably see what I can do. Gringe, is this something you'd like to see corrected?

Link to comment
Share on other sites

  1. When first starting the Link Arena, the following incomplete line appears on the initial screen: "You must create a ".
  2. In Chapter 1, the Villager in one of the first set of houses says "If you wanna do well in battle you'd better use terrain wisely"; the word "wanna" seems a little out of place for this time period, no?
Lastly, now that master hacker tabachanker is on board, are there any plans to revisit and rename the trimmed menu entries (ie Trd / Discd / Suspnd), or to clean up the dots on the "2002 Nintendo Presents ***" screen?

Don't worry about the Link Arena just yet because I don't think I've even touched it. :P I'll get to it eventually, even though I expect less than one percent of people playing the game to actually use it.

As for "wanna," different characters talk a little bit differently, and even in FE7 villagers tended to use very conversational vocabulary and grammar. I'll be conscious of it and think a little more about it when I test the game again, though.

As for the trimmed words, I can probably see what I can do. Gringe, is this something you'd like to see corrected?

Actually, after getting the new version out, I wanted to make a short list of things that I've wanted to do from the start but which have been impossible so far. If you can help again, that would be great! I'll make the list soon.

Link to comment
Share on other sites

Actually, after getting the new version out, I wanted to make a short list of things that I've wanted to do from the start but which have been impossible so far. If you can help again, that would be great! I'll make the list soon.

Excellent! I'm still on vacations next week, so I will probably have the time to do a couple of those (maybe all?).

In the meantime, here's how to change the Item menu width from 5 tiles to 6 (if you do this, you'll be able to change to labels "Trd" and "Discd" to "Trade" and "Discard". 6 is the same width used in FE7 for this menu.

At offset $5C754E in the ROM file, change the byte $05 to $06.

Note: this is supposed to change the width of the Item menu. But it doesn't do anything because the game uses a hardcoded value instead! Change this anyway in case it is used somewhere else. It is the normal definition for the width of this menu (all menus use the same data structure).

At offset $01F7FE in the ROM file, change the $A0 to $C0.

Note: this is the actual hardcoded value. It is the width of the item menu * 32. This byte can't be higher than $FF (so the largest item menu we can have is 7 tiles wide)

The "End turn" menu (to change "Suspnd" to "Suspend") is easier. In FE7, it is 7 tiles wide instead of 6, so:

At offset $5C764A in the ROM file, change the byte $06 to $07.

Edited by tabachanker
Link to comment
Share on other sites

okay at gringe's request i'm experimenting with replacing the opening sequence font. my first thought was to use the pre-existing credits font, and if i do say so myself that was a pretty good idea

tumblr_nadqtjr3LA1qhx4jao1_250.pngtumblr_nadqtjr3LA1qhx4jao3_250.png

still needs a fair bit of tweaking - partially because i accidentally put the comma and period in the wrong spaces, and partially because it looks like this on the backgrounds

tumblr_nadqtjr3LA1qhx4jao2_250.png

this should be a pretty simple fix all i really need to do is add an outline and that'll be stupidly easy. once that's done, the extra 2px width on each letter will necessitate the widths be redefined, but that's fairly simple too. honestly i'm surprised my first attempt looked tolerable without width redefining! the only problem in this first try was the lower-case m (presumably the upper-case one as well)

UPDATE:

tumblr_nadrmd2kSf1qhx4jao1_250.png

okay i think i've got it! a few more tweaks and it should be ready for width table editing

Edited by bookofholsety
Link to comment
Share on other sites

Wow, just wow. The amount of talent displayed by this team is simply awe inspiring. I cant believe how much has been accomplished since my last post!

Gringe: no worries on the "wanna" issue, you've done an awesome job on the translation and I hope I didn't step on your toes. I just want to contribute in anyway I can, which is basically my eye for detail and my time to beta test. I trust your judgement and know whatever you choose will be perfect.

I can't wait to start testing the new version!

Link to comment
Share on other sites

Bravo bookofholsety! This font is fantastic! I'm really glad you took to time to edit it. As I said in one of my previous post, I'm a total noob when it comes to graphics!

Also, thanks to all of you for all your compliments. It's always a pleasure to see a project come to life, it's even better when people are actually interested in the thing. Thanks again!

Link to comment
Share on other sites

okay mission accomplished!

https://www.youtube.com/watch?fv=-a39gmi9AlI

i think i've got all the widths sorted out! took a frustrating amount of trial and error, and for a while i made an amusing/embarrassing mistake about which bytes correspond to which widths, but i think that's all of them in working order now. if you can see any obvious mistakes left in there in the video, let me know

anyway, IMPLEMENTING IT. i'm too lazy to learn how to make patches so you get the hard way. you're welcome :P

[spoiler=hex]
paste in the following five lines of hex, starting from offset 6916E0 (for the sake of simplicity this is the entire line, not just where the table begins)

82 DA 82 B8 00 0C 09 09 09 0A 0A 0A 0B 06 09 0B
0B 0C 0B 0A 0C 0A 09 09 0A 0A 0B 0E 0A 0A 0A 06
06 06 06 06 06 08 09 08 08 09 08 09 09 06 07 0A
06 0E 0A 09 09 08 07 08 07 09 08 0B 07 08 07 06
06 06 06 06 06 07 06 07 07 08 07 07 08 07 07 07


if you need a visual aid (i know i did), i've marked out which byte corresponds to which letter:

	glyph:	--TABLE START:  A  B  C  D  E  F  G  H  I  J  K
006916E0	82 DA 82 B8 00 0C 09 09 09 0A 0A 0A 0B 06 09 0B
	glyph:	 L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z --
006916F0	0B 0C 0B 0A 0C 0A 09 09 0A 0A 0B 0E 0A 0A 0A 06
	glyph:	-- -- -- -- --  a  b  c  d  e  f  g  h  i  j  k
00691700	06 06 06 06 06 08 09 08 08 09 08 09 09 06 07 0A
	glyph:	 l  m  n  o  p  q  r  s  t  u  v  w  x  y  z --
00691710	06 0E 0A 09 09 08 07 08 07 09 08 0B 07 08 07 06
	glyph:	-- -- -- -- --  0  1  2  3  4  5  6  7  8  9  -  
00691720	06 06 06 06 06 07 06 07 07 08 07 07 08 07 07 07
	glyph:	 '  :  .  ,  & :TABLE END- -- -- -- -- -- -- --
00691730	05 05 05 05 07 00 00 00 08 0C 00 00 09 0C 00 00

oh and of course the font graphic itself. offset 37F478 in gbage, you know the drill

MzkCdTV.png

i think i should go back and edit that one "the famed heroes who saved elibe" splash in the epilogue to use this font as well. y'know, for consistency, since that scene originally used a similar font to the opening

Link to comment
Share on other sites

Okay, after an amazing series of hacks from tabachanker, the new version is out...

v0.98 changelog:

-Prologue scroll fully implemented!!! (tabachanker)

-New prologue scroll font!!! (bookofholsety)

-The level up screens have been fixed to be fully consistent!!! (tabachanker)

-The menu screens have been widened!!! (tabachanker)

-...allowing for the full words for commands in menus such as Suspend, Discard, and Trade, which have been implemented

-Fixed Narcian's boss quote to display properly

-Fixed a missing pause in Lalum/Roy's C support

I found no instances of Eburakhm in the current patch, and the Douglas/Lalum missing pause has already been fixed.

As for a list of things that need to be done (no major details here, and some are bigger than others. These are just things that come to my mind)...

-A way to import and export the world map graphics so that we can finally change Ereb to Elibe (now about the only noticeable aesthetic problem left). I noticed this topic some time ago but have no idea of how to use this script. This is the biggest thing that still needs fixing.

-There's an inconsistency with the "[item] broke!" text. Without animations, it has an extra space. I believe I've tried to fix this but it didn't work so we need to do something more than a simple text edit.

-There are some message inconsistencies with FE7 due to limitations I didn't know how to work around (my fix was to put all messages in passive tense) (For example I had to use "[item] was stolen." instead of the "Stole a/an [item]." message from FE7). This isn't a huge deal, though.

-Weapon stat screens could be aligned better. There was a problem with the range stat because it uses the same offset in the stat screen (highlighted in red) and in the characters' current equipped item stat window (highlighted in green).

ofEqEdF.png

-Some events seem to have been somewhat broken by the old translation patch team. For example, in Chapter 10A, Elphin tells Roy that Bern is probably going to invade Lycia because his army is away and some dramatic music starts playing. They have this same conversation in Chapter 10B, but without the music. Also, backgrounds seem to be missing for some Sacae route conversations. This is probably the second biggest issue to fix.

Edited by gringe
Link to comment
Share on other sites

-Some events seem to have been somewhat broken by the old translation patch team. For example, in Chapter 10A, Elphin tells Roy that Bern is probably going to invade Lycia because his army is away and some dramatic music starts playing. They have this same conversation in Chapter 10B, but without the music. Also, backgrounds seem to be missing for some Sacae route conversations. This is probably the second biggest issue to fix.

That can all be changed through event hacking (it does not require ASM), however the translation patch team did not mess this up, it was just overlooked by the original developers (there was also a broken convo between thany and tate that never worked in chapter 19 sacae). I know this because you can see the event information in the original, unpatched rom.

Edited by Barth
Link to comment
Share on other sites

As for a list of things that need to be done (no major details here, and some are bigger than others. These are just things that come to my mind)...

-A way to import and export the world map graphics so that we can finally change Ereb to Elibe (now about the only noticeable aesthetic problem left). I noticed this topic some time ago but have no idea of how to use this script. This is the biggest thing that still needs fixing.

I successfully exported/imported a new world map using GBage. You have to set these properties:

  • In windows control panel
    • Offset: 2C8874 (offset for the world map, compressed)
    • Compressed graphics: checked
    • Size: Width: 30, Height: 20 (this is the important part, bitmap graphics are 240x160 pixels (or 30x20 tiles of 8x8 pixels)
  • In Palette control panel
    • Offset: 900000
    • Grpahics mode: Indexed bitmap checked (also important, this tells GBage that this is a bitmap graphic, not a tiled one)

Before doing this though, I had to copy the uncompressed palette at offset $900000 in the ROM file (it's an unused location). The original compressed palette is at $2D1BA0, but for some reason, when I use this offset, GBage's "compressed palette" checkbox stays grayed out.

With the uncompressed palette in place + those properties above, you can export a perfect copy of the world map in a 256 colors PNG file. Edit this PNG file with your graphics program of your choice. Then reimport with GBage.

I attached a zip file to this message with following files inside:

  • The UPS file: This patches v0.98 of the translation patch. With this, you will see my new version of the Elibe world map.
  • Old Elibe WorldMap Palette memdump.rom: This is the uncompressed palette used by the world map. If you want GBage to correctly export the original Elibe world map, put this in the ROM file in an unused place (like offset $900000). In GBage, you can now point the palette to this offset.

Elibe world map.zip

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...