Users browsing this thread: 2 Guest(s)
About the routine text from right to left(RTL)
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
« Next Oldest | Next Newest »
|
||||
Users browsing this thread: 2 Guest(s)