pokecrystal-board/engine/games/memory_game.asm
2023-09-24 15:06:19 +02:00

591 lines
8.7 KiB
NASM

_MemoryGame:
call .LoadGFXAndPals
call DelayFrame
.loop
call .JumptableLoop
jr nc, .loop
ret
.LoadGFXAndPals:
call DisableLCD
ld b, CGB_DIPLOMA
call GetCGBLayout
callfar ClearSpriteAnims
ld hl, MemoryGameLZ
ld de, vTiles2 tile $00
call Decompress
ld hl, MemoryGameGFX
ld de, vTiles0 tile $00
ld bc, 4 tiles
ld a, BANK(MemoryGameGFX)
call FarCopyBytes
ld a, SPRITE_ANIM_DICT_ARROW_CURSOR
ld hl, wSpriteAnimDict
ld [hli], a
ld [hl], $00
hlcoord 0, 0
ld bc, SCREEN_HEIGHT * SCREEN_WIDTH
xor a
call ByteFill
xor a
ldh [hSCY], a
ldh [hSCX], a
ldh [rWY], a
ld [wJumptableIndex], a
ld a, $1
ldh [hBGMapMode], a
ld a, LCDC_DEFAULT
ldh [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 MemoryGame_InitStrings
ld hl, wJumptableIndex
inc [hl]
ret
.ResetBoard:
call UnusedCursor_InterpretJoypad_AnimateCursor
jr nc, .proceed
ld hl, wJumptableIndex
set 7, [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_OBJ_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, $7
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, $3
ld [wJumptableIndex], a
ret
.RevealAll:
ldh a, [hJoypadPressed]
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 WaitPressAorB_BlinkCursor
ld hl, wJumptableIndex
inc [hl]
.AskPlayAgain:
call UnusedCursor_InterpretJoypad_AnimateCursor
jr nc, .restart
ld hl, wJumptableIndex
set 7, [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 PrintText1bpp
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, MemoryGameDarnText
call PrintText1bpp
ret
.VictoryText:
text_asm
push bc
hlcoord 2, 13
call MemoryGame_PlaceCard
ld hl, MemoryGameYeahText
pop bc
inc bc
inc bc
inc bc
ret
MemoryGameYeahText:
text_far _MemoryGameYeahText
text_end
MemoryGameDarnText:
text_far _MemoryGameDarnText
text_end
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, .japstr1
call PlaceString
hlcoord 15, 0
ld de, .japstr2
call PlaceString
ld hl, .dummy_text
call PrintText1bpp
ret
.dummy_text
db "@"
.japstr1
db "?????@"
.japstr2
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_InterpretJoypad_AnimateCursor:
ld a, [wJumptableIndex]
cp $7
jr nc, .quit
call JoyTextDelay
ld hl, hJoypadPressed
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_VAR1
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_VAR1
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_VAR1
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_VAR1
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_VAR1
add hl, bc
ld a, [hl]
add 9
ld [hl], a
ret
MemoryGameLZ:
INCBIN "gfx/memory_game/memory_game.2bpp.lz"