This is why I said "you can decide for yourself".Asaki wrote:Hmm...it doesn't look like it says. "Text has been rewritten" could mean either way, really.
How did Final Fantasy VI do a non-fixed-width font?
Moderator: Moderators
Forum rules
- For making cartridges of your Super NES games, see Reproduction.
Re: How did Final Fantasy VI do a non-fixed-width font?
Re: How did Final Fantasy VI do a non-fixed-width font?
This means it's not a retranslation. If they took the original text, re-translate it and insert it into the game, it would be a re-translation. Changing the text to "look better" is not a retranslation. At least this hack does not pretend to be one.
J2E's FF4 so called "re-translation" is an offender here, it does not re-translate the game (or, at least, only parts of it), yet they self claimed their hack was a retranslation.
J2E's FF4 so called "re-translation" is an offender here, it does not re-translate the game (or, at least, only parts of it), yet they self claimed their hack was a retranslation.
Re: How did Final Fantasy VI do a non-fixed-width font?
The Secret of Mana VWF hack contains references to Final Fantasy VII, so if it's supposed to be a retranslation, it's not a very faithful one.
Re: How did Final Fantasy VI do a non-fixed-width font?
Fascinating website, never had come across it before...Revenant wrote:The Secret of Mana VWF hack contains references to Final Fantasy VII, so if it's supposed to be a retranslation, it's not a very faithful one.
and yeah a little controversy is fun now and then. But please don't damn the whole project as "unfaithful" for making fun of Square fanbois. (or being one). As for personal opinion, I never considered it a literal translation either, just more fun and understandable to play.
Re: How did Final Fantasy VI do a non-fixed-width font?
Besides, Ted Woolsey's translations weren't literal anyway. Apparently the translation of SOM was so terse because ROM size.
Re: How did Final Fantasy VI do a non-fixed-width font?
That's too bad. I tried replaying the game a couple years ago (hadn't played it since I was a kid), and that game could seriously use a proper re-translation. IMO, Final Fantasy Adventure had a more enjoyable localization >_<Revenant wrote:The Secret of Mana VWF hack contains references to Final Fantasy VII, so if it's supposed to be a retranslation, it's not a very faithful one.
Re: How did Final Fantasy VI do a non-fixed-width font?
Maybe the iPhone version was a retranslation ?
Re: How did Final Fantasy VI do a non-fixed-width font?
no, the iphone version uses the original text.
Re: How did Final Fantasy VI do a non-fixed-width font?
Here's how Ultimate Mortal Kombat 3 does it (posting here for a wiki link that links here)
Unrelated, but this seems to be a compiled game: a lot of stack manipulation, code mostly deals with 16-bit and 32-bit values (each 32-bit ram var wasting a byte due to it being a 24-bit space)
The main routine is at 88:90f8, XA is the src of a 0-terminated ascii string, and Y is the pixel Y to plot to.
Example of code that calls it:
Each ascii char is mapped, through different tables, eventually to a pixel width (for example, for calculating where to plot the 1st char in a centered line, by summing all the line's char's widths, or where to plot subsequent chars) eg 88:8db6 having a collection of pixel widths
Some more snippets of the core part of the VWF routine:
This does the pixel column shifting, and adding to a buffer
And at 88:8f67, this handles plotting to a pixel row
There's a lot of code omitted, but this is gist of the core VWF bit.
Unrelated, but this seems to be a compiled game: a lot of stack manipulation, code mostly deals with 16-bit and 32-bit values (each 32-bit ram var wasting a byte due to it being a 24-bit space)
The main routine is at 88:90f8, XA is the src of a 0-terminated ascii string, and Y is the pixel Y to plot to.
Example of code that calls it:
Code: Select all
; 83:b9c4
; First displayed VWF line (copyright), loads its ascii text from 83:bbd9 to pixel row 4
ldy #$0004
lda #$bbd9
ldx #$0083
jsl $8890f8
Some more snippets of the core part of the VWF routine:
This does the pixel column shifting, and adding to a buffer
Code: Select all
; 88:8fca
; This is a 16-bit table that maps 0-7 (pixel col in tile) to an address in `BufferShiftedCharByte` so that 0-7 `lsr`s are performed
ShiftsForBufferingCharByte:
.rept 8 index i
.dw BufferShiftedCharByte+(7-i)
.endr
; 88:8fda
; A - curr char's pixel row within a tile (0-7)
; X - curr char's row byte for the current bitplane (gets stored in wVwfCharPxRowByte)
; wVwfBitplaneDest - 0: bitplane 1, 1: bitplane 0, 2: bitplane 3, 3: bitplane 2
; wCurrVwfBufferAddr - manipped based on bitplane and pixel row, then passed onto `BufferShiftedCharByte`
; wVwfCurrCharsPixelColInTile - similar to A, but for col in tile
BufferVwfCharBitplane:
...
; B = char's row byte for the current bitplane. Shift it and add it to a tile data buffer
lda wVwfCharPxRowByte.b
xba
ldx wVwfCurrCharsPixelColInTile.b
jmp (ShiftsForBufferingCharByte, X)
; 88:9023
; B - char pixel row byte
; wVwfExistingTileDataForChar - the leftover tile data from previous chars
; wVwfRightHalfsTileDataOffs - offset into `wCurrVwfBufferAddr` for placing the left tile the shifted char tile data takes up
; wVwfLeftHalfsTileDataOffs - as above, for the right tile
; wCurrVwfBufferAddr
BufferShiftedCharByte:
; 0-7 of these `lsr`s are jumped to depending on the char's col position in a tile
lsr
lsr
lsr
lsr
lsr
lsr
lsr
; unknown - $a4 seems to be unused after this, but it will contain the final left+right combined result
ora wVwfExistingTileDataForChar.b
sta $a4
; Shifted char byte has right half in A, and left half in B, add them to the tile data buffer
ldy wVwfRightHalfsTileDataOffs
seta8
sta [wCurrVwfBufferAddr], Y
xba
ldy wVwfLeftHalfsTileDataOffs
sta [wCurrVwfBufferAddr], Y
seta16
rts
Code: Select all
.accu 16
.index 16
; wVwfCurrCharsPixelColInTile - curr char's pixel col within a tile (0-7)
; wVwfPxRowAdjust - curr char's starting pixel row within a tile (0-7)
; wVwfCharsFullTileDataSrc - points to the $20-byte tile data for the char
; wVwfCharBufferAddrTopHalf - in case `wVwfPxRowAdjust` isn't 0, this ram var points to the top tile's dest addr in a tile data buffer
; wVwfCharBufferAddrBottomHalf - as above, but for the bottom half
BufferFullVwfChar:
; Init bitplane dest, and save bank of VWF data buffer dest
stz wVwfBitplaneDest.b
lda wVwfCharBufferAddrTopHalf.b+2
sta wCurrVwfBufferAddr.b+2
@nextBitplane:
; Init pixel row for the bitplane, and the 1st pixel row idx in the current tile to draw to
stz wVwfCurrCharPxRow.b
lda wVwfPxRowAdjust.b
sta wVwfCharsPxRowAdjusted.b
; A = pixel row
lda #$0000
@nextPxRow:
; Each pixel row takes 2 bytes per $10 bytes
asl
tay
; Bitplanes 2 and 3 get tile data $10 bytes ahead
lda wVwfBitplaneDest.b
cmp #$0002
bcc @afterBitplane23adjust
tya
clc
adc #$0010
tay
@afterBitplane23adjust:
; Get char's pixel row tile data. Bitplanes 1/3 use the high/2nd byte...
lda [wVwfCharsFullTileDataSrc], Y
ldx wVwfBitplaneDest.b
beq @bitplane0or2
cpx #$0002
beq @bitplane1or3
; Bitplanes 0/2 use the low/1st byte
and #$00ff
bra +
@bitplane1or3:
and #$ff00
xba
; X (char's pixel row tile data byte) is saved for the below buffer routine
+ tax
; Jump if we're now drawing for the bottom tile
ldy wVwfCharsPxRowAdjusted.b
cpy #$0008
bcs @rowInBottomTile
; Else set the buffer addr to the top half, and pixel row to its adjusted val/plot Y
lda wVwfCharBufferAddrTopHalf.b
sta wCurrVwfBufferAddr.b
tya
jmp @bufferCharPxRow
@rowInBottomTile:
; Set buffer addr to the bottom half, and pixel row to its adjusted val-8 (plot Y within the bottom tile
lda wVwfCharBufferAddrBottomHalf.b
sta wCurrVwfBufferAddr.b
lda wVwfCharsPxRowAdjusted.b
and #$0007
@bufferCharPxRow:
; Buffer the char's row byte for the current bitplane
jsr BufferVwfCharBitplane
; +1 to pixel row being processed (to check if we've done all 8) and to the plot Y
inc wVwfCurrCharPxRow.b
inc wVwfCharsPxRowAdjusted.b
lda wVwfCurrCharPxRow.b
cmp #$0008
bcc @nextPxRow
; End once all bitplanes are done
inc wVwfBitplaneDest.b
lda wVwfBitplaneDest.b
cmp #$0004
bcc @nextBitplane
rts
Re: How did Final Fantasy VI do a non-fixed-width font?
As someone who has hacked SNES games and added variable width fonts before I can explain how it works.
So to draw text most SNES games will use a background layer. Since you have a limited amount of sprites you
can display each scanline; developers using sprites for text is rare.
Since SNES uses a background layer to display text; it is more difficult to do a non-fixed-width font on SNES
than on later consoles such as the PS1. On consoles such as PS1 to create a variable width font you simply
need to change the positions of textures.
So to create a variable width font on tile-based systems; developers use software rendering.
The main idea is this, you would draw a letter of text to a 16x16 tile buffer in WRAM. Let's call this tile
the "text_buffer_tile". Then you would shift each pixel in the next letter by the current letter's width and
store the shifted next letter into a second tile; let's call it the "shifted_tile". Then you would merge
the pixels in the shifted tile into the text buffer tile using "OR" instructions.
So now the text buffer tile should contain data from the first and second letter.
However, there's still one problem. You might shift the tile for the next letter and all of the pixels might not
fit into the shifted tile since the tile is only 16x16. Therefore, you will need a third tile to store pixels that overflow.
Overflowing pixels are basically pixels that don't fit into the current text tile.
So once the text buffer tile is filled, you DMA that tile to VRAM, clear the tile in WRAM and then write any overflowing
pixels to the text buffer tile. Then you rinse and repeat. Once the text buffer tile is filled again, you DMA it to the next
16x16 slot in VRAM and rinse and repeat.
So to draw text most SNES games will use a background layer. Since you have a limited amount of sprites you
can display each scanline; developers using sprites for text is rare.
Since SNES uses a background layer to display text; it is more difficult to do a non-fixed-width font on SNES
than on later consoles such as the PS1. On consoles such as PS1 to create a variable width font you simply
need to change the positions of textures.
So to create a variable width font on tile-based systems; developers use software rendering.
The main idea is this, you would draw a letter of text to a 16x16 tile buffer in WRAM. Let's call this tile
the "text_buffer_tile". Then you would shift each pixel in the next letter by the current letter's width and
store the shifted next letter into a second tile; let's call it the "shifted_tile". Then you would merge
the pixels in the shifted tile into the text buffer tile using "OR" instructions.
So now the text buffer tile should contain data from the first and second letter.
However, there's still one problem. You might shift the tile for the next letter and all of the pixels might not
fit into the shifted tile since the tile is only 16x16. Therefore, you will need a third tile to store pixels that overflow.
Overflowing pixels are basically pixels that don't fit into the current text tile.
So once the text buffer tile is filled, you DMA that tile to VRAM, clear the tile in WRAM and then write any overflowing
pixels to the text buffer tile. Then you rinse and repeat. Once the text buffer tile is filled again, you DMA it to the next
16x16 slot in VRAM and rinse and repeat.