;###########################################;

; Variable width font routine for xxxxxx    ;
; The change affects the main dialogue only ;
; Compiled using Byuu's xKas software.      ;
; NOTE: Code inserted Assuming NO HEADER    ;
;###########################################;

;##########################
; Variables that exist    #
;##########################
 !Tile	 = $0C80
 !Xpos	 = $0C88
 !Char	 = $0C8A
 !Bits	 = $0CDC
 !iCount = $0CDE

 !Temp1	 = $0CE0	; for adding shadow
 !Temp2	 = $0CE2	; for adding shadow
 !Ypos	 = $0CE4	; $0CE2 + $0CE3

 !Buffer = $8010	; actually = $7f8000
;##########################
; Variables that exist    #
;##########################



hirom

;----------------------;
; Main routine's start ;
;----------------------;
main() assume mx:%10 {

;---------------------------------------;
; Redirect the original code to my code ;
;---------------------------------------;
	org $C00B92
FixLineBreak:
	jsl _ResetPixelsLeft_
	nop

;------------------------------------------;
; This fixes the number conversion routine ;
;------------------------------------------;
	org $C0197C
FixNumbers:
	adc.w #$0030

	;-------------
	org $C00AD2
InitSomeVariables:
	jsl	_Init_Vars_
	nop
	nop

	;-------------

	org $C00BB7
RedirectFontCode:
	jsl	_Vwf_Main_
rts



;-----------------------;	
;                       ;
; VWF Routine Main Code ;
;                       ;
;-----------------------;
	org $ED0200
_Vwf_Main_:
	php
	rep #$30
	;-----------
	lda !Char
	and.w #$00ff
	sta !Char
	sec
	sbc.w #$0020
	;-----------
	rep 5 : asl 
	sta !Xpos
	sep #$20
	stz !Bits+1
	stz !Tile+1

;-----------------------------------;
; Start loading the font and adjust ;
; where needed. Simple routine.     ;
;-----------------------------------;
_Load_Data_:  
	lda !Bits		; check to see if any bits left on previous tile
	beq _New_Tile_		; if none, then start a new tile

	;-------------
	and.b #$0F
	sta !Bits
	bne _Tile_Used_		; if not, store data from new font on the previous tile
	;-------------
	stz !Bits		; else, clear the bits when bits == #$10

_Tile_Used_:			; still decrement because tile was increased twice
	dec !Tile		; return to the previous tile

;------------------------------;
; Use a new tile when starting ;
; or when a tile is used all up;
;------------------------------;
_New_Tile_:			; New tile or VWF tile
	rep #$20
	lda !Tile 		; load the tile position
	and.w #$001F
	rep 5 : asl  		; 32 bytes per tile -> 16x16 tile, 2-Bpp
	sta !Ypos		; Y = index to current TILE in memory


;######################################
; Universal font adjust If needed...  #
;######################################
Load_Font:
	ldy !Ypos		; get to tile data storage position
	ldx !Xpos		; get to font data in ROM

	;------------
	sep #$20
	lda !Bits		; test to see if any bits left from previous tile
	bne _Bits_Left_
 	
	;------------
	jmp _No_Bit_Shift_	; if not, DON'T Adjust new font data on the current tile

_Bits_Left_:
	pha			; we have bits left, so shift tile. 
	dec			; subtract 1 since there is no ZERO index
	asl			; To index a WORD table, multiply value by 2
	sta !Bits		; Value = Index to shift table	

	;------------
	lda #$02
	sta !Xpos		; loop conter, do twice

_Top_Bottom:
	lda.b #$08		; 32-loops per font -> Adjust a 8x16 - 2-Bpp font
	sta !iCount		; loop counter

	;------------------------;
	; Adjust the tile pixels ;
	;------------------------;
	Adjust:
		lda FontData,x   	; load a byte from the font. Set it as the HIGH byte	
		xba
		lda FontData+8,x 	; load the other side of the font
		inx
		rep #$20		

		;------------
		phx	
		ldx !Bits		; get the shift table index
		jsr ShiftBits
		jsr _Merge_Tiles_	; add in old font data and store as new font data
					; ( SEE SUBROUTINE AT THE END OF FILE )
		plx
		;------------

		sep #$20
		dec !iCount		; decrement tile loop counter
		bne Adjust		; loop until counter == #$00

	;------------
	jsr Set_Y_Index
	dec !Xpos
	bne _Top_Bottom

	;------------
	lda $01,s		; load the bits left from stack
	sta !Bits 
	ldx !Char		; load char pointer value
	lda Width,x		; load width of that font
	cmp !Bits		; is it larger than what was left on the current tile?
	beq _NoOverFlow_	; if we used all pixels and no over flow, then no left shift needed
	;-------------
	bcc _NoOverFlow_	; if not, then go do the math to setup for the next font on the same tile

;###################################;
; Finish loading the font data.     ;
; There was data overflow.          ;
; Now adjust by shifting tiles left ;
;###################################;
_OverFlow_:
	pha			; save the font's width
	lda.b #$10
	sec	
	sbc $02,s		; the bits left is what the font needs to	
	dec
	clc
	adc.b #$0F		; access the Left Shift table
	asl
	sta !Bits		; use this value as the shift table index

	;------------
	pla			; restore the font's width
	sec
	sbc $01,s		; EX: 6 pixels left. ( Font width = 8 ). 
	sta $01,s		;     ( 8 - 6 = 2 ), 2 = NEW pixels left. 

	;------------
	lda.b #$10		; NEW tile size
	sec
	sbc $01,s		; Subtract the bits used from a NEW tile size
	sta $01,s		; save as NEW pixels left

	;------------
	inc !Tile		; get to the next tile
	lda !Tile		

	rep #$20
	and.w #$001F
	rep 5 : asl 		; 64 bytes for a 16x16 tile 
	;------------

	tay
	lda !Char
	sec
	sbc.w #$0020
	rep 5 : asl 
	tax 
	;------------
	sep #$20
	lda.b #$02
	sta !Xpos		; 2 - loop conter

_Top_Bottom3:
	lda.b #$08		; 
	sta !iCount		; loop counter

;##########################;
;                          ;
;##########################;
	Left_Shift: 
		lda FontData,x		; load the font data
		xba
		lda FontData+8,x	; load the other half of the same font
		inx
		rep #$20		
	
		;-------------
		phx
		ldx !Bits
		jsr ShiftBits
		jsr _Merge_Tiles_	; store the first 8-Bit value with No ORA'ing or EOR'ing
					; ( SEE SUBROUTINE AT THE END OF FILE )
		plx

		;------------
		sep #$20
		dec !iCount		; loop until the font is done
		bne Left_Shift
	
	;------------
	jsr Set_Y_Index
	dec !Xpos
	bne _Top_Bottom3

	;------------
	pla			; pull the bits left
	sta !Bits		; store as NEW bits left for later use
	bra EndOfRoutine	; goto the end


;##################################
; Come here when current Char's   #
;width is <= Bits left on the tile#
;##################################
_NoOverFlow_:
	; Assumes: Bits left still on stack
	;-------------
	lda !Bits		; load the bits left
	sec			; set the carry flag	
	sbc Width,x		; subtract the width of the NEWLY stored font from bits left
	sta !Bits 		; store that value as the NEW bits left
	pla			; pull garbage
	bra EndOfRoutine	; leave routine

;#########################################
; Do no shifting at all to the font data #
;#########################################
_No_Bit_Shift_:
	sep #$20
	lda.b #$02		; 2 loops, 8 for top -> 8 for bottom
	sta !Xpos		; this is to load and store the top and bottom tiles

_Top_Bottom2:
	lda.b #$08
	sta !iCount

	;------------
	_Loop_:
		lda FontData,x 		; load font data
		xba
		lda FontData+8,x
		inx
		;-------------
		jsr _Merge_Tiles_
		sep #$20
		dec !iCount
		bne _Loop_

	;------------
	jsr Set_Y_Index
	dec !Xpos
	bne _Top_Bottom2

	;------------
	ldx !Char
	lda.b #$10		; load tile width
	sec
	sbc Width,x		; subtract font's width
	sta !Bits		; store as bits left

;-----------------------------------;
;                                   ;
; End of the VWF 16x16 font routine ;
;                                   ;
;-----------------------------------;
EndOfRoutine:		; leave routine
	sep #$20
	inc !Tile
	plp
rtl
}



