From ddf12e824003658cb1243705ae9cb262efd22837 Mon Sep 17 00:00:00 2001 From: shoofle Date: Sun, 2 Mar 2025 13:10:46 -0500 Subject: [PATCH] various fixes and streamlines and function encapsulation --- 00TheFool.inc | 107 ++++++++++++++++++++++++++----------------- 00thefool.aseprite | Bin 6806 -> 6804 bytes 00thefool.asm | 24 ---------- 01TheMagician.inc | 41 +++++++++++++++++ CardHelpers.inc | 36 +++++++++++++-- CopyRangeSafe.inc | 9 ++-- ScreenCardBrowse.inc | 40 ++++++++-------- ScreenCardRead.inc | 30 +++++------- SpriteTiles.asm | 41 +++++++++++++++++ source.zip | Bin 297544 -> 299581 bytes 10 files changed, 217 insertions(+), 111 deletions(-) delete mode 100644 00thefool.asm create mode 100644 SpriteTiles.asm diff --git a/00TheFool.inc b/00TheFool.inc index 8fa394c..40627ed 100644 --- a/00TheFool.inc +++ b/00TheFool.inc @@ -30,11 +30,11 @@ def Card_Offset_functions equ @-TheFool ; CARD_VARS_START+2: timer 2 ; CARD_VARS_START+4: animation frame for dog ; CARD_VARS_START+5: -; CARD_VARS_START+6: y of zero +; CARD_VARS_START+6: frame of zero ; CARD_VARS_START+7: .fInit: ld a, [rLCDC] - xor a, %0000_0100 + and a, %1111_1011 ld [rLCDC], a ld hl, CARD_VARS_START ld a, 0 @@ -44,8 +44,8 @@ def Card_Offset_functions equ @-TheFool ld [hl+], a ld [hl+], a ; frame of dog animation ld [hl+], a - ld [hl+], a ; y of zero - ld [hl+], a ; x of zero + ld [hl+], a ; frame of zero animation + ld [hl+], a ld hl, .doggie1 ld de, MY_OAM @@ -62,18 +62,11 @@ def Card_Offset_functions equ @-TheFool ret .fUpdate: - ld a, [rDELTAT] - ld b, a - - ld a, [CARD_VARS_START] - add a, b - ld [CARD_VARS_START], a + ld hl, CARD_VARS_START + call IncrementTimer + ld a, [CARD_VARS_START+1] - adc a, 0 - ld [CARD_VARS_START+1], a ; increment time. when the 16bit time register is greater - - ld a, [CARD_VARS_START+1] - cp a, $08 ; $10 00 = 1 second + cp a, 06 ; $10 00 = 1 second jp c, .doneWithTimer1 ; if the timer is less than $0800, skip to end ;otherwise reset the timer @@ -85,16 +78,11 @@ def Card_Offset_functions equ @-TheFool call .dogDance .doneWithTimer1 - - ld a, [CARD_VARS_START+2] - add a, b - ld [CARD_VARS_START+2], a - ld a, [CARD_VARS_START+2+1] - adc a, 0 - ld [CARD_VARS_START+2+1], a + ld hl, CARD_VARS_START+2 + call IncrementTimer ld a, [CARD_VARS_START+2+1] - cp a, $10 ; $10 00 = 1 second + cp a, $02 ; $10 00 = 1 second jp c, .doneWithTimer2 ; if the timer is less than $0800, skip to end ;otherwise reset the timer @@ -102,30 +90,25 @@ def Card_Offset_functions equ @-TheFool ld [CARD_VARS_START+2], a ld [CARD_VARS_START+2+1], a -.doneWithTimer2 - - ret -println "card vars start is ", CARD_VARS_START - -.fDraw: - ret + call .zeroRotate -.dogDance: +.doneWithTimer2 + ret - ld hl, CARD_VARS_START+4 - inc [hl] - ld a, 2 - cp a, [hl] +.dogDance: + ld a, [CARD_VARS_START+4] ; dog animation frame + inc a + cp a, 2 jp nz, :+ - ld [hl], 0 + ld a, 0 ; zero the frame if it was 2 : - ld a, [hl] ; a now holds the frame of the animation. + ld [CARD_VARS_START+4], a cp a, 0 jp z, .frame1 cp a, 1 jp z, .frame2 - ret + ret ; shouldn't ever hit this .frame1 ld hl, .doggie1 @@ -149,6 +132,42 @@ println "card vars start is ", CARD_VARS_START ld a, $23 call BuildMetaSprite ret + +.zeroRotate: + ld hl, .zeroCoords + ld a, [CARD_VARS_START + 6] + inc a + call ArrayClampLooping + ld [CARD_VARS_START + 6], a + + ld b, 0 + ld c, a + + ld hl, .zeroCoords+1 + add hl, bc ; add bc twice (it's a list of pairs) to jump to the bc'th element + add hl, bc ; of the list + ld b, [hl] ; load y into b + inc hl + ld c, [hl] ; load x into c + + + ld hl, .zero + ld de, MY_OAM + 6*4 ; we've already written six sprites for the doggie, 4 bytes each + ld a, $22 ; two by two + ; location of source tile map: hl + ; location in memory to write to: de + ; y and x in b and c (set above) + ; height and width in a & %11110000 and a & %00001111 ??? that's deranged + call BuildMetaSprite + ret + +.zeroCoords: ; length-prefixed list of y, x + db 4, 26, 41, 27, 42, 26, 43, 25, 42 + +.fDraw: + ret + + .SpriteTiles: @@ -162,10 +181,10 @@ println "card vars start is ", CARD_VARS_START db $00,$00,$00,$00,$00,$00,$0e,$0e,$8f,$8b,$ff,$fd,$ff,$01,$ff,$01 db $ff,$00,$ff,$00,$ff,$00,$ff,$80,$ff,$93,$fe,$96,$fc,$dc,$70,$70 db $ff,$01,$ff,$01,$ff,$01,$ff,$01,$ff,$c9,$7f,$4b,$7e,$6e,$38,$38 - db $00,$00,$03,$03,$0c,$0c,$10,$10,$20,$20,$20,$20,$40,$40,$40,$40 - db $00,$00,$c0,$c0,$30,$30,$08,$08,$04,$04,$04,$04,$02,$02,$02,$02 - db $40,$40,$40,$40,$20,$20,$20,$20,$10,$10,$0c,$0c,$03,$03,$00,$00 - db $02,$02,$02,$02,$04,$04,$04,$04,$08,$08,$30,$30,$c0,$c0,$00,$00 + db $00,$00,$03,$03,$07,$07,$0c,$0c,$18,$18,$18,$18,$30,$30,$30,$30 + db $00,$00,$c0,$c0,$e0,$e0,$30,$30,$18,$18,$18,$18,$0c,$0c,$0c,$0c + db $30,$30,$30,$30,$18,$18,$18,$18,$0c,$0c,$07,$07,$03,$03,$00,$00 + db $0c,$0c,$0c,$0c,$18,$18,$18,$18,$30,$30,$e0,$e0,$c0,$c0,$00,$00 .SpriteTilesEnd: .doggie1: ; tiles start at 0 @@ -175,6 +194,10 @@ println "card vars start is ", CARD_VARS_START db $01, $02, $07 db $04, $05, $09 +.zero: + db $0a, $0b + db $0c, $0d + .KeyArtTiles: db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 db $1f,$00,$0f,$00,$0f,$00,$0f,$00,$07,$00,$07,$00,$07,$00,$07,$00 diff --git a/00thefool.aseprite b/00thefool.aseprite index 4e173d2210ab7a9ce44e80319d2f18fa29808372..8e49e047363af9b9685552686aed7a2ad4d3c826 100644 GIT binary patch delta 169 zcmV;a09OB&HIy|0l#u~{0Ti);2onLklZq2Ee}w=50C=3OQNb3#APCa<|9@VYHnUkB z#s!@V;YsuhuwgVb<_gcKmClI4QngvFsBn>jJB%0XU8%TeH*nO0{ddTbBJ<@IX-eUq zT3wC2y!tYR3Q#7nkKYeq@jvok`)9e3*Z|(;_x=-s;Mm_|bYVEP^GkoqSR@|~qE|-4wY6uDMas delta 171 zcmV;c095~!HI_92mXQH}0T!`=2onLmlZq2Ee}@170C=3OQo$C0AP58Z|NopKqz{2S zv_spAnp;Hl3s5iy26M;G=t^hAU{Pb%6*X=mc*6KVol4Ecdw{(k?75E~DY9JKLE2Jy zw$@Z{Up{jgLk%c1sO!%KSpA^?b$*r&Neo~eexE-vaEaH|zP(#TvYBPJDKDZM)y#`P Z4Bce3pDcRw0akSa`IE5$mb2Rwxdm2NOez2X diff --git a/00thefool.asm b/00thefool.asm deleted file mode 100644 index 38a53ab..0000000 --- a/00thefool.asm +++ /dev/null @@ -1,24 +0,0 @@ - ; original export script by gabriel reis, modified by shoofle - - -.SpriteTiles: - db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 - db $01,$01,$01,$01,$01,$01,$01,$01,$1f,$1f,$1f,$10,$1f,$10,$1f,$1c - db $f0,$f0,$fc,$5c,$fe,$06,$5f,$a3,$ff,$01,$ff,$00,$ff,$00,$ff,$00 - db $00,$00,$00,$00,$00,$00,$07,$07,$87,$85,$ff,$fd,$ff,$01,$ff,$01 - db $07,$07,$01,$01,$01,$01,$01,$01,$00,$00,$00,$00,$00,$00,$00,$00 - db $ff,$00,$ff,$00,$ff,$00,$ff,$80,$ff,$93,$fe,$d2,$7e,$76,$1c,$1c - db $ff,$01,$ff,$01,$ff,$01,$ff,$01,$ff,$c9,$7f,$69,$3f,$3b,$0e,$0e - db $00,$00,$00,$00,$00,$00,$0e,$0e,$8f,$8b,$ff,$fd,$ff,$01,$ff,$01 - db $ff,$00,$ff,$00,$ff,$00,$ff,$80,$ff,$93,$fe,$96,$fc,$dc,$70,$70 - db $ff,$01,$ff,$01,$ff,$01,$ff,$01,$ff,$c9,$7f,$4b,$7e,$6e,$38,$38 - db $00,$00,$03,$03,$0c,$0c,$10,$10,$20,$20,$20,$20,$40,$40,$40,$40 - db $00,$00,$c0,$c0,$30,$30,$08,$08,$04,$04,$04,$04,$02,$02,$02,$02 - db $40,$40,$40,$40,$20,$20,$20,$20,$10,$10,$0c,$0c,$03,$03,$00,$00 - db $02,$02,$02,$02,$04,$04,$04,$04,$08,$08,$30,$30,$c0,$c0,$00,$00 -.SpriteTilesEnd: - -.Sprites: ; tiles start at 0 - db $01, $02, $07 - db $04, $05, $09 -.SpritesEnd: diff --git a/01TheMagician.inc b/01TheMagician.inc index a4e2792..edd7626 100644 --- a/01TheMagician.inc +++ b/01TheMagician.inc @@ -8,7 +8,48 @@ TheMagician: dw MagicianMap dw MagicianTilesEnd - MagicianTiles dw MagicianTiles + dw .SpriteTilesEnd - .SpriteTiles + dw .SpriteTiles + dw .fInit + dw .fUpdate + dw .fDraw +; CARD_VARS_START + 0 ; timer for lemniscate +; CARD_VARS_START + 2 ; frame counter 1 +; CARD_VARS_START + 3 ; frame counter 2 +.fInit: + ld a, [rLCDC] + and a, %1111_1011 + ld [rLCDC], a + ld hl, CARD_VARS_START + ld a, 0 + ld [hl+], a ; timer for dog @ +0 + ld [hl+], a + ld [hl+], a ; frame of animation 1 + ld [hl+], a ; frame of animation 2 + ret +.fUpdate: + ret +.fDraw: + ret + +.SpriteTiles: + db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + db $01,$01,$01,$01,$01,$01,$01,$01,$1f,$1f,$1f,$10,$1f,$10,$1f,$1c + db $f0,$f0,$fc,$5c,$fe,$06,$5f,$a3,$ff,$01,$ff,$00,$ff,$00,$ff,$00 + db $00,$00,$00,$00,$00,$00,$07,$07,$87,$85,$ff,$fd,$ff,$01,$ff,$01 + db $07,$07,$01,$01,$01,$01,$01,$01,$00,$00,$00,$00,$00,$00,$00,$00 + db $ff,$00,$ff,$00,$ff,$00,$ff,$80,$ff,$93,$fe,$d2,$7e,$76,$1c,$1c + db $ff,$01,$ff,$01,$ff,$01,$ff,$01,$ff,$c9,$7f,$69,$3f,$3b,$0e,$0e + db $00,$00,$00,$00,$00,$00,$0e,$0e,$8f,$8b,$ff,$fd,$ff,$01,$ff,$01 + db $ff,$00,$ff,$00,$ff,$00,$ff,$80,$ff,$93,$fe,$96,$fc,$dc,$70,$70 + db $ff,$01,$ff,$01,$ff,$01,$ff,$01,$ff,$c9,$7f,$4b,$7e,$6e,$38,$38 + db $00,$00,$03,$03,$07,$07,$0c,$0c,$18,$18,$18,$18,$30,$30,$30,$30 + db $00,$00,$c0,$c0,$e0,$e0,$30,$30,$18,$18,$18,$18,$0c,$0c,$0c,$0c + db $30,$30,$30,$30,$18,$18,$18,$18,$0c,$0c,$07,$07,$03,$03,$00,$00 + db $0c,$0c,$0c,$0c,$18,$18,$18,$18,$30,$30,$e0,$e0,$c0,$c0,$00,$00 +.SpriteTilesEnd: + MagicianTiles: db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 db $ff,$ff,$ff,$ff,$e0,$e0,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff diff --git a/CardHelpers.inc b/CardHelpers.inc index f84714c..9d888a5 100644 --- a/CardHelpers.inc +++ b/CardHelpers.inc @@ -1,9 +1,6 @@ ; CARD_HELPER_VARS_START defines the beginning of the $100 bytes set aside for system usage def cvCardAddress equ 0 ; location of the current card's struct - - - LoadCardData: LoadCardDataAsync: ; first and foremost, clear the card init, update, and draw handles, so there's @@ -153,6 +150,37 @@ LoadCardDataAsync: ld a, [hl+] ld [CARD_DRAW+1], a - call CARD_INIT - 1 + call CardInit ret + +CardInit: + call CARD_INIT - 1 + ret + +CardUpdate: + call CARD_UPDATE - 1 + ret + +CardDraw: + call CARD_DRAW - 1 + ret + + +IncrementTimer: + ; hl is the location in memory of a timer + ; squashes a and de + ; uses the value from rDELTAT + ld d, h + ld e, l + inc de + ld a, [rDELTAT] + add a, [hl] + ld [hl], a + ld h, d + ld l, e + ld a, [hl] + adc a, 0 + ld [hl], a + dec hl + ret \ No newline at end of file diff --git a/CopyRangeSafe.inc b/CopyRangeSafe.inc index ac732cd..5d07fff 100644 --- a/CopyRangeSafe.inc +++ b/CopyRangeSafe.inc @@ -13,6 +13,7 @@ DEF SAFE_TRANSFER_START EQU 145 DEF SAFE_TRANSFER_END EQU 153 +CopyRange: CopyRangeUnsafe: ; this is threadsafe but not vblank safe ; hl is source ; de is destination @@ -23,14 +24,16 @@ CopyRangeUnsafe: ; this is threadsafe but not vblank safe dec bc ld a, b or a, c ; check if bc is zero - jp nz, CopyRangeUnsafe + jp nz, CopyRange ret +CopyRangeBy8s: CopyRangeUnsafeBy8s: ; hl is source ; de is destination - ; bc is length to copy + ; bc is 1/8 of length to copy!!! + ; so like this will copy 8*bc bytes! ld a, [hl+] ld [de], a @@ -59,7 +62,7 @@ CopyRangeUnsafeBy8s: dec bc ld a, b or a, c ; check if bc is zero - jp nz, CopyRangeUnsafeBy8s + jp nz, CopyRangeBy8s nop nop ret \ No newline at end of file diff --git a/ScreenCardBrowse.inc b/ScreenCardBrowse.inc index ad30350..98f2a9d 100644 --- a/ScreenCardBrowse.inc +++ b/ScreenCardBrowse.inc @@ -13,43 +13,38 @@ CardBrowseSetup: ld hl, .asyncTask call Async_Spawn_HL + + ; make sure working oam is clear + ld hl, ZEROES + ld de, MY_OAM + ld bc, $100 + call CopyRange + ret -.asyncTask - ld a, HIGH(ZEROES) - ld de, SAFE_DMA_LOCATION ; arguments to the first async call. - call RunDMA - +.asyncTask: ld hl, CardBrowse.UITilemap ; origin ld de, $9800 ; destination ld b, 18 ; height ld c, 20 ; width - call CopyTilesToMapUnsafe + call CopyTilesToMap + ld a, 0 + ld [vBlocked], a call RefreshCardTask - ld a, 0 - ld [vBlocked], a ret CardBrowseUpdate: + call CardUpdate + ld hl, vTime - ld a, [rDELTAT] - ld b, a - ld a, [vTime] - add a, b - ld [vTime], a - ld a, [vTime+1] - adc a, 0 - ld [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 + call IncrementTimer ld a, [vTime+1] cp a, $01 - jp c, .doneTimer ; if the timer is less than $0100, skip to end + jp c, .doneTimer ; reset the timer and do behavior when vTime passes $0100 - ;otherwise reset the timer ld a, 0 ld [vTime], a ld [vTime+1], a @@ -118,10 +113,15 @@ CardBrowseDraw: ld bc, (SquaresTileset8 - SquaresTileset7) / 8 call CopyRangeUnsafeBy8s + ld de, SAFE_DMA_LOCATION + ld a, HIGH(MY_OAM) call RunDMA ret RefreshCardTask: + ld a, [vSelectedCardIndex] + ld [vPreviousCardIndex], a + call DrawDeckMinimap call LoadCardData ret diff --git a/ScreenCardRead.inc b/ScreenCardRead.inc index d42bf13..3a91f62 100644 --- a/ScreenCardRead.inc +++ b/ScreenCardRead.inc @@ -11,41 +11,35 @@ CardReadSetup: ld a, 1 ld [vBlocked], a - ld hl, CardReadSetupAsyncTask + ld hl, .asyncTask call Async_Spawn_HL ld hl, ZEROES ld de, MY_OAM ld bc, $100 - call CopyRangeUnsafe - + call CopyRange ret - -CardReadSetupAsyncTask: + +.asyncTask: ld hl, CardRead.UITilemap ; origin ld de, $9800 ; destination ld b, 18 ; height ld c, 20 ; width - call CopyTilesToMapUnsafe + call CopyTilesToMap + + ld a, 0 + ld [vBlocked], a call ChangedCardTask + ret CardReadUpdate: - call CARD_UPDATE - 1 - + call CardUpdate + ld hl, vTime - ld a, [rDELTAT] - ld b, a - ld a, [vTime] - add a, b - ld [vTime], a - ld a, [vTime+1] - adc a, 0 - ld [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 + call IncrementTimer ld a, [vTime+1] cp a, $01 diff --git a/SpriteTiles.asm b/SpriteTiles.asm new file mode 100644 index 0000000..a9e5837 --- /dev/null +++ b/SpriteTiles.asm @@ -0,0 +1,41 @@ + ; original export script by gabriel reis, modified by shoofle + + +SpriteTiles: + + db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + db $01,$01,$01,$01,$01,$01,$01,$01,$1f,$1f,$1f,$10,$1f,$10,$1f,$1c + db $f0,$f0,$fc,$5c,$fe,$06,$5f,$a3,$ff,$01,$ff,$00,$ff,$00,$ff,$00 + db $00,$00,$00,$00,$00,$00,$07,$07,$87,$85,$ff,$fd,$ff,$01,$ff,$01 + db $07,$07,$01,$01,$01,$01,$01,$01,$00,$00,$00,$00,$00,$00,$00,$00 + db $ff,$00,$ff,$00,$ff,$00,$ff,$80,$ff,$93,$fe,$d2,$7e,$76,$1c,$1c + db $ff,$01,$ff,$01,$ff,$01,$ff,$01,$ff,$c9,$7f,$69,$3f,$3b,$0e,$0e + db $00,$00,$00,$00,$00,$00,$0e,$0e,$8f,$8b,$ff,$fd,$ff,$01,$ff,$01 + db $ff,$00,$ff,$00,$ff,$00,$ff,$80,$ff,$93,$fe,$96,$fc,$dc,$70,$70 + db $ff,$01,$ff,$01,$ff,$01,$ff,$01,$ff,$c9,$7f,$4b,$7e,$6e,$38,$38 + db $00,$00,$03,$03,$07,$07,$0c,$0c,$18,$18,$18,$18,$30,$30,$30,$30 + db $00,$00,$c0,$c0,$e0,$e0,$30,$30,$18,$18,$18,$18,$0c,$0c,$0c,$0c + db $30,$30,$30,$30,$18,$18,$18,$18,$0c,$0c,$07,$07,$03,$03,$00,$00 + db $0c,$0c,$0c,$0c,$18,$18,$18,$18,$30,$30,$e0,$e0,$c0,$c0,$00,$00 + + + +Sprites: + db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 + db $00, $00, $00, $00, $0a, $0b, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 + db $00, $00, $00, $00, $0c, $0d, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 + db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 + db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 + db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 + db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 + db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 + db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 + db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 + db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 + db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 + db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 + db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 + db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 + db $00, $00, $00, $01, $02, $03, $01, $02, $07, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 + db $00, $00, $00, $04, $08, $06, $04, $05, $09, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 + db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 diff --git a/source.zip b/source.zip index a87f9c4e677e1cc6d4290e1638a8dd9b559edd4b..e1b807b36889be0b1a8d792913ac47d27ee4bd80 100644 GIT binary patch delta 3901 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 delta 2717 zcmZuz4RBP|6~6D@8w%^@|Hme~$-bCXU^aDsAWcHXs0bh#}u)h+Lqq)HfgfS z-rckB{(R?r=bn4+d3)xiqPL$dGPkT{+(fXsyN{cl3F_`nt=h%=7nx?}Q^&UPWDTyo zx0HY2!p{Cf?Ed~dcX#_EddL*`yqJ*Bi(z;_`z+6`>i$+u^?S55=Z3wlV5g<62|dm6ULWb9i?T zyCdb=%RD9w$eqhrtQk9Jma?cR7bEk^!E?UDIfNWeovLBiDV)56eK`E)PBT2Wm=(au z#q3`A@?usvd}UV&gqEs#oG!k&mOtF`j&ifC<$Q&C_;AMJts4fOGvUOCbs@6hy!IIy5!-r5y(JX$NOBE~(_ zE2%>p=xz!A=;US8B*XX?T5f(+z*WB=&9=kMEwl^@yz~}0yM-1nayZkgK4{rUD`EWS zA~{egKfU0KqLy7*4i~)C0V5uI(OAxNxaM08Zlt+}RrrOME@Z0TFk1B`VM=&uG8Azs zpE?z^cUG(SN5b0XK)lNv2x+>@luk$46x9RacrYyA<`W4le_PdKaxAXuaXAo^Z>yEv zO|7fjHZ`?++C1K-RQWIP0Zz=RJdTWkLskOUc?8nlrkf+dvcl*Q`rC~~x z<+URCLYB=Dml*$FOpE;OGW^g=%gYRdLfJVbicbK2@U=E1Lmg;(QYtQ)HaBJ7po35L z&>A?}Mq}VRByCE4e>**4!F0CN(>sj>zfnx>6*%+m4asiIJbzKT%SicK-jMcLajA4f z`pm$r*(<$csBaBOSB;C(?3Id35o2wXmKd17R7g%keT+*>%f!;?dw>6PAwEYgHK6in z^i&-JMt}7DJI3?lCx2OF+^pxSf739TN62K}@Y=-BB-7{@iF@3T{^nh2clbz|< zWASKNE71}%U0LD%e!g7Tg#Qe2tF<9PNUIw5M?&=?JLVwA1cIIIBXD_$<9=ZWPHa9x z;0Hq-i!e0egzJ3*4-au$b!H7Fq{t}d(?7kBNl-owo2i+EluRRx=ZG%Br31X$u$JF) zHT;ccLQocF!0Nsy!QlhEbSIL2Fnap3TWk=eFavhvyhPlQXsnnHP&h3*sMUrOzorcO z_VY?39nSwgnWtI_K@oRkR{M7~Bg%45T-U;#@vdx+zCQ4)iHQnAP%_W5f2Gh}A@;aN z(?fxHHf3*-<<;XaSO`JMOzWKwGk9x&SKo($+#LB<{7g9^D4CaJU4jv(3rR5J{Oi^5 zd>(KNaBJm?q(C;T*3@kKfNT3iP#$`Tfq8&eVw8^KM9&z53;VcbB|34l`5#MemJ))J z8KqY)3)5c_PIx2Tnx4ghMq$i$@wz~LRiHfL-IN7%^BKW7p2MMPAFsFv8Be@y`69KpMsVt1^ka4n&!{g6z%h!={rcBN~ h%@aB|Zsr;-7}fNtOOmqyy{ZwP?V{TJZZ{XB{{f1T+3^4X