Font engine refactor

String rendering code is now replicated for each font, which makes the code much faster and tighter. This will also immensely simplify switching to left-justified text rendering, which turns out to be important. :-|
This commit is contained in:
blondie7575 2023-07-16 20:10:00 -07:00
parent 6a30a6a0dc
commit 1d3bfeba8f
9 changed files with 6356 additions and 101 deletions

1
.gitignore vendored
View File

@ -7,3 +7,4 @@
/fontEngine.lst /fontEngine.lst
/FONTBANK\#060000 /FONTBANK\#060000
/Art/Generated /Art/Generated
/fonts.lst

View File

@ -40,6 +40,9 @@ def main(argv):
numCharX = (int)(image.size[0]/CHAR_WIDTH) numCharX = (int)(image.size[0]/CHAR_WIDTH)
numCharY = (int)(image.size[1]/CHAR_HEIGHT) numCharY = (int)(image.size[1]/CHAR_HEIGHT)
# Generate wrapper code
addWrapperCode(prefix,CHAR_WIDTH,CHAR_FIRST)
# Generate jump table for glyphs # Generate jump table for glyphs
print ("%scharacterJumpTable:" % prefix) print ("%scharacterJumpTable:" % prefix)
for charY in range(0,numCharY): for charY in range(0,numCharY):
@ -152,7 +155,91 @@ def main(argv):
pendingStackMove += nextRowDelta # Save this stack move for next row, because we can often combine them pendingStackMove += nextRowDelta # Save this stack move for next row, because we can often combine them
# Footer for each rendering operation # Footer for each rendering operation
print ("\tjmp renderCharJumpReturn\n") print ("\tjmp renderCharJumpReturn_%s\n" % prefix)
return
def addWrapperCode(prefix, charWidth, firstChar):
code = """
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; renderString_{:s}
;
; Draws a Pascal string for font "{:s}"
;
; PARAML0 = Pointer to string
; Y = VRAM position of lower right corner of string at which to draw
;
; Trashes SCRATCHL,X,Y,A
;
renderString_{:s}:
sty SCRATCHL ; Cache VRAM position
plb ; Temporarily revert to caller's DBR to access their pointer
BITS8
lda (PARAML0)
tax
BITS16
phb
renderStringLoop_{:s}:
; Fetch and render next character in string
txy
lda #0
plb ; Temporarily revert to caller's DBR to access their pointer
BITS8A
lda (PARAML0),y
BITS16
phb
ldy SCRATCHL
jsr renderChar_{:s}
dex
beq renderStringDone_{:s}
; Calculate VRAM pointer for position of next character
lda SCRATCHL
sec
sbc #{:d}/2 ; Width of one char in bytes
sta SCRATCHL
bra renderStringLoop_{:s}
renderStringDone_{:s}:
jmp renderStringReturn
.export renderString_{:s}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; renderChar_{:s}
;
; Draws a single character
;
; A = ASCII code to draw
; Y = VRAM position of lower right corner at which to draw
;
renderChar_{:s}:
SAVE_AXY
sec
sbc #{:d} ; ASCII code of first char in font sheet
asl
tax
FASTGRAPHICS
jmp ({:s}characterJumpTable,x)
renderCharJumpReturn_{:s}: ; Compiled glyphs jump back here. Can't rts because stack is turboborked
SLOWGRAPHICS
RESTORE_AXY
rts
""".format(prefix,prefix,prefix,prefix,prefix,prefix,charWidth,prefix,prefix,prefix,prefix,prefix,firstChar,prefix,prefix)
print (code)
return
if __name__ == "__main__": if __name__ == "__main__":
main(sys.argv[1:]) main(sys.argv[1:])

View File

@ -71,10 +71,10 @@ terrain_e1:
fonts: fonts:
rm -rf $(FONTBANK) rm -rf $(FONTBANK)
./CompileFont.py 8 8 32 0 "font8" "Art/Assets/Font8x8.gif" > font8x8.s ./CompileFont.py 4 5 48 0 "tinyNum" "Art/Assets/TinyNumbers.gif" > fonts.s
./CompileFont.py 16 16 32 14 "font16" "Art/Assets/Font16x16.gif" > font16x16.s ./CompileFont.py 8 8 32 0 "font8" "Art/Assets/Font8x8.gif" >> fonts.s
./CompileFont.py 4 5 48 0 "num4" "Art/Assets/TinyNumbers.gif" > tinyNumbers.s # ./CompileFont.py 16 16 32 14 "font16" "Art/Assets/Font16x16.gif" > font16x16.s
@PATH=$(PATH):/usr/local/bin; $(CL65) -t apple2enh -C linkerConfig --cpu 65816 --start-addr 0000 -lfonts.lst fontEngine.s -o $(FONTBANK) @PATH=$(PATH):/usr/local/bin; $(CL65) -t apple2enh -C linkerConfig --cpu 65816 --start-addr 0000 -lfontEngine.lst fontEngine.s -o $(FONTBANK)
rm -f fontEngine.o rm -f fontEngine.o
clean: clean:

View File

@ -44,9 +44,6 @@ RANDOM = $ce ; 16 bit random number
RANDOML = $ce ; Low byte of random number generator RANDOML = $ce ; Low byte of random number generator
RANDOMH = $cf ; High byte of random number generator RANDOMH = $cf ; High byte of random number generator
; Far entry points
renderStringFar = $050000
; Terrain constants ; Terrain constants
TERRAINWIDTH = 640 ; In pixels TERRAINWIDTH = 640 ; In pixels
MAXTERRAINHEIGHT = 100 ; In pixels MAXTERRAINHEIGHT = 100 ; In pixels
@ -65,6 +62,9 @@ terrainData = $f500
; .endrepeat ; .endrepeat
terrainDataEnd = terrainData + (TERRAINWIDTH/2 * 2) terrainDataEnd = terrainData + (TERRAINWIDTH/2 * 2)
; Far symbols
renderStringFar = $050000 ; Main entry for font rendering engine
; Stash the size of the sound bank at the end of sound memory so loader can pass it to sound system ; Stash the size of the sound bank at the end of sound memory so loader can pass it to sound system
soundBankSize=$04fffe soundBankSize=$04fffe

View File

@ -4,113 +4,35 @@
.org $0000 .org $0000
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; renderString (Far entry point) ; renderString (Far entry point at $050000)
; ;
; Draws a Pascal string ; Draws a Pascal string in any font
; ;
; PARAML0 = Pointer to string ; PARAML0 = Pointer to string
; X = Font index
; Y = VRAM position of lower right corner of string at which to draw ; Y = VRAM position of lower right corner of string at which to draw
; A = Font index
; ;
; Trashes SCRATCHL,SCRATCHL2,PARAML1,X, Y, A ; Trashes SCRATCHL,X,Y,A
; ;
renderString: renderString:
NATIVE NATIVE
SAVE_DBR SAVE_DBR
sty SCRATCHL ; Cache VRAM position
txa ; Cache font character tables
asl asl
tay
lda fontJumpTable,y
sta renderCharBounce+1
lda fontFirstCharTable,y
sta SCRATCHL2
lda fontCharWidthTable,y
sta PARAML1
plb ; Temporarily revert to caller's DBR to access their pointer
BITS8
lda (PARAML0)
tax tax
BITS16 jmp (fontJumpTable,x) ; Can't JSR here because we need the stack in a particular state (with DBR cached on top)
phb
renderStringLoop: renderStringReturn:
; Fetch and render next character in string
txy
lda #0
plb ; Temporarily revert to caller's DBR to access their pointer
BITS8A
lda (PARAML0),y
BITS16
phb
ldy SCRATCHL
jsr renderChar
dex
beq renderStringDone
; Calculate VRAM pointer for position of next character
lda SCRATCHL
sec
sbc PARAML1
sta SCRATCHL
bra renderStringLoop
renderStringDone:
RESTORE_DBR RESTORE_DBR
rtl rtl
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; renderChar
;
; Draws a single character
;
; A = ASCII code to draw
; Y = VRAM position of lower right corner at which to draw
; SCRATCHL2 = First char in font
;
renderChar:
SAVE_AXY
sec
sbc SCRATCHL2
asl
tax
FASTGRAPHICS
renderCharBounce: ; Self modifying code. Don't panic
jmp ($1234,x)
renderCharJumpReturn: ; Compiled glyphs jump back here. Can't rts because stack is turboborked
SLOWGRAPHICS
RESTORE_AXY
rts
fontJumpTable: fontJumpTable:
.addr font8characterJumpTable .addr renderString_tinyNum
.addr font16characterJumpTable .addr renderString_font8
.addr num4characterJumpTable
fontCharWidthTable: ; In bytes
.word 4
.word 8
.word 2
fontFirstCharTable: ; ASCII codes .include "fonts.s"
.word 32
.word 32
.word 48
.include "tinyNumbers.s"
.include "font8x8.s"
.include "font16x16.s"
; Suppress some linker warnings - Must be the last thing in the file ; Suppress some linker warnings - Must be the last thing in the file
; This is because Quinn doesn't really know how to use ca65 properly ; This is because Quinn doesn't really know how to use ca65 properly

6245
fonts.s Normal file

File diff suppressed because it is too large Load Diff

View File

@ -229,7 +229,7 @@ drawNumber:
lda #intToStringResult lda #intToStringResult
sta PARAML0 sta PARAML0
txy txy
ldx #0 lda #1
jsl renderStringFar jsl renderStringFar
RESTORE_AXY RESTORE_AXY

View File

@ -135,7 +135,7 @@ renderInventoryItem_unselected:
tay tay
lda #intToStringPrefix lda #intToStringPrefix
sta PARAML0 sta PARAML0
ldx #2 lda #0
jsl renderStringFar jsl renderStringFar
renderInventoryItem_done: renderInventoryItem_done:

View File

@ -439,7 +439,7 @@ renderPlayerHeader:
sta PARAML0 sta PARAML0
phy phy
ldy #$25c0 ldy #$25c0
ldx #0 lda #1
jsl renderStringFar jsl renderStringFar
ply ply
@ -462,8 +462,8 @@ renderPlayerHeader:
lda #treatsStr lda #treatsStr
sta PARAML0 sta PARAML0
ldy #$25f2 ldy #$25f2
ldx #0 lda #1
jsl renderStringFromLeftFar jsl renderStringFar
RESTORE_AXY RESTORE_AXY
rts rts