; screen variables already ddefined in screencardread ;DEF vPreviousCardIndex EQU VARIABLES_START ;def vBlocked equ vPreviousCardIndex + 1 ScreenCardBrowse: dw CardBrowseSetup dw CardBrowseUpdate dw CardBrowseDraw dw CardBrowseTeardown CardBrowseSetup: ld a, 1 ldh [vBlocked], a 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, CardBrowse.UITilemap ; origin ld de, $9800 ; destination ld b, 18 ; height ld c, 20 ; width ld a, LOW(CopyTilesToMapThreadsafe) ld [vAsyncNext], a ld a, HIGH(CopyTilesToMapThreadsafe) ld [vAsyncNext+1], a ld a, LOW(CardBrowse.LoadCardDataAsync) ld [vAsyncAfter], a ld a, HIGH(CardBrowse.LoadCardDataAsync) ld [vAsyncAfter+1], a ret CardBrowseUpdate: 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 ld hl, rMYBTNP bit 4, [hl] jp z, .doneWithB ld hl, ScreenMainMenu call ChangeScene ret .doneWithB ldh a, [vSelectedCardIndex] ld hl, rMYBTNP bit 3, [hl] jp z, :+ ; skip the following code if down is not pressed inc a : bit 2, [hl] jp z, :+ ; skip the following code if up is not pressed dec a : ldh [vSelectedCardIndex], a ld hl, Cards call ArrayClampLooping ldh [vSelectedCardIndex], a ldh a, [vSelectedCardIndex] ld hl, vPreviousCardIndex cp a, [hl] ret z ; if the selected card diddn't change, nothing to do ldh a, [vBlocked] cp a, 0 ret nz ld a, LOW(CardBrowse.LoadCardDataAsync) ld [vAsyncAfter], a ld a, HIGH(CardBrowse.LoadCardDataAsync) ld [vAsyncAfter+1], a call DoInAsyncVBlank ret CardBrowseDraw: ld hl, SquaresTiles inc hl 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+$100*16 + 1*16 ld bc, (SquaresTileset8 - SquaresTileset7) / 8 call CopyRangeUnsafeBy8s ; the card data is loaded asynchronously, initiated in CardReadUpdate ret CardBrowseTeardown: ret CardBrowse.LoadCardDataAsync: ; to be called as async ei ld a, 1 ldh [vBlocked], a ldh a, [vSelectedCardIndex] ldh [vPreviousCardIndex], a ld b, 0 ld c, a ; load bc from a, the number of the card in the cards list ld hl, Cards + 1 ; skip the length prefix add hl, bc add hl, bc ; add this twice to double the offset because it's two bytes per address ; follow the pointer we're looking at ld a, [hl+] ld c, a ld a, [hl+] ld b, a ld h, b ld l, c ; hl now contains the address of the card data. ld a, LOW(.duringDraw) ld [vAsyncNext], a ld a, HIGH(.duringDraw) ld [vAsyncNext+1], a ld a, 0 ld [vAsyncAfter], a ld [vAsyncAfter+1], a di nop nop ret .duringDraw di ; these function calls should be fast so we'll disable interrupts and do them ; synchronously ; hl points to a card struct. ; card struct starts with a sequence of length-prefixed strings in memory ; so when we're done writing one, hl will be correctly placed to read the next ; length-prefixed print doesn't require passing a length ; so all we have to set is the destination for each ld de, $9800 + 32*11 + 10 call PrintString ld de, $9800 + 32*12 + 10 call PrintString ld de, $9800 + 32*14 + 10 call PrintString ld de, $9800 + 32*15 + 10 call PrintString ld de, $9800 + 32*16 + 10 call PrintString ei ; hl now contains the address after all the strings. ; [hl+] and [hl+] read the length first, into bc ld a, [hl+] ld c, a ld a, [hl+] ld b, a ; bc has length ld a, [hl+] ld e, a ld a, [hl+] ld d, a ; de has source of tile range copy ld h, d ld l, e ; source ld de, $9800 + 32 + 1 ; destination ld b, 16 ; height ld c, 8 ; width ld a, LOW(CopyTilesToMapThreadsafe) ld [vAsyncNext], a ld a, HIGH(CopyTilesToMapThreadsafe) ld [vAsyncNext+1], a ld a, LOW(.afterCopyTiles) ld [vAsyncAfter], a ld a, HIGH(.afterCopyTiles) ld [vAsyncAfter+1], a di nop nop ret .afterCopyTiles ei ldh a, [vSelectedCardIndex] ldh [vPreviousCardIndex], a ld b, 0 ld c, a ; load bc from a, the number of the card in the cards list ld hl, Cards + 1 ; skip the length prefix add hl, bc add hl, bc ; add this twice to double the offset because it's two bytes per address ; follow the pointer we're looking at ld a, [hl+] ld c, a ld a, [hl+] ld b, a ld h, b ld l, c ; hl now contains the address of the card data. di call PassList call PassList call PassList call PassList call PassList ; skip the strings ei inc hl inc hl ; skip tile map width inc hl inc hl ; skip tile map pointer ld a, [hl+] ld c, a ld a, [hl+] ld b, a ; bc has length of tile data ld a, [hl+] ld e, a ld a, [hl+] ld d, a ; de has source of tile range copy ld h, d ld l, e ; hl takes the source ld de, $91b0 ; always load tile data into the same spot in vram ld a, LOW(CopyRangeUnsafe) ld [vAsyncNext], a ld a, HIGH(CopyRangeUnsafe) ld [vAsyncNext+1], a ld a, LOW(.afterLoadingTiles) ld [vAsyncAfter], a ld a, HIGH(.afterLoadingTiles) ld [vAsyncAfter+1], a di nop nop ret .afterLoadingTiles ei ld a, 0 ldh [vBlocked], a ld a, 0 ld [vAsyncNext], a ld [vAsyncNext+1], a ld [vAsyncAfter], a ld [vAsyncAfter+1], a di nop nop ret CardBrowse.UITilemap: db $0e, $0a, $0a, $0a, $0a, $0a, $0a, $0a, $0a, $0f, $09, $02, $02, $02, $02, $02, $02, $02, $08, $01 db $0b, $00, $00, $00, $00, $00, $00, $00, $00, $0c, $03, $00, $00, $00, $00, $00, $00, $00, $04, $01 db $0b, $00, $00, $00, $00, $00, $00, $00, $00, $0c, $03, $00, $00, $00, $00, $00, $00, $00, $04, $01 db $0b, $00, $00, $00, $00, $00, $00, $00, $00, $0c, $03, $00, $00, $00, $00, $00, $00, $00, $04, $01 db $0b, $00, $00, $00, $00, $00, $00, $00, $00, $0c, $03, $00, $00, $00, $00, $00, $00, $00, $04, $01 db $0b, $00, $00, $00, $00, $00, $00, $00, $00, $0c, $03, $00, $00, $00, $00, $00, $00, $00, $04, $01 db $0b, $00, $00, $00, $00, $00, $00, $00, $00, $0c, $03, $00, $00, $00, $00, $00, $00, $00, $04, $01 db $0b, $00, $00, $00, $00, $00, $00, $00, $00, $0c, $06, $05, $05, $05, $05, $05, $05, $05, $07, $01 db $0b, $00, $00, $00, $00, $00, $00, $00, $00, $0c, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01 db $0b, $00, $00, $00, $00, $00, $00, $00, $00, $0c, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01 db $0b, $00, $00, $00, $00, $00, $00, $00, $00, $0c, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02 db $0b, $00, $00, $00, $00, $00, $00, $00, $00, $0c, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 db $0b, $00, $00, $00, $00, $00, $00, $00, $00, $0c, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 db $0b, $00, $00, $00, $00, $00, $00, $00, $00, $0c, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 db $0b, $00, $00, $00, $00, $00, $00, $00, $00, $0c, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 db $0b, $00, $00, $00, $00, $00, $00, $00, $00, $0c, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 db $0b, $00, $00, $00, $00, $00, $00, $00, $00, $0c, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 db $11, $0d, $0d, $0d, $0d, $0d, $0d, $0d, $0d, $10, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 CardBrowse.UITilemapEnd: