diff options
| author | luckytyphlosion <10688458+luckytyphlosion@users.noreply.github.com> | 2018-07-03 13:37:21 -0400 |
|---|---|---|
| committer | luckytyphlosion <10688458+luckytyphlosion@users.noreply.github.com> | 2018-07-03 13:37:21 -0400 |
| commit | 9824a5762008d083ea149af477a3093b89d269a7 (patch) | |
| tree | 84359c2f08878986c4b7486f576c8b9280840f7e /engine | |
| parent | 75e4f784924393ccedb27f2831e5a36fe11bada5 (diff) | |
| parent | 3fab27f221a8d5400d4b203809ff9b13355d55a3 (diff) | |
Merge branch 'master' of https://github.com/pret/pokegold-spaceworld
Diffstat (limited to 'engine')
| -rw-r--r-- | engine/Intro.asm | 800 | ||||
| -rwxr-xr-x | engine/events/field_moves.asm | 544 | ||||
| -rw-r--r-- | engine/menu/debug_menu.asm | 109 | ||||
| -rw-r--r-- | engine/menu/main_menu.asm | 339 | ||||
| -rw-r--r-- | engine/overworld/object_collision.asm | 157 | ||||
| -rw-r--r-- | engine/overworld/player_movement.asm | 1162 | ||||
| -rw-r--r-- | engine/palettes.asm | 4 | ||||
| -rw-r--r-- | engine/sprites/sprites.asm | 155 | ||||
| -rw-r--r-- | engine/title.asm | 4 |
9 files changed, 3069 insertions, 205 deletions
diff --git a/engine/Intro.asm b/engine/Intro.asm new file mode 100644 index 0000000..aa10842 --- /dev/null +++ b/engine/Intro.asm @@ -0,0 +1,800 @@ +include "constants.asm" + +SECTION "Oak Intro and Game Setup", ROMX[$558D], BANK[$01] + +DemoStart:: ; 558D + ld de, OakPic + lb bc, BANK(OakPic), $00 + call IntroDisplayPicCenteredOrUpperRight + call FadeInIntroPic + ld hl, OakSpeechDemo + call PrintText + call RotateThreePalettesRight + call ClearTileMap + ld de, ProtagonistPic + lb bc, BANK(ProtagonistPic), $00 + call IntroDisplayPicCenteredOrUpperRight + call MovePicLeft + ld a, %11010000 + ldh [rOBP0], a + call DemoSetUpPlayer + jp IntroCleanup + +GameStart:: ; 55BB + ld de, OakPic + lb bc, BANK(OakPic), $00 + call IntroDisplayPicCenteredOrUpperRight + call FadeInIntroPic + ld hl, OakSpeech1 + call PrintText + call RotateThreePalettesRight + call ClearTileMap + ld a, DEX_YADOKING + ld [wCurSpecies], a + ld [wMonDexIndex], a + call GetMonHeader + hlcoord 6, 4 + hlcoord 6, 4 + call PrepMonFrontpic + call MovePicLeft + ld hl, OakSpeech2 + call PrintText + ld a, DEX_YADOKING + call PlayCry + ld hl, OakSpeech3 + call PrintText + call RotateThreePalettesRight + call ClearTileMap + ld de, ProtagonistPic + lb bc, BANK(ProtagonistPic), $00 + call IntroDisplayPicCenteredOrUpperRight + call MovePicLeft + ld hl, OakSpeech4 + call PrintText + call ChoosePlayerName + call RotateThreePalettesRight + call ClearTileMap + ld de, RivalPic + lb bc, BANK(RivalPic), $00 + call IntroDisplayPicCenteredOrUpperRight + call FadeInIntroPic + ld hl, OakSpeech5 + call PrintText + call ChooseRivalName + call RotateThreePalettesRight + call ClearTileMap + ld de, OakPic + lb bc, BANK(OakPic), $00 + call IntroDisplayPicCenteredOrUpperRight + call FadeInIntroPic + ld hl, OakSpeech6 + call PrintText + callba SetClockDialog + call Function04ac + call RotateThreePalettesRight + call ClearTileMap + ld de, ProtagonistPic + lb bc, BANK(ProtagonistPic), $00 + call IntroDisplayPicCenteredOrUpperRight + call RotateThreePalettesLeft + ld hl, OakSpeech7 + call PrintText + ldh a, [hROMBank] + push af + ld a, $20 + ld [wMusicFade], a + ld de, MUSIC_NONE + ld a, e + ld [wMusicFadeIDLow], a + ld a, d + ld [wMusicFadeIDHigh], a + ld de, $000B ; should be a constant - shrink noise? + call PlaySFX + pop af + call Bankswitch + ld c, $04 + call DelayFrames + +IntroCleanup:: ; 568E + ld de, ShrinkPic1 + lb bc, BANK(ShrinkPic1), $00 + call IntroDisplayPicCenteredOrUpperRight + ld c, $04 + call DelayFrames + ld de, ShrinkPic2 + lb bc, BANK(ShrinkPic2), $00 + call IntroDisplayPicCenteredOrUpperRight + ld c, $14 + call DelayFrames + hlcoord 6, 5 + ld b, $07 + ld c, $07 + call ClearBox + ld c, $14 + call DelayFrames + call LoadStartingSprites + call LoadFontExtra + ld c, $32 + call DelayFrames + call RotateThreePalettesRight + call ClearTileMap + call Function0502 + ld a, $00 + ld [wd638], a + ld [wd637], a + +OverworldStart:: + call SetUpGameEntry + ld hl, wDebugFlags + bit CONTINUED_F, [hl] + call z, Function15b5 + ld hl, wd4a9 + set 0, [hl] + jp Function2a85 + +SetUpGameEntry:: ; 56E8 + ld a, $04 + ld [wd65e], a + ld a, $F2 + ldh [hMapEntryMethod], a + ld hl, wDebugFlags + bit CONTINUED_F, [hl] ; if we loaded a game + ret nz + ld a, $F1 + ldh [hMapEntryMethod], a + ld a, $00 + ld [wDefaultSpawnPoint], a + ld hl, GameStartPlacement + ld de, wMapGroup + ld bc, wd65e - wMapGroup + call CopyBytes + ret + +GameStartPlacement:: ; 570D + db $01 ; map group + db MAP_PLAYER_HOUSE_2F ; map + dwcoord 15, 45 ; screen anchor + db $04 ; metatile x + db $04 ; metatile y + db $00 ; in-metatile x + db $01 ; in-metatile y + +DebugSetUpPlayer:: ; 5715 + call SetPlayerNamesDebug + ld a, $0F + ld [wd15d], a + ld a, $42 + ld [wd15e], a + ld a, $3F + ld [wd15f], a + ld a, $FF + ld [wd163], a + ld [wd164], a + call GiveRandomJohto + ld a, $03 + call AddRandomPokemonToBox + call FillTMs + ld de, DebugBagItems + call FillBagWithList + ld hl, wPokedexOwned + call DebugFillPokedex + ld hl, wPokedexSeen + call DebugFillPokedex + ld hl, wAnnonDex + ld [hl], $01 + call Function40fd + ret + +DebugFillPokedex:: ; 5755 + ld b, $1F + ld a, $FF +.loop + ld [hl+], a + dec b + jr nz, .loop + ld [hl], $07 + ret + +FillBagWithList:: ; 5760 + ld hl, wNumBagItems +.loop + ld a, [de] + cp $FF + jr z, .yump + ld [wCurItem], a + inc de + ld a, [de] + inc de + ld [wItemQuantity], a + call ReceiveItem + jr .loop +.yump + ret + +DebugBagItems:: ; 5777 + db ITEM_IMPORTANT_BAG, $01 + db ITEM_BAG, $01 + db ITEM_TM_HOLDER, $01 + db ITEM_BALL_HOLDER, $01 + db ITEM_BICYCLE, $01 + db ITEM_MAIL, $06 + db ITEM_ULTRA_BALL, $1E + db ITEM_POKE_BALL, $63 + db ITEM_POTION, $1E + db ITEM_RARE_CANDY, $14 + db ITEM_MOON_STONE, $63 + db ITEM_FULL_HEAL, $63 + db ITEM_PROTEIN, $63 + db ITEM_QUICK_NEEDLE, $63 + db ITEM_SNAKESKIN, $63 + db ITEM_KINGS_ROCK, $63 + db ITEM_FLEE_FEATHER, $63 + db ITEM_FOCUS_ORB, $63 + db ITEM_SHARP_SCYTHE, $63 + db ITEM_DETECT_ORB, $63 + db $FF + +GiveRandomPokemon:: ; 57A0 + and a + ret z +.loop + push af + call RandomUnder246 + ld b, $0A + call GivePokemon + pop af + dec a + jr nz, .loop + ret + +GiveRandomJohto:: ; 57B0 +.loop + call Random + and $03 + jr z, .loop + dec a + ld b, a + add a, a + add a, b + add a, $98 ; maybe should be a constant - 152, aka the number of kanto pokes + ld b, $08 + call GivePokemon + ld a, $8D + ld [wPartyMon1 + 1], a + ret + +GiveKantoStarters:: ; 57C8 + ld a, $03 + ld b, $20 + call GivePokemon + ld a, $06 + ld b, $24 + call GivePokemon + ld a, $09 + ld b, $24 + call GivePokemon + ret + +GivePokemon:: ; 57DE + ld [wMonDexIndex], a + ld a, b + ld [wCurPartyLevel], a + ld a, $10 + call Predef + ret + +AddRandomPokemonToBox: ; 57EB + and a + ret z +.loop + push af + xor a + ld [wca44], a + call RandomUnder246 + ld [wcdd7], a + ld a, $05 + ld [wCurPartyLevel], a + callab AddPokemonToBox + ld a, [wcdd7] + ld [wMonDexIndex], a + callab Functiondd5c + pop af + dec a + jr nz, .loop + ret + +RandomUnder246:: ; 5818 +.loop + call Random + and a + jr z, .loop + cp $F6 + jr nc, .loop + ret + +FillTMs:: ; 5823 + ld b, $39 + ld a, $01 + ld hl, wTMsHMs +.loop + ld [hl+], a + dec b + jr nz, .loop + ret + +DebugGiveKeyItems:: ; 582F + ld hl, DebugKeyItemsList + ld de, wKeyItems + ld c, $FF +.loop + inc c + ld a, [hl+] + ld [de], a + inc de + cp $FF + jr nz, .loop + ld a, c + ld [wNumKeyItems], a + ret + +DebugKeyItemsList:: ; 5844 + db ITEM_TM_HOLDER + db ITEM_BALL_HOLDER + db ITEM_BAG + db ITEM_BICYCLE + db $FF + +DemoSetUpPlayer:: ; 5849 + ld hl, wPlayerName + ld de, DemoPlayerName + call CopyString + ld hl, wRivalName + ld de, DemoRivalName + call CopyString + call Function40fd + ld de, DemoItemList + call FillBagWithList + call GiveRandomJohto + ret + +DemoItemList:: ; 5868 + db ITEM_POKE_BALL, $05 + db ITEM_POTION, $0A + db ITEM_FULL_HEAL, $0A + db ITEM_STIMULUS_ORB, $01 + db ITEM_FOCUS_ORB, $01 + db $FF + +DemoPlayerName:: ; 5873 + db "サトシ@" + +DemoRivalName:: ; 5877 + db "シゲル@" + +OakSpeechDemo:: ; 587B + text "ようこそ" + line "ポケット モンスターの せかいへ!" + cont "ごぞんじ わしが オーキドじゃ!" + + para "きょう きみに きてもらったのは" + line "ほかでもない" + cont "あたらしい ずかんづくりを" + cont "てつだって ほしいのじゃ!" + + para "もちろん" + line "きみの パートナーとなる ポケモンと" + cont "りュックは ようい しておる" + + para "りュックの なかには" + line "キズぐすりと" + cont "モンスターボールが" + cont "はいっておるから あんしんじゃ!" + + para "すでに きみの ライバルは" + line "しゅっぱつ しとる" + + para "まけないよう がんばって くれい!" + prompt + +OakSpeech1:: ; 5956 + text "いやあ またせた!" + + para "ポケット モンスターの せかいへ" + line "ようこそ!" + + para "わたしの なまえは オーキド" + + para "みんなからは # はかせと" + line "したわれて おるよ" + prompt + +OakSpeech2:: ; 599F + text "きみも もちろん" + line "しっているとは おもうが" + + para "この せかいには" + line "ポケット モンスターと よばれる" + cont "いきもの たちが" + cont "いたるところに すんでいる!" + prompt + +OakSpeech3:: ; 59E8 + text "その # という いきものを" + line "ひとは ぺットに したり" + cont "しょうぶに つかったり" + cont "そして・・・" + + para "わたしは この #の" + line "けんきゅうを してる というわけだ" + prompt + +OakSpeech4:: ; 5A35 + text "では はじめに きみの なまえを" + line "おしえて もらおう!" + prompt + +OakSpeech5:: ; 5A52 + text "そして この しょうねんは" + line "きみの おさななじみであり" + cont"ライバルである" + + para "・・・えーと?" + line "なまえは なんて いったかな?" + prompt + +OakSpeech6:: ; 5A8F + text "さて きみの きねんすべき" + line "たびだちのひを" + cont "きろくしておこう!" + + para "じかんも なるべく せいかくにな!" + prompt + +OakSpeech7:: ; 5AC2 + text "<PLAYER>!" + + para "いよいよ これから" + line "きみの ものがたりの はじまりだ!" + + para "ゆめと ぼうけんと!" + line "ポケット モンスターの せかいへ!" + + para "レッツ ゴー!" + done + +SetPlayerNamesDebug:: ; 5B07 + ld hl, DebugPlayerName + ld de, wPlayerName + call CopyNameDebug + ld hl, DebugRivalName + ld de, wRivalName + +CopyNameDebug: + ld bc, PLAYER_NAME_LENGTH + call CopyBytes + ret + +DebugPlayerName: ; 5B1D + db "コージ@" + +DebugRivalName: ; 5B21 + db "レッド@" + +ChoosePlayerName:: ; 5B25 + call PanPortraitRight + ld hl, PlayerNameMenuHeader + call NamingWindow + ld a, [wMenuCursorY] + dec a + jr z, .loop + ld de, wPlayerName + call SaveCustomName + jr .farjump + +.loop + ld b, $01 + ld de, wPlayerName + callba Function113f4 + ld a, [wPlayerName] + cp "@" + jr z, .loop + + call RotateThreePalettesRight + call ClearTileMap + call LoadFontExtra + call WaitBGMap + ld de, $4D10 + ld bc, $1200 + call IntroDisplayPicCenteredOrUpperRight + call RotateThreePalettesLeft +.farjump + ld hl, ChoosePlayerNameEndText + call PrintText + ret + +ChoosePlayerNameEndText: ; 5B6F + text "ふむ・・・" + line "<PLAYER> と いうんだな!" + prompt + +PlayerNameMenuHeader: ; 5B81 + db MENU_BACKUP_TILES ; flags + menu_coords 00, 00, 10, 11 + dw PlayerNameMenuData + db 01 ; initial selection + +PlayerNameMenuData; 5B89 + db STATICMENU_CURSOR | STATICMENU_PLACE_TITLE | STATICMENU_DISABLE_B + db 04 ; items + db "じぶんできめる@" + db "ゴールド@" + db "サトシ@" + db "ジャック@" + db 3 ; x offset for the title string + db "なまえこうほ@" + +ChooseRivalName:: ; 5BA9 + call PanPortraitRight + ld hl, RivalNameMenuHeader + call NamingWindow + ld a, [wMenuCursorY] + dec a + jr z, .loop + ld de, wRivalName + call SaveCustomName + jr .farjump + +.loop + ld b, $02 + ld de, wRivalName + callba Function113f4 ; manual text entry box? + ld a, [wRivalName] + cp "@" + jr z, .loop + + call RotateThreePalettesRight + call ClearTileMap + call LoadFontExtra + call WaitBGMap + ld de, $4BD4 + ld bc, $1200 + call IntroDisplayPicCenteredOrUpperRight + call RotateThreePalettesLeft +.farjump + ld hl, ChooseRivalNameEndText + call PrintText + ret + +ChooseRivalNameEndText: ; 5BF3 + text "そうか そうだったな" + line "<RIVAL> という なまえだ" + prompt + +RivalNameMenuHeader: ; 5C0A + db MENU_BACKUP_TILES ; flags + menu_coords 00, 00, 10, 11 + dw RivalNameMenuData + db 01 ; initial selection + +RivalNameMenuData: ; 5C12 + db STATICMENU_CURSOR | STATICMENU_PLACE_TITLE | STATICMENU_DISABLE_B + db 04 ; items + db "じぶんできめる@" + db "シルバー@" + db "シゲル@" + db "ジョン@" + db 3 + db "なまえこうほ@" + +MomNamePrompt:: ; 5C31 + ld hl, MomNameMenuHeader + call NamingWindow + ld a, [wMenuCursorY] + dec a + jr z, .loop + ld de, wMomsName + call SaveCustomName + jr .escape + +.loop + ld b, $03 + ld de, wMomsName + callba Function113f4 + ld a, [wMomsName] + cp "@" + jr z, .loop + + call ClearPalettes + call ClearTileMap + callab Function140d9 + call LoadFontExtra + call GetMemSGBLayout + call WaitBGMap +.escape + ret + +MomNameMenuHeader: ; 5C71 + db MENU_BACKUP_TILES ; flags + menu_coords 00, 00, 10, 11 + dw .MomNameMenuData + db 01 ; initial selection + +.MomNameMenuData: ; 5C79 + db STATICMENU_CURSOR | STATICMENU_PLACE_TITLE | STATICMENU_DISABLE_B + db 04 ; items + db "じぶんで きめる@" + db "おかあさん@" + db "ママ@" + db "かあちゃん@" + db 3 + db "なまえこうほ@" + +NamingWindow:: ; 5C9B + ; loads the menu header put into hl + call LoadMenuHeader + call VerticalMenu + ld a, [wMenuCursorY] + dec a + call CopyNameFromMenu + call CloseWindow + ret + +SaveCustomName:: ; 5CAC + ld hl, wStringBuffer2 + ld bc, PLAYER_NAME_LENGTH + call CopyBytes + ret + +PanPortraitRight:: ; 5CB6 + hlcoord 5, 4 + ld d, $06 + ld e, $7E + ld b, d + ld c, e + ld d, $00 + add hl, de +.loop + xor a + ldh [hBGMapMode], a + push hl + push bc +.innerLoop + ;pans all the tiles onscreen to the right one + ld a, [hl+] + ld [hl-], a + dec hl + dec c + jr nz, .innerLoop + + call WaitBGMap + pop bc + pop hl + inc hl + dec b ; passed c - how many tiles right to pan? + jr nz, .loop + ret + +PanPortraitLeft:: ; 5CD7 + hlcoord 12, 4 + ld b, $06 + ld c, $7E +.loop + xor a + ldh [hBGMapMode], a + push hl + push bc +.innerloop + ld a, [hl-] + ld [hl+], a + inc hl + dec c + jr nz, .innerloop + + call WaitBGMap + pop bc + pop hl + inc hl + dec b + jr nz, .loop + ret + +MenuCallSettings:: ; 5CF3 + call SettingsScreen + ret + +FadeInIntroPic: ; 5CF7 + ld hl, IntroFadePalettes + ld b, 6 +.next + ld a, [hl+] + ldh [rBGP], a + ld c, 10 + call DelayFrames + dec b + jr nz, .next + ret + +IntroFadePalettes: + db %01010100 + db %10101000 + db %11111100 + db %11111000 + db %11110100 + db %11100100 + +MovePicLeft: ; 5D0E + ld a, 119 + ldh [hWX], a + call DelayFrame + + ld a, %11100100 + ldh [rBGP], a +.next + call DelayFrame + ldh a, [hWX] + sub 8 + cp $FF + ret z + ldh [hWX], a + jr .next + +IntroDisplayPicCenteredOrUpperRight:: ; 5D27 +; b = bank +; de = address of compressed pic +; c: 0 = centred, non-zero = upper-right + ld a, c + and a + hlcoord 13, 4 + jr nz, .skip + hlcoord 6, 4 +.skip + push hl + ld a, b + call UncompressSpriteFromDE + ld a, $00 + call OpenSRAM + ld hl, sSpriteBuffer1 + ld de, sSpriteBuffer0 + ld bc, DOUBLESPRITEBUFFERSIZE + call CopyBytes + call CloseSRAM + ld de, VRAM_Begin + $1000 + call InterlaceMergeSpriteBuffers + pop hl + xor a + ldh [hGraphicStartTile], a + ld bc, $0707 + predef PlaceGraphic + ret + +LoadStartingSprites: ; 5D5D + ld de, GoldSpriteGFX + lb bc, BANK(GoldSpriteGFX), $0C + ld hl, VRAM_Begin + call Request2bpp + ld hl, wVirtualOAM + ld de, GameStartSprites + ld c, $04 +.loop + ld a, [de] + inc de + ld [hl+], a + ld a, [de] + inc de + ld [hl+], a + ld a, [de] + inc de + ld [hl+], a + xor a + ld [hl+], a + dec c + jr nz, .loop + ret + +GameStartSprites: ; 5D80 + db $50, $48, $00 + db $50, $50, $01 + db $58, $48, $02 + db $58, $50, $03 + +; 5D8C
\ No newline at end of file diff --git a/engine/events/field_moves.asm b/engine/events/field_moves.asm index 4f688fe..bee72f9 100755 --- a/engine/events/field_moves.asm +++ b/engine/events/field_moves.asm @@ -1,3 +1,4 @@ +<<<<<<< HEAD INCLUDE "constants.asm" ; TODO - need to constantize tile ids, movements @@ -539,3 +540,546 @@ Text_ReturnToLastMonCenter: ; 03:5395 text "さいごに たちよった" line "#センターにもどります" done +======= +INCLUDE "constants.asm" + +; TODO - need to constantize tile ids, movements + +SECTION "Field Moves", ROMX[$4fab], BANK[$03] + +CutFunction: ; 03:4fab + call .ResetScriptID +.next + call .ExecScript + jr nc, .next + ld [wFieldMoveSucceeded], a + ret +.ResetScriptID + xor a + ld [wFieldMoveScriptID], a + ret +.ExecScript + ld a, [wFieldMoveScriptID] + ld hl, .CutScriptTable + jp CallJumptable + +.CutScriptTable ; 03:4fc5 + init_script_table + add_script TryCut + add_script CheckCuttableBlock + add_script CheckCuttableTile + add_script DoCut + add_script DoCut2 + add_script FailCut + +TryCut: ; 03:4fd1 + call GetMapEnvironment + cp ROUTE + jr z, .success + cp TOWN + jr z, .success + set_script FailCut + xor a + ret +.success + set_script CheckCuttableBlock + xor a + ret + +CheckCuttableBlock: ; 03:4fea + call GetFacingTileCoord + cp $80 + jr nz, .fail + call GetBlockLocation + ld a, l + ld [wMapBlocksAddress], a + ld a, h + ld [wMapBlocksAddress + 1], a + ld a, [hl] + call GetCutReplacementBlock + jr nc, .fail + dec hl + ld a, [hl] + ld [wReplacementBlock], a + set_script DoCut2 + xor a + ret +.fail + set_script CheckCuttableTile + xor a + ret + +GetCutReplacementBlock: ; 03:5015 + ld c, a + ld hl, CutReplacementBlocks +.loop + ld a, [hli] + cp -1 + ret z + inc hl + cp c + jr nz, .loop + scf + ret + +CutReplacementBlocks: ; 03:5023 +; replacement block, facing block + db $30, $25 + db $31, $2A + db $32, $34 + db $33, $35 + db -1 + +CheckCuttableTile: ; 03:502c + call GetFacingTileCoord + call IsCuttableTile + jr nc, .fail + call GetBlockLocation + ld a, [hl] + cp $3b + jr nz, .fail + ld a, l + ld [wMapBlocksAddress], a + ld a, h + ld [wMapBlocksAddress + 1], a + ld a, $04 + ld [wReplacementBlock], a + set_script DoCut + xor a + ret +.fail + set_script FailCut + xor a + ret + +IsCuttableTile: ; 03:5057 + ld hl, CuttableTiles + ld c, a +.loop + ld a, [hli] + cp -1 + ret z + cp c + jr nz, .loop + scf + ret + +CuttableTiles: ; 03:5064 + db $81 + db $82 + db $8A + db $8B + db -1 + +FailCut: ; 03:5069 + ld hl, Text_CantUseCutHere + call MenuTextBoxBackup + scf + ld a, SCRIPT_FAIL + ret + +Text_CantUseCutHere: ; 03:5073 + text "ここでは つかえません" + prompt + +DoCut: +DoCut2: ; 03:5080 + far_queue CutScript + scf + ld a, SCRIPT_SUCCESS + ret + +CutScript: ; 03:508C + call RefreshScreen + ld hl, wPartyMonNicknames + ld a, BOXMON + ld [wMonType], a + ld a, [wWhichPokemon] + call GetNick + call CopyStringToStringBuffer2 + ld hl, Text_CutItDown + call MenuTextBoxBackup + ld de, MUSIC_SURF + call PlaySFX + ld hl, wMapBlocksAddress + ld a, [hli] + ld h, [hl] + ld l, a + ld a, [wReplacementBlock] + ld [hl], a + call LoadMapPart + call UpdateSprites + call WaitBGMap + call Function1fea + scf + ret + +Text_CutItDown ; 03:50c4 + text_from_ram wStringBuffer2 + text " は " + line "くさかりを つかった!" + prompt + +SurfFunction: ; 03:50d8 + call .ResetScriptID +.next + call .ExecScript + jr nc, .next + ld [wFieldMoveSucceeded], a + ret +.ResetScriptID + xor a + ld [wFieldMoveScriptID], a + ret +.ExecScript + ld a, [wFieldMoveScriptID] + ld hl, .SurfScriptTable + jp CallJumptable + +.SurfScriptTable: ; 03:50f2 + init_script_table + add_script TrySurf + add_script DoSurf + add_script FailSurf + +TrySurf: ; 03:50f8 + call GetFacingTileCoord + and $f0 + cp $20 + jr z, .success + cp $40 + jr z, .success + set_script FailSurf + xor a + ret +.success + set_script DoSurf + xor a + ret + +DoSurf: ; 03:5113 + queue_ba SurfScript + ld a, -1 + ld [wFieldMoveScriptID], a + scf + ld a, SCRIPT_SUCCESS + ret + +FailSurf: ; 03:5124 + ld hl, Text_CantSurfHere + call MenuTextBoxBackup + ld a, -1 + ld [wFieldMoveScriptID], a + scf + ld a, SCRIPT_FAIL + ret + +Text_CantSurfHere: ; 03:5133 + text "ここでは のることが" + next "できません" + prompt + +SurfScript: ; 03:5145 + call RefreshScreen + ld hl, wPartyMonNicknames + ld a, BOXMON + ld [wMonType], a + ld a, [wWhichPokemon] + call GetNick + call CopyStringToStringBuffer2 + ld hl, Text_UsedSurf + call MenuTextBoxBackup + ld a, PLAYER_SURF + ld [wPlayerState], a + call RedrawPlayerSprite + call PlayMapMusic + call MovePlayerIntoWater + call Function1fea + ret + +Text_UsedSurf: ; 03:5171 + text_from_ram wStringBuffer2 + text " は " + line "@" + text_from_ram wPlayerName + text "を のせた!" + prompt + +MovePlayerIntoWater: ; 03:5185 + call InitMovementBuffer + call .get_movement_direction + call AppendToMovementBuffer + ld a, $32 + call AppendToMovementBuffer + ld a, 0 + ld hl, wMovementBuffer + call LoadMovementDataPointer +.get_movement_direction + ld a, [wPlayerWalking] + srl a + srl a + ld e, a + ld d, $00 + ld hl, SurfMovementDirections + add hl, de + ld a, [hl] + ret + +; Direction to move player, mapped to facing direction +SurfMovementDirections: ; 03:51ab + db 4, 5, 6, 7 + + +FlyFunction: ; 03:51af + call .ResetScriptID +.next + call .ExecScript + jr nc, .next + ld [wFieldMoveSucceeded], a + ret +.ResetScriptID + xor a + ld [wFieldMoveScriptID], a + ret +.ExecScript + ld a, [wFieldMoveScriptID] + ld hl, .FlyScriptTable + jp CallJumptable + +.FlyScriptTable: ; 03:51c9 + init_script_table + add_script TryFly + add_script ShowFlyMap + add_script DoFly + add_script FailFly + +TryFly: ; 03:51d1 + call GetMapEnvironment + cp TOWN + jr z, .success + cp ROUTE + jr z, .success + set_script FailFly + xor a + ret +.success + set_script ShowFlyMap + xor a + ret + +ShowFlyMap: ; 03:51ea + call LoadStandardMenuHeader + call ClearSprites + callab FlyMap + call ClearPalettes + call GetMemSGBLayout + call ExitMenu + ld a, [wFlyDestination] + cp -1 + jr z, .dont_fly + cp NUM_SPAWNS + jr nc, .dont_fly + set_script DoFly + xor a + ret +.dont_fly + call UpdateTimePals + ld a, -1 + ld [wFieldMoveScriptID], a + scf + ld a, SCRIPT_FAIL + ret + +DoFly: ; 03:521f + ld a, [wFlyDestination] + inc a + ld [wDefaultSpawnPoint], a + queue_ba FlyScript + ld a, -1 + ld [wFieldMoveScriptID], a + scf + ld a, SCRIPT_SUCCESS + ret + +FailFly: ; 03:5237 + ld hl, Text_CantUseFlyHere + call MenuTextBoxBackup + ld a, -1 + ld [wFieldMoveScriptID], a + scf + ld a, SCRIPT_FAIL + ret + +Text_CantUseFlyHere: ; 03:5246 + text "ここでは つかえません!" + prompt + +FlyScript: ; 03:5254 + ld a, MAPSETUP_TELEPORT + ldh [hMapEntryMethod], a + jpab Functionfcc24 + + +DigFunction: ; 03:5260 + call .ResetScriptID +.next + ld a, [wFieldMoveScriptID] + bit SCRIPT_FINISHED_F, a + jr nz, .finish + ld hl, .DigScriptTable + call CallJumptable + jr .next + +; Finish by returning only the low nibble +.finish + and $FF - SCRIPT_FINISHED_MASK + ld [wFieldMoveSucceeded], a + ret + +.ResetScriptID + xor a + ld [wFieldMoveScriptID], a + ret + +.DigScriptTable: ; 03:527D + init_script_table + add_script CheckCanDig + add_script DoDig + add_script FailDig + +CheckCanDig: ; 03:5283 + call GetMapEnvironment + cp INDOOR + jr z, .success + cp CAVE + jr z, .success + set_script FailDig + ret +.success + set_script DoDig + ret + +DoDig: ; 03:529a + queue_ab DigScript + ld a, SCRIPT_FINISHED_MASK | SCRIPT_SUCCESS + ld [wFieldMoveScriptID], a + ret + +FailDig: ; 03:52a8 + ld hl, Text_CantUseDigHere + call MenuTextBoxBackup + ld a, SCRIPT_FINISHED_MASK | SCRIPT_FAIL + ld [wFieldMoveScriptID], a + ret + +Text_CantUseDigHere: ; 03:52b4 + text "ここでは つかえません!" + prompt + +DigScript: ; 03:52c2 + ld hl, wDigWarpNumber + ld de, wNextWarp + ld bc, 3 + call CopyBytes + ld a, MAPSETUP_WARP + ldh [hMapEntryMethod], a + jpab Functionfcc24 + +EmptyFunctiond2da: ; 03:52da + ret + +TeleportFunction: ; 03:52db + xor a + ld [wFieldMoveScriptID], a +.next + ld a, [wFieldMoveScriptID] + bit SCRIPT_FINISHED_F, a + jr nz, .finish + ld hl, .TeleportScriptTable + call CallJumptable + jr .next + +; Finish by returning only the low nibble +.finish + and $FF - SCRIPT_FINISHED_MASK + ld [wFieldMoveSucceeded], a + ret + +.TeleportScriptTable + init_script_table + add_script TryTeleport + add_script DoTeleport + add_script FailTeleport + add_script CheckIfSpawnPoint + +TryTeleport: ; 03:52fc + call GetMapEnvironment + cp TOWN + jr z, .success + cp ROUTE + jr z, .success + set_script FailTeleport + ret +.success + set_script CheckIfSpawnPoint + ret + +CheckIfSpawnPoint ; 03:5313 + ld a, [wLastSpawnMapGroup] + ld d, a + ld a, [wLastSpawnMapNumber] + ld e, a + callab IsSpawnPoint + jr c, .not_spawn + ld hl, Text_CantFindDestination + call MenuTextBoxBackup + ld a, SCRIPT_FINISHED_MASK | SCRIPT_FAIL + ld [wFieldMoveScriptID], a + ret +.not_spawn + ld a, c + ld [wDefaultSpawnPoint], a + set_script DoTeleport + ret + +Text_CantFindDestination: ; 03:533B + text "とびさきが みつかりません" + para "" + done + +DoTeleport: ; 03:534b + queue_ba TeleportScript + ld a, SCRIPT_FINISHED_MASK | SCRIPT_SUCCESS + ld [wFieldMoveScriptID], a + ret + +FailTeleport: ; 03:5359 + ld hl, Text_CantUseTeleportHere + call MenuTextBoxBackup + ld a, SCRIPT_FINISHED_MASK | SCRIPT_FAIL + ld [wFieldMoveScriptID], a + scf + ret + +Text_CantUseTeleportHere: ; 03:5366 + text "ここでは つかえません!" + para "" + done + +TeleportScript: ; 03:5375 + call RefreshScreen + ld hl, Text_ReturnToLastMonCenter + call MenuTextBox + ld c, 60 + call DelayFrames + call CloseWindow + call Function1fea + ld a, MAPSETUP_TELEPORT + ldh [hMapEntryMethod], a + jpab Functionfcc24 + +Text_ReturnToLastMonCenter: ; 03:5395 + text "さいごに たちよった" + line "#センターにもどります" + done +>>>>>>> 3fab27f221a8d5400d4b203809ff9b13355d55a3 diff --git a/engine/menu/debug_menu.asm b/engine/menu/debug_menu.asm new file mode 100644 index 0000000..be46a00 --- /dev/null +++ b/engine/menu/debug_menu.asm @@ -0,0 +1,109 @@ +INCLUDE "constants.asm" + +SECTION "Debug Menu", ROMX[$4031], BANK[$01] + +DebugMenu:: ; $4031 + call ClearTileMap + call ClearWindowData + call LoadFont + call LoadFontsBattleExtra + call ClearSprites + call GetMemSGBLayout + xor a + ld [wWhichIndexSet], a + ld hl, DebugMenuHeader + call LoadMenuHeader + call OpenMenu + call CloseWindow + jp c, TitleSequenceStart + ld a, $41 + ld [wce5f], a + ld a, [wMenuSelection] + ld hl, DebugJumpTable + jp CallJumptable + +DebugJumpTable:: ; 4064 + dw DebugMenuOptionFight + dw DebugMenuOptionField + dw Function094c ; sound test + dw DebugMenuOptionSubGames + dw DebugMenuOptionMonsterTest + dw DebugMenuOptionName + +DebugMenuHeader: ; 4070 + db MENU_BACKUP_TILES ; flags + menu_coords 05, 02, SCREEN_WIDTH - 7, SCREEN_HEIGHT - 1 + dw .MenuData + db 01 ; default option + +.MenuData: ; 4078 + db $A0 + db 0 ; items + dw DebugMenuItems + db $8A, $1F + dw .Strings + +.Strings + db "ファイト@" + db "フィールド@" + db "サウンド@" + db "サブゲーム@" + db "モンスター@" + db "なまえ@" + +DebugMenuItems: + db 06 + db 00 + db 01 + db 02 + db 03 + db 04 + db 05 + db -1 + +DebugMenuOptionField:: ; 40A8 + ld hl, wDebugFlags + set DEBUG_FIELD_F, [hl] ; set debug mode + jp StartNewGame + +DebugMenuOptionFight:: ; 40B0 + ld hl, wDebugFlags + set DEBUG_BATTLE_F, [hl] + ld a, $54 + call Predef + ld hl, wDebugFlags + res DEBUG_BATTLE_F, [hl] + ret + +DebugMenuOptionSubGames:: ; 40C0 + callab CallSubGameMenu + jp DebugMenu + +DebugMenuOptionMonsterTest:: ; 40CB + ld hl, wPokedexOwned + ld de, wPokedexSeen + ld b, $1F + ld a, $FF +.loop + ld [hl+], a + ld [de], a + inc de + dec b + jr nz, .loop + ld a, $03 + ld [hl], a + ld [de], a + callab MonsterTest + ld a, $e4 + ldh [rBGP], a + +Function40eb:: + jp DebugMenu + +DebugMenuOptionName:: ; 40EE + callab OpenPokegear + ld a, $e4 + ldh [rBGP], a + jp DebugMenu + +; 40FD
\ No newline at end of file diff --git a/engine/menu/main_menu.asm b/engine/menu/main_menu.asm index 27e8f1d..432570a 100644 --- a/engine/menu/main_menu.asm +++ b/engine/menu/main_menu.asm @@ -1,45 +1,45 @@ INCLUDE "constants.asm" -SECTION "Main Menu Definition", ROMX[$53cc], BANK[$01] +SECTION "Main Menu", ROMX[$53CC], BANK[$01] -MainMenu: - ld hl, wd4a9 +MainMenu:: ; 01:53CC + ld hl, wd4a9 res 0, [hl] call ClearTileMap call GetMemSGBLayout call LoadFontExtra call LoadFont call ClearWindowData - call $5388 - ld hl, $ce60 + call Function5388 + ld hl, wce60 bit 0, [hl] - jr nz, .skip1 - xor a ; new game - jr .next1 -.skip1 - ld a, 1 ; continue -.next1 - ld a, [$ffa3] - and $83 - cp $83 - jr nz, .skip2 - ld a, 3 ; play pokemon, set time - jr .next2 -.skip2 - ld a, 2 ; play pokemon -.next2 - ld [$cbf7],a + jr nz, .setMenuContinue + xor a + jr .skip +.setMenuContinue + ld a, M_CONTINUE +.skip + ldh a, [hJoyState] + and D_DOWN | B_BUTTON | A_BUTTON + cp D_DOWN | B_BUTTON | A_BUTTON + jr nz, .setMenuPlay + ld a, M_SET_TIME + jr .triggerMenu +.setMenuPlay + ld a, M_PLAY_GAME +.triggerMenu + ld [wWhichIndexSet], a ld hl, MainMenuHeader call LoadMenuHeader call OpenMenu call CloseWindow - jp c, $5dae + jp c, TitleSequenceStart ld hl, MainMenuJumptable - ld a, [$cbf5] + ld a, [wMenuSelection] jp CallJumptable -MainMenuHeader: - db $40 +MainMenuHeader: ; 01:5418 + db MENU_BACKUP_TILES menu_coords 0, 0, 13, 7 dw .MenuData db 1 ; default option @@ -59,17 +59,11 @@ MainMenuHeader: db "じかんセット@" MainMenuJumptable: ; 01:5457 - dw $547c - dw NewGame - dw $5cf3 - dw NewGame - dw $5473 - -CONTINUE EQU 0 -NEW_GAME EQU 1 -OPTION EQU 2 -PLAY_POKEMON EQU 3 -SET_TIME EQU 4 + dw MainMenuOptionContinue + dw StartNewGame + dw MenuCallSettings + dw StartNewGame + dw MainMenuOptionSetTime MainMenuItems: @@ -99,176 +93,119 @@ PlayPokemonSetTimeMenu: db SET_TIME db -1 -SECTION "Oak Speech", ROMX[$555c], BANK[$01] +MainMenuOptionSetTime:: ; 5473 + callab SetTime + ret + +MainMenuOptionContinue:: ;547C + callab Function14624 + call DisplayContinueGameInfo +.loop + call ClearJoypad + call GetJoypad + ldh a, [hJoyState] + bit A_BUTTON_F, a + jr nz, .escape + bit B_BUTTON_F, a + jp nz, MainMenu + jr .loop +.escape + call Function5397 + call Function53b0 + ld hl, wDebugFlags + res DEBUG_FIELD_F, [hl] + set CONTINUED_F, [hl] + set 3, [hl] + ldh a, [hJoyState] + bit SELECT_F, a + jr z, .skip + set 1, [hl] +.skip + call ClearBGPalettes + call ClearTileMap + ld c, $0A + call DelayFrames + jp OverworldStart + +DisplayContinueGameInfo:: ; 54BF + xor a + ldh [hBGMapMode], a + hlcoord 4, 7 + ld b, $08 + ld c, $0D + call DrawTextBox + hlcoord 5, 9 + ld de, PlayerInfoText + call PlaceString + hlcoord 13, 9 + ld de, wPlayerName + call PlaceString + hlcoord 14, 11 + call PrintNumBadges + hlcoord 13, 13 + call PrintNumOwnedMons + hlcoord 12, 15 + call PrintPlayTime + ld a, $01 + ldh [hBGMapMode], a + ld c, $1E + call DelayFrames + ret -NewGame: - ld de, 0 +PrintNumBadges:: ;54FA + push hl + ld hl, wd163 ; badges? + ld b, $01 + call CountSetBits + pop hl + ld de, wCountSetBitsResult + ld bc, $0102 ; flags and constants for this? 1 byte source, 2 digit display + jp PrintNumber + +PrintNumOwnedMons:: ; 550D + push hl + ld hl, wPokedexOwned + ld b, $20 ; flag_array NUM_POKEMON? + call CountSetBits + pop hl + ld de, wCountSetBitsResult + ld bc, $0103 ; 1 byte, 3 digit + jp PrintNumber + +PrintPlayTime:: ; 5520 + ld de, hRTCHours + ld bc, $0103 ; 1 byte, 3 digit + call PrintNumber + ld [hl], ":" + inc hl + ld de, hRTCMinutes + ld bc, $8102 ; PRINTNUM_LEADINGZEROS, 1 byte, 2 digit + jp PrintNumber + +PlayerInfoText: + db "しゅじんこう" + next "もっているバッジ こ" + next "#ずかん ひき" + next "プレイじかん" + text_end + +StartNewGame:: ; 555C + ld de, MUSIC_NONE call PlayMusic - ld de, 3 + ld de, MUSIC_OAK_INTRO call PlayMusic call LoadFontExtra xor a - ld [$ffde], a - ld a, 1 - ld hl, $52f9 - call FarCall_hl + ldh [hBGMapMode], a + callba Function52f9 call ClearTileMap call ClearWindowData xor a - ld [$ffe8], a - ld a, [wce63] - bit 1, a - jp z, .OakSpeechPlayPokemon - call Function5715 - jp .PlayerShrink - -.OakSpeechPlayPokemon - ld de, OakPic - lb bc, BANK(OakPic), 0 - call $5d27 - call $5cf7 - ld hl, $587b - call PrintText - call RotateThreePalettesRight - call ClearTileMap - ld de, ProtagonistPic - lb bc, BANK(ProtagonistPic), 0 - call $5d27 - call $5d0e - ld a, $d0 - ld [$ff48], a - call $5849 - jp .PlayerShrink - -.OakSpeechNewGame - ld de, OakPic - lb bc, BANK(OakPic), 0 - call $5d27 - call $5cf7 - ld hl, $5956 - call PrintText - call RotateThreePalettesRight - call ClearTileMap - ld a, DEX_YADOKING - ld [$cb5b], a - ld [$cd78], a - call GetMonHeader - ld hl, $c2f6 - ld hl, $c2f6 - call PrepMonFrontpic - call $5d0e - ld hl, $599f - call PrintText - ld a, DEX_YADOKING - call PlayCry - ld hl, $59e8 - call PrintText - call RotateThreePalettesRight - call ClearTileMap - ld de, ProtagonistPic - lb bc, BANK(ProtagonistPic), 0 - call $5d27 - call $5d0e - ld hl, $5a35 - call PrintText - call $5b25 ; naming screen - call RotateThreePalettesRight - call ClearTileMap - ld de, RivalPic - lb bc, BANK(RivalPic), 0 - call $5d27 - call $5cf7 - ld hl, $5a52 - call PrintText - call $5ba9 ; naming screen - call RotateThreePalettesRight - call ClearTileMap - ld de, OakPic - lb bc, BANK(OakPic), 0 - call $5d27 - call $5cf7 - ld hl, $5a8f - call PrintText - ld a, $24 - ld hl, $4000 - call FarCall_hl - call Function04ac - call RotateThreePalettesRight - call ClearTileMap - ld de, ProtagonistPic - lb bc, BANK(ProtagonistPic), 0 - call $5d27 - call RotateThreePalettesLeft - ld hl, $5ac2 - call PrintText - ld a, [$ff98] - push af - ld a, $20 - ld [$c1a5], a - ld de, 0 - ld a, e - ld [$c1a7], a - ld a, d - ld [$c1a8], a - ld de, $b - call PlaySFX - pop af - call Bankswitch - ld c, 4 - call DelayFrames -.PlayerShrink - ld de, $4743 - ld bc, $400 - call $5d27 - ld c, 4 - call DelayFrames - ld de, $479d - ld bc, $400 - call $5d27 - ld c, 20 - call DelayFrames - ld hl, $c30a - ld b, 7 - ld c, 7 - call ClearBox - ld c, 20 - call DelayFrames - call $5d5d - call LoadFontExtra - ld c, 50 - call DelayFrames - call RotateThreePalettesRight - call ClearTileMap - call Function0502 - ld a, 0 - ld [$d638], a - ld [$d637], a - call Function56e8 - ld hl, wce63 - bit 2, [hl] - call z, Function15b5 - ld hl, wd4a9 - set 0, [hl] - jp Function2a85 - -Function56e8: - ld a, 4 - ld [$d65e], a - ld a, $f2 - ld [$ff9a], a - ld hl, $ce63 - bit 2, [hl] - ret nz - ld a, $f1 - ld [$ff9a], a - ld a, 0 - ld [$cc39], a - ld hl, .Data - ld de, $d656 - ld bc, 8 - call CopyBytes - ret -.Data - db $01, $09, $33, $c6, $04, $04, $00, $01 - -Function5715: + ldh [hMapAnims], a + ld a, [wDebugFlags] + bit DEBUG_FIELD_F, a + jp z, DemoStart + call DebugSetUpPlayer + jp IntroCleanup + +; 558D diff --git a/engine/overworld/object_collision.asm b/engine/overworld/object_collision.asm new file mode 100644 index 0000000..8d42a93 --- /dev/null +++ b/engine/overworld/object_collision.asm @@ -0,0 +1,157 @@ +INCLUDE "constants.asm" + +SECTION "GetSpritesNextTile", ROMX[$774a], BANK[$01] + +; Get the tile that the sprite will walk onto next +GetSpritesNextTile: ; 01:774a + ld hl, OBJECT_NEXT_MAP_X + add hl, bc + ld d, [hl] + ld hl, OBJECT_NEXT_MAP_Y + add hl, bc + ld e, [hl] + push bc + call GetCoordTile + pop bc + ret + +; Sets carry flag if the object (bc) next tile is a collision +_IsObjectCollisionTileSolid: ; 01:775a + call GetSpritesNextTile + ld e, a + ld d, 0 + ld hl, CollisionTypeTable + add hl, de + ld a, BANK(CollisionTypeTable) + call GetFarByte + and ALWAYS_SOLID ; also covers SOMETIMES_SOLID + ret z + scf + ret + + + +SECTION "_CheckObjectCollision", ROMX[$77dd], BANK[$01] + +; returns the carry flag if a sprite is at coords d, e +; will not collide with sprite index stored in hEventCollisionException +_CheckObjectCollision: ; 01:77dd + ld bc, wObjectStructs + xor a +.loop + ldh [hObjectStructIndexBuffer], a + ld hl, OBJECT_SPRITE + add hl, bc + ld a, [hl] + and a + jr z, .next + ld hl, OBJECT_NEXT_MAP_X + add hl, bc + ld a, [hl] + cp d + jr nz, .check_last_position + ld hl, OBJECT_NEXT_MAP_Y + add hl, bc + ld a, [hl] + cp e + jr nz, .check_last_position + ldh a, [hEventCollisionException] + ld l, a + ldh a, [hObjectStructIndexBuffer] + cp l + jr nz, .collision +.check_last_position + ld hl, OBJECT_MAP_X + add hl, bc + ld a, [hl] + cp d + jr nz, .next + ld hl, OBJECT_MAP_Y + add hl, bc + ld a, [hl] + cp e + jr nz, .next + ldh a, [hEventCollisionException] + ld l, a + ldh a, [hObjectStructIndexBuffer] + cp l + jr nz, .collision +.next + ld hl, OBJECT_LENGTH + add hl, bc + ld b, h + ld c, l + ldh a, [hObjectStructIndexBuffer] + inc a + cp NUM_OBJECT_STRUCTS + jr nz, .loop + and a + ret + +.collision + scf + ret + +SECTION "_CheckPlayerObjectCollision", ROMX[$7894], BANK[$01] + +; Sets the carry flag if the player will collide with another sprite's current or next position +_CheckPlayerObjectCollision: ; 01:7894 + ld a, [wPlayerNextMapX] + ld d, a + ld a, [wPlayerNextMapY] + ld e, a + ld bc, wObjectStructs + xor a + +.loop + ldh [hObjectStructIndexBuffer], a + ld hl, OBJECT_SPRITE + add hl, bc + ld a, [hl] + and a + jr z, .next + ld hl, OBJECT_NEXT_MAP_Y + add hl, bc + ld a, [hl] + cp e + jr nz, .check_last_position + ld hl, OBJECT_NEXT_MAP_X + add hl, bc + ld a, [hl] + cp d + jr nz, .check_last_position + +; skip the player sprite + ldh a, [hObjectStructIndexBuffer] + cp PLAYER_OBJECT_INDEX + jr z, .next + jr .collision + +.check_last_position + ld hl, OBJECT_MAP_Y + add hl, bc + ld a, [hl] + cp e + jr nz, .next + ld hl, OBJECT_MAP_X + add hl, bc + ld a, [hl] + cp d + jr nz, .next + jr .collision + +.next + ld hl, OBJECT_LENGTH + add hl, bc + ld b, h + ld c, l + ldh a, [hObjectStructIndexBuffer] + inc a + cp NUM_OBJECT_STRUCTS + jr nz, .loop + xor a + ret + +.collision + scf + ret diff --git a/engine/overworld/player_movement.asm b/engine/overworld/player_movement.asm new file mode 100644 index 0000000..3c8cf7c --- /dev/null +++ b/engine/overworld/player_movement.asm @@ -0,0 +1,1162 @@ +INCLUDE "constants.asm" + +SECTION "Player Movement", ROMX[$4000], BANK[$03] + +OverworldMovementCheck:: ; 03:4000 + jp _OverworldMovementCheck + +UnusedOverworldMovementCheck:: ; 03:4003 + ld a, PLAYER_OBJECT_INDEX + ldh [hEventCollisionException], a + ld a, [wPlayerDirection] + and a + jr z, SetPlayerIdle ; player movement is disabled + ldh a, [hJoyState] + ld d, a + ld hl, wDebugFlags + bit DEBUG_FIELD_F, [hl] + jr z, .skip_debug_move + bit B_BUTTON_F, d + jp nz, CheckMovementDebug +.skip_debug_move + ld a, [wPlayerState] + cp PLAYER_SKATE + jp z, CheckMovementSkateboard + cp PLAYER_SURF + jp z, OldCheckMovementSurf + jp CheckMovementWalkOrBike + +SetPlayerIdle: ; 03:402c + ld a, NO_MOVEMENT + +SetPlayerMovement: ; 03:402e + ld [wPlayerMovement], a + ld a, [wPlayerLastMapX] + ld [wPlayerNextMapX], a + ld a, [wPlayerLastMapY] + ld [wPlayerNextMapY], a + and a + ret + +CheckMovementWalkOrBike: ; 03:403f + call _CheckMovementWalkOrBike + jp SetPlayerMovement + +_CheckMovementWalkOrBike: ; 03:4045 + ld a, d + and D_PAD + jp z, .idle + ld a, d + bit D_DOWN_F, a + jp nz, .check_down + bit D_UP_F, a + jp nz, .check_up + bit D_LEFT_F, a + jp nz, .check_left + bit D_RIGHT_F, a + jr nz, .check_right +.idle + ld a, NO_MOVEMENT + ret + +.check_right + ld a, [wPlayerLastMapX] + inc a + ld [wPlayerNextMapX], a + call CheckPlayerObjectCollision + jr c, .face_right + call IsPlayerCollisionTileSolid + jr nc, .move_right + jr .face_right +.move_right + ld a, [wPlayerState] + cp PLAYER_BIKE + ld a, FAST_STEP_RIGHT + ret z + ld a, STEP_RIGHT + ret +.face_right + ld a, FACE_RIGHT + ret + +.check_left: + ld a, [wPlayerLastMapX] + dec a + ld [wPlayerNextMapX], a + call CheckPlayerObjectCollision + jr c, .face_left + call IsPlayerCollisionTileSolid + jr nc, .move_left + jr .face_left +.move_left + ld a, [wPlayerState] + cp PLAYER_BIKE + ld a, FAST_STEP_LEFT + ret z + ld a, STEP_LEFT + ret +.face_left + ld a, FACE_LEFT + ret + +.check_down + ld a, [wPlayerLastMapY] + inc a + ld [wPlayerNextMapY], a + call CheckPlayerObjectCollision + jr c, .face_down + call IsPlayerCollisionTileSolid + jr nc, .move_down + cp OLD_COLLISION_LEDGE + jr nz, .face_down + ld a, JUMP_DOWN + ret +.move_down + ld a, [wPlayerState] + cp PLAYER_BIKE + ld a, FAST_STEP_DOWN + ret z + ld a, STEP_DOWN + ret +.face_down + ld a, FACE_DOWN + ret + +.check_up + ld a, [wPlayerLastMapY] + dec a + ld [wPlayerNextMapY], a + call CheckPlayerObjectCollision + jr c, .face_up + call IsPlayerCollisionTileSolid + jr nc, .move_up + jr .face_up +.move_up + ld a, [wPlayerState] + cp PLAYER_BIKE + ld a, FAST_STEP_UP + ret z + ld a, STEP_UP + ret +.face_up + ld a, FACE_UP + ret + +CheckMovementDebug:: ; 03:40eb + ld a, d + call _CheckMovementDebug + jp SetPlayerMovement + +_CheckMovementDebug: ; 03:40f2 + bit D_DOWN_F, a + jr nz, .move_down + bit D_UP_F, a + jr nz, .move_up + bit D_LEFT_F, a + jr nz, .move_left + bit D_RIGHT_F, a + jr nz, .move_right + ld a, NO_MOVEMENT + ret + +.move_down + ld a, [wTileDown] + cp -1 + ld a, FAST_STEP_DOWN + ret nz + ld a, JUMP_UP + ret + +.move_up + ld a, [wTileUp] + cp -1 + ld a, FAST_STEP_UP + ret nz + ld a, JUMP_DOWN + ret + +.move_left + ld a, [wTileLeft] + cp -1 + ld a, FAST_STEP_LEFT + ret nz + ld a, JUMP_RIGHT + ret + +.move_right + ld a, [wTileRight] + cp -1 + ld a, FAST_STEP_RIGHT + ret nz + ld a, JUMP_LEFT + ret + +CheckMovementSkateboard:: ; 03:4131 + call _CheckMovementSkateboard + jp SetPlayerMovement + +_CheckMovementSkateboard: ; 03:4137 + ld a, [wSkatingDirection] + cp STANDING + jp z, .not_moving + push de + ld e, a + ld d, $00 + ld hl, .SkateMovementTable + add hl, de + add hl, de + ld a, [hli] + ld h, [hl] + ld l, a + pop de + jp hl + +.SkateMovementTable ; 03:414d + dw CheckSkateDown + dw CheckSkateUp + dw CheckSkateLeft + dw CheckSkateRight + +.not_moving ; 03:4155 + ld a, d + and D_PAD + jp z, .idle + bit D_DOWN_F, d + jp nz, CheckSkateDown + bit D_UP_F, d + jp nz, CheckSkateUp + bit D_LEFT_F, d + jp nz, CheckSkateLeft + bit D_RIGHT_F, d + jp nz, CheckSkateRight + +.idle + ld a, STANDING + ld [wSkatingDirection], a + ld a, NO_MOVEMENT + ret + +CheckSkateDown: ; 03:4177 + ld a, [wPlayerLastMapY] + inc a + ld [wPlayerNextMapY], a + ld a, DOWN + ld [wSkatingDirection], a + call CheckPlayerObjectCollision + jr c, .collision + call IsPlayerCollisionTileSolid + jr nc, .can_skate + cp OLD_COLLISION_LEDGE + jr z, .jump + cp (OLD_COLLISION_ROCK | COLLISION_FLAG) + jr nz, .collision + +.jump + ld a, FAST_JUMP_DOWN + ret + +.can_skate + call OldIsTileCollisionGrass + jr z, .slow + ld a, FAST_STEP_DOWN + ret + +.slow + ld a, STEP_DOWN + ret + +.collision + ld a, STANDING + ld [wSkatingDirection], a + ld a, FACE_DOWN + ret + +CheckSkateUp: ; 03:41ab + ld a, [wPlayerLastMapY] + dec a + ld [wPlayerNextMapY], a + ld a, UP + ld [wSkatingDirection], a + call CheckPlayerObjectCollision + jr c, .collision + call IsPlayerCollisionTileSolid + jr nc, .can_skate + cp (OLD_COLLISION_ROCK | COLLISION_FLAG) + jr nz, .collision + ld a, FAST_JUMP_UP + ret + +.can_skate + call OldIsTileCollisionGrass + jr z, .slow + ld a, FAST_STEP_UP + ret + +.slow + ld a, STEP_UP + ret + +.collision + ld a, STANDING + ld [wSkatingDirection], a + ld a, FACE_UP + ret + +CheckSkateLeft: ; 03:41db + ld a, [wPlayerLastMapX] + dec a + ld [wPlayerNextMapX], a + ld a, LEFT + ld [wSkatingDirection], a + call CheckPlayerObjectCollision + jr c, .collision + call IsPlayerCollisionTileSolid + jr nc, .can_skate + cp (OLD_COLLISION_ROCK | COLLISION_FLAG) + jr nz, .collision + ld a, FAST_JUMP_LEFT + ret + +.can_skate + call OldIsTileCollisionGrass + jr z, .slow + ld a, FAST_STEP_LEFT + ret + +.slow + ld a, STEP_LEFT + ret + +.collision + ld a, STANDING + ld [wSkatingDirection], a + ld a, FACE_LEFT + ret + +CheckSkateRight: ; 03:420b + ld a, [wPlayerLastMapX] + inc a + ld [wPlayerNextMapX], a + ld a, RIGHT + ld [wSkatingDirection], a + call CheckPlayerObjectCollision + jr c, .collision + call IsPlayerCollisionTileSolid + jr nc, .can_skate + cp (OLD_COLLISION_ROCK | COLLISION_FLAG) + jr nz, .collision + ld a, FAST_JUMP_RIGHT + ret + +.can_skate + call OldIsTileCollisionGrass + jr z, .slow + ld a, FAST_STEP_RIGHT + ret + +.slow + ld a, STEP_RIGHT + ret + +.collision + ld a, STANDING + ld [wSkatingDirection], a + ld a, FACE_RIGHT + ret + +OldIsTileCollisionGrass:: ; 03:423b +; Check whether collision ID in a is +; grass +; Result: +; nz - not grass +; z - grass + cp $82 + ret z + cp $83 + ret z + cp $8a + ret z + cp $8b + ret + +OldCheckMovementSurf:: ; 03:4247 + call _OldCheckMovementSurf + jp SetPlayerMovement + +_OldCheckMovementSurf: ; 03:424d + ld a, d + and D_PAD + bit D_DOWN_F, a + jp nz, .check_down + bit D_UP_F, a + jp nz, .check_up + bit D_LEFT_F, a + jp nz, .check_left + bit D_RIGHT_F, a + jr nz, .check_right + ld a, NO_MOVEMENT + ret + +.check_down + ld a, [wPlayerLastMapY] + inc a + ld [wPlayerNextMapY], a + call CheckPlayerObjectCollision + jr c, .face_down + call IsPlayerCollisionTileSolid + jr nc, .exit_water_down ; FIXME: This assumes cut-trees are solid, which they aren't. + ; You can walk into them from water because of this. + call OldIsTileCollisionWater + jr c, .face_down + ld a, STEP_DOWN + ret +.face_down + ld a, FACE_DOWN + ret +.exit_water_down + call SetPlayerStateWalk + ld a, SLOW_STEP_DOWN + ret + +.check_up + ld a, [wPlayerLastMapY] + dec a + ld [wPlayerNextMapY], a + call CheckPlayerObjectCollision + jr c, .face_up + call IsPlayerCollisionTileSolid + jr nc, .exit_water_up ; FIXME: This assumes cut-trees are solid, which they aren't. + ; You can walk into them from water because of this. + call OldIsTileCollisionWater + jr c, .face_up + ld a, STEP_UP + ret +.face_up + ld a, FACE_UP + ret +.exit_water_up + call SetPlayerStateWalk + ld a, SLOW_STEP_UP + ret + +.check_left + ld a, [wPlayerLastMapX] + dec a + ld [wPlayerNextMapX], a + call CheckPlayerObjectCollision + jr c, .face_left + call IsPlayerCollisionTileSolid + jr nc, .exit_water_left ; FIXME: This assumes cut-trees are solid, which they aren't. + ; You can walk into them from water because of this. + call OldIsTileCollisionWater + jr c, .face_left + ld a, STEP_LEFT + ret +.face_left + ld a, FACE_LEFT + ret +.exit_water_left + call SetPlayerStateWalk + ld a, SLOW_STEP_LEFT + ret + +.check_right + ld a, [wPlayerLastMapX] + inc a + ld [wPlayerNextMapX], a + call CheckPlayerObjectCollision + jr c, .face_right + call IsPlayerCollisionTileSolid + jr nc, .exit_water_right ; FIXME: This assumes cut-trees are solid, which they aren't. + ; You can walk into them from water because of this. + call OldIsTileCollisionWater + jr c, .face_right + ld a, STEP_RIGHT + ret +.face_right + ld a, FACE_RIGHT + ret +.exit_water_right + call SetPlayerStateWalk + ld a, SLOW_STEP_RIGHT + ret + +OldIsTileCollisionWater:: ; 03:42ee +; Check if collision ID in a is water +; Input: +; a - collision ID +; Result: +; c - water +; nc - not water + and COLLISION_TYPE_MASK + cp OLD_COLLISION_TYPE_WATER + ret z + cp OLD_COLLISION_TYPE_WATER2 + ret z + scf + ret + +SetPlayerStateWalk:: ; 03:42f8 + push bc + ld a, PLAYER_NORMAL + ld [wPlayerState], a + call RedrawPlayerSprite + pop bc + ret + +IsPlayerCollisionTileSolid:: ; 03:4303 +; Return whether the collision under player's feet +; is solid/sometimes solid or non-solid. +; Clobbers: a +; Results: +; a - collision ID under player's feet +; nc - non-solid +; c - solid/sometimes solid + push de + ld bc, wPlayerStruct + callab _IsObjectCollisionTileSolid + ld a, e + pop de + ret + +CheckPlayerObjectCollision:: ; 03:4312 +; Check whether player object currentl +; collides with any other object. +; Result: +; nc - no collision +; c - collision + push de + callab _CheckPlayerObjectCollision + pop de + ret nc + jp CheckCompanionObjectCollision + +CheckCompanionObjectCollision:: ; 03:4320 +; Marks the object struct pointed to by hl +; as having collided with player object. +; If object struct (as identified by hObjectStructIndexBuffer) +; is companion, cancel collision on 5th frames. +; Result: +; nc - no collision +; c - collision + ld hl, OBJECT_FLAGS + 1 + add hl, bc + set 1, [hl] ; mark object as having collided with player + ldh a, [hObjectStructIndexBuffer] + cp COMPANION_OBJECT_INDEX + jr z, .is_companion + xor a + ld [wCompanionCollisionFrameCounter], a + scf + ret +.is_companion + ld a, [wCompanionCollisionFrameCounter] + inc a + cp 5 + ld [wCompanionCollisionFrameCounter], a + jr z, .cancel_collision + scf + ret +.cancel_collision + xor a + ld [wCompanionCollisionFrameCounter], a + ret + +_OverworldMovementCheck:: ; 03:4344 + ld a, PLAYER_OBJECT_INDEX + ldh [hEventCollisionException], a + ld a, [wPlayerDirection] + and a + jp z, SetPlayerIdle + ldh a, [hJoyState] + ld d, a + ld hl, wDebugFlags + bit DEBUG_FIELD_F, [hl] + jr z, .skip_debug_move + bit B_BUTTON_F, d + jp nz, CheckMovementDebug + +.skip_debug_move + call GetPlayerMovementByState + jp SetPlayerMovement + +GetPlayerMovementByState: ; 03:4364 + ld a, [wPlayerState] + cp PLAYER_SKATE + jp z, CheckMovementSkateboard ; FIXME: CheckMovementSkateboard already calls SetPlayerMovement + ; The skateboard doesn't work, because it uses the current + ; coordinate as player animation. + cp PLAYER_SURF + jp z, CheckMovementSurf + jp CheckMovementWalk + +CheckMovementWalk:: ; 03:4374 + ld a, [wPlayerStandingTile] + swap a + and LOW((COLLISION_TYPE_MASK >> 4) | (COLLISION_TYPE_MASK << 4)) + ld hl, .WalkingCollisionTable + jp CallJumptable + +.WalkingCollisionTable ; 03:4381 + dw CheckMovementWalkRegular ; regular + dw CheckMovementWalkSolid ; trees, grass, etc. + dw CheckMovementWalkSolid ; water + dw CheckMovementWalkSolid ; water current + dw CheckMovementWalkLand ; slowdown and fixed movement + dw CheckMovementWalkLand2 ; fixed movement + dw CheckMovementWalkRegular ; ??? + dw CheckMovementWalkWarp ; warps + dw CheckMovementWalkMisc ; ??? + dw CheckMovementWalkSpecial ; counters, signposts, book cases + dw CheckMovementWalkJump ; jumps + dw CheckMovementWalkRegular ; unused -- movement prohibit not yet implemented + dw CheckMovementWalkRegular ; unused + dw CheckMovementWalkRegular ; unused + dw CheckMovementWalkRegular ; unused + dw CheckMovementWalkRegular ; unused + +NoWalkMovement: ; 03:43a1 + ld a, NO_MOVEMENT + ret + +CheckMovementWalkSolid:: ; 03:43a4 + jp CheckMovementWalkRegular + +CheckMovementWalkLand:: ; 03:43a7 + ld a, [wPlayerStandingTile] + and COLLISION_SUBTYPE_MASK + jr nz, .force_movement + call CheckMovementWalkRegular + call SlowDownMovementWalk + ret + +.force_movement + ld b, STEP_DOWN + cp (COLLISION_LAND_S & COLLISION_SUBTYPE_MASK) + jr z, .finish + ld b, STEP_UP + cp (COLLISION_LAND_N & COLLISION_SUBTYPE_MASK) + jr z, .finish + ld b, STEP_LEFT + cp (COLLISION_LAND_W & COLLISION_SUBTYPE_MASK) + jr z, .finish + ld b, STEP_RIGHT + cp (COLLISION_LAND_E & COLLISION_SUBTYPE_MASK) + jr z, .finish + ; fall-through --> map other codes to COLLISION_LAND_E +.finish + ld a, b + ret + +SlowDownMovementWalk: ; 03:43cf + ld b, SLOW_STEP_DOWN + cp STEP_DOWN + jr z, .finish + ld b, SLOW_STEP_UP + cp STEP_UP + jr z, .finish + ld b, SLOW_STEP_LEFT + cp STEP_LEFT + jr z, .finish + ld b, SLOW_STEP_RIGHT + cp STEP_RIGHT + jr z, .finish + ret +.finish + ld a, b + ret + +CheckMovementWalkLand2:: ; 03:43ea + ld a, [wPlayerStandingTile] + and COLLISION_SUBTYPE_MASK + ld b, STEP_DOWN + cp (COLLISION_LAND2_S & COLLISION_SUBTYPE_MASK) + jr z, .finish + ld b, STEP_UP + cp (COLLISION_LAND2_N & COLLISION_SUBTYPE_MASK) + jr z, .finish + ld b, STEP_LEFT + cp (COLLISION_LAND2_W & COLLISION_SUBTYPE_MASK) + jr z, .finish + ld b, STEP_RIGHT + cp (COLLISION_LAND2_E & COLLISION_SUBTYPE_MASK) + jr z, .finish + ; fall-through --> map other codes to COLLISION_LAND2_E +.finish + ld a, b + ret + +UnusedCheckMovementWalk60:: ; 03:4409 + jp CheckMovementWalkRegular + +CheckMovementWalkWarp:: ; 03:440c + ld a, [wPlayerStandingTile] + and COLLISION_SUBTYPE_MASK + jr z, .check_dpad + cp 1 + jr z, .move_down + ld a, [wPlayerStandingTile] + cp $7a + jr z, .move_down + jp CheckMovementWalkRegular +.move_down + ld a, STEP_DOWN + ret + +.check_dpad + ldh a, [hJoyState] + bit D_DOWN_F, a + jr nz, .down + bit D_UP_F, a + jr nz, .up + bit D_LEFT_F, a + jr nz, .left + bit D_RIGHT_F, a + jr nz, .right + jp NoWalkMovement + +.down + ld a, [wTileDown] + cp -1 + jp nz, CheckMovementWalkRegular + call z, .moved_out_of_bounds + ld a, FACE_DOWN + ret +.up + ld a, [wTileUp] + cp -1 + jp nz, CheckMovementWalkRegular + call z, .moved_out_of_bounds + ld a, FACE_UP + ret +.left + ld a, [wTileLeft] + cp -1 + jp nz, CheckMovementWalkRegular + call z, .moved_out_of_bounds + ld a, FACE_LEFT + ret +.right + ld a, [wTileRight] + cp -1 + jp nz, CheckMovementWalkRegular + call z, .moved_out_of_bounds + ld a, FACE_RIGHT + ret + +.moved_out_of_bounds + ret + +CheckMovementWalkMisc:: ; 03:4472 + jp CheckMovementWalkRegular + +CheckMovementWalkSpecial:: ; 03:4475 + jp CheckMovementWalkRegular + +CheckMovementWalkRegular:: ; 03:4478 + ldh a, [hJoyState] + bit D_DOWN_F, a + jp nz, CheckWalkDown + bit D_UP_F, a + jp nz, CheckWalkUp + bit D_LEFT_F, a + jp nz, CheckWalkLeft + bit D_RIGHT_F, a + jp nz, CheckWalkRight + jp NoWalkMovement + +CheckMovementWalkJump: ; 03:4491 + ldh a, [hJoyState] + bit D_DOWN_F, a + jr nz, .down + bit D_UP_F, a + jr nz, .up + bit D_LEFT_F, a + jr nz, .left + bit D_RIGHT_F, a + jr nz, .right + jp NoWalkMovement + +.down + ld a, [wPlayerStandingTile] + and COLLISION_SUBTYPE_MASK + cp (COLLISION_JUMP_S & COLLISION_SUBTYPE_MASK) + jr z, .jump_down + cp (COLLISION_JUMP_SE & COLLISION_SUBTYPE_MASK) + jr z, .jump_down + cp (COLLISION_JUMP_SW & COLLISION_SUBTYPE_MASK) + jr z, .jump_down + jp CheckWalkDown +.jump_down + ld a, JUMP_DOWN + ret + +.up + ld a, [wPlayerStandingTile] + and COLLISION_SUBTYPE_MASK + cp (COLLISION_JUMP_N & COLLISION_SUBTYPE_MASK) + jr z, .jump_up + cp (COLLISION_JUMP_NE & COLLISION_SUBTYPE_MASK) + jr z, .jump_up + cp (COLLISION_JUMP_NW & COLLISION_SUBTYPE_MASK) + jr z, .jump_up + jp CheckWalkUp +.jump_up + ld a, JUMP_UP + ret + +.left + ld a, [wPlayerStandingTile] + and COLLISION_SUBTYPE_MASK + cp (COLLISION_JUMP_W & COLLISION_SUBTYPE_MASK) + jr z, .jump_left + cp (COLLISION_JUMP_SW & COLLISION_SUBTYPE_MASK) + jr z, .jump_left + cp (COLLISION_JUMP_NW & COLLISION_SUBTYPE_MASK) + jr z, .jump_left + jp CheckWalkLeft +.jump_left + ld a, JUMP_LEFT + ret + +.right + ld a, [wPlayerStandingTile] + and COLLISION_SUBTYPE_MASK + cp (COLLISION_JUMP_E & COLLISION_SUBTYPE_MASK) + jr z, .jump_right + cp (COLLISION_JUMP_SE & COLLISION_SUBTYPE_MASK) + jr z, .jump_right + cp (COLLISION_JUMP_NE & COLLISION_SUBTYPE_MASK) + jr z, .jump_right + jp CheckWalkRight +.jump_right + ld a, JUMP_RIGHT + ret + +CheckWalkDown:: ; 03:4502 + ld d, 0 + ld e, 1 + call CheckObjectCollision + jr c, .face_down + ld a, [wTileDown] + call CheckCollisionSolid + jr c, .face_down + ld a, STEP_DOWN + ret +.face_down + ld a, FACE_DOWN + ret + +CheckWalkUp:: ; 03:4519 + ld d, 0 + ld e, -1 + call CheckObjectCollision + jr c, .face_up + ld a, [wTileUp] + call CheckCollisionSolid + jr c, .face_up + ld a, STEP_UP + ret +.face_up + ld a, FACE_UP + ret + +CheckWalkLeft:: ; 03:4530 + ld d, -1 + ld e, 0 + call CheckObjectCollision + jr c, .face_left + ld a, [wTileLeft] + call CheckCollisionSolid + jr c, .face_left + ld a, STEP_LEFT + ret +.face_left + ld a, FACE_LEFT + ret + +CheckWalkRight:: ; 03:4547 + ld d, 1 + ld e, 0 + call CheckObjectCollision + jr c, .face_right + ld a, [wTileRight] + call CheckCollisionSolid + jr c, .face_right + ld a, STEP_RIGHT + ret +.face_right + ld a, FACE_RIGHT + ret + +CheckMovementSurf:: ; 03:455e + ld a, [wPlayerStandingTile] + swap a + and LOW((COLLISION_TYPE_MASK >> 4) | (COLLISION_TYPE_MASK << 4)) + ld hl, .SurfCollisionTable + jp CallJumptable + +.SurfCollisionTable ; 03:456b + dw CheckMovementSurfRegular + dw CheckMovementSurfRegular + dw CheckMovementSurfWater + dw CheckMovementSurfWater2 + dw CheckMovementSurfRegular + dw CheckMovementSurfRegular + dw CheckMovementSurfRegular + dw CheckMovementSurfRegular + dw CheckMovementSurfRegular + dw CheckMovementSurfRegular + dw CheckMovementSurfRegular + dw CheckMovementSurfRegular + dw CheckMovementSurfRegular + dw CheckMovementSurfRegular + dw CheckMovementSurfRegular + dw CheckMovementSurfRegular + +CheckMovementSurfRegular:: ; 03:458b + ldh a, [hJoyState] + bit D_DOWN_F, a + jp nz, CheckSurfDown + bit D_UP_F, a + jp nz, CheckSurfUp + bit D_LEFT_F, a + jp nz, CheckSurfLeft + bit D_RIGHT_F, a + jp nz, CheckSurfRight + jp NoWalkMovement + +CheckMovementSurfWater:: ; 03:45a4 + ld a, [wPlayerStandingTile] + and COLLISION_SUBTYPE_MASK + cp (COLLISION_WATERFALL & COLLISION_SUBTYPE_MASK) + jr nz, CheckMovementSurfRegular +; waterfall + ld a, FAST_STEP_DOWN + ret + +CheckMovementSurfWater2:: ; 03:45b0 + ld a, [wPlayerStandingTile] + and COLLISION_WATER_SUBTYPE_MASK + ld d, STEP_RIGHT + jr z, .finish ; COLLISION_WATER2_E + ld d, STEP_LEFT + cp (COLLISION_WATER2_W & COLLISION_WATER_SUBTYPE_MASK) + jr z, .finish + ld d, STEP_UP + cp (COLLISION_WATER2_N & COLLISION_WATER_SUBTYPE_MASK) + jr z, .finish + ld d, STEP_DOWN + cp (COLLISION_WATER2_S & COLLISION_WATER_SUBTYPE_MASK) + jr z, .finish + ; fall-through --> no aliasing due to mask +.finish + ld a, d + ret + +CheckSurfDown: ; 03:45cd + ld d, 0 + ld e, 1 + call CheckObjectCollision + jr c, .face_down + ld a, [wTileDown] + call CheckCollisionSometimesSolid + jr c, .face_down ; FIXME: This assumes cut-trees are solid, which they aren't. + ; You can walk into them from water because of this. + call nz, SurfDismount + ld a, STEP_DOWN + ret +.face_down + ld a, FACE_DOWN + ret + +CheckSurfUp: ; 03:45e7 + ld d, 0 + ld e, -1 + call CheckObjectCollision + jr c, .face_up + ld a, [wTileUp] + call CheckCollisionSometimesSolid + jr c, .face_up ; FIXME: This assumes cut-trees are solid, which they aren't. + ; You can walk into them from water because of this. + call nz, SurfDismount + ld a, STEP_UP + ret +.face_up + ld a, FACE_UP + ret + +CheckSurfLeft: ; 03:4601 + ld d, -1 + ld e, 0 + call CheckObjectCollision + jr c, .face_left + ld a, [wTileLeft] + call CheckCollisionSometimesSolid + jr c, .face_left ; FIXME: This assumes cut-trees are solid, which they aren't. + ; You can walk into them from water because of this. + call nz, SurfDismount + ld a, STEP_LEFT + ret +.face_left + ld a, FACE_LEFT + ret + +CheckSurfRight: ; 03:461b + ld d, 1 + ld e, 0 + call CheckObjectCollision + jr c, .face_right + ld a, [wTileRight] + call CheckCollisionSometimesSolid + jr c, .face_right ; FIXME: This assumes cut-trees are solid, which they aren't. + ; You can walk into them from water because of this. + call nz, SurfDismount + ld a, STEP_RIGHT + ret +.face_right + ld a, FACE_RIGHT + ret + +SurfDismount: ; 03:4635 + jp SetPlayerStateWalk + +CheckObjectCollision:: ; 03:4638 +; Check if coordinates relative +; to player collide with another object +; Clobbers: +; a, hl +; Input: +; de - Relative coords x, y +; Output: +; nc - no collision +; c - collision +; hObjectStructIndexBuffer - Event ID of colliding event + ld a, PLAYER_OBJECT_INDEX + ldh [hEventCollisionException], a + ld a, [wPlayerNextMapX] + add d + ld d, a + ld a, [wPlayerNextMapY] + add e + ld e, a + callab _CheckObjectCollision + ret nc + jp CheckCompanionObjectCollision + +CheckCollisionSolid:: +; Checks whether collision ID in a +; is solid or not. +; Clobbers: +; hl +; Input: +; a - collision ID +; Result: +; a - collision type +; c - solid +; nc - not solid + call GetCollisionType + and a + ret z + scf + ret + +GetCollisionType:: +; Get collision type for collision ID in a +; Clobbers: hl +; Input: +; a - collision ID +; Result: +; a - collision type +; 00 - not solid +; 01 - sometimes solid (cut tree, water etc.) +; 0F - always solid + push de + ld hl, CollisionTypeTable + ld e, a + ld d, 0 + add hl, de + ld a, [hl] + pop de + ret + +SECTION "Rest of Player Movement", ROMX[$4764], BANK[$03] + +_UnusedReturnFalse:: ; 03:4764 + xor a + ret + +_UnusedReturnTrue:: ; 03:4766 + xor a + scf + ret + +CheckCollisionSometimesSolid:: ; 03:4769 +; Checks whether collision ID in a +; is sometimes, always or never solid. +; Clobbers: +; hl +; Input: +; a - collision ID +; Result: +; c - always solid +; nc - sometimes not solid, check a +; a - result +; 00 - sometimes solid +; 01 - never solid + call GetCollisionType + cp SOMETIMES_SOLID + jr z, .sometimes_solid + and a + jr z, .never_solid + jr .always_solid +.sometimes_solid + xor a + ret +.never_solid + ld a, 1 + and a + ret +.always_solid + scf + ret + + +SECTION "_RedrawPlayerSprite", ROMX[$4000], BANK[$05] + +_RedrawPlayerSprite: ; 05:4000 + call GetPlayerSprite + ld hl, vChars0 + call LoadOverworldSprite + ret + +GetPlayerSprite: ; 05:400a + ld a, [wPlayerState] + ld hl, PlayerSpriteTable + ld c, a +.loop + ld a, [hli] + cp c + jr z, .match + inc hl + cp -1 + jr nz, .loop + xor a + ld [wPlayerState], a + ld a, SPRITE_GOLD + jr .skip +.match + ld a, [hl] +.skip + ld [wUsedSprites], a + ld [wPlayerSprite], a + ld [wPlayerObjectSprite], a + ret + +PlayerSpriteTable: ; 03:402d +; state, sprite + db PLAYER_NORMAL, SPRITE_GOLD + db PLAYER_BIKE, SPRITE_GOLD_BIKE + db PLAYER_SKATE, SPRITE_GOLD_SKATEBOARD + db PLAYER_SURF, SPRITE_LAPLACE + db -1 diff --git a/engine/palettes.asm b/engine/palettes.asm index d1f93c0..67ed9fe 100644 --- a/engine/palettes.asm +++ b/engine/palettes.asm @@ -1,6 +1,6 @@ INCLUDE "constants.asm" -SECTION "Overworld fade", ROMX[$433e],BANK[$23] +SECTION "Overworld fade", ROMX[$433e], BANK[$23] OverworldFadeIn:: ; 23:433e ld c, 0 @@ -18,7 +18,7 @@ OverworldFadeOut:: ; 23:4349 ; TODO: merge this -SECTION "Palette fading, part 2?", ROMX[$43d1],BANK[$23] +SECTION "Palette fading, part 2?", ROMX[$43d1], BANK[$23] ApplyPalettesAtHL:: ; 23:43d1 push hl diff --git a/engine/sprites/sprites.asm b/engine/sprites/sprites.asm new file mode 100644 index 0000000..a1dc401 --- /dev/null +++ b/engine/sprites/sprites.asm @@ -0,0 +1,155 @@ +INCLUDE "constants.asm" + +SECTION "LoadOverworldSprite", ROMX[$4150], BANK[$05] + +LoadOverworldSprite: ; 05:4150 + push af + call GetOverworldSpriteData + push bc + push hl + push de + ld a, [wcdaf] + bit 7, a + jr nz, .dont_copy + call Get2bpp +.dont_copy + pop de + ld hl, SPRITE_TILE_SIZE * 3 + add hl, de + ld d, h + ld e, l + pop hl + ld bc, vChars1 - vChars0 + add hl, bc + pop bc + pop af + call IsAnimatedSprite + ret c + ld a, [wcdaf] + bit 6, a + ret nz + call Get2bpp + ret + +; get the data for overworld sprite in a +; returns: gfx ptr in hl, length in c, bank in b +GetOverworldSpriteData: ; 05:417d + push hl + dec a + ld l, a + ld h, 0 + add hl, hl + add hl, hl + ld bc, OverworldSprites + add hl, bc + ld e, [hl] + inc hl + ld d, [hl] + inc hl + ld c, [hl] + swap c + inc hl + ld b, [hl] + pop hl + ret + +SECTION "OverworldSprites", ROMX[$423B], BANK[$05] + +overworld_sprite: MACRO +; pointer, length, bank + dw \1 + db \2 tiles, BANK(\1) +ENDM + +OverworldSprites:: + overworld_sprite GoldSpriteGFX, 12 + overworld_sprite GoldBikeSpriteGFX, 12 + overworld_sprite GoldSkateboardSpriteGFX, 12 + overworld_sprite SilverSpriteGFX, 12 + overworld_sprite OkidoSpriteGFX, 12 + overworld_sprite RedSpriteGFX, 12 + overworld_sprite BlueSpriteGFX, 12 + overworld_sprite MasakiSpriteGFX, 12 + overworld_sprite ElderSpriteGFX, 12 + overworld_sprite SakakiSpriteGFX, 12 + overworld_sprite GantetsuSpriteGFX, 12 + overworld_sprite MomSpriteGFX, 12 + overworld_sprite SilversMomSpriteGFX, 12 + overworld_sprite RedsMomSpriteGFX, 12 + overworld_sprite RedsMomSpriteGFX, 12 + overworld_sprite NanamiSpriteGFX, 12 + overworld_sprite EvilOkidoSpriteGFX, 12 + overworld_sprite KikukoSpriteGFX, 12 + overworld_sprite HayatoSpriteGFX, 12 + overworld_sprite TsukushiSpriteGFX, 12 + overworld_sprite TsukushiSpriteGFX, 12 + overworld_sprite EnokiSpriteGFX, 12 + overworld_sprite MikanSpriteGFX, 12 + overworld_sprite MikanSpriteGFX, 12 + overworld_sprite CooltrainerMSpriteGFX, 12 + overworld_sprite CooltrainerMSpriteGFX, 12 + overworld_sprite CooltrainerMSpriteGFX, 12 + overworld_sprite CooltrainerMSpriteGFX, 12 + overworld_sprite CooltrainerMSpriteGFX, 12 + overworld_sprite CooltrainerMSpriteGFX, 12 + overworld_sprite CooltrainerMSpriteGFX, 12 + overworld_sprite CooltrainerMSpriteGFX, 12 + overworld_sprite CooltrainerMSpriteGFX, 12 + overworld_sprite CooltrainerMSpriteGFX, 12 + overworld_sprite CooltrainerMSpriteGFX, 12 + overworld_sprite CooltrainerMSpriteGFX, 12 + overworld_sprite CooltrainerFSpriteGFX, 12 + overworld_sprite BugCatcherBoySpriteGFX, 12 + overworld_sprite TwinSpriteGFX, 12 + overworld_sprite YoungsterSpriteGFX, 12 + overworld_sprite LassSpriteGFX, 12 + overworld_sprite TeacherSpriteGFX, 12 + overworld_sprite GirlSpriteGFX, 12 + overworld_sprite SuperNerdSpriteGFX, 12 + overworld_sprite RockerSpriteGFX, 12 + overworld_sprite PokefanMSpriteGFX, 12 + overworld_sprite PokefanFSpriteGFX, 12 + overworld_sprite GrampsSpriteGFX, 12 + overworld_sprite GrannySpriteGFX, 12 + overworld_sprite SwimmerMSpriteGFX, 12 + overworld_sprite SwimmerFSpriteGFX, 12 + overworld_sprite RocketMSpriteGFX, 12 + overworld_sprite RocketMSpriteGFX, 12 + overworld_sprite RocketMSpriteGFX, 12 + overworld_sprite RocketFSpriteGFX, 12 + overworld_sprite NurseSpriteGFX, 12 + overworld_sprite LinkReceptionistSpriteGFX, 12 + overworld_sprite ClerkSpriteGFX, 12 + overworld_sprite FisherSpriteGFX, 12 + overworld_sprite FishingGuruSpriteGFX, 12 + overworld_sprite ScientistSpriteGFX, 12 + overworld_sprite MediumSpriteGFX, 12 + overworld_sprite SageSpriteGFX, 12 + overworld_sprite FrowningManSpriteGFX, 12 + overworld_sprite GentlemanSpriteGFX, 12 + overworld_sprite BlackbeltSpriteGFX, 12 + overworld_sprite ReceptionistSpriteGFX, 12 + overworld_sprite OfficerSpriteGFX, 12 + overworld_sprite CaptainSpriteGFX, 12 + overworld_sprite CaptainSpriteGFX, 12 + overworld_sprite CaptainSpriteGFX, 12 + overworld_sprite MohawkSpriteGFX, 12 + overworld_sprite GymGuySpriteGFX, 12 + overworld_sprite SailorSpriteGFX, 12 + overworld_sprite HelmetSpriteGFX, 12 + overworld_sprite BurglarSpriteGFX, 12 + overworld_sprite SidonSpriteGFX, 12 + overworld_sprite PippiSpriteGFX, 12 + overworld_sprite PoppoSpriteGFX, 12 + overworld_sprite LizardonSpriteGFX, 12 + overworld_sprite KabigonSpriteGFX, 4 + overworld_sprite PawouSpriteGFX, 12 + overworld_sprite NyorobonSpriteGFX, 12 + overworld_sprite LaplaceSpriteGFX, 12 + overworld_sprite PokeBallSpriteGFX, 4 + overworld_sprite PokedexSpriteGFX, 4 + overworld_sprite PaperSpriteGFX, 4 + overworld_sprite OldLinkReceptionistSpriteGFX, 4 + overworld_sprite OldLinkReceptionistSpriteGFX, 4 + overworld_sprite EggSpriteGFX, 4 + overworld_sprite BoulderSpriteGFX, 4 diff --git a/engine/title.asm b/engine/title.asm index 7f9d707..d7ae3a7 100644 --- a/engine/title.asm +++ b/engine/title.asm @@ -630,9 +630,9 @@ SetTitleGfxNext:: ret if DEBUG -SECTION "Title screen TEMPORARY", ROMX[$62A5],BANK[1] ; TODO: merge this with the main section above +SECTION "Title screen TEMPORARY", ROMX[$62A5], BANK[$01] ; TODO: merge this with the main section above else -SECTION "Title screen TEMPORARY", ROMX[$62A2],BANK[1] ; TODO: merge this with the main section above +SECTION "Title screen TEMPORARY", ROMX[$62A2], BANK[$01] ; TODO: merge this with the main section above endc |
