From 971827783426da8a4c4bbcdc6782f17909e98f2e Mon Sep 17 00:00:00 2001 From: shoofle Date: Thu, 23 Jan 2025 13:16:55 -0500 Subject: [PATCH] shuffle functionality working! --- Async.inc | 5 +- Random.inc | 131 ++++++++++++++ ScreenCardBrowse.inc | 57 +++++- ScreenCardRead.inc | 71 ++------ ScreenMainMenu.inc | 146 +++++++++++++-- ScreenShuffle.inc | 395 +++++++++++++++++++++++++++++++++++++++++ ScreenSpreadSelect.inc | 4 +- judgement.aseprite | Bin 0 -> 5502 bytes justice.aseprite | Bin 5992 -> 6039 bytes main.asm | 59 ++++-- screendesigns.aseprite | Bin 4954 -> 4947 bytes source.zip | Bin 203924 -> 216299 bytes thedevil.aseprite | Bin 0 -> 5697 bytes themoon.aseprite | Bin 0 -> 5550 bytes thestar.aseprite | Bin 0 -> 5209 bytes thesun.aseprite | Bin 0 -> 5908 bytes thetower.aseprite | Bin 0 -> 5825 bytes theworld.aseprite | Bin 0 -> 5746 bytes tileset.asm | 45 +++-- 19 files changed, 793 insertions(+), 120 deletions(-) create mode 100644 Random.inc create mode 100644 ScreenShuffle.inc create mode 100644 judgement.aseprite create mode 100644 thedevil.aseprite create mode 100644 themoon.aseprite create mode 100644 thestar.aseprite create mode 100644 thesun.aseprite create mode 100644 thetower.aseprite create mode 100644 theworld.aseprite diff --git a/Async.inc b/Async.inc index f434c4f..12c84a6 100644 --- a/Async.inc +++ b/Async.inc @@ -1,3 +1,4 @@ +; async variables from ff80-ff8f! def vAsyncAF equ $ff80 def vAsyncHL EQU $ff82 def vAsyncDE EQU $ff84 @@ -8,7 +9,7 @@ def vAsyncAfter equ $ff8c def vAsyncProgress equ $ff8e def SAFE_ASYNC_START EQU 146 -def SAFE_ASYNC_END EQU 153 +def SAFE_ASYNC_END EQU 152 DoInAsyncVBlank: di @@ -133,7 +134,7 @@ DoInAsyncVBlank_EnterThread: DoInAsyncVBlank_EarlyReturn: ; stack: ; af, de, bc, hl, PC (smc int @ LYC90), PC (hw int @ LYC 90), PC (outer context) - PRINTln "early return handle is ", DoInAsyncVBlank_EarlyReturn + ;PRINTln "early return handle is ", DoInAsyncVBlank_EarlyReturn ; save state of registers di push af diff --git a/Random.inc b/Random.inc new file mode 100644 index 0000000..4edfdc3 --- /dev/null +++ b/Random.inc @@ -0,0 +1,131 @@ +ClockLFSR: ; uses af, bc and clocks one bit of the LFSR. +; at return time, a holds the bottom eight of lfsr state. + ldh a, [rLFSR] ; + ld b, a ; b has shifted value ; 1 cycle + + srl b ; second tap is two shifts ; 2 cycles + srl b ; 2 cycles + xor a, b ; 1 cycle + + srl b ; third tap iis one more shift ; 2 cycles + xor a, b ; 1 cycle + + srl b ; fourth tap is two more shifts ; 2 cycles + srl b ; 2 cycles + xor a, b ; 1 cycle + + and a, $1 ; now the zero flag is set iff the tap bit is 0 ; 1 cycle + + ; set carry flag from zero flag + scf ; 1 cycle + jr nz, .noComplementCarry ; 2 or 3 cycles + ccf ; 1 cycle if prev was 2 cycles :) +.noComplementCarry + ldh a, [rLFSR+1] ; 2 cycles + rra ; 1 cycle ; this should populate with the carry flag + ldh [rLFSR+1], a ; 2 cycles + ldh a, [rLFSR] ; 2 cycles + rra ; 1 cycle + ldh [rLFSR], a ; 2 cycles + ret ; 37 cycles total. can call roughly three of these per scanline + +OneRandomByte: ; clocks LFSR 8 times so a is + call ClockLFSR + call ClockLFSR + call ClockLFSR + call ClockLFSR + call ClockLFSR + call ClockLFSR + call ClockLFSR + call ClockLFSR + ret + +RandomUnderD: ; takes d as limit (inclusive) + ; check what the highest bit of d is and dispatch to thee number of bits + ; we're going to generate + ld d, a + + ld e, %1111_1111 + bit 7, d + jr nz, .inEight + + ld e, %0111_1111 + bit 6, d + jr nz, .inSeven + + ld e, %0011_1111 + bit 5, d + jr nz, .inSix + + ld e, %0001_1111 + bit 4, d + jr nz, .inFive + + ld e, %0000_1111 + bit 3, d + jr nz, .inFour + + ld e, %0000_0111 + bit 2, d + jr nz, .inThree + + ld e, %0000_0011 + bit 1, d + jr nz, .inTwo + + ld e, %0000_0001 + bit 0, d + jr nz, .inOne + + ld a, 0 + ret + +.inEight + call ClockLFSR +.inSeven + call ClockLFSR +.inSix + call ClockLFSR +.inFive + call ClockLFSR +.inFour + call ClockLFSR +.inThree + call ClockLFSR +.inTwo + call ClockLFSR +.inOne + call ClockLFSR + and a, e + cp a, d + ret z + ret c + jr .inOne + + +SwapCards: ; takes hl as array, c and e as indices to swap (uses b and d) + inc hl ; first element of array + push hl ; save it for later + ld b, 0 + ld d, 0 + add hl, bc + ld a, [hl] + ld b, a ; stash old [hl+0c] in b + pop hl + push hl + add hl, de + ld a, [hl] + ld d, a ; stash old [hl+0e] in d + ld [hl], b ; put old [hl+0c] in [hl+0e] + pop hl + ld b, 0 ; return 0 to b + add hl, bc + ld [hl], d ; put old [hl+0e] in [hl+0c] + ret + + + + + + + \ No newline at end of file diff --git a/ScreenCardBrowse.inc b/ScreenCardBrowse.inc index d966a70..3c4fbd9 100644 --- a/ScreenCardBrowse.inc +++ b/ScreenCardBrowse.inc @@ -116,6 +116,8 @@ CardBrowseUpdate: ret CardBrowseDraw: + ; the card data is loaded asynchronously, initiated in CardReadUpdate + ld hl, SquaresTiles inc hl ld b, 0 @@ -132,9 +134,54 @@ CardBrowseDraw: ld bc, (SquaresTileset8 - SquaresTileset7) / 8 call CopyRangeUnsafeBy8s - ; the card data is loaded asynchronously, initiated in CardReadUpdate + call DrawDeckMinimap ret +DrawDeckMinimap: + ld hl, Cards + ld c, [hl] ; count of cards + srl c + set 0, c + + ld hl, vSelectedCardIndex + ld d, [hl] ; selected card! + ld b, $ff ; start at -1 lol + ld hl, $9800 + 32 + 11 + +.loop + inc b + ld a, b + cp a, 2 + jp nz, .noNewLine + ld [hl], $13 + ld hl, $9800 + 32*2 + 11 +.noNewLine + ld a, b + cp a, c + jp nc, .doneDrawing + ld a, d + srl a + cp a, b + jp z, .drawSelectedCard +.drawUnselectedCards + ld [hl], $12 + inc hl + jp .loop +.drawSelectedCard + bit 0, d + jp nz, .drawSelectedSecond + ld [hl], $14 + inc hl + jp .loop +.drawSelectedSecond + ld [hl], $15 + inc hl + jp .loop +.doneDrawing + ld [hl], $13 + ret + + CardBrowseTeardown: ret @@ -298,13 +345,13 @@ 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, $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, $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 diff --git a/ScreenCardRead.inc b/ScreenCardRead.inc index 8449b8b..7a207d5 100644 --- a/ScreenCardRead.inc +++ b/ScreenCardRead.inc @@ -164,7 +164,12 @@ LoadCardDataAsync: ldh [vPreviousCardIndex], a ld b, 0 - ld c, a ; load bc from a, the number of the card in the cards list + ld c, a ; load bc from a, the number of the card in the shuffled deck + ld hl, SHUFFLED_DECK + 1 + add hl, bc + ld a, [hl] ; this now holds the index into the ROM cards array + + ld c, a ; loadd bc from a, the number of the card in the ROM deck 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 @@ -243,6 +248,12 @@ LoadCardDataAsync: .afterCopyTiles ldh a, [vSelectedCardIndex] ldh [vPreviousCardIndex], a + + ld b, 0 + ld c, a ; load bc from a, the number of the card in the shuffled deck + ld hl, SHUFFLED_DECK + 1 + add hl, bc + ld a, [hl] ; this now holds the index into the ROM cards array ld b, 0 ld c, a ; load bc from a, the number of the card in the cards list @@ -281,7 +292,7 @@ LoadCardDataAsync: ld h, d ld l, e ; hl takes the source - ld de, $91b0 ; always load tile data into the same spot in vram + ld de, $9000 + VARIABLE_TILES_START*$10 ; always load tile data into the same spot in vram ld a, LOW(CopyRangeUnsafe) ld [vAsyncNext], a ld a, HIGH(CopyRangeUnsafe) @@ -310,61 +321,6 @@ LoadCardDataAsync: ret - -BigLetterTiles: - db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 - db $ee,$ee,$44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$44 - db $7c,$7c,$44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$ee,$ee - db $10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$38,$38 - db $38,$38,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10 - db $70,$70,$40,$40,$40,$40,$40,$40,$40,$40,$40,$40,$42,$42,$fe,$fe - db $fe,$fe,$42,$42,$40,$40,$40,$40,$40,$40,$40,$40,$40,$40,$40,$40 - db $48,$48,$44,$44,$44,$44,$44,$44,$44,$44,$42,$42,$42,$42,$e3,$e3 - db $fc,$fc,$42,$42,$42,$42,$42,$42,$42,$42,$7c,$7c,$48,$48,$48,$48 - db $42,$42,$42,$42,$42,$42,$42,$42,$42,$42,$42,$42,$42,$42,$3c,$3c - db $3c,$3c,$42,$42,$42,$42,$42,$42,$42,$42,$42,$42,$42,$42,$42,$42 - db $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$70,$70 - db $7c,$7c,$22,$22,$22,$22,$22,$22,$22,$22,$3c,$3c,$20,$20,$20,$20 - db $38,$38,$44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$ee,$ee - db $10,$10,$28,$28,$28,$28,$28,$28,$28,$28,$28,$28,$28,$28,$28,$28 - db $ce,$ce,$44,$44,$64,$64,$54,$54,$54,$54,$54,$54,$54,$54,$54,$54 - db $54,$54,$54,$54,$54,$54,$54,$54,$54,$54,$4c,$4c,$44,$44,$e6,$e6 - db $fe,$fe,$92,$92,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10 - db $7e,$7e,$22,$22,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20 - db $38,$38,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$70,$70 - db $70,$70,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20 - db $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$22,$22,$7e,$7e - db $42,$42,$42,$42,$42,$42,$42,$42,$42,$42,$42,$42,$42,$42,$fc,$fc - db $f8,$f8,$44,$44,$42,$42,$42,$42,$44,$44,$78,$78,$44,$44,$42,$42 - db $ee,$ee,$44,$44,$44,$44,$44,$44,$44,$44,$7c,$7c,$44,$44,$44,$44 - db $44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$ee,$ee - db $7e,$7e,$22,$22,$20,$20,$20,$20,$20,$20,$38,$38,$20,$20,$20,$20 - db $fe,$fe,$42,$42,$40,$40,$40,$40,$40,$40,$70,$70,$40,$40,$40,$40 - db $40,$40,$40,$40,$40,$40,$40,$40,$40,$40,$40,$40,$42,$42,$fe,$fe - db $3c,$3c,$42,$42,$42,$42,$42,$42,$40,$40,$40,$40,$40,$40,$40,$40 - db $40,$40,$40,$40,$40,$40,$40,$40,$42,$42,$42,$42,$42,$42,$3c,$3c - db $42,$42,$42,$42,$42,$42,$42,$42,$42,$42,$42,$42,$44,$44,$f8,$f8 - db $f8,$f8,$44,$44,$42,$42,$42,$42,$42,$42,$42,$42,$42,$42,$42,$42 - db $80,$80,$80,$80,$8f,$8f,$8a,$8a,$82,$82,$82,$82,$44,$44,$38,$38 - db $38,$38,$44,$44,$82,$82,$82,$82,$82,$82,$80,$80,$80,$80,$80,$80 - db $04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$44,$44,$44,$44,$38,$38 - db $0e,$0e,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04 - db $ee,$ee,$44,$44,$44,$44,$48,$48,$50,$50,$60,$60,$50,$50,$48,$48 - db $54,$54,$54,$54,$54,$54,$54,$54,$44,$44,$44,$44,$44,$44,$ee,$ee - db $c6,$c6,$6c,$6c,$54,$54,$54,$54,$54,$54,$54,$54,$54,$54,$54,$54 - db $42,$42,$42,$42,$42,$42,$42,$42,$4a,$4a,$4c,$4c,$4c,$4c,$36,$36 - db $3c,$3c,$42,$42,$42,$42,$40,$40,$40,$40,$3c,$3c,$02,$02,$02,$02 - db $02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$42,$42,$42,$42,$3c,$3c - db $44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$28,$28,$10,$10 - db $44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$38,$38 - db $44,$44,$54,$54,$54,$54,$54,$54,$54,$54,$54,$54,$54,$54,$28,$28 - db $10,$10,$10,$10,$28,$28,$28,$28,$28,$28,$44,$44,$44,$44,$ee,$ee - db $ee,$ee,$44,$44,$44,$44,$28,$28,$28,$28,$28,$28,$10,$10,$10,$10 - db $ee,$ee,$44,$44,$44,$44,$28,$28,$10,$10,$10,$10,$10,$10,$10,$10 - db $fe,$fe,$82,$82,$04,$04,$04,$04,$08,$08,$08,$08,$08,$08,$10,$10 - db $10,$10,$20,$20,$20,$20,$20,$20,$40,$40,$40,$40,$82,$82,$fe,$fe -BigLetterTilesEnd: - 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 @@ -384,5 +340,4 @@ UITilemap: 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 - UITilemapEnd: diff --git a/ScreenMainMenu.inc b/ScreenMainMenu.inc index 3d1483a..8114ad7 100644 --- a/ScreenMainMenu.inc +++ b/ScreenMainMenu.inc @@ -1,19 +1,18 @@ ; global variables at the start of hram -DEF vCurrentSpread EQU $ff90 ; 16bit address of current spread -DEF vSelectedSpreadIndex equ vCurrentSpread + 2 -def vSelectedSpreadCard equ vSelectedSpreadIndex + 1 -def vSelectedCardIndex equ vSelectedSpreadCard+1 -DEF vFrameCountSquares EQU vSelectedCardIndex+1 -DEF vTime EQU vFrameCountSquares+1 ; 16bit -println "after vTime is ", vTime+2 +DEF vCurrentSpread EQU GLOBAL_VARS_START ; 16bit address of current spread, ff90 +DEF vSelectedSpreadIndex equ vCurrentSpread + 2 ; ff92 +def vSelectedSpreadCard equ vSelectedSpreadIndex + 1 ; ff93 +def vSelectedCardIndex equ vSelectedSpreadCard+1 ; ff94 +DEF vFrameCountSquares EQU vSelectedCardIndex+1 ; ff95 +DEF vTime EQU vFrameCountSquares+1 ; 16bit ; ff96 +println "after vTime is ", vTime+2 ; ff98 -; (but after async vars!) -; they probably don't needd to be there but whatever +; screen-specific variables DEF vFrameCount1 EQU VARIABLES_START DEF vFrameCount2 equ vFrameCount1+1 DEF vFrameCount3 EQU vFrameCount2+1 -DEF vMenuIndex equ vFrameCount3 + 1 +DEF vMenuIndex equ vFrameCount3+1 DEF vMenuIndexPrevious equ vMenuIndex + 1 ScreenMainMenu: @@ -235,7 +234,9 @@ MainMenuUpdate: call ChangeScene ret .option2 - jp .doneWithMenuSelect + ld hl, ScreenShuffle + call ChangeScene + ret .option3 ld a, 0 ldh [vSelectedCardIndex], a @@ -284,11 +285,6 @@ MainMenuUpdate: call ArrayClampLooping ldh [vFrameCount3], a - ;ldh a, [vFrameCount4] - ;inc a - ;call ArrayClampLooping - ;ldh [vFrameCount4], a - ld hl, SquaresTiles ldh a, [vFrameCountSquares] inc a @@ -405,6 +401,9 @@ MainMenuTeardown: DrawWholeCard: ; hl memory location, b y, c x, e width, d wiggle ld a, e + cp a, 32 + ld e, TileStartCardBackSprites24 + jp z, Draw4x4Card cp a, 24 ld e, TileStartCardBackSprites24 jp z, Draw3x3Card @@ -435,9 +434,8 @@ DrawWholeCard: ; hl memory location, b y, c x, e width, d wiggle ; else fall through into 2x2card Draw2x2Card: -; hl memory location, b y coord, c x coord, e width +; hl memory location, b y coord, c x coord, e tile start ; top-left - ld e, TileStartCardBackSprites16 ld a, $0 call DrawTile @@ -561,6 +559,118 @@ Draw3x3Card: call DrawTile ret +Draw4x4Card: +; hl memory location, b y coord, c x coord, e base for tiles, d wiggle + + ;first row + ; top-left + ld a, 0 + call DrawTile + + ld a, c + add a, 8 ; add stride to x + ld c, a + ld a, $2 + call DrawTile + + ld a, c + add a, 8 + ld c, a + ld a, $2 + call DrawTile + + ld a, c + add a, 8 + ld c, a + ld a, $4 + call DrawTile + + ;second row + ld a, b + add a, 16 + ld b, a ; add 16 to y coord + ld a, c + sub a, 24 + ld c, a ; restore the state to before we drew the first row + ld a, $6 + call DrawTile + + ld a, c + add a, 8 + ld c, a + ld a, $8 + call DrawTile + + ld a, c + add a, 8 + ld c, a + ld a, $8 + call DrawTile + + ld a, c + add a, 8 + ld c, a + ld a, $a + call DrawTile + + + ;second row + ld a, b + add a, 16 + ld b, a ; add 16 to y coord + ld a, c + sub a, 24 + ld c, a ; restore the state to before we drew the first row + ld a, $6 + call DrawTile + + ld a, c + add a, 8 + ld c, a + ld a, $8 + call DrawTile + + ld a, c + add a, 8 + ld c, a + ld a, $8 + call DrawTile + + ld a, c + add a, 8 + ld c, a + ld a, $a + call DrawTile + + ; third row + ld a, b + add a, 16 + ld b, a ; add stridex2 to y coord + ld a, c + sub a, 24 + ld c, a ; subtract stridex2 from x + ld a, $c + call DrawTile + + ld a, c + add a, 8 + ld c, a + ld a, $e + call DrawTile + + ld a, c + add a, 8 + ld c, a + ld a, $e + call DrawTile + + ld a, c + add a, 8 + ld c, a + ld a, $10 + call DrawTile + ret + DrawTile: ; b: y. c: x. a: part id. hl: location of sprite in OAM ; e: sprite bank ld d, a ; immediateely put the card part id into d diff --git a/ScreenShuffle.inc b/ScreenShuffle.inc new file mode 100644 index 0000000..2b2d151 --- /dev/null +++ b/ScreenShuffle.inc @@ -0,0 +1,395 @@ +; screen variables already ddefined in screencardread +;DEF vPreviousCardIndex EQU VARIABLES_START +;def vBlocked equ vPreviousCardIndex + 1 +def vAnimationFrame EQU VARIABLES_START +def vAnimationState EQU vAnimationFrame+1 +def vCurrentAnimation EQU vAnimationState+1 ; 2 bytes +def vShuffleIndex equ vCurrentAnimation+2 +def vShuffleTime equ vShuffleIndex+1 ; 2 bytes + +ScreenShuffle: + dw ShuffleSetup + dw ShuffleUpdate + dw ShuffleDraw + dw ShuffleTeardown + +ShuffleSetup: + ld hl, SHUFFLED_DECK + ld a, [hl] + dec a + ldh [vShuffleIndex], a + + ld a, 0 + ldh [vAnimationFrame], a + ldh [vAnimationState], a + ld a, LOW(ShuffleAnimationRight) + ldh [vCurrentAnimation], a + ld a, HIGH(ShuffleAnimationRight) + ldh [vCurrentAnimation+1], 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, vMenuIndexPrevious+2 ; arguments to the first async call. + + call DoInAsyncVBlank + + ld hl, ZEROES ; hl is source + ld de, $c000 ; de is destination + ld bc, $100 ; length to copy + call CopyRangeUnsafe + + ret + +.loadUIMap + + ld hl, Shuffle.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(.loadTiles) + ld [vAsyncAfter], a + ld a, HIGH(.loadTiles) + ld [vAsyncAfter+1], a + ret +.loadTiles + ld hl, Shuffle.UITileData + ld de, $9000 + VARIABLE_TILES_START*16 + ld bc, Shuffle.UITileDataEnd - Shuffle.UITileData + + ld a, LOW(CopyRangeUnsafe) + ldh [vAsyncNext], a + ld a, HIGH(CopyRangeUnsafe) + ldh [vAsyncNext+1], a + + ld a, LOW(.drawBigCard) + ld [vAsyncAfter], a + ld a, HIGH(.drawBigCard) + ld [vAsyncAfter+1], a + ret +.drawBigCard + ld hl, $9800 + $20*5 + 8 + ld a, VARIABLE_TILES_START + ld [hl+], a + inc a + ld [hl+], a + ld [hl+], a + inc a + ld [hl+], a + ld b, 0 + ld c, 32 - 4 + add hl, bc + + + inc a + ld [hl+], a + inc a + ld [hl+], a + ld [hl+], a + inc a + ld [hl+], a + add hl, bc + sub a, 2 + + ld [hl+], a + inc a + ld [hl+], a + ld [hl+], a + inc a + ld [hl+], a + add hl, bc + sub a, 2 + + ld [hl+], a + inc a + ld [hl+], a + ld [hl+], a + inc a + ld [hl+], a + add hl, bc + sub a, 2 + + ld [hl+], a + inc a + ld [hl+], a + ld [hl+], a + inc a + ld [hl+], a + add hl, bc + sub a, 2 + + ld [hl+], a + inc a + ld [hl+], a + ld [hl+], a + inc a + ld [hl+], a + add hl, bc + sub a, 2 + + ld [hl+], a + inc a + ld [hl+], a + ld [hl+], a + inc a + ld [hl+], a + add hl, bc + inc a + + ld [hl+], a + inc a + ld [hl+], a + ld [hl+], a + inc a + ld [hl+], a + ret + +ShuffleUpdate: + ld hl, vShuffleTime + ldh a, [rDELTAT] + ld b, a + ld a, [hl] + add a, b + ld [hl+], a ; inc hl to get high byte + ld a, [hl] + adc a, 0 + ld [hl], a ; this is addinig rDELTAT to vShuffleTime so we can use it for + ; seeding the rng + + + ld hl, vTime + ldh a, [rDELTAT] + ld b, a + ld a, [hl] + add a, b + ld [hl+], a ; inc hl to get high byte + ld a, [hl] + adc a, 0 + ld [hl], 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 + + ld a, [hl] + cp a, $01 + jp c, .doneTimer ; if the timer is less than $0100, skip to end + + ;otherwise reset the timer + ld a, 0 + ld [hl-], a + ld [hl], a + + ld hl, SquaresTiles + ldh a, [vFrameCountSquares] + inc a + call ArrayClampLooping + ldh [vFrameCountSquares], a + +.doneTimer + + ld hl, rMYBTNP + + ld a, 0 + cp a, [hl] + jr z, .noButtons + ldh a, [rLFSR] + ldh [rLFSR+1], a ; lfsr = (lfsr << 8) + (vShuffleTime & $ff) + ldh a, [vShuffleTime] + ldh [rLFSR], a + +.noButtons + + bit 4, [hl] + jp z, .doneWithB + ld hl, ScreenMainMenu + call ChangeScene + ret +.doneWithB + bit 0, [hl] + jp z, .doneWithRight + + ld a, 1 + ldh [vAnimationState], a + ld a, 0 + ldh [vAnimationFrame], a + + ld a, LOW(ShuffleAnimationRight) + ldh [vCurrentAnimation], a + ld a, HIGH(ShuffleAnimationRight) + ldh [vCurrentAnimation+1], a + + call DoSomeShuffling +.doneWithRight + bit 1, [hl] + jp z, .doneWithLeft + + ld a, 1 + ldh [vAnimationState], a + ld a, 0 + ldh [vAnimationFrame], a + + ld a, LOW(ShuffleAnimationRightReturn) + ldh [vCurrentAnimation], a + ld a, HIGH(ShuffleAnimationRightReturn) + ldh [vCurrentAnimation+1], a +.doneWithLeft + + ;animation logic! + ldh a, [vCurrentAnimation] + ld l, a + ldh a, [vCurrentAnimation+1] + ld h, a ; fetch current animation + + ldh a, [vAnimationState] + or a, a + jp z, .doneWithAnimation + + ldh a, [vAnimationFrame] + inc a + cp a, [hl] + jp nz, .animNotDone + dec a + ldh [vAnimationFrame], a + ld a, 0 + ld [vAnimationState], a + ldh a, [vAnimationFrame] +.animNotDone + call ArrayClampLooping + ldh [vAnimationFrame], a + +.doneWithAnimation + inc hl + ld b, 0 + ldh a, [vAnimationFrame] + ld c, a + add hl, bc + add hl, bc ; two bytes per entry + + ; hl points to xy offsets + ld a, 40+16 + add a, [hl] + ld b, a + inc hl + ld a, 64+8 + add a, [hl] + ld c, a + ld a, 32 + ld e, a + ld hl, $c000 + call DrawWholeCard + + ret + +ShuffleDraw: + ; the card data is loaded asynchronously, initiated in CardReadUpdate + + 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 ; tile number $101 is the sliding background + ld bc, (SquaresTileset8 - SquaresTileset7) / 8 + call CopyRangeUnsafeBy8s + + ld de, vMenuIndexPrevious+2 ; safe bytes in hram for dma code to live at + ld a, $c0 + call RunDMA + + ret + +ShuffleTeardown: + ret + +DoSomeShuffling: + call OneSwap + call OneSwap + call OneSwap + call OneSwap + call OneSwap + call OneSwap + ret + +OneSwap: ; shuffles once and decrements vshuffleindex + ; vShuffleIndex holds the index of the next card to swap with something + ldh a, [vShuffleIndex] + cp a, 1 + jp z, .zeroIndex ; if we're swapping index 1 with index 0 skip it + + ld d, a + dec d ; this holds the highest index we could want to swap with + + call RandomUnderD ; takes d as limit (inclusive) + ld e, a ; shuffle 2 is randint(vshuffleindex-1) + ld c, d ; shuffle 1 is vshuffleindex + ld hl, SHUFFLED_DECK + call SwapCards ; arguments c and e as indices to swap, hl as array in memory + + ldh a, [vShuffleIndex] + dec a + ldh [vShuffleIndex], a ; decrement vshuffleindex so the next time around + ; we do the next step of the shuffle + ret +.zeroIndex + ld a, [SHUFFLED_DECK] + dec a + ldh [vShuffleIndex], a + ret + + +ShuffleAnimationRight: + db 15, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15 +ShuffleAnimationRightReturn: + db 15, 15, 15, 14, 14, 13, 13, 12, 12, 11, 11, 10, 10, 9, 9, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1 + +Shuffle.UITilemap: + 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, $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 +Shuffle.UITilemapEnd: + +Shuffle.UITileData: + db $00,$ff,$7f,$ff,$7f,$ff,$60,$ff,$6f,$ff,$6d,$fa,$6a,$fd,$6d,$fa ; top-left + db $00,$ff,$ff,$ff,$ff,$ff,$00,$ff,$ff,$ff,$55,$aa,$aa,$55,$55,$aa ; top-middle + db $00,$ff,$fe,$ff,$fe,$ff,$06,$ff,$f6,$ff,$56,$bf,$b6,$5f,$56,$bf ; top-right + db $6a,$fd,$6d,$fa,$6a,$fd,$6d,$fa,$6a,$fd,$6d,$fa,$6a,$fd,$6d,$fa ; middle-left + db $aa,$55,$55,$aa,$aa,$55,$55,$aa,$aa,$55,$55,$aa,$aa,$55,$55,$aa ; middle-middle + db $b6,$5f,$56,$bf,$b6,$5f,$56,$bf,$b6,$5f,$56,$bf,$b6,$5f,$56,$bf ; middle-right + db $6a,$fd,$6d,$fa,$6a,$fd,$6f,$ff,$60,$ff,$7f,$ff,$7f,$ff,$00,$ff ; bottom-left + db $aa,$55,$55,$aa,$aa,$55,$ff,$ff,$00,$ff,$ff,$ff,$ff,$ff,$00,$ff ; bottom-middle + db $b6,$5f,$56,$bf,$b6,$5f,$f6,$ff,$06,$ff,$fe,$ff,$fe,$ff,$00,$ff ; bottom-right +Shuffle.UITileDataEnd: diff --git a/ScreenSpreadSelect.inc b/ScreenSpreadSelect.inc index 7ee2d46..69ef836 100644 --- a/ScreenSpreadSelect.inc +++ b/ScreenSpreadSelect.inc @@ -599,7 +599,7 @@ DrawSpreadMinimap: push hl ; need this bc drawsmallcard changes hl push bc ld a, [bc] - ld bc, $1817 + ld bc, $1716 call DrawSmallCard pop bc pop hl @@ -620,7 +620,7 @@ DrawSpreadMinimap: ld a, [hl] pop hl ; stack: empty - ld bc, $1a19 + ld bc, $1918 call DrawSmallCard ret diff --git a/judgement.aseprite b/judgement.aseprite new file mode 100644 index 0000000000000000000000000000000000000000..4302f29962eccb928da0f38173601f7ffc3a68b1 GIT binary patch literal 5502 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 diff --git a/main.asm b/main.asm index 9282ba1..f508b79 100644 --- a/main.asm +++ b/main.asm @@ -9,20 +9,38 @@ ; 0xc102 HIGH ; 0xc103 RET ; 0xc104 CALL ... +def MY_OAM equ $c000 DEF SCENE_SETUP EQU $c101 DEF SCENE_UPDATE EQU SCENE_SETUP + 4 ; call then ret is 3+1 bytes DEF SCENE_DRAW EQU SCENE_UPDATE + 4 DEF SCENE_TEARDOWN EQU SCENE_DRAW + 4 DEF INTERRUPT_LCD EQU $c111 +def SHUFFLED_DECK equ $c200 ; location for the shuffled deck def ZEROES equ $D000 def ONES equ $D200 -DEF rMYBTN EQU $FFA8 +DEF ASYNC_VARS_START equ $ff80 ; these are defined manually in async.inc +DEF SYSTEM_VARS_START equ ASYNC_VARS_START + $10 +; allocating $8 spaces for system variables, currently only using $3 bytes +DEF rMYBTN EQU SYSTEM_VARS_START DEF rMYBTNP EQU rMYBTN + 1 DEF rDELTAT EQU rMYBTNP + 1 -DEF VARIABLES_START EQU rDELTAT+1 +def rLFSR equ rDELTAT + 1 ; 16 bit +DEF GLOBAL_VARS_START EQU SYSTEM_VARS_START + $8 +; global app-wide variables go after GLOBAL_VARS_START. allocated $10 for them +def VARIABLES_START equ GLOBAL_VARS_START + $10 +; screen-specific variables live after VARIABLES_START + +; WRAM Layout looks like this: +; $c000 - $c100 OAM DMA source +; $c101 - $c113 self-modifying code interrupts +; $d000 - $d400 zeroes and ones, just because they're handy! + +def VARIABLE_TILES_START equ 27 + + INCLUDE "hardware.inc" SECTION "Interrupts", ROM0[$0] @@ -51,7 +69,7 @@ EntryPoint: ld [hl+], a ld a, b or a, c - dec bc + dec bc ; we still need to do the `or` to set the zero flag bc dec r16 doesn't do that jp nz, .buildZeros ld a, 1 @@ -62,8 +80,8 @@ EntryPoint: ld a, 1 ld [hl+], a ld a, b - or a, c - dec bc + or a, c + dec bc ; we still need to do the `or` to set the zero flag bc dec r16 doesn't do that jp nz, .buildOnes ld hl, UITiles @@ -76,10 +94,23 @@ EntryPoint: ld bc, LetterTilesEnd - LetterTiles call CopyRangeUnsafe - ; initialize app-wide variables + ; initialize global variables ld a, 0 ldh [vSelectedSpreadIndex], a ldh [vSelectedCardIndex], a + ld hl, Cards + ld b, [hl] + ld hl, SHUFFLED_DECK + ld [hl], b + inc hl +.writeCard + ld [hl+], a + inc a + cp a, b + jr nz, .writeCard + + ld a, %1010_1010 + ldh [rLFSR], a ; move on to framework stuff @@ -169,7 +200,6 @@ Loop: add a, 64 ldh [rDELTAT], a xor a, a ; zero a out in one cycle - ; store dpad and btn state in the rMYBTN register ld hl, rP1 @@ -309,6 +339,10 @@ run_dma_tail: ; This part must be in HRAM. Instructions: call SCENE_UPDATE + 2 ret + + + + UITiles: db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 @@ -329,11 +363,10 @@ UITiles: db $00,$00,$fc,$00,$fe,$00,$ae,$50,$1e,$e0,$06,$f8,$ce,$f0,$c6,$f8 db $ce,$f0,$c6,$f8,$0e,$f0,$16,$e8,$5e,$a0,$fe,$00,$fc,$00,$00,$00 db $63,$1f,$73,$0f,$60,$1f,$78,$07,$75,$0a,$7f,$00,$3f,$00,$00,$00 - db $00,$0f,$00,$10,$00,$10,$00,$10,$00,$0f,$00,$10,$00,$10,$00,$10 - db $00,$7f,$00,$80,$00,$80,$00,$80,$00,$7f,$00,$10,$00,$10,$00,$10 - db $00,$0f,$00,$10,$00,$10,$00,$10,$00,$7f,$00,$80,$00,$80,$00,$80 - db $00,$7f,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 - db $00,$0f,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + db $00,$77,$00,$88,$00,$88,$00,$88,$00,$88,$00,$88,$00,$88,$00,$77 + db $00,$00,$00,$80,$00,$80,$00,$80,$00,$80,$00,$80,$00,$80,$00,$00 + db $00,$77,$00,$88,$20,$a8,$20,$a8,$20,$a8,$20,$a8,$00,$88,$00,$77 + db $00,$77,$00,$88,$02,$8a,$02,$8a,$02,$8a,$02,$8a,$00,$88,$00,$77 db $56,$c3,$6a,$c3,$56,$c3,$6a,$c3,$56,$c3,$6a,$c3,$7e,$ff,$00,$ff db $00,$ff,$7e,$ff,$56,$c3,$6a,$c3,$56,$c3,$6a,$c3,$56,$c3,$6a,$c3 db $99,$5a,$99,$5a,$99,$5a,$99,$5a,$99,$5a,$81,$42,$81,$7e,$ff,$00 @@ -440,12 +473,14 @@ LetterTiles: LetterTilesEnd: INCLUDE "Async.inc" +INCLUDE "Random.inc" INCLUDE "CopyRangeSafe.inc" INCLUDE "CopyTilesSafe.inc" INCLUDE "ScreenMainMenu.inc" INCLUDE "ScreenSpreadSelect.inc" INCLUDE "ScreenCardRead.inc" INCLUDE "ScreenCardBrowse.inc" +INCLUDE "ScreenShuffle.inc" INCLUDE "CardLibrary.inc" diff --git a/screendesigns.aseprite b/screendesigns.aseprite index 76f70d16c67d30ad2c7666fc3803434d4b2bfa1a..51fb7f0252ca875c365bc5550df74242f0656c6c 100644 GIT binary patch delta 346 zcmV-g0j2)hCetPXQ;`9G4bu_;0Q&LO0Av6F0M)ULvI`F(0RR9aAOipZ00sa602-4{ z3>km*0001ZoUK#=62l+}L;3%o2NI|t54!h`@enIsEw&(H!@3gSF$Vg+pL09+^Q#W# z0=zsDcz1cM>fiN4C)HM#Tt{jx(y#!pbWMLz%iB@~-sy|~8Vz78%VdZ!5gm#l6{`Ya z7QXTstsip>N@zhsGj8)i&yq10H0}eff&H|;#y5D&3J2MPp7CD1c-$`BT;e)DZ!pE5 z^56RiJJ#D#iqCpE@_{~Yv)I4%SM*AdzkGmgkm&0001ZoV`?07K9)OM7;l<7i1tKtz7pleoR;c1EEAeup;XL&EV@6e1_FzAjJDw zY9SWhKz%H=@&=A|!Mu)KA0LI!^`SAXQ|J)k!Bfn1wcLWp4K@?tAOn5hzjL0)x$A?4 zfG*Dj-CZ5C{&(}x8QaR1`$%m>8W!M^uO)wKdt0f%HGlG7V*qSr8yq5>hz^BF#kxQ^ z3zvG%?1OGe2_r}t#>aXvvt-HzP5VjKN&T?DrZ;rUiU8LLf*6wj6aQ=5 z;d9m7ReoO8%T@8oACGD5FUBi+rO1@LKvnA(`sF;teth>X?g#A=2n`AV001B$006UD z0uTYSZVu!DFEwvSo5u#ktavaxiRLj9i3iF&e0c*I6Kfu^VAQ<9Wu71q^Af-UB$x*P MD^mjyvw;xO0{3N}mH+?% diff --git a/source.zip b/source.zip index d974b7f406ab113763b87290e703b7b59195f336..d6c812df26f3e2f5072de67fe4a206ac7853f551 100644 GIT binary patch delta 10840 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 NXNN+6xhITY{|&3%$y)#b delta 4412 zcmbVPYiv|S6uvXJ3+=WG+Sa~!bovN_v~}BEx(h8xsjakK477{o8MEEJORMd+EZYJ# zW=(2>Ad2xK6AdPiXo&bj8Ur`|1qp=26cMq8#QI1u#Kan3iTXpMo|(CK_wKgqRv=&J z+?g}qnK|do%$}JyZ6_ykY+F0z46DTcogA@`+w8+Kv>$F9Zd}fVs5-NZ3j^azin#Fd zM?Nw1(|4DbupVt(MukF}T#o)O=6yHZXz5Ze&3IAHl4YQ`t2)DSYF~*YF=T|<2(KzPf}P2ML-%eL*LvbD9zO<%u>++~lqw34TqI@_8yd0M)j z?(#NudbvvY@fMG_$-BB%J9`UFBRY8-9m=v25>Wi4$FH6K4Ar4b-_TI?!M=b(r>0Q1 z_RZ&LI#ZkY8tt%I2(fN&J4MhoZQuv=QUXkzagji~^S5>-#>Y2&q7@F}b zyu+l$$6&&wmHwWKh_%GuWB4x%ZCsCASjR1_-C2RxBdWIJcdgb##pL0=4fU! zY8cixpK4ONeg_zK_;m+zIsHNyXLL5PAgKd?-Va)OW*E z19p=xG)d#)Ob8AmCF_7I5z*w1xxNL7ACif|SV%n>WLPsV2##60(G-)NERh&soI$B) z5F|z>uLZX<7`vNaD>z)R5r$|iF8?duf<&C!#TuW(zf?s@YS zZd?GC{IY|!fK}s|>UUi1H@&y7Updec3aqn2A;Uff zd_&spm3R>8rNaxIxR{p?M~{@fGdd{R^apy0uZrv*X$|`Zl;*+VP{g?xYP|+1Ly3W}C)i!-PYL^>q3Dq`jYnLC{!@6?EUv*x~ zmL!J7yyiFlJa-I9&AxEJ)7KOBg%7i$d}~L-N_SoR>hc@i#gfGEpfQiP{q&P|nGj~7 z?~BpwOHkf3Br5&-0bSf7mzFZEc;zlhnF&;P=#~z-kW}xfYHU zvyzmXpw+U9UhmMC70=sbty|r6fk!5>=+PRFT#zw3jV1b+4Hpz_?XWChw0ZFV%?wGp IS17~RzYz-aasU7T diff --git a/thedevil.aseprite b/thedevil.aseprite new file mode 100644 index 0000000000000000000000000000000000000000..4547513c06373f69780176bc5e6c7b1fe4afd559 GIT binary patch literal 5697 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 literal 0 HcmV?d00001 diff --git a/themoon.aseprite b/themoon.aseprite new file mode 100644 index 0000000000000000000000000000000000000000..b0b98458ebb0eb96a2e4ec62d55e683886ba8946 GIT binary patch literal 5550 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 WnpvjB62n(!5}XJOx-6_gwDVuW%oH^M literal 0 HcmV?d00001 diff --git a/thestar.aseprite b/thestar.aseprite new file mode 100644 index 0000000000000000000000000000000000000000..2aaafc199c8758e9d39cf263a90168f59469dc73 GIT binary patch literal 5209 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 XT+EtbCsSi*S!wR%1&#)yUa{lfsyW1r literal 0 HcmV?d00001 diff --git a/thesun.aseprite b/thesun.aseprite new file mode 100644 index 0000000000000000000000000000000000000000..52ea6a86bf3f3df87b85fa3ef9030ec7825607dd GIT binary patch literal 5908 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 literal 0 HcmV?d00001 diff --git a/thetower.aseprite b/thetower.aseprite new file mode 100644 index 0000000000000000000000000000000000000000..88b301515e5780506460f59c2802b5c60e4cb1ec GIT binary patch literal 5825 zcmeHLc|6ox8~@E%#=b@onXA%bPmQIR$&#d9lw1r$C|ej&YA8aI)NOg?8gz?Kn_ulvIpZk99=ly(oKA-1&&hMP(oacL<^Lw82oKq5CC8R0JuQ>m3RRdrxEHC_}cgv)^7l3@eTuZ*1M&H}S~=QV>6QgEnC{@oD!)EDKW&!Z zQ&kx;-k?L3w8zSA7-aJwWD_s2tH>o`!dq_g?Gb{YA(2o4{D0SQkk!|7w~ezEIuQTa zR!9QI9&X6}t^onAe*VZ~9-glLD$u~7#4Ky>-mD)5!BQ71492WSilPV?dbIup2`Jr@ zoH~F<&kdFKJ%FQpYMd3s{0Ac@J0->^RZ0C@$M>syn~lseN#?e0=&WUxy&oqmKM-s5 zHBVS}OPXZL9H|PjV72TbvT<$_|VZYK+j^%+_E@z4$mv^vtgeQ{T zTnLQ&c!p}Xkbw_g&K{ku-{A8CbRseqY#&-&-&bU{fG0K$#CmUi_se|Vpwn~v(R8ZX z9h?Ft{drhl=B`nBgKN|MjutOZU%Dz~aU*5bPtCnrsD<&u&X9`Oks+Uj`mx56?y$n8 z;|0#J3|U%o;|1qe8|fysO9U{J9;mb-F3Oh%3WBH3?k_I`U+9m4&*CsKWF?zuwvkPQ z(7ONcALKjwzskis;2c+j3U1WH{s&hR13Wzf0z6%jp1*lpA~XQ_hB2E^%xDz zNw-DCH~iS-<7UQm{X+tE7{?joE0LmO@C{%t3|p1T*3~^-_LP`Hkh5)HEz?9^-r3Wy zR`Eg3HfAj?Vu((av%mN-%4thFOG?6yHT_1fDjKckj2#qEj zK_Bd|B`8QM7*!H1Lz4`;o>$Zow9(m2RbNfvhKN(|6bvSpSalYJL5rEHrBsn)DaMIy zWNUUMZllO-T}klmv)Fi{+Y$LK;@XKLxu^;dAJ(0yhi6zKJctwg<#n;vVa#)ul=DBn z7Pb-%7lRGRhLpcBFaB6Qt2y7ydz8Lyw922IlSy%$zHIX}+kFtNe1sx9JbXA;Eta~2 z?ZI%EsTj3yuqRd&TztSX0D`yLZIH}-X zi2p1V6b39^gLnG{aFf9G+{5Yhy_j3$NCDHA8Gwu_f##4C^+GsI7 z2|eQ_QP3;IQE9^y&8b@LK%cR-%T0r6P9`Cl=x3|XlxIGp>M@%lD-(*YWWhyl==*H< z4WH+8d~F$ZZ|6IrkL|@R2zc)ew7+LfpZkVVMRLrv!Hv>&iv!EYjCYRJ>?qJ{e;e{P zWEkN%xAz%sX0dnDak!>6Bd6uWSyDz+FX39DM~9Asw>Qm0@O)LUb*kbVPxgD-8B*xc zD+(w)0I)y18&Nu9I@1?TMur!1GAr%P3Ai!HPx)G(-Oc{=84l6w4N*+KsOQ3;F; zQhWwVS7T#v`{o{<&CI2KaMk*vgfH|87DtVE=E|hR>IDj=D{MDk;43F3)*$QTi;# zsedH|U=HE;MQU$`+I~azMS!ya5x^OG5peSKb$4=h4dC>AUFb?V@h{hzFQOb^<`DBC zp#mcCUxwklWCbNoRBCg^ze=7vR+Ri3l|GoAr`>rSInl$*eHEU^Qv}>vADc7S@4AZleXbez(BVktwG?-&6Hi!(q_M@T#qP@j$S8?dQOIlI?yWRd z%*8JCsV#IR@K?78(St$zPa?*BE6-38deYIxkI)%mdZwxJ2 z6NLydO&?I$A+Cy5*x}Q*OR65H+`7v~VT|{UR-9Z^SMqk91cTk%>TzKSRq)quLVKo6 zbR&;4d|@|(cVX%e0saymNfHt~KvXTf-;WE12RH#}t+2QN!1oP{TR~uac?W^b6C%|~ z7zKEByhwN$N@5X~gO-RinY%nsH~q*5vrjL(bhykLGcHtJc~}=pLoV^-yto>9fx}QT z@^y~|0N!tCly<>lvAoVG{_#+`sDFgsmx(MjkYK=aq$Kiy9JQbLqo;Xt=&SDesmqj}lV+lR-h6A~L%W5U{#w;# zqvIMq#pF1a63b|+mJev0(npbwn69flfh0|T`@Io7fkU&jp zC2xE#FVYdotIk^ojqZcf%vc~5gp`Kzw`&354m1;-R&2)3^8(H$xCIg{(Xn;=$a&KK z2}FVM(;L^g*vv(Ps|cJHZAN&OsCPo&`^TR;-?lImqJ4#WOJ+T+<{6+UE$Mvm5kmBa z`%li;XMP#Mw5#Qkoign$wtMC=)sV=I^SV3%fK>=2SSo{ zrcIf|Z;KU`8l$qDq!L1@b&cf_oU%#G`Wz56I2>w#zjqG@MSUOr*l0(g4Cx;o1wWwU z<^nf%_V;)8^@E>r^KkZ)h86~=Ju#=B&AurRtaLI%qxFUahEnj>*Jf5LsX0$oH3U7(wkUbtuU~5K|R@)Hk_O_dQWK3P_!}{ zC|$ol=pMcfv~h;orSr2qSS07fY33T;C1lrk86cv4tcgyk4SR2aN_7k zc@e|8T2o@0aSJ2%m>2G0R|GKEGKFq-zCo&P%#`$9tVx&{_ugooZZ98tlPYW2Xo1R5>kmVJ_8^-c=o(;brtwrV;X#xh>mZRu!yB0>%!NDkxJXd zq!J7@@Qv`w6_TQ0+7w91X&4^wwog2)bK3*{jlycyXj-r@d=Qi$#uu>gkX*PO-J1?H6^vkLI3ckOB)}*t+{vH8uCD96}~u)cW-<;f}`bBSRx{HSa~O z>g-Qa+l1Hz*>QW8F zr40=QD4s)v!i-Y2Ro!_rVX8+BasPr#c?YThFGxCF8Rm6=O_Z^FRk}mXq%@);FrBnk z`ZnkN!uS#+cxuE5@Tu-8Xp@*PDJpH)yJ_{BGdO3ybT)hKum&m#jKO_i4Uff}qE3!9 zps_+Or5lzMssQ{ zZa>#@OL@qR^VnpL8<&f^c$Ly73RG*rfQZ2~^?)TKRyV>dOLa?vdBkdv5%I!5UvZjo zNAbW$MJ`r9Hz=E|URGS|WI9bgG*#zE&Cey;FGO18JarvINtzNxe)+|uKrVr#LUmiR zTdbL~ZL=lR6kkfEXo5gSVMTYTX9a>Ydkc~L&kc$WUUeem4AFZi@DjtbfQr_{0k1pT zz0`BXm52t#P1J_kH4#ttGIIC2Ahn!9Zf)d8dz|^;UcbA87qnRywTXI#b_*kIDMu%8 zAUd?yu9gQR6}V_f6LyI>Qh{Ds!K$zI;m@iMUnBW7lF*;RUq&dm=~R#rLO`Q}Cm{VJ zD#!^KIfoqc^{11-2096BvlzTx4`(ym0`YIZi)D_JS1$}za z!J&0=e{B~3=@_eyR=`-x<4_#!5@iTUN?6t$nCHvM4KjcFbFT0&qp*czGAArNBKD+ zu0b}lsq?K&d2DM)%=ah8;=sj;HFn&T!9dVh`zwiMMLXp#<11X=x3pefw$JG8;vNzx zb)I>7))g+?k)0`YF)t-`I)y)_=E@Wl=mojkuS4|E zQfAO_9zdw|ZblgqjZ-Z1=CV9qsjd{J>$T_DOqlFdGVU&XeC(Tv+o7eLSL+lh=f0&1 zo5{Odt56iuUq9r26P6e7MvGr9H;-C8j{y<6GdTXxJmEMJV#yH|@2YKCMd65FdE@s( z;QOG5C7YgFX&=`2z{{)@+@ID+{Jbc*h1Y$b%IY6dCD^!2YcTu#Tgz$#;o7;Leb*!= zE%tmZ<9}h|eJ%X|@1iFOoi-Dk7ivEV2z59B9S7Vw7hmrHFDC@_n+eVc(CGR{p;_?m zuz>4&`-IS{r8K0!H{}4#F>nJ1Cl_abKiUHh(ybVN^FSWJ_#@l@^=?gbC-aAvoI9`J zP}v0}el?@@KMN~h0O9w6D;yL(=Fta zDGitbq|9)rfdu?_U}ztpg41Sem1yfn0^Cm?wru^h7hsdP++*yfnPT}7a2!w1t zPekhTga~OD>D@HBeb!QCK#jtuk&jO@!)zZ_g_%@&p=UViYfaQ3-Vnxu^Q3!Z0!$$G z@cDGv0H!Z^6m-I3u}qGtEHmMvF+YUg6^^ddJ`EoZ|Viy?m#m>}7_Q+{S zDKm%f1~iedBPn!eG`jMivHp^?2W^cU45nPnoiaRD4IH?+DiR2)cSv%Q#MIv@C}0o| z4r3dxv*UWXn)?c}M$oC634P`#{oRNz?UAw?2>qM=$I1EGy7Ctc4yI+8Bt!oUYntN;CybJsc9Y?Gu!aGxqkCQ2faYU0s)-^ z%2ZHsD72kB5c;hT{DDVlDZA`0{8FseTU9)IkD}eT g+$BTsTp!EvE}2~;M-#%