Users browsing this thread: 1 Guest(s)
About the routine text from right to left(RTL)
hello, i wondering about the correct way, to flip the routine text dialogues from right to left (LTR to RTL) using ASM.
I have try this before in NES, but not sure about SNES Game because i know nothing really...
is there anyone give tips or guide to this challenge.
hope to find someone interested in this.
thanks...
I have try this before in NES, but not sure about SNES Game because i know nothing really...
is there anyone give tips or guide to this challenge.
hope to find someone interested in this.
thanks...
It has more to do with FF3us than SNES games meaning the SNES is not limited in this regard. Simply put you need to look at bank $C0. There is a RAM value for position on line ($BF). Instead of starting at #$04 (beginning X position) and checking for ((position += character width) > #$E0 (max X position)) to go to the next line, you start at #$E0 and decrease each time you draw a character, checking for ((#$E0 - position) >= #$04), where position is increased each time you draw (position += current character width).
It's not well documented but by studying the code in bank $C0 it is doable. There would be special stuff like actor names to take care of, check $C08067 for special opcodes cases. I made a text centering opcode and got a good idea of the system. Here is my code to center text:
It's not well documented but by studying the code in bank $C0 it is doable. There would be special stuff like actor names to take care of, check $C08067 for special opcodes cases. I made a text centering opcode and got a good idea of the system. Here is my code to center text:
Code:
;------------------------------------------------------------------------
; Centring Control Character code (OP#$17)
;------------------------------------------------------------------------
CChar:
LDA $BF ; Load current line position
CMP #$04 ; Beginning of line
BNE brn_exitB ; Branch if we are not at the start of a line
STZ $3F ; Current word length: 0
sub_loop:
LDY $00 ; Current dialogue character: pointer + 0
LDA [$C9],Y ; Load dialogue character
BPL notDTE ; Branch if not DTE
AND #$7F ; Isolate DTE ID
ASL A ; Multiply by 2
TAX ; Index it
LDA $CF ; Load text buffer byte
CMP #$80 ; Check if buffer is empty
BEQ .sub_loopB ; branch if buffer is empty
LDA #$80 ;
STA $CF ; Set buffer as not empty
BRA secondDTE ; Verify second DTE character
.sub_loopB
LDA $C0DFA0,X ; Load DTE character 1
TAY ; Transfer A to X
LDA [$1A],Y ; Load width for variable font cell
CLC ; Prepare addition (no carry)
ADC $3F ; Add font cell width to sentence width
STA $3F ; Save as sentence width
secondDTE:
LDA $C0DFA1,X ; Load DTE character 2
TAY ; Save character index
LDA [$1A],Y ; Load width for variable font cell
CLC ; Prepare addition (no carry)
ADC $3F ; Add font cell width to sentence width
STA $3F ; Save as sentence width
BRA checkEol ; Check end of line an increment pointer if necessary
notDTE:
LDY $00 ; Clear Index
LDA [$C9],Y ; Load dialogue character
CMP #$01 ; Is it new line character?
BEQ calcMiddle ; branch if so (calculate center)
CMP #$11 ; Is it end parameter character?
BEQ calcMiddle ; branch if so (calculate center)
CMP #$12 ; Is it end parameter character?
BEQ calcMiddle ; branch if so (calculate center)
CMP #$13 ; Is it end of page character?
BEQ calcMiddle ; branch if so (calculate center)
CMP #$20 ; Is the character a character code?
BCC incDialog ; Branch if so (increment dialogue pointer and loop)
TAY ; Save character index
LDA [$1A],Y ; Load width for variable font cell
CLC ; Prepare addition (no carry)
ADC $3F ; Add font cell width to sentence width
STA $3F ; Save as sentence width
checkEol:
CMP #$E0 ; Compare to line max width
BCS brn_exitB ; we have ended the line, there's nothing to center...
incDialog:
INC $C9 ; Increment dialogue
BNE sub_loop
INC $CA
BNE sub_loop
INC $CB
BRA sub_loop
brn_exitB:
RTS
calcMiddle:
LDA #$E0 ; Load line width
SBC $3F ; Subtract sentence width
LSR A ; Divide by 2
STA $BF ; Store as position in line
TAY
STY $4204 ; Whatever is left, store as to be divided
LDA #$10
STA $4206 ; Divide Y by 16
NOP
NOP
NOP
NOP
NOP
NOP
NOP
LDA $4214 ; Load the division result
STA $4202 ; Store as a multiplier
LDA #$20
STA $4203 ; Multiply previous result by 32
NOP
NOP
NOP
LDA $4216 ; Get the multiplication result
ADC $C1
STA $C1
BRA brn_exitB
I wanted to add last night that the main entry point for dialogue display and decoding seems to be $C0814C. There are call to code before and after this offset. Here is also some RAM values from the FF6 wiki that could help:
Code:
$BA-$BC Dialog Window
---------------------
$BA Enable Dialog Window ($01 = open, $80 = close)
$BB Dialog Window Size ($00: smallest, $05: fully open)
$BC Dialog Window Top Y Position ($01: top, $12: bottom)
$BD-$D3 Dialog Text
-------------------
$BD Current Dialog Character
$BE Next Dialog Character
$BF Text's Current X Position on Dialog Window ($04-$E0)
$C0 Width of Current Word
+ $C1 Pointer to Next Tile in VRAM (+$3800)
+ $C3 Pointer to Current Tile in VRAM (+$3800)
$C5 Text Graphics Needs to be Copied to VRAM
+ $C6 Unused (set to #$0700)
$C8 Max X Position on Dialog Window (always $E0?)
++ $C9 Pointer to Current Dialog Character
$CC current region of dialog window that needs to be cleared in VRAM (starts at 9, decrements once per frame)
9 = none, waiting for keypress
+-----------+-----------+
| 8 | 7 |
+-----------+-----------+
| 6 | 5 |
+-----------+-----------+
| 4 | 3 |
+-----------+-----------+
| 2 | 1 |
+-----------+-----------+
0 = none, no text displayed (or map name displayed)
+ $CD Character to Display (top byte is for extra characters from FF6j)
$CF eppppppp
e: text buffer is empty
p: dialog text buffer position (+$7E9183)
+ $D0 Dialog Index
$D2 -
$D3 Keypress State (decrements when button is pressed or released)
0 = not waiting for keypress
1 = waiting for keypress
2 = waiting for key release
« Next Oldest | Next Newest »
Users browsing this thread: 1 Guest(s)