;
;  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.  TODO - 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.
        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
        jsr overwriteGameTile
        mend
        
        
        macro
        _setGameTile &type
        lda #&type
        jsr 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
        jsr setGameTile
        
        iny
        lda settings,y
        jsl asciiToTileType
        jsr setGameTile

        iny
        lda settings,y
        jsl asciiToTileType
        jsr setGameTile

        iny
        lda settings,y
        jsl asciiToTileType
        jsr setGameTile

        iny
        lda settings,y
        jsl asciiToTileType
        jsr setGameTile

        iny
        lda settings,y
        jsl asciiToTileType
        jsr setGameTile

        iny
        lda settings,y
        jsl asciiToTileType
        jsr setGameTile

        iny
        lda settings,y
        jsl asciiToTileType
        jsr setGameTile

        iny
        lda settings,y
        jsl asciiToTileType
        jsr setGameTile

        iny
        lda settings,y
        jsl asciiToTileType
        jsr setGameTile

        lda #TILE_EMPTY
        jsr setGameTile

        iny
        lda settings,y
        jsl asciiToTileType
        jsr setGameTile

        iny
        lda settings,y
        jsl asciiToTileType
        jsr setGameTile

        iny
        lda settings,y
        jsl asciiToTileType
        jsr 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
