BuGS/BuGS/global.macros

350 lines
7.9 KiB
Plaintext

;
; global.macros
; BuGS
;
; Created by Jeremy Rand on 2020-07-30.
;Copyright © 2020 Jeremy Rand. All rights reserved.
;
macro
_drawDirtyGameRow &rowNum
_drawDirtyGameRow_wait&rowNum anop
; This code loads into the accumulator the line currently being drawn to the
; screen by HW. It allows code to race just behind the beam and redraw the
; screen.
;
; Based on code found here:
; https://iigs.dreamhosters.com/gte/blitter.html
;
; Unlike that code, it does not change the baseline of the values. According
; to GS technote 39, this number ranges from $fa to $1ff. Scan line zero is
; $100 and scan line 199 is $1c7. We will race the beam by comparing to these
; offset numbers.
;
; Also according to that technote, it looks like these numbers are different
; in PAL mode. Do I need something here to handle PAL correctly? I switched
; my GS to 50Hz mode (startup/reboot with option held down to get the menu)
; and I didnt't detect any graphics glitches at all. I did notice that the
; game is noticably easier because things run a bit slower. If I do an online
; score system, I should record whether a score was gotten at 50Hz vs 60Hz.
; (and in fact, I have since implemented online high scores and record the
; frequency at which the game was played)
lda >VERTICAL_COUNTER ; load the counter value
and #$80ff ; mask out the VBL bits
asl a ; shift the word around
adc #0 ; move MSB -> LSB
lcla &scanLineNum
&scanLineNum seta &rowNum
&scanLineNum seta &scanLineNum*8
&scanLineNum seta &scanLineNum+264
cmp #&scanLineNum
blt _drawDirtyGameRow_wait&rowNum
lcla &tileOffset
&tileOffset seta &rowNum*50
lcla &lastTileOffset
&lastTileOffset seta 50+&tileOffset
.drawDirtyGameRowLoop
lda tileDirty+&tileOffset
beq _drawDirtyGameRow_skip&tileOffset
stz tileDirty+&tileOffset
ldy tileScreenOffset+&tileOffset
lda tileType+&tileOffset
jsl drawTile
_drawDirtyGameRow_skip&tileOffset anop
&tileOffset seta &tileOffset+2
aif &tileOffset<&lastTileOffset,.drawDirtyGameRowLoop
mend
macro
_dirtyGameOrNonGameTile &tileOffset
ldx &tileOffset
cpx #RHS_FIRST_TILE_OFFSET
bge _dirtyGameTile_nonGame&SYSCNT
lda #TILE_STATE_DIRTY
sta tileDirty,x
bra _dirtyGameTile_skip&SYSCNT
_dirtyGameTile_nonGame&SYSCNT anop
lda tileDirty,x
bne _dirtyGameTile_skip&SYSCNT
lda #TILE_STATE_DIRTY
sta tileDirty,x
ldy numDirtyNonGameTiles
txa
sta dirtyNonGameTiles,y
iny
iny
sty numDirtyNonGameTiles
_dirtyGameTile_skip&SYSCNT anop
mend
macro
_dirtyGameOrNonGameTileX &tileOffset
ldy &tileOffset,x
cpy #RHS_FIRST_TILE_OFFSET
bge _dirtyGameTile_nonGame&SYSCNT
lda #TILE_STATE_DIRTY
sta tileDirty,y
bra _dirtyGameTile_skip&SYSCNT
_dirtyGameTile_nonGame&SYSCNT anop
lda tileDirty,y
bne _dirtyGameTile_skip&SYSCNT
lda #TILE_STATE_DIRTY
sta tileDirty,y
tya
ldy numDirtyNonGameTiles
sta dirtyNonGameTiles,y
iny
iny
sty numDirtyNonGameTiles
_dirtyGameTile_skip&SYSCNT anop
mend
; Pass the tile offset to mark as dirty in the X register
macro
_dirtyNonGameTile
lda tileDirty,x
bne _dirtyNonGameTile_skip&SYSCNT
lda #TILE_STATE_DIRTY
sta tileDirty,x
ldy numDirtyNonGameTiles
txa
sta dirtyNonGameTiles,y
iny
iny
sty numDirtyNonGameTiles
_dirtyNonGameTile_skip&SYSCNT anop
mend
macro
_overwriteGameTile &type
lda #&type
jsl overwriteGameTile
mend
macro
_setGameTile &type
lda #&type
jsl setGameTile
mend
macro
_highScoreRow &nthScore
ldy #SETTINGS_HIGH_SCORE_OFFSET+HIGH_SCORE_SCORE_TEXT_OFFSET+&nthScore*SETTINGS_HIGH_SCORE_SIZE
lda settings,y
jsl asciiToTileType
jsl setGameTile
iny
lda settings,y
jsl asciiToTileType
jsl setGameTile
iny
lda settings,y
jsl asciiToTileType
jsl setGameTile
iny
lda settings,y
jsl asciiToTileType
jsl setGameTile
iny
lda settings,y
jsl asciiToTileType
jsl setGameTile
iny
lda settings,y
jsl asciiToTileType
jsl setGameTile
iny
lda settings,y
jsl asciiToTileType
jsl setGameTile
iny
lda settings,y
jsl asciiToTileType
jsl setGameTile
iny
lda settings,y
jsl asciiToTileType
jsl setGameTile
iny
lda settings,y
jsl asciiToTileType
jsl setGameTile
lda #TILE_EMPTY
jsl setGameTile
iny
lda settings,y
jsl asciiToTileType
jsl setGameTile
iny
lda settings,y
jsl asciiToTileType
jsl setGameTile
iny
lda settings,y
jsl asciiToTileType
jsl setGameTile
mend
macro
_globalHighScoreRow &nthScore
ldy #2+&nthScore*SETTINGS_HIGH_SCORE_SIZE
lda highScoreResponse,y
jsl asciiToTileType
jsl setGameTile
iny
lda highScoreResponse,y
jsl asciiToTileType
jsl setGameTile
iny
lda highScoreResponse,y
jsl asciiToTileType
jsl setGameTile
iny
lda highScoreResponse,y
jsl asciiToTileType
jsl setGameTile
iny
lda highScoreResponse,y
jsl asciiToTileType
jsl setGameTile
iny
lda highScoreResponse,y
jsl asciiToTileType
jsl setGameTile
iny
lda highScoreResponse,y
jsl asciiToTileType
jsl setGameTile
iny
lda highScoreResponse,y
jsl asciiToTileType
jsl setGameTile
iny
lda highScoreResponse,y
jsl asciiToTileType
jsl setGameTile
iny
lda highScoreResponse,y
jsl asciiToTileType
jsl setGameTile
lda #TILE_EMPTY
jsl setGameTile
iny
lda highScoreResponse,y
jsl asciiToTileType
jsl setGameTile
iny
lda highScoreResponse,y
jsl asciiToTileType
jsl setGameTile
iny
lda highScoreResponse,y
jsl asciiToTileType
jsl setGameTile
mend
; Update the score
macro
_incrementScore &increment
lda playerNum
asl a
tax
lda #&increment
clc
adc gameScore,x
sta gameScore,x
bcc _incrementScore_noCarry&SYSCNT
inc gameScore+2,x
_incrementScore_noCarry&SYSCNT anop
ldx playerNum
lda #&increment
clc
adc scoreWithin12000,x
cmp #12000
blt _incrementScore_noExtraMan&SYSCNT
sec
sbc #12000
pha
jsl playerAddLife
pla
ldx playerNum
_incrementScore_noExtraMan&SYSCNT anop
sta scoreWithin12000,x
lda #&increment
clc
adc scoreWithin20000,x
cmp #20000
blt _incrementScore_no2000&SYSCNT
sec
sbc #20000
inc scoreNum20000,x
_incrementScore_no2000&SYSCNT anop
sta scoreWithin20000,x
mend
; Wait for the DOC to be ready
macro
_docWait
_docWait_&SYSCNT anop
lda >SOUND_CONTROL_REG
bmi _docWait_&SYSCNT
mend
macro
_writeReg &reg,&value
ldy &reg
lda &value
jsr writeReg
mend