gb-tarot/ScreenSpreadSelect.inc

691 lines
15 KiB
PHP

DEF vPreviousSpreadIndex EQU VARIABLES_START
def vPreviousSpreadCard equ vPreviousSpreadIndex + 1
ScreenSpreadSelect:
dw SpreadSelectSetup
dw SpreadSelectUpdate
dw SpreadSelectDraw
dw SpreadSelectTeardown
SpreadSelectSetup:
ld a, 0
ldh [vPreviousSpreadIndex], a
ldh [vSelectedSpreadCard], a
ldh [vPreviousSpreadCard], a
call UpdateCurrentSpread
ld a, LOW(RunDMA) ; zero out the OAM
ld [vAsyncNext], a
ld a, HIGH(RunDMA)
ld [vAsyncNext+1], a
ld a, LOW(.loadUIMap)
ld [vAsyncAfter], a
ld a, HIGH(.loadUIMap)
ld [vAsyncAfter+1], a
ld a, HIGH(ZEROES)
ld de, $ffc0 ; arguments to the first async call.
call DoInAsyncVBlank
ret
.loadUIMap
ld hl, SpreadSelectTilemap
ld de, $9800
ld b, 18
ld c, 20
ld a, LOW(CopyTilesToMapThreadsafe)
ld [vAsyncNext], a
ld a, HIGH(CopyTilesToMapThreadsafe)
ld [vAsyncNext+1], a
ld a, LOW(.loadFaceCardTiles)
ld [vAsyncAfter], a
ld a, HIGH(.loadFaceCardTiles)
ld [vAsyncAfter+1], a
ret
.loadFaceCardTiles
ld hl, CardPartTiles
ld de, $9000 - ($10)*16
ld bc, CardPartTilesEnd - CardPartTiles
ld a, LOW(CopyRangeUnsafe)
ld [vAsyncNext], a
ld a, HIGH(CopyRangeUnsafe)
ld [vAsyncNext+1], a
ld a, LOW(DrawSpreadAsync)
ld [vAsyncAfter], a
ld a, HIGH(DrawSpreadAsync)
ld [vAsyncAfter+1], a
ret
SpreadSelectUpdate:
ld hl, rMYBTNP
bit 4, [hl]
jp z, .doneB
ld hl, ScreenMainMenu
call ChangeScene
ret
.doneB
bit 5, [hl]
jp z, .doneA
ld hl, ScreenCardRead
call ChangeScene
ret
.doneA
;up and down
ld a, [vSelectedSpreadIndex]
bit 3, [hl] ; select the down key
jp z, .doneDown ; skip the following code if down is not pressed
inc a ; increment when they press down
.doneDown
bit 2, [hl] ; select up key
jp z, .doneUp ; skip the following code if up is not pressed
dec a ; decrement when they press up because the deck has card 0 at the top
.doneUp
ld hl, Spreads
call ArrayClampLooping
ldh [vSelectedSpreadIndex], a ; save clamped index
; left and righgt
ldh a, [vSelectedSpreadCard]
ld hl, rMYBTNP
bit 1, [hl]
jp z, .doneLeft ; skip the following code if left is not pressed
dec a
.doneLeft
bit 0, [hl]
jp z, .doneRight ; skip the following code if right is not pressed
inc a
.doneRight
ld hl, vCurrentSpread
ld c, [hl]
inc hl
ld b, [hl]
ld h, b
ld l, c
; hl has current spread, a has index
call ArrayClampLooping
ldh [vSelectedSpreadCard], a
ld hl, vTime
ldh a, [rDELTAT]
ld b, a
ldh a, [vTime]
add a, b
ldh [vTime], a
ldh a, [vTime+1]
adc a, 0
ldh [vTime+1], a ; increment time. when the 16bit time register is greater
; than 4096 ($10_00) then one second has passed. so that's satisfied when
; vTime+1 is equal to or greater than $10
ldh a, [vTime+1]
cp a, $01
jp c, .doneTimer ; if the timer is less than $0100, skip to end
;otherwise reset the timer
ld a, 0
ldh [vTime], a
ldh [vTime+1], a
ld hl, SquaresTiles
ldh a, [vFrameCountSquares]
inc a
call ArrayClampLooping
ldh [vFrameCountSquares], a
.doneTimer
ldh a, [vSelectedSpreadIndex]
ld hl, vPreviousSpreadIndex
cp a, [hl]
jp nz, .spreadChanged ; update the spread if the spread changed
ldh a, [vSelectedSpreadCard]
ld hl, vPreviousSpreadCard
cp a, [hl]
jp nz, .cardChanged ; update the spread if the card changed
ret
.spreadChanged
ld a, [vAsyncPC]
ld b, a
ld a, [vAsyncPC+1]
or a, b
ret nz ; early return if the async threadd is in use
ld a, [vSelectedSpreadIndex]
ld [vPreviousSpreadIndex], a
ld a, 0
ld [vSelectedSpreadCard], a
ld [vPreviousSpreadCard], a
call UpdateCurrentSpread
; execute an async call to DrawSpreadAsync.
ld a, LOW(DrawSpreadAsync)
ld [vAsyncNext], a
ld a, HIGH(DrawSpreadAsync)
ld [vAsyncNext+1], a
call DoInAsyncVBlank
ret
.cardChanged
ld a, [vAsyncPC]
ld b, a
ld a, [vAsyncPC+1]
or a, b
ret nz ; early return if the async threadd is in use
ld a, [vSelectedSpreadIndex]
ld [vPreviousSpreadIndex], a
ld a, [vSelectedSpreadCard]
ld [vPreviousSpreadCard], a
call UpdateCurrentSpread
; execute an async call to DrawSpreadAsync.
ld a, LOW(DrawSpreadALittleAsync)
ld [vAsyncNext], a
ld a, HIGH(DrawSpreadALittleAsync)
ld [vAsyncNext+1], a
call DoInAsyncVBlank
ret
UpdateCurrentSpread:
; find the correct spread address
ld hl, Spreads
inc hl ; skip length of spreads
ld a, [vSelectedSpreadIndex]
inc a ; we're decing at the start so we inc first to prepare...
ld d, 0
.findSpread
dec a
jp z, .spreadFound
ld e, [hl] ; skip cards in spread
inc hl
add hl, de
.skipCardDescription ; e has number of cards in spread
di
call PassList
call PassList ; one card description has two strings
dec e ; this will not work if the spreadd had zero cardss. i will overflow.
jp nz, .skipCardDescription
ei
ld e, [hl] ; skip title of spread
inc hl
add hl, de
ld e, [hl] ; skip description
inc hl
add hl, de
jp .findSpread
.spreadFound
ld a, l
ld [vCurrentSpread], a
ld a, h
ld [vCurrentSpread+1], a ; save the current spread (hl) into vcurrentspread.
ret
DrawSpreadAsync:
ldh a, [vSelectedSpreadIndex]
ldh [vPreviousSpreadIndex], a
ld de, $9800 + 32*5 + 3
ld hl, ONES
ld b, 8
ld c, 14
ld a, LOW(CopyTilesToMapThreadsafe)
ld [vAsyncNext], a
ld a, HIGH(CopyTilesToMapThreadsafe)
ld [vAsyncNext+1], a
ld a, LOW(.afterClear)
ld [vAsyncAfter], a
ld a, HIGH(.afterClear)
ld [vAsyncAfter+1], a
ret ; return from async execution now that we've registered desire
; to call copytilestomapthreadsafe
; and then drawspread
.afterClear
ld a, [vCurrentSpread]
ld l, a
ld a, [vCurrentSpread+1]
ld h, a
ld e, [hl] ; e holds length of spread
di
call PassList ; step past spread layout
ei
nop
nop
.PassCardPositionDescriptions
di
call PassList ; step past one pdesc
call PassList ; step past two pdesc
ei
dec e ; we've looked at one
jp nz, .PassCardPositionDescriptions
.foundSpreadTitle
ld de, $9800 + 32 + 1
ld a, LOW(PrintString)
ld [vAsyncNext], a
ld a, HIGH(PrintString)
ld [vAsyncNext+1], a
ld a, LOW(.afterTitle)
ld [vAsyncAfter], a
ld a, HIGH(.afterTitle)
ld [vAsyncAfter+1], a
ret
.afterTitle
ld de, $9800 + (32*2) + 1
ld a, LOW(PrintString)
ld [vAsyncNext], a
ld a, HIGH(PrintString)
ld [vAsyncNext+1], a
ld a, LOW(DrawSpreadALittleAsync)
ld [vAsyncAfter], a
ld a, HIGH(DrawSpreadALittleAsync)
ld [vAsyncAfter+1], a
ret
DrawSpreadALittleAsync:
ld hl, $9800 + 32*5 + 3
ldh a, [vSelectedSpreadCard]
ld d, 0
ld e, a ; e contains the selected index
ld a, LOW(DrawSpreadBigAndThreadsafe)
ld [vAsyncNext], a
ld a, HIGH(DrawSpreadBigAndThreadsafe)
ld [vAsyncNext+1], a
ld a, LOW(.drawSpreadPositionDescription)
ld [vAsyncAfter], a
ld a, HIGH(.drawSpreadPositionDescription)
ld [vAsyncAfter+1], a
ret
.drawSpreadPositionDescription
di
ld a, [vCurrentSpread]
ld l, a
ld a, [vCurrentSpread+1]
ld h, a ; hl points at beginning of card list
call PassList ; hl points at first card description
ld a, [vSelectedSpreadCard]
ld e, a
cp a, 0
jp z, .printIt
.stepForwardCardDescription
call PassList
call PassList
dec e
jp nz, .stepForwardCardDescription
.printIt
ei
nop
nop
.drawFirstDescription
ld de, $9800+32*15 + 6
ld a, LOW(PrintString)
ld [vAsyncNext], a
ld a, HIGH(PrintString)
ld [vAsyncNext+1], a
ld a, LOW(.drawSecondDescription)
ld [vAsyncAfter], a
ld a, HIGH(.drawSecondDescription)
ld [vAsyncAfter+1], a
ret
.drawSecondDescription
ld de, $9800+32*16 + 6
ld a, LOW(PrintString)
ld [vAsyncNext], a
ld a, HIGH(PrintString)
ld [vAsyncNext+1], a
ld a, 0
ld [vAsyncAfter], a
ld [vAsyncAfter+1], a
ret
SpreadSelectDraw:
di
ld hl, SquaresTiles + 1
ld b, 0
ldh a, [vFrameCountSquares]
ld c, a
add hl, bc
add hl, bc
ld c, [hl]
inc hl
ld b, [hl]
ld h, b
ld l, c
ld de, $8000 + $1000 + $10
ld a, [hl+]
ld [de], a
inc de
ld a, [hl+]
ld [de], a
inc de
ld a, [hl+]
ld [de], a
inc de
ld a, [hl+]
ld [de], a
inc de
ld a, [hl+]
ld [de], a
inc de
ld a, [hl+]
ld [de], a
inc de
ld a, [hl+]
ld [de], a
inc de
ld a, [hl+]
ld [de], a
inc de
ld a, [hl+]
ld [de], a
inc de
ld a, [hl+]
ld [de], a
inc de
ld a, [hl+]
ld [de], a
inc de
ld a, [hl+]
ld [de], a
inc de
ld a, [hl+]
ld [de], a
inc de
ld a, [hl+]
ld [de], a
inc de
ld a, [hl+]
ld [de], a
inc de
ld a, [hl+]
ld [de], a
reti
SpreadSelectTeardown:
ret
DrawSpreadBigAndThreadsafe:
; hl for location on screen
; current spread address in vCurrentSpread
; e for index of selected card
di
ld a, [vCurrentSpread]
ld c, a
ld a, [vCurrentSpread+1]
ld b, a
ld a, [bc]
cp a, 0 ; length of spread
jp z, .doneDrawingSpread ; return early if the spread is empty
ld d, a ; length of spread in d
inc d
.drawCards
ei
nop
nop
di
dec d
jp z, .doneWithSpread ; if we're drawing zero remaining cards, stop drawing
inc bc ; step forward
push hl ; need this bc drawsmallcard changes hl
ld a, [bc]
call DrawBigCard
pop hl
jp .drawCards
.doneWithSpread
; stack has spread address
; d is zero
; e should have currently selected index
ld b, h
ld c, l ; stash hl in bc for a mo; this should be a location in vram
ld a, [vCurrentSpread]
ld l, a
ld a, [vCurrentSpread+1]
ld h, a
;spread address in hl
inc hl ; skip the tiles length
ld d, 0
ld a, [vSelectedSpreadCard]
ld e, a
add hl, de
ld a, [hl] ; load card descriptor into a
ld h, b
ld l, c; retrieve vram address
ei
nop
di
nop
nop
call DrawBigCardSelected
.doneDrawingSpread
ei
nop
nop
ret
DrawBigCard: ; starting from screen location hl, draw a card at
;the location described in a
; saves de and is therefore not threadsafe
push de
ld d, a
swap a
and a, %0000_1111
sla a
ld e, a
ld a, d
and a, %0000_1111
ld d, 0
add hl, de ; step right
ld e, 64
jp z, .drawCard
.stepDown
add hl, de ; step down
dec a
jp nz, .stepDown
.drawCard
ld de, 32
ld [hl], -16 + $1
inc hl
ld [hl], -16 + $2
add hl, de
ld [hl], -16 + $4
dec hl
ld [hl], -16 + $3
add hl, de
ld [hl], -16 + $3
inc hl
ld [hl], -16 + $4
add hl, de
ld [hl], -16 + $6
dec hl
ld [hl], -16 + $5
pop de
ret
DrawBigCardSelected: ; starting from screen location hl, draw a card at
;the location described in a
push de
push af
swap a
ld d, 0
and a, %0000_1111
sla a
ld e, a
add hl, de ; step right
ld e, 64
pop af
and a, %0000_1111
jp z, .drawCard
.stepDown
add hl, de ; step down
dec a
jp nz, .stepDown
.drawCard
ld de, 32
ld [hl], -16 + $7
inc hl
ld [hl], -16 + $8
add hl, de
ld [hl], -16 + $a
dec hl
ld [hl], -16 + $9
add hl, de
ld [hl], -16 + $b
inc hl
ld [hl], -16 + $c
add hl, de
ld [hl], -16 + $e
dec hl
ld [hl], -16 + $d
pop de
ret
DrawSpreadMinimap:
; hl for location on screen
; bc for current spread address
; a for index of selected card
push af
push bc
ld a, [bc]
ld d, 0
ld e, a ; length of spread in de
.drawCards
ld a, e
cp a, 0
jp z, .doneWithSpread ; if we're drawing zero remaining cards, stop drawing
dec e
inc bc ; step forward
push hl ; need this bc drawsmallcard changes hl
push bc
ld a, [bc]
ld bc, $1817
call DrawSmallCard
pop bc
pop hl
jp .drawCards
.doneWithSpread ; stack has hl, bc, af at the time of jumping here
pop bc ; stack: af
pop af
ld d, 0
ld e, a ; index of selected card in spread
inc e ; skip the length
push hl ; stack: hl
ld h, b
ld l, c ; put bc in hl temporarily so we can add to hl
add hl, de
ld a, [hl]
pop hl ; stack: empty
ld bc, $1a19
call DrawSmallCard
ret
DrawSmallCard: ; starting from screen location hl, draw a card at
;the location described in a, top and bottom sprite in b and c
push de
push af
swap a
ld d, 0
and a, %0000_1111
ld e, a
add hl, de ; step right
ld e, 32
pop af
and a, %0000_1111
jp z, .drawCard
:
dec a
add hl, de ; step down
cp a, 0
jp nz, :-
.drawCard
ld [hl], b
add hl, de
ld [hl], c
pop de
ret
CardPartTiles:
db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
db $00,$ff,$7f,$ff,$7f,$ff,$60,$ff,$6f,$ff,$6d,$fa,$6a,$fd,$6d,$fa
db $00,$ff,$fe,$ff,$fe,$ff,$06,$ff,$f6,$ff,$56,$bf,$b6,$5f,$56,$bf
db $6a,$fd,$6d,$fa,$6a,$fd,$6d,$fa,$6a,$fd,$6d,$fa,$6a,$fd,$6d,$fa
db $b6,$5f,$56,$bf,$b6,$5f,$56,$bf,$b6,$5f,$56,$bf,$b6,$5f,$56,$bf
db $6a,$fd,$6d,$fa,$6a,$fd,$6f,$ff,$60,$ff,$7f,$ff,$7f,$ff,$00,$ff
db $b6,$5f,$56,$bf,$b6,$5f,$f6,$ff,$06,$ff,$fe,$ff,$fe,$ff,$00,$ff
db $ff,$00,$80,$7f,$80,$7f,$9f,$7f,$9f,$7f,$98,$78,$99,$79,$9a,$7a
db $ff,$00,$01,$fe,$01,$fe,$f9,$fe,$f9,$fe,$19,$1e,$19,$1e,$d9,$de
db $9a,$7a,$99,$79,$98,$78,$9c,$78,$99,$78,$9b,$79,$9b,$7a,$9b,$7a
db $d9,$de,$99,$9e,$d9,$de,$f9,$de,$99,$9e,$d9,$9e,$d9,$9e,$d9,$5e
db $98,$78,$98,$7b,$99,$7a,$9a,$7c,$9f,$7b,$99,$79,$99,$79,$98,$78
db $59,$5e,$19,$fe,$f9,$1e,$19,$1e,$d9,$de,$d9,$de,$59,$5e,$19,$1e
db $98,$79,$98,$79,$98,$78,$9f,$7f,$9f,$7f,$80,$7f,$80,$7f,$ff,$00
db $19,$9e,$19,$9e,$19,$1e,$f9,$fe,$f9,$fe,$01,$fe,$01,$fe,$ff,$00
CardPartTilesEnd:
SpreadSelectTilemap:
db $09, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $08
db $03, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $04
db $03, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $04
db $06, $05, $05, $05, $05, $05, $05, $05, $05, $05, $05, $05, $05, $05, $05, $05, $05, $05, $05, $07
db $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01
db $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01
db $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01
db $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01
db $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01
db $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01
db $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01
db $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01
db $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01
db $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01
db $01, $01, $01, $01, $01, $09, $02, $02, $02, $02, $02, $02, $02, $02, $08, $01, $01, $01, $01, $01
db $01, $01, $01, $01, $01, $03, $00, $00, $00, $00, $00, $00, $00, $00, $04, $01, $01, $01, $01, $01
db $01, $01, $01, $01, $01, $03, $00, $00, $00, $00, $00, $00, $00, $00, $04, $01, $01, $01, $01, $01
db $01, $01, $01, $01, $01, $06, $05, $05, $05, $05, $05, $05, $05, $05, $07, $01, $01, $01, $01, $01
SpreadSelectTilemapEnd: