summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xconstants/sprite_anim_constants.asm8
-rw-r--r--engine/games/memory_minigame.asm626
-rw-r--r--engine/games/picross_minigame.asm1930
-rw-r--r--gfx/gfx.asm10
-rw-r--r--gfx/gfx.mk1
-rw-r--r--gfx/minigames/picross.pngbin336 -> 0 bytes
-rw-r--r--gfx/minigames/picross_background.pngbin0 -> 140 bytes
-rw-r--r--gfx/minigames/picross_grid.pngbin0 -> 112 bytes
-rw-r--r--gfx/minigames/picross_highlights.pngbin0 -> 96 bytes
-rw-r--r--gfx/minigames/picross_numbers.pngbin0 -> 184 bytes
-rw-r--r--layout.link6
-rw-r--r--ram/vram.asm10
-rw-r--r--ram/wram.asm40
-rwxr-xr-xshim.sym5
14 files changed, 2630 insertions, 6 deletions
diff --git a/constants/sprite_anim_constants.asm b/constants/sprite_anim_constants.asm
index 9e30dd9..ff489f8 100755
--- a/constants/sprite_anim_constants.asm
+++ b/constants/sprite_anim_constants.asm
@@ -21,6 +21,9 @@ NUM_SPRITE_ANIM_STRUCTS EQU 10 ; see wSpriteAnimationStructs
; wSpriteAnimDict keys
SPRITE_ANIM_DICT_DEFAULT EQU $00
+SPRITE_ANIM_DICT_10 EQU $10
+SPRITE_ANIM_DICT_22 EQU $22
+SPRITE_ANIM_DICT_25 EQU $25
SPRITE_ANIM_DICT_GS_SPLASH EQU $27
SPRITE_ANIM_DICT_29 EQU $29
@@ -54,6 +57,10 @@ SPRITE_ANIM_INDEX_MINIGAME_PIKACHU_TAIL EQU $30
SPRITE_ANIM_INDEX_MINIGAME_NOTE EQU $31
SPRITE_ANIM_INDEX_MINIGAME_JIGGLYPUFF EQU $32
+SPRITE_ANIM_INDEX_MINIGAME_PICROSS_CURSOR EQU $33
+SPRITE_ANIM_INDEX_MINIGAME_PICROSS_DUST EQU $34
+SPRITE_ANIM_INDEX_MINIGAME_PICROSS_GOLD EQU $35
+
SPRITE_ANIM_INDEX_39 EQU $39
SPRITE_ANIM_INDEX_GAMEFREAK_LOGO EQU $3a
SPRITE_ANIM_INDEX_GS_INTRO_STAR EQU $3b
@@ -64,6 +71,7 @@ SPRITE_ANIM_INDEX_SLOTS_EGG EQU $3f
SPRITE_ANIM_INDEX_40 EQU $40
SPRITE_ANIM_INDEX_41 EQU $41
+SPRITE_ANIM_INDEX_MEMORY_GAME_CURSOR EQU $43
SPRITE_ANIM_INDEX_TRAINERGEAR_POINTER EQU $44
SPRITE_ANIM_INDEX_RADIO_TUNING_KNOB EQU $4b
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
+
diff --git a/engine/games/picross_minigame.asm b/engine/games/picross_minigame.asm
new file mode 100644
index 0000000..9a1b9aa
--- /dev/null
+++ b/engine/games/picross_minigame.asm
@@ -0,0 +1,1930 @@
+INCLUDE "constants.asm"
+
+SECTION "engine/games/picross_minigame.asm", ROMX
+
+; PicrossSprites constants
+ const_def
+ const PATTERN_NORMAL
+ const PATTERN_TILESET
+
+; PicrossMinigame.Jumptable constants
+ const_def
+ const PICROSS_INIT_MODE
+ const PICROSS_RUN_MODE
+ const PICROSS_EXIT_MODE
+PICROSS_END_LOOP_F EQU 7
+
+; wPicrossCurrentCellType constants
+ const_def
+ const PICROSS_BLANK_CELL
+ const PICROSS_COLORED_CELL
+ const PICROSS_MARKED_CELL
+
+PICROSS_GFX_BGTILE EQU $80
+PICROSS_GFX_BUSHTILE EQU $81
+PICROSS_GFX_BUSHGROUNDTILE EQU $82
+PICROSS_GFX_GROUNDTILE EQU $83
+
+PICROSS_GFX_COLUMNS EQU $84
+PICROSS_GFX_ROWS EQU $b4
+PICROSS_GFX_TABLESTART equ $f0
+
+; The Picross game area is referred as the "table" here.
+; The table consists of 256 cells, divided into 4x4 "grids" of 16 cells each.
+
+PicrossMinigame:
+ call .Init
+ call DelayFrame
+.loop
+ call .GameLoop
+ jr nc, .loop
+ call ClearJoypad
+ ret
+
+.Init:
+ call DisableLCD
+ callba InitEffectObject
+ call .InitGFX
+ call .PlacePlayerBG
+ call .InitRAM
+
+ depixel 8, 8, 0, 0
+ ld a, SPRITE_ANIM_INDEX_MINIGAME_PICROSS_CURSOR
+ call InitSpriteAnimStruct
+
+ ld a, c
+ ld [wPicrossCursorSpritePointer], a
+ ld a, b
+ ld [wPicrossCursorSpritePointer+1], a
+
+ depixel 5, 4, 4, 4
+ ld a, SPRITE_ANIM_INDEX_MINIGAME_PICROSS_GOLD
+ call InitSpriteAnimStruct
+
+ ld a, -1
+ ld [wPicrossCurrentCellType], a
+ call Picross_InitPicrossTable
+ call Picross_InitPicrossDigits
+
+ 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, %11010000
+ ld [rOBP0], a
+
+ xor a ; PICROSS_BLANK_CELL
+ ld [wPicrossCurrentCellType], a
+ ret
+
+.InitGFX:
+ ld hl, PicrossBackgroundGFX
+ ld de, vPicrossBackground
+ ld bc, 4 tiles
+ ld a, BANK(PicrossBackgroundGFX)
+ call FarCopyData
+
+; load column GFX
+ ld de, vPicrossBackground tile 4
+ ld b, 4
+.column_outer_loop
+ push bc
+ ld b, 4
+.column_inner_loop
+ push bc
+ ld hl, PicrossGridHighlightsGFX
+ ld bc, 3 tiles
+ ld a, BANK(PicrossGridHighlightsGFX)
+ call FarCopyData
+ pop bc
+ dec b
+ jr nz, .column_inner_loop
+ pop bc
+ dec b
+ jr nz, .column_outer_loop
+
+; load row GFX
+ ld de, vPicrossBackground tile $34
+ ld b, 4
+.row_outer_loop
+ push bc
+ ld b, 3
+.row1
+ push bc
+ ld hl, PicrossGridHighlightsGFX tile 3
+ ld bc, 1 tiles
+ ld a, BANK(PicrossGridHighlightsGFX)
+ call FarCopyData
+ pop bc
+ dec b
+ jr nz, .row1
+ ld b, 3
+.row2
+ push bc
+ ld hl, PicrossGridHighlightsGFX tile 4
+ ld bc, 1 tiles
+ ld a, BANK(PicrossGridHighlightsGFX)
+ call FarCopyData
+ pop bc
+ dec b
+ jr nz, .row2
+ ld b, 3
+.row3
+ push bc
+ ld hl, PicrossGridHighlightsGFX tile 5
+ ld bc, LEN_2BPP_TILE
+ ld a, BANK(PicrossGridHighlightsGFX)
+ call FarCopyData
+ pop bc
+ dec b
+ jr nz, .row3
+ ld b, 2
+.row4
+ push bc
+ ld hl, PicrossGridHighlightsGFX tile 3
+ ld bc, LEN_2BPP_TILE
+ ld a, BANK(PicrossGridHighlightsGFX)
+ call FarCopyData
+ pop bc
+ dec b
+ jr nz, .row4
+ ld b, 2
+.row5
+ push bc
+ ld hl, PicrossGridHighlightsGFX tile 4
+ ld bc, LEN_2BPP_TILE
+ ld a, BANK(PicrossGridHighlightsGFX)
+ call FarCopyData
+ pop bc
+ dec b
+ jr nz, .row5
+ ld b, 2
+.row6
+ push bc
+ ld hl, PicrossGridHighlightsGFX tile 5
+ ld bc, LEN_2BPP_TILE
+ ld a, BANK(PicrossGridHighlightsGFX)
+ call FarCopyData
+ pop bc
+ dec b
+ jr nz, .row6
+ pop bc
+ dec b
+ jr nz, .row_outer_loop
+
+; load Picross table
+ ld de, vPicrossPlayArea
+ ld b, 16
+.load_grid
+ push bc
+ ld hl, PicrossGridGFX
+ ld bc, 9 tiles
+ ld a, BANK(PicrossGridGFX)
+ call FarCopyData
+ pop bc
+ dec b
+ jr nz, .load_grid
+
+; load cursor GFX
+ ld de, vSprites
+ ld hl, PicrossCursorGFX
+ ld bc, 9 tiles
+ ld a, BANK(PicrossCursorGFX)
+ call FarCopyData
+
+; load Gold sprites
+ ld de, vSprites + $100
+ ld hl, GoldSpriteGFX + $40
+ ld bc, 4 tiles
+ ld a, BANK(GoldSpriteGFX)
+ call FarCopyData
+
+ ld de, vSprites + $140
+ ld hl, GoldSpriteGFX + $100
+ ld bc, 4 tiles
+ ld a, BANK(GoldSpriteGFX)
+ call FarCopyData
+
+ ld a, SPRITE_ANIM_DICT_25
+ ld hl, wSpriteAnimDict
+ ld [hli], a
+ ld [hl], SPRITE_ANIM_DICT_DEFAULT
+ inc hl
+ ld a, SPRITE_ANIM_DICT_22
+ ld [hli], a
+ ld [hl], SPRITE_ANIM_DICT_10
+ ret
+
+.PlacePlayerBG:
+ hlcoord 0, 0
+ ld bc, SCREEN_WIDTH * SCREEN_HEIGHT
+ ld a, PICROSS_GFX_BGTILE
+ call ByteFill
+
+ hlcoord 1, 1
+ ld bc, 5
+ ld a, PICROSS_GFX_BUSHTILE
+ call ByteFill
+
+ hlcoord 1, 2
+ ld bc, 5
+ ld a, PICROSS_GFX_BUSHTILE
+ call ByteFill
+
+ hlcoord 1, 3
+ ld bc, 5
+ ld a, PICROSS_GFX_BUSHGROUNDTILE
+ call ByteFill
+
+ hlcoord 1, 4
+ ld bc, 5
+ ld a, PICROSS_GFX_GROUNDTILE
+ call ByteFill
+ ret
+
+.InitRAM:
+ ld hl, wPicrossMarkedCells
+ ld bc, $514
+ xor a
+ call ByteFill
+ ret
+
+.GameLoop:
+ call .GetJoypadState
+ ld a, [wJumptableIndex]
+ bit PICROSS_END_LOOP_F, a
+ jr nz, .quit
+
+ call .ExecuteJumptable
+ callba EffectObjectJumpNoDelay
+ call DelayFrame
+ and a
+ ret
+
+.quit
+ scf
+ ret
+
+.GetJoypadState:
+ call GetJoypadDebounced
+ ldh a, [hJoyState]
+ ld [wc606], a
+ ld hl, wc607
+ ld a, [hl]
+ and a
+ ret z
+ dec [hl]
+ xor a
+ ld [wc606], a
+ ret
+
+.ExecuteJumptable:
+ jumptable .Jumptable, wJumptableIndex
+
+.Jumptable:
+ dw .InitMode
+ dw .RunMode
+ dw .ExitMode
+
+.InitMode:
+ call .PlaceBGMapTiles
+ ld hl, wJumptableIndex
+ inc [hl]
+ ret
+
+.RunMode:
+ call Picross_CheckPuzzleSolved
+ jr c, .solved
+ call Picross_ProcessJoypad
+ ret
+
+.solved
+; Deallocate the cursor sprite
+ ld hl, wPicrossCursorSpritePointer
+ ld c, [hl]
+ inc hl
+ ld b, [hl]
+ ld hl, SPRITEANIMSTRUCT_INDEX
+ add hl, bc
+ ld [hl], 0
+
+; Exit Picross minigame
+ ld hl, wJumptableIndex
+ inc [hl]
+
+.ExitMode:
+ ldh a, [hJoyDown]
+ and START
+ ret z
+
+; Game will truly exit once the Start button is pressed
+ ld hl, wJumptableIndex
+ set PICROSS_END_LOOP_F, [hl]
+ ret
+
+.PlaceBGMapTiles:
+ xor a
+ ldh [hBGMapMode], a
+ call .PlacePlayerBG
+ call .PlaceColumnNumbers
+ call .PlaceRowNumbers
+ call .PlaceTable
+ call .HandleError
+ ld a, 1
+ ldh [hBGMapMode], a
+ ret
+
+.PlaceTable:
+ ld hl, .TableCoords
+ ld c, 4 * 4
+ ld a, PICROSS_GFX_TABLESTART
+.place_table_loop
+ push bc
+ push hl
+ ld e, [hl]
+ inc hl
+ ld h, [hl]
+ ld l, e
+ call .PlaceTableGrid
+ pop hl
+ inc hl
+ inc hl
+ pop bc
+ dec c
+ jr nz, .place_table_loop
+ ret
+
+.PlaceTableGrid:
+ ld de, SCREEN_WIDTH
+ ld b, 3
+.placegrid_outerloop
+ push hl
+ ld c, 3
+.placegrid_innerloop
+ ld [hli], a
+ inc a
+ dec c
+ jr nz, .placegrid_innerloop
+ pop hl
+ add hl, de
+ dec b
+ jr nz, .placegrid_outerloop
+ ret
+
+.TableCoords:
+; row 1
+ dwcoord 7, 6
+ dwcoord 10, 6
+ dwcoord 13, 6
+ dwcoord 16, 6
+
+; row 2
+ dwcoord 7, 9
+ dwcoord 10, 9
+ dwcoord 13, 9
+ dwcoord 16, 9
+
+; row 3
+ dwcoord 7, 12
+ dwcoord 10, 12
+ dwcoord 13, 12
+ dwcoord 16, 12
+
+; row 4
+ dwcoord 7, 15
+ dwcoord 10, 15
+ dwcoord 13, 15
+ dwcoord 16, 15
+
+.PlaceColumnNumbers:
+; Set up the tile map for the column numbers.
+ hlcoord 7, 1
+ ld b, 4
+ ld a, PICROSS_GFX_COLUMNS
+.column_numbers_outer_loop
+ push hl
+ ld de, SCREEN_HEIGHT
+ ld c, 4
+.column_numbers_inner_loop
+ ld [hli], a
+ inc a
+ ld [hli], a
+ inc a
+ ld [hl], a
+ inc a
+ add hl, de
+ dec c
+ jr nz, .column_numbers_inner_loop
+ pop hl
+ inc hl
+ inc hl
+ inc hl
+ dec b
+ jr nz, .column_numbers_outer_loop
+ ret
+
+.PlaceRowNumbers:
+; Set up the tile map for the row numbers.
+ hlcoord 1, 6
+ ld b, 4
+ ld a, PICROSS_GFX_ROWS
+.row_numbers_loop1
+ push hl
+ push hl
+ ld de, SCREEN_HEIGHT
+ ld c, 3
+.row_numbers_loop2
+ ld [hli], a
+ inc a
+ ld [hli], a
+ inc a
+ ld [hl], a
+ inc a
+ add hl, de
+ dec c
+ jr nz, .row_numbers_loop2
+ pop hl
+ inc hl
+ inc hl
+ inc hl
+ ld de, SCREEN_HEIGHT + 1
+ ld c, 3
+.row_numbers_loop3
+ ld [hli], a
+ inc a
+ ld [hl], a
+ inc a
+ add hl, de
+ dec c
+ jr nz, .row_numbers_loop3
+ pop hl
+ ld de, $3c
+ add hl, de
+ dec b
+ jr nz, .row_numbers_loop1
+ ret
+
+.HandleError:
+ ld a, [wPicrossErrorCheck]
+ and a
+ ret z
+
+; Print "ERROR" in the middle of the game display.
+ ld hl, .ErrorBitmap
+ decoord 0, 9
+ ld c, .ErrorBitmapEnd - .ErrorBitmap
+
+.print_message:
+ ld a, [hli]
+ add a, PICROSS_GFX_BGTILE
+ ld [de], a
+ inc de
+ dec c
+ jr nz, .print_message
+ ret
+
+.ErrorBitmap:
+ pushc
+ charmap " ", 0
+ charmap "█", 1
+ db " ██ ██ ██ ███ ██ "
+ db " █ █ █ █ █ █ █ █ █ "
+ db " ██ ██ ██ █ █ ██ "
+ db " █ █ █ █ █ █ █ █ █ "
+ db " ██ █ █ █ █ ███ █ █ "
+ popc
+.ErrorBitmapEnd:
+
+Picross_CheckPuzzleSolved:
+ ld de, wPicrossBitmap
+ ld hl, wPicrossMarkedCells
+ ld c, 0
+.loop
+ ld a, [de]
+ and a
+ jr z, .skip
+ ld a, [hl]
+ cp 1
+ jr nz, .unsolved
+ jr .continue
+.skip
+ ld a, [hl]
+ cp 1
+ jr z, .unsolved
+.continue
+ inc hl
+ inc de
+ dec c
+ jr nz, .loop
+
+; Puzzle is solved
+ scf
+ ret
+
+.unsolved
+ and a
+ ret
+
+Picross_ProcessJoypad:
+ ld hl, hJoySum
+ ld a, [hl]
+ and A_BUTTON
+ jr nz, .a_pressed
+
+ ld a, [hl]
+ and B_BUTTON
+ jr nz, .b_pressed
+ ret
+
+.b_pressed
+ ld a, 1
+ jr .mark_cell
+
+.a_pressed
+ xor a
+
+.mark_cell
+ ld [wPicrossJoypadAction], a
+ ld a, 1
+ ld [wca59], a
+ call Picross_DetermineGridCoord
+ call Picross_MarkCell
+ call Picross_InitDustObject
+ ret
+
+Picross_InitDustObject:
+ ld hl, wPicrossCursorSpritePointer
+ ld c, [hl]
+ inc hl
+ ld b, [hl]
+ ld hl, SPRITEANIMSTRUCT_XCOORD
+ add hl, bc
+ ld e, [hl]
+ inc e
+ inc e
+ inc e
+ ld hl, SPRITEANIMSTRUCT_YCOORD
+ add hl, bc
+ ld d, [hl]
+ inc d
+ inc d
+ ld a, [wPicrossCurrentCellType]
+ cp PICROSS_COLORED_CELL
+ ret nz
+
+; Make dust object only if we are marking a cell
+ ld a, SPRITE_ANIM_INDEX_MINIGAME_PICROSS_DUST
+ call InitSpriteAnimStruct
+ ret
+
+Picross_DetermineGridCoord:
+; Determines wPicrossCurrentGridNumber and wPicrossCurrentCellNumber
+; from the cursor's current X and Y position.
+ ld hl, wPicrossCursorSpritePointer
+ ld c, [hl]
+ inc hl
+ ld b, [hl]
+
+ ld hl, SPRITEANIMSTRUCT_XCOORD
+ add hl, bc
+ ld a, [hl]
+ sub $40
+ call .WriteXGridCoords
+
+ ld hl, SPRITEANIMSTRUCT_YCOORD
+ add hl, bc
+ ld a, [hl]
+ sub $40
+ call .WriteYGridCoords
+ ret
+
+.WriteXGridCoords:
+ cp $48
+ jr nc, .fourth_grid_column
+ cp $30
+ jr nc, .third_grid_column
+ cp $18
+ jr nc, .second_grid_column
+
+; first grid column
+ call .WriteXCellCoords
+ ld a, 0
+ jr .grid_column_okay
+
+.second_grid_column
+ sub $18
+ call .WriteXCellCoords
+ ld a, 1
+ jr .grid_column_okay
+
+.third_grid_column
+ sub $30
+ call .WriteXCellCoords
+ ld a, 2
+ jr .grid_column_okay
+
+.fourth_grid_column
+ sub $48
+ call .WriteXCellCoords
+ ld a, 3
+
+.grid_column_okay
+ ld [wPicrossCurrentGridNumber], a
+ ret
+
+.WriteYGridCoords:
+ cp $48
+ jr nc, .fourth_grid_row
+ cp $30
+ jr nc, .third_grid_row
+ cp $18
+ jr nc, .second_grid_row
+
+; first grid row
+ call .WriteYCellCoords
+ ld a, [wPicrossCurrentGridNumber]
+ add a, 0
+ jr .grid_row_okay
+
+.second_grid_row
+ sub $18
+ call .WriteYCellCoords
+ ld a, [wPicrossCurrentGridNumber]
+ add a, 4
+ jr .grid_row_okay
+
+.third_grid_row
+ sub $30
+ call .WriteYCellCoords
+ ld a, [wPicrossCurrentGridNumber]
+ add a, 8
+ jr .grid_row_okay
+
+.fourth_grid_row
+ sub $48
+ call .WriteYCellCoords
+ ld a, [wPicrossCurrentGridNumber]
+ add a, 12
+
+.grid_row_okay
+ ld [wPicrossCurrentGridNumber], a
+ ret
+
+.WriteXCellCoords:
+ cp $12
+ jr z, .fourth_cell_column
+ cp $c
+ jr z, .third_cell_column
+ cp $6
+ jr z, .second_cell_column
+
+; first cell column
+ ld a, 0
+ jr .cell_column_okay
+
+.second_cell_column
+ ld a, 1
+ jr .cell_column_okay
+
+.third_cell_column
+ ld a, 2
+ jr .cell_column_okay
+
+.fourth_cell_column
+ ld a, 3
+
+.cell_column_okay
+ ld [wPicrossCurrentCellNumber], a
+ ret
+
+.WriteYCellCoords:
+ cp $12
+ jr z, .fourth_cell_row
+ cp $c
+ jr z, .third_cell_row
+ cp $6
+ jr z, .second_cell_row
+
+; first cell row
+ ld a, [wPicrossCurrentCellNumber]
+ add a, 0
+ jr .cell_row_okay
+
+.second_cell_row
+ ld a, [wPicrossCurrentCellNumber]
+ add a, 4
+ jr .cell_row_okay
+
+.third_cell_row
+ ld a, [wPicrossCurrentCellNumber]
+ add a, 8
+ jr .cell_row_okay
+
+.fourth_cell_row
+ ld a, [wPicrossCurrentCellNumber]
+ add a, 12
+
+.cell_row_okay
+ ld [wPicrossCurrentCellNumber], a
+ ret
+
+Picross_MarkCell:
+ call Picross_SetTargetCellType
+ ld hl, vPicrossPlayArea
+
+; space between each grid in VRAM
+ ld de, 9 tiles
+ ld a, [wPicrossCurrentGridNumber]
+
+.find_tile
+ and a
+ jr z, .update_tile
+ dec a
+ add hl, de
+ jr .find_tile
+
+.update_tile
+ push hl
+ ld e, l
+ ld d, h
+ ld hl, wPicrossRowGFX2bppBuffer
+ ld c, 9
+ ld b, BANK(@)
+ call Request2bpp
+ call Picross_SetMarkedCellGFX
+ pop hl
+
+ ld de, wPicrossRowGFX2bppBuffer
+ ld c, 9
+ ld b, BANK(@)
+ call Request2bpp
+ ret
+
+Picross_SetTargetCellType:
+ ld a, [wPicrossCurrentGridNumber]
+ ld d, a
+ and 12
+ swap a
+ ld e, a
+ ld a, d
+ and 3
+ sla a
+ sla a
+ or e
+ ld e, a
+
+ ld a, [wPicrossCurrentCellNumber]
+ ld d, a
+ and 12
+ sla a
+ sla a
+ or e
+ ld e, a
+ ld a, d
+ and 3
+ or e
+ ld e, a
+ ld d, 0
+
+ ld hl, wPicrossMarkedCells
+ add hl, de
+ ldh a, [hJoypadState]
+ and %11111100
+ jr z, .check_b_pressed
+
+ ld a, [wPicrossCurrentCellType]
+ ld [hl], a
+ ret
+
+.check_b_pressed
+ ld a, [wPicrossJoypadAction]
+ and a
+ jr z, .check_a_pressed
+ ld a, [hl]
+ cp B_BUTTON
+ jr z, .done
+
+ ld a, PICROSS_MARKED_CELL
+ ld [wPicrossCurrentCellType], a
+ ld [hl], a
+ ret
+
+.check_a_pressed
+ ld a, [hl]
+ cp A_BUTTON
+ jr z, .done
+
+ ld a, PICROSS_COLORED_CELL
+ ld [wPicrossCurrentCellType], a
+ ld [hl], a
+ ret
+
+.done
+ xor a ; PICROSS_BLANK_CELL
+ ld [wPicrossCurrentCellType], a
+ ld [hl], a
+ ret
+
+Picross_SetMarkedCellGFX:
+ ld a, [wPicrossCurrentCellNumber]
+ ld e, a
+ ld d, 0
+ ld hl, .BufferRoutineTable
+ add hl, de
+ add hl, de
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld [wPicrossBase2bppPointer], a
+ ld a, [hli]
+ ld [wPicrossBase2bppPointer + 1], a
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ jp hl
+
+.BufferRoutineTable:
+ dw wPicrossRowGFX2bppBuffer, Picross_SetCellGFX_1
+ dw wPicrossRowGFX2bppBuffer, Picross_SetCellGFX_2
+ dw wPicrossRowGFX2bppBuffer + $10, Picross_SetCellGFX_3
+ dw wPicrossRowGFX2bppBuffer + $20, Picross_SetCellGFX_4
+
+ dw wPicrossRowGFX2bppBuffer, Picross_SetCellGFX_5
+ dw wPicrossRowGFX2bppBuffer, Picross_SetCellGFX_6
+ dw wPicrossRowGFX2bppBuffer + $10, Picross_SetCellGFX_7
+ dw wPicrossRowGFX2bppBuffer + $20, Picross_SetCellGFX_8
+
+ dw wPicrossRowGFX2bppBuffer + $30, Picross_SetCellGFX_9
+ dw wPicrossRowGFX2bppBuffer + $30, Picross_SetCellGFX_10
+ dw wPicrossRowGFX2bppBuffer + $40, Picross_SetCellGFX_11
+ dw wPicrossRowGFX2bppBuffer + $50, Picross_SetCellGFX_12
+
+ dw wPicrossRowGFX2bppBuffer + $60, Picross_SetCellGFX_13
+ dw wPicrossRowGFX2bppBuffer + $60, Picross_SetCellGFX_14
+ dw wPicrossRowGFX2bppBuffer + $70, Picross_SetCellGFX_15
+ dw wPicrossRowGFX2bppBuffer + $80, Picross_SetCellGFX_16
+
+Picross_InitPicrossTable:
+; Pick between 4 available layouts at random.
+ call Random
+ and 3
+
+ call Picross_LoadLayout
+ call Picross_GoThroughLayout
+ call Picross_PopulateRAMBitmap
+ ret
+
+Picross_PopulateRAMBitmap:
+ ld de, wPicrossBitmap
+
+; Populate top half
+ ld hl, wPicrossLayoutBuffer
+ ld c, 8
+.tiles
+ push bc
+ push hl
+ call .PopulateOneRow
+ ld bc, LEN_2BPP_TILE
+ add hl, bc
+ call .PopulateOneRow
+ pop hl
+ inc hl
+ inc hl
+ pop bc
+ dec c
+ jr nz, .tiles
+
+; Populate bottom half
+ ld hl, wPicrossLayoutBuffer2
+ ld c, 8
+.tiles2
+ push bc
+ push hl
+ call .PopulateOneRow
+ ld bc, LEN_2BPP_TILE
+ add hl, bc
+ call .PopulateOneRow
+ pop hl
+ inc hl
+ inc hl
+ pop bc
+ dec c
+ jr nz, .tiles2
+ ret
+
+.PopulateOneRow:
+ ld b, [hl]
+ ld c, 8
+.loop
+ ld a, 0
+ sla b
+ rl a
+ ld [de], a
+ inc de
+ dec c
+ jr nz, .loop
+ ret
+
+Picross_GoThroughLayout:
+ ld hl, wPicrossLayoutBuffer - 1
+ ld c, $20
+.loop
+ ld a, [hli]
+ and [hl]
+ ld [hli], a
+ dec c
+ jr nz, .loop
+ ret
+
+Picross_InitPicrossDigits:
+ call Picross_InitDigitBuffer
+ call Picross_CountColumnDigits
+ jr c, .errored
+
+ call Picross_ApplyColumnDigits
+ call Picross_InitDigitBuffer
+ call Picross_CountRowDigits
+ jr c, .errored
+
+ call Picross_ApplyRowDigits
+ xor a
+ ld [wPicrossErrorCheck], a
+ ret
+
+.errored
+ ld a, 1
+ ld [wPicrossErrorCheck], a
+ ret
+
+Picross_InitDigitBuffer:
+ ld hl, wPicrossNumbersBuffer
+ ld c, 0
+ ld a, $ff
+.loop
+ ld [hli], a
+ dec c
+ jr nz, .loop
+ ret
+
+Picross_CountColumnDigits:
+ ld hl, wPicrossBitmap
+ ld de, wPicrossNumbersBuffer
+ ld c, $10
+.loop
+ push bc
+ push hl
+ push de
+ call .CountDigits
+ jr nc, .error
+ pop de
+ ld hl, 5
+ add hl, de
+ ld e, l
+ ld d, h
+ pop hl
+ inc hl
+ pop bc
+ dec c
+ jr nz, .loop
+ and a
+ ret
+
+.error
+ pop de
+ pop hl
+ pop bc
+ scf
+ ret
+
+.CountDigits:
+ xor a
+ ld [de], a
+ ld b, 0
+ ld c, $11
+.loop1
+ call .determine
+ ret c
+ and a
+ jr z, .loop1
+ xor a
+ ld [de], a
+.loop2
+ ld a, [de]
+ inc a
+ ld [de], a
+ call .determine
+ ret c
+ and a
+ jr nz, .loop2
+ inc de
+ inc b
+ ld a, b
+ cp 5
+ jr c, .loop1
+ and a
+ ret
+
+.determine
+ push de
+ ld a, [hl]
+ ld de, $10
+ add hl, de
+ pop de
+ dec c
+ jr z, .skip
+ and a
+ ret
+
+.skip
+ scf
+ ret
+
+Picross_CountRowDigits:
+ ld hl, wPicrossBitmap
+ ld de, wPicrossNumbersBuffer
+ ld c, $10
+.loop
+ push bc
+ push hl
+ push de
+ call .CountDigits
+ jr nc, .error
+ pop de
+ ld hl, 6
+ add hl, de
+ ld e, l
+ ld d, h
+ pop hl
+ ld bc, $10
+ add hl, bc
+ pop bc
+ dec c
+ jr nz, .loop
+ and a
+ ret
+
+.error
+ pop de
+ pop hl
+ pop bc
+ scf
+ ret
+
+.CountDigits:
+ xor a
+ ld [de], a
+ ld b, 0
+ ld c, 17
+.loop1
+ call .determine
+ ret c
+ and a
+ jr z, .loop1
+ xor a
+ ld [de], a
+.loop2
+ ld a, [de]
+ inc a
+ ld [de], a
+ call .determine
+ ret c
+ and a
+ jr nz, .loop2
+ inc de
+ inc b
+ ld a, b
+ cp 6
+ jr c, .loop1
+ and a
+ ret
+.determine
+ ld a, [hli]
+ dec c
+ jr z, .skip
+ and a
+ ret
+
+.skip
+ scf
+ ret
+
+Picross_ApplyColumnDigits:
+ ld c, 80
+ ld hl, Picross_VRAMAndDigitRowPointers
+ call Picross_ApplyDigits
+ ret
+
+Picross_VRAMAndDigitRowPointers:
+; A huge table of VRAM locations and the subroutine to apply to it.
+; This is used for printing the row digits in the proper positions.
+
+; row 0
+ dw vPicrossBackground tile 4, Picross_SetCellGFX_1
+ dw vPicrossBackground tile 4, Picross_SetCellGFX_5
+ dw vPicrossBackground tile 7, Picross_SetCellGFX_9
+ dw vPicrossBackground tile 10, Picross_SetCellGFX_13
+ dw vPicrossBackground tile 13, Picross_SetCellGFX_1
+; row 1
+ dw vPicrossBackground tile 4, Picross_SetCellGFX_2
+ dw vPicrossBackground tile 4, Picross_SetCellGFX_6
+ dw vPicrossBackground tile 7, Picross_SetCellGFX_10
+ dw vPicrossBackground tile 10, Picross_SetCellGFX_14
+ dw vPicrossBackground tile 13, Picross_SetCellGFX_2
+; row 2
+ dw vPicrossBackground tile 5, Picross_SetCellGFX_3
+ dw vPicrossBackground tile 5, Picross_SetCellGFX_7
+ dw vPicrossBackground tile 8, Picross_SetCellGFX_11
+ dw vPicrossBackground tile 11, Picross_SetCellGFX_15
+ dw vPicrossBackground tile 14, Picross_SetCellGFX_3
+; row 3
+ dw vPicrossBackground tile 6, Picross_SetCellGFX_4
+ dw vPicrossBackground tile 6, Picross_SetCellGFX_8
+ dw vPicrossBackground tile 9, Picross_SetCellGFX_12
+ dw vPicrossBackground tile 12, Picross_SetCellGFX_16
+ dw vPicrossBackground tile 15, Picross_SetCellGFX_4
+; row 4
+ dw vPicrossBackground tile 16, Picross_SetCellGFX_1
+ dw vPicrossBackground tile 16, Picross_SetCellGFX_5
+ dw vPicrossBackground tile 19, Picross_SetCellGFX_9
+ dw vPicrossBackground tile 22, Picross_SetCellGFX_13
+ dw vPicrossBackground tile 25, Picross_SetCellGFX_1
+; row 5
+ dw vPicrossBackground tile 16, Picross_SetCellGFX_2
+ dw vPicrossBackground tile 16, Picross_SetCellGFX_6
+ dw vPicrossBackground tile 19, Picross_SetCellGFX_10
+ dw vPicrossBackground tile 22, Picross_SetCellGFX_14
+ dw vPicrossBackground tile 25, Picross_SetCellGFX_2
+ dw vPicrossBackground tile 17, Picross_SetCellGFX_3
+; row 6
+ dw vPicrossBackground tile 17, Picross_SetCellGFX_7
+ dw vPicrossBackground tile 20, Picross_SetCellGFX_11
+ dw vPicrossBackground tile 23, Picross_SetCellGFX_15
+ dw vPicrossBackground tile 26, Picross_SetCellGFX_3
+ dw vPicrossBackground tile 18, Picross_SetCellGFX_4
+; row 7
+ dw vPicrossBackground tile 18, Picross_SetCellGFX_8
+ dw vPicrossBackground tile 21, Picross_SetCellGFX_12
+ dw vPicrossBackground tile 24, Picross_SetCellGFX_16
+ dw vPicrossBackground tile 27, Picross_SetCellGFX_4
+ dw vPicrossBackground tile 28, Picross_SetCellGFX_1
+; row 8
+ dw vPicrossBackground tile 28, Picross_SetCellGFX_5
+ dw vPicrossBackground tile 31, Picross_SetCellGFX_9
+ dw vPicrossBackground tile 34, Picross_SetCellGFX_13
+ dw vPicrossBackground tile 37, Picross_SetCellGFX_1
+ dw vPicrossBackground tile 28, Picross_SetCellGFX_2
+; row 9
+ dw vPicrossBackground tile 28, Picross_SetCellGFX_6
+ dw vPicrossBackground tile 31, Picross_SetCellGFX_10
+ dw vPicrossBackground tile 34, Picross_SetCellGFX_14
+; row 10
+ dw vPicrossBackground tile 37, Picross_SetCellGFX_2
+ dw vPicrossBackground tile 29, Picross_SetCellGFX_3
+ dw vPicrossBackground tile 29, Picross_SetCellGFX_7
+ dw vPicrossBackground tile 32, Picross_SetCellGFX_11
+ dw vPicrossBackground tile 35, Picross_SetCellGFX_15
+ dw vPicrossBackground tile 38, Picross_SetCellGFX_3
+; row 11
+ dw vPicrossBackground tile 30, Picross_SetCellGFX_4
+ dw vPicrossBackground tile 30, Picross_SetCellGFX_8
+ dw vPicrossBackground tile 33, Picross_SetCellGFX_12
+ dw vPicrossBackground tile 36, Picross_SetCellGFX_16
+ dw vPicrossBackground tile 39, Picross_SetCellGFX_4
+; row 12
+ dw vPicrossBackground tile 40, Picross_SetCellGFX_1
+ dw vPicrossBackground tile 40, Picross_SetCellGFX_5
+ dw vPicrossBackground tile 43, Picross_SetCellGFX_9
+ dw vPicrossBackground tile 46, Picross_SetCellGFX_13
+ dw vPicrossBackground tile 49, Picross_SetCellGFX_1
+; row 13
+ dw vPicrossBackground tile 40, Picross_SetCellGFX_2
+ dw vPicrossBackground tile 40, Picross_SetCellGFX_6
+ dw vPicrossBackground tile 43, Picross_SetCellGFX_10
+ dw vPicrossBackground tile 46, Picross_SetCellGFX_14
+ dw vPicrossBackground tile 49, Picross_SetCellGFX_2
+; row 14
+ dw vPicrossBackground tile 41, Picross_SetCellGFX_3
+ dw vPicrossBackground tile 41, Picross_SetCellGFX_7
+ dw vPicrossBackground tile 44, Picross_SetCellGFX_11
+ dw vPicrossBackground tile 47, Picross_SetCellGFX_15
+ dw vPicrossBackground tile 50, Picross_SetCellGFX_3
+; row 15
+ dw vPicrossBackground tile 42, Picross_SetCellGFX_4
+ dw vPicrossBackground tile 42, Picross_SetCellGFX_8
+ dw vPicrossBackground tile 45, Picross_SetCellGFX_12
+ dw vPicrossBackground tile 48, Picross_SetCellGFX_16
+ dw vPicrossBackground tile 51, Picross_SetCellGFX_4
+
+Picross_ApplyRowDigits:
+ ld c, 96
+ ld hl, Picross_VRAMAndDigitColumnPointers
+ call Picross_ApplyDigits
+ ret
+
+Picross_VRAMAndDigitColumnPointers:
+; Another huge table of VRAM locations and the subroutine to apply to it.
+; Used for printing the column digits in the proper positions.
+
+; column 0
+ dw vPicrossBackground tile 52, Picross_SetCellGFX_1
+ dw vPicrossBackground tile 52, Picross_SetCellGFX_2
+ dw vPicrossBackground tile 53, Picross_SetCellGFX_3
+ dw vPicrossBackground tile 54, Picross_SetCellGFX_4
+ dw vPicrossBackground tile 61, Picross_SetCellGFX_1
+ dw vPicrossBackground tile 61, Picross_SetCellGFX_2
+; column 1
+ dw vPicrossBackground tile 52, Picross_SetCellGFX_5
+ dw vPicrossBackground tile 52, Picross_SetCellGFX_6
+ dw vPicrossBackground tile 53, Picross_SetCellGFX_7
+ dw vPicrossBackground tile 54, Picross_SetCellGFX_8
+ dw vPicrossBackground tile 61, Picross_ApplyDigit_17
+ dw vPicrossBackground tile 61, Picross_ApplyDigit_18
+; column 2
+ dw vPicrossBackground tile 55, Picross_SetCellGFX_9
+ dw vPicrossBackground tile 55, Picross_SetCellGFX_10
+ dw vPicrossBackground tile 56, Picross_SetCellGFX_11
+ dw vPicrossBackground tile 57, Picross_SetCellGFX_12
+ dw vPicrossBackground tile 63, Picross_ApplyDigit_19
+ dw vPicrossBackground tile 63, Picross_ApplyDigit_20
+; column 3
+ dw vPicrossBackground tile 58, Picross_SetCellGFX_13
+ dw vPicrossBackground tile 58, Picross_SetCellGFX_14
+ dw vPicrossBackground tile 59, Picross_SetCellGFX_15
+ dw vPicrossBackground tile 60, Picross_SetCellGFX_16
+ dw vPicrossBackground tile 65, Picross_SetCellGFX_13
+ dw vPicrossBackground tile 65, Picross_SetCellGFX_14
+; column 4
+ dw vPicrossBackground tile 67, Picross_SetCellGFX_1
+ dw vPicrossBackground tile 67, Picross_SetCellGFX_2
+ dw vPicrossBackground tile 68, Picross_SetCellGFX_3
+ dw vPicrossBackground tile 69, Picross_SetCellGFX_4
+ dw vPicrossBackground tile 76, Picross_SetCellGFX_1
+ dw vPicrossBackground tile 76, Picross_SetCellGFX_2
+; column 5
+ dw vPicrossBackground tile 67, Picross_SetCellGFX_5
+ dw vPicrossBackground tile 67, Picross_SetCellGFX_6
+ dw vPicrossBackground tile 68, Picross_SetCellGFX_7
+ dw vPicrossBackground tile 69, Picross_SetCellGFX_8
+ dw vPicrossBackground tile 76, Picross_ApplyDigit_17
+ dw vPicrossBackground tile 76, Picross_ApplyDigit_18
+; column 6
+ dw vPicrossBackground tile 70, Picross_SetCellGFX_9
+ dw vPicrossBackground tile 70, Picross_SetCellGFX_10
+ dw vPicrossBackground tile 71, Picross_SetCellGFX_11
+ dw vPicrossBackground tile 72, Picross_SetCellGFX_12
+ dw vPicrossBackground tile 78, Picross_ApplyDigit_19
+ dw vPicrossBackground tile 78, Picross_ApplyDigit_20
+; column 7
+ dw vPicrossBackground tile 73, Picross_SetCellGFX_13
+ dw vPicrossBackground tile 73, Picross_SetCellGFX_14
+ dw vPicrossBackground tile 74, Picross_SetCellGFX_15
+ dw vPicrossBackground tile 75, Picross_SetCellGFX_16
+ dw vPicrossBackground tile 80, Picross_SetCellGFX_13
+ dw vPicrossBackground tile 80, Picross_SetCellGFX_14
+; column 8
+ dw vPicrossBackground tile 82, Picross_SetCellGFX_1
+ dw vPicrossBackground tile 82, Picross_SetCellGFX_2
+ dw vPicrossBackground tile 83, Picross_SetCellGFX_3
+ dw vPicrossBackground tile 84, Picross_SetCellGFX_4
+ dw vPicrossBackground tile 91, Picross_SetCellGFX_1
+ dw vPicrossBackground tile 91, Picross_SetCellGFX_2
+; column 9
+ dw vPicrossBackground tile 82, Picross_SetCellGFX_5
+ dw vPicrossBackground tile 82, Picross_SetCellGFX_6
+ dw vPicrossBackground tile 83, Picross_SetCellGFX_7
+ dw vPicrossBackground tile 84, Picross_SetCellGFX_8
+ dw vPicrossBackground tile 91, Picross_ApplyDigit_17
+ dw vPicrossBackground tile 91, Picross_ApplyDigit_18
+; column 10
+ dw vPicrossBackground tile 85, Picross_SetCellGFX_9
+ dw vPicrossBackground tile 85, Picross_SetCellGFX_10
+ dw vPicrossBackground tile 86, Picross_SetCellGFX_11
+ dw vPicrossBackground tile 87, Picross_SetCellGFX_12
+ dw vPicrossBackground tile 93, Picross_ApplyDigit_19
+ dw vPicrossBackground tile 93, Picross_ApplyDigit_20
+; column 11
+ dw vPicrossBackground tile 88, Picross_SetCellGFX_13
+ dw vPicrossBackground tile 88, Picross_SetCellGFX_14
+ dw vPicrossBackground tile 89, Picross_SetCellGFX_15
+ dw vPicrossBackground tile 90, Picross_SetCellGFX_16
+ dw vPicrossBackground tile 95, Picross_SetCellGFX_13
+ dw vPicrossBackground tile 95, Picross_SetCellGFX_14
+; column 12
+ dw vPicrossBackground tile 97, Picross_SetCellGFX_1
+ dw vPicrossBackground tile 97, Picross_SetCellGFX_2
+ dw vPicrossBackground tile 98, Picross_SetCellGFX_3
+ dw vPicrossBackground tile 99, Picross_SetCellGFX_4
+ dw vPicrossBackground tile 106, Picross_SetCellGFX_1
+ dw vPicrossBackground tile 106, Picross_SetCellGFX_2
+; column 13
+ dw vPicrossBackground tile 97, Picross_SetCellGFX_5
+ dw vPicrossBackground tile 97, Picross_SetCellGFX_6
+ dw vPicrossBackground tile 98, Picross_SetCellGFX_7
+ dw vPicrossBackground tile 99, Picross_SetCellGFX_8
+ dw vPicrossBackground tile 106, Picross_ApplyDigit_17
+ dw vPicrossBackground tile 106, Picross_ApplyDigit_18
+; column 14
+ dw vPicrossBackground tile 100, Picross_SetCellGFX_9
+ dw vPicrossBackground tile 100, Picross_SetCellGFX_10
+ dw vPicrossBackground tile 101, Picross_SetCellGFX_11
+ dw vPicrossBackground tile 102, Picross_SetCellGFX_12
+ dw vPicrossBackground tile 108, Picross_ApplyDigit_19
+ dw vPicrossBackground tile 108, Picross_ApplyDigit_20
+; column 15
+ dw vPicrossBackground tile 103, Picross_SetCellGFX_13
+ dw vPicrossBackground tile 103, Picross_SetCellGFX_14
+ dw vPicrossBackground tile 104, Picross_SetCellGFX_15
+ dw vPicrossBackground tile 105, Picross_SetCellGFX_16
+ dw vPicrossBackground tile 110, Picross_SetCellGFX_13
+ dw vPicrossBackground tile 110, Picross_SetCellGFX_14
+
+Picross_ApplyDigits:
+ xor a
+ ld [wPicrossDrawingRoutineCounter], a
+.loop
+ push bc
+ push hl
+ call Picross_ApplyDigit
+ pop hl
+ inc hl
+ inc hl
+ inc hl
+ inc hl
+ pop bc
+ dec c
+ jr nz, .loop
+ ret
+
+Picross_ApplyDigit:
+ push hl
+ ld hl, wPicrossDrawingRoutineCounter
+ ld e, [hl]
+ inc [hl]
+ ld d, 0
+ ld hl, wPicrossNumbersBuffer
+ add hl, de
+ ld a, [hl]
+ cp $ff
+ jr z, .done_applying_digit
+
+ swap a
+ and $f0
+ ld e, a
+ ld a, [hl]
+ swap a
+ and $f
+ ld d, a
+
+ ld hl, PicrossNumbersGFX
+ add hl, de
+ ld a, l
+ ld [wPicrossBaseGFXPointer], a
+ ld a, h
+ ld [wPicrossBaseGFXPointer+1], a
+ pop hl
+
+ ld a, [hli]
+ ld [wPicrossBase2bppPointer], a
+ ld a, [hli]
+ ld [wPicrossBase2bppPointer+1], a
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ jp hl
+
+.done_applying_digit
+ pop hl
+ ret
+
+Picross_SetCellGFX_1:
+ call Picross_SetTileGFXPointerDE
+ ld hl, 0
+ call Picross_AddToHL2bppPointer
+ ld c, 10
+ call Picross_ApplyTileGFXTopLeftFull
+ ret
+
+Picross_SetCellGFX_2:
+ call Picross_SetTileGFXPointerDE
+ ld hl, 0
+ call Picross_AddToHL2bppPointer
+ ld c, 10
+ call Picross_ApplyTileGFXTopRight1
+
+ call Picross_SetTileGFXPointerDE
+ ld hl, $10
+ call Picross_AddToHL2bppPointer
+ ld c, 10
+ call Picross_ApplyTileGFXTopLeft1
+
+ ret
+
+Picross_SetCellGFX_3:
+ call Picross_SetTileGFXPointerDE
+ ld hl, 0
+ call Picross_AddToHL2bppPointer
+ ld c, 10
+ call Picross_ApplyTileGFXTopRight2
+
+ call Picross_SetTileGFXPointerDE
+ ld hl, $10
+ call Picross_AddToHL2bppPointer
+ ld c, 10
+ call Picross_ApplyTileGFXTopLeft2
+
+ ret
+
+Picross_SetCellGFX_4:
+ call Picross_SetTileGFXPointerDE
+ ld hl, 0
+ call Picross_AddToHL2bppPointer
+ ld c, 10
+ call Picross_ApplyTileGFXTopRightFull
+ ret
+
+Picross_SetCellGFX_5:
+ call Picross_SetTileGFXPointerDE
+ ld hl, 12
+ call Picross_AddToHL2bppPointer
+ ld c, 4
+ call Picross_ApplyTileGFXTopLeftFull
+ ld hl, $30
+ call Picross_AddToHL2bppPointer
+ ld c, 6
+ call Picross_ApplyTileGFXTopLeftFull
+ ret
+
+Picross_SetCellGFX_6:
+ call Picross_SetTileGFXPointerDE
+ ld hl, 12
+ call Picross_AddToHL2bppPointer
+ ld c, 4
+ call Picross_ApplyTileGFXTopRight1
+ ld hl, $30
+ call Picross_AddToHL2bppPointer
+ ld c, 6
+ call Picross_ApplyTileGFXTopRight1
+ call Picross_SetTileGFXPointerDE
+ ld hl, $1c
+ call Picross_AddToHL2bppPointer
+ ld c, 4
+ call Picross_ApplyTileGFXTopLeft1
+ ld hl, $40
+ call Picross_AddToHL2bppPointer
+ ld c, 6
+ call Picross_ApplyTileGFXTopLeft1
+ ret
+
+Picross_SetCellGFX_7:
+ call Picross_SetTileGFXPointerDE
+ ld hl, $c
+ call Picross_AddToHL2bppPointer
+ ld c, 4
+ call Picross_ApplyTileGFXTopRight2
+ ld hl, $30
+ call Picross_AddToHL2bppPointer
+ ld c, 6
+ call Picross_ApplyTileGFXTopRight2
+ call Picross_SetTileGFXPointerDE
+ ld hl, $1c
+ call Picross_AddToHL2bppPointer
+ ld c, 4
+ call Picross_ApplyTileGFXTopLeft2
+ ld hl, $40
+ call Picross_AddToHL2bppPointer
+ ld c, 6
+ call Picross_ApplyTileGFXTopLeft2
+ ret
+
+Picross_SetCellGFX_8:
+ call Picross_SetTileGFXPointerDE
+ ld hl, $c
+ call Picross_AddToHL2bppPointer
+ ld c, 4
+ call Picross_ApplyTileGFXTopRightFull
+ ld hl, $30
+ call Picross_AddToHL2bppPointer
+ ld c, 6
+ call Picross_ApplyTileGFXTopRightFull
+ ret
+
+Picross_SetCellGFX_9:
+ call Picross_SetTileGFXPointerDE
+ ld hl, 8
+ call Picross_AddToHL2bppPointer
+ ld c, 8
+ call Picross_ApplyTileGFXTopLeftFull
+ ld hl, $30
+ call Picross_AddToHL2bppPointer
+ ld c, 2
+ call Picross_ApplyTileGFXTopLeftFull
+ ret
+
+Picross_SetCellGFX_10:
+ call Picross_SetTileGFXPointerDE
+ ld hl, 8
+ call Picross_AddToHL2bppPointer
+ ld c, 8
+ call Picross_ApplyTileGFXTopRight1
+ ld hl, $30
+ call Picross_AddToHL2bppPointer
+ ld c, 2
+ call Picross_ApplyTileGFXTopRight1
+ call Picross_SetTileGFXPointerDE
+ ld hl, $18
+ call Picross_AddToHL2bppPointer
+ ld c, 8
+ call Picross_ApplyTileGFXTopLeft1
+ ld hl, $40
+ call Picross_AddToHL2bppPointer
+ ld c, 2
+ call Picross_ApplyTileGFXTopLeft1
+ ret
+
+Picross_SetCellGFX_11:
+ call Picross_SetTileGFXPointerDE
+ ld hl, 8
+ call Picross_AddToHL2bppPointer
+ ld c, 8
+ call Picross_ApplyTileGFXTopRight2
+ ld hl, $30
+ call Picross_AddToHL2bppPointer
+ ld c, 2
+ call Picross_ApplyTileGFXTopRight2
+ call Picross_SetTileGFXPointerDE
+ ld hl, $18
+ call Picross_AddToHL2bppPointer
+ ld c, 8
+ call Picross_ApplyTileGFXTopLeft2
+ ld hl, $40
+ call Picross_AddToHL2bppPointer
+ ld c, 2
+ call Picross_ApplyTileGFXTopLeft2
+ ret
+
+Picross_SetCellGFX_12:
+ call Picross_SetTileGFXPointerDE
+ ld hl, 8
+ call Picross_AddToHL2bppPointer
+ ld c, 8
+ call Picross_ApplyTileGFXTopRightFull
+ ld hl, $30
+ call Picross_AddToHL2bppPointer
+ ld c, 2
+ call Picross_ApplyTileGFXTopRightFull
+ ret
+
+Picross_SetCellGFX_13:
+ call Picross_SetTileGFXPointerDE
+ ld hl, 4
+ call Picross_AddToHL2bppPointer
+ ld c, $a
+ call Picross_ApplyTileGFXTopLeftFull
+ ret
+
+Picross_SetCellGFX_14:
+ call Picross_SetTileGFXPointerDE
+ ld hl, 4
+ call Picross_AddToHL2bppPointer
+ ld c, $a
+ call Picross_ApplyTileGFXTopRight1
+ call Picross_SetTileGFXPointerDE
+ ld hl, $14
+ call Picross_AddToHL2bppPointer
+ ld c, $a
+ call Picross_ApplyTileGFXTopLeft1
+ ret
+
+Picross_SetCellGFX_15:
+ call Picross_SetTileGFXPointerDE
+ ld hl, 4
+ call Picross_AddToHL2bppPointer
+ ld c, $a
+ call Picross_ApplyTileGFXTopRight2
+ call Picross_SetTileGFXPointerDE
+ ld hl, $14
+ call Picross_AddToHL2bppPointer
+ ld c, $a
+ call Picross_ApplyTileGFXTopLeft2
+ ret
+
+Picross_SetCellGFX_16:
+ call Picross_SetTileGFXPointerDE
+ ld hl, 4
+ call Picross_AddToHL2bppPointer
+ ld c, 10
+ call Picross_ApplyTileGFXTopRightFull
+ ret
+
+Picross_ApplyDigit_17:
+ call Picross_SetTileGFXPointerDE
+ ld hl, $c
+ call Picross_AddToHL2bppPointer
+ ld c, 4
+ call Picross_ApplyTileGFXTopLeftFull
+ ld hl, $20
+ call Picross_AddToHL2bppPointer
+ ld c, 6
+ call Picross_ApplyTileGFXTopLeftFull
+ ret
+
+Picross_ApplyDigit_18:
+ call Picross_SetTileGFXPointerDE
+ ld hl, $c
+ call Picross_AddToHL2bppPointer
+ ld c, 4
+ call Picross_ApplyTileGFXTopRight1
+ ld hl, $20
+ call Picross_AddToHL2bppPointer
+ ld c, 6
+ call Picross_ApplyTileGFXTopRight1
+ call Picross_SetTileGFXPointerDE
+ ld hl, $1c
+ call Picross_AddToHL2bppPointer
+ ld c, 4
+ call Picross_ApplyTileGFXTopLeft1
+ ld hl, $30
+ call Picross_AddToHL2bppPointer
+ ld c, 6
+ call Picross_ApplyTileGFXTopLeft1
+ ret
+
+Picross_ApplyDigit_19:
+ call Picross_SetTileGFXPointerDE
+ ld hl, 8
+ call Picross_AddToHL2bppPointer
+ ld c, 8
+ call Picross_ApplyTileGFXTopLeftFull
+ ld hl, $20
+ call Picross_AddToHL2bppPointer
+ ld c, 2
+ call Picross_ApplyTileGFXTopLeftFull
+ ret
+
+Picross_ApplyDigit_20:
+ call Picross_SetTileGFXPointerDE
+ ld hl, 8
+ call Picross_AddToHL2bppPointer
+ ld c, 8
+ call Picross_ApplyTileGFXTopRight1
+ ld hl, $20
+ call Picross_AddToHL2bppPointer
+ ld c, 2
+ call Picross_ApplyTileGFXTopRight1
+ call Picross_SetTileGFXPointerDE
+ ld hl, $18
+ call Picross_AddToHL2bppPointer
+ ld c, 8
+ call Picross_ApplyTileGFXTopLeft1
+ ld hl, $30
+ call Picross_AddToHL2bppPointer
+ ld c, 2
+ call Picross_ApplyTileGFXTopLeft1
+ ret
+
+Picross_AddToHL2bppPointer:
+ push de
+ ld a, [wPicrossBase2bppPointer]
+ ld e, a
+ ld a, [wPicrossBase2bppPointer+1]
+ ld d, a
+ add hl, de
+ pop de
+ ret
+
+Picross_ApplyTileGFXTopLeftFull:
+ ld a, [de]
+ inc de
+ ld b, $f8
+ call Picross_ApplyTileGFXCommon
+ dec c
+ jr nz, Picross_ApplyTileGFXTopLeftFull
+ ret
+
+Picross_ApplyTileGFXTopRight1:
+ ld a, [de]
+ inc de
+ rlca
+ rlca
+ ld b, 3
+ call Picross_ApplyTileGFXCommon
+ dec c
+ jr nz, Picross_ApplyTileGFXTopRight1
+ ret
+
+Picross_ApplyTileGFXTopLeft1:
+ ld a, [de]
+ inc de
+ sla a
+ sla a
+ ld b, $e0
+ call Picross_ApplyTileGFXCommon
+ dec c
+ jr nz, Picross_ApplyTileGFXTopLeft1
+ ret
+
+Picross_ApplyTileGFXTopRight2:
+ ld a, [de]
+ inc de
+ swap a
+ ld b, $f
+ call Picross_ApplyTileGFXCommon
+ dec c
+ jr nz, Picross_ApplyTileGFXTopRight2
+ ret
+
+Picross_ApplyTileGFXTopLeft2:
+ ld a, [de]
+ inc de
+ swap a
+ ld b, $80
+ call Picross_ApplyTileGFXCommon
+ dec c
+ jr nz, Picross_ApplyTileGFXTopLeft2
+ ret
+
+Picross_ApplyTileGFXTopRightFull:
+ ld a, [de]
+ inc de
+ srl a
+ srl a
+ ld b, 62
+ call Picross_ApplyTileGFXCommon
+ dec c
+ jr nz, Picross_ApplyTileGFXTopRightFull
+ ret
+
+Picross_ApplyTileGFXCommon:
+ push de
+ push af
+ ld a, [wPicrossCurrentCellType]
+ cp -1
+ jr nz, .skip
+ pop af
+ and b
+ ld e, a
+ ld a, [hl]
+ or e
+ ld [hl], a
+ jr .finish
+
+.skip
+ ld a, b
+ xor $ff
+ ld e, a
+ ld a, [hl]
+ and e
+ ld [hl], a
+ pop af
+ and b
+ ld e, a
+ ld a, [hl]
+ or e
+ ld [hl], a
+ jr .finish
+
+.asm_e3516 ; unreferenced
+ ld a, b
+ xor $ff
+ ld e, a
+ ld a, [hl]
+ and e
+ ld [hl], a
+ pop af
+
+.finish
+ pop de
+ inc hl
+ ret
+
+Picross_SetTileGFXPointerDE:
+ ld a, [wPicrossCurrentCellType]
+ cp -1
+ jr z, .skip
+ and 3
+ ld e, a
+ ld d, 0
+ ld hl, .CellGFX
+ add hl, de
+ add hl, de
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ ret
+
+.skip:
+ ld a, [wPicrossBaseGFXPointer]
+ ld e, a
+ ld a, [wPicrossBaseGFXPointer+1]
+ ld d, a
+ ret
+
+.CellGFX:
+; A "tileset" of 5x5 dots to place over the grid GFX.
+ dw .empty
+ dw .colored
+ dw .marked
+ dw .empty
+
+pusho
+opt b.X ; . = 0, X = 1
+.empty:
+ db %........, %........
+ db %.XX.X..., %........
+ db %.X..X..., %........
+ db %....X..., %........
+ db %.XXXX..., %........
+
+.colored:
+ db %XXXXX..., %XXXXX...
+ db %X......., %XXXXX...
+ db %X......., %XXXXX...
+ db %X......., %XXXXX...
+ db %X......., %XXXXX...
+
+.marked:
+ db %........, %........
+ db %..X.X..., %.X.X....
+ db %.X..X..., %..X.....
+ db %....X..., %.X.X....
+ db %.XXXX..., %........
+popo
+
+Picross_LoadLayout:
+ ld l, a
+ ld h, 0
+ add hl, hl
+ add hl, hl
+ ld de, PicrossSprites
+ add hl, de
+ ld a, [hli]
+ and a
+ jr z, .normal_pattern
+
+.tileset_pattern
+; Pattern originates from a tileset.
+; Its bottom half GFX is exactly $100 apart from the top half.
+ ld b, [hl]
+ inc hl
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld de, wPicrossLayoutBuffer - 1
+ ld a, b
+ ld bc, 2 tiles
+ push bc
+ push af
+ push hl
+ call FarCopyData
+ pop hl
+
+; apply offset of bottom half GFX
+ ld bc, $100
+ add hl, bc
+ pop af
+ pop bc
+ call FarCopyData
+ ret
+
+.normal_pattern
+; Pattern originates from regular 2bpp data.
+; Its bottom half GFX directly follows the top half.
+ ld b, [hl]
+ inc hl
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld de, wPicrossLayoutBuffer - 1
+ ld a, b
+ ld bc, 4 tiles
+ call FarCopyData
+ ret
+
+picross_pattern: MACRO
+if _NARG > 2
+ db \1
+ dbw \2, \3
+else
+ db \1
+ dba \2
+endc
+ENDM
+
+PicrossSprites:
+ picross_pattern PATTERN_NORMAL, DiglettIcon
+ picross_pattern PATTERN_NORMAL, GengarIcon
+ picross_pattern PATTERN_NORMAL, AnnonIcon
+ picross_pattern PATTERN_NORMAL, SnorlaxIcon
+; TODO: Setting fixed bank $C for now before Tileset_0c_GFX is ripped
+ picross_pattern PATTERN_TILESET, $c, Tileset_0c_GFX + $200
+ picross_pattern PATTERN_NORMAL, PoliwrathSpriteGFX
+
diff --git a/gfx/gfx.asm b/gfx/gfx.asm
index b4ed26d..6af0a86 100644
--- a/gfx/gfx.asm
+++ b/gfx/gfx.asm
@@ -535,8 +535,14 @@ MemoryGameGFX::
INCBIN "gfx/minigames/matches.2bpp"
SECTION "gfx.asm@Picross GFX", ROMX
-PicrossGFX::
-INCBIN "gfx/minigames/picross.2bpp"
+PicrossNumbersGFX::
+INCBIN "gfx/minigames/picross_numbers.2bpp"
+PicrossBackgroundGFX::
+INCBIN "gfx/minigames/picross_background.2bpp"
+PicrossGridHighlightsGFX::
+INCBIN "gfx/minigames/picross_highlights.2bpp"
+PicrossGridGFX::
+INCBIN "gfx/minigames/picross_grid.2bpp"
PicrossCursorGFX::
INCBIN "gfx/minigames/picross_cursor.2bpp"
diff --git a/gfx/gfx.mk b/gfx/gfx.mk
index 6880d1a..afc5d10 100644
--- a/gfx/gfx.mk
+++ b/gfx/gfx.mk
@@ -17,6 +17,7 @@ $(BUILD)/gfx/minigames/slots_2.2bpp: tools/gfx += --interleave --png=$<
$(BUILD)/gfx/minigames/slots_3.2bpp: tools/gfx += --interleave --png=$< --remove-duplicates --keep-whitespace --remove-xflip
$(BUILD)/gfx/minigames/slots_4.2bpp: tools/gfx += --interleave --png=$<
$(BUILD)/gfx/minigames/poker.2bpp: tools/gfx += --trim-whitespace
+$(BUILD)/gfx/minigames/picross_numbers.2bpp: tools/gfx += --trim-whitespace
$(BUILD)/gfx/intro/jigglypuff_pikachu.2bpp: tools/gfx += --trim-whitespace
diff --git a/gfx/minigames/picross.png b/gfx/minigames/picross.png
deleted file mode 100644
index 37f7e62..0000000
--- a/gfx/minigames/picross.png
+++ /dev/null
Binary files differ
diff --git a/gfx/minigames/picross_background.png b/gfx/minigames/picross_background.png
new file mode 100644
index 0000000..4b779cf
--- /dev/null
+++ b/gfx/minigames/picross_background.png
Binary files differ
diff --git a/gfx/minigames/picross_grid.png b/gfx/minigames/picross_grid.png
new file mode 100644
index 0000000..1228a48
--- /dev/null
+++ b/gfx/minigames/picross_grid.png
Binary files differ
diff --git a/gfx/minigames/picross_highlights.png b/gfx/minigames/picross_highlights.png
new file mode 100644
index 0000000..25f8a90
--- /dev/null
+++ b/gfx/minigames/picross_highlights.png
Binary files differ
diff --git a/gfx/minigames/picross_numbers.png b/gfx/minigames/picross_numbers.png
new file mode 100644
index 0000000..b9f7896
--- /dev/null
+++ b/gfx/minigames/picross_numbers.png
Binary files differ
diff --git a/layout.link b/layout.link
index 49120fe..9dda4d6 100644
--- a/layout.link
+++ b/layout.link
@@ -895,9 +895,11 @@ ROMX $38
"gfx.asm@Poker GFX"
org $5f93
"gfx.asm@15 Puzzle GFX"
- org $6606
+ org $622b
+ "engine/games/memory_minigame.asm"
"gfx.asm@Matches GFX"
- org $75b7
+ org $6886
+ "engine/games/picross_minigame.asm"
"gfx.asm@Picross GFX"
ROMX $39
diff --git a/ram/vram.asm b/ram/vram.asm
index bf10e4d..531fa9e 100644
--- a/ram/vram.asm
+++ b/ram/vram.asm
@@ -52,6 +52,16 @@ vTitleLogo::
vTitleLogo2::
; TODO: what size?
+NEXTU
+
+ ds $80 tiles
+
+vPicrossBackground::
+ ds $70 tiles
+
+vPicrossPlayArea::
+ ds $90 tiles
+
ENDU
diff --git a/ram/wram.asm b/ram/wram.asm
index 0979c19..dc8010a 100644
--- a/ram/wram.asm
+++ b/ram/wram.asm
@@ -244,6 +244,22 @@ wc51a:: ds 1
ds 25
wSlotsEnd:: db
+NEXTU
+
+ ds 200
+
+wMemoryGameCards:: ds 9 * 5
+wMemoryGameCardsEnd::
+wMemoryGameLastCardPicked:: db
+wMemoryGameCard1:: db
+wMemoryGameCard2:: db
+wMemoryGameCard1Location:: db
+wMemoryGameCard2Location:: db
+wMemoryGameNumberTriesRemaining:: db
+wMemoryGameLastMatches:: ds 5
+wMemoryGameCounter:: db
+wMemoryGameNumCardsMatched:: db
+
ENDU
@@ -325,6 +341,29 @@ wPikachuMinigameTilesPointer:: ds 2
wPikachuMinigameColumnBuffer:: ds 16
NEXTU
+
+wPicrossCursorSpritePointer:: ds 2
+wPicrossCurrentGridNumber:: ds 1
+wPicrossCurrentCellNumber:: ds 1
+wPicrossCurrentCellType:: ds 1
+wPicrossJoypadAction:: ds 1
+ ds 1
+wc607:: ds 1
+wPicrossMarkedCells:: ds 4*4*4*4
+ ds 1
+wPicrossLayoutBuffer:: ds $20
+wPicrossLayoutBuffer2:: ds $20 - 1
+wPicrossBitmap:: ds 4*4*4*4
+wPicrossBase2bppPointer:: ds 2
+wPicrossBaseGFXPointer:: ds 2
+wPicrossDrawingRoutineCounter:: ds 1
+ ds 11
+wPicrossNumbersBuffer:: ds 4*4*4*4
+wPicrossRowGFX2bppBuffer:: ds 144
+ ds 112
+wPicrossErrorCheck:: ds 1
+ ds 1
+NEXTU
; Battle-related
ds $1ea
@@ -512,6 +551,7 @@ SECTION "CB5E", WRAM0[$CB5E]
wJumptableIndex:: db
wSlotsDelay::
+wMemoryGameCardChoice::
wFlyDestination::
wIntroSceneFrameCounter::
wTrainerGearPointerPosition::
diff --git a/shim.sym b/shim.sym
index 8abffa2..69db964 100755
--- a/shim.sym
+++ b/shim.sym
@@ -149,8 +149,9 @@
38:48A2 PokerMinigame
38:5AE3 FifteenPuzzleMinigame
-38:622B MemoryMinigame
-38:6886 PicrossMinigame
+
+38:4E5F Cursor_AnimateCursor
+38:4EA8 Cursor_InterpretJoypad
; SFX shims
3C:43BE Sfx_01