;############################
; Bit Shifting Code         ;
;############################
ShiftBits:            ; Assumes X = Index to Shift Table
  
  jmp (_Shifter_,X)

_Shifter_:
 dw _R1,_R2,_R3,_R4,_R5,_R6,_R7,_R8,_R9,_RA,_RB,_RC,_RD,_RE,_RF
 dw _L1,_L2,_L3,_L4,_L5,_L6,_L7,_L8,_L9,_LA,_LB,_LC,_LD,_LE,_LF


;###########################
; Shift bits to the right  ;
;###########################
_R1:
  LSR
_R2:
  LSR
_R3:
  LSR
_R4:
  LSR
_R5:
  LSR
_R6:
  LSR
_R7:
  LSR
_R8:
  LSR
_R9:
  LSR
_RA:
  LSR
_RB:
  LSR
_RC:
  LSR
_RD:
  LSR
_RE:
  LSR
_RF:
  LSR

  ;------------;
rts


;###########################
; Shift bits to the left   ;
;###########################
_L1:
  ASL
_L2:
  ASL
_L3:
  ASL
_L4:
  ASL
_L5:
  ASL
_L6:
  ASL
_L7:
  ASL
_L8:
  ASL
_L9:
  ASL
_LA:
  ASL
_LB:
  ASL
_LC:
  ASL
_LD:
  ASL
_LE:
  ASL
_LF:
  ASL

  ;------------;
rts


;############################
; Add in the shadow to font #
;############################
_Merge_Tiles_:		 	
	php
	rep #$20
	pha 
	jsr _Store_Byte_
	;-------------
	pla
	jsr _Store_Byte_
	plp
rts


;#############################
; Store the data correctly   #
;#############################
_Store_Byte_:
	php
	sep #$20
	phb
	pea $7F7F
	plb  
	plb
	;------------
	ora !Buffer+16,y		; The lost pixels are stored first
	sta !Buffer+16,y
	xba
	ora !Buffer,y			; Store the working pixels also
	sta !Buffer,y 
	;------------
	plb
	iny
	plp
rts


;########################
; Set Y for top/bottom  #
;########################
Set_Y_Index:
	php
	rep #$20
	tya
	clc
	adc.w #$01F0
	tay
	txa
	clc
	adc.w #$0008
	tax
	plp
rts


;##############################;
; This code resets pixels left ;
; after a line break is called ;
;##############################;
_ResetPixelsLeft_:
	sep #$20
	stz !Bits
	stz !Tile
rtl


;#################################;
; This code resets pixels left    ;
; and a few other needed variables;
;#################################;
_Init_Vars_:
	stz $0C90
	stz !Tile
	stz !Bits
rtl
}

;-------------------------------;
; Where the font data is stored ;
;-------------------------------;
;	org $ED0200
FontData:
	incbin C:\romhack\trans\xxxxxx\Dat\Tahoma.bin
Width:
	incbin C:\romhack\trans\xxxxxx\Dat\Tahoma.wid

