DEF vSelectedSpreadIndex EQU VARIABLES_START DEF vPreviousSpreadIndex EQU vSelectedSpreadIndex + 1 def vSelectedSpreadCard equ vPreviousSpreadIndex + 1 ScreenSpreadSelect: dw SpreadSelectSetup dw SpreadSelectUpdate dw SpreadSelectDraw dw SpreadSelectTeardown SpreadSelectSetup: ld a, 0 ldh [vSelectedCardInSpread], a ldh [vPreviousSpreadIndex], a ldh [vSelectedSpreadIndex], a ld hl, ZEROES 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(.loadUITiles) ld [vAsyncAfter], a ld a, HIGH(.loadUITiles) ld [vAsyncAfter+1], a call DoInAsyncVBlank ld a, HIGH(ZEROES) ld de, $ffc0 call RunDMA ret .loadUITiles ld hl, UITiles ; source ld de, $8000 + $80*16; destination of copy ld bc, UITilesEnd - UITiles ; length to copy 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 ld a, [vSelectedSpreadIndex] bit 3, [hl] ; select the down key jp z, .doneDown ; skip the following code if down is not pressed dec a ; increment when they press down because the deck has card 0 at the top .doneDown bit 2, [hl] ; select up key jp z, .doneUp ; skip the following code if up is not pressed inc a ; decrement when they press up because the deck has card 0 at the top .doneUp ld hl, Spreads call ArrayClampLooping ldh [vSelectedSpreadIndex], a ; load current selected tile index ld hl, vPreviousSpreadIndex cp a, [hl] ret z ; we're done if previous index is same as new index ; execute an async call to DrawSpreadAsync. ld a, LOW(DrawSpreadAsync) ld [vAsyncNext], a ld a, HIGH(DrawSpreadAsync) ld [vAsyncNext+1], a call DoInAsyncVBlank ret ; return from main thread. go back to looping. DrawSpreadAsync: ldh a, [vSelectedSpreadIndex] ldh [vPreviousSpreadIndex], a ; 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 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. ld de, $9800 + 32*4 + 3 ld hl, ZEROES ld b, 8 ld c, 10 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 d, 0 ld e, [hl] inc e add hl, de ld de, $9800 + 32 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) ld a, LOW(PrintString) ld [vAsyncNext], a ld a, HIGH(PrintString) ld [vAsyncNext+1], a ld a, LOW(.afterDescription) ld [vAsyncAfter], a ld a, HIGH(.afterDescription) ld [vAsyncAfter+1], a ret .afterDescription ld hl, $9800 + 32*4 + 3 ldh a, [vSelectedSpreadCard] 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(.finishAsyncUpdate) ld [vAsyncAfter], a ld a, HIGH(.finishAsyncUpdate) ld [vAsyncAfter+1], a ret .finishAsyncUpdate ; signal that we're done with execution of the async thread ld a, 0 ld [vAsyncNext], a ld [vAsyncNext+1], a ld [vAsyncAfter], a ld [vAsyncAfter+1], a ret SpreadSelectDraw: ret SpreadSelectTeardown: ret DrawSpreadBigAndThreadsafe: ; hl for location on screen ; bc for current spread address ; actually holding that 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 ret z ; return early if the spread is empty ld d, a ; length of spread in d inc d .drawCards ei 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 e ; skip the tiles length add hl, de ld a, [hl] ; load card descriptor into a ld h, b ld l, c; retrieve vram address ei nop di call DrawBigCardSelected ei ret DrawSpreadBig: ; hl for location on screen ; bc for current spread address ; e for index of selected card ld a, [bc] cp a, 0 ; length of spread ret z ; return early if the spread is empty push bc ld d, a ; length of spread in d inc d .drawCards 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 pop hl ; put bc from stack into hl, this is the spread address inc e ; skip the tiles length add hl, de ld a, [hl] ld h, b ld l, c; retrieve ;call DrawBigCardSelected 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], $12 inc hl ld [hl], $1e add hl, de ld [hl], $1f dec hl ld [hl], $13 add hl, de ld [hl], $13 inc hl ld [hl], $1f add hl, de ld [hl], $23 dec hl ld [hl], $17 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], $12 inc hl ld [hl], $1e add hl, de ld [hl], $1f dec hl ld [hl], $13 add hl, de ld [hl], $13 inc hl ld [hl], $1f add hl, de ld [hl], $23 dec hl ld [hl], $17 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, $8384 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, $8586 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