333 lines
12 KiB
PHP
333 lines
12 KiB
PHP
;-----------------------------------------------------------------------------
|
|
; text.inc
|
|
; Part of manic miner, the zx spectrum game, made for Apple II
|
|
;
|
|
; Stefan Wessels, 2020
|
|
; This is free and unencumbered software released into the public domain.
|
|
|
|
;-----------------------------------------------------------------------------
|
|
.segment "CODE"
|
|
|
|
;-----------------------------------------------------------------------------
|
|
.proc textSHowText
|
|
|
|
xpos = srcPtrL
|
|
ypos = srcPtrH
|
|
rows = sizeH
|
|
strIndex = sizeL
|
|
color = dstPtrL ; and H
|
|
fontL = charGfx + 1
|
|
fontH = charGfx + 2
|
|
|
|
stx xpos
|
|
sty ypos
|
|
|
|
loop:
|
|
lda #0
|
|
sta fontH ; init the pointer hi to 0 for later mult rol's
|
|
ldx strIndex ; get the index into the string
|
|
|
|
read:
|
|
lda PLACEHOLDER, x ; get the character in the string
|
|
sec
|
|
sbc #32 ; the font only starts at space (char 32 or $20)
|
|
asl ; mult by 16 as that's how wide a char is in bytes
|
|
asl
|
|
rol fontH
|
|
asl
|
|
rol fontH
|
|
asl
|
|
rol fontH ; srcPtr now points at the char but $0000 based
|
|
adc #<font ; add the font start
|
|
sta fontL
|
|
lda fontH
|
|
adc #>font
|
|
sta fontH ; srcPtr now point at the actual character memory
|
|
|
|
lda #8 ; font is 8 rows high
|
|
sta rows
|
|
ldy ypos ; start each character on the same line
|
|
|
|
iLoop:
|
|
lda strIndex ; strIndex is also col offset from xpos
|
|
asl ; but font is 2 cols wide
|
|
adc xpos ; add the xpos to get screen col
|
|
adc rowL, y ; and add the row
|
|
sta write + 1 ; lo byte of where to write to screen buffer
|
|
lda currPageH ; get the hi page
|
|
adc rowH, y ; add the row
|
|
sta write + 2 ; and complete the screen buffer write address
|
|
|
|
ldx #1 ; set up for copying 2 font bytes (1 char)
|
|
charGfx:
|
|
lda PLACEHOLDER, x ; get the font
|
|
eorMask:
|
|
eor #$00 ; eor to invert if necessary
|
|
and color, x ; and to get the color needed
|
|
write:
|
|
sta PLACEHOLDER, x ; and write to screen memory
|
|
dex ; go left a byte
|
|
bpl charGfx ; and repeat to do 2 bytes
|
|
dec rows ; done one of the 8 rows needed
|
|
beq nextChar ; repeat for all 8 rows, then done
|
|
iny ; more rows - next row in y
|
|
lda fontL ; move along 2 in the font
|
|
adc #2
|
|
sta fontL
|
|
bcc iLoop
|
|
inc fontH
|
|
bcs iLoop ; BRA
|
|
|
|
nextChar:
|
|
dec strIndex ; string done from the back, so move left in string
|
|
bpl loop ; if not all of string done, loop
|
|
|
|
done:
|
|
rts
|
|
|
|
.endproc
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; Macro that takes a lo and hi for the text with optional color and invert wanted
|
|
; sets up what's needed to call textShow which does the printing
|
|
.macro printXYlh xpos, ypos, textL, textH, len, colorMask, inverse
|
|
|
|
.local color, strIndex
|
|
|
|
color = dstPtrL ; textShow expects color masks in dstPtr(L and H)
|
|
strIndex = sizeL
|
|
|
|
.ifblank colorMask
|
|
lda #$ff ; no color (white) is a mask of $ff left and right
|
|
sta color
|
|
sta color + 1
|
|
.else
|
|
ldx colorMask ; this is an index into mask[Left|Right]
|
|
lda masksLeft, x
|
|
sta color
|
|
lda masksRight, x
|
|
sta color + 1
|
|
.endif
|
|
|
|
.ifblank inverse
|
|
lda #0 ; eor o is not inverse
|
|
.else
|
|
lda #$7f ; eor $7f inverts the color (leave MSB)
|
|
.endif
|
|
|
|
sta textSHowText::eorMask + 1 ; set the eor in the code
|
|
|
|
lda textL ; set the string pointer in the code
|
|
sta textSHowText::read + 1
|
|
lda textH
|
|
sta textSHowText::read + 2
|
|
ldx len ; 0 based
|
|
stx strIndex
|
|
lda xpos ; and x/y coords in x and y registers
|
|
asl
|
|
tax
|
|
ldy ypos
|
|
jsr textSHowText ; print that string
|
|
|
|
.endmacro
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; macro to take text address and split it into lo and hi (shorthand)
|
|
.macro printXY xpos, ypos, text, len, colorMask, inverse
|
|
printXYlh xpos, ypos, #<text, #>text, len, colorMask, inverse
|
|
.endmacro
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; Build a memory cache of the level name since this is re-drawn much more -
|
|
; every time the level scrolls left or right and copying from a cache is
|
|
; much faster than doing a text print
|
|
.proc textSetLevelText
|
|
|
|
lda #0
|
|
sta sizeL ; index into string
|
|
sta read + 2 ; hi byte of string address
|
|
|
|
lda currLevel ; start with the level
|
|
asl ; multiply by 32
|
|
asl
|
|
asl
|
|
asl
|
|
rol read + 2
|
|
asl
|
|
rol read + 2
|
|
adc #<roTextLevel ; add the base address of the string
|
|
sta read + 1
|
|
lda #>roTextLevel
|
|
adc read + 2
|
|
sta read + 2 ; read + 1 as a ptr now points at the string for this level
|
|
|
|
lda #<levelNameGfx0 ; start at the top of the name cache
|
|
sta write + 1 ; and make write + 1 be a pointer to the cache
|
|
lda #>levelNameGfx0
|
|
sta write + 2
|
|
|
|
lda #32 ; These strings are 32 characters wide
|
|
sta dstPtrL
|
|
|
|
loop:
|
|
lda #0
|
|
sta srcPtrH ; init the pointer hi to 0 for later mult rol's
|
|
ldx sizeL ; get the index into the string
|
|
read:
|
|
lda PLACEHOLDER, x ; get the character in the string
|
|
sec
|
|
sbc #32 ; the font only starts at space (char 32 or $20)
|
|
asl ; mult by 16 as that's how wide a char is in bytes
|
|
asl
|
|
rol srcPtrH
|
|
asl
|
|
rol srcPtrH
|
|
asl
|
|
rol srcPtrH ; srcPtr now points at the char but $0000 based
|
|
adc #<font ; add the font start
|
|
sta srcPtrL
|
|
lda srcPtrH
|
|
adc #>font
|
|
sta srcPtrH ; srcPtr now point at the actual character memory
|
|
|
|
lda #8 ; copy 8 rows / character
|
|
sta sizeH
|
|
ldy #1 ; start at the right hand side character
|
|
lrLoop:
|
|
ldx #1 ; load x for the right hand side as well
|
|
copyLoop:
|
|
lda (srcPtrL), y ; get the line pixel
|
|
eor #$7f ; invert
|
|
maskName:
|
|
and maskGreen, x ; mask for color (always green but left vs right hand side)
|
|
write:
|
|
sta PLACEHOLDER, x ; store to the cache
|
|
dey ; back up a byte
|
|
dex
|
|
bpl copyLoop ; do 2 bytes, right and left hand
|
|
lda write + 1 ; get the cache ptr low
|
|
clc
|
|
step:
|
|
adc #64 ; step to the next line - 64 bytes along
|
|
sta write + 1 ; update the pointer
|
|
bcc :+
|
|
inc write + 2 ; if it wrapped, update the hi byte
|
|
:
|
|
iny ; y is now at minus 1 the last byte written
|
|
iny ; so advance it by 4 to get to the next right hand side byte
|
|
iny
|
|
iny
|
|
dec sizeH ; done one line
|
|
bne lrLoop ; if any lines left, keep going
|
|
|
|
sec
|
|
lda write + 1
|
|
sbc #<((64*8)-2)
|
|
sta write + 1
|
|
lda write + 2
|
|
sbc #>((64*8)-2)
|
|
sta write + 2
|
|
clc
|
|
|
|
inc sizeL ; move to the next character in the string
|
|
dec dstPtrL ; see if 32 characters were done
|
|
bne loop ; if not, keep going
|
|
|
|
done:
|
|
rts
|
|
|
|
.endproc
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; x has digit (5 means 1's, 4 means 10's, etc)
|
|
; a is the number to add 0..9
|
|
.proc textAddScore
|
|
|
|
clc
|
|
adc score, x ; get the current digit
|
|
cmp #'9'+1 ; has it rolled over
|
|
bcc okay ; then simply increment
|
|
sec
|
|
sbc #10
|
|
sta score, x ; and save over the 9
|
|
lda #1
|
|
dex ; previous digit
|
|
bmi over ; if it rolls over 999999
|
|
cpx #1 ; if the digit is now the 010000 (1)
|
|
bne textAddScore ; no, then work with this digit
|
|
ldy lives
|
|
cpy #9 ; max out at 9 lives (keeps cheat boot on-screen)
|
|
bcs textAddScore
|
|
inc lives ; yes, then add a life
|
|
bne textAddScore ; and then work with this digit
|
|
okay:
|
|
sta score, x ; and store it
|
|
over:
|
|
lda #UI_COMPONENT_SCORE ; mark the score texts as needing an update
|
|
jmp uiUpdateComponent
|
|
|
|
done:
|
|
rts
|
|
|
|
.endproc
|
|
|
|
;-----------------------------------------------------------------------------
|
|
.proc textCheckHighScore
|
|
|
|
ldx #0 ; start at the most significant digit
|
|
:
|
|
lda score, x ; get the score
|
|
cmp highScore, x ; compare to the high score
|
|
bcc done ; if smaller then highscore gt score
|
|
bne newHigh ; if ne then highscore gt score
|
|
inx ; digits equal so check next digit
|
|
cpx #6 ; compare x to max digits (+ 1)
|
|
bcc :- ; x is 5 or less, keep checking digits
|
|
|
|
done:
|
|
rts
|
|
|
|
newHigh:
|
|
ldx #5 ; copy the 6 score digits over the highscore digits
|
|
:
|
|
lda score, x
|
|
sta highScore, x
|
|
dex
|
|
bpl :-
|
|
lda #UI_COMPONENT_HIGHSCORE
|
|
jmp uiUpdateComponent
|
|
|
|
.endproc
|
|
|
|
;-----------------------------------------------------------------------------
|
|
.proc textColorCycle
|
|
|
|
color = tmpBot + 1
|
|
xPos = tmpBot + 2
|
|
yPos = tmpBot + 3
|
|
textL = tmpBot + 4
|
|
textH = tmpBot + 5
|
|
len = tmpBot + 6
|
|
|
|
prntLoop:
|
|
printXYlh xPos, yPos, textL, textH, #0, color
|
|
|
|
dec len ; one less character to color
|
|
beq done ; all characters done?
|
|
inc xPos ; move to the next character on screen
|
|
inc textL ; and move to the next character in the sting
|
|
bne :+ ; did the string wrap a buffer
|
|
inc textH ; yes, up the Hi
|
|
:
|
|
dec color ; prev color
|
|
bpl :+ ; still ge 0
|
|
lda #4 ; no, wrap to index 4
|
|
sta color ; and save that as the color
|
|
:
|
|
jmp prntLoop ;and print this character
|
|
|
|
done:
|
|
rts
|
|
|
|
.endproc
|