summaryrefslogtreecommitdiff
path: root/engine/games/memory_minigame.asm
diff options
context:
space:
mode:
Diffstat (limited to 'engine/games/memory_minigame.asm')
-rw-r--r--engine/games/memory_minigame.asm626
1 files changed, 626 insertions, 0 deletions
diff --git a/engine/games/memory_minigame.asm b/engine/games/memory_minigame.asm
new file mode 100644
index 0000000..6462106
--- /dev/null
+++ b/engine/games/memory_minigame.asm
@@ -0,0 +1,626 @@
+INCLUDE "constants.asm"
+
+SECTION "engine/games/memory_minigame.asm", ROMX
+
+; MemoryMinigame.Jumptable indices
+ const_def
+ const MEMORYGAME_RESTART_GAME
+ const MEMORYGAME_RESTART_BOARD
+ const MEMORYGAME_INIT_BOARD_AND_CURSOR
+ const MEMORYGAME_CHECK_TRIES_REMAINING
+ const MEMORYGAME_PICK_CARD_1
+ const MEMORYGAME_PICK_CARD_2
+ const MEMORYGAME_DELAY_PICK_AGAIN
+ const MEMORYGAME_REVEAL_ALL
+ const MEMORYGAME_ASK_PLAY_AGAIN
+MEMORYGAME_END_LOOP_F EQU 7
+
+MEMORYGAME_STARTING_COINS EQU 256
+
+MemoryMinigame:
+; Always start off with 256 coins
+ ld hl, wCoins
+ ld [hl], HIGH(MEMORYGAME_STARTING_COINS)
+ inc hl
+ ld [hl], LOW(MEMORYGAME_STARTING_COINS)
+
+ call .LoadGFXAndPals
+ call DelayFrame
+.loop
+ call .JumptableLoop
+ jr nc, .loop
+ ret
+
+.LoadGFXAndPals:
+ call DisableLCD
+ ld b, SGB_DIPLOMA
+ call GetSGBLayout
+ callab InitEffectObject
+
+ ld hl, MemoryGameGFX
+ ld de, vChars2
+ ld bc, $70 tiles
+ ld a, BANK(MemoryGameGFX)
+ call FarCopyData
+
+ ld hl, PointerGFX
+ ld de, vSprites
+ ld bc, $4 tiles
+ ld a, BANK(PointerGFX)
+ call FarCopyData
+
+ ld a, SPRITE_ANIM_DICT_29
+ ld hl, wSpriteAnimDict
+ ld [hli], a
+ ld [hl], 0
+
+ hlcoord 0, 0
+ ld bc, SCREEN_WIDTH * SCREEN_HEIGHT
+ xor a
+ call ByteFill
+
+ xor a
+ ldh [hSCY], a
+ ldh [hSCX], a
+ ld [rWY], a
+ ld [wJumptableIndex], a
+ ld a, 1
+ ldh [hBGMapMode], a
+ ld a, %11100011
+ ld [rLCDC], a
+ ld a, %11100100
+ ld [rBGP], a
+ ld a, %11100000
+ ld [rOBP0], a
+ ret
+
+.JumptableLoop:
+ ld a, [wJumptableIndex]
+ bit MEMORYGAME_END_LOOP_F, a
+ jr nz, .quit
+ call .ExecuteJumptable
+ callab EffectObjectJumpNoDelay
+ 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 MemoryGame_InitStrings
+ ld hl, wJumptableIndex
+ inc [hl]
+ ret
+
+.ResetBoard:
+ call Cursor_AnimateCursor
+ jr nc, .proceed
+ ld hl, wJumptableIndex
+ set MEMORYGAME_END_LOOP_F, [hl]
+ ret
+
+.proceed
+ call MemoryGame_InitBoard
+ ld hl, wJumptableIndex
+ inc [hl]
+ xor a
+ ld [wMemoryGameCounter], a
+ ld hl, wMemoryGameLastMatches
+rept 4
+ ld [hli], a
+endr
+ ld [hl], a
+ ld [wMemoryGameNumCardsMatched], a
+
+.InitBoardTilemapAndCursorObject:
+ ld hl, wMemoryGameCounter
+ ld a, [hl]
+ cp 45
+ jr nc, .spawn_object
+ inc [hl]
+ call MemoryGame_Card2Coord
+ xor a
+ ld [wMemoryGameLastCardPicked], a
+ call MemoryGame_PlaceCard
+ ret
+
+.spawn_object
+ depixel 6, 3, 4, 4
+ ld a, SPRITE_ANIM_INDEX_MEMORY_GAME_CURSOR
+ call InitSpriteAnimStruct
+ ld a, 5
+ ld [wMemoryGameNumberTriesRemaining], a
+ ld hl, wJumptableIndex
+ inc [hl]
+ ret
+
+.CheckTriesRemaining:
+ ld a, [wMemoryGameNumberTriesRemaining]
+ hlcoord 17, 0
+ add "0"
+ ld [hl], a
+ ld hl, wMemoryGameNumberTriesRemaining
+ ld a, [hl]
+ and a
+ jr nz, .next_try
+ ld a, MEMORYGAME_REVEAL_ALL
+ ld [wJumptableIndex], a
+ ret
+
+.next_try
+ dec [hl]
+ xor a
+ ld [wMemoryGameCardChoice], a
+ ld hl, wJumptableIndex
+ inc [hl]
+
+.PickCard1:
+ ld a, [wMemoryGameCardChoice]
+ and a
+ ret z
+ dec a
+ ld e, a
+ ld d, 0
+ ld hl, wMemoryGameCards
+ add hl, de
+ ld a, [hl]
+ cp -1
+ ret z
+ ld [wMemoryGameLastCardPicked], a
+ ld [wMemoryGameCard1], a
+ ld a, e
+ ld [wMemoryGameCard1Location], a
+ call MemoryGame_Card2Coord
+ call MemoryGame_PlaceCard
+ xor a
+ ld [wMemoryGameCardChoice], a
+ ld hl, wJumptableIndex
+ inc [hl]
+ ret
+
+.PickCard2:
+ ld a, [wMemoryGameCardChoice]
+ and a
+ ret z
+ dec a
+ ld hl, wMemoryGameCard1Location
+ cp [hl]
+ ret z
+ ld e, a
+ ld d, 0
+ ld hl, wMemoryGameCards
+ add hl, de
+ ld a, [hl]
+ cp -1
+ ret z
+ ld [wMemoryGameLastCardPicked], a
+ ld [wMemoryGameCard2], a
+ ld a, e
+ ld [wMemoryGameCard2Location], a
+ call MemoryGame_Card2Coord
+ call MemoryGame_PlaceCard
+ ld a, 64
+ ld [wMemoryGameCounter], a
+ ld hl, wJumptableIndex
+ inc [hl]
+
+.DelayPickAgain:
+ ld hl, wMemoryGameCounter
+ ld a, [hl]
+ and a
+ jr z, .PickAgain
+ dec [hl]
+ ret
+
+.PickAgain:
+ call MemoryGame_CheckMatch
+ ld a, MEMORYGAME_CHECK_TRIES_REMAINING
+ ld [wJumptableIndex], a
+ ret
+
+.RevealAll:
+ ldh a, [hJoypadDown]
+ and A_BUTTON
+ ret z
+ xor a
+ ld [wMemoryGameCounter], a
+
+.RevelationLoop:
+ ld hl, wMemoryGameCounter
+ ld a, [hl]
+ cp 45
+ jr nc, .finish_round
+ inc [hl]
+ push af
+ call MemoryGame_Card2Coord
+ pop af
+ push hl
+ ld e, a
+ ld d, 0
+ ld hl, wMemoryGameCards
+ add hl, de
+ ld a, [hl]
+ pop hl
+ cp -1
+ jr z, .RevelationLoop
+ ld [wMemoryGameLastCardPicked], a
+ call MemoryGame_PlaceCard
+ jr .RevelationLoop
+
+.finish_round
+ call TextboxWaitPressAorB_BlinkCursor
+ ld hl, wJumptableIndex
+ inc [hl]
+
+.AskPlayAgain:
+ call Cursor_InterpretJoypad
+ jr nc, .restart
+ ld hl, wJumptableIndex
+ set MEMORYGAME_END_LOOP_F, [hl]
+ ret
+
+.restart
+ xor a
+ ld [wJumptableIndex], a
+ ret
+
+MemoryGame_CheckMatch:
+ ld hl, wMemoryGameCard1
+ ld a, [hli]
+ cp [hl]
+ jr nz, .no_match
+
+ ld a, [wMemoryGameCard1Location]
+ call MemoryGame_Card2Coord
+ call MemoryGame_DeleteCard
+
+ ld a, [wMemoryGameCard2Location]
+ call MemoryGame_Card2Coord
+ call MemoryGame_DeleteCard
+
+ ld a, [wMemoryGameCard1Location]
+ ld e, a
+ ld d, 0
+ ld hl, wMemoryGameCards
+ add hl, de
+ ld [hl], -1
+
+ ld a, [wMemoryGameCard2Location]
+ ld e, a
+ ld d, 0
+ ld hl, wMemoryGameCards
+ add hl, de
+ ld [hl], -1
+
+ ld hl, wMemoryGameLastMatches
+.find_empty_slot
+ ld a, [hli]
+ and a
+ jr nz, .find_empty_slot
+ dec hl
+ ld a, [wMemoryGameCard1]
+ ld [hl], a
+ ld [wMemoryGameLastCardPicked], a
+ ld hl, wMemoryGameNumCardsMatched
+ ld e, [hl]
+ inc [hl]
+ inc [hl]
+ ld d, 0
+ hlcoord 5, 0
+ add hl, de
+ call MemoryGame_PlaceCard
+ ld hl, .VictoryText
+ call PrintText
+ ret
+
+.no_match
+ xor a
+ ld [wMemoryGameLastCardPicked], a
+
+ ld a, [wMemoryGameCard1Location]
+ call MemoryGame_Card2Coord
+ call MemoryGame_PlaceCard
+
+ ld a, [wMemoryGameCard2Location]
+ call MemoryGame_Card2Coord
+ call MemoryGame_PlaceCard
+
+ ld hl, .DarnText
+ call PrintText
+ ret
+
+.VictoryText:
+ start_asm
+ push bc
+ hlcoord 2, 13
+ call MemoryGame_PlaceCard
+ ld hl, .YeahText
+ pop bc
+ inc bc
+ inc bc
+ inc bc
+ ret
+
+.YeahText:
+ text " いただき!"
+ done
+
+.DarnText:
+ text "ざんねん⋯⋯"
+ done
+
+MemoryGame_InitBoard:
+ ld hl, wMemoryGameCards
+ ld bc, wMemoryGameCardsEnd - wMemoryGameCards
+ xor a
+ call ByteFill
+ call MemoryGame_GetDistributionOfTiles
+
+ ld c, 2
+ ld b, [hl]
+ call MemoryGame_SampleTilePlacement
+
+ ld c, 8
+ ld b, [hl]
+ call MemoryGame_SampleTilePlacement
+
+ ld c, 4
+ ld b, [hl]
+ call MemoryGame_SampleTilePlacement
+
+ ld c, 7
+ ld b, [hl]
+ call MemoryGame_SampleTilePlacement
+
+ ld c, 3
+ ld b, [hl]
+ call MemoryGame_SampleTilePlacement
+
+ ld c, 6
+ ld b, [hl]
+ call MemoryGame_SampleTilePlacement
+
+ ld c, 1
+ ld b, [hl]
+ call MemoryGame_SampleTilePlacement
+
+ ld c, 5
+ ld hl, wMemoryGameCards
+ ld b, wMemoryGameCardsEnd - wMemoryGameCards
+.loop
+ ld a, [hl]
+ and a
+ jr nz, .no_load
+ ld [hl], c
+.no_load
+ inc hl
+ dec b
+ jr nz, .loop
+ ret
+
+
+MemoryGame_SampleTilePlacement:
+ push hl
+ ld de, wMemoryGameCards
+.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
+
+MemoryGame_GetDistributionOfTiles:
+ 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
+
+MemoryGame_PlaceCard:
+ ld a, [wMemoryGameLastCardPicked]
+ 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
+
+MemoryGame_DeleteCard:
+ 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
+
+MemoryGame_InitStrings:
+ hlcoord 0, 0
+ ld bc, SCREEN_WIDTH * SCREEN_HEIGHT
+ ld a, 1
+ call ByteFill
+ hlcoord 0, 0
+ ld de, .str1
+ call PlaceString
+ hlcoord 15, 0
+ ld de, .str2
+ call PlaceString
+ ld hl, .dummy_text
+ call PrintText
+ ret
+
+.dummy_text
+ db "@"
+.str1
+ db "とったもの@"
+.str2
+ db "あと かい@"
+
+MemoryGame_Card2Coord:
+ 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
+
+MemoryGame_AnimateCursor: ; Called from sprite animation routine?
+ ld a, [wJumptableIndex]
+ cp MEMORYGAME_REVEAL_ALL
+ jr nc, .quit
+ call GetJoypadDebounced
+ ld hl, hJoypadDown
+ 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 [wMemoryGameCardChoice], 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 a, $10
+ ld [hl], a
+ ld hl, SPRITEANIMSTRUCT_0C
+ add hl, bc
+ ld a, [hl]
+ add a, 9
+ ld [hl], a
+ ret
+