summaryrefslogtreecommitdiff
path: root/engine/games
diff options
context:
space:
mode:
authorRangi <remy.oukaour+rangi42@gmail.com>2018-04-04 23:56:40 -0400
committerRangi <remy.oukaour+rangi42@gmail.com>2018-04-04 23:56:40 -0400
commit81306889e33c599f8015bc4e653929bb7de00967 (patch)
tree7a812968ba565a13ef400cdcb5230e6e8185a1ec /engine/games
parent145efc13535fbc9d8ab2786d29209d97aebf0481 (diff)
parentf750d4f4185529cfb440ac7825d202ebcf160766 (diff)
Merge branch 'master' of https://github.com/pret/pokecrystal
Diffstat (limited to 'engine/games')
-rw-r--r--engine/games/card_flip.asm1692
-rw-r--r--engine/games/dummy_game.asm612
-rw-r--r--engine/games/slot_machine.asm2352
-rw-r--r--engine/games/unown_puzzle.asm877
4 files changed, 5533 insertions, 0 deletions
diff --git a/engine/games/card_flip.asm b/engine/games/card_flip.asm
new file mode 100644
index 000000000..fbeb3e3b6
--- /dev/null
+++ b/engine/games/card_flip.asm
@@ -0,0 +1,1692 @@
+CARDFLIP_LIGHT_OFF EQU $ef
+CARDFLIP_LIGHT_ON EQU $f5
+
+CARDFLIP_DECK_SIZE EQU 4 * 6
+
+; two labels below called from inside ./dummy_game.asm
+Unknown_e00ed: ; e00ed (38:40ed)
+; Graphics for an unused Game Corner
+; game were meant to be here.
+ret_e00ed: ; e00ed (38:40ed)
+ ret
+
+_CardFlip: ; e00ee (38:40ee)
+ ld hl, wOptions
+ set 4, [hl]
+ call ClearBGPalettes
+ call ClearTileMap
+ call ClearSprites
+ ld de, MUSIC_NONE
+ call PlayMusic
+ call DelayFrame
+ call DisableLCD
+ call LoadStandardFont
+ call LoadFontsExtra
+
+ ld hl, CardFlipLZ01
+ ld de, vTiles2 tile $00
+ call Decompress
+ ld hl, CardFlipLZ02
+ ld de, vTiles2 tile $3e
+ call Decompress
+ ld hl, CardFlipLZ03
+ ld de, vTiles0 tile $00
+ call Decompress
+ ld hl, CardFlipOffButtonGFX
+ ld de, vTiles0 tile CARDFLIP_LIGHT_OFF
+ ld bc, 1 tiles
+ call CopyBytes
+ ld hl, CardFlipOnButtonGFX
+ ld de, vTiles0 tile CARDFLIP_LIGHT_ON
+ ld bc, 1 tiles
+ call CopyBytes
+
+ call CardFlip_ShiftDigitsLeftTwoPixels
+ call CardFlip_InitTilemap
+ call CardFlip_InitAttrPals
+ call EnableLCD
+ call WaitBGMap2
+ ld a, $e4
+ call DmgToCgbBGPals
+ ld de, $e4e4
+ call DmgToCgbObjPals
+ call DelayFrame
+ xor a
+ ld [wJumptableIndex], a
+ ld a, $2
+ ld [wCardFlipCursorY], a
+ ld [wCardFlipCursorX], a
+ ld de, MUSIC_GAME_CORNER
+ call PlayMusic
+.MasterLoop:
+ ld a, [wJumptableIndex]
+ bit 7, a
+ jr nz, .leavethegame
+ call .CardFlip
+ jr .MasterLoop
+.leavethegame
+ call WaitSFX
+ ld de, SFX_QUIT_SLOTS
+ call PlaySFX
+ call WaitSFX
+ call ClearBGPalettes
+ ld hl, wOptions
+ res 4, [hl]
+ ret
+
+.CardFlip: ; e0191 (38:4191)
+ ld a, [wJumptableIndex]
+ ld e, a
+ ld d, 0
+ ld hl, .Jumptable
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ jp hl
+; e01a0 (38:41a0)
+
+.Jumptable: ; e01a0
+ dw .AskPlayWithThree
+ dw .DeductCoins
+ dw .ChooseACard
+ dw .PlaceYourBet
+ dw .CheckTheCard
+ dw .TabulateTheResult
+ dw .PlayAgain
+ dw .Quit
+; e01b0
+
+.Increment: ; e01b0
+ ld hl, wJumptableIndex
+ inc [hl]
+ ret
+; e01b5
+
+.AskPlayWithThree: ; e01b5
+ ld hl, .PlayWithThreeCoinsText
+ call CardFlip_UpdateCoinBalanceDisplay
+ call YesNoBox
+ jr c, .SaidNo
+ call CardFlip_ShuffleDeck
+ call .Increment
+ ret
+
+.SaidNo:
+ ld a, 7
+ ld [wJumptableIndex], a
+ ret
+; e01cd
+
+.PlayWithThreeCoinsText: ; 0xe01cd
+ ; Play with three coins?
+ text_jump UnknownText_0x1c5793
+ db "@"
+; 0xe01d2
+
+.DeductCoins: ; e01d2
+ ld a, [wCoins]
+ ld h, a
+ ld a, [wCoins + 1]
+ ld l, a
+ ld a, h
+ and a
+ jr nz, .deduct ; You have at least 256 coins.
+ ld a, l
+ cp 3
+ jr nc, .deduct ; You have at least 3 coins.
+ ld hl, .NotEnoughCoinsText
+ call CardFlip_UpdateCoinBalanceDisplay
+ ld a, 7
+ ld [wJumptableIndex], a
+ ret
+
+.deduct
+ ld de, -3
+ add hl, de
+ ld a, h
+ ld [wCoins], a
+ ld a, l
+ ld [wCoins + 1], a
+ ld de, SFX_TRANSACTION
+ call PlaySFX
+ xor a
+ ld [hBGMapMode], a
+ call CardFlip_PrintCoinBalance
+ ld a, $1
+ ld [hBGMapMode], a
+ call WaitSFX
+ call .Increment
+ ret
+; e0212
+
+.NotEnoughCoinsText: ; 0xe0212
+ ; Not enough coins…
+ text_jump UnknownText_0x1c57ab
+ db "@"
+; 0xe0217
+
+.ChooseACard: ; e0217
+ xor a
+ ld [hBGMapMode], a
+ hlcoord 0, 0
+ lb bc, 12, 9
+ call CardFlip_FillGreenBox
+ hlcoord 9, 0
+ ld bc, SCREEN_WIDTH
+ ld a, [wCardFlipNumCardsPlayed]
+ call AddNTimes
+ ld [hl], CARDFLIP_LIGHT_ON
+ ld a, $1
+ ld [hBGMapMode], a
+ ld c, 20
+ call DelayFrames
+ hlcoord 2, 0
+ call PlaceCardFaceDown
+ ld a, $1
+ ld [hBGMapMode], a
+ ld c, 20
+ call DelayFrames
+ hlcoord 2, 6
+ call PlaceCardFaceDown
+ call WaitBGMap
+ ld hl, .ChooseACardText
+ call CardFlip_UpdateCoinBalanceDisplay
+ xor a
+ ld [wCardFlipWhichCard], a
+.loop
+ call JoyTextDelay
+ ld a, [hJoyLast]
+ and A_BUTTON
+ jr nz, .next
+ ld de, SFX_KINESIS
+ call PlaySFX
+ call PlaceOAMCardBorder
+ ld c, 4
+ call DelayFrames
+ ld hl, wCardFlipWhichCard
+ ld a, [hl]
+ xor $1
+ ld [hl], a
+ jr .loop
+
+.next
+ ld de, SFX_SLOT_MACHINE_START
+ call PlaySFX
+ ld a, $3
+.loop2
+ push af
+ call PlaceOAMCardBorder
+ ld c, 4
+ call DelayFrames
+ call ClearSprites
+ ld c, 4
+ call DelayFrames
+ pop af
+ dec a
+ jr nz, .loop2
+ ld hl, wCardFlipWhichCard
+ ld a, [hl]
+ push af
+ xor $1
+ ld [hl], a
+ call GetCoordsOfChosenCard
+ lb bc, 6, 5
+ call CardFlip_FillGreenBox
+ pop af
+ ld [wCardFlipWhichCard], a
+ call .Increment
+ ret
+; e02b2
+
+.ChooseACardText: ; 0xe02b2
+ ; Choose a card.
+ text_jump UnknownText_0x1c57be
+ db "@"
+; 0xe02b7
+
+.PlaceYourBet: ; e02b7
+ ld hl, .PlaceYourBetText
+ call CardFlip_UpdateCoinBalanceDisplay
+.betloop
+ call JoyTextDelay
+ ld a, [hJoyLast]
+ and A_BUTTON
+ jr nz, .betdone
+ call ChooseCard_HandleJoypad
+ call CardFlip_UpdateCursorOAM
+ call DelayFrame
+ jr .betloop
+
+.betdone
+ call .Increment
+ ret
+; e02d5
+
+.PlaceYourBetText: ; 0xe02d5
+ ; Place your bet.
+ text_jump UnknownText_0x1c57ce
+ db "@"
+; 0xe02da
+
+.CheckTheCard: ; e02da
+ xor a
+ ld [hVBlankCounter], a
+ call CardFlip_UpdateCursorOAM
+ call WaitSFX
+ ld de, SFX_CHOOSE_A_CARD
+ call PlaySFX
+ call WaitSFX
+ ld a, [wCardFlipNumCardsPlayed]
+ ld e, a
+ ld d, 0
+ ld hl, wDeck
+ add hl, de
+ add hl, de
+ ld a, [wCardFlipWhichCard]
+ ld e, a
+ add hl, de
+ ld a, [hl]
+ ld [wCardFlipFaceUpCard], a
+ ld e, a
+ ld hl, wDiscardPile
+ add hl, de
+ ld [hl], TRUE
+ call GetCoordsOfChosenCard
+ call CardFlip_DisplayCardFaceUp
+ call WaitBGMap2
+ call .Increment
+ ret
+; e0314
+
+.TabulateTheResult: ; e0314
+ call CardFlip_CheckWinCondition
+ call WaitPressAorB_BlinkCursor
+ call .Increment
+ ret
+; e031e
+
+.PlayAgain: ; e031e
+ call ClearSprites
+ ld hl, .PlayAgainText
+ call CardFlip_UpdateCoinBalanceDisplay
+ call YesNoBox
+ jr nc, .Continue
+ call .Increment
+ ret
+
+.Continue:
+ ld a, [wCardFlipNumCardsPlayed]
+ inc a
+ ld [wCardFlipNumCardsPlayed], a
+ cp 12
+ jr c, .KeepTheCurrentDeck
+ call CardFlip_InitTilemap
+ ld a, $1
+ ld [hBGMapMode], a
+ call CardFlip_ShuffleDeck
+ ld hl, .CardsShuffledText
+ call PrintText
+ jr .LoopAround
+
+.KeepTheCurrentDeck:
+ call CardFlip_BlankDiscardedCardSlot
+
+.LoopAround:
+ ld a, 1
+ ld [wJumptableIndex], a
+ ret
+; e0356
+
+.PlayAgainText: ; 0xe0356
+ ; Want to play again?
+ text_jump UnknownText_0x1c57df
+ db "@"
+; 0xe035b
+
+.CardsShuffledText: ; 0xe035b
+ ; The cards have been shuffled.
+ text_jump UnknownText_0x1c57f4
+ db "@"
+; 0xe0360
+
+.Quit: ; e0360
+ ld hl, wJumptableIndex
+ set 7, [hl]
+ ret
+; e0366
+
+CardFlip_ShuffleDeck: ; e0366
+ ld hl, wDeck
+ ld bc, CARDFLIP_DECK_SIZE
+ xor a
+ call ByteFill
+ ld de, wDeck
+ ld c, CARDFLIP_DECK_SIZE - 1
+.loop
+ call Random
+ and $1f
+ cp CARDFLIP_DECK_SIZE
+ jr nc, .loop
+ ld l, a
+ ld h, $0
+ add hl, de
+ ld a, [hl]
+ and a
+ jr nz, .loop
+ ld [hl], c
+ dec c
+ jr nz, .loop
+ xor a
+ ld [wCardFlipNumCardsPlayed], a
+ ld hl, wDiscardPile
+ ld bc, CARDFLIP_DECK_SIZE
+ call ByteFill
+ ret
+; e0398
+
+CollapseCursorPosition: ; e0398
+ ld hl, 0
+ ld bc, 6
+ ld a, [wCardFlipCursorY]
+ call AddNTimes
+ ld b, $0
+ ld a, [wCardFlipCursorX]
+ ld c, a
+ add hl, bc
+ ret
+; e03ac
+
+GetCoordsOfChosenCard: ; e03ac
+ ld a, [wCardFlipWhichCard]
+ and a
+ jr nz, .BottomCard
+ hlcoord 2, 0
+ bcpixel 2, 3
+ jr .done
+
+.BottomCard:
+ hlcoord 2, 6
+ bcpixel 8, 3
+
+.done
+ ret
+; e03c1
+
+PlaceCardFaceDown: ; e03c1
+ xor a
+ ld [hBGMapMode], a
+ ld de, .FaceDownCardTilemap
+ lb bc, 6, 5
+ call CardFlip_CopyToBox
+ ret
+; e03ce
+
+.FaceDownCardTilemap: ; e03ce
+ db $08, $09, $09, $09, $0a
+ db $0b, $28, $2b, $28, $0c
+ db $0b, $2c, $2d, $2e, $0c
+ db $0b, $2f, $30, $31, $0c
+ db $0b, $32, $33, $34, $0c
+ db $0d, $0e, $0e, $0e, $0f
+; e03ec
+
+CardFlip_DisplayCardFaceUp: ; e03ec
+ xor a
+ ld [hBGMapMode], a
+ push hl
+ push hl
+ ; Flip the card face up.
+ ld de, .FaceUpCardTilemap
+ lb bc, 6, 5
+ call CardFlip_CopyToBox
+
+ ; Get the level and species of the upturned card.
+ ld a, [wCardFlipFaceUpCard]
+ ld e, a
+ ld d, 0
+ ld hl, .Deck
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld e, a
+ ld d, [hl]
+
+ ; Place the level.
+ pop hl
+ ld bc, 3 + SCREEN_WIDTH
+ add hl, bc
+ ld [hl], e
+
+ ; Place the Pokepic.
+ ld bc, SCREEN_HEIGHT
+ add hl, bc
+ ld a, d
+ ld de, SCREEN_WIDTH
+ ld b, 3
+.row
+ push hl
+ ld c, 3
+.col
+ ld [hli], a
+ inc a
+ dec c
+ jr nz, .col
+ pop hl
+ add hl, de
+ dec b
+ jr nz, .row
+ pop hl
+
+ ; Pointless CGB check
+ ld a, [hCGB]
+ and a
+ ret z
+
+ ; Set the attributes
+ ld de, wAttrMap - wTileMap
+ add hl, de
+ ld a, [wCardFlipFaceUpCard]
+ and 3
+ inc a
+ lb bc, 6, 5
+ call CardFlip_FillBox
+ ret
+; e043b
+
+.FaceUpCardTilemap: ; e043b
+ db $18, $19, $19, $19, $1a
+ db $1b, $35, $7f, $7f, $1c
+ db $0b, $28, $28, $28, $0c
+ db $0b, $28, $28, $28, $0c
+ db $0b, $28, $28, $28, $0c
+ db $1d, $1e, $1e, $1e, $1f
+; e0459
+
+.Deck: ; e0459
+ ; level, pic anchor (3x3)
+ db "1", $4e, "1", $57, "1", $69, "1", $60
+ db "2", $4e, "2", $57, "2", $69, "2", $60
+ db "3", $4e, "3", $57, "3", $69, "3", $60
+ db "4", $4e, "4", $57, "4", $69, "4", $60
+ db "5", $4e, "5", $57, "5", $69, "5", $60
+ db "6", $4e, "6", $57, "6", $69, "6", $60
+; e0489
+
+CardFlip_UpdateCoinBalanceDisplay: ; e0489
+ push hl
+ hlcoord 0, 12
+ ld b, 4
+ ld c, SCREEN_WIDTH - 2
+ call TextBox
+ pop hl
+ call PrintTextBoxText
+ call CardFlip_PrintCoinBalance
+ ret
+; e049c
+
+CardFlip_PrintCoinBalance: ; e049c
+ hlcoord 9, 15
+ ld b, 1
+ ld c, 9
+ call TextBox
+ hlcoord 10, 16
+ ld de, .CoinStr
+ call PlaceString
+ hlcoord 15, 16
+ ld de, wCoins
+ lb bc, PRINTNUM_LEADINGZEROS | 2, 4
+ call PrintNum
+ ret
+; e04bc
+
+.CoinStr:
+ db "COIN@"
+; e04c1
+
+CardFlip_InitTilemap: ; e04c1 (38:44c1)
+ xor a
+ ld [hBGMapMode], a
+ hlcoord 0, 0
+ ld bc, SCREEN_HEIGHT * SCREEN_WIDTH
+ ld a, $29
+ call ByteFill
+ hlcoord 9, 0
+ ld de, CardFlipTilemap
+ lb bc, 12, 11
+ call CardFlip_CopyToBox
+ hlcoord 0, 12
+ lb bc, 4, 18
+ call TextBox
+ ret
+; e04e5 (38:44e5)
+
+CardFlip_FillGreenBox: ; e04e5
+ ld a, $29
+
+CardFlip_FillBox: ; e04e7 (38:44e7)
+.row
+ push bc
+ push hl
+.col
+ ld [hli], a
+ dec c
+ jr nz, .col
+ pop hl
+ ld bc, SCREEN_WIDTH
+ add hl, bc
+ pop bc
+ dec b
+ jr nz, .row
+ ret
+
+CardFlip_CopyToBox: ; e04f7 (38:44f7)
+.row
+ push bc
+ push hl
+.col
+ ld a, [de]
+ inc de
+ ld [hli], a
+ dec c
+ jr nz, .col
+ pop hl
+ ld bc, SCREEN_WIDTH
+ add hl, bc
+ pop bc
+ dec b
+ jr nz, .row
+ ret
+; e0509 (38:4509)
+
+CardFlip_CopyOAM: ; e0509
+ ld de, wVirtualOAMSprite00
+ ld a, [hli]
+.loop
+ push af
+ ld a, [hli]
+ add b
+ ld [de], a ; y
+ inc de
+ ld a, [hli]
+ add c
+ ld [de], a ; x
+ inc de
+ ld a, [hli]
+ ld [de], a ; tile id
+ inc de
+ ld a, [hli]
+ ld [de], a ; attributes
+ inc de
+ pop af
+ dec a
+ jr nz, .loop
+ ret
+; e0521
+
+CardFlip_ShiftDigitsLeftTwoPixels: ; e0521 (38:4521)
+ ld de, vTiles0 tile "0"
+ ld hl, vTiles0 tile "0" + 2
+ ld bc, 10 tiles - 2
+ call CopyBytes
+ ld hl, vTiles0 tile "9" + 1 tiles - 2
+ xor a
+ ld [hli], a
+ ld [hl], a
+ ret
+; e0534 (38:4534)
+
+CardFlip_BlankDiscardedCardSlot: ; e0534
+ xor a
+ ld [hBGMapMode], a
+ ld a, [wCardFlipFaceUpCard]
+ ld e, a
+ ld d, 0
+
+ and 3 ; get mon
+ ld c, a
+ ld b, 0
+
+ ld a, e
+ and $1c ; get level
+ srl a
+ add LOW(.Jumptable)
+ ld l, a
+ ld a, 0
+ adc HIGH(.Jumptable)
+ ld h, a
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ jp hl
+; e0553
+
+.Jumptable: ; e0553
+ dw .Level1
+ dw .Level2
+ dw .Level3
+ dw .Level4
+ dw .Level5
+ dw .Level6
+; e055f
+
+.Level1: ; e055f
+ ld hl, wDiscardPile + 4
+ add hl, de
+ ld a, [hl]
+ and a
+ jr nz, .discarded2
+ hlcoord 13, 3
+ add hl, bc
+ add hl, bc
+ ld [hl], $36
+ ld bc, SCREEN_WIDTH
+ add hl, bc
+ ld [hl], $37
+ ret
+
+.discarded2
+ hlcoord 13, 3
+ add hl, bc
+ add hl, bc
+ ld [hl], $36
+ ld bc, SCREEN_WIDTH
+ add hl, bc
+ ld [hl], $3d
+ ret
+; e0583
+
+.Level2: ; e0583
+ ld hl, wDiscardPile - 4
+ add hl, de
+ ld a, [hl]
+ and a
+ jr nz, .discarded1
+ hlcoord 13, 4
+ add hl, bc
+ add hl, bc
+ ld [hl], $3b
+ ld bc, SCREEN_WIDTH
+ add hl, bc
+ ld [hl], $3a
+ ret
+
+.discarded1
+ hlcoord 13, 4
+ add hl, bc
+ add hl, bc
+ ld [hl], $3d
+ ld bc, SCREEN_WIDTH
+ add hl, bc
+ ld [hl], $3a
+ ret
+; e05a7
+
+.Level3: ; e05a7
+ ld hl, wDiscardPile + 4
+ add hl, de
+ ld a, [hl]
+ and a
+ jr nz, .discarded4
+ hlcoord 13, 6
+ add hl, bc
+ add hl, bc
+ ld [hl], $36
+ ld bc, SCREEN_WIDTH
+ add hl, bc
+ ld [hl], $38
+ ret
+
+.discarded4
+ hlcoord 13, 6
+ add hl, bc
+ add hl, bc
+ ld [hl], $36
+ ld bc, SCREEN_WIDTH
+ add hl, bc
+ ld [hl], $3d
+ ret
+; e05cb
+
+.Level4: ; e05cb
+ ld hl, wDiscardPile - 4
+ add hl, de
+ ld a, [hl]
+ and a
+ jr nz, .discarded3
+ hlcoord 13, 7
+ add hl, bc
+ add hl, bc
+ ld [hl], $3c
+ ld bc, SCREEN_WIDTH
+ add hl, bc
+ ld [hl], $3a
+ ret
+
+.discarded3
+ hlcoord 13, 7
+ add hl, bc
+ add hl, bc
+ ld [hl], $3d
+ ld bc, SCREEN_WIDTH
+ add hl, bc
+ ld [hl], $3a
+ ret
+; e05ef
+
+.Level5: ; e05ef
+ ld hl, wDiscardPile + 4
+ add hl, de
+ ld a, [hl]
+ and a
+ jr nz, .discarded6
+ hlcoord 13, 9
+ add hl, bc
+ add hl, bc
+ ld [hl], $36
+ ld bc, SCREEN_WIDTH
+ add hl, bc
+ ld [hl], $39
+ ret
+
+.discarded6
+ hlcoord 13, 9
+ add hl, bc
+ add hl, bc
+ ld [hl], $36
+ ld bc, SCREEN_WIDTH
+ add hl, bc
+ ld [hl], $3d
+ ret
+; e0613
+
+.Level6: ; e0613
+ ld hl, wDiscardPile - 4
+ add hl, de
+ ld a, [hl]
+ and a
+ jr nz, .discarded5
+ hlcoord 13, 10
+ add hl, bc
+ add hl, bc
+ ld [hl], $3c
+ ld bc, SCREEN_WIDTH
+ add hl, bc
+ ld [hl], $3a
+ ret
+
+.discarded5
+ hlcoord 13, 10
+ add hl, bc
+ add hl, bc
+ ld [hl], $3d
+ ld bc, SCREEN_WIDTH
+ add hl, bc
+ ld [hl], $3a
+ ret
+; e0637
+
+CardFlip_CheckWinCondition: ; e0637
+ call CollapseCursorPosition
+ add hl, hl
+ ld de, .Jumptable
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ jp hl
+; e0643
+
+.Jumptable: ; e0643
+ dw .Impossible
+ dw .Impossible
+ dw .PikaJiggly
+ dw .PikaJiggly
+ dw .PoliOddish
+ dw .PoliOddish
+
+ dw .Impossible
+ dw .Impossible
+ dw .Pikachu
+ dw .Jigglypuff
+ dw .Poliwag
+ dw .Oddish
+
+ dw .OneTwo
+ dw .One
+ dw .PikaOne
+ dw .JigglyOne
+ dw .PoliOne
+ dw .OddOne
+
+ dw .OneTwo
+ dw .Two
+ dw .PikaTwo
+ dw .JigglyTwo
+ dw .PoliTwo
+ dw .OddTwo
+
+ dw .ThreeFour
+ dw .Three
+ dw .PikaThree
+ dw .JigglyThree
+ dw .PoliThree
+ dw .OddThree
+
+ dw .ThreeFour
+ dw .Four
+ dw .PikaFour
+ dw .JigglyFour
+ dw .PoliFour
+ dw .OddFour
+
+ dw .FiveSix
+ dw .Five
+ dw .PikaFive
+ dw .JigglyFive
+ dw .PoliFive
+ dw .OddFive
+
+ dw .FiveSix
+ dw .Six
+ dw .PikaSix
+ dw .JigglySix
+ dw .PoliSix
+ dw .OddSix
+; e06a3
+
+.Impossible: ; e06a3
+ jp .Lose
+; e06a6
+
+.PikaJiggly: ; e06a6
+ ld a, [wCardFlipFaceUpCard]
+ and $2
+ jp nz, .Lose
+ jr .WinSix
+
+.PoliOddish: ; e06b0
+ ld a, [wCardFlipFaceUpCard]
+ and $2
+ jr nz, .WinSix
+ jp .Lose
+
+.WinSix: ; e06ba
+ ld c, $6
+ ld de, SFX_2ND_PLACE
+ jp .Payout
+; e06c2
+
+.OneTwo: ; e06c2
+ ld a, [wCardFlipFaceUpCard]
+ and $18
+ jr z, .WinNine
+ jp .Lose
+
+.ThreeFour: ; e06cc
+ ld a, [wCardFlipFaceUpCard]
+ and $18
+ cp $8
+ jr z, .WinNine
+ jp .Lose
+
+.FiveSix: ; e06d8
+ ld a, [wCardFlipFaceUpCard]
+ and $18
+ cp $10
+ jr z, .WinNine
+ jp .Lose
+
+.WinNine: ; e06e4
+ ld c, $9
+ ld de, SFX_2ND_PLACE
+ jp .Payout
+; e06ec
+
+.Pikachu: ; e06ec
+ ld a, [wCardFlipFaceUpCard]
+ and $3
+ jr z, .WinTwelve
+ jp .Lose
+
+.Jigglypuff: ; e06f6
+ ld a, [wCardFlipFaceUpCard]
+ and $3
+ cp $1
+ jr z, .WinTwelve
+ jp .Lose
+
+.Poliwag: ; e0702
+ ld a, [wCardFlipFaceUpCard]
+ and $3
+ cp $2
+ jr z, .WinTwelve
+ jp .Lose
+
+.Oddish: ; e070e
+ ld a, [wCardFlipFaceUpCard]
+ and $3
+ cp $3
+ jr z, .WinTwelve
+ jp .Lose
+
+.WinTwelve: ; e071a
+ ld c, $c
+ ld de, SFX_2ND_PLACE
+ jp .Payout
+; e0722
+
+.One: ; e0722
+ ld a, [wCardFlipFaceUpCard]
+ and $1c
+ jr z, .WinEighteen
+ jp .Lose
+
+.Two: ; e072c
+ ld a, [wCardFlipFaceUpCard]
+ and $1c
+ cp $4
+ jr z, .WinEighteen
+ jp .Lose
+
+.Three: ; e0738
+ ld a, [wCardFlipFaceUpCard]
+ and $1c
+ cp $8
+ jr z, .WinEighteen
+ jp .Lose
+
+.Four: ; e0744
+ ld a, [wCardFlipFaceUpCard]
+ and $1c
+ cp $c
+ jr z, .WinEighteen
+ jp .Lose
+
+.Five: ; e0750
+ ld a, [wCardFlipFaceUpCard]
+ and $1c
+ cp $10
+ jr z, .WinEighteen
+ jp .Lose
+
+.Six: ; e075c
+ ld a, [wCardFlipFaceUpCard]
+ and $1c
+ cp $14
+ jr z, .WinEighteen
+ jp .Lose
+
+.WinEighteen: ; e0768
+ ld c, $12
+ ld de, SFX_2ND_PLACE
+ jp .Payout
+; e0770
+
+
+.PikaOne: ; e0770
+ ld e, $0
+ jr .CheckWin72
+
+.JigglyOne: ; e0774
+ ld e, $1
+ jr .CheckWin72
+
+.PoliOne: ; e0778
+ ld e, $2
+ jr .CheckWin72
+
+.OddOne: ; e077c
+ ld e, $3
+ jr .CheckWin72
+
+.PikaTwo: ; e0780
+ ld e, $4
+ jr .CheckWin72
+
+.JigglyTwo: ; e0784
+ ld e, $5
+ jr .CheckWin72
+
+.PoliTwo: ; e0788
+ ld e, $6
+ jr .CheckWin72
+
+.OddTwo: ; e078c
+ ld e, $7
+ jr .CheckWin72
+
+.PikaThree: ; e0790
+ ld e, $8
+ jr .CheckWin72
+
+.JigglyThree: ; e0794
+ ld e, $9
+ jr .CheckWin72
+
+.PoliThree: ; e0798
+ ld e, $a
+ jr .CheckWin72
+
+.OddThree: ; e079c
+ ld e, $b
+ jr .CheckWin72
+
+.PikaFour: ; e07a0
+ ld e, $c
+ jr .CheckWin72
+
+.JigglyFour: ; e07a4
+ ld e, $d
+ jr .CheckWin72
+
+.PoliFour: ; e07a8
+ ld e, $e
+ jr .CheckWin72
+
+.OddFour: ; e07ac
+ ld e, $f
+ jr .CheckWin72
+
+.PikaFive: ; e07b0
+ ld e, $10
+ jr .CheckWin72
+
+.JigglyFive: ; e07b4
+ ld e, $11
+ jr .CheckWin72
+
+.PoliFive: ; e07b8
+ ld e, $12
+ jr .CheckWin72
+
+.OddFive: ; e07bc
+ ld e, $13
+ jr .CheckWin72
+
+.PikaSix: ; e07c0
+ ld e, $14
+ jr .CheckWin72
+
+.JigglySix: ; e07c4
+ ld e, $15
+ jr .CheckWin72
+
+.PoliSix: ; e07c8
+ ld e, $16
+ jr .CheckWin72
+
+.OddSix: ; e07cc
+ ld e, $17
+
+.CheckWin72: ; e07ce
+ ld a, [wCardFlipFaceUpCard]
+ cp e
+ jr nz, .Lose
+ ld c, 72
+ ld de, SFX_2ND_PLACE
+ jr .Payout
+
+.Lose: ; e07db
+ ld de, SFX_WRONG
+ call PlaySFX
+ ld hl, .Text_Darn
+ call CardFlip_UpdateCoinBalanceDisplay
+ call WaitSFX
+ ret
+
+.Payout: ; e07eb
+ push bc
+ push de
+ ld hl, .Text_Yeah
+ call CardFlip_UpdateCoinBalanceDisplay
+ pop de
+ call PlaySFX
+ call WaitSFX
+ pop bc
+.loop
+ push bc
+ call .IsCoinCaseFull
+ jr c, .full
+ call .AddCoinPlaySFX
+
+.full
+ call CardFlip_PrintCoinBalance
+ ld c, 2
+ call DelayFrames
+ pop bc
+ dec c
+ jr nz, .loop
+ ret
+; e0811
+
+.Text_Yeah: ; 0xe0811
+ ; Yeah!
+ text_jump UnknownText_0x1c5813
+ db "@"
+; 0xe0816
+
+.Text_Darn: ; 0xe0816
+ ; Darn…
+ text_jump UnknownText_0x1c581a
+ db "@"
+; 0xe081b
+
+.AddCoinPlaySFX: ; e081b
+ ld a, [wCoins]
+ ld h, a
+ ld a, [wCoins + 1]
+ ld l, a
+ inc hl
+ ld a, h
+ ld [wCoins], a
+ ld a, l
+ ld [wCoins + 1], a
+ ld de, SFX_PAY_DAY
+ call PlaySFX
+ ret
+; e0833
+
+.IsCoinCaseFull: ; e0833
+ ld a, [wCoins]
+ cp HIGH(MAX_COINS)
+ jr c, .less
+ jr z, .check_low
+ jr .more
+
+.check_low
+ ld a, [wCoins + 1]
+ cp LOW(MAX_COINS)
+ jr c, .less
+
+.more
+ scf
+ ret
+
+.less
+ and a
+ ret
+; e0849
+
+PlaceOAMCardBorder: ; e0849
+ call GetCoordsOfChosenCard
+ ld hl, .SpriteData
+ call CardFlip_CopyOAM
+ ret
+; e0853
+
+.SpriteData: ; e0853
+ db 18
+ dsprite 0, 0, 0, 0, $04, 0
+ dsprite 0, 0, 1, 0, $06, 0
+ dsprite 0, 0, 2, 0, $06, 0
+ dsprite 0, 0, 3, 0, $06, 0
+ dsprite 0, 0, 4, 0, $04, 0 | X_FLIP
+
+ dsprite 1, 0, 0, 0, $05, 0
+ dsprite 1, 0, 4, 0, $05, 0 | X_FLIP
+
+ dsprite 2, 0, 0, 0, $05, 0
+ dsprite 2, 0, 4, 0, $05, 0 | X_FLIP
+
+ dsprite 3, 0, 0, 0, $05, 0
+ dsprite 3, 0, 4, 0, $05, 0 | X_FLIP
+
+ dsprite 4, 0, 0, 0, $05, $00
+ dsprite 4, 0, 4, 0, $05, 0 | X_FLIP
+
+ dsprite 5, 0, 0, 0, $04, 0 | Y_FLIP
+ dsprite 5, 0, 1, 0, $06, 0 | Y_FLIP
+ dsprite 5, 0, 2, 0, $06, 0 | Y_FLIP
+ dsprite 5, 0, 3, 0, $06, 0 | Y_FLIP
+ dsprite 5, 0, 4, 0, $04, 0 | X_FLIP | Y_FLIP
+; e089c
+
+ChooseCard_HandleJoypad: ; e089c
+ ld hl, hJoyLast
+ ld a, [hl]
+ and D_LEFT
+ jp nz, .d_left
+ ld a, [hl]
+ and D_RIGHT
+ jp nz, .d_right
+ ld a, [hl]
+ and D_UP
+ jp nz, .d_up
+ ld a, [hl]
+ and D_DOWN
+ jp nz, .d_down
+ ret
+; e08b8
+
+.d_left ; e08b8
+ ld hl, wCardFlipCursorX
+ ld a, [wCardFlipCursorY]
+ and a
+ jr z, .mon_pair_left
+ cp $1
+ jr z, .mon_group_left
+ ld a, [hl]
+ and a
+ ret z
+ dec [hl]
+ jp .play_sound
+
+.mon_group_left
+ ld a, [hl]
+ cp $3
+ jr c, .left_to_number_gp
+ dec [hl]
+ jp .play_sound
+
+.mon_pair_left
+ ld a, [hl]
+ and $e
+ ld [hl], a
+ cp $3
+ jr c, .left_to_number_gp
+ dec [hl]
+ dec [hl]
+ jp .play_sound
+
+.left_to_number_gp
+ ld a, $2
+ ld [wCardFlipCursorY], a
+ ld a, $1
+ ld [wCardFlipCursorX], a
+ jp .play_sound
+; e08ef
+
+.d_right ; e08ef
+ ld hl, wCardFlipCursorX
+ ld a, [wCardFlipCursorY]
+ and a
+ jr z, .mon_pair_right
+ ld a, [hl]
+ cp $5
+ ret nc
+ inc [hl]
+ jr .play_sound
+
+.mon_pair_right
+ ld a, [hl]
+ and $e
+ ld [hl], a
+ cp $4
+ ret nc
+ inc [hl]
+ inc [hl]
+ jr .play_sound
+
+.d_up ; e090a
+ ld hl, wCardFlipCursorY
+ ld a, [wCardFlipCursorX]
+ and a
+ jr z, .num_pair_up
+ cp $1
+ jr z, .num_gp_up
+ ld a, [hl]
+ and a
+ ret z
+ dec [hl]
+ jr .play_sound
+
+.num_gp_up
+ ld a, [hl]
+ cp $3
+ jr c, .up_to_mon_group
+ dec [hl]
+ jr .play_sound
+
+.num_pair_up
+ ld a, [hl]
+ and $e
+ ld [hl], a
+ cp $3
+ jr c, .up_to_mon_group
+ dec [hl]
+ dec [hl]
+ jr .play_sound
+
+.up_to_mon_group
+ ld a, $1
+ ld [wCardFlipCursorY], a
+ ld a, $2
+ ld [wCardFlipCursorX], a
+ jr .play_sound
+
+.d_down ; e093d
+ ld hl, wCardFlipCursorY
+ ld a, [wCardFlipCursorX]
+ and a
+ jr z, .num_pair_down
+ ld hl, wCardFlipCursorY
+ ld a, [hl]
+ cp $7
+ ret nc
+ inc [hl]
+ jr .play_sound
+
+.num_pair_down
+ ld a, [hl]
+ and $e
+ ld [hl], a
+ cp $6
+ ret nc
+ inc [hl]
+ inc [hl]
+
+.play_sound ; e0959
+ ld de, SFX_POKEBALLS_PLACED_ON_TABLE
+ call PlaySFX
+ ret
+; e0960
+
+CardFlip_UpdateCursorOAM: ; e0960
+ call ClearSprites
+ ld a, [hCGB]
+ and a
+ jr nz, .skip
+ ld a, [hVBlankCounter]
+ and $4
+ ret nz
+
+.skip
+ call CollapseCursorPosition
+ add hl, hl
+ add hl, hl
+ ld de, .OAMData
+ add hl, de
+ ld a, [hli]
+ ld c, a
+ ld a, [hli]
+ ld b, a
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ call CardFlip_CopyOAM
+ ret
+; e0981
+
+.OAMData: ; e0981
+cardflip_cursor: MACRO
+if _NARG >= 5
+ dbpixel \1, \2, \3, \4
+ dw \5
+else
+ dbpixel \1, \2
+ dw \3
+endc
+ENDM
+
+ cardflip_cursor 11, 2, .Impossible
+ cardflip_cursor 12, 2, .Impossible
+ cardflip_cursor 13, 2, .PokeGroupPair
+ cardflip_cursor 13, 2, .PokeGroupPair
+ cardflip_cursor 17, 2, .PokeGroupPair
+ cardflip_cursor 17, 2, .PokeGroupPair
+
+ cardflip_cursor 11, 3, .Impossible
+ cardflip_cursor 12, 3, .Impossible
+ cardflip_cursor 13, 3, .PokeGroup
+ cardflip_cursor 15, 3, .PokeGroup
+ cardflip_cursor 17, 3, .PokeGroup
+ cardflip_cursor 19, 3, .PokeGroup
+
+ cardflip_cursor 11, 5, .NumGroupPair
+ cardflip_cursor 12, 5, .NumGroup
+ cardflip_cursor 13, 5, .SingleTile
+ cardflip_cursor 15, 5, .SingleTile
+ cardflip_cursor 17, 5, .SingleTile
+ cardflip_cursor 19, 5, .SingleTile
+
+ cardflip_cursor 11, 5, .NumGroupPair
+ cardflip_cursor 12, 6, 0, 4, .NumGroup
+ cardflip_cursor 13, 6, 0, 4, .SingleTile
+ cardflip_cursor 15, 6, 0, 4, .SingleTile
+ cardflip_cursor 17, 6, 0, 4, .SingleTile
+ cardflip_cursor 19, 6, 0, 4, .SingleTile
+
+ cardflip_cursor 11, 8, .NumGroupPair
+ cardflip_cursor 12, 8, .NumGroup
+ cardflip_cursor 13, 8, .SingleTile
+ cardflip_cursor 15, 8, .SingleTile
+ cardflip_cursor 17, 8, .SingleTile
+ cardflip_cursor 19, 8, .SingleTile
+
+ cardflip_cursor 11, 8, .NumGroupPair
+ cardflip_cursor 12, 9, 0, 4, .NumGroup
+ cardflip_cursor 13, 9, 0, 4, .SingleTile
+ cardflip_cursor 15, 9, 0, 4, .SingleTile
+ cardflip_cursor 17, 9, 0, 4, .SingleTile
+ cardflip_cursor 19, 9, 0, 4, .SingleTile
+
+ cardflip_cursor 11, 11, .NumGroupPair
+ cardflip_cursor 12, 11, .NumGroup
+ cardflip_cursor 13, 11, .SingleTile
+ cardflip_cursor 15, 11, .SingleTile
+ cardflip_cursor 17, 11, .SingleTile
+ cardflip_cursor 19, 11, .SingleTile
+
+ cardflip_cursor 11, 11, .NumGroupPair
+ cardflip_cursor 12, 12, 0, 4, .NumGroup
+ cardflip_cursor 13, 12, 0, 4, .SingleTile
+ cardflip_cursor 15, 12, 0, 4, .SingleTile
+ cardflip_cursor 17, 12, 0, 4, .SingleTile
+ cardflip_cursor 19, 12, 0, 4, .SingleTile
+; e0a41
+
+.SingleTile: ; e0a41
+ db 6
+ dsprite 0, 0, -1, 7, $00, 0 | PRIORITY
+ dsprite 0, 0, 0, 0, $02, 0 | PRIORITY
+ dsprite 0, 0, 1, 0, $03, 0 | PRIORITY
+ dsprite 0, 5, -1, 7, $00, 0 | Y_FLIP | PRIORITY
+ dsprite 0, 5, 0, 0, $02, 0 | Y_FLIP | PRIORITY
+ dsprite 0, 5, 1, 0, $03, 0 | PRIORITY
+
+.PokeGroup: ; e0a5a
+ db 26
+ dsprite 0, 0, -1, 7, $00, 0 | PRIORITY
+ dsprite 0, 0, 0, 0, $02, 0 | PRIORITY
+ dsprite 0, 0, 1, 0, $00, 0 | X_FLIP | PRIORITY
+ dsprite 1, 0, -1, 7, $01, 0 | PRIORITY
+ dsprite 1, 0, 1, 0, $01, 0 | X_FLIP | PRIORITY
+ dsprite 2, 0, -1, 7, $01, 0 | PRIORITY
+ dsprite 2, 0, 1, 0, $03, 0 | PRIORITY
+ dsprite 3, 0, -1, 7, $01, 0 | PRIORITY
+ dsprite 3, 0, 1, 0, $03, 0 | PRIORITY
+ dsprite 4, 0, -1, 7, $01, 0 | PRIORITY
+ dsprite 4, 0, 1, 0, $03, 0 | PRIORITY
+ dsprite 5, 0, -1, 7, $01, 0 | PRIORITY
+ dsprite 5, 0, 1, 0, $03, 0 | PRIORITY
+ dsprite 6, 0, -1, 7, $01, 0 | PRIORITY
+ dsprite 6, 0, 1, 0, $03, 0 | PRIORITY
+ dsprite 7, 0, -1, 7, $01, 0 | PRIORITY
+ dsprite 7, 0, 1, 0, $03, 0 | PRIORITY
+ dsprite 8, 0, -1, 7, $01, 0 | PRIORITY
+ dsprite 8, 0, 1, 0, $03, 0 | PRIORITY
+ dsprite 9, 0, -1, 7, $01, 0 | PRIORITY
+ dsprite 9, 0, 1, 0, $03, 0 | PRIORITY
+ dsprite 10, 0, -1, 7, $01, 0 | PRIORITY
+ dsprite 10, 0, 1, 0, $03, 0 | PRIORITY
+ dsprite 10, 1, -1, 7, $00, 0 | Y_FLIP | PRIORITY
+ dsprite 10, 1, 0, 0, $02, 0 | Y_FLIP | PRIORITY
+ dsprite 10, 1, 1, 0, $03, 0 | PRIORITY
+
+.NumGroup: ; e0ac3
+ db 20
+ dsprite 0, 0, -1, 7, $00, 0 | PRIORITY
+ dsprite 0, 0, 0, 0, $02, 0 | PRIORITY
+ dsprite 0, 0, 1, 0, $02, 0 | PRIORITY
+ dsprite 0, 0, 2, 0, $03, 0 | PRIORITY
+ dsprite 0, 0, 3, 0, $02, 0 | PRIORITY
+ dsprite 0, 0, 4, 0, $03, 0 | PRIORITY
+ dsprite 0, 0, 5, 0, $02, 0 | PRIORITY
+ dsprite 0, 0, 6, 0, $03, 0 | PRIORITY
+ dsprite 0, 0, 7, 0, $02, 0 | PRIORITY
+ dsprite 0, 0, 8, 0, $03, 0 | PRIORITY
+ dsprite 0, 5, -1, 7, $00, 0 | Y_FLIP | PRIORITY
+ dsprite 0, 5, 0, 0, $02, 0 | Y_FLIP | PRIORITY
+ dsprite 0, 5, 1, 0, $02, 0 | Y_FLIP | PRIORITY
+ dsprite 0, 5, 2, 0, $03, 0 | PRIORITY
+ dsprite 0, 5, 3, 0, $02, 0 | Y_FLIP | PRIORITY
+ dsprite 0, 5, 4, 0, $03, 0 | PRIORITY
+ dsprite 0, 5, 5, 0, $02, 0 | Y_FLIP | PRIORITY
+ dsprite 0, 5, 6, 0, $03, 0 | PRIORITY
+ dsprite 0, 5, 7, 0, $02, 0 | Y_FLIP | PRIORITY
+ dsprite 0, 5, 8, 0, $03, 0 | PRIORITY
+
+.NumGroupPair: ; e0b14
+ db 30
+ dsprite 0, 0, 0, 0, $00, 0 | PRIORITY
+ dsprite 0, 0, 1, 0, $02, 0 | PRIORITY
+ dsprite 0, 0, 2, 0, $02, 0 | PRIORITY
+ dsprite 0, 0, 3, 0, $03, 0 | PRIORITY
+ dsprite 0, 0, 4, 0, $02, 0 | PRIORITY
+ dsprite 0, 0, 5, 0, $03, 0 | PRIORITY
+ dsprite 0, 0, 6, 0, $02, 0 | PRIORITY
+ dsprite 0, 0, 7, 0, $03, 0 | PRIORITY
+ dsprite 0, 0, 8, 0, $02, 0 | PRIORITY
+ dsprite 0, 0, 9, 0, $03, 0 | PRIORITY
+ dsprite 1, 0, 0, 0, $01, 0 | PRIORITY
+ dsprite 1, 0, 3, 0, $03, 0 | PRIORITY
+ dsprite 1, 0, 5, 0, $03, 0 | PRIORITY
+ dsprite 1, 0, 7, 0, $03, 0 | PRIORITY
+ dsprite 1, 0, 9, 0, $03, 0 | PRIORITY
+ dsprite 2, 0, 0, 0, $01, 0 | PRIORITY
+ dsprite 2, 0, 3, 0, $03, 0 | PRIORITY
+ dsprite 2, 0, 5, 0, $03, 0 | PRIORITY
+ dsprite 2, 0, 7, 0, $03, 0 | PRIORITY
+ dsprite 2, 0, 9, 0, $03, 0 | PRIORITY
+ dsprite 2, 1, 0, 0, $00, 0 | Y_FLIP | PRIORITY
+ dsprite 2, 1, 1, 0, $02, 0 | Y_FLIP | PRIORITY
+ dsprite 2, 1, 2, 0, $02, 0 | Y_FLIP | PRIORITY
+ dsprite 2, 1, 3, 0, $03, 0 | PRIORITY
+ dsprite 2, 1, 4, 0, $03, 0 | PRIORITY
+ dsprite 2, 1, 5, 0, $03, 0 | PRIORITY
+ dsprite 2, 1, 6, 0, $03, 0 | PRIORITY
+ dsprite 2, 1, 7, 0, $03, 0 | PRIORITY
+ dsprite 2, 1, 8, 0, $03, 0 | PRIORITY
+ dsprite 2, 1, 9, 0, $03, 0 | PRIORITY
+
+.PokeGroupPair: ; e0b8d
+ db 38
+ dsprite 0, 0, -1, 7, $00, 0 | PRIORITY
+ dsprite 0, 0, 3, 0, $00, 0 | X_FLIP | PRIORITY
+ dsprite 1, 0, -1, 7, $01, 0 | PRIORITY
+ dsprite 1, 0, 3, 0, $01, 0 | X_FLIP | PRIORITY
+ dsprite 2, 0, -1, 7, $01, 0 | PRIORITY
+ dsprite 2, 0, 3, 0, $01, 0 | X_FLIP | PRIORITY
+ dsprite 3, 0, -1, 7, $01, 0 | PRIORITY
+ dsprite 3, 0, 1, 0, $03, 0 | PRIORITY
+ dsprite 3, 0, 3, 0, $03, 0 | PRIORITY
+ dsprite 4, 0, -1, 7, $01, 0 | PRIORITY
+ dsprite 4, 0, 1, 0, $03, 0 | PRIORITY
+ dsprite 4, 0, 3, 0, $03, 0 | PRIORITY
+ dsprite 5, 0, -1, 7, $01, 0 | PRIORITY
+ dsprite 5, 0, 1, 0, $03, 0 | PRIORITY
+ dsprite 5, 0, 3, 0, $03, 0 | PRIORITY
+ dsprite 6, 0, -1, 7, $01, 0 | PRIORITY
+ dsprite 6, 0, 1, 0, $03, 0 | PRIORITY
+ dsprite 6, 0, 3, 0, $03, 0 | PRIORITY
+ dsprite 7, 0, -1, 7, $01, 0 | PRIORITY
+ dsprite 7, 0, 1, 0, $03, 0 | PRIORITY
+ dsprite 7, 0, 3, 0, $03, 0 | PRIORITY
+ dsprite 8, 0, -1, 7, $01, 0 | PRIORITY
+ dsprite 8, 0, 1, 0, $03, 0 | PRIORITY
+ dsprite 8, 0, 3, 0, $03, 0 | PRIORITY
+ dsprite 9, 0, -1, 7, $01, 0 | PRIORITY
+ dsprite 9, 0, 1, 0, $03, 0 | PRIORITY
+ dsprite 9, 0, 3, 0, $03, 0 | PRIORITY
+ dsprite 10, 0, -1, 7, $01, 0 | PRIORITY
+ dsprite 10, 0, 1, 0, $03, 0 | PRIORITY
+ dsprite 10, 0, 3, 0, $03, 0 | PRIORITY
+ dsprite 11, 0, -1, 7, $01, 0 | PRIORITY
+ dsprite 11, 0, 1, 0, $03, 0 | PRIORITY
+ dsprite 11, 0, 3, 0, $03, 0 | PRIORITY
+ dsprite 11, 1, -1, 7, $00, 0 | Y_FLIP | PRIORITY
+ dsprite 11, 1, 0, 0, $02, 0 | Y_FLIP | PRIORITY
+ dsprite 11, 1, 1, 0, $03, 0 | Y_FLIP | PRIORITY
+ dsprite 11, 1, 2, 0, $02, 0 | Y_FLIP | PRIORITY
+ dsprite 11, 1, 3, 0, $03, 0 | X_FLIP | Y_FLIP | PRIORITY
+
+.Impossible: ; e0c26
+ db 4
+ dsprite 0, 0, 0, 0, $00, 0 | PRIORITY
+ dsprite 0, 0, 1, 0, $00, 0 | X_FLIP | PRIORITY
+ dsprite 1, 0, 0, 0, $00, 0 | Y_FLIP | PRIORITY
+ dsprite 1, 0, 1, 0, $00, 0 | X_FLIP | Y_FLIP | PRIORITY
+; e0c37
+
+CardFlip_InitAttrPals: ; e0c37 (38:4c37)
+ ld a, [hCGB]
+ and a
+ ret z
+
+ hlcoord 0, 0, wAttrMap
+ ld bc, SCREEN_HEIGHT * SCREEN_WIDTH
+ xor a
+ call ByteFill
+
+ hlcoord 12, 1, wAttrMap
+ lb bc, 2, 2
+ ld a, $1
+ call CardFlip_FillBox
+
+ hlcoord 14, 1, wAttrMap
+ lb bc, 2, 2
+ ld a, $2
+ call CardFlip_FillBox
+
+ hlcoord 16, 1, wAttrMap
+ lb bc, 2, 2
+ ld a, $3
+ call CardFlip_FillBox
+
+ hlcoord 18, 1, wAttrMap
+ lb bc, 2, 2
+ ld a, $4
+ call CardFlip_FillBox
+
+ hlcoord 9, 0, wAttrMap
+ lb bc, 12, 1
+ ld a, $1
+ call CardFlip_FillBox
+
+ ld a, [rSVBK]
+ push af
+ ld a, BANK(wBGPals1)
+ ld [rSVBK], a
+ ld hl, .palettes
+ ld de, wBGPals1
+ ld bc, 9 palettes
+ call CopyBytes
+ pop af
+ ld [rSVBK], a
+ ret
+; e0c93 (38:4c93)
+
+.palettes ; e0c93
+INCLUDE "gfx/card_flip/card_flip.pal"
+; e0cdb
+
+CardFlipLZ03: ; e0cdb
+INCBIN "gfx/card_flip/card_flip_3.2bpp.lz"
+
+CardFlipOffButtonGFX: ; e0cf6
+INCBIN "gfx/card_flip/off.2bpp"
+
+CardFlipOnButtonGFX: ; e0d06
+INCBIN "gfx/card_flip/on.2bpp"
+
+CardFlipLZ01: ; e0d16
+INCBIN "gfx/card_flip/card_flip_1.2bpp.lz"
+
+CardFlipLZ02: ; e0ea8
+INCBIN "gfx/card_flip/card_flip_2.2bpp.lz"
+
+CardFlipTilemap: ; e110c
+INCBIN "gfx/card_flip/card_flip.tilemap"
+; e1190
diff --git a/engine/games/dummy_game.asm b/engine/games/dummy_game.asm
new file mode 100644
index 000000000..6d7e12196
--- /dev/null
+++ b/engine/games/dummy_game.asm
@@ -0,0 +1,612 @@
+_DummyGame: ; e1e5b (38:5e5b)
+ call .LoadGFXAndPals
+ call DelayFrame
+.loop
+ call .JumptableLoop
+ jr nc, .loop
+ ret
+
+.LoadGFXAndPals:
+ call DisableLCD
+ ld b, SCGB_DIPLOMA
+ call GetSGBLayout
+ callfar ClearSpriteAnims
+ ld hl, LZ_e2221
+ ld de, vTiles2 tile $00
+ call Decompress
+ ld hl, Unknown_e00ed
+ ld de, vTiles0 tile $00
+ ld bc, 4 tiles
+ ld a, BANK(Unknown_e00ed)
+ call FarCopyBytes
+ ld a, $8
+ ld hl, wc300
+ ld [hli], a
+ ld [hl], $0
+ hlcoord 0, 0
+ ld bc, SCREEN_HEIGHT * SCREEN_WIDTH
+ xor a
+ call ByteFill
+ xor a
+ ld [hSCY], a
+ ld [hSCX], a
+ ld [rWY], a
+ ld [wJumptableIndex], a
+ ld a, $1
+ ld [hBGMapMode], a
+ ld a, LCDC_DEFAULT
+ ld [rLCDC], a
+ ld a, $e4
+ call DmgToCgbBGPals
+ ld a, $e0
+ call DmgToCgbObjPal0
+ ret
+
+.JumptableLoop:
+ ld a, [wJumptableIndex]
+ bit 7, a
+ jr nz, .quit
+ call .ExecuteJumptable
+ callfar PlaySpriteAnimations
+ call DelayFrame
+ and a
+ ret
+
+.quit
+ scf
+ ret
+
+.ExecuteJumptable:
+ jumptable .Jumptable, wJumptableIndex
+
+.Jumptable:
+ dw .RestartGame
+ dw .ResetBoard
+ dw .InitBoardTilemapAndCursorObject
+ dw .CheckTriesRemaining
+ dw .PickCard1
+ dw .PickCard2
+ dw .DelayPickAgain
+ dw .RevealAll
+ dw .AskPlayAgain
+
+.RestartGame:
+ call DummyGame_InitStrings
+ ld hl, wJumptableIndex
+ inc [hl]
+ ret
+
+.ResetBoard:
+ call ret_e00ed
+ jr nc, .proceed
+ ld hl, wJumptableIndex
+ set 7, [hl]
+ ret
+
+.proceed
+ call DummyGame_InitBoard
+ ld hl, wJumptableIndex
+ inc [hl]
+ xor a
+ ld [wDummyGameCounter], a
+ ld hl, wDummyGameLastMatches
+rept 4
+ ld [hli], a
+endr
+ ld [hl], a
+ ld [wDummyGameNumCardsMatched], a
+.InitBoardTilemapAndCursorObject:
+ ld hl, wDummyGameCounter
+ ld a, [hl]
+ cp 45
+ jr nc, .spawn_object
+ inc [hl]
+ call DummyGame_Card2Coord
+ xor a
+ ld [wDummyGameLastCardPicked], a
+ call DummyGame_PlaceCard
+ ret
+
+.spawn_object
+ depixel 6, 3, 4, 4
+ ld a, SPRITE_ANIM_INDEX_DUMMY_GAME
+ call _InitSpriteAnimStruct
+ ld a, 5
+ ld [wDummyGameNumberTriesRemaining], a
+ ld hl, wJumptableIndex
+ inc [hl]
+ ret
+
+.CheckTriesRemaining:
+ ld a, [wDummyGameNumberTriesRemaining]
+ hlcoord 17, 0
+ add "0"
+ ld [hl], a
+ ld hl, wDummyGameNumberTriesRemaining
+ ld a, [hl]
+ and a
+ jr nz, .next_try
+ ld a, $7
+ ld [wJumptableIndex], a
+ ret
+
+.next_try
+ dec [hl]
+ xor a
+ ld [wcf64], a
+ ld hl, wJumptableIndex
+ inc [hl]
+.PickCard1:
+ ld a, [wcf64]
+ and a
+ ret z
+ dec a
+ ld e, a
+ ld d, 0
+ ld hl, wDummyGameCards
+ add hl, de
+ ld a, [hl]
+ cp -1
+ ret z
+ ld [wDummyGameLastCardPicked], a
+ ld [wDummyGameCard1], a
+ ld a, e
+ ld [wDummyGameCard1Location], a
+ call DummyGame_Card2Coord
+ call DummyGame_PlaceCard
+ xor a
+ ld [wcf64], a
+ ld hl, wJumptableIndex
+ inc [hl]
+ ret
+
+.PickCard2:
+ ld a, [wcf64]
+ and a
+ ret z
+ dec a
+ ld hl, wDummyGameCard1Location
+ cp [hl]
+ ret z
+ ld e, a
+ ld d, 0
+ ld hl, wDummyGameCards
+ add hl, de
+ ld a, [hl]
+ cp -1
+ ret z
+ ld [wDummyGameLastCardPicked], a
+ ld [wDummyGameCard2], a
+ ld a, e
+ ld [wDummyGameCard2Location], a
+ call DummyGame_Card2Coord
+ call DummyGame_PlaceCard
+ ld a, 64
+ ld [wDummyGameCounter], a
+ ld hl, wJumptableIndex
+ inc [hl]
+.DelayPickAgain:
+ ld hl, wDummyGameCounter
+ ld a, [hl]
+ and a
+ jr z, .PickAgain
+ dec [hl]
+ ret
+
+.PickAgain:
+ call DummyGame_CheckMatch
+ ld a, $3
+ ld [wJumptableIndex], a
+ ret
+
+.RevealAll:
+ ld a, [hJoypadPressed]
+ and A_BUTTON
+ ret z
+ xor a
+ ld [wDummyGameCounter], a
+.RevelationLoop:
+ ld hl, wDummyGameCounter
+ ld a, [hl]
+ cp 45
+ jr nc, .finish_round
+ inc [hl]
+ push af
+ call DummyGame_Card2Coord
+ pop af
+ push hl
+ ld e, a
+ ld d, $0
+ ld hl, wDummyGameCards
+ add hl, de
+ ld a, [hl]
+ pop hl
+ cp -1
+ jr z, .RevelationLoop
+ ld [wDummyGameLastCardPicked], a
+ call DummyGame_PlaceCard
+ jr .RevelationLoop
+
+.finish_round
+ call WaitPressAorB_BlinkCursor
+ ld hl, wJumptableIndex
+ inc [hl]
+.AskPlayAgain:
+ call ret_e00ed
+ jr nc, .restart
+ ld hl, wJumptableIndex
+ set 7, [hl]
+ ret
+
+.restart
+ xor a
+ ld [wJumptableIndex], a
+ ret
+
+; e2010
+
+DummyGame_CheckMatch: ; e2010
+ ld hl, wDummyGameCard1
+ ld a, [hli]
+ cp [hl]
+ jr nz, .no_match
+
+ ld a, [wDummyGameCard1Location]
+ call DummyGame_Card2Coord
+ call DummyGame_DeleteCard
+
+ ld a, [wDummyGameCard2Location]
+ call DummyGame_Card2Coord
+ call DummyGame_DeleteCard
+
+ ld a, [wDummyGameCard1Location]
+ ld e, a
+ ld d, $0
+ ld hl, wDummyGameCards
+ add hl, de
+ ld [hl], -1
+
+ ld a, [wDummyGameCard2Location]
+ ld e, a
+ ld d, 0
+ ld hl, wDummyGameCards
+ add hl, de
+ ld [hl], -1
+
+ ld hl, wDummyGameLastMatches
+.find_empty_slot
+ ld a, [hli]
+ and a
+ jr nz, .find_empty_slot
+ dec hl
+ ld a, [wDummyGameCard1]
+ ld [hl], a
+ ld [wDummyGameLastCardPicked], a
+ ld hl, wDummyGameNumCardsMatched
+ ld e, [hl]
+ inc [hl]
+ inc [hl]
+ ld d, 0
+ hlcoord 5, 0
+ add hl, de
+ call DummyGame_PlaceCard
+ ld hl, .VictoryText
+ call PrintText
+ ret
+
+.no_match
+ xor a
+ ld [wDummyGameLastCardPicked], a
+
+ ld a, [wDummyGameCard1Location]
+ call DummyGame_Card2Coord
+ call DummyGame_PlaceCard
+
+ ld a, [wDummyGameCard2Location]
+ call DummyGame_Card2Coord
+ call DummyGame_PlaceCard
+
+ ld hl, DummyGameText_Darn
+ call PrintText
+ ret
+
+.VictoryText:
+ start_asm
+ push bc
+ hlcoord 2, 13
+ call DummyGame_PlaceCard
+ ld hl, DummyGameText_Yeah
+ pop bc
+ inc bc
+ inc bc
+ inc bc
+ ret
+
+; e2093
+
+DummyGameText_Yeah: ; 0xe2093
+ ; , yeah!
+ text_jump UnknownText_0x1c1a5b
+ db "@"
+; 0xe2098
+
+DummyGameText_Darn: ; 0xe2098
+ ; Darn…
+ text_jump UnknownText_0x1c1a65
+ db "@"
+; 0xe209d
+
+DummyGame_InitBoard: ; e209d
+ ld hl, wDummyGameCards
+ ld bc, wDummyGameCardsEnd - wDummyGameCards
+ xor a
+ call ByteFill
+ call DummyGame_GetDistributionOfTiles
+
+ ld c, 2
+ ld b, [hl]
+ call DummyGame_SampleTilePlacement
+
+ ld c, 8
+ ld b, [hl]
+ call DummyGame_SampleTilePlacement
+
+ ld c, 4
+ ld b, [hl]
+ call DummyGame_SampleTilePlacement
+
+ ld c, 7
+ ld b, [hl]
+ call DummyGame_SampleTilePlacement
+
+ ld c, 3
+ ld b, [hl]
+ call DummyGame_SampleTilePlacement
+
+ ld c, 6
+ ld b, [hl]
+ call DummyGame_SampleTilePlacement
+
+ ld c, 1
+ ld b, [hl]
+ call DummyGame_SampleTilePlacement
+
+ ld c, 5
+ ld hl, wDummyGameCards
+ ld b, wDummyGameCardsEnd - wDummyGameCards
+.loop
+ ld a, [hl]
+ and a
+ jr nz, .no_load
+ ld [hl], c
+.no_load
+ inc hl
+ dec b
+ jr nz, .loop
+ ret
+
+; e20e5
+
+DummyGame_SampleTilePlacement: ; e20e5
+ push hl
+ ld de, wDummyGameCards
+.loop
+ call Random
+ and %00111111
+ cp 45
+ jr nc, .loop
+ ld l, a
+ ld h, 0
+ add hl, de
+ ld a, [hl]
+ and a
+ jr nz, .loop
+ ld [hl], c
+ dec b
+ jr nz, .loop
+ pop hl
+ inc hl
+ ret
+
+; e2101
+
+DummyGame_GetDistributionOfTiles: ; e2101
+ ld a, [wMenuCursorY]
+ dec a
+ ld l, a
+ ld h, 0
+ add hl, hl
+ add hl, hl
+ add hl, hl
+ ld de, .distributions
+ add hl, de
+ ret
+
+.distributions
+ db $02, $03, $06, $06, $06, $08, $08, $06
+ db $02, $02, $04, $06, $06, $08, $08, $09
+ db $02, $02, $02, $04, $07, $08, $08, $0c
+; e2128
+
+DummyGame_PlaceCard: ; e2128
+ ld a, [wDummyGameLastCardPicked]
+ sla a
+ sla a
+ add 4
+ ld [hli], a
+ inc a
+ ld [hld], a
+ inc a
+ ld bc, SCREEN_WIDTH
+ add hl, bc
+ ld [hli], a
+ inc a
+ ld [hl], a
+ ld c, 3
+ call DelayFrames
+ ret
+
+; e2142
+
+DummyGame_DeleteCard: ; e2142
+ ld a, $1
+ ld [hli], a
+ ld [hld], a
+ ld bc, SCREEN_WIDTH
+ add hl, bc
+ ld [hli], a
+ ld [hl], a
+ ld c, 3
+ call DelayFrames
+ ret
+
+; e2152
+
+DummyGame_InitStrings: ; e2152
+ hlcoord 0, 0
+ ld bc, SCREEN_WIDTH * SCREEN_HEIGHT
+ ld a, $1
+ call ByteFill
+ hlcoord 0, 0
+ ld de, .japstr1
+ call PlaceString
+ hlcoord 15, 0
+ ld de, .japstr2
+ call PlaceString
+ ld hl, .dummy_text
+ call PrintText
+ ret
+
+.dummy_text
+ db "@"
+.japstr1
+ db "とったもの@"
+.japstr2
+ db "あと かい@"
+; e2183
+
+DummyGame_Card2Coord: ; e2183
+ ld d, 0
+.find_row
+ sub 9
+ jr c, .found_row
+ inc d
+ jr .find_row
+
+.found_row
+ add 9
+ ld e, a
+ hlcoord 1, 2
+ ld bc, 2 * SCREEN_WIDTH
+.loop2
+ ld a, d
+ and a
+ jr z, .done
+ add hl, bc
+ dec d
+ jr .loop2
+
+.done
+ sla e
+ add hl, de
+ ret
+
+; e21a1
+
+DummyGame_InterpretJoypad_AnimateCursor: ; e21a1 (38:61a1)
+ ld a, [wJumptableIndex]
+ cp $7
+ jr nc, .quit
+ call JoyTextDelay
+ ld hl, hJoypadPressed ; $ffa3
+ ld a, [hl]
+ and A_BUTTON
+ jr nz, .pressed_a
+ ld a, [hl]
+ and D_LEFT
+ jr nz, .pressed_left
+ ld a, [hl]
+ and D_RIGHT
+ jr nz, .pressed_right
+ ld a, [hl]
+ and D_UP
+ jr nz, .pressed_up
+ ld a, [hl]
+ and D_DOWN
+ jr nz, .pressed_down
+ ret
+
+.quit
+ ld hl, SPRITEANIMSTRUCT_INDEX
+ add hl, bc
+ ld [hl], $0
+ ret
+
+.pressed_a
+ ld hl, SPRITEANIMSTRUCT_0C
+ add hl, bc
+ ld a, [hl]
+ inc a
+ ld [wcf64], a
+ ret
+
+.pressed_left
+ ld hl, SPRITEANIMSTRUCT_XOFFSET
+ add hl, bc
+ ld a, [hl]
+ and a
+ ret z
+ sub 1 tiles
+ ld [hl], a
+ ld hl, SPRITEANIMSTRUCT_0C
+ add hl, bc
+ dec [hl]
+ ret
+
+.pressed_right
+ ld hl, SPRITEANIMSTRUCT_XOFFSET
+ add hl, bc
+ ld a, [hl]
+ cp (9 - 1) tiles
+ ret z
+ add 1 tiles
+ ld [hl], a
+ ld hl, SPRITEANIMSTRUCT_0C
+ add hl, bc
+ inc [hl]
+ ret
+
+.pressed_up
+ ld hl, SPRITEANIMSTRUCT_YOFFSET
+ add hl, bc
+ ld a, [hl]
+ and a
+ ret z
+ sub 1 tiles
+ ld [hl], a
+ ld hl, SPRITEANIMSTRUCT_0C
+ add hl, bc
+ ld a, [hl]
+ sub 9
+ ld [hl], a
+ ret
+
+.pressed_down
+ ld hl, SPRITEANIMSTRUCT_YOFFSET
+ add hl, bc
+ ld a, [hl]
+ cp (5 - 1) tiles
+ ret z
+ add 1 tiles
+ ld [hl], a
+ ld hl, SPRITEANIMSTRUCT_0C
+ add hl, bc
+ ld a, [hl]
+ add 9
+ ld [hl], a
+ ret
+
+; e2221 (38:6221)
+
+LZ_e2221: ; e2221
+INCBIN "gfx/dummy_game/dummy_game.2bpp.lz"
diff --git a/engine/games/slot_machine.asm b/engine/games/slot_machine.asm
new file mode 100644
index 000000000..924c78924
--- /dev/null
+++ b/engine/games/slot_machine.asm
@@ -0,0 +1,2352 @@
+SLOTS_NO_BIAS EQU -1
+SLOTS_NO_MATCH EQU -1
+
+SLOTS_SEVEN EQU $00
+SLOTS_POKEBALL EQU $04
+SLOTS_CHERRY EQU $08
+SLOTS_PIKACHU EQU $0c
+SLOTS_SQUIRTLE EQU $10
+SLOTS_STARYU EQU $14
+
+REEL_SIZE EQU 15
+
+; Constants for slot_reel offsets (see macros/wram.asm)
+REEL_ACTION EQUS "(wReel1ReelAction - wReel1)"
+REEL_TILEMAP_ADDR EQUS "(wReel1TilemapAddr - wReel1)"
+REEL_POSITION EQUS "(wReel1Position - wReel1)"
+REEL_SPIN_DISTANCE EQUS "(wReel1SpinDistance - wReel1)"
+REEL_SPIN_RATE EQUS "(wReel1SpinRate - wReel1)"
+REEL_OAM_ADDR EQUS "(wReel1OAMAddr - wReel1)"
+REEL_X_COORD EQUS "(wReel1XCoord - wReel1)"
+REEL_MANIP_COUNTER EQUS "(wReel1ManipCounter - wReel1)"
+REEL_MANIP_DELAY EQUS "(wReel1ManipDelay - wReel1)"
+REEL_FIELD_0B EQUS "(wReel1Field0b - wReel1)"
+REEL_STOP_DELAY EQUS "(wReel1StopDelay - wReel1)"
+
+; SlotsJumptable constants
+ const_def
+ const SLOTS_INIT
+ const SLOTS_BET_AND_START
+ const SLOTS_WAIT_START
+ const SLOTS_WAIT_REEL1
+ const SLOTS_WAIT_STOP_REEL1
+ const SLOTS_WAIT_REEL2
+ const SLOTS_WAIT_STOP_REEL2
+ const SLOTS_WAIT_REEL3
+ const SLOTS_WAIT_STOP_REEL3
+ const SLOTS_NEXT_09
+ const SLOTS_NEXT_0A
+ const SLOTS_NEXT_0B
+ const SLOTS_FLASH_IF_WIN
+ const SLOTS_FLASH_SCREEN
+ const SLOTS_GIVE_EARNED_COINS
+ const SLOTS_PAYOUT_TEXT_AND_ANIM
+ const SLOTS_PAYOUT_ANIM
+ const SLOTS_RESTART_OF_QUIT
+ const SLOTS_QUIT
+SLOTS_END_LOOP_F EQU 7
+
+; ReelActionJumptable constants
+ const_def
+ const REEL_ACTION_DO_NOTHING
+ const REEL_ACTION_STOP_REEL_IGNORE_JOYPAD
+ const REEL_ACTION_QUADRUPLE_RATE
+ const REEL_ACTION_DOUBLE_RATE
+ const REEL_ACTION_NORMAL_RATE
+ const REEL_ACTION_HALF_RATE
+ const REEL_ACTION_QUARTER_RATE
+ const REEL_ACTION_STOP_REEL1
+ const REEL_ACTION_STOP_REEL2
+ const REEL_ACTION_STOP_REEL3
+ const REEL_ACTION_SET_UP_REEL2_SKIP_TO_7
+ const REEL_ACTION_WAIT_REEL2_SKIP_TO_7
+ const REEL_ACTION_FAST_SPIN_REEL2_UNTIL_LINED_UP_7S
+ const REEL_ACTION_UNUSED
+ const REEL_ACTION_CHECK_DROP_REEL
+ const REEL_ACTION_WAIT_DROP_REEL
+ const REEL_ACTION_START_SLOW_ADVANCE_REEL3
+ const REEL_ACTION_WAIT_SLOW_ADVANCE_REEL3
+ const REEL_ACTION_INIT_GOLEM
+ const REEL_ACTION_WAIT_GOLEM
+ const REEL_ACTION_END_GOLEM
+ const REEL_ACTION_INIT_CHANSEY
+ const REEL_ACTION_WAIT_CHANSEY
+ const REEL_ACTION_WAIT_EGG
+ const REEL_ACTION_DROP_REEL
+
+_SlotMachine:
+ ld hl, wOptions
+ set NO_TEXT_SCROLL, [hl]
+ call .InitGFX
+ call DelayFrame
+.loop
+ call SlotsLoop
+ jr nc, .loop
+ call WaitSFX
+ ld de, SFX_QUIT_SLOTS
+ call PlaySFX
+ call WaitSFX
+ call ClearBGPalettes
+ farcall StubbedTrainerRankings_EndSlotsWinStreak
+ ld hl, wOptions
+ res NO_TEXT_SCROLL, [hl]
+ ld hl, rLCDC
+ res rLCDC_SPRITE_SIZE, [hl] ; 8x8
+ ret
+
+.InitGFX: ; 926f7 (24:66f7)
+ call ClearBGPalettes
+ call ClearTileMap
+ call ClearSprites
+ ld de, MUSIC_NONE
+ call PlayMusic
+ call DelayFrame
+ call DisableLCD
+ hlbgcoord 0, 0
+ ld bc, vBGMap1 - vBGMap0
+ ld a, " "
+ call ByteFill
+ ld b, SCGB_SLOT_MACHINE
+ call GetSGBLayout
+ callfar ClearSpriteAnims
+ ld hl, wSlots
+ ld bc, wSlotsDataEnd - wSlots
+ xor a
+ call ByteFill
+
+ ld hl, Slots2LZ
+ ld de, vTiles0 tile $00
+ call Decompress
+
+ ld hl, Slots3LZ
+ ld de, vTiles0 tile $40
+ call Decompress
+
+ ld hl, Slots1LZ
+ ld de, vTiles2 tile $00
+ call Decompress
+
+ ld hl, Slots2LZ
+ ld de, vTiles2 tile $25
+ call Decompress
+
+ ld hl, SlotsTilemap
+ decoord 0, 0
+ ld bc, SCREEN_WIDTH * 12
+ call CopyBytes
+
+ ld hl, rLCDC
+ set rLCDC_SPRITE_SIZE, [hl] ; 8x16
+ call EnableLCD
+ ld hl, wSlots
+ ld bc, wSlotsEnd - wSlots
+ xor a
+ call ByteFill
+ call Slots_InitReelTiles
+ call Slots_GetPals
+ ld a, $7
+ ld hl, wSpriteAnimDict
+ ld [hli], a
+ ld [hl], $40
+ xor a ; SLOTS_INIT
+ ld [wJumptableIndex], a
+ ld a, SLOTS_NO_BIAS
+ ld [wSlotBias], a
+ ld de, MUSIC_GAME_CORNER
+ call PlayMusic
+ xor a
+ ld [wKeepSevenBiasChance], a ; 87.5% chance
+ call Random
+ and %00101010
+ ret nz
+ ld a, 1
+ ld [wKeepSevenBiasChance], a ; 12.5% chance
+ ret
+
+Slots_GetPals: ; 9279b (24:679b)
+ ld a, %11100100
+ call DmgToCgbBGPals
+ lb de, %11100100, %11100100
+ ld a, [hCGB]
+ and a
+ jr nz, .cgb
+ lb de, %11000000, %11100100
+.cgb
+ call DmgToCgbObjPals
+ ret
+
+SlotsLoop: ; 927af (24:67af)
+ ld a, [wJumptableIndex]
+ bit SLOTS_END_LOOP_F, a
+ jr nz, .stop
+ call SlotsJumptable
+ call Slots_SpinReels
+ xor a
+ ld [wCurrSpriteOAMAddr], a
+ callfar DoNextFrameForFirst16Sprites
+ call .PrintCoinsAndPayout
+ call .Stubbed_Function927d3
+ call DelayFrame
+ and a
+ ret
+
+.stop
+ scf
+ ret
+
+.Stubbed_Function927d3: ; 927d3 (24:67d3)
+; dummied out
+ ret
+ ld a, [wReel1ReelAction]
+ and a
+ ret nz
+ ld a, [wReel2ReelAction]
+ and a
+ ret nz
+ ld a, [wFirstTwoReelsMatchingSevens]
+ and a
+ jr nz, .matching_sevens
+ ld a, %11100100
+ call DmgToCgbBGPals
+ ret
+
+.matching_sevens
+ ld a, [wTextDelayFrames]
+ and $7
+ ret nz
+ ld a, [rBGP]
+ xor %00001100
+ call DmgToCgbBGPals
+ ret
+
+; 927f8
+
+.PrintCoinsAndPayout: ; 927f8 (24:67f8)
+ hlcoord 5, 1
+ ld de, wCoins
+ lb bc, PRINTNUM_LEADINGZEROS | 2, 4
+ call PrintNum
+ hlcoord 11, 1
+ ld de, wPayout
+ lb bc, PRINTNUM_LEADINGZEROS | 2, 4
+ call PrintNum
+ ret
+
+; 92811 (24:6811)
+
+Unreferenced_Function92811: ; 92811
+; debug function?
+ ld a, [wSlotBias]
+ add 0
+ daa
+ ld e, a
+ and $f
+ add "0"
+ hlcoord 1, 0
+ ld [hl], a
+ ld a, e
+ swap a
+ and $f
+ add "0"
+ hlcoord 0, 0
+ ld [hl], a
+ ret
+
+; 9282c
+
+Unreferenced_Function9282c: ; 9282c
+; animate OAM tiles?
+ ld hl, wcf66
+ ld a, [hl]
+ inc [hl]
+ and $7
+ ret nz
+ ld hl, wVirtualOAMSprite16TileID
+ ld c, NUM_SPRITE_OAM_STRUCTS - 16
+.loop
+ ld a, [hl]
+ xor %00100000
+ ld [hli], a ; tile id
+rept SPRITEOAMSTRUCT_LENGTH + -1
+ inc hl
+endr
+ dec c
+ jr nz, .loop
+ ret
+
+; 92844
+
+SlotsJumptable: ; 92844 (24:6844)
+ jumptable .Jumptable, wJumptableIndex
+
+.Jumptable:
+ dw SlotsAction_Init ; 00
+ dw SlotsAction_BetAndStart ; 01
+ dw SlotsAction_WaitStart ; 02
+ dw SlotsAction_WaitReel1 ; 03
+ dw SlotsAction_WaitStopReel1 ; 04
+ dw SlotsAction_WaitReel2 ; 05
+ dw SlotsAction_WaitStopReel2 ; 06
+ dw SlotsAction_WaitReel3 ; 07
+ dw SlotsAction_WaitStopReel3 ; 08
+ dw SlotsAction_Next ; 09
+ dw SlotsAction_Next ; 0a
+ dw SlotsAction_Next ; 0b
+ dw SlotsAction_FlashIfWin ; 0c
+ dw SlotsAction_FlashScreen ; 0d
+ dw SlotsAction_GiveEarnedCoins ; 0e
+ dw SlotsAction_PayoutTextAndAnim ; 0f
+ dw SlotsAction_PayoutAnim ; 10
+ dw SlotsAction_RestartOrQuit ; 11
+ dw SlotsAction_Quit ; 12
+
+SlotsAction_Next: ; 92879 (24:6879)
+ ld hl, wJumptableIndex
+ inc [hl]
+ ret
+
+SlotsAction_Init: ; 9287e (24:687e)
+ call SlotsAction_Next
+ xor a
+ ld [wFirstTwoReelsMatching], a
+ ld [wFirstTwoReelsMatchingSevens], a
+ ld a, SLOTS_NO_MATCH
+ ld [wSlotMatched], a
+ ret
+
+SlotsAction_BetAndStart: ; 9288e (24:688e)
+ call Slots_AskBet
+ jr nc, .proceed
+ ld a, SLOTS_QUIT
+ ld [wJumptableIndex], a
+ ret
+
+.proceed
+ call SlotsAction_Next
+ call Slots_IlluminateBetLights
+ call Slots_InitBias
+ ld a, 32
+ ld [wSlotsDelay], a
+ ld a, REEL_ACTION_NORMAL_RATE
+ ld [wReel1ReelAction], a
+ ld [wReel2ReelAction], a
+ ld [wReel3ReelAction], a
+ ld a, 4
+ ld [wReel1ManipCounter], a
+ ld [wReel2ManipCounter], a
+ ld [wReel3ManipCounter], a
+ call WaitSFX
+ ld a, SFX_SLOT_MACHINE_START
+ call Slots_PlaySFX
+ ret
+
+SlotsAction_WaitStart: ; 928c6 (24:68c6)
+ ld hl, wSlotsDelay
+ ld a, [hl]
+ and a
+ jr z, .proceed
+ dec [hl]
+ ret
+
+.proceed
+ call SlotsAction_Next
+ xor a
+ ld [hJoypadSum], a
+ ret
+
+SlotsAction_WaitReel1: ; 928d6 (24:68d6)
+ ld hl, hJoypadSum
+ ld a, [hl]
+ and A_BUTTON
+ ret z
+ call SlotsAction_Next
+ call Slots_StopReel1
+ ld [wReel1ReelAction], a
+SlotsAction_WaitStopReel1: ; 928e6 (24:68e6)
+ ld a, [wReel1ReelAction]
+ cp REEL_ACTION_DO_NOTHING
+ ret nz
+ ld a, SFX_STOP_SLOT
+ call Slots_PlaySFX
+ ld bc, wReel1
+ ld de, wReel1Stopped
+ call Slots_LoadReelState
+ call SlotsAction_Next
+ xor a
+ ld [hJoypadSum], a
+SlotsAction_WaitReel2: ; 92900 (24:6900)
+ ld hl, hJoypadSum
+ ld a, [hl]
+ and A_BUTTON
+ ret z
+ call SlotsAction_Next
+ call Slots_StopReel2
+ ld [wReel2ReelAction], a
+SlotsAction_WaitStopReel2: ; 92910 (24:6910)
+ ld a, [wReel2ReelAction]
+ cp REEL_ACTION_DO_NOTHING
+ ret nz
+ ld a, SFX_STOP_SLOT
+ call Slots_PlaySFX
+ ld bc, wReel2
+ ld de, wReel2Stopped
+ call Slots_LoadReelState
+ call SlotsAction_Next
+ xor a
+ ld [hJoypadSum], a
+SlotsAction_WaitReel3: ; 9292a (24:692a)
+ ld hl, hJoypadSum
+ ld a, [hl]
+ and A_BUTTON
+ ret z
+ call SlotsAction_Next
+ call Slots_StopReel3
+ ld [wReel3ReelAction], a
+SlotsAction_WaitStopReel3: ; 9293a (24:693a)
+ ld a, [wReel3ReelAction]
+ cp REEL_ACTION_DO_NOTHING
+ ret nz
+ ld a, SFX_STOP_SLOT
+ call Slots_PlaySFX
+ ld bc, wReel3
+ ld de, wReel3Stopped
+ call Slots_LoadReelState
+ call SlotsAction_Next
+ xor a
+ ld [hJoypadSum], a
+ ret
+
+SlotsAction_FlashIfWin: ; 92955 (24:6955)
+ ld a, [wSlotMatched]
+ cp SLOTS_NO_MATCH
+ jr nz, .GotIt
+ call SlotsAction_Next
+ call SlotsAction_Next
+ ret
+
+.GotIt:
+ call SlotsAction_Next
+ ld a, 16
+ ld [wSlotsDelay], a
+SlotsAction_FlashScreen: ; 9296b (24:696b)
+ ld hl, wSlotsDelay
+ ld a, [hl]
+ and a
+ jr z, .done
+ dec [hl]
+ srl a
+ ret z
+
+ ld a, [rOBP0]
+ xor $ff
+ ld e, a
+ ld d, a
+ call DmgToCgbObjPals
+ ret
+
+.done
+ call Slots_GetPals
+ call SlotsAction_Next
+ ret
+
+SlotsAction_GiveEarnedCoins: ; 92987 (24:6987)
+ xor a
+ ld [wFirstTwoReelsMatching], a
+ ld [wFirstTwoReelsMatchingSevens], a
+ ld a, %11100100
+ call DmgToCgbBGPals
+ call Slots_GetPayout
+ xor a
+ ld [wSlotsDelay], a
+ call SlotsAction_Next
+ ret
+
+SlotsAction_PayoutTextAndAnim: ; 9299e (24:699e)
+ call Slots_PayoutText
+ call SlotsAction_Next
+SlotsAction_PayoutAnim: ; 929a4 (24:69a4)
+ ld hl, wSlotsDelay
+ ld a, [hl]
+ inc [hl]
+ and $1
+ ret z
+ ld hl, wPayout
+ ld a, [hli]
+ ld d, a
+ or [hl]
+ jr z, .done
+ ld e, [hl]
+ dec de
+ ld [hl], e
+ dec hl
+ ld [hl], d
+ ld hl, wCoins
+ ld d, [hl]
+ inc hl
+ ld e, [hl]
+ call Slots_CheckCoinCaseFull
+ jr c, .okay
+ inc de
+.okay
+ ld [hl], e
+ dec hl
+ ld [hl], d
+ ld a, [wSlotsDelay]
+ and $7
+ ret z ; ret nz would be more appropriate
+ ld de, SFX_GET_COIN_FROM_SLOTS
+ call PlaySFX
+ ret
+
+.done
+ call SlotsAction_Next
+ ret
+
+SlotsAction_RestartOrQuit: ; 929d9 (24:69d9)
+ call Slots_DeilluminateBetLights
+ call WaitPressAorB_BlinkCursor
+ call Slots_AskPlayAgain
+ jr c, .exit_slots
+ ld a, SLOTS_INIT
+ ld [wJumptableIndex], a
+ ret
+
+.exit_slots
+ ld a, SLOTS_QUIT
+ ld [wJumptableIndex], a
+ ret
+
+SlotsAction_Quit: ; 929f0 (24:69f0)
+ ld hl, wJumptableIndex
+ set SLOTS_END_LOOP_F, [hl]
+ ret
+
+Slots_LoadReelState: ; 929f6 (24:69f6)
+ push de
+ call Slots_GetCurrentReelState
+ pop de
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hli]
+ ld [de], a
+ ret
+
+Slots_CheckCoinCaseFull: ; 92a04 (24:6a04)
+ ld a, d
+ cp HIGH(MAX_COINS)
+ jr c, .not_full
+ ld a, e
+ cp LOW(MAX_COINS)
+ jr c, .not_full
+ scf
+ ret
+
+.not_full
+ and a
+ ret
+
+Slots_GetCurrentReelState: ; 92a12 (24:6a12)
+ ld hl, REEL_POSITION
+ add hl, bc
+ ld a, [hl]
+ and a
+ jr nz, .okay
+ ld a, $f
+.okay
+ dec a
+ and $f
+ ld e, a
+ ld d, $0
+ ld hl, REEL_TILEMAP_ADDR
+ add hl, bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ add hl, de
+ ret
+
+Slots_StopReel1: ; 92a2b (24:6a2b)
+; Always set the REEL_ACTION_STOP_REEL1 action.
+ ld a, REEL_ACTION_STOP_REEL1
+ ret
+
+Slots_StopReel2: ; 92a2e (24:6a2e)
+; As long as, the following three meet, there's a 31.25% chance
+; to set action REEL_ACTION_SET_UP_REEL2_SKIP_TO_7:
+; - Bet is >= 2 coins
+; - There's a 7 symbol visible in reel #1
+; - Current spin isn't biased or is biased towards SEVEN
+; In any other case, REEL_ACTION_STOP_REEL2 is set.
+
+ ld a, [wSlotBet]
+ cp $2
+ jr c, .dont_jump
+ ld a, [wSlotBias]
+ and a
+ jr z, .skip
+ cp SLOTS_NO_BIAS
+ jr nz, .dont_jump
+.skip
+ call .CheckReel1ForASeven
+ jr nz, .dont_jump
+ call Random
+ cp $50 ; 32%
+ jr nc, .dont_jump
+ ld a, REEL_ACTION_SET_UP_REEL2_SKIP_TO_7
+ ret
+
+.dont_jump
+ ld a, REEL_ACTION_STOP_REEL2
+ ret
+
+.CheckReel1ForASeven: ; 92a51 (24:6a51)
+ ld a, [wReel1Stopped]
+ and a
+ ret z
+ ld a, [wReel1Stopped + 1]
+ and a
+ ret z
+ ld a, [wReel1Stopped + 2]
+ and a
+ ret
+
+Slots_StopReel3: ; 92a60 (24:6a60)
+; If no matching SEVEN symbols in reels #1 and #2:
+; - REEL_ACTION_STOP_REEL3, 100%
+
+; If matching SEVEN symbols and NO bias to SEVEN:
+; - REEL_ACTION_STOP_REEL3, 37.5%
+; - REEL_ACTION_START_SLOW_ADVANCE_REEL3, 31.3%
+; - REEL_ACTION_INIT_GOLEM, 31.3%
+; - REEL_ACTION_INIT_CHANSEY, 0%
+
+; If matching SEVEN symbols and bias to SEVEN:
+; - REEL_ACTION_STOP_REEL3, 29.7%
+; - REEL_ACTION_START_SLOW_ADVANCE_REEL3, 23.4%
+; - REEL_ACTION_INIT_GOLEM, 23.4%
+; - REEL_ACTION_INIT_CHANSEY, 23.4%
+
+ ld a, [wFirstTwoReelsMatching]
+ and a
+ jr z, .stop
+ ld a, [wFirstTwoReelsMatchingSevens]
+ and a
+ jr z, .stop
+ ld a, [wSlotBias]
+ and a
+ jr nz, .biased
+ call Random
+ cp 180
+ jr nc, .stop
+ cp 120
+ jr nc, .slow_advance
+ cp 60
+ jr nc, .golem
+ ld a, REEL_ACTION_INIT_CHANSEY
+ ret
+
+.biased
+ call Random
+ cp 160
+ jr nc, .stop
+ cp 80
+ jr nc, .slow_advance
+.golem
+ ld a, REEL_ACTION_INIT_GOLEM
+ ret
+
+.slow_advance
+ ld a, REEL_ACTION_START_SLOW_ADVANCE_REEL3
+ ret
+
+.stop
+ ld a, REEL_ACTION_STOP_REEL3
+ ret
+
+Slots_InitReelTiles: ; 92a98 (24:6a98)
+ ld bc, wReel1
+ ld hl, REEL_OAM_ADDR
+ add hl, bc
+ ld de, wVirtualOAMSprite16
+ ld [hl], e
+ inc hl
+ ld [hl], d
+ ld hl, REEL_TILEMAP_ADDR
+ add hl, bc
+ ld de, Reel1Tilemap
+ ld [hl], e
+ inc hl
+ ld [hl], d
+ ld hl, REEL_X_COORD
+ add hl, bc
+ ld [hl], 6 * 8
+ call .OAM
+
+ ld bc, wReel2
+ ld hl, REEL_OAM_ADDR
+ add hl, bc
+ ld de, wVirtualOAMSprite24
+ ld [hl], e
+ inc hl
+ ld [hl], d
+ ld hl, REEL_TILEMAP_ADDR
+ add hl, bc
+ ld de, Reel2Tilemap
+ ld [hl], e
+ inc hl
+ ld [hl], d
+ ld hl, REEL_X_COORD
+ add hl, bc
+ ld [hl], 10 * 8
+ call .OAM
+
+ ld bc, wReel3
+ ld hl, REEL_OAM_ADDR
+ add hl, bc
+ ld de, wVirtualOAMSprite32
+ ld [hl], e
+ inc hl
+ ld [hl], d
+ ld hl, REEL_TILEMAP_ADDR
+ add hl, bc
+ ld de, Reel3Tilemap
+ ld [hl], e
+ inc hl
+ ld [hl], d
+ ld hl, REEL_X_COORD
+ add hl, bc
+ ld [hl], 14 * 8
+ call .OAM
+ ret
+
+.OAM: ; 92af9 (24:6af9)
+ ld hl, REEL_ACTION
+ add hl, bc
+ ld [hl], REEL_ACTION_DO_NOTHING
+ ld hl, REEL_POSITION
+ add hl, bc
+ ld [hl], REEL_SIZE - 1
+ ld hl, REEL_SPIN_DISTANCE
+ add hl, bc
+ ld [hl], REEL_ACTION_DO_NOTHING
+ call Slots_UpdateReelPositionAndOAM
+ ret
+
+Slots_SpinReels: ; 92b0f (24:6b0f)
+ ld bc, wReel1
+ call .SpinReel
+ ld bc, wReel2
+ call .SpinReel
+ ld bc, wReel3
+ call .SpinReel
+ ret
+
+.SpinReel: ; 92b22 (24:6b22)
+ ld hl, REEL_SPIN_DISTANCE
+ add hl, bc
+ ld a, [hl]
+ and $f
+ jr nz, .skip
+ call ReelActionJumptable
+.skip
+ ld hl, REEL_SPIN_RATE
+ add hl, bc
+ ld a, [hl]
+ and a
+ ret z
+ ld d, a
+ ld hl, REEL_SPIN_DISTANCE
+ add hl, bc
+ add [hl]
+ ld [hl], a
+ and $f
+ jr z, Slots_UpdateReelPositionAndOAM
+ ld hl, REEL_OAM_ADDR
+ add hl, bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld e, $8
+.loop
+ ld a, [hl]
+ add d
+ ld [hli], a
+ inc hl
+ inc hl
+ inc hl
+ dec e
+ jr nz, .loop
+ ret
+
+Slots_UpdateReelPositionAndOAM: ; 92b53 (24:6b53)
+ ld hl, REEL_X_COORD
+ add hl, bc
+ ld a, [hl]
+ ld [wCurrReelXCoord], a
+ ld a, 10 * 8
+ ld [wCurrReelYCoord], a
+ ld hl, REEL_POSITION
+ add hl, bc
+ ld e, [hl]
+ ld d, 0
+ ld hl, REEL_TILEMAP_ADDR
+ add hl, bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ add hl, de
+ ld e, l
+ ld d, h
+ call .LoadOAM
+ ld hl, REEL_POSITION
+ add hl, bc
+ ld a, [hl]
+ inc a
+ and $f
+ cp REEL_SIZE
+ jr nz, .load
+ xor a
+.load
+ ld [hl], a
+ ret
+
+.LoadOAM: ; 92b83 (24:6b83)
+ ld hl, REEL_OAM_ADDR
+ add hl, bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+.loop
+ ld a, [wCurrReelYCoord]
+ ld [hli], a ; y
+ ld a, [wCurrReelXCoord]
+ ld [hli], a ; x
+ ld a, [de]
+ ld [hli], a ; tile id
+ srl a
+ srl a
+ set OAM_PRIORITY, a
+ ld [hli], a ; attributes
+
+ ld a, [wCurrReelYCoord]
+ ld [hli], a ; y
+ ld a, [wCurrReelXCoord]
+ add 1 * TILE_WIDTH
+ ld [hli], a ; x
+ ld a, [de]
+ inc a
+ inc a
+ ld [hli], a ; tile id
+ srl a
+ srl a
+ set OAM_PRIORITY, a
+ ld [hli], a ; attributes
+ inc de
+ ld a, [wCurrReelYCoord]
+ sub 2 * TILE_WIDTH
+ ld [wCurrReelYCoord], a
+ cp 2 * TILE_WIDTH
+ jr nz, .loop
+ ret
+
+; 92bbe (24:6bbe)
+
+Unreferenced_Function92bbe: ; 92bbe
+ push hl
+ srl a
+ srl a
+ add LOW(.Unknown_92bce)
+ ld l, a
+ ld a, 0
+ adc HIGH(.Unknown_92bce)
+ ld h, a
+ ld a, [hl]
+ pop hl
+ ret
+
+; 92bce
+
+.Unknown_92bce: ; 92bce
+ db 0, 1, 2, 3, 4, 5
+; 92bd4
+
+ReelActionJumptable: ; 92bd4 (24:6bd4)
+ ld hl, REEL_ACTION
+ add hl, bc
+ ld e, [hl]
+ ld d, 0
+ ld hl, .Jumptable
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ jp hl
+
+; 92be4 (24:6be4)
+
+.Jumptable: ; 92be4
+ dw ReelAction_DoNothing ; 00
+ dw ReelAction_StopReelIgnoreJoypad ; 01
+ dw ReelAction_QuadrupleRate ; 02
+ dw ReelAction_DoubleRate ; 03
+ dw ReelAction_NormalRate ; 04
+ dw ReelAction_HalfRate ; 05
+ dw ReelAction_QuarterRate ; 06
+ dw ReelAction_StopReel1 ; 07
+ dw ReelAction_StopReel2 ; 08
+ dw ReelAction_StopReel3 ; 09
+ dw ReelAction_SetUpReel2SkipTo7 ; 0a
+ dw ReelAction_WaitReel2SkipTo7 ; 0b
+ dw ReelAction_FastSpinReel2UntilLinedUp7s ; 0c
+ dw ReelAction_Unused ; 0d
+ dw ReelAction_CheckDropReel ; 0e
+ dw ReelAction_WaitDropReel ; 0f
+ dw ReelAction_StartSlowAdvanceReel3 ; 10
+ dw ReelAction_WaitSlowAdvanceReel3 ; 11
+ dw ReelAction_InitGolem ; 12
+ dw ReelAction_WaitGolem ; 13
+ dw ReelAction_EndGolem ; 14
+ dw ReelAction_InitChansey ; 15
+ dw ReelAction_WaitChansey ; 16
+ dw ReelAction_WaitEgg ; 17
+ dw ReelAction_DropReel ; 18
+; 92c16
+
+ReelAction_DoNothing: ; 92c16
+ ret
+
+; 92c17
+
+ReelAction_QuadrupleRate: ; 92c17
+ ld hl, REEL_SPIN_RATE
+ add hl, bc
+ ld [hl], 16
+ ret
+
+; 92c1e
+
+ReelAction_DoubleRate: ; 92c1e
+ ld hl, REEL_SPIN_RATE
+ add hl, bc
+ ld [hl], 8
+ ret
+
+; 92c25
+
+ReelAction_NormalRate: ; 92c25
+ ld hl, REEL_SPIN_RATE
+ add hl, bc
+ ld [hl], 4
+ ret
+
+; 92c2c
+
+ReelAction_HalfRate: ; 92c2c
+ ld hl, REEL_SPIN_RATE
+ add hl, bc
+ ld [hl], 2
+ ret
+
+; 92c33
+
+ReelAction_QuarterRate: ; 92c33
+ ld hl, REEL_SPIN_RATE
+ add hl, bc
+ ld [hl], 1
+ ret
+
+; 92c3a
+
+Slots_StopReel: ; 92c3a
+ ld hl, REEL_SPIN_RATE
+ add hl, bc
+ ld [hl], 0
+ ld hl, REEL_ACTION
+ add hl, bc
+ ld [hl], REEL_ACTION_STOP_REEL_IGNORE_JOYPAD
+ ld hl, REEL_STOP_DELAY
+ add hl, bc
+ ld [hl], 3
+ReelAction_StopReelIgnoreJoypad: ; 92c4c
+ ld hl, REEL_STOP_DELAY
+ add hl, bc
+ ld a, [hl]
+ and a
+ jr z, .EndReel
+ dec [hl]
+ ret
+
+.EndReel:
+ ld hl, REEL_ACTION
+ add hl, bc
+ ld a, REEL_ACTION_DO_NOTHING
+ ld [hl], a
+ ret
+
+; 92c5e
+
+ReelAction_StopReel1: ; 92c5e
+; If no bias: don't manipulate reel.
+; If bias: manipulate reel up to wReel1ManipCounter (i.e. 4) slots,
+; stoping early if the biased symbol shows up anywhere in reel #1,
+; even if the current bet won't allow lining it up.
+
+ ld a, [wSlotBias]
+ cp SLOTS_NO_BIAS
+ jr z, .NoBias
+ ld hl, REEL_MANIP_COUNTER
+ add hl, bc
+ ld a, [hl]
+ and a
+ jr z, .NoBias
+ dec [hl]
+ call .CheckForBias
+ ret nz
+.NoBias:
+ call Slots_StopReel
+ ret
+
+; 92c76
+
+.CheckForBias: ; 92c76
+ call Slots_GetCurrentReelState
+ ld a, [wSlotBias]
+ ld e, a
+ ld a, [hli]
+ cp e
+ ret z
+ ld a, [hli]
+ cp e
+ ret z
+ ld a, [hl]
+ cp e
+ ret
+
+; 92c86
+
+ReelAction_StopReel2: ; 92c86
+; If no bias: don't manipulate reel.
+; If bias: manipulate reel up to wReel2ManipCounter (i.e. 4) slots,
+; stoping early if the biased symbol is lined up in the first two
+; reels, according to the lines that the current bet allows.
+
+ call Slots_CheckMatchedFirstTwoReels
+ jr nc, .nope
+ ld a, [wSlotBuildingMatch]
+ ld hl, wSlotBias
+ cp [hl]
+ jr z, .NoBias
+.nope
+ ld a, [wSlotBias]
+ cp SLOTS_NO_BIAS
+ jr z, .NoBias
+ ld hl, REEL_MANIP_COUNTER
+ add hl, bc
+ ld a, [hl]
+ and a
+ jr z, .NoBias
+ dec [hl]
+ ret
+
+.NoBias:
+ call Slots_StopReel
+ ret
+
+; 92ca9
+
+ReelAction_StopReel3: ; 92ca9
+; Manipulate the reel up to wReel3ManipCounter (i.e. 4) slots,
+; stopping early if the bias symbol is lined up for a win.
+; If not biased to any symbols, stop as soon as nothing is lined up.
+
+ call Slots_CheckMatchedAllThreeReels
+ jr nc, .NoMatch
+ ld hl, wSlotBias
+ cp [hl]
+ jr z, .NoBias
+ ld hl, REEL_MANIP_COUNTER
+ add hl, bc
+ ld a, [hl]
+ and a
+ ret z
+ dec [hl]
+ ret
+
+.NoMatch:
+ ld a, [wSlotBias]
+ cp SLOTS_NO_BIAS
+ jr z, .NoBias
+ ld hl, REEL_MANIP_COUNTER
+ add hl, bc
+ ld a, [hl]
+ and a
+ jr z, .NoBias
+ dec [hl]
+ ret
+
+.NoBias:
+ call Slots_StopReel
+ ret
+
+; 92cd2
+
+ReelAction_SetUpReel2SkipTo7: ; 92cd2
+; Unique reel 2 action (see Slots_StopReel2)
+; Ensures that 7 symbols become lined up in the first two reels,
+; but more often than not, this is only a way to get our hopes up, as
+; it makes exciting reel #3 modes with no success hope more common.
+
+ call Slots_CheckMatchedFirstTwoReels
+ jr nc, .no_match
+ ld a, [wFirstTwoReelsMatchingSevens]
+ and a
+ jr z, .no_match
+ call Slots_StopReel
+ ret
+
+.no_match
+ ld a, SFX_STOP_SLOT
+ call Slots_PlaySFX
+ ld hl, REEL_ACTION
+ add hl, bc
+ inc [hl] ; REEL_ACTION_WAIT_REEL2_SKIP_TO_7
+ ld hl, REEL_MANIP_DELAY
+ add hl, bc
+ ld [hl], 32
+ ld hl, REEL_SPIN_RATE
+ add hl, bc
+ ld [hl], 0
+ ret
+
+; 92cf8
+
+ReelAction_WaitReel2SkipTo7: ; 92cf8
+ ld hl, REEL_MANIP_DELAY
+ add hl, bc
+ ld a, [hl]
+ and a
+ jr z, .asm_92d02
+ dec [hl]
+ ret
+
+.asm_92d02
+ ld a, SFX_THROW_BALL
+ call Slots_PlaySFX
+ ld hl, REEL_ACTION
+ add hl, bc
+ inc [hl] ; REEL_ACTION_FAST_SPIN_REEL2_UNTIL_LINED_UP_7S
+ ld hl, REEL_SPIN_RATE
+ add hl, bc
+ ld [hl], 8
+ ret
+
+; 92d13
+
+ReelAction_FastSpinReel2UntilLinedUp7s: ; 92d13
+ call Slots_CheckMatchedFirstTwoReels
+ ret nc
+ ld a, [wFirstTwoReelsMatchingSevens]
+ and a
+ ret z
+ call Slots_StopReel
+ ret
+
+; 92d20
+
+ReelAction_InitGolem: ; 92d20
+; Ensures SEVENs are lined up if there's bias to SEVEN.
+; Ensures nothing is lined up if there's no bias symbols.
+; No other bias symbols are compatible with this mode.
+
+; This is achieved by throwing Golem until the desired result
+; is produced. The amount of Golem thrown can be anywhere from
+; 1 to 14 for SEVEN bias, and 4-8 for no bias.
+
+ call Slots_CheckMatchedAllThreeReels
+ ret c
+ ld a, SFX_STOP_SLOT
+ call Slots_PlaySFX
+ call Slots_WaitSFX
+ ld hl, REEL_ACTION
+ add hl, bc
+ inc [hl] ; REEL_ACTION_WAIT_GOLEM
+ ld hl, REEL_SPIN_RATE
+ add hl, bc
+ ld [hl], 0
+ call Slots_GetNumberOfGolems
+ push bc
+ push af
+ depixel 12, 13
+ ld a, SPRITE_ANIM_INDEX_SLOTS_GOLEM
+ call _InitSpriteAnimStruct
+ ld hl, SPRITEANIMSTRUCT_0E
+ add hl, bc
+ pop af
+ ld [hl], a
+ pop bc
+ xor a
+ ld [wSlotsDelay], a
+ReelAction_WaitGolem: ; 92d4f
+ ld a, [wSlotsDelay]
+ cp 2
+ jr z, .two
+ cp 1
+ jr z, .one
+ ret
+
+.two
+ call Slots_CheckMatchedAllThreeReels
+ call Slots_StopReel
+ ret
+
+.one
+ ld hl, REEL_ACTION
+ add hl, bc
+ inc [hl] ; REEL_ACTION_END_GOLEM
+ ld hl, REEL_SPIN_RATE
+ add hl, bc
+ ld [hl], 8
+ ret
+
+; 92d6e
+
+ReelAction_EndGolem: ; 92d6e
+ xor a
+ ld [wSlotsDelay], a
+ ld hl, REEL_ACTION
+ add hl, bc
+ dec [hl] ; REEL_ACTION_WAIT_GOLEM
+ ld hl, REEL_SPIN_RATE
+ add hl, bc
+ ld [hl], 0
+ ret
+
+; 92d7e
+
+ReelAction_InitChansey: ; 92d7e
+; Ensures the lining up of SEVEN symbols, but this mode is only possible
+; when there is bias to SEVEN symbols (and even then, it's still rare).
+; Chansey releases and egg and reel #3 is made to advance 17 slots very
+; quickly as many times as necessary for the match to SEVENs to show up.
+
+ call Slots_CheckMatchedAllThreeReels
+ ret c
+ ld a, SFX_STOP_SLOT
+ call Slots_PlaySFX
+ call Slots_WaitSFX
+ ld hl, REEL_ACTION
+ add hl, bc
+ inc [hl] ; REEL_ACTION_WAIT_CHANSEY
+ ld hl, REEL_SPIN_RATE
+ add hl, bc
+ ld [hl], 0
+ push bc
+ depixel 12, 0
+ ld a, SPRITE_ANIM_INDEX_SLOTS_CHANSEY
+ call _InitSpriteAnimStruct
+ pop bc
+ xor a
+ ld [wSlotsDelay], a
+ ret
+
+; 92da4
+
+ReelAction_WaitChansey: ; 92da4
+ ld a, [wSlotsDelay]
+ and a
+ ret z
+ ld hl, REEL_ACTION
+ add hl, bc
+ inc [hl] ; REEL_ACTION_WAIT_EGG
+ ld a, 2
+ ld [wSlotsDelay], a
+ReelAction_WaitEgg: ; 92db3
+ ld a, [wSlotsDelay]
+ cp $4
+ ret c
+ ld hl, REEL_ACTION
+ add hl, bc
+ inc [hl] ; REEL_ACTION_DROP_REEL
+ ld hl, REEL_SPIN_RATE
+ add hl, bc
+ ld [hl], 16
+ ld hl, REEL_MANIP_DELAY
+ add hl, bc
+ ld [hl], 17
+ReelAction_DropReel: ; 92dca
+ ld hl, REEL_MANIP_DELAY
+ add hl, bc
+ ld a, [hl]
+ and a
+ jr z, .check_match
+ dec [hl]
+ ret
+
+.check_match
+ call Slots_CheckMatchedAllThreeReels
+ jr nc, .EggAgain
+ and a
+ jr nz, .EggAgain
+ ld a, 5
+ ld [wSlotsDelay], a
+ call Slots_StopReel
+ ret
+
+.EggAgain:
+ ld hl, REEL_SPIN_RATE
+ add hl, bc
+ ld [hl], 0
+ ld hl, REEL_ACTION
+ add hl, bc
+ dec [hl]
+ dec [hl] ; REEL_ACTION_WAIT_CHANSEY
+ ld a, 1
+ ld [wSlotsDelay], a
+ ret
+
+; 92df7
+
+ReelAction_Unused: ; 92df7
+ call Slots_CheckMatchedAllThreeReels
+ ret c
+ ld a, SFX_STOP_SLOT
+ call Slots_PlaySFX
+ call Slots_WaitSFX
+ ld hl, REEL_ACTION
+ add hl, bc
+ inc [hl] ; REEL_ACTION_CHECK_DROP_REEL
+ call Slots_GetNumberOfGolems
+ ld hl, REEL_MANIP_DELAY
+ add hl, bc
+ ld [hl], a
+ReelAction_CheckDropReel: ; 92e10
+ ld hl, REEL_MANIP_DELAY
+ add hl, bc
+ ld a, [hl]
+ and a
+ jr nz, .spin
+ call Slots_CheckMatchedAllThreeReels
+ call Slots_StopReel
+ ret
+
+.spin
+ dec [hl]
+ ld hl, REEL_ACTION
+ add hl, bc
+ inc [hl] ; REEL_ACTION_WAIT_DROP_REEL
+ ld hl, REEL_FIELD_0B
+ add hl, bc
+ ld [hl], 32
+ ld hl, REEL_SPIN_RATE
+ add hl, bc
+ ld [hl], 0
+ReelAction_WaitDropReel: ; 92e31
+ ld hl, REEL_FIELD_0B
+ add hl, bc
+ ld a, [hl]
+ and a
+ jr z, .DropReel
+ dec [hl]
+ ret
+
+.DropReel:
+ ld hl, REEL_ACTION
+ add hl, bc
+ dec [hl]
+ ld hl, REEL_SPIN_RATE
+ add hl, bc
+ ld [hl], 8
+ ret
+
+; 92e47
+
+ReelAction_StartSlowAdvanceReel3: ; 92e47
+; Ensures SEVENs are lined up if there's bias to SEVEN.
+; Ensures nothing is lined up if there's no bias symbols.
+; No other bias symbols are compatible with this mode.
+
+; This is achieved by slowly advancing the reel a full round,
+; plus any necessary slot until the desired result is produced.
+
+ call Slots_CheckMatchedAllThreeReels
+ ret c
+ ld a, SFX_STOP_SLOT
+ call Slots_PlaySFX
+ call Slots_WaitSFX
+ ld hl, REEL_SPIN_RATE
+ add hl, bc
+ ld [hl], 1
+ ld hl, REEL_ACTION
+ add hl, bc
+ inc [hl] ; REEL_ACTION_WAIT_SLOW_ADVANCE_REEL3
+ ld hl, REEL_MANIP_DELAY
+ add hl, bc
+ ld [hl], 16
+ReelAction_WaitSlowAdvanceReel3: ; 92e64
+ ld hl, REEL_MANIP_DELAY
+ add hl, bc
+ ld a, [hl]
+ and a
+ jr z, .check1
+ dec [hl]
+.play_sfx
+ ld a, SFX_GOT_SAFARI_BALLS
+ call Slots_PlaySFX
+ ret
+
+.check1
+ ld a, [wSlotBias]
+ and a
+ jr nz, .check2
+ call Slots_CheckMatchedAllThreeReels
+ jr nc, .play_sfx
+ and a
+ jr nz, .play_sfx
+ call Slots_StopReel
+ call WaitSFX
+ ret
+
+.check2
+ call Slots_CheckMatchedAllThreeReels
+ jr c, .play_sfx
+ call Slots_StopReel
+ call WaitSFX
+ ret
+
+; 92e94
+
+Slots_CheckMatchedFirstTwoReels: ; 92e94
+ xor a
+ ld [wFirstTwoReelsMatching], a
+ ld [wFirstTwoReelsMatchingSevens], a
+ call Slots_GetCurrentReelState
+ call Slots_CopyReelState
+ ld a, [wSlotBet]
+ and 3
+ ld e, a
+ ld d, 0
+ ld hl, .Jumptable
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld de, .return
+ push de
+ jp hl
+
+.return
+ ld a, [wFirstTwoReelsMatching]
+ and a
+ ret z
+ scf
+ ret
+
+; 92ebd
+
+.Jumptable: ; 92ebd
+ dw .zero
+ dw .one
+ dw .two
+ dw .three
+; 92ec5
+
+.three ; 92ec5
+ call .CheckUpwardsDiag
+ call .CheckDownwardsDiag
+
+.two ; 92ecb
+ call .CheckBottomRow
+ call .CheckTopRow
+
+.one ; 92ed1
+ call .CheckMiddleRow
+
+.zero ; 92ed4
+ ret
+
+; 92ed5
+
+.CheckBottomRow: ; 92ed5
+ ld hl, wCurrReelStopped
+ ld a, [wReel1Stopped]
+ cp [hl]
+ call z, .StoreResult
+ ret
+
+; 92ee0
+
+.CheckUpwardsDiag: ; 92ee0
+ ld hl, wCurrReelStopped + 1
+ ld a, [wReel1Stopped]
+ cp [hl]
+ call z, .StoreResult
+ ret
+
+; 92eeb
+
+.CheckMiddleRow: ; 92eeb
+ ld hl, wCurrReelStopped + 1
+ ld a, [wReel1Stopped + 1]
+ cp [hl]
+ call z, .StoreResult
+ ret
+
+; 92ef6
+
+.CheckDownwardsDiag: ; 92ef6
+ ld hl, wCurrReelStopped + 1
+ ld a, [wReel1Stopped + 2]
+ cp [hl]
+ call z, .StoreResult
+ ret
+
+; 92f01
+
+.CheckTopRow: ; 92f01
+ ld hl, wCurrReelStopped + 2
+ ld a, [wReel1Stopped + 2]
+ cp [hl]
+ call z, .StoreResult
+ ret
+
+; 92f0c
+
+.StoreResult: ; 92f0c
+ ld [wSlotBuildingMatch], a
+ and a
+ jr nz, .matching_sevens
+ ld a, 1
+ ld [wFirstTwoReelsMatchingSevens], a
+
+.matching_sevens
+ ld a, 1
+ ld [wFirstTwoReelsMatching], a
+ ret
+
+; 92f1d
+
+Slots_CheckMatchedAllThreeReels: ; 92f1d
+ ld a, SLOTS_NO_MATCH
+ ld [wSlotMatched], a
+ call Slots_GetCurrentReelState
+ call Slots_CopyReelState
+ ld a, [wSlotBet]
+ and 3
+ ld e, a
+ ld d, 0
+ ld hl, .Jumptable
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld de, .return
+ push de
+ jp hl
+
+.return
+ ld a, [wSlotMatched]
+ cp SLOTS_NO_MATCH
+ jr nz, .matched_nontrivial
+ and a
+ ret
+
+.matched_nontrivial
+ scf
+ ret
+
+; 92f48
+
+.Jumptable: ; 92f48
+ dw .zero
+ dw .one
+ dw .two
+ dw .three
+; 92f50
+
+.three ; 92f50
+ call .CheckUpwardsDiag
+ call .CheckDownwardsDiag
+
+.two ; 92f56
+ call .CheckBottomRow
+ call .CheckTopRow
+
+.one ; 92f5c
+ call .CheckMiddleRow
+
+.zero ; 92f5f
+ ret
+
+; 92f60
+
+.CheckBottomRow: ; 92f60
+ ld hl, wCurrReelStopped
+ ld a, [wReel1Stopped]
+ cp [hl]
+ ret nz
+ ld hl, wReel2Stopped
+ cp [hl]
+ call z, .StoreResult
+ ret
+
+; 92f70
+
+.CheckUpwardsDiag: ; 92f70
+ ld hl, wCurrReelStopped + 2
+ ld a, [wReel1Stopped]
+ cp [hl]
+ ret nz
+ ld hl, wReel2Stopped + 1
+ cp [hl]
+ call z, .StoreResult
+ ret
+
+; 92f80
+
+.CheckMiddleRow: ; 92f80
+ ld hl, wCurrReelStopped + 1
+ ld a, [wReel1Stopped + 1]
+ cp [hl]
+ ret nz
+ ld hl, wReel2Stopped + 1
+ cp [hl]
+ call z, .StoreResult
+ ret
+
+; 92f90
+
+.CheckDownwardsDiag: ; 92f90
+ ld hl, wCurrReelStopped
+ ld a, [wReel1Stopped + 2]
+ cp [hl]
+ ret nz
+ ld hl, wReel2Stopped + 1
+ cp [hl]
+ call z, .StoreResult
+ ret
+
+; 92fa0
+
+.CheckTopRow: ; 92fa0
+ ld hl, wCurrReelStopped + 2
+ ld a, [wReel1Stopped + 2]
+ cp [hl]
+ ret nz
+ ld hl, wReel2Stopped + 2
+ cp [hl]
+ call z, .StoreResult
+ ret
+
+; 92fb0
+
+.StoreResult: ; 92fb0
+ ld [wSlotMatched], a
+ ret
+
+; 92fb4
+
+Slots_CopyReelState: ; 92fb4
+ ld de, wCurrReelStopped
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hl]
+ ld [de], a
+ ret
+
+; 92fc0
+
+Slots_GetNumberOfGolems: ; 92fc0
+ ld hl, REEL_POSITION
+ add hl, bc
+ ld a, [hl]
+ push af
+ push hl
+ call .Check7Bias
+ pop hl
+ pop af
+ ld [hl], a
+ ld a, e
+ ret
+
+; 92fcf
+
+.Check7Bias: ; 92fcf
+ ld a, [wSlotBias]
+ and a
+ jr nz, .not_biased_to_seven
+ ld e, $0
+.loop1
+ ld hl, REEL_POSITION
+ add hl, bc
+ inc [hl]
+ inc e
+ push de
+ call Slots_CheckMatchedAllThreeReels
+ pop de
+ jr nc, .loop1
+ and a
+ jr nz, .loop1
+ ret
+
+.not_biased_to_seven
+ call Random
+ and $7
+ cp $4 ; ((50 percent) & 7) + 1
+ jr c, .not_biased_to_seven
+ ld e, a
+.loop2
+ ld a, e
+ inc e
+ ld hl, REEL_POSITION
+ add hl, bc
+ add [hl]
+ ld [hl], a
+ push de
+ call Slots_CheckMatchedAllThreeReels
+ pop de
+ jr c, .loop2
+ ret
+
+; 93002
+
+Slots_InitBias: ; 93002 (24:7002)
+ ld a, [wSlotBias]
+ and a
+ ret z
+ ld hl, .Normal
+ ld a, [wScriptVar]
+ and a
+ jr z, .okay
+ ld hl, .Lucky
+.okay
+ call Random
+ ld c, a
+.loop
+ ld a, [hli]
+ cp c
+ jr nc, .done
+ inc hl
+ jr .loop
+
+.done
+ ld a, [hl]
+ ld [wSlotBias], a
+ ret
+
+; 93023 (24:7023)
+
+.Normal: ; 93023
+ db $01, SLOTS_SEVEN ; 1/256
+ db $03, SLOTS_POKEBALL ; 1/128
+ db $0a, SLOTS_STARYU ; 7/256
+ db $14, SLOTS_SQUIRTLE ; 5/128
+ db $28, SLOTS_PIKACHU ; 5/64
+ db $30, SLOTS_CHERRY ; 1/32
+ db $ff, SLOTS_NO_BIAS ; everything else
+; 93031
+
+.Lucky: ; 93031
+ db $02, SLOTS_SEVEN ; 1/128
+ db $03, SLOTS_POKEBALL ; 1/256
+ db $08, SLOTS_STARYU ; 5/256
+ db $10, SLOTS_SQUIRTLE ; 1/32
+ db $1e, SLOTS_PIKACHU ; 7/128
+ db $50, SLOTS_CHERRY ; 25/128
+ db $ff, SLOTS_NO_BIAS ; everything else
+; 9303f
+
+Slots_IlluminateBetLights: ; 9303f (24:703f)
+ ld b, $14 ; turned on
+ ld a, [wSlotBet]
+ dec a
+ jr z, Slots_Lights1OnOff
+ dec a
+ jr z, Slots_Lights2OnOff
+ jr Slots_Lights3OnOff
+
+Slots_DeilluminateBetLights: ; 9304c (24:704c)
+ ld b, $23 ; turned off
+Slots_Lights3OnOff: ; 9304e (24:704e)
+ hlcoord 3, 2
+ call Slots_TurnLightsOnOrOff
+ hlcoord 3, 10
+ call Slots_TurnLightsOnOrOff
+Slots_Lights2OnOff: ; 9305a (24:705a)
+ hlcoord 3, 4
+ call Slots_TurnLightsOnOrOff
+ hlcoord 3, 8
+ call Slots_TurnLightsOnOrOff
+Slots_Lights1OnOff: ; 93066 (24:7066)
+ hlcoord 3, 6
+
+Slots_TurnLightsOnOrOff: ; 93069 (24:7069)
+ ld a, b
+ ld [hl], a
+ ld de, SCREEN_WIDTH / 2 + 3
+ add hl, de
+ ld [hl], a
+ ld de, SCREEN_WIDTH / 2 - 3
+ add hl, de
+ inc a
+ ld [hl], a
+ ld de, SCREEN_WIDTH / 2 + 3
+ add hl, de
+ ld [hl], a
+ ret
+
+Slots_AskBet: ; 9307c (24:707c)
+.loop
+ ld hl, .Text_BetHowManyCoins
+ call PrintText
+ ld hl, .MenuHeader
+ call LoadMenuHeader
+ call VerticalMenu
+ call CloseWindow
+ ret c
+ ld a, [wMenuCursorY]
+ ld b, a
+ ld a, 4
+ sub b
+ ld [wSlotBet], a
+ ld hl, wCoins
+ ld c, a
+ ld a, [hli]
+ and a
+ jr nz, .Start
+ ld a, [hl]
+ cp c
+ jr nc, .Start
+ ld hl, .Text_NotEnoughCoins
+ call PrintText
+ jr .loop
+
+.Start:
+ ld hl, wCoins + 1
+ ld a, [hl]
+ sub c
+ ld [hld], a
+ jr nc, .ok
+ dec [hl]
+.ok
+ call WaitSFX
+ ld de, SFX_PAY_DAY
+ call PlaySFX
+ ld hl, .Text_Start
+ call PrintText
+ and a
+ ret
+
+; 930c7 (24:70c7)
+
+.Text_BetHowManyCoins: ; 0x930c7
+ ; Bet how many coins?
+ text_jump UnknownText_0x1c5049
+ db "@"
+; 0x930cc
+
+.Text_Start: ; 0x930cc
+ ; Start!
+ text_jump UnknownText_0x1c505e
+ db "@"
+; 0x930d1
+
+.Text_NotEnoughCoins: ; 0x930d1
+ ; Not enough coins.
+ text_jump UnknownText_0x1c5066
+ db "@"
+; 0x930d6
+
+.MenuHeader: ; 0x930d6
+ db MENU_BACKUP_TILES ; flags
+ menu_coords 14, 10, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1
+ dw .MenuData
+ db 1 ; default option
+; 0x930de
+
+.MenuData: ; 0x930de
+ db STATICMENU_CURSOR ; flags
+ db 3 ; items
+ db " 3@"
+ db " 2@"
+ db " 1@"
+; 0x930e9
+
+Slots_AskPlayAgain: ; 930e9 (24:70e9)
+ ld hl, wCoins
+ ld a, [hli]
+ or [hl]
+ jr nz, .you_have_coins
+ ld hl, .Text_OutOfCoins
+ call PrintText
+ ld c, 60
+ call DelayFrames
+ jr .exit_slots
+
+.you_have_coins
+ ld hl, .Text_PlayAgain
+ call PrintText
+ call LoadMenuTextBox
+ lb bc, 14, 12
+ call PlaceYesNoBox
+ ld a, [wMenuCursorY]
+ dec a
+ call CloseWindow
+ and a
+ jr nz, .exit_slots
+ and a
+ ret
+
+.exit_slots
+ scf
+ ret
+
+; 9311a (24:711a)
+
+.Text_OutOfCoins: ; 9311a
+ text_jump UnknownText_0x1c5079
+ db "@"
+
+.Text_PlayAgain: ; 9311f
+ text_jump UnknownText_0x1c5092
+ db "@"
+
+Slots_GetPayout: ; 93124 (24:7124)
+ ld a, [wSlotMatched]
+ cp SLOTS_NO_MATCH
+ jr z, .no_win
+ srl a
+ ld e, a
+ ld d, 0
+ ld hl, .PayoutTable
+ add hl, de
+ ld a, [hli]
+ ld [wPayout + 1], a
+ ld e, a
+ ld a, [hl]
+ ld [wPayout], a
+ ld d, a
+ farcall StubbedTrainerRankings_AddToSlotsPayouts
+ ret
+
+.PayoutTable:
+ dw 300
+ dw 50
+ dw 6
+ dw 8
+ dw 10
+ dw 15
+
+.no_win
+ ld hl, wPayout
+ xor a
+ ld [hli], a
+ ld [hl], a
+ ret
+
+Slots_PayoutText: ; 93158 (24:7158)
+ ld a, [wSlotMatched]
+ cp SLOTS_NO_MATCH
+ jr nz, .MatchedSomething
+ ld hl, .Text_Darn
+ call PrintText
+ farcall StubbedTrainerRankings_EndSlotsWinStreak
+ ret
+
+.MatchedSomething:
+ srl a
+ ld e, a
+ ld d, 0
+ ld hl, .PayoutStrings
+ add hl, de
+ add hl, de
+ add hl, de
+ ld de, wStringBuffer2
+ ld bc, 4
+ call CopyBytes
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld de, .return
+ push de
+ jp hl
+
+.return
+ ld hl, .Text_PrintPayout
+ call PrintText
+ farcall StubbedTrainerRankings_AddToSlotsWinStreak
+ ret
+
+; 93195 (24:7195)
+
+.PayoutStrings: ; 93195
+ dbw "300@", .LinedUpSevens
+ dbw "50@@", .LinedUpPokeballs
+ dbw "6@@@", .LinedUpMonOrCherry
+ dbw "8@@@", .LinedUpMonOrCherry
+ dbw "10@@", .LinedUpMonOrCherry
+ dbw "15@@", .LinedUpMonOrCherry
+; 931b9
+
+.Text_PrintPayout: ; 0x931b9
+ start_asm
+ ld a, [wSlotMatched]
+ add $25
+ ldcoord_a 2, 13
+ inc a
+ ldcoord_a 2, 14
+ inc a
+ ldcoord_a 3, 13
+ inc a
+ ldcoord_a 3, 14
+ hlcoord 18, 17
+ ld [hl], "▼"
+ ld hl, .Text_LinedUpWonCoins
+rept 4
+ inc bc
+endr
+ ret
+
+; 931db
+
+.Text_LinedUpWonCoins: ; 0x931db
+ ; lined up! Won @ coins!
+ text_jump UnknownText_0x1c509f
+ db "@"
+; 0x931e0
+
+.Text_Darn: ; 0x931e0
+ ; Darn!
+ text_jump UnknownText_0x1c50bb
+ db "@"
+; 0x931e5
+
+.LinedUpSevens: ; 931e5
+ ld a, SFX_2ND_PLACE
+ call Slots_PlaySFX
+ call WaitSFX
+
+; Oddly, the rarest mode (wKeepSevenBiasChance = 1) is the one with
+; the worse odds to favor seven symbol streaks (12.5% vs 25%).
+; it's possible that either the wKeepSevenBiasChance initialization
+; or this code was intended to lead to flipped percentages.
+ ld a, [wKeepSevenBiasChance]
+ and a
+ jr nz, .lower_seven_streak_odds
+ call Random
+ and %0010100
+ ret z ; 25% chance to stick with seven symbol bias
+ ld a, SLOTS_NO_BIAS
+ ld [wSlotBias], a
+ ret
+
+.lower_seven_streak_odds
+ call Random
+ and %0011100
+ ret z ; 12.5% chance to stick with seven symbol bias
+ ld a, SLOTS_NO_BIAS
+ ld [wSlotBias], a
+ ret
+
+; 9320b
+
+.LinedUpPokeballs: ; 9320b
+ ld a, SFX_3RD_PLACE
+ call Slots_PlaySFX
+ call WaitSFX
+ ret
+
+; 93214
+
+.LinedUpMonOrCherry: ; 93214
+ ld a, SFX_PRESENT
+ call Slots_PlaySFX
+ call WaitSFX
+ ret
+
+; 9321d
+
+Slots_AnimateGolem: ; 9321d (24:721d)
+ ld hl, SPRITEANIMSTRUCT_JUMPTABLE_INDEX
+ add hl, bc
+ ld e, [hl]
+ ld d, 0
+ ld hl, .Jumptable
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ jp hl
+
+.Jumptable: ; 9322d (24:722d)
+ dw .init
+ dw .fall
+ dw .roll
+
+.init ; 93233 (24:7233)
+ ld hl, SPRITEANIMSTRUCT_0E
+ add hl, bc
+ ld a, [hl]
+ and a
+ jr nz, .retain
+ ld a, 2
+ ld [wSlotsDelay], a
+ ld hl, SPRITEANIMSTRUCT_INDEX
+ add hl, bc
+ ld [hl], $0
+ ret
+
+.retain
+ dec [hl]
+ ld hl, SPRITEANIMSTRUCT_JUMPTABLE_INDEX
+ add hl, bc
+ inc [hl]
+ ld hl, SPRITEANIMSTRUCT_0C
+ add hl, bc
+ ld [hl], $30
+ ld hl, SPRITEANIMSTRUCT_XOFFSET
+ add hl, bc
+ ld [hl], $0
+
+.fall ; 93259 (24:7259)
+ ld hl, SPRITEANIMSTRUCT_0C
+ add hl, bc
+ ld a, [hl]
+ cp $20
+ jr c, .play_sound
+ dec [hl]
+ ld e, a
+ ld d, 14 * 8
+ farcall BattleAnim_Sine_e
+ ld a, e
+ ld hl, SPRITEANIMSTRUCT_YOFFSET
+ add hl, bc
+ ld [hl], a
+ ret
+
+.play_sound
+ ld hl, SPRITEANIMSTRUCT_JUMPTABLE_INDEX
+ add hl, bc
+ inc [hl]
+ ld hl, SPRITEANIMSTRUCT_0D
+ add hl, bc
+ ld [hl], $2
+ ld a, 1
+ ld [wSlotsDelay], a
+ ld a, SFX_PLACE_PUZZLE_PIECE_DOWN
+ call Slots_PlaySFX
+ ret
+
+.roll ; 93289 (24:7289)
+ ld hl, SPRITEANIMSTRUCT_XOFFSET
+ add hl, bc
+ ld a, [hl]
+ inc [hl]
+ inc [hl]
+ cp 9 * 8
+ jr nc, .restart
+ and $3
+ ret nz
+ ld hl, SPRITEANIMSTRUCT_0D
+ add hl, bc
+ ld a, [hl]
+ xor $ff
+ inc a
+ ld [hl], a
+ ld [hSCY], a
+ ret
+
+.restart
+ ld hl, SPRITEANIMSTRUCT_JUMPTABLE_INDEX
+ add hl, bc
+ xor a
+ ld [hl], a
+ ld [hSCY], a
+ ret
+
+Slots_AnimateChansey: ; 932ac (24:72ac)
+ ld hl, SPRITEANIMSTRUCT_JUMPTABLE_INDEX
+ add hl, bc
+ ld e, [hl]
+ ld d, 0
+ ld hl, .Jumptable
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ jp hl
+
+.Jumptable: ; 932bc (24:72bc)
+ dw .walk
+ dw .one
+ dw .two
+
+.walk ; 932c2 (24:72c2)
+ ld hl, SPRITEANIMSTRUCT_XCOORD
+ add hl, bc
+ ld a, [hl]
+ inc [hl]
+ cp 13 * 8
+ jr z, .limit
+ and $f
+ ret nz
+ ld de, SFX_JUMP_OVER_LEDGE
+ call PlaySFX
+ ret
+
+.limit
+ ld hl, SPRITEANIMSTRUCT_JUMPTABLE_INDEX
+ add hl, bc
+ inc [hl]
+ ld a, 1
+ ld [wSlotsDelay], a
+
+.one ; 932e0 (24:72e0)
+ ld a, [wSlotsDelay]
+ cp $2
+ jr z, .retain
+ cp $5
+ ret nz
+ ld hl, SPRITEANIMSTRUCT_INDEX
+ add hl, bc
+ ld [hl], $0
+ ret
+
+.retain
+ ld hl, SPRITEANIMSTRUCT_JUMPTABLE_INDEX
+ add hl, bc
+ inc [hl]
+ ld hl, SPRITEANIMSTRUCT_0C
+ add hl, bc
+ ld [hl], $8
+.two ; 932fc (24:72fc)
+ ld hl, SPRITEANIMSTRUCT_0C
+ add hl, bc
+ ld a, [hl]
+ and a
+ jr z, .spawn_egg
+ dec [hl]
+ ret
+
+.spawn_egg
+ ld hl, SPRITEANIMSTRUCT_JUMPTABLE_INDEX
+ add hl, bc
+ dec [hl]
+ push bc
+ depixel 12, 13, 0, 4
+ ld a, SPRITE_ANIM_INDEX_SLOTS_EGG
+ call _InitSpriteAnimStruct
+ pop bc
+ ret
+
+; 93316 (24:7316)
+
+Slots_WaitSFX: ; 93316
+ push bc
+ ld c, 16
+ call DelayFrames
+ pop bc
+ ret
+
+; 9331e
+
+Slots_PlaySFX: ; 9331e (24:731e)
+ push de
+ ld e, a
+ ld d, 0
+ call PlaySFX
+ pop de
+ ret
+
+; 93327 (24:7327)
+
+; The first three positions are repeated to
+; avoid needing to check indices when copying.
+Reel1Tilemap: ; 93327
+ db SLOTS_SEVEN ; 0
+ db SLOTS_CHERRY ; 1
+ db SLOTS_STARYU ; 2
+ db SLOTS_PIKACHU ; 3
+ db SLOTS_SQUIRTLE ; 4
+ db SLOTS_SEVEN ; 5
+ db SLOTS_CHERRY ; 6
+ db SLOTS_STARYU ; 7
+ db SLOTS_PIKACHU ; 8
+ db SLOTS_SQUIRTLE ; 9
+ db SLOTS_POKEBALL ; 10
+ db SLOTS_CHERRY ; 11
+ db SLOTS_STARYU ; 12
+ db SLOTS_PIKACHU ; 13
+ db SLOTS_SQUIRTLE ; 14
+ db SLOTS_SEVEN ; 0
+ db SLOTS_CHERRY ; 1
+ db SLOTS_STARYU ; 2
+
+Reel2Tilemap: ; 93339
+ db SLOTS_SEVEN ; 0
+ db SLOTS_PIKACHU ; 1
+ db SLOTS_CHERRY ; 2
+ db SLOTS_SQUIRTLE ; 3
+ db SLOTS_STARYU ; 4
+ db SLOTS_POKEBALL ; 5
+ db SLOTS_PIKACHU ; 6
+ db SLOTS_CHERRY ; 7
+ db SLOTS_SQUIRTLE ; 8
+ db SLOTS_STARYU ; 9
+ db SLOTS_POKEBALL ; 10
+ db SLOTS_PIKACHU ; 11
+ db SLOTS_CHERRY ; 12
+ db SLOTS_SQUIRTLE ; 13
+ db SLOTS_STARYU ; 14
+ db SLOTS_SEVEN ; 0
+ db SLOTS_PIKACHU ; 1
+ db SLOTS_CHERRY ; 2
+
+Reel3Tilemap: ; 9334b
+ db SLOTS_SEVEN ; 0
+ db SLOTS_PIKACHU ; 1
+ db SLOTS_CHERRY ; 2
+ db SLOTS_SQUIRTLE ; 3
+ db SLOTS_STARYU ; 4
+ db SLOTS_PIKACHU ; 5
+ db SLOTS_CHERRY ; 6
+ db SLOTS_SQUIRTLE ; 7
+ db SLOTS_STARYU ; 8
+ db SLOTS_PIKACHU ; 9
+ db SLOTS_POKEBALL ; 10
+ db SLOTS_CHERRY ; 11
+ db SLOTS_SQUIRTLE ; 12
+ db SLOTS_STARYU ; 13
+ db SLOTS_PIKACHU ; 14
+ db SLOTS_SEVEN ; 0
+ db SLOTS_PIKACHU ; 1
+ db SLOTS_CHERRY ; 2
+; 9335d
+
+SlotsTilemap: ; 9335d
+INCBIN "gfx/slots/slots.tilemap"
+; 9344d
+
+Slots1LZ: ; 9344d
+INCBIN "gfx/slots/slots_1.2bpp.lz"
+; 935cd
+
+Slots2LZ: ; 935cd
+INCBIN "gfx/slots/slots_2.2bpp.lz"
+; 9382d
+
+Slots3LZ: ; 9382d
+INCBIN "gfx/slots/slots_3.2bpp.lz"
+; 93a3d
diff --git a/engine/games/unown_puzzle.asm b/engine/games/unown_puzzle.asm
new file mode 100644
index 000000000..300f07de4
--- /dev/null
+++ b/engine/games/unown_puzzle.asm
@@ -0,0 +1,877 @@
+PUZZLE_BORDER EQU $ee
+PUZZLE_VOID EQU $ef
+
+puzcoord EQUS "* 6 +"
+
+_UnownPuzzle: ; e1190
+ ld a, [hInMenu]
+ push af
+ ld a, $1
+ ld [hInMenu], a
+ call ClearBGPalettes
+ call ClearTileMap
+ call ClearSprites
+ xor a
+ ld [hBGMapMode], a
+ call DisableLCD
+ ld hl, wc608 ; includes wPuzzlePieces
+ ld bc, wc7e8 - wc608
+ xor a
+ call ByteFill
+ ld hl, UnownPuzzleCursorGFX
+ ld de, vTiles1 tile $60
+ ld bc, 4 tiles
+ call CopyBytes
+ ld hl, UnownPuzzleStartCancelLZ
+ ld de, vTiles1 tile $6d
+ call Decompress
+ call LoadUnownPuzzlePiecesGFX
+ hlcoord 0, 0
+ ld bc, SCREEN_WIDTH * SCREEN_HEIGHT
+ ld a, PUZZLE_BORDER
+ call ByteFill
+ hlcoord 4, 3
+ lb bc, 12, 12
+ ld a, PUZZLE_VOID
+ call UnownPuzzle_FillBox
+ call InitUnownPuzzlePiecePositions
+ call UnownPuzzle_UpdateTilemap
+ call PlaceStartCancelBox
+ xor a
+ ld [hSCY], a
+ ld [hSCX], a
+ ld [rWY], a
+ ld [wJumptableIndex], a
+ ld [wHoldingUnownPuzzlePiece], a
+ ld [wUnownPuzzleCursorPosition], a
+ ld [wUnownPuzzleHeldPiece], a
+ ld a, %10010011
+ ld [rLCDC], a
+ call WaitBGMap
+ ld b, SCGB_UNOWN_PUZZLE
+ call GetSGBLayout
+ ld a, $e4
+ call DmgToCgbBGPals
+ ld a, $24
+ call DmgToCgbObjPal0
+ xor a
+ ld [wSolvedUnownPuzzle], a
+ call DelayFrame
+.loop
+ call JoyTextDelay
+ ld a, [wJumptableIndex]
+ bit 7, a
+ jr nz, .quit
+ call UnownPuzzleJumptable
+ ld a, [wHoldingUnownPuzzlePiece]
+ and a
+ jr nz, .holding_piece
+ ld a, [hVBlankCounter]
+ and $10
+ jr z, .clear
+.holding_piece
+ call RedrawUnownPuzzlePieces
+ jr .next
+
+.clear
+ call ClearSprites
+.next
+ call DelayFrame
+ jr .loop
+
+.quit
+ pop af
+ ld [hInMenu], a
+ call ClearBGPalettes
+ call ClearTileMap
+ call ClearSprites
+ ld a, LCDC_DEFAULT
+ ld [rLCDC], a
+ ret
+; e124e
+
+InitUnownPuzzlePiecePositions: ; e124e
+ ld c, 1
+ ld b, 16
+.load_loop
+ call Random
+ and $f
+ ld hl, .PuzzlePieceInitialPositions
+ ld e, a
+ ld d, $0
+ add hl, de
+ ld e, [hl]
+ ld hl, wPuzzlePieces
+ add hl, de
+ ld a, [hl]
+ and a
+ jr nz, .load_loop
+ ld [hl], c
+ inc c
+ dec b
+ jr nz, .load_loop
+ ret
+; e126d
+
+.PuzzlePieceInitialPositions: ; e126d
+initpuzcoord: MACRO
+rept _NARG / 2
+ db \1 puzcoord \2
+ shift
+ shift
+endr
+ENDM
+ initpuzcoord 0,0, 0,1, 0,2, 0,3, 0,4, 0,5
+ initpuzcoord 1,0, 1,5
+ initpuzcoord 2,0, 2,5
+ initpuzcoord 3,0, 3,5
+ initpuzcoord 4,0, 4,5
+ initpuzcoord 5,0, 5,5
+ ; START > CANCEL
+; e127d
+
+PlaceStartCancelBox: ; e127d
+ call PlaceStartCancelBoxBorder
+ hlcoord 5, 16
+ ld a, $f6
+ ld c, 10
+.loop
+ ld [hli], a
+ inc a
+ dec c
+ jr nz, .loop
+ ret
+; e128d
+
+PlaceStartCancelBoxBorder: ; e128d
+ hlcoord 4, 15
+ ld a, $f0
+ ld [hli], a
+ ld bc, 10
+ ld a, $f1
+ call ByteFill
+ hlcoord 15, 15
+ ld a, $f2
+ ld [hli], a
+ hlcoord 4, 16
+ ld a, $f3
+ ld [hli], a
+ ld bc, 10
+ ld a, PUZZLE_VOID
+ call ByteFill
+ hlcoord 15, 16
+ ld a, $f3
+ ld [hli], a
+ hlcoord 4, 17
+ ld a, $f4
+ ld [hli], a
+ ld bc, 10
+ ld a, $f1
+ call ByteFill
+ hlcoord 15, 17
+ ld a, $f5
+ ld [hl], a
+ ret
+; e12ca
+
+UnownPuzzleJumptable: ; e12ca
+ ld a, [wJumptableIndex]
+ ld e, a
+ ld d, 0
+ ld hl, .Jumptable
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ jp hl
+; e12d9
+
+.Jumptable: ; e12d9
+ dw .Function
+; e12db
+
+.Function: ; e12db
+ ld a, [hJoyPressed]
+ and START
+ jp nz, UnownPuzzle_Quit
+ ld a, [hJoyPressed]
+ and A_BUTTON
+ jp nz, UnownPuzzle_A
+ ld hl, hJoyLast
+ ld a, [hl]
+ and D_UP
+ jr nz, .d_up
+ ld a, [hl]
+ and D_DOWN
+ jr nz, .d_down
+ ld a, [hl]
+ and D_LEFT
+ jr nz, .d_left
+ ld a, [hl]
+ and D_RIGHT
+ jr nz, .d_right
+ ret
+
+.d_up
+ ld hl, wUnownPuzzleCursorPosition
+ ld a, [hl]
+ cp 1 puzcoord 0
+ ret c
+ sub 6
+ ld [hl], a
+ jr .done_joypad
+
+.d_down
+ ld hl, wUnownPuzzleCursorPosition
+ ld a, [hl]
+ cp 4 puzcoord 1
+ ret z
+ cp 4 puzcoord 2
+ ret z
+ cp 4 puzcoord 3
+ ret z
+ cp 4 puzcoord 4
+ ret z
+ cp 5 puzcoord 0
+ ret nc
+ add 6
+ ld [hl], a
+ jr .done_joypad
+
+.d_left
+ ld hl, wUnownPuzzleCursorPosition
+ ld a, [hl]
+ and a
+ ret z
+ cp 1 puzcoord 0
+ ret z
+ cp 2 puzcoord 0
+ ret z
+ cp 3 puzcoord 0
+ ret z
+ cp 4 puzcoord 0
+ ret z
+ cp 5 puzcoord 0
+ ret z
+ cp 5 puzcoord 5
+ jr z, .left_overflow
+ dec [hl]
+ jr .done_joypad
+
+.left_overflow
+ ld [hl], 5 puzcoord 0
+ jr .done_joypad
+
+.d_right
+ ld hl, wUnownPuzzleCursorPosition
+ ld a, [hl]
+ cp 0 puzcoord 5
+ ret z
+ cp 1 puzcoord 5
+ ret z
+ cp 2 puzcoord 5
+ ret z
+ cp 3 puzcoord 5
+ ret z
+ cp 4 puzcoord 5
+ ret z
+ cp 5 puzcoord 5
+ ret z
+ cp 5 puzcoord 0
+ jr z, .right_overflow
+ inc [hl]
+ jr .done_joypad
+
+.right_overflow
+ ld [hl], 5 puzcoord 5
+
+.done_joypad
+ ld a, [wHoldingUnownPuzzlePiece]
+ and a
+ jr nz, .holding_piece
+ ld de, SFX_POUND
+ jr .play_sfx
+
+.holding_piece
+ ld de, SFX_MOVE_PUZZLE_PIECE
+
+.play_sfx
+ call PlaySFX
+ ret
+; e1376
+
+UnownPuzzle_A: ; e1376
+ ld a, [wHoldingUnownPuzzlePiece]
+ and a
+ jr nz, .TryPlacePiece
+ call UnownPuzzle_CheckCurrentTileOccupancy
+ and a
+ jr z, UnownPuzzle_InvalidAction
+ ld de, SFX_MEGA_KICK
+ call PlaySFX
+ ld [hl], 0
+ ld [wUnownPuzzleHeldPiece], a
+ call RedrawUnownPuzzlePieces
+ call FillUnoccupiedPuzzleSpace
+ call WaitBGMap
+ call WaitSFX
+ ld a, TRUE
+ ld [wHoldingUnownPuzzlePiece], a
+ ret
+
+.TryPlacePiece:
+ call UnownPuzzle_CheckCurrentTileOccupancy
+ and a
+ jr nz, UnownPuzzle_InvalidAction
+ ld de, SFX_PLACE_PUZZLE_PIECE_DOWN
+ call PlaySFX
+ ld a, [wUnownPuzzleHeldPiece]
+ ld [hl], a
+ call PlaceUnownPuzzlePieceGFX
+ call WaitBGMap
+ xor a
+ ld [wUnownPuzzleHeldPiece], a
+ call RedrawUnownPuzzlePieces
+ xor a
+ ld [wHoldingUnownPuzzlePiece], a
+ call WaitSFX
+ call CheckSolvedUnownPuzzle
+ ret nc
+
+; You solved the puzzle!
+ call PlaceStartCancelBoxBorder
+ call ClearSprites
+ ld de, SFX_1ST_PLACE
+ call PlaySFX
+ call WaitSFX
+ call SimpleWaitPressAorB
+ ld a, TRUE
+ ld [wSolvedUnownPuzzle], a
+UnownPuzzle_Quit: ; e13de
+ ld hl, wJumptableIndex
+ set 7, [hl]
+ ret
+
+UnownPuzzle_InvalidAction: ; e13e4
+ ld de, SFX_WRONG
+ call PlaySFX
+ call WaitSFX
+ ret
+; e13ee
+
+UnownPuzzle_FillBox: ; e13ee
+ ld de, SCREEN_WIDTH
+.row
+ push bc
+ push hl
+.col
+ ld [hli], a
+ dec c
+ jr nz, .col
+ pop hl
+ add hl, de
+ pop bc
+ dec b
+ jr nz, .row
+ ret
+; e13fe
+
+UnownPuzzle_UpdateTilemap: ; e13fe
+ xor a
+ ld [wUnownPuzzleCursorPosition], a
+ ld c, 6 * 6
+.loop
+ push bc
+ call UnownPuzzle_CheckCurrentTileOccupancy
+ ld [wUnownPuzzleHeldPiece], a
+ and a
+ jr z, .not_holding_piece
+ call PlaceUnownPuzzlePieceGFX
+ jr .next
+
+.not_holding_piece
+ call FillUnoccupiedPuzzleSpace
+
+.next
+ ld hl, wUnownPuzzleCursorPosition
+ inc [hl]
+ pop bc
+ dec c
+ jr nz, .loop
+ ret
+; e141f
+
+PlaceUnownPuzzlePieceGFX: ; e141f
+ ld a, $2 ; tilemap coords
+ call GetUnownPuzzleCoordData
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ push hl
+ call GetCurrentPuzzlePieceVTileCorner
+ pop hl
+ ld de, SCREEN_WIDTH
+ ld b, 3
+.row
+ ld c, 3
+ push hl
+.col
+ ld [hli], a
+ inc a
+ dec c
+ jr nz, .col
+ add 9
+ pop hl
+ add hl, de
+ dec b
+ jr nz, .row
+ ret
+; e1441
+
+FillUnoccupiedPuzzleSpace: ; e1441
+ ld a, 2 ; tilemap coords
+ call GetUnownPuzzleCoordData
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ push hl
+ ld a, 4 ; tile
+ call GetUnownPuzzleCoordData
+ ld a, [hl]
+ pop hl
+ ld de, SCREEN_WIDTH
+ ld b, 3
+.row
+ ld c, 3
+ push hl
+.col
+ ld [hli], a
+ dec c
+ jr nz, .col
+ pop hl
+ add hl, de
+ dec b
+ jr nz, .row
+ ret
+; e1463
+
+GetUnownPuzzleCoordData: ; e1463
+ ld e, a
+ ld d, 0
+ ld hl, UnownPuzzleCoordData
+ add hl, de
+ ld a, [wUnownPuzzleCursorPosition]
+ ld e, a
+rept 6
+ add hl, de
+endr
+ ret
+; e1475
+
+UnownPuzzle_CheckCurrentTileOccupancy: ; e1475
+ ld hl, wPuzzlePieces
+ ld a, [wUnownPuzzleCursorPosition]
+ ld e, a
+ ld d, $0
+ add hl, de
+ ld a, [hl]
+ ret
+; e1481
+
+GetCurrentPuzzlePieceVTileCorner: ; e1481
+ ld a, [wUnownPuzzleHeldPiece]
+ ld hl, .Corners
+ add l
+ ld l, a
+ ld a, $0
+ adc h
+ ld h, a
+ ld a, [hl]
+ ret
+; e148f
+
+.Corners: ; e148f
+; 00, 01, 02
+; 0c, 0d, 0e
+; 18, 19, 1a
+ db $e0 ; no piece selected
+ db $00, $03, $06, $09
+ db $24, $27, $2a, $2d
+ db $48, $4b, $4e, $51
+ db $6c, $6f, $72, $75
+; e14a0
+
+CheckSolvedUnownPuzzle: ; e14a0
+ ld hl, .SolvedPuzzleConfiguration
+ ld de, wPuzzlePieces
+ ld c, 6 * 6
+.loop
+ ld a, [de]
+ cp [hl]
+ jr nz, .not_solved
+ inc de
+ inc hl
+ dec c
+ jr nz, .loop
+ scf
+ ret
+
+.not_solved
+ and a
+ ret
+; e14b5
+
+.SolvedPuzzleConfiguration: ; e14b5
+ db $00, $00, $00, $00, $00, $00
+ db $00, $01, $02, $03, $04, $00
+ db $00, $05, $06, $07, $08, $00
+ db $00, $09, $0a, $0b, $0c, $00
+ db $00, $0d, $0e, $0f, $10, $00
+ db $00, $00, $00, $00, $00, $00
+; e14d9
+
+RedrawUnownPuzzlePieces: ; e14d9
+ call GetCurrentPuzzlePieceVTileCorner
+ ld [wd002], a
+ xor a
+ call GetUnownPuzzleCoordData ; get pixel positions
+ ld a, [hli]
+ ld b, [hl]
+ ld c, a
+ ld a, [wd002]
+ cp $e0
+ jr z, .NoPiece
+ ld hl, .OAM_HoldingPiece
+ jr .load
+
+.NoPiece:
+ ld hl, .OAM_NotHoldingPiece
+
+.load
+ ld de, wVirtualOAMSprite00
+.loop
+ ld a, [hli]
+ cp -1
+ ret z
+ add b
+ ld [de], a ; y
+ inc de
+ ld a, [hli]
+ add c
+ ld [de], a ; x
+ inc de
+ ld a, [wd002]
+ add [hl]
+ ld [de], a ; tile id
+ inc hl
+ inc de
+ ld a, [hli]
+ ld [de], a ; attributes
+ inc de
+ jr .loop
+; e150f
+
+.OAM_HoldingPiece: ; e150f
+ dsprite -1, -4, -1, -4, $00, 0
+ dsprite -1, -4, 0, -4, $01, 0
+ dsprite -1, -4, 0, 4, $02, 0
+ dsprite 0, -4, -1, -4, $0c, 0
+ dsprite 0, -4, 0, -4, $0d, 0
+ dsprite 0, -4, 0, 4, $0e, 0
+ dsprite 0, 4, -1, -4, $18, 0
+ dsprite 0, 4, 0, -4, $19, 0
+ dsprite 0, 4, 0, 4, $1a, 0
+ db -1
+
+.OAM_NotHoldingPiece: ; e1534
+ dsprite -1, -4, -1, -4, $00, 0
+ dsprite -1, -4, 0, -4, $01, 0
+ dsprite -1, -4, 0, 4, $00, 0 | X_FLIP
+ dsprite 0, -4, -1, -4, $02, 0
+ dsprite 0, -4, 0, -4, $03, 0
+ dsprite 0, -4, 0, 4, $02, 0 | X_FLIP
+ dsprite 0, 4, -1, -4, $00, 0 | Y_FLIP
+ dsprite 0, 4, 0, -4, $01, 0 | Y_FLIP
+ dsprite 0, 4, 0, 4, $00, 0 | X_FLIP | Y_FLIP
+ db -1
+
+UnownPuzzleCoordData: ; e1559
+
+puzzle_coords: MACRO
+ dbpixel \1, \2, \3, \4
+ dwcoord \5, \6
+ db \7, \8
+ENDM
+; OAM coords, tilemap coords, vacant tile, filler
+ puzzle_coords 3, 3, 4, 4, 1, 0, PUZZLE_BORDER, 0
+ puzzle_coords 6, 3, 4, 4, 4, 0, PUZZLE_BORDER, 0
+ puzzle_coords 9, 3, 4, 4, 7, 0, PUZZLE_BORDER, 0
+ puzzle_coords 12, 3, 4, 4, 10, 0, PUZZLE_BORDER, 0
+ puzzle_coords 15, 3, 4, 4, 13, 0, PUZZLE_BORDER, 0
+ puzzle_coords 18, 3, 4, 4, 16, 0, PUZZLE_BORDER, 0
+
+ puzzle_coords 3, 6, 4, 4, 1, 3, PUZZLE_BORDER, 0
+ puzzle_coords 6, 6, 4, 4, 4, 3, PUZZLE_VOID, 0
+ puzzle_coords 9, 6, 4, 4, 7, 3, PUZZLE_VOID, 0
+ puzzle_coords 12, 6, 4, 4, 10, 3, PUZZLE_VOID, 0
+ puzzle_coords 15, 6, 4, 4, 13, 3, PUZZLE_VOID, 0
+ puzzle_coords 18, 6, 4, 4, 16, 3, PUZZLE_BORDER, 0
+
+ puzzle_coords 3, 9, 4, 4, 1, 6, PUZZLE_BORDER, 0
+ puzzle_coords 6, 9, 4, 4, 4, 6, PUZZLE_VOID, 0
+ puzzle_coords 9, 9, 4, 4, 7, 6, PUZZLE_VOID, 0
+ puzzle_coords 12, 9, 4, 4, 10, 6, PUZZLE_VOID, 0
+ puzzle_coords 15, 9, 4, 4, 13, 6, PUZZLE_VOID, 0
+ puzzle_coords 18, 9, 4, 4, 16, 6, PUZZLE_BORDER, 0
+
+ puzzle_coords 3, 12, 4, 4, 1, 9, PUZZLE_BORDER, 0
+ puzzle_coords 6, 12, 4, 4, 4, 9, PUZZLE_VOID, 0
+ puzzle_coords 9, 12, 4, 4, 7, 9, PUZZLE_VOID, 0
+ puzzle_coords 12, 12, 4, 4, 10, 9, PUZZLE_VOID, 0
+ puzzle_coords 15, 12, 4, 4, 13, 9, PUZZLE_VOID, 0
+ puzzle_coords 18, 12, 4, 4, 16, 9, PUZZLE_BORDER, 0
+
+ puzzle_coords 3, 15, 4, 4, 1, 12, PUZZLE_BORDER, 0
+ puzzle_coords 6, 15, 4, 4, 4, 12, PUZZLE_VOID, 0
+ puzzle_coords 9, 15, 4, 4, 7, 12, PUZZLE_VOID, 0
+ puzzle_coords 12, 15, 4, 4, 10, 12, PUZZLE_VOID, 0
+ puzzle_coords 15, 15, 4, 4, 13, 12, PUZZLE_VOID, 0
+ puzzle_coords 18, 15, 4, 4, 16, 12, PUZZLE_BORDER, 0
+
+ puzzle_coords 3, 18, 4, 4, 1, 15, PUZZLE_BORDER, 0
+ puzzle_coords 6, 18, 4, 4, 4, 15, PUZZLE_BORDER, 0
+ puzzle_coords 9, 18, 4, 4, 7, 15, PUZZLE_BORDER, 0
+ puzzle_coords 12, 18, 4, 4, 10, 15, PUZZLE_BORDER, 0
+ puzzle_coords 15, 18, 4, 4, 13, 15, PUZZLE_BORDER, 0
+ puzzle_coords 18, 18, 4, 4, 16, 15, PUZZLE_BORDER, 0
+
+ConvertLoadedPuzzlePieces: ; e1631
+ ld hl, vTiles2
+ ld de, vTiles0
+ ld b, 6
+.loop
+ push bc
+ push hl
+ push hl
+ call .EnlargePuzzlePieceTiles
+ pop hl
+ ld bc, 1 tiles / 2
+ add hl, bc
+ call .EnlargePuzzlePieceTiles
+ pop hl
+ ld bc, 6 tiles
+ add hl, bc
+ pop bc
+ dec b
+ jr nz, .loop
+ call UnownPuzzle_AddPuzzlePieceBorders
+ ret
+; e1654
+
+.EnlargePuzzlePieceTiles: ; e1654
+; double size
+ ld c, 6
+.loop1
+ push bc
+ push hl
+ push hl
+ ld c, 4
+.loop2
+ push bc
+ ld a, [hli]
+ and $f0
+ swap a
+ call .GetEnlargedTile
+ ld c, a
+ ld a, [hli]
+ and $f0
+ swap a
+ call .GetEnlargedTile
+ ld b, a
+ ld a, c
+ ld [de], a
+ inc de
+ ld a, b
+ ld [de], a
+ inc de
+ ld a, c
+ ld [de], a
+ inc de
+ ld a, b
+ ld [de], a
+ inc de
+ pop bc
+ dec c
+ jr nz, .loop2
+ pop hl
+ ld c, 4
+.loop3
+ push bc
+ ld a, [hli]
+ and $f
+ call .GetEnlargedTile
+ ld c, a
+ ld a, [hli]
+ and $f
+ call .GetEnlargedTile
+ ld b, a
+ ld a, c
+ ld [de], a
+ inc de
+ ld a, b
+ ld [de], a
+ inc de
+ ld a, c
+ ld [de], a
+ inc de
+ ld a, b
+ ld [de], a
+ inc de
+ pop bc
+ dec c
+ jr nz, .loop3
+ pop hl
+ ld bc, 1 tiles
+ add hl, bc
+ pop bc
+ dec c
+ jr nz, .loop1
+ ret
+; e16aa
+
+.GetEnlargedTile: ; e16aa
+ push hl
+ ld hl, .EnlargedTiles
+ add l
+ ld l, a
+ ld a, 0
+ adc h
+ ld h, a
+ ld a, [hl]
+ pop hl
+ ret
+; e16b7
+
+.EnlargedTiles: ; e16b7
+
+x = 0
+rept 16
+ db ((x & %1000) * %11000) + ((x & %0100) * %1100) + ((x & %0010) * %110) + ((x & %0001) * %11)
+x = x + 1
+endr
+; e16c7
+
+UnownPuzzle_AddPuzzlePieceBorders: ; e16c7
+ ld hl, PuzzlePieceBorderData
+ ld a, 8
+.loop
+ push af
+ push hl
+ ld a, [hli]
+ ld e, a
+ ld a, [hli]
+ ld d, a
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ call .LoadGFX
+ pop hl
+rept 4
+ inc hl
+endr
+ pop af
+ dec a
+ jr nz, .loop
+ ret
+; e16e2
+
+.LoadGFX: ; e16e2
+ lb bc, 4, 4
+.loop1
+ push bc
+
+.loop2
+ push de
+ push hl
+
+ ld b, 1 tiles
+.loop3
+ ld a, [de]
+ or [hl]
+ ld [hli], a
+ inc de
+ dec b
+ jr nz, .loop3
+
+ pop hl
+ ld de, 3 tiles
+ add hl, de
+ pop de
+ dec c
+ jr nz, .loop2
+
+ ld bc, 24 tiles
+ add hl, bc
+ pop bc
+ dec b
+ jr nz, .loop1
+ ret
+; e1703
+
+PuzzlePieceBorderData: ; e1703
+ dw .TileBordersGFX + 0 tiles, vTiles0 tile $00
+ dw .TileBordersGFX + 1 tiles, vTiles0 tile $01
+ dw .TileBordersGFX + 2 tiles, vTiles0 tile $02
+ dw .TileBordersGFX + 3 tiles, vTiles0 tile $0c
+ dw .TileBordersGFX + 4 tiles, vTiles0 tile $0e
+ dw .TileBordersGFX + 5 tiles, vTiles0 tile $18
+ dw .TileBordersGFX + 6 tiles, vTiles0 tile $19
+ dw .TileBordersGFX + 7 tiles, vTiles0 tile $1a
+; e1723
+
+.TileBordersGFX: ; e1723
+INCBIN "gfx/unown_puzzle/tile_borders.2bpp"
+
+LoadUnownPuzzlePiecesGFX: ; e17a3
+ ld a, [wScriptVar]
+ maskbits NUM_UNOWN_PUZZLES
+ ld e, a
+ ld d, 0
+ ld hl, .LZPointers
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld de, vTiles2
+ call Decompress
+ call ConvertLoadedPuzzlePieces
+ ret
+; e17bd
+
+.LZPointers: ; e17bd
+; entries correspond to UNOWNPUZZLE_* constants
+ dw KabutoPuzzleLZ
+ dw OmanytePuzzleLZ
+ dw AerodactylPuzzleLZ
+ dw HoOhPuzzleLZ
+; e17c5
+
+UnownPuzzleCursorGFX: ; e17c5
+INCBIN "gfx/unown_puzzle/cursor.2bpp"
+
+UnownPuzzleStartCancelLZ: ; e1805
+INCBIN "gfx/unown_puzzle/start_cancel.2bpp.lz"
+
+HoOhPuzzleLZ: ; e18ab
+INCBIN "gfx/unown_puzzle/hooh.2bpp.lz"
+
+AerodactylPuzzleLZ: ; e19fb
+INCBIN "gfx/unown_puzzle/aerodactyl.2bpp.lz"
+
+KabutoPuzzleLZ: ; e1bab
+INCBIN "gfx/unown_puzzle/kabuto.2bpp.lz"
+
+OmanytePuzzleLZ: ; e1c9b
+INCBIN "gfx/unown_puzzle/omanyte.2bpp.lz"