diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/coord_event_weather.c | 47 | ||||
-rw-r--r-- | src/fame_checker.c | 10 | ||||
-rw-r--r-- | src/main.c | 4 | ||||
-rw-r--r-- | src/menu2.c | 851 | ||||
-rw-r--r-- | src/mevent_8145654.c | 4 | ||||
-rw-r--r-- | src/oak_speech.c | 1891 | ||||
-rw-r--r-- | src/roamer.c | 240 | ||||
-rw-r--r-- | src/scanline_effect.c | 262 | ||||
-rw-r--r-- | src/scrcmd.c | 6 | ||||
-rw-r--r-- | src/sound.c | 18 | ||||
-rw-r--r-- | src/text.c | 10 | ||||
-rw-r--r-- | src/tm_case.c | 1537 | ||||
-rw-r--r-- | src/trainer_tower.c | 2 | ||||
-rw-r--r-- | src/vs_seeker.c | 2 | ||||
-rw-r--r-- | src/window.c | 2 |
15 files changed, 4865 insertions, 21 deletions
diff --git a/src/coord_event_weather.c b/src/coord_event_weather.c new file mode 100644 index 000000000..4dbdd574b --- /dev/null +++ b/src/coord_event_weather.c @@ -0,0 +1,47 @@ +#include "global.h" + +void nullsub_27(void) {} +void nullsub_28(void) {} +void nullsub_29(void) {} +void nullsub_30(void) {} +void nullsub_31(void) {} +void nullsub_32(void) {} +void nullsub_33(void) {} +void nullsub_34(void) {} +void nullsub_35(void) {} +void nullsub_36(void) {} +void nullsub_37(void) {} +void nullsub_38(void) {} +void nullsub_39(void) {} + +struct { + u8 weatherId; + void (*callback)(void); +} const gUnknown_83A72A8[] = { + {0x01, nullsub_27}, + {0x02, nullsub_28}, + {0x03, nullsub_29}, + {0x04, nullsub_30}, + {0x05, nullsub_31}, + {0x06, nullsub_32}, + {0x07, nullsub_33}, + {0x08, nullsub_34}, + {0x09, nullsub_35}, + {0x0a, nullsub_36}, + {0x0b, nullsub_37}, + {0x14, nullsub_38}, + {0x15, nullsub_39} +}; + +void trigger_activate_weather(u8 weatherId) +{ + u8 i; + for (i = 0; i < NELEMS(gUnknown_83A72A8); i++) + { + if (gUnknown_83A72A8[i].weatherId == weatherId) + { + gUnknown_83A72A8[i].callback(); + return; + } + } +} diff --git a/src/fame_checker.c b/src/fame_checker.c index bbbe02c58..c47e52f06 100644 --- a/src/fame_checker.c +++ b/src/fame_checker.c @@ -779,7 +779,7 @@ static void GetPickModeText(void) if (HasUnlockedAllFlavorTextsForCurrentPerson() == TRUE) offset = NUM_FAMECHECKER_PERSONS; StringExpandPlaceholders(gStringVar4, sFameCheckerNameAndQuotesPointers[sFameCheckerData->unlockedPersons[who] + offset]); - AddTextPrinterParametrized(FCWINDOWID_MSGBOX, 2, gStringVar4, sub_80F78A8(), NULL, 2, 1, 3); + AddTextPrinterParametrized(FCWINDOWID_MSGBOX, 2, gStringVar4, GetTextSpeedSetting(), NULL, 2, 1, 3); FC_PutWindowTilemapAndCopyWindowToVramMode3(FCWINDOWID_MSGBOX); } } @@ -790,7 +790,7 @@ static void PrintSelectedNameInBrightGreen(u8 taskId) u16 cursorPos = FameCheckerGetCursorY(); FillWindowPixelRect(FCWINDOWID_MSGBOX, 0x11, 0, 0, 0xd0, 0x20); StringExpandPlaceholders(gStringVar4, sFameCheckerFlavorTextPointers[sFameCheckerData->unlockedPersons[cursorPos] * 6 + data[1]]); - AddTextPrinterParametrized(FCWINDOWID_MSGBOX, 2, gStringVar4, sub_80F78A8(), NULL, 2, 1, 3); + AddTextPrinterParametrized(FCWINDOWID_MSGBOX, 2, gStringVar4, GetTextSpeedSetting(), NULL, 2, 1, 3); FC_PutWindowTilemapAndCopyWindowToVramMode3(FCWINDOWID_MSGBOX); } @@ -803,7 +803,7 @@ static void WipeMsgBoxAndTransfer(void) static void Setup_DrawMsgAndListBoxes(void) { sub_80F6E9C(); - sub_80F6EE4(FCWINDOWID_MSGBOX, TRUE); + DrawDialogueFrame(FCWINDOWID_MSGBOX, TRUE); FC_PutWindowTilemapAndCopyWindowToVramMode3(FCWINDOWID_MSGBOX); FC_PutWindowTilemapAndCopyWindowToVramMode3(FCWINDOWID_LIST); } @@ -853,7 +853,7 @@ static void Task_DestroyAssetsAndCloseFameChecker(u8 taskId) FreeQuestionMarkSpriteResources(); FreeListMenuSelectorArrowPairResources(); SetMainCallback2(sFameCheckerData->savedCallback); - sub_810713C(sFameCheckerData->listMenuTaskId, 0, 0); + DestroyListMenu(sFameCheckerData->listMenuTaskId, NULL, NULL); Free(sBg3TilemapBuffer); Free(sBg1TilemapBuffer); Free(sBg2TilemapBuffer); @@ -1009,7 +1009,7 @@ static void FCSetup_ClearVideoRegisters(void) static void FCSetup_ResetTasksAndSpriteResources(void) { - remove_some_task(); + ScanlineEffect_Stop(); ResetTasks(); ResetSpriteData(); dp13_810BB8C(); diff --git a/src/main.c b/src/main.c index 068cc8578..bfab49c49 100644 --- a/src/main.c +++ b/src/main.c @@ -29,7 +29,7 @@ extern void MapMusicMain(void); extern void EnableInterrupts(u16); extern void sub_800DD28(void); extern u16 SetFlashTimerIntr(u8 timerNum, void (**intrFunc)(void)); -extern void remove_some_task(void); +extern void ScanlineEffect_Stop(void); extern void sub_80F50F4(void); extern bool32 sub_80F5118(void); extern bool8 sub_813B870(void); @@ -441,7 +441,7 @@ void DoSoftReset(void) { REG_IME = 0; m4aSoundVSyncOff(); - remove_some_task(); + ScanlineEffect_Stop(); DmaStop(1); DmaStop(2); DmaStop(3); diff --git a/src/menu2.c b/src/menu2.c new file mode 100644 index 000000000..ec244b8f7 --- /dev/null +++ b/src/menu2.c @@ -0,0 +1,851 @@ +#include "global.h" +#include "text.h" +#include "gpu_regs.h" +#include "task.h" +#include "wild_encounter.h" +#include "string_util.h" +#include "constants/species.h" + +static void Task_SmoothBlendLayers(u8 taskId); + +static const u8 gUnknown_845FD54[][5] = { + [SPECIES_BULBASAUR - 1] = {0x16, 0x1b, 0x30, 0x16, 0x29}, + [SPECIES_IVYSAUR - 1] = {0x14, 0x1b, 0x30, 0x15, 0x2a}, + [SPECIES_VENUSAUR - 1] = {0x1b, 0x20, 0x20, 0x1b, 0x33}, + [SPECIES_CHARMANDER - 1] = {0x14, 0x0f, 0x38, 0x13, 0x1e}, + [SPECIES_CHARMELEON - 1] = {0x0d, 0x11, 0x30, 0x0f, 0x22}, + [SPECIES_CHARIZARD - 1] = {0x1b, 0x07, 0x28, 0x1a, 0x19}, + [SPECIES_SQUIRTLE - 1] = {0x19, 0x13, 0x30, 0x1a, 0x22}, + [SPECIES_WARTORTLE - 1] = {0x16, 0x13, 0x30, 0x17, 0x21}, + [SPECIES_BLASTOISE - 1] = {0x12, 0x08, 0x28, 0x15, 0x19}, + [SPECIES_CATERPIE - 1] = {0x15, 0x14, 0x30, 0x13, 0x24}, + [SPECIES_METAPOD - 1] = {0x13, 0x1d, 0x30, 0x18, 0x2a}, + [SPECIES_BUTTERFREE - 1] = {0x12, 0x1b, 0x08, 0x12, 0x2a}, + [SPECIES_WEEDLE - 1] = {0x16, 0x1c, 0x30, 0x15, 0x2b}, + [SPECIES_KAKUNA - 1] = {0x19, 0x13, 0x30, 0x1a, 0x24}, + [SPECIES_BEEDRILL - 1] = {0x19, 0x16, 0x08, 0x19, 0x25}, + [SPECIES_PIDGEY - 1] = {0x15, 0x12, 0x30, 0x12, 0x1e}, + [SPECIES_PIDGEOTTO - 1] = {0x24, 0x0e, 0x30, 0x1f, 0x1e}, + [SPECIES_PIDGEOT - 1] = {0x0c, 0x13, 0x08, 0x0a, 0x23}, + [SPECIES_RATTATA - 1] = {0x17, 0x1e, 0x30, 0x18, 0x2d}, + [SPECIES_RATICATE - 1] = {0x12, 0x14, 0x30, 0x10, 0x26}, + [SPECIES_SPEAROW - 1] = {0x15, 0x14, 0x30, 0x15, 0x1f}, + [SPECIES_FEAROW - 1] = {0x0c, 0x27, 0x00, 0x0b, 0x3f}, + [SPECIES_EKANS - 1] = {0x11, 0x0f, 0x30, 0x14, 0x1d}, + [SPECIES_ARBOK - 1] = {0x1b, 0x01, 0x28, 0x1d, 0x10}, + [SPECIES_PIKACHU - 1] = {0x19, 0x13, 0x30, 0x1a, 0x1f}, + [SPECIES_RAICHU - 1] = {0x19, 0x14, 0x28, 0x1c, 0x22}, + [SPECIES_SANDSHREW - 1] = {0x17, 0x16, 0x30, 0x18, 0x25}, + [SPECIES_SANDSLASH - 1] = {0x11, 0x13, 0x28, 0x13, 0x22}, + [SPECIES_NIDORAN_F - 1] = {0x16, 0x15, 0x30, 0x18, 0x21}, + [SPECIES_NIDORINA - 1] = {0x1f, 0x17, 0x30, 0x1e, 0x28}, + [SPECIES_NIDOQUEEN - 1] = {0x10, 0x0b, 0x28, 0x13, 0x1c}, + [SPECIES_NIDORAN_M - 1] = {0x15, 0x22, 0x28, 0x15, 0x31}, + [SPECIES_NIDORINO - 1] = {0x13, 0x1e, 0x28, 0x1b, 0x2d}, + [SPECIES_NIDOKING - 1] = {0x12, 0x15, 0x28, 0x13, 0x27}, + [SPECIES_CLEFAIRY - 1] = {0x19, 0x14, 0x30, 0x1b, 0x24}, + [SPECIES_CLEFABLE - 1] = {0x1c, 0x12, 0x30, 0x1d, 0x21}, + [SPECIES_VULPIX - 1] = {0x10, 0x16, 0x30, 0x0e, 0x25}, + [SPECIES_NINETALES - 1] = {0x28, 0x10, 0x28, 0x27, 0x1e}, + [SPECIES_JIGGLYPUFF - 1] = {0x1d, 0x15, 0x30, 0x1e, 0x25}, + [SPECIES_WIGGLYTUFF - 1] = {0x1a, 0x12, 0x30, 0x1c, 0x22}, + [SPECIES_ZUBAT - 1] = {0x14, 0x1d, 0x08, 0x14, 0x29}, + [SPECIES_GOLBAT - 1] = {0x23, 0x1a, 0x00, 0x21, 0x2e}, + [SPECIES_ODDISH - 1] = {0x1d, 0x20, 0x28, 0x1d, 0x2b}, + [SPECIES_GLOOM - 1] = {0x1c, 0x18, 0x28, 0x1c, 0x27}, + [SPECIES_VILEPLUME - 1] = {0x1c, 0x1e, 0x28, 0x1d, 0x2a}, + [SPECIES_PARAS - 1] = {0x1d, 0x1a, 0x30, 0x1c, 0x27}, + [SPECIES_PARASECT - 1] = {0x1e, 0x1c, 0x28, 0x20, 0x2e}, + [SPECIES_VENONAT - 1] = {0x1b, 0x16, 0x10, 0x1a, 0x29}, + [SPECIES_VENOMOTH - 1] = {0x12, 0x19, 0x08, 0x16, 0x27}, + [SPECIES_DIGLETT - 1] = {0x1e, 0x16, 0x30, 0x1c, 0x23}, + [SPECIES_DUGTRIO - 1] = {0x1a, 0x11, 0x30, 0x1a, 0x1f}, + [SPECIES_MEOWTH - 1] = {0x1c, 0x16, 0x30, 0x1c, 0x23}, + [SPECIES_PERSIAN - 1] = {0x13, 0x13, 0x30, 0x13, 0x21}, + [SPECIES_PSYDUCK - 1] = {0x1c, 0x13, 0x30, 0x17, 0x29}, + [SPECIES_GOLDUCK - 1] = {0x17, 0x12, 0x28, 0x17, 0x22}, + [SPECIES_MANKEY - 1] = {0x1c, 0x15, 0x30, 0x1b, 0x23}, + [SPECIES_PRIMEAPE - 1] = {0x1e, 0x16, 0x30, 0x1a, 0x27}, + [SPECIES_GROWLITHE - 1] = {0x14, 0x17, 0x30, 0x14, 0x24}, + [SPECIES_ARCANINE - 1] = {0x0f, 0x09, 0x28, 0x0c, 0x19}, + [SPECIES_POLIWAG - 1] = {0x15, 0x14, 0x30, 0x13, 0x1f}, + [SPECIES_POLIWHIRL - 1] = {0x1f, 0x10, 0x30, 0x1e, 0x17}, + [SPECIES_POLIWRATH - 1] = {0x22, 0x0c, 0x30, 0x21, 0x18}, + [SPECIES_ABRA - 1] = {0x1f, 0x13, 0x30, 0x1f, 0x21}, + [SPECIES_KADABRA - 1] = {0x1b, 0x12, 0x30, 0x1c, 0x25}, + [SPECIES_ALAKAZAM - 1] = {0x1c, 0x11, 0x28, 0x1d, 0x26}, + [SPECIES_MACHOP - 1] = {0x1b, 0x11, 0x30, 0x1b, 0x1e}, + [SPECIES_MACHOKE - 1] = {0x1d, 0x11, 0x30, 0x1d, 0x1f}, + [SPECIES_MACHAMP - 1] = {0x1a, 0x0d, 0x28, 0x1c, 0x1b}, + [SPECIES_BELLSPROUT - 1] = {0x15, 0x0e, 0x30, 0x0e, 0x1c}, + [SPECIES_WEEPINBELL - 1] = {0x1a, 0x1c, 0x10, 0x15, 0x32}, + [SPECIES_VICTREEBEL - 1] = {0x1e, 0x0f, 0x30, 0x1c, 0x1b}, + [SPECIES_TENTACOOL - 1] = {0x1a, 0x15, 0x30, 0x1e, 0x26}, + [SPECIES_TENTACRUEL - 1] = {0x1b, 0x10, 0x28, 0x1c, 0x26}, + [SPECIES_GEODUDE - 1] = {0x1c, 0x20, 0x28, 0x1d, 0x2d}, + [SPECIES_GRAVELER - 1] = {0x1d, 0x19, 0x28, 0x1e, 0x26}, + [SPECIES_GOLEM - 1] = {0x19, 0x1b, 0x28, 0x1c, 0x27}, + [SPECIES_PONYTA - 1] = {0x0f, 0x11, 0x30, 0x0e, 0x23}, + [SPECIES_RAPIDASH - 1] = {0x2f, 0x0f, 0x28, 0x2b, 0x1e}, + [SPECIES_SLOWPOKE - 1] = {0x14, 0x1f, 0x28, 0x15, 0x2f}, + [SPECIES_SLOWBRO - 1] = {0x0e, 0x0d, 0x28, 0x0c, 0x1f}, + [SPECIES_MAGNEMITE - 1] = {0x20, 0x1b, 0x10, 0x1f, 0x29}, + [SPECIES_MAGNETON - 1] = {0x1f, 0x14, 0x08, 0x1f, 0x22}, + [SPECIES_FARFETCHD - 1] = {0x16, 0x14, 0x30, 0x16, 0x29}, + [SPECIES_DODUO - 1] = {0x11, 0x16, 0x30, 0x0d, 0x2c}, + [SPECIES_DODRIO - 1] = {0x1d, 0x04, 0x28, 0x0e, 0x07}, + [SPECIES_SEEL - 1] = {0x1b, 0x24, 0x20, 0x17, 0x35}, + [SPECIES_DEWGONG - 1] = {0x12, 0x0a, 0x30, 0x0e, 0x1a}, + [SPECIES_GRIMER - 1] = {0x1f, 0x10, 0x30, 0x1d, 0x25}, + [SPECIES_MUK - 1] = {0x17, 0x0f, 0x30, 0x19, 0x22}, + [SPECIES_SHELLDER - 1] = {0x1a, 0x18, 0x30, 0x17, 0x29}, + [SPECIES_CLOYSTER - 1] = {0x19, 0x1e, 0x28, 0x1d, 0x2c}, + [SPECIES_GASTLY - 1] = {0x1a, 0x1f, 0x08, 0x19, 0x30}, + [SPECIES_HAUNTER - 1] = {0x20, 0x14, 0x08, 0x1d, 0x26}, + [SPECIES_GENGAR - 1] = {0x1a, 0x16, 0x30, 0x19, 0x28}, + [SPECIES_ONIX - 1] = {0x1f, 0x24, 0x20, 0x28, 0x36}, + [SPECIES_DROWZEE - 1] = {0x1a, 0x0e, 0x30, 0x1a, 0x1e}, + [SPECIES_HYPNO - 1] = {0x1c, 0x12, 0x30, 0x19, 0x24}, + [SPECIES_KRABBY - 1] = {0x1d, 0x1d, 0x30, 0x1a, 0x2b}, + [SPECIES_KINGLER - 1] = {0x1e, 0x1f, 0x28, 0x1c, 0x30}, + [SPECIES_VOLTORB - 1] = {0x1c, 0x1b, 0x30, 0x1b, 0x2b}, + [SPECIES_ELECTRODE - 1] = {0x1c, 0x18, 0x30, 0x1d, 0x2e}, + [SPECIES_EXEGGCUTE - 1] = {0x21, 0x17, 0x30, 0x20, 0x24}, + [SPECIES_EXEGGUTOR - 1] = {0x1c, 0x17, 0x28, 0x1b, 0x25}, + [SPECIES_CUBONE - 1] = {0x1b, 0x12, 0x30, 0x1b, 0x22}, + [SPECIES_MAROWAK - 1] = {0x14, 0x0f, 0x30, 0x11, 0x23}, + [SPECIES_HITMONLEE - 1] = {0x2e, 0x11, 0x30, 0x28, 0x22}, + [SPECIES_HITMONCHAN - 1] = {0x22, 0x0e, 0x30, 0x1e, 0x1d}, + [SPECIES_LICKITUNG - 1] = {0x14, 0x11, 0x30, 0x14, 0x24}, + [SPECIES_KOFFING - 1] = {0x1e, 0x14, 0x10, 0x1d, 0x20}, + [SPECIES_WEEZING - 1] = {0x11, 0x0d, 0x10, 0x0f, 0x1c}, + [SPECIES_RHYHORN - 1] = {0x0e, 0x23, 0x20, 0x14, 0x33}, + [SPECIES_RHYDON - 1] = {0x0d, 0x12, 0x28, 0x17, 0x22}, + [SPECIES_CHANSEY - 1] = {0x1a, 0x0d, 0x30, 0x1a, 0x1a}, + [SPECIES_TANGELA - 1] = {0x1c, 0x18, 0x30, 0x1d, 0x29}, + [SPECIES_KANGASKHAN - 1] = {0x1b, 0x06, 0x28, 0x1c, 0x14}, + [SPECIES_HORSEA - 1] = {0x1c, 0x14, 0x30, 0x16, 0x23}, + [SPECIES_SEADRA - 1] = {0x10, 0x17, 0x30, 0x09, 0x2a}, + [SPECIES_GOLDEEN - 1] = {0x16, 0x23, 0x20, 0x15, 0x34}, + [SPECIES_SEAKING - 1] = {0x16, 0x0f, 0x30, 0x10, 0x18}, + [SPECIES_STARYU - 1] = {0x1c, 0x18, 0x30, 0x1a, 0x26}, + [SPECIES_STARMIE - 1] = {0x1d, 0x13, 0x30, 0x1b, 0x20}, + [SPECIES_MR_MIME - 1] = {0x24, 0x11, 0x30, 0x25, 0x1e}, + [SPECIES_SCYTHER - 1] = {0x10, 0x19, 0x28, 0x12, 0x27}, + [SPECIES_JYNX - 1] = {0x1b, 0x0f, 0x30, 0x19, 0x1c}, + [SPECIES_ELECTABUZZ - 1] = {0x14, 0x11, 0x30, 0x17, 0x20}, + [SPECIES_MAGMAR - 1] = {0x10, 0x0e, 0x30, 0x0b, 0x19}, + [SPECIES_PINSIR - 1] = {0x1d, 0x1c, 0x28, 0x20, 0x2b}, + [SPECIES_TAUROS - 1] = {0x11, 0x1d, 0x28, 0x13, 0x2e}, + [SPECIES_MAGIKARP - 1] = {0x16, 0x15, 0x30, 0x13, 0x23}, + [SPECIES_GYARADOS - 1] = {0x0b, 0x18, 0x28, 0x16, 0x29}, + [SPECIES_LAPRAS - 1] = {0x16, 0x08, 0x28, 0x15, 0x16}, + [SPECIES_DITTO - 1] = {0x24, 0x12, 0x30, 0x1f, 0x20}, + [SPECIES_EEVEE - 1] = {0x16, 0x16, 0x30, 0x16, 0x23}, + [SPECIES_VAPOREON - 1] = {0x18, 0x23, 0x28, 0x18, 0x30}, + [SPECIES_JOLTEON - 1] = {0x14, 0x1b, 0x30, 0x16, 0x28}, + [SPECIES_FLAREON - 1] = {0x16, 0x17, 0x30, 0x14, 0x25}, + [SPECIES_PORYGON - 1] = {0x18, 0x12, 0x30, 0x10, 0x23}, + [SPECIES_OMANYTE - 1] = {0x1d, 0x1d, 0x30, 0x1c, 0x2b}, + [SPECIES_OMASTAR - 1] = {0x16, 0x1a, 0x30, 0x19, 0x2d}, + [SPECIES_KABUTO - 1] = {0x1b, 0x16, 0x30, 0x1a, 0x27}, + [SPECIES_KABUTOPS - 1] = {0x15, 0x11, 0x30, 0x15, 0x1f}, + [SPECIES_AERODACTYL - 1] = {0x13, 0x1d, 0x00, 0x14, 0x30}, + [SPECIES_SNORLAX - 1] = {0x35, 0x09, 0x30, 0x2e, 0x14}, + [SPECIES_ARTICUNO - 1] = {0x18, 0x0b, 0x18, 0x17, 0x17}, + [SPECIES_ZAPDOS - 1] = {0x0e, 0x0e, 0x10, 0x04, 0x28}, + [SPECIES_MOLTRES - 1] = {0x0b, 0x2a, 0x08, 0x0b, 0x38}, + [SPECIES_DRATINI - 1] = {0x0d, 0x12, 0x30, 0x0b, 0x21}, + [SPECIES_DRAGONAIR - 1] = {0x18, 0x0e, 0x30, 0x13, 0x1c}, + [SPECIES_DRAGONITE - 1] = {0x1b, 0x07, 0x18, 0x19, 0x17}, + [SPECIES_MEWTWO - 1] = {0x2b, 0x09, 0x28, 0x2c, 0x18}, + [SPECIES_MEW - 1] = {0x19, 0x14, 0x10, 0x1f, 0x21}, + [SPECIES_CHIKORITA - 1] = {0x1b, 0x17, 0x30, 0x1b, 0x24}, + [SPECIES_BAYLEEF - 1] = {0x1d, 0x10, 0x30, 0x20, 0x1d}, + [SPECIES_MEGANIUM - 1] = {0x05, 0x0d, 0x28, 0x0d, 0x1b}, + [SPECIES_CYNDAQUIL - 1] = {0x11, 0x1b, 0x30, 0x14, 0x27}, + [SPECIES_QUILAVA - 1] = {0x25, 0x18, 0x30, 0x27, 0x26}, + [SPECIES_TYPHLOSION - 1] = {0x09, 0x10, 0x28, 0x10, 0x1c}, + [SPECIES_TOTODILE - 1] = {0x16, 0x10, 0x30, 0x19, 0x20}, + [SPECIES_CROCONAW - 1] = {0x16, 0x10, 0x30, 0x18, 0x21}, + [SPECIES_FERALIGATR - 1] = {0x0e, 0x0a, 0x28, 0x08, 0x1a}, + [SPECIES_SENTRET - 1] = {0x1e, 0x0a, 0x30, 0x1d, 0x15}, + [SPECIES_FURRET - 1] = {0x21, 0x0e, 0x30, 0x21, 0x19}, + [SPECIES_HOOTHOOT - 1] = {0x1d, 0x15, 0x30, 0x1c, 0x24}, + [SPECIES_NOCTOWL - 1] = {0x19, 0x0e, 0x30, 0x18, 0x1c}, + [SPECIES_LEDYBA - 1] = {0x1b, 0x15, 0x30, 0x1c, 0x24}, + [SPECIES_LEDIAN - 1] = {0x18, 0x12, 0x10, 0x1c, 0x21}, + [SPECIES_SPINARAK - 1] = {0x20, 0x20, 0x28, 0x20, 0x2d}, + [SPECIES_ARIADOS - 1] = {0x17, 0x23, 0x28, 0x15, 0x30}, + [SPECIES_CROBAT - 1] = {0x22, 0x1e, 0x08, 0x23, 0x2b}, + [SPECIES_CHINCHOU - 1] = {0x1f, 0x1d, 0x30, 0x1f, 0x29}, + [SPECIES_LANTURN - 1] = {0x10, 0x23, 0x28, 0x19, 0x33}, + [SPECIES_PICHU - 1] = {0x1e, 0x17, 0x30, 0x1e, 0x24}, + [SPECIES_CLEFFA - 1] = {0x1c, 0x18, 0x30, 0x1e, 0x26}, + [SPECIES_IGGLYBUFF - 1] = {0x1f, 0x19, 0x30, 0x1f, 0x24}, + [SPECIES_TOGEPI - 1] = {0x21, 0x15, 0x30, 0x1f, 0x20}, + [SPECIES_TOGETIC - 1] = {0x1b, 0x10, 0x30, 0x1c, 0x1c}, + [SPECIES_NATU - 1] = {0x1c, 0x17, 0x30, 0x15, 0x21}, + [SPECIES_XATU - 1] = {0x1b, 0x08, 0x30, 0x19, 0x14}, + [SPECIES_MAREEP - 1] = {0x16, 0x15, 0x30, 0x15, 0x24}, + [SPECIES_FLAAFFY - 1] = {0x19, 0x12, 0x30, 0x18, 0x21}, + [SPECIES_AMPHAROS - 1] = {0x0f, 0x0a, 0x30, 0x10, 0x1b}, + [SPECIES_BELLOSSOM - 1] = {0x1f, 0x13, 0x30, 0x1f, 0x20}, + [SPECIES_MARILL - 1] = {0x1d, 0x15, 0x30, 0x1d, 0x22}, + [SPECIES_AZUMARILL - 1] = {0x1a, 0x12, 0x30, 0x17, 0x1f}, + [SPECIES_SUDOWOODO - 1] = {0x20, 0x10, 0x30, 0x20, 0x1f}, + [SPECIES_POLITOED - 1] = {0x1d, 0x0f, 0x30, 0x1e, 0x20}, + [SPECIES_HOPPIP - 1] = {0x23, 0x25, 0x08, 0x25, 0x33}, + [SPECIES_SKIPLOOM - 1] = {0x1e, 0x18, 0x08, 0x1c, 0x27}, + [SPECIES_JUMPLUFF - 1] = {0x1d, 0x21, 0x08, 0x20, 0x2f}, + [SPECIES_AIPOM - 1] = {0x1e, 0x29, 0x18, 0x1e, 0x35}, + [SPECIES_SUNKERN - 1] = {0x1f, 0x20, 0x08, 0x24, 0x2e}, + [SPECIES_SUNFLORA - 1] = {0x1c, 0x0c, 0x30, 0x1b, 0x19}, + [SPECIES_YANMA - 1] = {0x1b, 0x28, 0x08, 0x16, 0x35}, + [SPECIES_WOOPER - 1] = {0x1d, 0x13, 0x30, 0x1f, 0x21}, + [SPECIES_QUAGSIRE - 1] = {0x15, 0x09, 0x30, 0x12, 0x18}, + [SPECIES_ESPEON - 1] = {0x11, 0x1b, 0x30, 0x11, 0x29}, + [SPECIES_UMBREON - 1] = {0x23, 0x15, 0x30, 0x23, 0x22}, + [SPECIES_MURKROW - 1] = {0x24, 0x13, 0x30, 0x20, 0x22}, + [SPECIES_SLOWKING - 1] = {0x1e, 0x13, 0x28, 0x1d, 0x25}, + [SPECIES_MISDREAVUS - 1] = {0x28, 0x21, 0x08, 0x26, 0x2e}, + [SPECIES_UNOWN - 1] = {0x20, 0x17, 0x08, 0x1f, 0x21}, + [SPECIES_WOBBUFFET - 1] = {0x1d, 0x09, 0x30, 0x1d, 0x1a}, + [SPECIES_GIRAFARIG - 1] = {0x0b, 0x0d, 0x28, 0x11, 0x1d}, + [SPECIES_PINECO - 1] = {0x1d, 0x12, 0x10, 0x19, 0x25}, + [SPECIES_FORRETRESS - 1] = {0x19, 0x17, 0x08, 0x1e, 0x26}, + [SPECIES_DUNSPARCE - 1] = {0x10, 0x1b, 0x30, 0x0c, 0x2d}, + [SPECIES_GLIGAR - 1] = {0x1e, 0x13, 0x08, 0x1d, 0x23}, + [SPECIES_STEELIX - 1] = {0x0c, 0x0d, 0x28, 0x0d, 0x1c}, + [SPECIES_SNUBBULL - 1] = {0x1b, 0x15, 0x30, 0x1a, 0x23}, + [SPECIES_GRANBULL - 1] = {0x1c, 0x09, 0x30, 0x19, 0x18}, + [SPECIES_QWILFISH - 1] = {0x1f, 0x26, 0x20, 0x1d, 0x33}, + [SPECIES_SCIZOR - 1] = {0x15, 0x0f, 0x10, 0x1a, 0x1a}, + [SPECIES_SHUCKLE - 1] = {0x25, 0x0a, 0x30, 0x24, 0x18}, + [SPECIES_HERACROSS - 1] = {0x18, 0x19, 0x28, 0x1a, 0x26}, + [SPECIES_SNEASEL - 1] = {0x1c, 0x13, 0x30, 0x1d, 0x24}, + [SPECIES_TEDDIURSA - 1] = {0x1e, 0x12, 0x30, 0x1b, 0x23}, + [SPECIES_URSARING - 1] = {0x1e, 0x04, 0x28, 0x1d, 0x14}, + [SPECIES_SLUGMA - 1] = {0x20, 0x18, 0x30, 0x20, 0x28}, + [SPECIES_MAGCARGO - 1] = {0x16, 0x11, 0x30, 0x17, 0x23}, + [SPECIES_SWINUB - 1] = {0x1c, 0x18, 0x30, 0x1b, 0x25}, + [SPECIES_PILOSWINE - 1] = {0x18, 0x23, 0x20, 0x18, 0x36}, + [SPECIES_CORSOLA - 1] = {0x19, 0x1d, 0x28, 0x19, 0x2b}, + [SPECIES_REMORAID - 1] = {0x15, 0x1f, 0x28, 0x13, 0x2b}, + [SPECIES_OCTILLERY - 1] = {0x1c, 0x11, 0x30, 0x1a, 0x20}, + [SPECIES_DELIBIRD - 1] = {0x1d, 0x11, 0x30, 0x1b, 0x1f}, + [SPECIES_MANTINE - 1] = {0x16, 0x1e, 0x28, 0x1f, 0x27}, + [SPECIES_SKARMORY - 1] = {0x1e, 0x00, 0x28, 0x13, 0x07}, + [SPECIES_HOUNDOUR - 1] = {0x25, 0x11, 0x30, 0x25, 0x1f}, + [SPECIES_HOUNDOOM - 1] = {0x0d, 0x13, 0x30, 0x0d, 0x24}, + [SPECIES_KINGDRA - 1] = {0x0e, 0x13, 0x28, 0x0a, 0x2c}, + [SPECIES_PHANPY - 1] = {0x1b, 0x11, 0x30, 0x19, 0x24}, + [SPECIES_DONPHAN - 1] = {0x11, 0x15, 0x30, 0x19, 0x2c}, + [SPECIES_PORYGON2 - 1] = {0x18, 0x11, 0x30, 0x11, 0x20}, + [SPECIES_STANTLER - 1] = {0x15, 0x15, 0x28, 0x17, 0x28}, + [SPECIES_SMEARGLE - 1] = {0x18, 0x10, 0x30, 0x1b, 0x25}, + [SPECIES_TYROGUE - 1] = {0x1e, 0x12, 0x30, 0x1f, 0x1f}, + [SPECIES_HITMONTOP - 1] = {0x1a, 0x39, 0x10, 0x1a, 0x2b}, + [SPECIES_SMOOCHUM - 1] = {0x20, 0x18, 0x30, 0x21, 0x26}, + [SPECIES_ELEKID - 1] = {0x1d, 0x14, 0x30, 0x1d, 0x23}, + [SPECIES_MAGBY - 1] = {0x1c, 0x15, 0x30, 0x1a, 0x24}, + [SPECIES_MILTANK - 1] = {0x18, 0x0e, 0x30, 0x18, 0x1e}, + [SPECIES_BLISSEY - 1] = {0x1d, 0x09, 0x30, 0x1d, 0x19}, + [SPECIES_RAIKOU - 1] = {0x29, 0x0c, 0x28, 0x27, 0x1e}, + [SPECIES_ENTEI - 1] = {0x08, 0x09, 0x28, 0x0b, 0x18}, + [SPECIES_SUICUNE - 1] = {0x23, 0x1d, 0x28, 0x26, 0x2c}, + [SPECIES_LARVITAR - 1] = {0x1c, 0x18, 0x30, 0x1a, 0x24}, + [SPECIES_PUPITAR - 1] = {0x1b, 0x19, 0x30, 0x1b, 0x28}, + [SPECIES_TYRANITAR - 1] = {0x06, 0x0b, 0x28, 0x0d, 0x19}, + [SPECIES_LUGIA - 1] = {0x08, 0x2a, 0x08, 0x14, 0x34}, + [SPECIES_HO_OH - 1] = {0x0d, 0x25, 0x08, 0x0e, 0x34}, + [SPECIES_CELEBI - 1] = {0x15, 0x21, 0x08, 0x1a, 0x2b}, + [SPECIES_OLD_UNOWN_B - 1] = {0x1f, 0x12, 0x08, 0x1e, 0x1c}, + [SPECIES_OLD_UNOWN_C - 1] = {0x20, 0x17, 0x08, 0x1f, 0x21}, + [SPECIES_OLD_UNOWN_D - 1] = {0x1c, 0x19, 0x08, 0x1b, 0x23}, + [SPECIES_OLD_UNOWN_E - 1] = {0x21, 0x19, 0x08, 0x20, 0x23}, + [SPECIES_OLD_UNOWN_F - 1] = {0x1b, 0x13, 0x08, 0x1a, 0x1d}, + [SPECIES_OLD_UNOWN_G - 1] = {0x20, 0x16, 0x08, 0x1f, 0x21}, + [SPECIES_OLD_UNOWN_H - 1] = {0x20, 0x19, 0x08, 0x1f, 0x23}, + [SPECIES_OLD_UNOWN_I - 1] = {0x20, 0x19, 0x08, 0x1f, 0x23}, + [SPECIES_OLD_UNOWN_J - 1] = {0x20, 0x16, 0x08, 0x1f, 0x20}, + [SPECIES_OLD_UNOWN_K - 1] = {0x1d, 0x1a, 0x08, 0x1c, 0x24}, + [SPECIES_OLD_UNOWN_L - 1] = {0x20, 0x16, 0x08, 0x1f, 0x1f}, + [SPECIES_OLD_UNOWN_M - 1] = {0x20, 0x1c, 0x08, 0x1f, 0x26}, + [SPECIES_OLD_UNOWN_N - 1] = {0x20, 0x1a, 0x08, 0x1f, 0x23}, + [SPECIES_OLD_UNOWN_O - 1] = {0x20, 0x1a, 0x08, 0x1f, 0x23}, + [SPECIES_OLD_UNOWN_P - 1] = {0x20, 0x16, 0x08, 0x1f, 0x20}, + [SPECIES_OLD_UNOWN_Q - 1] = {0x1d, 0x16, 0x08, 0x1c, 0x20}, + [SPECIES_OLD_UNOWN_R - 1] = {0x20, 0x15, 0x08, 0x1f, 0x1f}, + [SPECIES_OLD_UNOWN_S - 1] = {0x20, 0x19, 0x08, 0x1f, 0x23}, + [SPECIES_OLD_UNOWN_T - 1] = {0x20, 0x1e, 0x08, 0x1f, 0x28}, + [SPECIES_OLD_UNOWN_U - 1] = {0x20, 0x17, 0x08, 0x1f, 0x21}, + [SPECIES_OLD_UNOWN_V - 1] = {0x1e, 0x1e, 0x08, 0x1d, 0x28}, + [SPECIES_OLD_UNOWN_W - 1] = {0x20, 0x1d, 0x08, 0x1f, 0x27}, + [SPECIES_OLD_UNOWN_X - 1] = {0x20, 0x19, 0x08, 0x1f, 0x23}, + [SPECIES_OLD_UNOWN_Y - 1] = {0x20, 0x15, 0x08, 0x1f, 0x1f}, + [SPECIES_OLD_UNOWN_Z - 1] = {0x20, 0x19, 0x08, 0x1f, 0x23}, + [SPECIES_TREECKO - 1] = {0x1a, 0x0f, 0x30, 0x19, 0x20}, + [SPECIES_GROVYLE - 1] = {0x0d, 0x05, 0x10, 0x05, 0x13}, + [SPECIES_SCEPTILE - 1] = {0x10, 0x04, 0x28, 0x0c, 0x12}, + [SPECIES_TORCHIC - 1] = {0x17, 0x18, 0x30, 0x15, 0x25}, + [SPECIES_COMBUSKEN - 1] = {0x20, 0x12, 0x28, 0x1e, 0x20}, + [SPECIES_BLAZIKEN - 1] = {0x1a, 0x07, 0x28, 0x1d, 0x13}, + [SPECIES_MUDKIP - 1] = {0x1b, 0x1d, 0x28, 0x19, 0x2c}, + [SPECIES_MARSHTOMP - 1] = {0x1d, 0x11, 0x30, 0x1c, 0x20}, + [SPECIES_SWAMPERT - 1] = {0x1b, 0x11, 0x28, 0x1b, 0x23}, + [SPECIES_POOCHYENA - 1] = {0x14, 0x12, 0x30, 0x0f, 0x20}, + [SPECIES_MIGHTYENA - 1] = {0x09, 0x0d, 0x28, 0x09, 0x1c}, + [SPECIES_ZIGZAGOON - 1] = {0x0b, 0x1a, 0x30, 0x09, 0x2b}, + [SPECIES_LINOONE - 1] = {0x0d, 0x28, 0x18, 0x0b, 0x37}, + [SPECIES_WURMPLE - 1] = {0x21, 0x17, 0x30, 0x1f, 0x26}, + [SPECIES_SILCOON - 1] = {0x13, 0x1c, 0x30, 0x11, 0x2a}, + [SPECIES_BEAUTIFLY - 1] = {0x0f, 0x1b, 0x08, 0x0e, 0x28}, + [SPECIES_CASCOON - 1] = {0x14, 0x1d, 0x30, 0x11, 0x2c}, + [SPECIES_DUSTOX - 1] = {0x14, 0x19, 0x08, 0x16, 0x26}, + [SPECIES_LOTAD - 1] = {0x19, 0x25, 0x28, 0x17, 0x32}, + [SPECIES_LOMBRE - 1] = {0x22, 0x10, 0x30, 0x29, 0x1d}, + [SPECIES_LUDICOLO - 1] = {0x1c, 0x0f, 0x28, 0x1b, 0x24}, + [SPECIES_SEEDOT - 1] = {0x1b, 0x17, 0x30, 0x18, 0x28}, + [SPECIES_NUZLEAF - 1] = {0x20, 0x0d, 0x30, 0x1a, 0x1d}, + [SPECIES_SHIFTRY - 1] = {0x32, 0x11, 0x28, 0x2e, 0x23}, + [SPECIES_NINCADA - 1] = {0x18, 0x1a, 0x30, 0x17, 0x28}, + [SPECIES_NINJASK - 1] = {0x17, 0x21, 0x00, 0x17, 0x2f}, + [SPECIES_SHEDINJA - 1] = {0x16, 0x19, 0x08, 0x18, 0x2a}, + [SPECIES_TAILLOW - 1] = {0x17, 0x10, 0x30, 0x14, 0x1e}, + [SPECIES_SWELLOW - 1] = {0x0c, 0x0a, 0x28, 0x05, 0x16}, + [SPECIES_SHROOMISH - 1] = {0x1f, 0x16, 0x30, 0x1d, 0x23}, + [SPECIES_BRELOOM - 1] = {0x25, 0x0c, 0x30, 0x23, 0x19}, + [SPECIES_SPINDA - 1] = {0x21, 0x16, 0x30, 0x1f, 0x27}, + [SPECIES_WINGULL - 1] = {0x1a, 0x16, 0x10, 0x15, 0x26}, + [SPECIES_PELIPPER - 1] = {0x1d, 0x0a, 0x10, 0x09, 0x1b}, + [SPECIES_SURSKIT - 1] = {0x1d, 0x16, 0x30, 0x1c, 0x25}, + [SPECIES_MASQUERAIN - 1] = {0x1a, 0x21, 0x08, 0x14, 0x30}, + [SPECIES_WAILMER - 1] = {0x17, 0x17, 0x30, 0x16, 0x28}, + [SPECIES_WAILORD - 1] = {0x17, 0x03, 0x30, 0x09, 0x13}, + [SPECIES_SKITTY - 1] = {0x24, 0x1a, 0x30, 0x22, 0x2a}, + [SPECIES_DELCATTY - 1] = {0x1e, 0x12, 0x30, 0x1c, 0x21}, + [SPECIES_KECLEON - 1] = {0x19, 0x10, 0x30, 0x13, 0x1e}, + [SPECIES_BALTOY - 1] = {0x1d, 0x15, 0x30, 0x1b, 0x22}, + [SPECIES_CLAYDOL - 1] = {0x1e, 0x0d, 0x28, 0x1d, 0x24}, + [SPECIES_NOSEPASS - 1] = {0x1f, 0x10, 0x30, 0x15, 0x23}, + [SPECIES_TORKOAL - 1] = {0x0e, 0x19, 0x28, 0x0a, 0x27}, + [SPECIES_SABLEYE - 1] = {0x1e, 0x16, 0x30, 0x1d, 0x27}, + [SPECIES_BARBOACH - 1] = {0x17, 0x12, 0x30, 0x15, 0x1e}, + [SPECIES_WHISCASH - 1] = {0x18, 0x20, 0x28, 0x17, 0x31}, + [SPECIES_LUVDISC - 1] = {0x19, 0x0f, 0x30, 0x13, 0x1c}, + [SPECIES_CORPHISH - 1] = {0x1f, 0x14, 0x30, 0x1d, 0x23}, + [SPECIES_CRAWDAUNT - 1] = {0x14, 0x0c, 0x28, 0x18, 0x23}, + [SPECIES_FEEBAS - 1] = {0x18, 0x1e, 0x28, 0x16, 0x2f}, + [SPECIES_MILOTIC - 1] = {0x20, 0x0c, 0x28, 0x1f, 0x1d}, + [SPECIES_CARVANHA - 1] = {0x16, 0x19, 0x30, 0x13, 0x22}, + [SPECIES_SHARPEDO - 1] = {0x19, 0x0c, 0x28, 0x17, 0x27}, + [SPECIES_TRAPINCH - 1] = {0x29, 0x13, 0x30, 0x17, 0x18}, + [SPECIES_VIBRAVA - 1] = {0x10, 0x27, 0x20, 0x0e, 0x34}, + [SPECIES_FLYGON - 1] = {0x22, 0x07, 0x10, 0x21, 0x13}, + [SPECIES_MAKUHITA - 1] = {0x22, 0x13, 0x30, 0x1c, 0x23}, + [SPECIES_HARIYAMA - 1] = {0x24, 0x0f, 0x28, 0x26, 0x1c}, + [SPECIES_ELECTRIKE - 1] = {0x11, 0x18, 0x30, 0x14, 0x27}, + [SPECIES_MANECTRIC - 1] = {0x2f, 0x18, 0x28, 0x2e, 0x29}, + [SPECIES_NUMEL - 1] = {0x10, 0x1a, 0x30, 0x0d, 0x2a}, + [SPECIES_CAMERUPT - 1] = {0x0d, 0x22, 0x28, 0x0e, 0x36}, + [SPECIES_SPHEAL - 1] = {0x1e, 0x0f, 0x30, 0x18, 0x1f}, + [SPECIES_SEALEO - 1] = {0x1c, 0x09, 0x30, 0x1a, 0x18}, + [SPECIES_WALREIN - 1] = {0x19, 0x01, 0x28, 0x10, 0x16}, + [SPECIES_CACNEA - 1] = {0x1f, 0x17, 0x30, 0x1d, 0x29}, + [SPECIES_CACTURNE - 1] = {0x1d, 0x0e, 0x28, 0x1d, 0x1b}, + [SPECIES_SNORUNT - 1] = {0x1e, 0x16, 0x30, 0x1e, 0x26}, + [SPECIES_GLALIE - 1] = {0x1a, 0x1c, 0x08, 0x1a, 0x31}, + [SPECIES_LUNATONE - 1] = {0x1c, 0x16, 0x08, 0x19, 0x2c}, + [SPECIES_SOLROCK - 1] = {0x18, 0x18, 0x10, 0x17, 0x31}, + [SPECIES_AZURILL - 1] = {0x1b, 0x10, 0x30, 0x18, 0x1f}, + [SPECIES_SPOINK - 1] = {0x21, 0x14, 0x30, 0x1b, 0x28}, + [SPECIES_GRUMPIG - 1] = {0x14, 0x10, 0x30, 0x15, 0x20}, + [SPECIES_PLUSLE - 1] = {0x1c, 0x16, 0x08, 0x1d, 0x25}, + [SPECIES_MINUN - 1] = {0x21, 0x16, 0x08, 0x1f, 0x26}, + [SPECIES_MAWILE - 1] = {0x2d, 0x14, 0x30, 0x2f, 0x24}, + [SPECIES_MEDITITE - 1] = {0x1f, 0x17, 0x30, 0x1e, 0x25}, + [SPECIES_MEDICHAM - 1] = {0x21, 0x0f, 0x28, 0x1e, 0x1d}, + [SPECIES_SWABLU - 1] = {0x1b, 0x16, 0x10, 0x17, 0x23}, + [SPECIES_ALTARIA - 1] = {0x1d, 0x0b, 0x10, 0x1a, 0x1a}, + [SPECIES_WYNAUT - 1] = {0x1a, 0x15, 0x30, 0x1b, 0x26}, + [SPECIES_DUSKULL - 1] = {0x10, 0x18, 0x08, 0x14, 0x2e}, + [SPECIES_DUSCLOPS - 1] = {0x1c, 0x0f, 0x30, 0x1a, 0x28}, + [SPECIES_ROSELIA - 1] = {0x1e, 0x11, 0x30, 0x1d, 0x20}, + [SPECIES_SLAKOTH - 1] = {0x19, 0x1e, 0x30, 0x18, 0x2f}, + [SPECIES_VIGOROTH - 1] = {0x10, 0x12, 0x28, 0x14, 0x24}, + [SPECIES_SLAKING - 1] = {0x37, 0x0f, 0x30, 0x29, 0x21}, + [SPECIES_GULPIN - 1] = {0x1b, 0x18, 0x30, 0x17, 0x26}, + [SPECIES_SWALOT - 1] = {0x1f, 0x06, 0x30, 0x15, 0x13}, + [SPECIES_TROPIUS - 1] = {0x18, 0x0a, 0x28, 0x20, 0x18}, + [SPECIES_WHISMUR - 1] = {0x1f, 0x19, 0x30, 0x1d, 0x29}, + [SPECIES_LOUDRED - 1] = {0x1c, 0x12, 0x28, 0x22, 0x27}, + [SPECIES_EXPLOUD - 1] = {0x10, 0x10, 0x28, 0x1a, 0x2a}, + [SPECIES_CLAMPERL - 1] = {0x20, 0x1a, 0x30, 0x1e, 0x26}, + [SPECIES_HUNTAIL - 1] = {0x13, 0x1e, 0x28, 0x15, 0x33}, + [SPECIES_GOREBYSS - 1] = {0x0d, 0x1f, 0x28, 0x03, 0x32}, + [SPECIES_ABSOL - 1] = {0x2a, 0x11, 0x28, 0x2a, 0x22}, + [SPECIES_SHUPPET - 1] = {0x16, 0x19, 0x08, 0x17, 0x27}, + [SPECIES_BANETTE - 1] = {0x1c, 0x14, 0x08, 0x1b, 0x23}, + [SPECIES_SEVIPER - 1] = {0x0e, 0x0d, 0x30, 0x0b, 0x1e}, + [SPECIES_ZANGOOSE - 1] = {0x18, 0x0c, 0x28, 0x15, 0x1a}, + [SPECIES_RELICANTH - 1] = {0x0c, 0x1f, 0x30, 0x09, 0x2d}, + [SPECIES_ARON - 1] = {0x18, 0x1c, 0x30, 0x1a, 0x2c}, + [SPECIES_LAIRON - 1] = {0x0b, 0x21, 0x30, 0x12, 0x2f}, + [SPECIES_AGGRON - 1] = {0x10, 0x0b, 0x28, 0x16, 0x1b}, + [SPECIES_CASTFORM - 1] = {0x1d, 0x18, 0x08, 0x1b, 0x26}, + [SPECIES_VOLBEAT - 1] = {0x25, 0x15, 0x08, 0x21, 0x25}, + [SPECIES_ILLUMISE - 1] = {0x20, 0x12, 0x08, 0x1f, 0x20}, + [SPECIES_LILEEP - 1] = {0x1e, 0x11, 0x30, 0x1f, 0x1e}, + [SPECIES_CRADILY - 1] = {0x12, 0x16, 0x28, 0x15, 0x28}, + [SPECIES_ANORITH - 1] = {0x1c, 0x1e, 0x30, 0x1b, 0x2b}, + [SPECIES_ARMALDO - 1] = {0x15, 0x05, 0x28, 0x14, 0x13}, + [SPECIES_RALTS - 1] = {0x1f, 0x17, 0x30, 0x20, 0x23}, + [SPECIES_KIRLIA - 1] = {0x1c, 0x12, 0x30, 0x1f, 0x1e}, + [SPECIES_GARDEVOIR - 1] = {0x35, 0x07, 0x28, 0x32, 0x14}, + [SPECIES_BAGON - 1] = {0x17, 0x13, 0x30, 0x16, 0x26}, + [SPECIES_SHELGON - 1] = {0x19, 0x1b, 0x30, 0x19, 0x2c}, + [SPECIES_SALAMENCE - 1] = {0x09, 0x11, 0x30, 0x0a, 0x21}, + [SPECIES_BELDUM - 1] = {0x16, 0x19, 0x08, 0x18, 0x23}, + [SPECIES_METANG - 1] = {0x22, 0x0f, 0x10, 0x1f, 0x21}, + [SPECIES_METAGROSS - 1] = {0x24, 0x1b, 0x28, 0x22, 0x2b}, + [SPECIES_REGIROCK - 1] = {0x16, 0x07, 0x28, 0x14, 0x12}, + [SPECIES_REGICE - 1] = {0x19, 0x0c, 0x28, 0x17, 0x19}, + [SPECIES_REGISTEEL - 1] = {0x19, 0x0d, 0x28, 0x19, 0x19}, + [SPECIES_KYOGRE - 1] = {0x0e, 0x19, 0x28, 0x0b, 0x26}, + [SPECIES_GROUDON - 1] = {0x04, 0x0b, 0x28, 0x0a, 0x19}, + [SPECIES_RAYQUAZA - 1] = {0x0c, 0x0e, 0x10, 0x0e, 0x1f}, + [SPECIES_LATIAS - 1] = {0x1e, 0x0c, 0x10, 0x23, 0x19}, + [SPECIES_LATIOS - 1] = {0x05, 0x0e, 0x10, 0x05, 0x1d}, + [SPECIES_JIRACHI - 1] = {0x1c, 0x15, 0x08, 0x1e, 0x22}, + [SPECIES_DEOXYS - 1] = {0x1b, 0x08, 0x28, 0x1c, 0x16}, + [SPECIES_CHIMECHO - 1] = {0x1d, 0x0c, 0x08, 0x1c, 0x1a}, + [SPECIES_OLD_UNOWN_EMARK - 1] = {0x20, 0x21, 0x08, 0x20, 0x2b}, + [SPECIES_OLD_UNOWN_QMARK - 1] = {0x20, 0x23, 0x08, 0x20, 0x2d} +}; + +void box_print(u8 windowId, u8 fontId, u8 x, u8 y, const struct TextColor * color, s8 speed, const u8 * str) +{ + struct TextSubPrinter printer; + + printer.current_text_offset = str; + printer.windowId = windowId; + printer.fontId = fontId; + printer.x = x; + printer.y = y; + printer.currentX = printer.x; + printer.currentY = printer.y; + printer.letterSpacing = GetFontAttribute(fontId, 2); + printer.lineSpacing = GetFontAttribute(fontId, 3); + printer.fontColor_l = 0; + printer.fontColor_h = color->bgColor; + printer.bgColor = color->fgColor; + printer.shadowColor = color->shadowColor; + AddTextPrinter(&printer, speed, NULL); +} + +void AddTextPrinterParametrized2(u8 windowId, u8 fontId, u8 x, u8 y, u8 letterSpacing, u8 lineSpacing, const struct TextColor *color, s8 speed, const u8 *str) +{ + struct TextSubPrinter printer; + + printer.current_text_offset = str; + printer.windowId = windowId; + printer.fontId = fontId; + printer.x = x; + printer.y = y; + printer.currentX = printer.x; + printer.currentY = printer.y; + printer.letterSpacing = letterSpacing; + printer.lineSpacing = lineSpacing; + printer.fontColor_l = 0; + printer.fontColor_h = color->bgColor; + printer.bgColor = color->fgColor; + printer.shadowColor = color->shadowColor; + AddTextPrinter(&printer, speed, NULL); +} + +void sub_812E62C(u8 windowId, u8 fontId, const u8 *str, u8 x, u8 y, u8 speed, void (*callback)(struct TextSubPrinter *, u16), u8 letterSpacing, u8 lineSpacing) +{ + struct TextSubPrinter printer; + + printer.current_text_offset = str; + printer.windowId = windowId; + printer.fontId = fontId; + printer.x = x; + printer.y = y; + printer.currentX = x; + printer.currentY = y; + printer.letterSpacing = letterSpacing; + printer.lineSpacing = lineSpacing; + printer.fontColor_l = 0; + printer.fontColor_h = GetFontAttribute(fontId, 5); + printer.bgColor = GetFontAttribute(fontId, 6); + printer.shadowColor = GetFontAttribute(fontId, 7); + AddTextPrinter(&printer, speed, callback); +} + +void sub_812E6DC(u8 windowId, const u8 * src, u16 x, u16 y) +{ + s32 i; + + for (i = 0; gSaveBlock2Ptr->playerName[i] != EOS; i++) + ; + + StringExpandPlaceholders(gStringVar4, src); + if (i != 5) + { + AddTextPrinterParameterized(windowId, 2, gStringVar4, x, y, 0xFF, NULL); + } + else + { + sub_812E62C(windowId, 2, gStringVar4, x, y, 0xFF, NULL, 0, 0); + } +} + +// Yeah, no, I'm not bothering with this +NAKED +void sub_819A080(void * a0, void * a1, u16 a2, u16 a3, u16 a4, u16 a5, u16 a6, u16 a7) +{ + asm_unified("\tpush {r4-r7,lr}\n" + "\tmov r7, r10\n" + "\tmov r6, r9\n" + "\tmov r5, r8\n" + "\tpush {r5-r7}\n" + "\tsub sp, 0x28\n" + "\tstr r0, [sp]\n" + "\tstr r1, [sp, 0x4]\n" + "\tldr r0, [sp, 0x48]\n" + "\tldr r4, [sp, 0x4C]\n" + "\tldr r1, [sp, 0x50]\n" + "\tldr r5, [sp, 0x54]\n" + "\tlsls r2, 16\n" + "\tlsrs r2, 16\n" + "\tstr r2, [sp, 0x8]\n" + "\tlsls r3, 16\n" + "\tlsrs r3, 16\n" + "\tlsls r0, 16\n" + "\tlsrs r0, 16\n" + "\tstr r0, [sp, 0xC]\n" + "\tlsls r4, 16\n" + "\tlsrs r4, 16\n" + "\tlsls r1, 16\n" + "\tlsrs r1, 16\n" + "\tlsls r5, 16\n" + "\tlsrs r5, 16\n" + "\tldr r2, [sp, 0x4]\n" + "\tldrh r0, [r2, 0x4]\n" + "\tldr r2, [sp, 0xC]\n" + "\tsubs r0, r2\n" + "\tldr r2, [sp, 0x8]\n" + "\tadds r2, r1, r2\n" + "\tstr r2, [sp, 0x10]\n" + "\tcmp r0, r1\n" + "\tbge _0812E7B4\n" + "\tldr r1, [sp, 0x8]\n" + "\tadds r0, r1\n" + "\tstr r0, [sp, 0x10]\n" + "_0812E7B4:\n" + "\tldr r2, [sp, 0x4]\n" + "\tldrh r1, [r2, 0x6]\n" + "\tsubs r0, r1, r4\n" + "\tcmp r0, r5\n" + "\tbge _0812E7C6\n" + "\tadds r0, r3, r1\n" + "\tsubs r0, r4\n" + "\tstr r0, [sp, 0x14]\n" + "\tb _0812E7CA\n" + "_0812E7C6:\n" + "\tadds r5, r3, r5\n" + "\tstr r5, [sp, 0x14]\n" + "_0812E7CA:\n" + "\tldr r0, [sp]\n" + "\tldrh r1, [r0, 0x4]\n" + "\tmovs r2, 0x7\n" + "\tadds r0, r1, 0\n" + "\tands r0, r2\n" + "\tadds r1, r0\n" + "\tasrs r1, 3\n" + "\tstr r1, [sp, 0x18]\n" + "\tldr r0, [sp, 0x4]\n" + "\tldrh r1, [r0, 0x4]\n" + "\tadds r0, r1, 0\n" + "\tands r0, r2\n" + "\tadds r1, r0\n" + "\tasrs r1, 3\n" + "\tstr r1, [sp, 0x1C]\n" + "\tmov r12, r3\n" + "\tmov r8, r4\n" + "\tldr r1, [sp, 0x14]\n" + "\tcmp r12, r1\n" + "\tblt _0812E7F4\n" + "\tb _0812E932\n" + "_0812E7F4:\n" + "\tldr r5, [sp, 0x8]\n" + "\tldr r6, [sp, 0xC]\n" + "\tmov r2, r12\n" + "\tadds r2, 0x1\n" + "\tstr r2, [sp, 0x20]\n" + "\tmov r0, r8\n" + "\tadds r0, 0x1\n" + "\tstr r0, [sp, 0x24]\n" + "\tldr r1, [sp, 0x10]\n" + "\tcmp r5, r1\n" + "\tblt _0812E80C\n" + "\tb _0812E922\n" + "_0812E80C:\n" + "\tmovs r7, 0x1\n" + "\tmovs r2, 0xF0\n" + "\tmov r10, r2\n" + "\tmovs r0, 0xF\n" + "\tmov r9, r0\n" + "_0812E816:\n" + "\tasrs r0, r5, 1\n" + "\tmovs r1, 0x3\n" + "\tands r0, r1\n" + "\tldr r2, [sp]\n" + "\tldr r1, [r2]\n" + "\tadds r1, r0\n" + "\tasrs r0, r5, 3\n" + "\tlsls r0, 5\n" + "\tadds r1, r0\n" + "\tmov r2, r12\n" + "\tasrs r0, r2, 3\n" + "\tldr r2, [sp, 0x18]\n" + "\tmuls r0, r2\n" + "\tlsls r0, 5\n" + "\tadds r1, r0\n" + "\tmov r2, r12\n" + "\tlsls r0, r2, 29\n" + "\tlsrs r0, 27\n" + "\tadds r3, r1, r0\n" + "\tasrs r0, r6, 1\n" + "\tmovs r1, 0x3\n" + "\tands r0, r1\n" + "\tldr r2, [sp, 0x4]\n" + "\tldr r1, [r2]\n" + "\tadds r1, r0\n" + "\tasrs r0, r6, 3\n" + "\tlsls r0, 5\n" + "\tadds r1, r0\n" + "\tmov r2, r8\n" + "\tasrs r0, r2, 3\n" + "\tldr r2, [sp, 0x1C]\n" + "\tmuls r0, r2\n" + "\tlsls r0, 5\n" + "\tadds r1, r0\n" + "\tmov r2, r8\n" + "\tlsls r0, r2, 29\n" + "\tlsrs r0, 27\n" + "\tadds r4, r1, r0\n" + "\tadds r0, r4, 0\n" + "\tands r0, r7\n" + "\tcmp r0, 0\n" + "\tbeq _0812E8C2\n" + "\tsubs r4, 0x1\n" + "\tadds r0, r6, 0\n" + "\tands r0, r7\n" + "\tcmp r0, 0\n" + "\tbeq _0812E89A\n" + "\tldrh r0, [r4]\n" + "\tldr r2, _0812E88C @ =0x00000fff\n" + "\tands r2, r0\n" + "\tadds r0, r5, 0\n" + "\tands r0, r7\n" + "\tcmp r0, 0\n" + "\tbeq _0812E890\n" + "\tldrb r1, [r3]\n" + "\tmov r0, r10\n" + "\tands r0, r1\n" + "\tlsls r0, 8\n" + "\tb _0812E912\n" + "\t.align 2, 0\n" + "_0812E88C: .4byte 0x00000fff\n" + "_0812E890:\n" + "\tldrb r1, [r3]\n" + "\tmov r0, r9\n" + "\tands r0, r1\n" + "\tlsls r0, 12\n" + "\tb _0812E912\n" + "_0812E89A:\n" + "\tldrh r0, [r4]\n" + "\tldr r2, _0812E8B4 @ =0x0000f0ff\n" + "\tands r2, r0\n" + "\tadds r0, r5, 0\n" + "\tands r0, r7\n" + "\tcmp r0, 0\n" + "\tbeq _0812E8B8\n" + "\tldrb r1, [r3]\n" + "\tmov r0, r10\n" + "\tands r0, r1\n" + "\tlsls r0, 4\n" + "\tb _0812E912\n" + "\t.align 2, 0\n" + "_0812E8B4: .4byte 0x0000f0ff\n" + "_0812E8B8:\n" + "\tldrb r1, [r3]\n" + "\tmov r0, r9\n" + "\tands r0, r1\n" + "\tlsls r0, 8\n" + "\tb _0812E912\n" + "_0812E8C2:\n" + "\tadds r0, r6, 0\n" + "\tands r0, r7\n" + "\tcmp r0, 0\n" + "\tbeq _0812E8EE\n" + "\tldrh r0, [r4]\n" + "\tldr r2, _0812E8E0 @ =0x0000ff0f\n" + "\tands r2, r0\n" + "\tadds r0, r5, 0\n" + "\tands r0, r7\n" + "\tcmp r0, 0\n" + "\tbeq _0812E8E4\n" + "\tldrb r1, [r3]\n" + "\tmov r0, r10\n" + "\tb _0812E910\n" + "\t.align 2, 0\n" + "_0812E8E0: .4byte 0x0000ff0f\n" + "_0812E8E4:\n" + "\tldrb r1, [r3]\n" + "\tmov r0, r9\n" + "\tands r0, r1\n" + "\tlsls r0, 4\n" + "\tb _0812E912\n" + "_0812E8EE:\n" + "\tldrh r0, [r4]\n" + "\tldr r2, _0812E908 @ =0x0000fff0\n" + "\tands r2, r0\n" + "\tadds r0, r5, 0\n" + "\tands r0, r7\n" + "\tcmp r0, 0\n" + "\tbeq _0812E90C\n" + "\tldrb r1, [r3]\n" + "\tmov r0, r10\n" + "\tands r0, r1\n" + "\tlsrs r0, 4\n" + "\tb _0812E912\n" + "\t.align 2, 0\n" + "_0812E908: .4byte 0x0000fff0\n" + "_0812E90C:\n" + "\tldrb r1, [r3]\n" + "\tmov r0, r9\n" + "_0812E910:\n" + "\tands r0, r1\n" + "_0812E912:\n" + "\torrs r2, r0\n" + "\tstrh r2, [r4]\n" + "\tadds r5, 0x1\n" + "\tadds r6, 0x1\n" + "\tldr r0, [sp, 0x10]\n" + "\tcmp r5, r0\n" + "\tbge _0812E922\n" + "\tb _0812E816\n" + "_0812E922:\n" + "\tldr r1, [sp, 0x20]\n" + "\tmov r12, r1\n" + "\tldr r2, [sp, 0x24]\n" + "\tmov r8, r2\n" + "\tldr r0, [sp, 0x14]\n" + "\tcmp r12, r0\n" + "\tbge _0812E932\n" + "\tb _0812E7F4\n" + "_0812E932:\n" + "\tadd sp, 0x28\n" + "\tpop {r3-r5}\n" + "\tmov r8, r3\n" + "\tmov r9, r4\n" + "\tmov r10, r5\n" + "\tpop {r4-r7}\n" + "\tpop {r0}\n" + "\tbx r0"); +} + +#define tEvA data[0] +#define tEvB data[1] +#define tEvAEnd data[2] +#define tEvBEnd data[3] +#define tEvADelta data[4] +#define tEvBDelta data[5] +#define tEvWhich data[6] +#define tEvStepCount data[8] + +void StartBlendTask(u8 eva_start, u8 evb_start, u8 eva_end, u8 evb_end, u8 ev_step, u8 priority) +{ + u8 taskId = CreateTask(Task_SmoothBlendLayers, priority); + gTasks[taskId].tEvA = eva_start << 8; + gTasks[taskId].tEvB = evb_start << 8; + gTasks[taskId].tEvAEnd = eva_end; + gTasks[taskId].tEvBEnd = evb_end; + gTasks[taskId].tEvADelta = (eva_end - eva_start) * 256 / ev_step; + gTasks[taskId].tEvBDelta = (evb_end - evb_start) * 256 / ev_step; + gTasks[taskId].tEvStepCount = ev_step; + SetGpuReg(REG_OFFSET_BLDALPHA, (evb_start << 8) | eva_start); +} + +bool8 IsBlendTaskActive(void) +{ + return FuncIsActiveTask(Task_SmoothBlendLayers); +} + +static void Task_SmoothBlendLayers(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + if (tEvStepCount != 0) + { + if (tEvWhich == 0) + { + tEvA += tEvADelta; + tEvWhich = 1; + } + else + { + if (--tEvStepCount != 0) + { + tEvB += tEvBDelta; + } + else + { + tEvA = tEvAEnd << 8; + tEvB = tEvBEnd << 8; + } + tEvWhich = 0; + } + SetGpuReg(REG_OFFSET_BLDALPHA, (tEvB & ~0xFF) | ((u16)tEvA >> 8)); + if (tEvStepCount == 0) + DestroyTask(taskId); + } +} + +u8 sub_812EA78(u16 species, u32 personality, u8 a2) +{ + if (species == SPECIES_UNOWN) + { + u8 unownLetter = GetUnownLetterByPersonality(personality); + switch (unownLetter) + { + case 0: + break; + case 26: + species = SPECIES_OLD_UNOWN_EMARK; + break; + case 27: + species = SPECIES_OLD_UNOWN_QMARK; + break; + default: + species = SPECIES_OLD_UNOWN_B + unownLetter - 1; + break; + } + } + if (species != SPECIES_NONE && a2 < 5) + { + species--; + if (gUnknown_845FD54[species][a2] != 0xFF) + return gUnknown_845FD54[species][a2]; + } + return 32; +} + +s8 sub_812EAE4(u16 species, u32 personality, u8 a2) +{ + return sub_812EA78(species, personality, a2) - 32; +} diff --git a/src/mevent_8145654.c b/src/mevent_8145654.c index c39d76f25..65f515d1b 100644 --- a/src/mevent_8145654.c +++ b/src/mevent_8145654.c @@ -58,7 +58,7 @@ void sub_8145D18(u8 whichWindow); void sub_8146060(void); void sub_81461D8(void); -extern const struct OamData gUnknown_83AC9F8; +extern const struct OamData gOamData_83AC9F8; const struct TextColor gUnknown_8467068[] = { {0, 2, 3}, @@ -113,7 +113,7 @@ const struct SpritePalette gUnknown_8467F60[] = { {gUnknown_8467ED4, 0x8000} }; const struct SpriteTemplate gUnknown_8467FA0 = { - 0x8000, 0x8000, &gUnknown_83AC9F8, gDummySpriteAnimTable, NULL, gDummySpriteAffineAnimTable, SpriteCallbackDummy + 0x8000, 0x8000, &gOamData_83AC9F8, gDummySpriteAnimTable, NULL, gDummySpriteAffineAnimTable, SpriteCallbackDummy }; const struct UnkStruct_8467FB8 gUnknown_8467FB8[8] = { {1, 0, 0, 0, gUnknown_846718C, gUnknown_8467288, gUnknown_846708C}, diff --git a/src/oak_speech.c b/src/oak_speech.c new file mode 100644 index 000000000..f00d683cf --- /dev/null +++ b/src/oak_speech.c @@ -0,0 +1,1891 @@ +#include "global.h" +#include "main.h" +#include "decompress.h" +#include "task.h" +#include "malloc.h" +#include "gpu_regs.h" +#include "wild_encounter.h" +#include "palette.h" +#include "blend_palette.h" +#include "text.h" +#include "window.h" +#include "text_window.h" +#include "bg.h" +#include "menu.h" +#include "help_system.h" +#include "new_menu_helpers.h" +#include "pokemon_3.h" +#include "sound.h" +#include "event_scripts.h" +#include "scanline_effect.h" +#include "string_util.h" +#include "pokeball.h" +#include "naming_screen.h" +#include "math_util.h" +#include "overworld.h" +#include "random.h" +#include "oak_speech.h" +#include "constants/species.h" +#include "constants/songs.h" + +struct OakSpeechResources +{ + void * solidColorsGfx; + void * trainerPicTilemapBuffer; + void * unk_0008; + u8 filler_000C[4]; + u16 unk_0010; + u16 unk_0012; + u16 unk_0014[4]; + u8 unk_001C[3]; + u8 textSpeed; + u8 filler_0020[0x1800]; + u8 bg2TilemapBuffer[0x400]; + u8 bg1TilemapBuffer[0x800]; +}; //size=0x2420 + +EWRAM_DATA struct OakSpeechResources * sOakSpeechResources = NULL; + +static void Task_OaksSpeech1(u8 taskId); +static void CreateHelpDocsPage1(void); +static void Task_OaksSpeech2(u8 taskId); +static void Task_OakSpeech3(u8 taskId); +static void Task_OakSpeech5(u8 taskId); +static void Task_OakSpeech6(u8 taskId); +static void Task_OakSpeech7(u8 taskId); +static void Task_OakSpeech8(u8 taskId); +static void Task_OakSpeech9(u8 taskId); +static void Task_OakSpeech10(u8 taskId); +static void Task_OakSpeech10(u8 taskId); +static void Task_OakSpeech11(u8 taskId); +static void Task_OakSpeech12(u8 taskId); +static void Task_OakSpeech13(u8 taskId); +static void Task_OakSpeech14(u8 taskId); +static void Task_OakSpeech15(u8 taskId); +static void Task_OakSpeech16(u8 taskId); +static void Task_OakSpeech17(u8 taskId); +static void Task_OakSpeech18(u8 taskId); +static void Task_OakSpeech19(u8 taskId); +static void Task_OakSpeech20(u8 taskId); +static void Task_OakSpeech21(u8 taskId); +static void Task_OakSpeech22(u8 taskId); +static void Task_OakSpeech23(u8 taskId); +static void Task_OakSpeech24(u8 taskId); +static void Task_OakSpeech29(u8 taskId); +static void Task_OakSpeech25(u8 taskId); +static void Task_OakSpeech26(u8 taskId); +static void Task_OakSpeech27(u8 taskId); +static void Task_OakSpeech30(u8 taskId); +static void Task_OakSpeech31(u8 taskId); +static void Task_OakSpeech32(u8 taskId); +static void Task_OakSpeech34(u8 taskId); +static void Task_OakSpeech33(u8 taskId); +static void Task_OakSpeech36(u8 taskId); +static void Task_OakSpeech37(u8 taskId); +static void Task_OakSpeech38(u8 taskId); +static void Task_OakSpeech38_3(u8 taskId); +static void Task_OakSpeech39(u8 taskId); +static void Task_OakSpeech38_1(u8 taskId); +static void Task_OakSpeech38_sub1(u8 taskId); +static void Task_OakSpeech38_2(u8 taskId); +static void Task_OakSpeech38_sub2(u8 taskId); +static void Task_OakSpeech40(u8 taskId); +static void Task_OakSpeech41(u8 taskId); +static void Task_OakSpeech42(u8 taskId); + +static void CB2_ReturnFromNamingScreen(void); +static void CreateNidoranFSprite(u8 taskId); +static void CreatePikaOrGrassPlatformSpriteAndLinkToCurrentTask(u8 taskId, u8 state); +static void DestroyLinkedPikaOrGrassPlatformSprites(u8 taskId, u8 state); +static void LoadOaksSpeechTrainerPic(u16 whichPic, u16 tileOffset); +static void DestroyOaksSpeechTrainerPic(void); +static void CreateFadeInTask(u8 taskId, u8 state); +static void CreateFadeOutTask(u8 taskId, u8 state); +static void PrintNameChoiceOptions(u8 taskId, u8 state); +static void GetDefaultName(u8 arg0, u8 namePick); + +extern const u8 gText_Controls[]; +extern const u8 gText_ABUTTONNext[]; +extern const u8 gText_ABUTTONNext_BBUTTONBack[]; +extern const u8 gText_Boy[]; +extern const u8 gText_Girl[]; + +extern const struct CompressedSpriteSheet gUnknown_8235194[]; +extern const struct CompressedSpritePalette gUnknown_82373F4; + +ALIGNED(4) static const u16 sHelpDocsPalette[] = INCBIN_U16("data/oak_speech/help_docs_palette.gbapal"); +static const u32 sOakSpeechGfx_GameStartHelpUI[] = INCBIN_U32("data/oak_speech/oak_speech_gfx_game_start_help_u_i.4bpp.lz"); +static const u32 sNewGameAdventureIntroTilemap[] = INCBIN_U32("data/oak_speech/new_game_adventure_intro_tilemap.bin.lz"); +static const u32 sOakSpeechGfx_SolidColors[] = INCBIN_U32("data/oak_speech/oak_speech_gfx_solid_colors.4bpp.lz"); +static const u32 sOakSpeech_BackgroundTilemap[] = INCBIN_U32("data/oak_speech/oak_speech_background_tilemap.bin.lz"); +static const u16 sHelpDocsPage2Tilemap[] = INCBIN_U16("data/oak_speech/help_docs_page2_tilemap.bin"); +static const u16 sHelpDocsPage3Tilemap[] = INCBIN_U16("data/oak_speech/help_docs_page3_tilemap.bin"); +static const u16 sOakSpeechGfx_LeafPal[] = INCBIN_U16("data/oak_speech/oak_speech_gfx_leaf_pal.gbapal"); +static const u32 sOakSpeechGfx_LeafPic[] = INCBIN_U32("data/oak_speech/oak_speech_gfx_leaf_pic.8bpp.lz"); +static const u16 sOakSpeechGfx_RedPal[] = INCBIN_U16("data/oak_speech/oak_speech_gfx_red_pal.gbapal"); +static const u32 sOakSpeechGfx_RedPic[] = INCBIN_U32("data/oak_speech/oak_speech_gfx_red_pic.8bpp.lz"); +static const u16 sOakSpeechGfx_OakPal[] = INCBIN_U16("data/oak_speech/oak_speech_gfx_oak_pal.gbapal"); +static const u32 sOakSpeechGfx_OakPic[] = INCBIN_U32("data/oak_speech/oak_speech_gfx_oak_pic.8bpp.lz"); +static const u16 sOakSpeechGfx_RivalPal[] = INCBIN_U16("data/oak_speech/oak_speech_gfx_rival_pal.gbapal"); +static const u32 sOakSpeechGfx_RivalPic[] = INCBIN_U32("data/oak_speech/oak_speech_gfx_rival_pic.8bpp.lz"); +static const u16 sOakSpeech_GrassPlatformPalette[] = INCBIN_U16("data/oak_speech/oak_speech_grass_platform_palette.gbapal"); +static const u16 sOakSpeech_PikaPalette[] = INCBIN_U16("data/oak_speech/oak_speech_pika_palette.gbapal"); +static const u32 sOakSpeechGfx_GrassPlatform[] = INCBIN_U32("data/oak_speech/oak_speech_gfx_grass_platform.4bpp.lz"); +static const u32 sOakSpeechGfx_Pika1[] = INCBIN_U32("data/oak_speech/oak_speech_gfx_pika1.4bpp.lz"); +static const u32 sOakSpeechGfx_Pika2[] = INCBIN_U32("data/oak_speech/oak_speech_gfx_pika2.4bpp.lz"); +static const u32 sOakSpeechGfx_PikaEyes[] = INCBIN_U32("data/oak_speech/oak_speech_gfx_pika_eyes.4bpp.lz"); + +static const struct BgTemplate sBgTemplates[3] = { + { + .bg = 0, + .charBaseIndex = 2, + .mapBaseIndex = 31, + .screenSize = 0, + .paletteMode = 0, + .priority = 0, + .baseTile = 0x000 + }, { + .bg = 1, + .charBaseIndex = 0, + .mapBaseIndex = 30, + .screenSize = 0, + .paletteMode = 0, + .priority = 2, + .baseTile = 0x000 + }, { + .bg = 2, + .charBaseIndex = 0, + .mapBaseIndex = 28, + .screenSize = 1, + .paletteMode = 1, + .priority = 1, + .baseTile = 0x000 + } +}; + +static const struct WindowTemplate sHelpDocsWindowTemplates1[] = { + { + .priority = 0x00, + .tilemapLeft = 0x00, + .tilemapTop = 0x07, + .width = 0x1e, + .height = 0x04, + .paletteNum = 0x0f, + .baseBlock = 0x0001 + }, DUMMY_WIN_TEMPLATE +}; + +static const struct WindowTemplate sHelpDocsWindowTemplates2[] = { + { + .priority = 0x00, + .tilemapLeft = 0x06, + .tilemapTop = 0x03, + .width = 0x18, + .height = 0x06, + .paletteNum = 0x0f, + .baseBlock = 0x0001 + }, { + .priority = 0x00, + .tilemapLeft = 0x06, + .tilemapTop = 0x0a, + .width = 0x18, + .height = 0x04, + .paletteNum = 0x0f, + .baseBlock = 0x0092 + }, { + .priority = 0x00, + .tilemapLeft = 0x06, + .tilemapTop = 0x0f, + .width = 0x18, + .height = 0x04, + .paletteNum = 0x0f, + .baseBlock = 0x00f3 + }, DUMMY_WIN_TEMPLATE +}; + +static const struct WindowTemplate sHelpDocsWindowTemplates3[] = { + { + .priority = 0x00, + .tilemapLeft = 0x06, + .tilemapTop = 0x03, + .width = 0x18, + .height = 0x04, + .paletteNum = 0x0f, + .baseBlock = 0x0001 + }, { + .priority = 0x00, + .tilemapLeft = 0x06, + .tilemapTop = 0x08, + .width = 0x18, + .height = 0x04, + .paletteNum = 0x0f, + .baseBlock = 0x0062 + }, { + .priority = 0x00, + .tilemapLeft = 0x06, + .tilemapTop = 0x0d, + .width = 0x18, + .height = 0x06, + .paletteNum = 0x0f, + .baseBlock = 0x00c3 + }, DUMMY_WIN_TEMPLATE +}; + +static const struct WindowTemplate *const sHelpDocsWindowTemplatePtrs[3] = { + sHelpDocsWindowTemplates1, + sHelpDocsWindowTemplates2, + sHelpDocsWindowTemplates3 +}; + +static const struct WindowTemplate sNewGameAdventureIntroWindowTemplates[] = { + { + .priority = 0x00, + .tilemapLeft = 0x01, + .tilemapTop = 0x04, + .width = 0x1c, + .height = 0x0f, + .paletteNum = 0x0f, + .baseBlock = 0x0001 + }, { + .priority = 0x00, + .tilemapLeft = 0x12, + .tilemapTop = 0x09, + .width = 0x09, + .height = 0x04, + .paletteNum = 0x0f, + .baseBlock = 0x0174 + }, { + .priority = 0x00, + .tilemapLeft = 0x02, + .tilemapTop = 0x02, + .width = 0x06, + .height = 0x04, + .paletteNum = 0x0f, + .baseBlock = 0x0180 + }, { + .priority = 0x00, + .tilemapLeft = 0x02, + .tilemapTop = 0x02, + .width = 0x0c, + .height = 0x0a, + .paletteNum = 0x0f, + .baseBlock = 0x0001 + }, DUMMY_WIN_TEMPLATE +}; + +ALIGNED(4) const struct TextColor sTextColor_HelpSystem = { + 0x00, 0x01, 0x02 +}; + +ALIGNED(4) const struct TextColor sTextColor_OakSpeech = { + 0x00, 0x02, 0x03 +}; + +static const u8 *const sNewGameAdventureIntroTextPointers[] = { + gNewGameAdventureIntro1, + gNewGameAdventureIntro2, + gNewGameAdventureIntro3 +}; + +static const struct CompressedSpriteSheet sOakSpeech_PikaSpriteSheets[3] = { + { (const void *)sOakSpeechGfx_Pika1, 0x0400, 0x1001 }, + { (const void *)sOakSpeechGfx_Pika2, 0x0200, 0x1002 }, + { (const void *)sOakSpeechGfx_PikaEyes, 0x0080, 0x1003 }, +}; + +static const struct CompressedSpriteSheet sOakSpeech_GrassPlatformSpriteSheet = { + (const void *)sOakSpeechGfx_GrassPlatform, 0x0600, 0x1000 +}; + +static const struct SpritePalette sOakSpeech_PikaSpritePal = { + (const void *)sOakSpeech_PikaPalette, 0x1001 +}; + +static const struct SpritePalette sOakSpeech_GrassPlatformSpritePal = { + (const void *)sOakSpeech_GrassPlatformPalette, 0x1000 +}; + +static const union AnimCmd sGrassPlatformAnim1[] = { + ANIMCMD_FRAME( 0, 0), + ANIMCMD_END +}; + +static const union AnimCmd sGrassPlatformAnim2[] = { + ANIMCMD_FRAME(16, 0), + ANIMCMD_END +}; + +static const union AnimCmd sGrassPlatformAnim3[] = { + ANIMCMD_FRAME(32, 0), + ANIMCMD_END +}; + +static const union AnimCmd *const sGrassPlatformAnims1[] = { + sGrassPlatformAnim1 +}; +static const union AnimCmd *const sGrassPlatformAnims2[] = { + sGrassPlatformAnim2 +}; +static const union AnimCmd *const sGrassPlatformAnims3[] = { + sGrassPlatformAnim3 +}; + +extern const struct OamData gOamData_83ACAF8; + +static const struct SpriteTemplate sOakSpeech_GrassPlatformSpriteTemplates[3] = { + { 0x1000, 0x1000, &gOamData_83ACAF8, sGrassPlatformAnims1, NULL, gDummySpriteAffineAnimTable, SpriteCallbackDummy }, + { 0x1000, 0x1000, &gOamData_83ACAF8, sGrassPlatformAnims2, NULL, gDummySpriteAffineAnimTable, SpriteCallbackDummy }, + { 0x1000, 0x1000, &gOamData_83ACAF8, sGrassPlatformAnims3, NULL, gDummySpriteAffineAnimTable, SpriteCallbackDummy }, +}; + +static const union AnimCmd sPikaAnim1[] = { + ANIMCMD_FRAME( 0, 30), + ANIMCMD_FRAME(16, 30), + ANIMCMD_JUMP(0) +}; + +static const union AnimCmd sPikaAnim2[] = { + ANIMCMD_FRAME(0, 60), + ANIMCMD_FRAME(0, 60), + ANIMCMD_FRAME(0, 60), + ANIMCMD_FRAME(0, 60), + ANIMCMD_FRAME(0, 60), + ANIMCMD_FRAME(0, 60), + ANIMCMD_FRAME(8, 12), + ANIMCMD_FRAME(0, 12), + ANIMCMD_FRAME(8, 12), + ANIMCMD_FRAME(0, 60), + ANIMCMD_FRAME(0, 60), + ANIMCMD_FRAME(0, 60), + ANIMCMD_FRAME(8, 12), + ANIMCMD_FRAME(0, 12), + ANIMCMD_FRAME(8, 12), + ANIMCMD_JUMP(0) +}; + +static const union AnimCmd sPikaAnim3[] = { + ANIMCMD_FRAME(0, 60), + ANIMCMD_FRAME(0, 60), + ANIMCMD_FRAME(0, 60), + ANIMCMD_FRAME(0, 60), + ANIMCMD_FRAME(0, 60), + ANIMCMD_FRAME(2, 8), + ANIMCMD_FRAME(0, 8), + ANIMCMD_FRAME(2, 8), + ANIMCMD_FRAME(0, 60), + ANIMCMD_FRAME(0, 60), + ANIMCMD_FRAME(0, 60), + ANIMCMD_FRAME(2, 8), + ANIMCMD_FRAME(0, 8), + ANIMCMD_FRAME(2, 8), + ANIMCMD_JUMP(0) +}; + +static const union AnimCmd *const sPikaAnims1[] = { + sPikaAnim1 +}; +static const union AnimCmd *const sPikaAnims2[] = { + sPikaAnim2 +}; +static const union AnimCmd *const sPikaAnims3[] = { + sPikaAnim3 +}; + +extern const struct OamData gOamData_83AC9D8; +extern const struct OamData gOamData_83AC9F8; +extern const struct OamData gOamData_83AC9E8; + +static const struct SpriteTemplate sOakSpeech_PikaSpriteTemplates[3] = { + { 0x1001, 0x1001, &gOamData_83AC9D8, sPikaAnims1, NULL, gDummySpriteAffineAnimTable, SpriteCallbackDummy }, + { 0x1002, 0x1001, &gOamData_83AC9F8, sPikaAnims2, NULL, gDummySpriteAffineAnimTable, SpriteCallbackDummy }, + { 0x1003, 0x1001, &gOamData_83AC9E8, sPikaAnims3, NULL, gDummySpriteAffineAnimTable, SpriteCallbackDummy } +}; + +static const u8 *const sHelpDocsPtrs[] = { + gNewGame_HelpDocs2, gNewGame_HelpDocs3, gNewGame_HelpDocs4, + gNewGame_HelpDocs5, gNewGame_HelpDocs6, gNewGame_HelpDocs7 +}; + +static const u8 *const sMaleNameChoices[] = { + gNameChoice_Red, + gNameChoice_Fire, + gNameChoice_Ash, + gNameChoice_Kene, + gNameChoice_Geki, + gNameChoice_Jak, + gNameChoice_Janne, + gNameChoice_Jonn, + gNameChoice_Kamon, + gNameChoice_Karl, + gNameChoice_Taylor, + gNameChoice_Oscar, + gNameChoice_Hiro, + gNameChoice_Max, + gNameChoice_Jon, + gNameChoice_Ralph, + gNameChoice_Kay, + gNameChoice_Tosh, + gNameChoice_Roak +}; + +static const u8 *const sFemaleNameChoices[] = { + gNameChoice_Red, + gNameChoice_Fire, + gNameChoice_Omi, + gNameChoice_Jodi, + gNameChoice_Amanda, + gNameChoice_Hillary, + gNameChoice_Makey, + gNameChoice_Michi, + gNameChoice_Paula, + gNameChoice_June, + gNameChoice_Cassie, + gNameChoice_Rey, + gNameChoice_Seda, + gNameChoice_Kiko, + gNameChoice_Mina, + gNameChoice_Norie, + gNameChoice_Sai, + gNameChoice_Momo, + gNameChoice_Suzi +}; + +static const u8 *const sRivalNameChoices[] = { + gNameChoice_Green, + gNameChoice_Gary, + gNameChoice_Kaz, + gNameChoice_Toru +}; + +static void VBlankCB_NewGameOaksSpeech(void) +{ + LoadOam(); + ProcessSpriteCopyRequests(); + TransferPlttBuffer(); +} + +static void CB2_NewGameOaksSpeech(void) +{ + RunTasks(); + RunTextPrinters(); + AnimateSprites(); + BuildOamBuffer(); + UpdatePaletteFade(); +} + +void StartNewGameScene(void) +{ + gPlttBufferUnfaded[0] = RGB_BLACK; + gPlttBufferFaded[0] = RGB_BLACK; + CreateTask(Task_OaksSpeech1, 0); + SetMainCallback2(CB2_NewGameOaksSpeech); +} + +static void Task_OaksSpeech1(u8 taskId) +{ + switch (gMain.state) + { + case 0: + SetVBlankCallback(NULL); + SetHBlankCallback(NULL); + DmaFill16(3, 0, VRAM, VRAM_SIZE); + DmaFill32(3, 0, OAM, OAM_SIZE); + DmaFill16(3, 0, PLTT + sizeof(u16), PLTT_SIZE - 2); + ResetPaletteFade(); + ScanlineEffect_Stop(); + ResetSpriteData(); + FreeAllSpritePalettes(); + reset_temp_tile_data_buffers(); + HelpSystem_SetSomeVariable2(2); + break; + case 1: + sOakSpeechResources = AllocZeroed(sizeof(*sOakSpeechResources)); + SetUpMonSpriteManagerMaybe(1, 1); + break; + case 2: + SetGpuReg(REG_OFFSET_WIN0H, 0); + SetGpuReg(REG_OFFSET_WIN0V, 0); + SetGpuReg(REG_OFFSET_WIN1H, 0); + SetGpuReg(REG_OFFSET_WIN1V, 0); + SetGpuReg(REG_OFFSET_WININ, 0); + SetGpuReg(REG_OFFSET_WINOUT, 0); + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + SetGpuReg(REG_OFFSET_BLDY, 0); + break; + case 3: + ResetBgsAndClearDma3BusyFlags(0); + InitBgsFromTemplates(1, sBgTemplates, NELEMS(sBgTemplates)); + SetBgTilemapBuffer(1, sOakSpeechResources->bg1TilemapBuffer); + SetBgTilemapBuffer(2, sOakSpeechResources->bg2TilemapBuffer); + ChangeBgX(1, 0, 0); + ChangeBgY(1, 0, 0); + ChangeBgX(2, 0, 0); + ChangeBgY(2, 0, 0); + gSpriteCoordOffsetX = 0; + gSpriteCoordOffsetY = 0; + break; + case 4: + gPaletteFade.bufferTransferDisabled = TRUE; + InitStandardTextBoxWindows(); + ResetBg0(); + Menu_LoadStdPalAt(0xD0); + LoadPalette(sHelpDocsPalette, 0x000, 0x080); + LoadPalette(stdpal_get(2) + 15, 0x000, 0x002); + break; + case 5: + sOakSpeechResources->textSpeed = GetTextSpeedSetting(); + gTextFlags.flag_0 = TRUE; + decompress_and_copy_tile_data_to_vram(1, sOakSpeechGfx_GameStartHelpUI, 0, 0, 0); + break; + case 6: + if (free_temp_tile_data_buffers_if_possible()) + return; + ClearDialogWindowAndFrame(0, 1); + FillBgTilemapBufferRect_Palette0(1, 0x0000, 0, 0, 32, 32); + CopyBgTilemapBufferToVram(1); + break; + case 7: + CreateWindow_SnapRight_StdPal(0, 30, 0, 13, 0x1C4); + FillBgTilemapBufferRect_Palette0(1, 0xD00F, 0, 0, 30, 2); + FillBgTilemapBufferRect_Palette0(1, 0xD002, 0, 2, 30, 1); + FillBgTilemapBufferRect_Palette0(1, 0xD00E, 0, 19, 30, 1); + CreateHelpDocsPage1(); + gPaletteFade.bufferTransferDisabled = FALSE; + gTasks[taskId].data[5] = CreateTextCursorSpriteForOakSpeech(0, 0xE6, 0x95, 0, 0); + BlendPalettes(0xFFFFFFFF, 0x10, 0x00); + break; + case 10: + BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, RGB_BLACK); + SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_OBJ_ON); + ShowBg(0); + ShowBg(1); + SetVBlankCallback(VBlankCB_NewGameOaksSpeech); + PlayBGM(BGM_FRLG_GAME_EXPLANATION_START); + gTasks[taskId].func = Task_OaksSpeech2; + gMain.state = 0; + return; + } + + gMain.state++; +} + +static void CreateHelpDocsPage1(void) +{ + Menu_PrintHelpSystemUIHeader(gText_Controls, gText_ABUTTONNext, 0, 0, 1); + sOakSpeechResources->unk_0014[0] = AddWindow(sHelpDocsWindowTemplatePtrs[sOakSpeechResources->unk_0012]); + PutWindowTilemap(sOakSpeechResources->unk_0014[0]); + FillWindowPixelBuffer(sOakSpeechResources->unk_0014[0], 0x00); + AddTextPrinterParametrized2(sOakSpeechResources->unk_0014[0], 2, 2, 0, 1, 1, &sTextColor_HelpSystem, 0, gNewGame_HelpDocs1); + CopyWindowToVram(sOakSpeechResources->unk_0014[0], 3); + FillBgTilemapBufferRect_Palette0(1, 0x3000, 1, 3, 5, 16); + CopyBgTilemapBufferToVram(1); +} + +static void Task_OakSpeech4(u8 taskId) +{ + u8 i = 0; + u8 r7 = sOakSpeechResources->unk_0012 - 1; + if (sOakSpeechResources->unk_0012 == 0) + { + CreateHelpDocsPage1(); + } + else + { + PrintTextOnRightSnappedWindow(gText_ABUTTONNext_BBUTTONBack, 0, 1); + for (i = 0; i < 3; i++) + { + sOakSpeechResources->unk_0014[i] = AddWindow(&sHelpDocsWindowTemplatePtrs[sOakSpeechResources->unk_0012][i]); + PutWindowTilemap(sOakSpeechResources->unk_0014[i]); + FillWindowPixelBuffer(sOakSpeechResources->unk_0014[i], 0x00); + AddTextPrinterParametrized2(sOakSpeechResources->unk_0014[i], 2, 6, 0, 1, 1, &sTextColor_HelpSystem, 0, sHelpDocsPtrs[i + r7 * 3]); + CopyWindowToVram(sOakSpeechResources->unk_0014[i], 3); + } + + if (sOakSpeechResources->unk_0012 == 1) + { + CopyToBgTilemapBufferRect(1, sHelpDocsPage2Tilemap, 1, 3, 5, 16); + } + else + { + CopyToBgTilemapBufferRect(1, sHelpDocsPage3Tilemap, 1, 3, 5, 16); + } + CopyBgTilemapBufferToVram(1); + } + BeginNormalPaletteFade(0xFFFFDFFF, -1, 16, 0, stdpal_get(2)[15]); + gTasks[taskId].func = Task_OaksSpeech2; +} + +static void Task_OaksSpeech2(u8 taskId) +{ + if (!gPaletteFade.active && JOY_NEW((A_BUTTON | B_BUTTON))) + { + if (JOY_NEW(A_BUTTON)) + { + gTasks[taskId].data[15] = 1; + if (sOakSpeechResources->unk_0012 < 2) + { + BeginNormalPaletteFade(0xFFFFDFFF, -1, 0, 16, stdpal_get(2)[15]); + } + } + else + { + if (sOakSpeechResources->unk_0012 != 0) + { + gTasks[taskId].data[15] = -1; + BeginNormalPaletteFade(0xFFFFDFFF, -1, 0, 16, stdpal_get(2)[15]); + } + else + return; + } + } + else + return; + PlaySE(SE_SELECT); + gTasks[taskId].func = Task_OakSpeech3; +} + +static void Task_OakSpeech3(u8 taskId) +{ + u8 r8 = 0; + u8 i; + + if (!gPaletteFade.active) + { + switch (sOakSpeechResources->unk_0012) { + case 0: + r8 = 1; + break; + case 1: + case 2: + r8 = 3; + break; + } + sOakSpeechResources->unk_0012 += gTasks[taskId].data[15]; + if (sOakSpeechResources->unk_0012 < 3) + { + for (i = 0; i < r8; i++) + { + FillWindowPixelBuffer(sOakSpeechResources->unk_0014[i], 0x00); + ClearWindowTilemap(sOakSpeechResources->unk_0014[i]); + CopyWindowToVram(sOakSpeechResources->unk_0014[i], 3); + RemoveWindow(sOakSpeechResources->unk_0014[i]); + sOakSpeechResources->unk_0014[i] = 0; + } + gTasks[taskId].func = Task_OakSpeech4; + } + else + { + BeginNormalPaletteFade(0xFFFFFFFF, 2, 0, 16, 0); + gTasks[taskId].func = Task_OakSpeech5; + } + } +} + +static void Task_OakSpeech5(u8 taskId) +{ + u8 i = 0; + + if (!gPaletteFade.active) + { + for (i = 0; i < 3; i++) + { + FillWindowPixelBuffer(sOakSpeechResources->unk_0014[i], 0x00); + ClearWindowTilemap(sOakSpeechResources->unk_0014[i]); + CopyWindowToVram(sOakSpeechResources->unk_0014[i], 3); + RemoveWindow(sOakSpeechResources->unk_0014[i]); + sOakSpeechResources->unk_0014[i] = 0; + } + FillBgTilemapBufferRect_Palette0(1, 0x000, 0, 2, 30, 18); + CopyBgTilemapBufferToVram(1); + sub_8006398(gTasks[taskId].data[5]); + sOakSpeechResources->unk_0014[0] = RGB_BLACK; + LoadPalette(sOakSpeechResources->unk_0014, 0, 2); + gTasks[taskId].data[3] = 32; + gTasks[taskId].func = Task_OakSpeech6; + } +} + +static void Task_OakSpeech6(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + u32 sp14 = 0; + + if (data[3] != 0) + data[3]--; + else + { + PlayBGM(BGM_FRLG_GAME_EXPLANATION_MIDDLE); + sub_810F71C(); + PrintTextOnRightSnappedWindow(gText_ABUTTONNext, 0, 1); + sOakSpeechResources->unk_0008 = malloc_and_decompress(sNewGameAdventureIntroTilemap, &sp14); + CopyToBgTilemapBufferRect(1, sOakSpeechResources->unk_0008, 0, 2, 30, 19); + CopyBgTilemapBufferToVram(1); + Free(sOakSpeechResources->unk_0008); + sOakSpeechResources->unk_0008 = NULL; + data[14] = AddWindow(&sNewGameAdventureIntroWindowTemplates[0]); + PutWindowTilemap(data[14]); + FillWindowPixelBuffer(data[14], 0x00); + CopyWindowToVram(data[14], 3); + sOakSpeechResources->unk_0012 = 0; + gMain.state = 0; + data[15] = 16; + AddTextPrinterParametrized2(data[14], 2, 3, 5, 1, 0, &sTextColor_OakSpeech, 0, sNewGameAdventureIntroTextPointers[0]); + data[5] = CreateTextCursorSpriteForOakSpeech(0, 0xe2, 0x91, 0, 0); + gSprites[data[5]].oam.objMode = ST_OAM_OBJ_BLEND; + gSprites[data[5]].oam.priority = 0; + CreatePikaOrGrassPlatformSpriteAndLinkToCurrentTask(taskId, 0); + BeginNormalPaletteFade(0xFFFFFFFF, 2, 16, 0, 0); + gTasks[taskId].func = Task_OakSpeech7; + } +} + +static void Task_OakSpeech7(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + switch (gMain.state) + { + case 0: + if (!gPaletteFade.active) + { + SetGpuReg(REG_OFFSET_WIN0H, 0x00F0); + SetGpuReg(REG_OFFSET_WIN0V, 0x10A0); + SetGpuReg(REG_OFFSET_WININ, 0x003F); + SetGpuReg(REG_OFFSET_WINOUT, 0x001F); + SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON); + gMain.state = 1; + } + break; + case 1: + if (JOY_NEW((A_BUTTON | B_BUTTON))) + { + if (JOY_NEW(A_BUTTON)) + { + sOakSpeechResources->unk_0012++; + } + else if (sOakSpeechResources->unk_0012 != 0) + { + sOakSpeechResources->unk_0012--; + } + else + { + break; + } + PlaySE(SE_SELECT); + if (sOakSpeechResources->unk_0012 == 3) + { + gMain.state = 4; + } + else + { + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG0 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_BG1); + SetGpuReg(REG_OFFSET_BLDALPHA, (16 - data[15]) | data[15]); + gMain.state++; + } + } + break; + case 2: + data[15] -= 2; + SetGpuReg(REG_OFFSET_BLDALPHA, ((16 - data[15]) << 8) | data[15]); + if (data[15] <= 0) + { + FillWindowPixelBuffer(data[14], 0x00); + AddTextPrinterParametrized2(data[14], 2, 3, 5, 1, 0, &sTextColor_OakSpeech, 0, sNewGameAdventureIntroTextPointers[sOakSpeechResources->unk_0012]); + if (sOakSpeechResources->unk_0012 == 0) + { + sub_810F71C(); + PrintTextOnRightSnappedWindow(gText_ABUTTONNext, 0, 1); + } + else + { + sub_810F71C(); + PrintTextOnRightSnappedWindow(gText_ABUTTONNext_BBUTTONBack, 0, 1); + } + gMain.state++; + } + break; + case 3: + data[15] += 2; + SetGpuReg(REG_OFFSET_BLDALPHA, ((16 - data[15]) << 8) | data[15]); + if (data[15] >= 16) + { + data[15] = 16; + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + gMain.state = 1; + } + break; + case 4: + sub_8006398(gTasks[taskId].data[5]); + PlayBGM(BGM_FRLG_GAME_EXPLANATION_END); + data[15] = 24; + gMain.state++; + break; + default: + if (data[15] != 0) + data[15]--; + else + { + gMain.state = 0; + sOakSpeechResources->unk_0012 = 0; + SetGpuReg(REG_OFFSET_WIN0H, 0); + SetGpuReg(REG_OFFSET_WIN0V, 0); + SetGpuReg(REG_OFFSET_WININ, 0); + SetGpuReg(REG_OFFSET_WINOUT, 0); + ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON); + BeginNormalPaletteFade(0xFFFFFFFF, 2, 0, 16, RGB_BLACK); + gTasks[taskId].func = Task_OakSpeech8; + } + break; + } +} + +static void Task_OakSpeech8(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + if (!gPaletteFade.active) + { + sub_810F740(); + FillWindowPixelBuffer(data[14], 0x00); + ClearWindowTilemap(data[14]); + CopyWindowToVram(data[14], 3); + RemoveWindow(data[14]); + data[14] = 0; + FillBgTilemapBufferRect_Palette0(1, 0x000, 0, 0, 30, 20); + CopyBgTilemapBufferToVram(1); + DestroyLinkedPikaOrGrassPlatformSprites(taskId, 0); + data[3] = 80; + gTasks[taskId].func = Task_OakSpeech9; + } +} + +static void Task_OakSpeech9(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + u32 size = 0; + + if (data[3] != 0) + data[3]--; + else + { + sOakSpeechResources->solidColorsGfx = malloc_and_decompress(sOakSpeechGfx_SolidColors, &size); + LoadBgTiles(1, sOakSpeechResources->solidColorsGfx, size, 0); + CopyToBgTilemapBuffer(1, sOakSpeech_BackgroundTilemap, 0, 0); + CopyBgTilemapBufferToVram(1); + CreateNidoranFSprite(taskId); + LoadOaksSpeechTrainerPic(3, 0); + CreatePikaOrGrassPlatformSpriteAndLinkToCurrentTask(taskId, 1); + PlayBGM(BGM_FRLG_ROUTE_24); + BeginNormalPaletteFade(0xFFFFFFFF, 5, 16, 0, RGB_BLACK); + data[3] = 80; + ShowBg(2); + gTasks[taskId].func = Task_OakSpeech10; + } +} + +#define OaksSpeechPrintMessage(str, speed) ({ \ + DrawDialogueFrame(0, FALSE);\ + if (str != gStringVar4) \ + { \ + StringExpandPlaceholders(gStringVar4, str); \ + AddTextPrinterParametrized(0, 4, gStringVar4, speed, NULL, 2, 1, 3); \ + } \ + else \ + { \ + AddTextPrinterParametrized(0, 4, str, speed, NULL, 2, 1, 3); \ + } \ + CopyWindowToVram(0, 3); \ +}) + +static void Task_OakSpeech10(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + if (!gPaletteFade.active) + { + if (data[3] != 0) + data[3]--; + else + { + OaksSpeechPrintMessage(gOakText_WelcomeToTheWorld, sOakSpeechResources->textSpeed); + gTasks[taskId].func = Task_OakSpeech11; + } + } +} + +static void Task_OakSpeech11(u8 taskId) +{ + if (!IsTextPrinterActive(0)) + { + OaksSpeechPrintMessage(gOakText_WorldInhabited1, sOakSpeechResources->textSpeed); + gTasks[taskId].data[3] = 30; + gTasks[taskId].func = Task_OakSpeech12; + } +} + +static void Task_OakSpeech12(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + u8 spriteId; + + if (!IsTextPrinterActive(0)) + { + if (data[3] != 0) + data[3]--; + // else { + spriteId = gTasks[taskId].data[4]; + gSprites[spriteId].invisible = FALSE; + gSprites[spriteId].data[0] = 0; + CreatePokeballSpriteToReleaseMon(spriteId, gSprites[spriteId].oam.paletteNum, 0x64, 0x42, 0, 0, 32, 0xFFFF1FFF); + gTasks[taskId].func = Task_OakSpeech13; + gTasks[taskId].data[3] = 0; + // } + } +} + +static void Task_OakSpeech13(u8 taskId) +{ + if (IsCryFinished()) + { + if (gTasks[taskId].data[3] >= 96) + gTasks[taskId].func = Task_OakSpeech14; + } + if (gTasks[taskId].data[3] < 0x4000) + { + gTasks[taskId].data[3]++; + if (gTasks[taskId].data[3] == 32) + { + OaksSpeechPrintMessage(gOakText_WorldInhabited2, sOakSpeechResources->textSpeed); + PlayCry1(SPECIES_NIDORAN_F, 0); + } + } +} + +static void Task_OakSpeech14(u8 taskId) +{ + if (!IsTextPrinterActive(0)) + { + OaksSpeechPrintMessage(gOakText_PetsBattlingStudy, sOakSpeechResources->textSpeed); + gTasks[taskId].func = Task_OakSpeech15; + } +} + +static void Task_OakSpeech15(u8 taskId) +{ + u8 spriteId; + + if (!IsTextPrinterActive(0)) + { + ClearDialogWindowAndFrame(0, 1); + spriteId = gTasks[taskId].data[4]; + gTasks[taskId].data[6] = sub_804BB98(spriteId, gSprites[spriteId].oam.paletteNum, 0x64, 0x42, 0, 0, 32, 0xFFFF1F3F); + gTasks[taskId].data[3] = 48; + gTasks[taskId].data[0] = 64; + gTasks[taskId].func = Task_OakSpeech16; + } +} + +static void Task_OakSpeech16(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + if (data[0] != 0) + { + if (data[0] < 24) + { + gSprites[data[4]].pos1.y--; + } + data[0]--; + } + else + { + if (data[3] == 48) + { + DestroySprite(&gSprites[data[4]]); + DestroySprite(&gSprites[data[6]]); + } + if (data[3] != 0) + { + data[3]--; + } + else + { + OaksSpeechPrintMessage(gOakText_TellMeALittleAboutYourself, sOakSpeechResources->textSpeed); + gTasks[taskId].func = Task_OakSpeech17; + } + } +} + +static void Task_OakSpeech17(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + if (!IsTextPrinterActive(0)) + { + ClearDialogWindowAndFrame(0, 1); + CreateFadeInTask(taskId, 2); + data[3] = 48; + gTasks[taskId].func = Task_OakSpeech18; + } +} + +static void Task_OakSpeech18(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + if (data[2] != 0) + { + if (data[3] != 0) + data[3]--; + else + { + data[1] = -60; + DestroyOaksSpeechTrainerPic(); + OaksSpeechPrintMessage(gOakText_AskPlayerGender, sOakSpeechResources->textSpeed); + gTasks[taskId].func = Task_OakSpeech19; + } + } +} + +static void Task_OakSpeech19(u8 taskId) +{ + if (!IsTextPrinterActive(0)) + { + gTasks[taskId].data[13] = AddWindow(&sNewGameAdventureIntroWindowTemplates[1]); + PutWindowTilemap(gTasks[taskId].data[13]); + SetWindowBorderStyle(gTasks[taskId].data[13], 1, sub_80F796C(), 14); + FillWindowPixelBuffer(gTasks[taskId].data[13], 0x11); + sOakSpeechResources->unk_001C[0] = 1; + sOakSpeechResources->unk_001C[1] = 2; + sOakSpeechResources->unk_001C[2] = 3; + box_print(gTasks[taskId].data[13], 2, 8, 1, sOakSpeechResources->unk_001C, 0, gText_Boy); + sOakSpeechResources->unk_001C[0] = 1; + sOakSpeechResources->unk_001C[1] = 2; + sOakSpeechResources->unk_001C[2] = 3; + box_print(gTasks[taskId].data[13], 2, 8, 17, sOakSpeechResources->unk_001C, 0, gText_Girl); + ProgramAndPlaceMenuCursorOnWindow(gTasks[taskId].data[13], 2, 0, 1, GetFontAttribute(2, 1) + 2, 2, 0); + CopyWindowToVram(gTasks[taskId].data[13], 3); + gTasks[taskId].func = Task_OakSpeech20; + } +} + +static void Task_OakSpeech20(u8 taskId) +{ + s8 input = ProcessMenuInputNoWrapAround(); + switch (input) + { + case 0: + gSaveBlock2Ptr->playerGender = MALE; + break; + case 1: + gSaveBlock2Ptr->playerGender = FEMALE; + break; + case -1: + case -2: + return; + } + gTasks[taskId].func = Task_OakSpeech21; + +} + +static void Task_OakSpeech21(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + sub_810F4D8(data[13], 1); + RemoveWindow(data[13]); + data[13] = 0; + ClearDialogWindowAndFrame(0, 1); + FillBgTilemapBufferRect_Palette0(0, 0, 0, 0, 30, 20); + CopyBgTilemapBufferToVram(0); + gTasks[taskId].func = Task_OakSpeech22; +} + +static void Task_OakSpeech22(u8 taskId) +{ + if (gSaveBlock2Ptr->playerGender == MALE) + LoadOaksSpeechTrainerPic(MALE, 0); + else + LoadOaksSpeechTrainerPic(FEMALE, 0); + CreateFadeOutTask(taskId, 2); + gTasks[taskId].data[3] = 32; + gTasks[taskId].func = Task_OakSpeech23; +} + +static void Task_OakSpeech23(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + if (data[2] != 0) + { + if (data[3] != 0) + data[3]--; + else + { + data[1] = 0; + OaksSpeechPrintMessage(gOakText_AskPlayerName, sOakSpeechResources->textSpeed); + gTasks[taskId].func = Task_OakSpeech24; + } + } +} + +static void Task_OakSpeech24(u8 taskId) +{ + if (!IsTextPrinterActive(0)) + { + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_BLACK); + sOakSpeechResources->unk_0010 = 0; + gTasks[taskId].func = Task_OakSpeech25; + } +} +static void Task_OakSpeech35(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + if (!IsTextPrinterActive(0)) + { + if (data[1] > -60) + { + data[1] -= 2; + gSpriteCoordOffsetX += 2; + ChangeBgX(2, 0x200, 2); + } + else + { + data[1] = -60; + PrintNameChoiceOptions(taskId, sOakSpeechResources->unk_0010); + gTasks[taskId].func = Task_OakSpeech29; + } + } +} + +static void Task_OakSpeech28(u8 taskId) +{ + PrintNameChoiceOptions(taskId, sOakSpeechResources->unk_0010); + if (sOakSpeechResources->unk_0010 == 0) + { + OaksSpeechPrintMessage(gOakText_AskPlayerName, 0); + } + else + { + OaksSpeechPrintMessage(gOakText_AskRivalName, 0); + } + gTasks[taskId].func = Task_OakSpeech29; +} + +static void Task_OakSpeech29(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + s8 input = ProcessMenuInput(); + switch (input) + { + case 1: + case 2: + case 3: + case 4: + PlaySE(SE_SELECT); + sub_810F4D8(data[13], TRUE); + RemoveWindow(data[13]); + GetDefaultName(sOakSpeechResources->unk_0010, input - 1); + data[15] = 1; + gTasks[taskId].func = Task_OakSpeech26; + break; + case 0: + PlaySE(SE_SELECT); + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, 0); + gTasks[taskId].func = Task_OakSpeech25; + break; + case -1: + break; + } +} + +static void Task_OakSpeech25(u8 taskId) +{ + if (!gPaletteFade.active) + { + GetDefaultName(sOakSpeechResources->unk_0010, 0); + if (sOakSpeechResources->unk_0010 == 0) + { + DoNamingScreen(0, gSaveBlock2Ptr->playerName, gSaveBlock2Ptr->playerGender, 0, 0, CB2_ReturnFromNamingScreen); + } + else + { + sub_810F4D8(gTasks[taskId].data[13], 1); + RemoveWindow(gTasks[taskId].data[13]); + DoNamingScreen(4, gSaveBlock1Ptr->rivalName, 0, 0, 0, CB2_ReturnFromNamingScreen); + } + DestroyLinkedPikaOrGrassPlatformSprites(taskId, 1); + FreeAllWindowBuffers(); + } +} + +static void Task_OakSpeech26(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + if (!gPaletteFade.active) + { + if (data[15] == 1) + { + if (sOakSpeechResources->unk_0010 == 0) + { + StringExpandPlaceholders(gStringVar4, gOakText_FinalizePlayerName); + } + else + { + StringExpandPlaceholders(gStringVar4, gOakText_ConfirmRivalName); + } + OaksSpeechPrintMessage(gStringVar4, sOakSpeechResources->textSpeed); + data[15] = 0; + data[3] = 25; + } + else if (!IsTextPrinterActive(0)) + { + if (data[3] != 0) + data[3]--; + else + { + sub_810FF60(&sNewGameAdventureIntroWindowTemplates[2], 2, 0, 2, sub_80F796C(), 14, 0); + gTasks[taskId].func = Task_OakSpeech27; + } + } + } +} + +static void Task_OakSpeech27(u8 taskId) +{ + s8 input = ProcessMenuInputNoWrap_(); + switch (input) + { + case 0: + PlaySE(SE_SELECT); + gTasks[taskId].data[3] = 40; + if (sOakSpeechResources->unk_0010 == 0) + { + ClearDialogWindowAndFrame(0, 1); + CreateFadeInTask(taskId, 2); + gTasks[taskId].func = Task_OakSpeech30; + } + else + { + StringExpandPlaceholders(gStringVar4, gOakText_RememberRivalName); + OaksSpeechPrintMessage(gStringVar4, sOakSpeechResources->textSpeed); + gTasks[taskId].func = Task_OakSpeech31; + } + break; + case 1: + case -1: + PlaySE(SE_SELECT); + if (sOakSpeechResources->unk_0010 == 0) + gTasks[taskId].func = Task_OakSpeech24; + else + gTasks[taskId].func = Task_OakSpeech28; + break; + } +} + +static void Task_OakSpeech30(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + if (data[2] != 0) + { + DestroyOaksSpeechTrainerPic(); + if (data[3] != 0) + data[3]--; + else + gTasks[taskId].func = Task_OakSpeech32; + } +} + +static void Task_OakSpeech31(u8 taskId) +{ + if (!IsTextPrinterActive(0)) + { + ClearDialogWindowAndFrame(0, 1); + CreateFadeInTask(taskId, 2); + gTasks[taskId].func = Task_OakSpeech33; + } +} + +static void Task_OakSpeech32(u8 taskId) +{ + ChangeBgX(2, 0, 0); + gTasks[taskId].data[1] = 0; + gSpriteCoordOffsetX = 0; + LoadOaksSpeechTrainerPic(2, 0); + CreateFadeOutTask(taskId, 2); + gTasks[taskId].func = Task_OakSpeech34; +} + +static void Task_OakSpeech34(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + if (data[2] != 0) + { + OaksSpeechPrintMessage(gOakText_IntroduceRival, sOakSpeechResources->textSpeed); + sOakSpeechResources->unk_0010 = 1; + gTasks[taskId].func = Task_OakSpeech35; + } +} + +static void Task_OakSpeech33(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + if (data[2] != 0) + { + DestroyOaksSpeechTrainerPic(); + if (data[3] != 0) + data[3]--; + else + { + if (gSaveBlock2Ptr->playerGender == MALE) + LoadOaksSpeechTrainerPic(MALE, 0); + else + LoadOaksSpeechTrainerPic(FEMALE, 0); + gTasks[taskId].data[1] = 0; + gSpriteCoordOffsetX = 0; + ChangeBgX(2, 0, 0); + CreateFadeOutTask(taskId, 2); + gTasks[taskId].func = Task_OakSpeech36; + } + } +} + +static void Task_OakSpeech36(u8 taskId) +{ + if (gTasks[taskId].data[2] != 0) + { + StringExpandPlaceholders(gStringVar4, gOakText_LegendAboutToUnfold); + OaksSpeechPrintMessage(gStringVar4, sOakSpeechResources->textSpeed); + gTasks[taskId].data[3] = 30; + gTasks[taskId].func = Task_OakSpeech37; + } +} + +static void Task_OakSpeech37(u8 taskId) +{ + if (!IsTextPrinterActive(0)) + { + if (gTasks[taskId].data[3] != 0) + gTasks[taskId].data[3]--; + else + { + FadeOutBGM(4); + gTasks[taskId].func = Task_OakSpeech38; + } + } +} + +static void Task_OakSpeech38(u8 taskId) +{ + sOakSpeechResources->unk_0012 = 0; + Task_OakSpeech38_1(taskId); + Task_OakSpeech38_2(taskId); + Task_OakSpeech38_3(taskId); +} + +static void Task_OakSpeech38_3(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + SetBgAttribute(2, 6, 1); + data[0] = 0; + data[1] = 0; + data[2] = 256; + data[15] = 0; + gTasks[taskId].func = Task_OakSpeech39; +} + +static void Task_OakSpeech39(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + s16 x, y; + u16 r0; + + sOakSpeechResources->unk_0012++; + if (sOakSpeechResources->unk_0012 % 20 == 0) + { + if (sOakSpeechResources->unk_0012 == 40) + PlaySE(SE_FU_ZUZUZU); + r0 = data[2]; + data[2] -= 32; + x = sub_80D8B90(r0 - 8); + y = sub_80D8B90(data[2] - 16); + SetBgAffine(2, 0x7800, 0x5400, 0x78, 0x54, x, y, 0); + if (data[2] <= 96) + { + data[15] = 1; + data[0] = 36; + gTasks[taskId].func = Task_OakSpeech40; + } + } +} + +static void Task_OakSpeech38_1(u8 taskId) +{ + u8 taskId2 = CreateTask(Task_OakSpeech38_sub1, 1); + s16 * data = gTasks[taskId2].data; + data[0] = 0; + data[1] = 0; + data[2] = 0; + data[15] = 0; + BeginNormalPaletteFade(0xFFFF0FCF, 4, 0, 16, RGB_BLACK); +} + +static void Task_OakSpeech38_sub1(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + if (!gPaletteFade.active) + { + if (data[1] != 0) + { + DestroyTask(taskId); + DestroyLinkedPikaOrGrassPlatformSprites(taskId, 1); + } + else + { + data[1]++; + BeginNormalPaletteFade(0x0000F000, 0, 0, 16, RGB_BLACK); + } + } +} + +static void Task_OakSpeech38_2(u8 taskId) +{ + u8 taskId2 = CreateTask(Task_OakSpeech38_sub2, 2); + s16 * data = gTasks[taskId2].data; + data[0] = 8; + data[1] = 0; + data[2] = 8; + data[14] = 0; + data[15] = 0; +} + +static void Task_OakSpeech38_sub2(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + u8 i; + + if (data[0] != 0) + data[0]--; + else + { + if (data[1] <= 0 && data[2] != 0) + data[2]--; + BlendPalette(0x40, 0x20, data[14], RGB_WHITE); + data[14]++; + data[1]--; + data[0] = data[2]; + if (data[14] > 14) + { + for (i = 0; i < 32; i++) + { + gPlttBufferFaded[i + 0x40] = RGB_WHITE; + gPlttBufferUnfaded[i + 0x40] = RGB_WHITE; + } + DestroyTask(taskId); + } + } +} + +static void Task_OakSpeech40(u8 taskId) +{ + if (gTasks[taskId].data[0] != 0) + gTasks[taskId].data[0]--; + else + { + BeginNormalPaletteFade(0x00000030, 2, 0, 16, RGB_BLACK); + gTasks[taskId].func = Task_OakSpeech41; + } +} + +static void Task_OakSpeech41(u8 taskId) +{ + if (!gPaletteFade.active) + { + gTasks[taskId].func = Task_OakSpeech42; + } +} + +static void Task_OakSpeech42(u8 taskId) +{ + FreeAllWindowBuffers(); + sub_8044D80(); + Free(sOakSpeechResources); + sOakSpeechResources = NULL; + gTextFlags.flag_0 = FALSE; + SetMainCallback2(CB2_NewGame); + DestroyTask(taskId); +} + +static void CB2_ReturnFromNamingScreen(void) +{ + u8 taskId; + + switch (gMain.state) + { + case 0: + SetVBlankCallback(NULL); + DmaFill16(3, 0, VRAM, VRAM_SIZE); + DmaFill32(3, 0, OAM, OAM_SIZE); + DmaFill16(3, RGB_BLACK, PLTT + sizeof(u16), PLTT_SIZE - sizeof(u16)); + ResetPaletteFade(); + ScanlineEffect_Stop(); + ResetSpriteData(); + FreeAllSpritePalettes(); + reset_temp_tile_data_buffers(); + break; + case 1: + ResetBgsAndClearDma3BusyFlags(0); + InitBgsFromTemplates(1, sBgTemplates, NELEMS(sBgTemplates)); + SetBgTilemapBuffer(1, sOakSpeechResources->bg1TilemapBuffer); + SetBgTilemapBuffer(2, sOakSpeechResources->bg2TilemapBuffer); + ChangeBgX(1, 0, 0); + ChangeBgY(1, 0, 0); + ChangeBgX(2, 0, 0); + ChangeBgY(2, 0, 0); + break; + case 2: + SetGpuReg(REG_OFFSET_WIN0H, 0); + SetGpuReg(REG_OFFSET_WIN0V, 0); + SetGpuReg(REG_OFFSET_WININ, 0); + SetGpuReg(REG_OFFSET_WINOUT, 0); + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + SetGpuReg(REG_OFFSET_BLDY, 0); + break; + case 3: + FreeAllWindowBuffers(); + InitStandardTextBoxWindows(); + ResetBg0(); + LoadPalette(sHelpDocsPalette, 0, 0xe0); + break; + case 4: + decompress_and_copy_tile_data_to_vram(1, sOakSpeechGfx_SolidColors, 0, 0, 0); + break; + case 5: + if (free_temp_tile_data_buffers_if_possible()) + return; + FillBgTilemapBufferRect_Palette0(1, 0x000, 0, 0, 30, 20); + CopyToBgTilemapBuffer(1, sOakSpeech_BackgroundTilemap, 0, 0); + FillBgTilemapBufferRect_Palette0(2, 0x000, 0, 0, 30, 20); + CopyBgTilemapBufferToVram(1); + CopyBgTilemapBufferToVram(2); + break; + case 6: + taskId = CreateTask(Task_OakSpeech26, 0); + if (sOakSpeechResources->unk_0010 == 0) + { + if (gSaveBlock2Ptr->playerGender == MALE) + LoadOaksSpeechTrainerPic(MALE, 0); + else + LoadOaksSpeechTrainerPic(FEMALE, 0); + } + else + LoadOaksSpeechTrainerPic(2, 0); + gTasks[taskId].data[1] = -60; + gSpriteCoordOffsetX += 60; + ChangeBgX(2, -0x3C00, 0); + CreatePikaOrGrassPlatformSpriteAndLinkToCurrentTask(taskId, 1); + gTasks[taskId].data[15] = 1; + break; + case 7: + BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, RGB_BLACK); + SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_1D_MAP | DISPCNT_OBJ_ON); + ShowBg(0); + ShowBg(1); + ShowBg(2); + EnableInterrupts(INTR_FLAG_VBLANK); + SetVBlankCallback(VBlankCB_NewGameOaksSpeech); + gTextFlags.flag_0 = TRUE; + SetMainCallback2(CB2_NewGameOaksSpeech); + return; + } + + gMain.state++; +} + +static void CreateNidoranFSprite(u8 taskId) +{ + u8 spriteId; + + DecompressPicFromTable(gUnknown_8235194, sub_8044E00(0), SPECIES_NIDORAN_F); + sub_800F078(&gUnknown_82373F4); + sub_803F7D4(SPECIES_NIDORAN_F, 0); + spriteId = CreateSprite(&gMultiuseSpriteTemplate, 0x60, 0x60, 1); + gSprites[spriteId].callback = SpriteCallbackDummy; + gSprites[spriteId].oam.priority = 1; + gSprites[spriteId].invisible = TRUE; + gTasks[taskId].data[4] = spriteId; +} + +static void SpriteCB_PikaSync(struct Sprite * sprite) +{ + sprite->pos2.y = gSprites[sprite->data[0]].animCmdIndex; +} + +static void CreatePikaOrGrassPlatformSpriteAndLinkToCurrentTask(u8 taskId, u8 state) +{ + u8 spriteId; + u8 i = 0; + + switch (state) + { + case 0: + LoadCompressedObjectPic(&sOakSpeech_PikaSpriteSheets[0]); + LoadCompressedObjectPic(&sOakSpeech_PikaSpriteSheets[1]); + LoadCompressedObjectPic(&sOakSpeech_PikaSpriteSheets[2]); + LoadSpritePalette(&sOakSpeech_PikaSpritePal); + spriteId = CreateSprite(&sOakSpeech_PikaSpriteTemplates[0], 0x10, 0x11, 2); + gSprites[spriteId].oam.priority = 0; + gTasks[taskId].data[7] = spriteId; + spriteId = CreateSprite(&sOakSpeech_PikaSpriteTemplates[1], 0x10, 0x09, 3); + gSprites[spriteId].oam.priority = 0; + gSprites[spriteId].data[0] = gTasks[taskId].data[7]; + gSprites[spriteId].callback = SpriteCB_PikaSync; + gTasks[taskId].data[8] = spriteId; + spriteId = CreateSprite(&sOakSpeech_PikaSpriteTemplates[2], 0x18, 0x0D, 1); + gSprites[spriteId].oam.priority = 0; + gSprites[spriteId].data[0] = gTasks[taskId].data[7]; + gSprites[spriteId].callback = SpriteCB_PikaSync; + gTasks[taskId].data[9] = spriteId; + break; + case 1: + LoadCompressedObjectPic(&sOakSpeech_GrassPlatformSpriteSheet); + LoadSpritePalette(&sOakSpeech_GrassPlatformSpritePal); + for (i = 0; i < 3; i++) + { + spriteId = CreateSprite(&sOakSpeech_GrassPlatformSpriteTemplates[i], i * 32 + 88, 0x70, 1); + gSprites[spriteId].oam.priority = 2; + gSprites[spriteId].animPaused = TRUE; + gSprites[spriteId].coordOffsetEnabled = TRUE; + gTasks[taskId].data[7 + i] = spriteId; + } + break; + } +} + +static void DestroyLinkedPikaOrGrassPlatformSprites(u8 taskId, u8 state) +{ + u8 i; + + for (i = 0; i < 3; i++) + { + DestroySprite(&gSprites[gTasks[taskId].data[7 + i]]); + } + + switch (state) + { + case 0: + FreeSpriteTilesByTag(0x1003); + FreeSpriteTilesByTag(0x1002); + FreeSpriteTilesByTag(0x1001); + FreeSpritePaletteByTag(0x1001); + break; + case 1: + FreeSpriteTilesByTag(0x1000); + FreeSpritePaletteByTag(0x1000); + break; + } +} + +static void LoadOaksSpeechTrainerPic(u16 whichPic, u16 tileOffset) +{ + u32 i; + + switch (whichPic) + { + case 0: // FIRE + LoadPalette(sOakSpeechGfx_RedPal, 0x40, 0x40); + LZ77UnCompVram(sOakSpeechGfx_RedPic, (void *)0x06000600 + tileOffset); + break; + case 1: // LEAF + LoadPalette(sOakSpeechGfx_LeafPal, 0x40, 0x40); + LZ77UnCompVram(sOakSpeechGfx_LeafPic, (void *)0x06000600 + tileOffset); + break; + case 2: // BLUE + LoadPalette(sOakSpeechGfx_RivalPal, 0x60, 0x40); + LZ77UnCompVram(sOakSpeechGfx_RivalPic, (void *)0x06000600 + tileOffset); + break; + case 3: // OAK + LoadPalette(sOakSpeechGfx_OakPal, 0x60, 0x40); + LZ77UnCompVram(sOakSpeechGfx_OakPic, (void *)0x06000600 + tileOffset); + break; + default: + return; + } + + sOakSpeechResources->trainerPicTilemapBuffer = AllocZeroed(0x60); + for (i = 0; i < 0x60; i++) + ((u8 *)sOakSpeechResources->trainerPicTilemapBuffer)[i] = i; + FillBgTilemapBufferRect(2, 0x000, 0, 0, 32, 32, 0x10); + CopyRectToBgTilemapBufferRect(2, sOakSpeechResources->trainerPicTilemapBuffer, 0, 0, 8, 12, 11, 2, 8, 12, 0x10, (tileOffset / 64) + 0x18, 0x00); + CopyBgTilemapBufferToVram(2); + Free(sOakSpeechResources->trainerPicTilemapBuffer); + sOakSpeechResources->trainerPicTilemapBuffer = 0; +} + +static void DestroyOaksSpeechTrainerPic(void) +{ + FillBgTilemapBufferRect(2, 0x000, 11, 1, 8, 12, 0x10); + CopyBgTilemapBufferToVram(2); +} + +static void Task_SlowFadeIn(u8 taskId) +{ + u8 i = 0; + if (gTasks[taskId].data[1] == 0) + { + gTasks[gTasks[taskId].data[0]].data[2] = 1; + DestroyTask(taskId); + for (i = 0; i < 3; i++) + { + gSprites[gTasks[taskId].data[7 + i]].invisible = TRUE; + } + } + else + { + if (gTasks[taskId].data[4] != 0) + gTasks[taskId].data[4]--; + else + { + gTasks[taskId].data[4] = gTasks[taskId].data[3]; + gTasks[taskId].data[1]--; + gTasks[taskId].data[2]++; + if (gTasks[taskId].data[1] == 8) + { + for (i = 0; i < 3; i++) + { + gSprites[gTasks[taskId].data[7 + i]].invisible ^= TRUE; + } + } + SetGpuReg(REG_OFFSET_BLDALPHA, (gTasks[taskId].data[2] * 256) + gTasks[taskId].data[1]); + } + } +} + +static void CreateFadeInTask(u8 taskId, u8 state) +{ + u8 taskId2; + u8 i = 0; + + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG2 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_BG1 | BLDCNT_TGT2_OBJ); + SetGpuReg(REG_OFFSET_BLDALPHA, 0x10); + SetGpuReg(REG_OFFSET_BLDY, 0); + gTasks[taskId].data[2] = 0; + taskId2 = CreateTask(Task_SlowFadeIn, 0); + gTasks[taskId2].data[0] = taskId; + gTasks[taskId2].data[1] = 16; + gTasks[taskId2].data[2] = 0; + gTasks[taskId2].data[3] = state; + gTasks[taskId2].data[4] = state; + for (i = 0; i < 3; i++) + { + gTasks[taskId2].data[7 + i] = gTasks[taskId].data[7 + i]; + } +} + +static void Task_SlowFadeOut(u8 taskId) +{ + u8 i = 0; + + if (gTasks[taskId].data[1] == 16) + { + if (!gPaletteFade.active) + { + gTasks[gTasks[taskId].data[0]].data[2] = 1; + DestroyTask(taskId); + } + } + else + { + if (gTasks[taskId].data[4] != 0) + gTasks[taskId].data[4]--; + else + { + gTasks[taskId].data[4] = gTasks[taskId].data[3]; + gTasks[taskId].data[1] += 2; + gTasks[taskId].data[2] -= 2; + if (gTasks[taskId].data[1] == 8) + { + for (i = 0; i < 3; i++) + { + gSprites[gTasks[taskId].data[7 + i]].invisible ^= TRUE; + } + } + SetGpuReg(REG_OFFSET_BLDALPHA, (gTasks[taskId].data[2] * 256) + gTasks[taskId].data[1]); + } + } +} + +static void CreateFadeOutTask(u8 taskId, u8 state) +{ + u8 taskId2; + u8 i = 0; + + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG2 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_BG1 | BLDCNT_TGT2_OBJ); + SetGpuReg(REG_OFFSET_BLDALPHA, 0x1000); + SetGpuReg(REG_OFFSET_BLDY, 0); + gTasks[taskId].data[2] = 0; + taskId2 = CreateTask(Task_SlowFadeOut, 0); + gTasks[taskId2].data[0] = taskId; + gTasks[taskId2].data[1] = 0; + gTasks[taskId2].data[2] = 16; + gTasks[taskId2].data[3] = state; + gTasks[taskId2].data[4] = state; + for (i = 0; i < 3; i++) + { + gTasks[taskId2].data[7 + i] = gTasks[taskId].data[7 + i]; + } +} + +static void PrintNameChoiceOptions(u8 taskId, u8 state) +{ + s16 * data = gTasks[taskId].data; + const u8 *const * textPtrs; + u8 i; + + data[13] = AddWindow(&sNewGameAdventureIntroWindowTemplates[3]); + PutWindowTilemap(data[13]); + SetWindowBorderStyle(data[13], 1, sub_80F796C(), 14); + FillWindowPixelBuffer(gTasks[taskId].data[13], 0x11); + AddTextPrinterParameterized(data[13], 2, gOtherText_NewName, 8, 1, 0, NULL); + if (state == 0) + textPtrs = gSaveBlock2Ptr->playerGender == MALE ? sMaleNameChoices : sFemaleNameChoices; + else + textPtrs = sRivalNameChoices; + for (i = 0; i < 4; i++) + { + AddTextPrinterParameterized(data[13], 2, textPtrs[i], 8, 16 * (i + 1) + 1, 0, NULL); + } + ProgramAndPlaceMenuCursorOnWindow(data[13], 2, 0, 1, 16, 5, 0); + CopyWindowToVram(data[13], 3); +} + +static void GetDefaultName(u8 arg0, u8 namePick) +{ + const u8 * src; + u8 * dest; + u8 i; + + if (arg0 == 0) + { + if (gSaveBlock2Ptr->playerGender == MALE) + src = sMaleNameChoices[Random() % 19]; + else + src = sFemaleNameChoices[Random() % 19]; + dest = gSaveBlock2Ptr->playerName; + } + else + { + src = sRivalNameChoices[namePick]; + dest = gSaveBlock1Ptr->rivalName; + } + for (i = 0; i < PLAYER_NAME_LENGTH - 1 && src[i] != EOS; i++) + dest[i] = src[i]; + for (; i < PLAYER_NAME_LENGTH; i++) + dest[i] = EOS; +} diff --git a/src/roamer.c b/src/roamer.c new file mode 100644 index 000000000..b42855644 --- /dev/null +++ b/src/roamer.c @@ -0,0 +1,240 @@ +#include "global.h" +#include "roamer.h" +#include "random.h" +#include "overworld.h" +#include "field_specials.h" +#include "constants/species.h" +#include "constants/maps.h" +#include "constants/region_map.h" + +EWRAM_DATA u8 sLocationHistory[3][2] = {}; +EWRAM_DATA u8 sRoamerLocation[2] = {}; + +#define saveRoamer (*(&gSaveBlock1Ptr->roamer)) + +enum +{ + MAP_GRP = 0, // map group + MAP_NUM = 1, // map number +}; + +const u8 sRoamerLocations[][7] = { + {MAP_NUM(ROUTE1), MAP_NUM(ROUTE2), MAP_NUM(ROUTE21_NORTH), MAP_NUM(ROUTE22), 0xff, 0xff, 0xff}, + {MAP_NUM(ROUTE2), MAP_NUM(ROUTE1), MAP_NUM(ROUTE3), MAP_NUM(ROUTE22), 0xff, 0xff, 0xff}, + {MAP_NUM(ROUTE3), MAP_NUM(ROUTE2), MAP_NUM(ROUTE4), 0xff, 0xff, 0xff, 0xff}, + {MAP_NUM(ROUTE4), MAP_NUM(ROUTE3), MAP_NUM(ROUTE5), MAP_NUM(ROUTE9), MAP_NUM(ROUTE24), 0xff, 0xff}, + {MAP_NUM(ROUTE5), MAP_NUM(ROUTE4), MAP_NUM(ROUTE6), MAP_NUM(ROUTE7), MAP_NUM(ROUTE8), MAP_NUM(ROUTE9), MAP_NUM(ROUTE24)}, + {MAP_NUM(ROUTE6), MAP_NUM(ROUTE5), MAP_NUM(ROUTE7), MAP_NUM(ROUTE8), MAP_NUM(ROUTE11), 0xff, 0xff}, + {MAP_NUM(ROUTE7), MAP_NUM(ROUTE5), MAP_NUM(ROUTE6), MAP_NUM(ROUTE8), MAP_NUM(ROUTE16), 0xff, 0xff}, + {MAP_NUM(ROUTE8), MAP_NUM(ROUTE5), MAP_NUM(ROUTE6), MAP_NUM(ROUTE7), MAP_NUM(ROUTE10), MAP_NUM(ROUTE12), 0xff}, + {MAP_NUM(ROUTE9), MAP_NUM(ROUTE4), MAP_NUM(ROUTE5), MAP_NUM(ROUTE10), MAP_NUM(ROUTE24), 0xff, 0xff}, + {MAP_NUM(ROUTE10), MAP_NUM(ROUTE8), MAP_NUM(ROUTE9), MAP_NUM(ROUTE12), 0xff, 0xff, 0xff}, + {MAP_NUM(ROUTE11), MAP_NUM(ROUTE6), MAP_NUM(ROUTE12), 0xff, 0xff, 0xff, 0xff}, + {MAP_NUM(ROUTE12), MAP_NUM(ROUTE10), MAP_NUM(ROUTE11), MAP_NUM(ROUTE13), 0xff, 0xff, 0xff}, + {MAP_NUM(ROUTE13), MAP_NUM(ROUTE12), MAP_NUM(ROUTE14), 0xff, 0xff, 0xff, 0xff}, + {MAP_NUM(ROUTE14), MAP_NUM(ROUTE13), MAP_NUM(ROUTE15), 0xff, 0xff, 0xff, 0xff}, + {MAP_NUM(ROUTE15), MAP_NUM(ROUTE14), MAP_NUM(ROUTE18), MAP_NUM(ROUTE19), 0xff, 0xff, 0xff}, + {MAP_NUM(ROUTE16), MAP_NUM(ROUTE7), MAP_NUM(ROUTE17), 0xff, 0xff, 0xff, 0xff}, + {MAP_NUM(ROUTE17), MAP_NUM(ROUTE16), MAP_NUM(ROUTE18), 0xff, 0xff, 0xff, 0xff}, + {MAP_NUM(ROUTE18), MAP_NUM(ROUTE15), MAP_NUM(ROUTE17), MAP_NUM(ROUTE19), 0xff, 0xff, 0xff}, + {MAP_NUM(ROUTE19), MAP_NUM(ROUTE15), MAP_NUM(ROUTE18), MAP_NUM(ROUTE20), 0xff, 0xff, 0xff}, + {MAP_NUM(ROUTE20), MAP_NUM(ROUTE19), MAP_NUM(ROUTE21_NORTH), 0xff, 0xff, 0xff, 0xff}, + {MAP_NUM(ROUTE21_NORTH), MAP_NUM(ROUTE1), MAP_NUM(ROUTE20), 0xff, 0xff, 0xff, 0xff}, + {MAP_NUM(ROUTE22), MAP_NUM(ROUTE1), MAP_NUM(ROUTE2), MAP_NUM(ROUTE23), 0xff, 0xff, 0xff}, + {MAP_NUM(ROUTE23), MAP_NUM(ROUTE22), MAP_NUM(ROUTE2), 0xff, 0xff, 0xff, 0xff}, + {MAP_NUM(ROUTE24), MAP_NUM(ROUTE4), MAP_NUM(ROUTE5), MAP_NUM(ROUTE9), 0xff, 0xff, 0xff}, + {MAP_NUM(ROUTE25), MAP_NUM(ROUTE24), MAP_NUM(ROUTE9), 0xff, 0xff, 0xff, 0xff}, + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff} +}; + +void ClearRoamerData(void) +{ + u32 i; + gSaveBlock1Ptr->roamer = (struct Roamer){}; + sRoamerLocation[MAP_GRP] = 0; + sRoamerLocation[MAP_NUM] = 0; + for (i = 0; i < 3; i++) + { + sLocationHistory[i][MAP_GRP] = 0; + sLocationHistory[i][MAP_NUM] = 0; + } +} + +#define GetRoamerSpecies() ({\ + u16 a;\ + switch (ScrSpecial_GetStarter())\ + {\ + default:\ + a = SPECIES_RAIKOU;\ + break;\ + case SPECIES_BULBASAUR:\ + a = SPECIES_ENTEI;\ + break;\ + case SPECIES_CHARMANDER:\ + a = SPECIES_SUICUNE;\ + break;\ + }\ + a;\ +}) + +void CreateInitialRoamerMon(void) +{ + struct Pokemon * tmpMon = &gEnemyParty[0]; + u16 roamerMon; + + CreateMon(tmpMon, (roamerMon = GetRoamerSpecies()), 50, 0x20, 0, 0, 0, 0); + saveRoamer.species = roamerMon; + saveRoamer.level = 50; + saveRoamer.status = 0; + saveRoamer.active = TRUE; + saveRoamer.ivs = GetMonData(tmpMon, MON_DATA_IVS); + saveRoamer.personality = GetMonData(tmpMon, MON_DATA_PERSONALITY); + saveRoamer.hp = GetMonData(tmpMon, MON_DATA_MAX_HP); + saveRoamer.cool = GetMonData(tmpMon, MON_DATA_COOL); + saveRoamer.beauty = GetMonData(tmpMon, MON_DATA_BEAUTY); + saveRoamer.cute = GetMonData(tmpMon, MON_DATA_CUTE); + saveRoamer.smart = GetMonData(tmpMon, MON_DATA_SMART); + saveRoamer.tough = GetMonData(tmpMon, MON_DATA_TOUGH); + sRoamerLocation[MAP_GRP] = 3; + sRoamerLocation[MAP_NUM] = sRoamerLocations[Random() % (ARRAY_COUNT(sRoamerLocations) - 1)][0]; +} + +void InitRoamer(void) +{ + ClearRoamerData(); + CreateInitialRoamerMon(); +} + +void UpdateLocationHistoryForRoamer(void) +{ + sLocationHistory[2][MAP_GRP] = sLocationHistory[1][MAP_GRP]; + sLocationHistory[2][MAP_NUM] = sLocationHistory[1][MAP_NUM]; + sLocationHistory[1][MAP_GRP] = sLocationHistory[0][MAP_GRP]; + sLocationHistory[1][MAP_NUM] = sLocationHistory[0][MAP_NUM]; + sLocationHistory[0][MAP_GRP] = gSaveBlock1Ptr->location.mapGroup; + sLocationHistory[0][MAP_NUM] = gSaveBlock1Ptr->location.mapNum; +} + +void RoamerMoveToOtherLocationSet(void) +{ + u8 mapNum = 0; + struct Roamer *roamer = &saveRoamer; + + if (!roamer->active) + return; + + sRoamerLocation[MAP_GRP] = 3; + + while (1) + { + mapNum = sRoamerLocations[Random() % (ARRAY_COUNT(sRoamerLocations) - 1)][0]; + if (sRoamerLocation[MAP_NUM] != mapNum) + { + sRoamerLocation[MAP_NUM] = mapNum; + return; + } + } +} + + +void RoamerMove(void) +{ + u8 locSet = 0; + + if ((Random() % 16) == 0) + { + RoamerMoveToOtherLocationSet(); + } + else + { + struct Roamer *roamer = &saveRoamer; + + if (!roamer->active) + return; + + while (locSet < (ARRAY_COUNT(sRoamerLocations) - 1)) + { + if (sRoamerLocation[MAP_NUM] == sRoamerLocations[locSet][0]) + { + u8 mapNum; + while (1) + { + mapNum = sRoamerLocations[locSet][(Random() % 6) + 1]; + if (!(sLocationHistory[2][MAP_GRP] == 3 && sLocationHistory[2][MAP_NUM] == mapNum) && mapNum != 0xFF) + break; + } + sRoamerLocation[MAP_NUM] = mapNum; + return; + } + locSet++; + } + } +} + +bool8 IsRoamerAt(u8 mapGroup, u8 mapNum) +{ + struct Roamer *roamer = &saveRoamer; + + if (roamer->active && mapGroup == sRoamerLocation[MAP_GRP] && mapNum == sRoamerLocation[MAP_NUM]) + return TRUE; + else + return FALSE; +} + +void CreateRoamerMonInstance(void) +{ + struct Pokemon *mon; + struct Roamer *roamer; + + mon = &gEnemyParty[0]; + ZeroEnemyPartyMons(); + roamer = &saveRoamer; + CreateMonWithIVsPersonality(mon, roamer->species, roamer->level, roamer->ivs, roamer->personality); + SetMonData(mon, MON_DATA_STATUS, &gSaveBlock1Ptr->roamer.status); + SetMonData(mon, MON_DATA_HP, &gSaveBlock1Ptr->roamer.hp); + SetMonData(mon, MON_DATA_COOL, &gSaveBlock1Ptr->roamer.cool); + SetMonData(mon, MON_DATA_BEAUTY, &gSaveBlock1Ptr->roamer.beauty); + SetMonData(mon, MON_DATA_CUTE, &gSaveBlock1Ptr->roamer.cute); + SetMonData(mon, MON_DATA_SMART, &gSaveBlock1Ptr->roamer.smart); + SetMonData(mon, MON_DATA_TOUGH, &gSaveBlock1Ptr->roamer.tough); +} + +bool8 TryStartRoamerEncounter(void) +{ + if (IsRoamerAt(gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum) == TRUE && (Random() % 4) == 0) + { + CreateRoamerMonInstance(); + return TRUE; + } + else + { + return FALSE; + } +} +void UpdateRoamerHPStatus(struct Pokemon *mon) +{ + saveRoamer.hp = GetMonData(mon, MON_DATA_HP); + saveRoamer.status = GetMonData(mon, MON_DATA_STATUS); + + RoamerMoveToOtherLocationSet(); +} + +void SetRoamerInactive(void) +{ + struct Roamer *roamer = &saveRoamer; + roamer->active = FALSE; +} + +void GetRoamerLocation(u8 *mapGroup, u8 *mapNum) +{ + *mapGroup = sRoamerLocation[MAP_GRP]; + *mapNum = sRoamerLocation[MAP_NUM]; +} + +u16 GetRoamerLocationMapSectionId(void) +{ + struct Roamer *roamer = &saveRoamer; + if (!saveRoamer.active) + return MAPSEC_NONE; + return get_mapheader_by_bank_and_number(sRoamerLocation[MAP_GRP], sRoamerLocation[MAP_NUM])->regionMapSectionId; +} diff --git a/src/scanline_effect.c b/src/scanline_effect.c new file mode 100644 index 000000000..22699b96d --- /dev/null +++ b/src/scanline_effect.c @@ -0,0 +1,262 @@ +#include "global.h" +#include "battle.h" +#include "task.h" +#include "trig.h" +#include "scanline_effect.h" + +extern u16 gBattle_BG0_X; +extern u16 gBattle_BG0_Y; +extern u16 gBattle_BG1_X; +extern u16 gBattle_BG1_Y; +extern u16 gBattle_BG2_X; +extern u16 gBattle_BG2_Y; +extern u16 gBattle_BG3_X; +extern u16 gBattle_BG3_Y; + +static void CopyValue16Bit(void); +static void CopyValue32Bit(void); + +// EWRAM vars + +// Per-scanline register values. +// This is double buffered so that it can be safely written to at any time +// without overwriting the buffer that the DMA is currently reading +EWRAM_DATA u16 gScanlineEffectRegBuffers[2][0x3C0] = {0}; + +EWRAM_DATA struct ScanlineEffect gScanlineEffect = {0}; +EWRAM_DATA static bool8 sShouldStopWaveTask = FALSE; + +void ScanlineEffect_Stop(void) +{ + gScanlineEffect.state = 0; + DmaStop(0); + if (gScanlineEffect.waveTaskId != 0xFF) + { + DestroyTask(gScanlineEffect.waveTaskId); + gScanlineEffect.waveTaskId = 0xFF; + } +} + +void ScanlineEffect_Clear(void) +{ + CpuFill16(0, gScanlineEffectRegBuffers, sizeof(gScanlineEffectRegBuffers)); + gScanlineEffect.dmaSrcBuffers[0] = NULL; + gScanlineEffect.dmaSrcBuffers[1] = NULL; + gScanlineEffect.dmaDest = NULL; + gScanlineEffect.dmaControl = 0; + gScanlineEffect.srcBuffer = 0; + gScanlineEffect.state = 0; + gScanlineEffect.unused16 = 0; + gScanlineEffect.unused17 = 0; + gScanlineEffect.waveTaskId = 0xFF; +} + +void ScanlineEffect_SetParams(struct ScanlineEffectParams params) +{ + if (params.dmaControl == SCANLINE_EFFECT_DMACNT_16BIT) // 16-bit + { + // Set the DMA src to the value for the second scanline because the + // first DMA transfer occurs in HBlank *after* the first scanline is drawn + gScanlineEffect.dmaSrcBuffers[0] = (u16 *)gScanlineEffectRegBuffers[0] + 1; + gScanlineEffect.dmaSrcBuffers[1] = (u16 *)gScanlineEffectRegBuffers[1] + 1; + gScanlineEffect.setFirstScanlineReg = CopyValue16Bit; + } + else // assume 32-bit + { + // Set the DMA src to the value for the second scanline because the + // first DMA transfer occurs in HBlank *after* the first scanline is drawn + gScanlineEffect.dmaSrcBuffers[0] = (u32 *)gScanlineEffectRegBuffers[0] + 1; + gScanlineEffect.dmaSrcBuffers[1] = (u32 *)gScanlineEffectRegBuffers[1] + 1; + gScanlineEffect.setFirstScanlineReg = CopyValue32Bit; + } + + gScanlineEffect.dmaControl = params.dmaControl; + gScanlineEffect.dmaDest = params.dmaDest; + gScanlineEffect.state = params.initState; + gScanlineEffect.unused16 = params.unused9; + gScanlineEffect.unused17 = params.unused9; +} + +void ScanlineEffect_InitHBlankDmaTransfer(void) +{ + if (gScanlineEffect.state == 0) + { + return; + } + else if (gScanlineEffect.state == 3) + { + gScanlineEffect.state = 0; + DmaStop(0); + sShouldStopWaveTask = TRUE; + } + else + { + DmaStop(0); + // Set DMA to copy to dest register on each HBlank for the next frame. + // The HBlank DMA transfers do not occurr during VBlank, so the transfer + // will begin on the HBlank after the first scanline + DmaSet(0, gScanlineEffect.dmaSrcBuffers[gScanlineEffect.srcBuffer], gScanlineEffect.dmaDest, gScanlineEffect.dmaControl); + // Manually set the reg for the first scanline + gScanlineEffect.setFirstScanlineReg(); + // Swap current buffer + gScanlineEffect.srcBuffer ^= 1; + } +} + +// These two functions are used to copy the register for the first scanline, +// depending whether it is a 16-bit register or a 32-bit register. + +static void CopyValue16Bit(void) +{ + u16 *dest = (u16 *)gScanlineEffect.dmaDest; + u16 *src = (u16 *)&gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer]; + + *dest = *src; +} + +static void CopyValue32Bit(void) +{ + u32 *dest = (u32 *)gScanlineEffect.dmaDest; + u32 *src = (u32 *)&gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer]; + + *dest = *src; +} + +#define tStartLine data[0] +#define tEndLine data[1] +#define tWaveLength data[2] +#define tSrcBufferOffset data[3] +#define tFramesUntilMove data[4] +#define tDelayInterval data[5] +#define tRegOffset data[6] +#define tApplyBattleBgOffsets data[7] + +static void TaskFunc_UpdateWavePerFrame(u8 taskId) +{ + int value = 0; + int i; + int offset; + + if (sShouldStopWaveTask) + { + DestroyTask(taskId); + gScanlineEffect.waveTaskId = 0xFF; + } + else + { + if (gTasks[taskId].tApplyBattleBgOffsets) + { + switch (gTasks[taskId].tRegOffset) + { + case SCANLINE_EFFECT_REG_BG0HOFS: + value = gBattle_BG0_X; + break; + case SCANLINE_EFFECT_REG_BG0VOFS: + value = gBattle_BG0_Y; + break; + case SCANLINE_EFFECT_REG_BG1HOFS: + value = gBattle_BG1_X; + break; + case SCANLINE_EFFECT_REG_BG1VOFS: + value = gBattle_BG1_Y; + break; + case SCANLINE_EFFECT_REG_BG2HOFS: + value = gBattle_BG2_X; + break; + case SCANLINE_EFFECT_REG_BG2VOFS: + value = gBattle_BG2_Y; + break; + case SCANLINE_EFFECT_REG_BG3HOFS: + value = gBattle_BG3_X; + break; + case SCANLINE_EFFECT_REG_BG3VOFS: + value = gBattle_BG3_Y; + break; + } + } + if (gTasks[taskId].tFramesUntilMove != 0) + { + gTasks[taskId].tFramesUntilMove--; + offset = gTasks[taskId].tSrcBufferOffset + 320; + for (i = gTasks[taskId].tStartLine; i < gTasks[taskId].tEndLine; i++) + { + gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = gScanlineEffectRegBuffers[0][offset] + value; + offset++; + } + } + else + { + gTasks[taskId].tFramesUntilMove = gTasks[taskId].tDelayInterval; + offset = gTasks[taskId].tSrcBufferOffset + 320; + for (i = gTasks[taskId].tStartLine; i < gTasks[taskId].tEndLine; i++) + { + gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = gScanlineEffectRegBuffers[0][offset] + value; + offset++; + } + + // increment src buffer offset + gTasks[taskId].tSrcBufferOffset++; + if (gTasks[taskId].tSrcBufferOffset == gTasks[taskId].tWaveLength) + gTasks[taskId].tSrcBufferOffset = 0; + } + } +} + +static void GenerateWave(u16 *buffer, u8 frequency, u8 amplitude, u8 unused) +{ + u16 i = 0; + u8 theta = 0; + + while (i < 256) + { + buffer[i] = (gSineTable[theta] * amplitude) / 256; + theta += frequency; + i++; + } +} + +// Initializes a background "wave" effect that affects scanlines startLine (inclusive) to endLine (exclusive). +// 'frequency' and 'amplitude' control the frequency and amplitude of the wave. +// 'delayInterval' controls how fast the wave travels up the screen. The wave will shift upwards one scanline every 'delayInterval'+1 frames. +// 'regOffset' is the offset of the video register to modify. +u8 ScanlineEffect_InitWave(u8 startLine, u8 endLine, u8 frequency, u8 amplitude, u8 delayInterval, u8 regOffset, bool8 applyBattleBgOffsets) +{ + int i; + int offset; + struct ScanlineEffectParams params; + u8 taskId; + + ScanlineEffect_Clear(); + + params.dmaDest = (void *)(REG_ADDR_BG0HOFS + regOffset); + params.dmaControl = SCANLINE_EFFECT_DMACNT_16BIT; + params.initState = 1; + params.unused9 = 0; + ScanlineEffect_SetParams(params); + + taskId = CreateTask(TaskFunc_UpdateWavePerFrame, 0); + + gTasks[taskId].tStartLine = startLine; + gTasks[taskId].tEndLine = endLine; + gTasks[taskId].tWaveLength = 256 / frequency; + gTasks[taskId].tSrcBufferOffset = 0; + gTasks[taskId].tFramesUntilMove = delayInterval; + gTasks[taskId].tDelayInterval = delayInterval; + gTasks[taskId].tRegOffset = regOffset; + gTasks[taskId].tApplyBattleBgOffsets = applyBattleBgOffsets; + + gScanlineEffect.waveTaskId = taskId; + sShouldStopWaveTask = FALSE; + + GenerateWave(&gScanlineEffectRegBuffers[0][320], frequency, amplitude, endLine - startLine); + + offset = 320; + for (i = startLine; i < endLine; i++) + { + gScanlineEffectRegBuffers[0][i] = gScanlineEffectRegBuffers[0][offset]; + gScanlineEffectRegBuffers[1][i] = gScanlineEffectRegBuffers[0][offset]; + offset++; + } + + return taskId; +} diff --git a/src/scrcmd.c b/src/scrcmd.c index 12b35daa4..e7c61db1f 100644 --- a/src/scrcmd.c +++ b/src/scrcmd.c @@ -1567,7 +1567,7 @@ bool8 ScrCmd_braillemessage(struct ScriptContext *ctx) ptr = (u8 *)ctx->data[0]; sub_80F6E9C(); - sub_80F6EE4(0, 1); + DrawDialogueFrame(0, 1); AddTextPrinterParameterized(0, 6, ptr, 0, 1, 0, NULL); return FALSE; } @@ -1636,8 +1636,8 @@ bool8 ScrCmd_bufferitemname(struct ScriptContext *ctx) return FALSE; } -extern const u8 gUnknown_83A72A0[]; -extern const u8 gUnknown_83A72A2[]; +const u8 gUnknown_83A72A0[] = _("S"); +const u8 gUnknown_83A72A2[] = _("IES"); bool8 ScrCmd_bufferitemnameplural(struct ScriptContext *ctx) { diff --git a/src/sound.c b/src/sound.c index f94e44506..ba6511d1c 100644 --- a/src/sound.c +++ b/src/sound.c @@ -40,7 +40,23 @@ extern struct MusicPlayerInfo gMPlayInfo_SE2; extern struct MusicPlayerInfo gMPlayInfo_SE3; extern struct ToneData gCryTable[]; extern struct ToneData gCryTable2[]; -extern const struct Fanfare sFanfares[]; + +static const struct Fanfare sFanfares[] = { + { MUS_FANFA1, 80 }, + { MUS_FANFA4, 160 }, + { MUS_FANFA5, 220 }, + { MUS_ME_WAZA, 220 }, + { MUS_ME_ASA, 160 }, + { MUS_ME_BACHI, 340 }, + { MUS_ME_WASURE, 180 }, + { MUS_ME_KINOMI, 120 }, + { MUS_ME_B_BIG, 250 }, + { MUS_ME_B_SMALL, 150 }, + { MUS_ME_ZANNEN, 160 }, + { BGM_FRLG_FLUTE, 450 }, + { BGM_FRLG_ME_KEYITEM, 170 }, + { BGM_FRLG_ME_POKEDEX_EVAL, 196 } +}; extern u16 SpeciesToCryId(u16); diff --git a/src/text.c b/src/text.c index 874e12fd5..d74d77e2f 100644 --- a/src/text.c +++ b/src/text.c @@ -8,8 +8,8 @@ extern u8 gGlyphInfo[0x90]; extern u8 gUnknown_203ADFA; -extern u16 gUnknown_841F408[]; -extern const struct OamData gUnknown_83AC9D0; +extern u16 gTMCaseMainWindowPalette[]; +extern const struct OamData gOamData_83AC9D0; extern void FillBitmapRect4Bit(struct Bitmap *surface, u16 x, u16 y, u16 width, u16 height, u8 fillValue); extern void FillWindowPixelRect(u8 windowId, u8 fillValue, u16 x, u16 y, u16 width, u16 height); @@ -52,7 +52,7 @@ const struct SpriteSheet gUnknown_81EA68C[] = const struct SpritePalette gUnknown_81EA6A4[] = { - {gUnknown_841F408, 0x8000}, + {gTMCaseMainWindowPalette, 0x8000}, {NULL} }; @@ -60,7 +60,7 @@ const struct SpriteTemplate gUnknown_81EA6B4 = { .tileTag = 0x8000, .paletteTag = 0x8000, - .oam = &gUnknown_83AC9D0, + .oam = &gOamData_83AC9D0, .anims = gDummySpriteAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, @@ -1791,7 +1791,7 @@ void sub_80062B0(struct Sprite *sprite) } } -u8 sub_8006300(u8 sheetId, u16 x, u16 y, u8 priority, u8 subpriority) +u8 CreateTextCursorSpriteForOakSpeech(u8 sheetId, u16 x, u16 y, u8 priority, u8 subpriority) { u8 spriteId; LoadSpriteSheet(&gUnknown_81EA68C[sheetId & 1]); diff --git a/src/tm_case.c b/src/tm_case.c new file mode 100644 index 000000000..2fc30da2d --- /dev/null +++ b/src/tm_case.c @@ -0,0 +1,1537 @@ +#include "global.h" +#include "malloc.h" +#include "bg.h" +#include "decompress.h" +#include "gpu_regs.h" +#include "palette.h" +#include "graphics.h" +#include "task.h" +#include "text.h" +#include "text_window.h" +#include "menu.h" +#include "menu_helpers.h" +#include "new_menu_helpers.h" +#include "list_menu.h" +#include "item.h" +#include "item_menu.h" +#include "link.h" +#include "money.h" +#include "shop.h" +#include "teachy_tv.h" +#include "pokemon_storage_system.h" +#include "string_util.h" +#include "party_menu.h" +#include "data2.h" +#include "scanline_effect.h" +#include "sound.h" +#include "strings.h" +#include "tm_case.h" +#include "menu_indicators.h" +#include "constants/items.h" +#include "constants/songs.h" + +#define TM_CASE_TM_TAG 400 + +struct UnkStruct_203B10C +{ + void (* savedCallback)(void); + u8 tmCaseMenuType; + u8 unk_05; + u8 unk_06; + u16 selectedRow; + u16 scrollOffset; +}; + +struct UnkStruct_203B118 +{ + void (* savedCallback)(void); + u8 tmSpriteId; + u8 maxTMsShown; + u8 numTMs; + u8 contextMenuWindowId; + u8 scrollIndicatorArrowPairId; + u16 currItem; + const u8 * menuActionIndices; + u8 numMenuActions; + s16 seqId; + u8 filler_14[8]; +}; + +struct UnkStruct_203B11C +{ + struct ItemSlot bagPocket_TMHM[BAG_TMHM_COUNT]; + struct ItemSlot bagPocket_KeyItems[BAG_KEYITEMS_COUNT]; + u16 unk_160; + u16 unk_162; +}; + +static EWRAM_DATA struct UnkStruct_203B10C sTMCaseStaticResources = {}; +static EWRAM_DATA struct UnkStruct_203B118 * sTMCaseDynamicResources = NULL; +static EWRAM_DATA struct UnkStruct_203B11C * sPokeDudePackBackup = NULL; +static EWRAM_DATA void * sTilemapBuffer = NULL; // tilemap buffer +static EWRAM_DATA struct ListMenuItem * sListMenuItemsBuffer = NULL; +static EWRAM_DATA u8 (* sListMenuStringsBuffer)[29] = NULL; +static EWRAM_DATA u16 * sTMSpritePaletteBuffer = NULL; + +static void CB2_SetUpTMCaseUI_Blocking(void); +static bool8 DoSetUpTMCaseUI(void); +static void ResetBufferPointers_NoFree(void); +static void LoadBGTemplates(void); +static bool8 HandleLoadTMCaseGraphicsAndPalettes(void); +static void CreateTMCaseListMenuBuffers(void); +static void InitTMCaseListMenuItems(void); +static void GetTMNumberAndMoveString(u8 * dest, u16 itemId); +static void TMCase_MoveCursorFunc(s32 itemIndex, bool8 onInit, struct ListMenu *list); +static void TMCase_ItemPrintFunc(u8 windowId, s32 itemId, u8 y); +static void TMCase_MoveCursor_UpdatePrintedDescription(s32 itemIndex); +static void PrintListMenuCursorAt_WithColorIdx(u8 a0, u8 a1); +static void CreateTMCaseScrollIndicatorArrowPair_Main(void); +static void TMCaseSetup_GetTMCount(void); +static void TMCaseSetup_InitListMenuPositions(void); +static void TMCaseSetup_UpdateVisualMenuOffset(void); +static void Task_FadeOutAndCloseTMCase(u8 taskId); +static void Task_TMCaseMain(u8 taskId); +static void Task_SelectTMAction_FromFieldBag(u8 taskId); +static void Task_TMContextMenu_HandleInput(u8 taskId); +static void TMHMContextMenuAction_Use(u8 taskId); +static void TMHMContextMenuAction_Give(u8 taskId); +static void PrintError_ThereIsNoPokemon(u8 taskId); +static void PrintError_ItemCantBeHeld(u8 taskId); +static void Task_WaitButtonAfterErrorPrint(u8 taskId); +static void Subtask_CloseContextMenuAndReturnToMain(u8 taskId); +static void TMHMContextMenuAction_Exit(u8 taskId); +static void Task_SelectTMAction_Type1(u8 taskId); +static void Task_SelectTMAction_Type3(u8 taskId); +static void Task_SelectTMAction_FromSellMenu(u8 taskId); +static void Task_AskConfirmSaleWithAmount(u8 taskId); +static void Task_PlaceYesNoBox(u8 taskId); +static void Task_SaleOfTMsCancelled(u8 taskId); +static void Task_InitQuantitySelectUI(u8 taskId); +static void SellTM_PrintQuantityAndSalePrice(s16 quantity, s32 value); +static void Task_QuantitySelect_HandleInput(u8 taskId); +static void Task_PrintSaleConfirmedText(u8 taskId); +static void Task_DoSaleOfTMs(u8 taskId); +static void Task_AfterSale_ReturnToList(u8 taskId); +static void Task_TMCaseDude1(u8 taskId); +static void Task_TMCaseDude_Playback(u8 taskId); +static void InitWindowTemplatesAndPals(void); +static void AddTextPrinterParameterized_ColorByIndex(u8 windowId, u8 fontId, const u8 * str, u8 x, u8 y, u8 letterSpacing, u8 lineSpacing, u8 speed, u8 colorIdx); +static void TMCase_SetWindowBorder1(u8 windowId); +static void TMCase_SetWindowBorder2(u8 windowId); +static void TMCase_PrintMessageWithFollowupTask(u8 taskId, u8 windowId, const u8 * str, TaskFunc func); +static void PrintStringTMCaseOnWindow3(void); +static void DrawMoveInfoUIMarkers(void); +static void TMCase_MoveCursor_UpdatePrintedTMInfo(u16 itemId); +static void PlaceHMTileInWindow(u8 windowId, u8 x, u8 y); +static void HandlePrintMoneyOnHand(void); +static void HandleCreateYesNoMenu(u8 taskId, const struct YesNoFuncTable * ptrs); +static u8 AddTMContextMenu(u8 * a0, u8 a1); +static void RemoveTMContextMenu(u8 * a0); +static u8 CreateTMSprite(u16 itemId); +static void SetTMSpriteAnim(struct Sprite * sprite, u8 var); +static void TintTMSpriteByType(u8 type); +static void UpdateTMSpritePosition(struct Sprite * sprite, u8 var); +static void InitSelectedTMSpriteData(u8 a0, u16 itemId); +static void SpriteCB_MoveTMSpriteInCase(struct Sprite * sprite); +static void LoadTMTypePalettes(void); + +static const struct BgTemplate sBGTemplates[] = { + { + .bg = 0, + .charBaseIndex = 0, + .mapBaseIndex = 31, + .screenSize = 0, + .paletteMode = 0, + .priority = 1, + .baseTile = 0x000 + }, { + .bg = 1, + .charBaseIndex = 0, + .mapBaseIndex = 30, + .screenSize = 0, + .paletteMode = 0, + .priority = 0, + .baseTile = 0x000 + }, { + .bg = 2, + .charBaseIndex = 0, + .mapBaseIndex = 29, + .screenSize = 0, + .paletteMode = 0, + .priority = 2, + .baseTile = 0x000 + } +}; + +static void (*const sSelectTMActionTasks[])(u8 taskId) = { + Task_SelectTMAction_FromFieldBag, + Task_SelectTMAction_Type1, + Task_SelectTMAction_FromSellMenu, + Task_SelectTMAction_Type3 +}; + +static const struct MenuAction sMenuActions_UseGiveExit[] = { + {gOtherText_Use, TMHMContextMenuAction_Use }, + {gOtherText_Give, TMHMContextMenuAction_Give}, + {gOtherText_Exit, TMHMContextMenuAction_Exit}, +}; + +static const u8 sMenuActionIndices_Field[] = {0, 1, 2}; +static const u8 sMenuActionIndices_UnionRoom[] = {1, 2}; +static const struct YesNoFuncTable sYesNoFuncTable = {Task_PrintSaleConfirmedText, Task_SaleOfTMsCancelled}; + +static const u8 sText_ClearTo18[] = _("{CLEAR_TO 18}"); +static const u8 sText_SingleSpace[] = _(" "); + +static ALIGNED(4) const u16 sPal3Override[] = {RGB(8, 8, 8), RGB(30, 16, 6)}; + +static const struct TextColor sTextColors[] = { + {0, 1, 2}, + {0, 2, 3}, + {0, 3, 6}, + {0, 14, 10} +}; + +static const struct WindowTemplate sWindowTemplates[] = { + {0x00, 0x0a, 0x01, 0x13, 0x0a, 0x0f, 0x0081}, + {0x00, 0x0c, 0x0c, 0x12, 0x08, 0x0a, 0x013f}, + {0x01, 0x05, 0x0f, 0x0f, 0x04, 0x0d, 0x01f9}, + {0x00, 0x00, 0x01, 0x0a, 0x02, 0x0f, 0x0235}, + {0x00, 0x01, 0x0d, 0x05, 0x06, 0x0c, 0x0249}, + {0x00, 0x07, 0x0d, 0x05, 0x06, 0x0c, 0x0267}, + {0x01, 0x02, 0x0f, 0x1a, 0x04, 0x0b, 0x0285}, + {0x01, 0x11, 0x09, 0x0c, 0x04, 0x0f, 0x02ed}, + {0x01, 0x01, 0x01, 0x08, 0x03, 0x0d, 0x031d}, + DUMMY_WIN_TEMPLATE +}; + +static const struct WindowTemplate sYesNoWindowTemplate = {0x01, 0x15, 0x09, 0x06, 0x04, 0x0f, 0x0335}; + +static const struct WindowTemplate sTMContextWindowTemplates[] = { + {0x01, 0x16, 0x0d, 0x07, 0x06, 0x0f, 0x01cf}, + {0x01, 0x16, 0x0f, 0x07, 0x04, 0x0f, 0x01cf} +}; + +static const struct OamData sTMSpriteOamData = { + .size = 2, + .priority = 2 +}; + +static const union AnimCmd sTMSpriteAnim0[] = { + ANIMCMD_FRAME(0, 0), + ANIMCMD_END +}; + +static const union AnimCmd sTMSpriteAnim1[] = { + ANIMCMD_FRAME(16, 0), + ANIMCMD_END +}; + +static const union AnimCmd *const sTMSpriteAnims[] = { + sTMSpriteAnim0, + sTMSpriteAnim1 +}; + +static const struct CompressedSpriteSheet sTMSpriteSheet = { + (const void *)gTMCase_TMSpriteGfx, + 0x400, + TM_CASE_TM_TAG +}; + +static const struct SpriteTemplate sTMSpriteTemplate = { + TM_CASE_TM_TAG, + TM_CASE_TM_TAG, + &sTMSpriteOamData, + sTMSpriteAnims, + NULL, + gDummySpriteAffineAnimTable, + SpriteCallbackDummy +}; + +static const u16 sTMSpritePaletteOffsetByType[] = { + [TYPE_NORMAL] = 0x000, + [TYPE_FIRE] = 0x010, + [TYPE_WATER] = 0x020, + [TYPE_GRASS] = 0x030, + [TYPE_ELECTRIC] = 0x040, + [TYPE_ROCK] = 0x050, + [TYPE_GROUND] = 0x060, + [TYPE_ICE] = 0x070, + [TYPE_FLYING] = 0x080, + [TYPE_FIGHTING] = 0x090, + [TYPE_GHOST] = 0x0a0, + [TYPE_BUG] = 0x0b0, + [TYPE_POISON] = 0x0c0, + [TYPE_PSYCHIC] = 0x0d0, + [TYPE_STEEL] = 0x0e0, + [TYPE_DARK] = 0x0f0, + [TYPE_DRAGON] = 0x100 +}; + +void InitTMCase(u8 type, void (* callback)(void), u8 a2) +{ + ResetBufferPointers_NoFree(); + sTMCaseDynamicResources = Alloc(sizeof(struct UnkStruct_203B118)); + sTMCaseDynamicResources->savedCallback = 0; + sTMCaseDynamicResources->scrollIndicatorArrowPairId = 0xFF; + sTMCaseDynamicResources->contextMenuWindowId = 0xFF; + if (type != 5) + sTMCaseStaticResources.tmCaseMenuType = type; + if (callback != NULL) + sTMCaseStaticResources.savedCallback = callback; + if (a2 != 0xFF) + sTMCaseStaticResources.unk_05 = a2; + gTextFlags.flag_2 = FALSE; + SetMainCallback2(CB2_SetUpTMCaseUI_Blocking); +} + +static void CB2_Idle(void) +{ + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + do_scheduled_bg_tilemap_copies_to_vram(); + UpdatePaletteFade(); +} + +static void VBlankCB_Idle(void) +{ + LoadOam(); + ProcessSpriteCopyRequests(); + TransferPlttBuffer(); +} + +static void CB2_SetUpTMCaseUI_Blocking(void) +{ + while (1) + { + if (sub_80BF72C() == TRUE) + break; + if (DoSetUpTMCaseUI() == TRUE) + break; + if (sub_80BF708() == TRUE) + break; + } +} + +static bool8 DoSetUpTMCaseUI(void) +{ + u8 taskId; + + switch (gMain.state) + { + case 0: + sub_80BF768(); + clear_scheduled_bg_copies_to_vram(); + gMain.state++; + break; + case 1: + ScanlineEffect_Stop(); + gMain.state++; + break; + case 2: + FreeAllSpritePalettes(); + gMain.state++; + break; + case 3: + ResetPaletteFade(); + gMain.state++; + break; + case 4: + ResetSpriteData(); + gMain.state++; + break; + case 5: + ResetTasks(); + gMain.state++; + break; + case 6: + LoadBGTemplates(); + sTMCaseDynamicResources->seqId = 0; + gMain.state++; + break; + case 7: + InitWindowTemplatesAndPals(); + gMain.state++; + break; + case 8: + if (HandleLoadTMCaseGraphicsAndPalettes()) + gMain.state++; + break; + case 9: + sub_809A5E4(&gBagPockets[POCKET_TM_CASE - 1]); + gMain.state++; + break; + case 10: + TMCaseSetup_GetTMCount(); + TMCaseSetup_InitListMenuPositions(); + TMCaseSetup_UpdateVisualMenuOffset(); + gMain.state++; + break; + case 11: + DrawMoveInfoUIMarkers(); + gMain.state++; + break; + case 12: + CreateTMCaseListMenuBuffers(); + InitTMCaseListMenuItems(); + gMain.state++; + break; + case 13: + PrintStringTMCaseOnWindow3(); + gMain.state++; + break; + case 14: + if (sTMCaseStaticResources.tmCaseMenuType == 4) + taskId = CreateTask(Task_TMCaseDude1, 0); + else + taskId = CreateTask(Task_TMCaseMain, 0); + gTasks[taskId].data[0] = ListMenuInit(&gMultiuseListMenuTemplate, sTMCaseStaticResources.scrollOffset, sTMCaseStaticResources.selectedRow); + gMain.state++; + break; + case 15: + CreateTMCaseScrollIndicatorArrowPair_Main(); + gMain.state++; + break; + case 16: + sTMCaseDynamicResources->tmSpriteId = CreateTMSprite(BagGetItemIdByPocketPosition(POCKET_TM_CASE, sTMCaseStaticResources.scrollOffset + sTMCaseStaticResources.selectedRow)); + gMain.state++; + break; + case 17: + BlendPalettes(0xFFFFFFFF, 16, 0); + gMain.state++; + break; + case 18: + BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, RGB_BLACK); + gMain.state++; + break; + default: + SetVBlankCallback(VBlankCB_Idle); + SetMainCallback2(CB2_Idle); + return TRUE; + } + + return FALSE; +} + +static void ResetBufferPointers_NoFree(void) +{ + sTMCaseDynamicResources = NULL; + sTilemapBuffer = NULL; + sListMenuItemsBuffer = NULL; + sListMenuStringsBuffer = NULL; + sTMSpritePaletteBuffer = NULL; +} + +static void LoadBGTemplates(void) +{ + void ** ptr; + sub_80BF7C8(); + ptr = &sTilemapBuffer; + *ptr = AllocZeroed(0x800); + ResetBgsAndClearDma3BusyFlags(0); + InitBgsFromTemplates(0, sBGTemplates, NELEMS(sBGTemplates)); + SetBgTilemapBuffer(2, *ptr); + schedule_bg_copy_tilemap_to_vram(1); + schedule_bg_copy_tilemap_to_vram(2); + SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_1D_MAP | DISPCNT_OBJ_ON); + SetGpuReg(REG_OFFSET_BLDCNT, 0); + ShowBg(0); + ShowBg(1); + ShowBg(2); +} + +static bool8 HandleLoadTMCaseGraphicsAndPalettes(void) +{ + switch (sTMCaseDynamicResources->seqId) + { + case 0: + reset_temp_tile_data_buffers(); + decompress_and_copy_tile_data_to_vram(1, gUnknown_8E845D8, 0, 0, 0); + sTMCaseDynamicResources->seqId++; + break; + case 1: + if (free_temp_tile_data_buffers_if_possible() != TRUE) + { + LZDecompressWram(gUnknown_8E84A24, sTilemapBuffer); + sTMCaseDynamicResources->seqId++; + } + break; + case 2: + LZDecompressWram(gUnknown_8E84B70, GetBgTilemapBuffer(1)); + sTMCaseDynamicResources->seqId++; + break; + case 3: + if (gSaveBlock2Ptr->playerGender == MALE) + LoadCompressedPalette(gUnknown_8E84CB0, 0, 0x80); + else + LoadCompressedPalette(gUnknown_8E84D20, 0, 0x80); + sTMCaseDynamicResources->seqId++; + break; + case 4: + LoadCompressedObjectPic(&sTMSpriteSheet); + sTMCaseDynamicResources->seqId++; + break; + default: + LoadTMTypePalettes(); + sTMCaseDynamicResources->seqId = 0; + return TRUE; + } + + return FALSE; +} + +static void CreateTMCaseListMenuBuffers(void) +{ + struct BagPocket * pocket = &gBagPockets[POCKET_TM_CASE - 1]; + sListMenuItemsBuffer = Alloc((pocket->capacity + 1) * sizeof(struct ListMenuItem)); + sListMenuStringsBuffer = Alloc(sTMCaseDynamicResources->numTMs * 29); +} + +static void InitTMCaseListMenuItems(void) +{ + struct BagPocket * pocket = &gBagPockets[POCKET_TM_CASE - 1]; + u16 i; + + for (i = 0; i < sTMCaseDynamicResources->numTMs; i++) + { + GetTMNumberAndMoveString(sListMenuStringsBuffer[i], pocket->itemSlots[i].itemId); + sListMenuItemsBuffer[i].unk_00 = sListMenuStringsBuffer[i]; + sListMenuItemsBuffer[i].unk_04 = i; + } + sListMenuItemsBuffer[i].unk_00 = gText_Close; + sListMenuItemsBuffer[i].unk_04 = -2; + gMultiuseListMenuTemplate.items = sListMenuItemsBuffer; + gMultiuseListMenuTemplate.totalItems = sTMCaseDynamicResources->numTMs + 1; + gMultiuseListMenuTemplate.windowId = 0; + gMultiuseListMenuTemplate.header_X = 0; + gMultiuseListMenuTemplate.item_X = 8; + gMultiuseListMenuTemplate.cursor_X = 0; + gMultiuseListMenuTemplate.lettersSpacing = 0; + gMultiuseListMenuTemplate.itemVerticalPadding = 2; + gMultiuseListMenuTemplate.upText_Y = 2; + gMultiuseListMenuTemplate.maxShowed = sTMCaseDynamicResources->maxTMsShown; + gMultiuseListMenuTemplate.fontId = 2; + gMultiuseListMenuTemplate.cursorPal = 2; + gMultiuseListMenuTemplate.fillValue = 0; + gMultiuseListMenuTemplate.cursorShadowPal = 3; + gMultiuseListMenuTemplate.moveCursorFunc = TMCase_MoveCursorFunc; + gMultiuseListMenuTemplate.itemPrintFunc = TMCase_ItemPrintFunc; + gMultiuseListMenuTemplate.cursorKind = 0; + gMultiuseListMenuTemplate.scrollMultiple = 0; +} + +static void GetTMNumberAndMoveString(u8 * dest, u16 itemId) +{ + StringCopy(gStringVar4, gText_FontSize0); + if (itemId >= ITEM_HM01) + { + StringAppend(gStringVar4, sText_ClearTo18); + StringAppend(gStringVar4, gOtherText_UnkF9_08_Clear_01); + ConvertIntToDecimalStringN(gStringVar1, itemId - ITEM_HM01 + 1, STR_CONV_MODE_LEADING_ZEROS, 1); + StringAppend(gStringVar4, gStringVar1); + } + else + { + StringAppend(gStringVar4, gOtherText_UnkF9_08_Clear_01); + ConvertIntToDecimalStringN(gStringVar1, itemId - ITEM_TM01 + 1, STR_CONV_MODE_LEADING_ZEROS, 2); + StringAppend(gStringVar4, gStringVar1); + } + StringAppend(gStringVar4, sText_SingleSpace); + StringAppend(gStringVar4, gText_FontSize2); + StringAppend(gStringVar4, gMoveNames[ItemIdToBattleMoveId(itemId)]); + StringCopy(dest, gStringVar4); +} + +static void TMCase_MoveCursorFunc(s32 itemIndex, bool8 onInit, struct ListMenu *list) +{ + u16 itemId; + + if (itemIndex == -2) + itemId = 0; + else + itemId = BagGetItemIdByPocketPosition(POCKET_TM_CASE, itemIndex); + + if (onInit != TRUE) + { + PlaySE(SE_SELECT); + InitSelectedTMSpriteData(sTMCaseDynamicResources->tmSpriteId, itemId); + } + TMCase_MoveCursor_UpdatePrintedDescription(itemIndex); + TMCase_MoveCursor_UpdatePrintedTMInfo(itemId); +} + +static void TMCase_ItemPrintFunc(u8 windowId, s32 itemId, u8 y) +{ + if (itemId != -2) + { + if (!itemid_is_unique(BagGetItemIdByPocketPosition(POCKET_TM_CASE, itemId))) + { + ConvertIntToDecimalStringN(gStringVar1, BagGetQuantityByPocketPosition(POCKET_TM_CASE, itemId), STR_CONV_MODE_RIGHT_ALIGN, 3); + StringExpandPlaceholders(gStringVar4, gText_TimesStrVar1); + AddTextPrinterParameterized_ColorByIndex(windowId, 0, gStringVar4, 0x7E, y, 0, 0, 0xFF, 1); + } + else + { + PlaceHMTileInWindow(windowId, 8, y); + } + } +} + +static void TMCase_MoveCursor_UpdatePrintedDescription(s32 itemIndex) +{ + const u8 * str; + if (itemIndex != -2) + { + str = ItemId_GetDescription(BagGetItemIdByPocketPosition(POCKET_TM_CASE, itemIndex)); + } + else + { + str = gText_TMCaseWillBePutAway; + } + FillWindowPixelBuffer(1, 0); + AddTextPrinterParameterized_ColorByIndex(1, 2, str, 2, 3, 1, 0, 0, 0); +} + +static void FillBG2RowWithPalette_2timesNplus1(s32 a0) +{ + sub_80F6B08(2, 0, 12, 30, 8, 2 * a0 + 1); + schedule_bg_copy_tilemap_to_vram(2); +} + +static void PrintListMenuCursorByID_WithColorIdx(u8 a0, u8 a1) +{ + PrintListMenuCursorAt_WithColorIdx(ListMenuGetYCoordForPrintingArrowCursor(a0), a1); +} + +static void PrintListMenuCursorAt_WithColorIdx(u8 a0, u8 a1) +{ + if (a1 == 0xFF) + { + FillWindowPixelRect(0, 0, 0, a0, GetFontAttribute(2, 0), GetFontAttribute(2, 1)); + CopyWindowToVram(0, 2); + } + else + { + AddTextPrinterParameterized_ColorByIndex(0, 2, gFameCheckerText_ListMenuCursor, 0, a0, 0, 0, 0, a1); + } +} + +static void CreateTMCaseScrollIndicatorArrowPair_Main(void) +{ + sTMCaseDynamicResources->scrollIndicatorArrowPairId = AddScrollIndicatorArrowPairParametrized(2, 0xA0, 0x08, 0x58, sTMCaseDynamicResources->numTMs - sTMCaseDynamicResources->maxTMsShown + 1, 0x6E, 0x6E, &sTMCaseStaticResources.scrollOffset); +} + +static void CreateTMCaseScrollIndicatorArrowPair_SellQuantitySelect(void) +{ + sTMCaseDynamicResources->currItem = 1; + sTMCaseDynamicResources->scrollIndicatorArrowPairId = AddScrollIndicatorArrowPairParametrized(2, 0x98, 0x48, 0x68, 2, 0x6E, 0x6E, &sTMCaseDynamicResources->currItem); +} + +static void RemoveTMCaseScrollIndicatorArrowPair(void) +{ + if (sTMCaseDynamicResources->scrollIndicatorArrowPairId != 0xFF) + { + RemoveScrollIndicatorArrowPair(sTMCaseDynamicResources->scrollIndicatorArrowPairId); + sTMCaseDynamicResources->scrollIndicatorArrowPairId = 0xFF; + } +} + +void ResetTMCaseCursorPos(void) +{ + sTMCaseStaticResources.selectedRow = 0; + sTMCaseStaticResources.scrollOffset = 0; +} + +static void TMCaseSetup_GetTMCount(void) +{ + struct BagPocket * pocket = &gBagPockets[POCKET_TM_CASE - 1]; + u16 i; + + sub_809A584(pocket->itemSlots, pocket->capacity); + sTMCaseDynamicResources->numTMs = 0; + for (i = 0; i < pocket->capacity; i++) + { + if (pocket->itemSlots[i].itemId == ITEM_NONE) + break; + sTMCaseDynamicResources->numTMs++; + } + sTMCaseDynamicResources->maxTMsShown = min(sTMCaseDynamicResources->numTMs + 1, 5); +} + +static void TMCaseSetup_InitListMenuPositions(void) +{ + if (sTMCaseStaticResources.scrollOffset != 0) + { + if (sTMCaseStaticResources.scrollOffset + sTMCaseDynamicResources->maxTMsShown > sTMCaseDynamicResources->numTMs + 1) + sTMCaseStaticResources.scrollOffset = sTMCaseDynamicResources->numTMs + 1 - sTMCaseDynamicResources->maxTMsShown; + } + if (sTMCaseStaticResources.scrollOffset + sTMCaseStaticResources.selectedRow >= sTMCaseDynamicResources->numTMs + 1) + { + if (sTMCaseDynamicResources->numTMs + 1 < 2) + sTMCaseStaticResources.selectedRow = 0; + else + sTMCaseStaticResources.selectedRow = sTMCaseDynamicResources->numTMs; + } +} + +static void TMCaseSetup_UpdateVisualMenuOffset(void) +{ + u8 i; + if (sTMCaseStaticResources.selectedRow > 3) + { + for (i = 0; i <= sTMCaseStaticResources.selectedRow - 3 && sTMCaseStaticResources.scrollOffset + sTMCaseDynamicResources->maxTMsShown != sTMCaseDynamicResources->numTMs + 1; i++) + { + do {} while (0); + sTMCaseStaticResources.selectedRow--; + sTMCaseStaticResources.scrollOffset++; + } + } +} + +static void DestroyTMCaseBuffers(void) +{ + if (sTMCaseDynamicResources != NULL) + Free(sTMCaseDynamicResources); + if (sTilemapBuffer != NULL) + Free(sTilemapBuffer); + if (sListMenuItemsBuffer != NULL) + Free(sListMenuItemsBuffer); + if (sListMenuStringsBuffer != NULL) + Free(sListMenuStringsBuffer); + if (sTMSpritePaletteBuffer != NULL) + Free(sTMSpritePaletteBuffer); + FreeAllWindowBuffers(); +} + +static void Task_BeginFadeOutFromTMCase(u8 taskId) +{ + BeginNormalPaletteFade(0xFFFFFFFF, -2, 0, 16, RGB_BLACK); + gTasks[taskId].func = Task_FadeOutAndCloseTMCase; +} + +static void Task_FadeOutAndCloseTMCase(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + if (!gPaletteFade.active) + { + DestroyListMenu(data[0], &sTMCaseStaticResources.scrollOffset, &sTMCaseStaticResources.selectedRow); + if (sTMCaseDynamicResources->savedCallback != NULL) + SetMainCallback2(sTMCaseDynamicResources->savedCallback); + else + SetMainCallback2(sTMCaseStaticResources.savedCallback); + RemoveTMCaseScrollIndicatorArrowPair(); + DestroyTMCaseBuffers(); + DestroyTask(taskId); + } +} + +static void Task_TMCaseMain(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + s32 input; + + if (!gPaletteFade.active) + { + if (sub_80BF72C() != TRUE) + { + input = ListMenuHandleInput(data[0]); + get_coro_args_x18_x1A(data[0], &sTMCaseStaticResources.scrollOffset, &sTMCaseStaticResources.selectedRow); + if (JOY_NEW(SELECT_BUTTON) && sTMCaseStaticResources.unk_05 == 1) + { + PlaySE(SE_SELECT); + gSpecialVar_ItemId = ITEM_NONE; + Task_BeginFadeOutFromTMCase(taskId); + } + else + { + switch (input) + { + case -1: + break; + case -2: + PlaySE(SE_SELECT); + gSpecialVar_ItemId = 0; + Task_BeginFadeOutFromTMCase(taskId); + break; + default: + PlaySE(SE_SELECT); + FillBG2RowWithPalette_2timesNplus1(1); + RemoveTMCaseScrollIndicatorArrowPair(); + PrintListMenuCursorByID_WithColorIdx(data[0], 2); + data[1] = input; + data[2] = BagGetQuantityByPocketPosition(POCKET_TM_CASE, input); + gSpecialVar_ItemId = BagGetItemIdByPocketPosition(POCKET_TM_CASE, input); + gTasks[taskId].func = sSelectTMActionTasks[sTMCaseStaticResources.tmCaseMenuType]; + break; + } + } + } + } +} + +static void Subtask_ReturnToTMCaseMain(u8 taskId) +{ + FillBG2RowWithPalette_2timesNplus1(0); + CreateTMCaseScrollIndicatorArrowPair_Main(); + gTasks[taskId].func = Task_TMCaseMain; +} + +static void Task_SelectTMAction_FromFieldBag(u8 taskId) +{ + u8 * strbuf; + TMCase_SetWindowBorder2(2); + if (!sub_80BF708() && InUnionRoom() != TRUE) + { + AddTMContextMenu(&sTMCaseDynamicResources->contextMenuWindowId, 0); + sTMCaseDynamicResources->menuActionIndices = sMenuActionIndices_Field; + sTMCaseDynamicResources->numMenuActions = NELEMS(sMenuActionIndices_Field); + } + else + { + AddTMContextMenu(&sTMCaseDynamicResources->contextMenuWindowId, 1); + sTMCaseDynamicResources->menuActionIndices = sMenuActionIndices_UnionRoom; + sTMCaseDynamicResources->numMenuActions = NELEMS(sMenuActionIndices_UnionRoom); + } + AddItemMenuActionTextPrinters(sTMCaseDynamicResources->contextMenuWindowId, 2, GetMenuCursorDimensionByFont(2, 0), 2, 0, GetFontAttribute(2, 1) + 2, sTMCaseDynamicResources->numMenuActions, sMenuActions_UseGiveExit, sTMCaseDynamicResources->menuActionIndices); + ProgramAndPlaceMenuCursorOnWindow(sTMCaseDynamicResources->contextMenuWindowId, 2, 0, 2, GetFontAttribute(2, 1) + 2, sTMCaseDynamicResources->numMenuActions, 0); + strbuf = Alloc(256); + GetTMNumberAndMoveString(strbuf, gSpecialVar_ItemId); + StringAppend(strbuf, gText_IsSelected); + AddTextPrinterParameterized_ColorByIndex(2, 2, strbuf, 0, 2, 1, 0, 0, 1); + Free(strbuf); + if (itemid_is_unique(gSpecialVar_ItemId)) + { + PlaceHMTileInWindow(2, 0, 2); + CopyWindowToVram(2, 2); + } + schedule_bg_copy_tilemap_to_vram(0); + schedule_bg_copy_tilemap_to_vram(1); + gTasks[taskId].func = Task_TMContextMenu_HandleInput; +} + +static void Task_TMContextMenu_HandleInput(u8 taskId) +{ + s8 input; + + if (sub_80BF72C() != TRUE) + { + input = ProcessMenuInputNoWrapAround(); + switch (input) + { + case -1: + PlaySE(SE_SELECT); + sMenuActions_UseGiveExit[sTMCaseDynamicResources->menuActionIndices[sTMCaseDynamicResources->numMenuActions - 1]].func.void_u8(taskId); + break; + case -2: + break; + default: + PlaySE(SE_SELECT); + sMenuActions_UseGiveExit[sTMCaseDynamicResources->menuActionIndices[input]].func.void_u8(taskId); + break; + } + } +} + +static void TMHMContextMenuAction_Use(u8 taskId) +{ + RemoveTMContextMenu(&sTMCaseDynamicResources->contextMenuWindowId); + sub_810F4D8(2, 0); + ClearWindowTilemap(2); + PutWindowTilemap(0); + schedule_bg_copy_tilemap_to_vram(0); + schedule_bg_copy_tilemap_to_vram(1); + if (CalculatePlayerPartyCount() == 0) + { + PrintError_ThereIsNoPokemon(taskId); + } + else + { + gUnknown_3005E98 = sub_8125B40; + sTMCaseDynamicResources->savedCallback = sub_8124C8C; + Task_BeginFadeOutFromTMCase(taskId); + } +} + +static void TMHMContextMenuAction_Give(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + u16 itemId = BagGetItemIdByPocketPosition(POCKET_TM_CASE, data[1]); + RemoveTMContextMenu(&sTMCaseDynamicResources->contextMenuWindowId); + sub_810F4D8(2, 0); + ClearWindowTilemap(2); + PutWindowTilemap(1); + PutWindowTilemap(4); + PutWindowTilemap(5); + schedule_bg_copy_tilemap_to_vram(0); + schedule_bg_copy_tilemap_to_vram(1); + if (!itemid_is_unique(itemId)) + { + if (CalculatePlayerPartyCount() == 0) + { + PrintError_ThereIsNoPokemon(taskId); + } + else + { + sTMCaseDynamicResources->savedCallback = sub_8126EDC; + Task_BeginFadeOutFromTMCase(taskId); + } + } + else + { + PrintError_ItemCantBeHeld(taskId); + } +} + +static void PrintError_ThereIsNoPokemon(u8 taskId) +{ + TMCase_PrintMessageWithFollowupTask(taskId, 2, gText_ThereIsNoPokemon, Task_WaitButtonAfterErrorPrint); +} + +static void PrintError_ItemCantBeHeld(u8 taskId) +{ + CopyItemName(gSpecialVar_ItemId, gStringVar1); + StringExpandPlaceholders(gStringVar4, gText_ItemCantBeHeld); + TMCase_PrintMessageWithFollowupTask(taskId, 2, gStringVar4, Task_WaitButtonAfterErrorPrint); +} + +static void Task_WaitButtonAfterErrorPrint(u8 taskId) +{ + if (JOY_NEW(A_BUTTON)) + { + PlaySE(SE_SELECT); + Subtask_CloseContextMenuAndReturnToMain(taskId); + } +} + +static void Subtask_CloseContextMenuAndReturnToMain(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + DestroyListMenu(data[0], &sTMCaseStaticResources.scrollOffset, &sTMCaseStaticResources.selectedRow); + data[0] = ListMenuInit(&gMultiuseListMenuTemplate, sTMCaseStaticResources.scrollOffset, sTMCaseStaticResources.selectedRow); + PrintListMenuCursorByID_WithColorIdx(data[0], 1); + sub_810F260(6, 0); + ClearWindowTilemap(6); + PutWindowTilemap(1); + PutWindowTilemap(4); + PutWindowTilemap(5); + schedule_bg_copy_tilemap_to_vram(0); + schedule_bg_copy_tilemap_to_vram(1); + Subtask_ReturnToTMCaseMain(taskId); +} + +static void TMHMContextMenuAction_Exit(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + RemoveTMContextMenu(&sTMCaseDynamicResources->contextMenuWindowId); + sub_810F4D8(2, 0); + ClearWindowTilemap(2); + PutWindowTilemap(0); + PrintListMenuCursorByID_WithColorIdx(data[0], 1); + PutWindowTilemap(1); + PutWindowTilemap(4); + PutWindowTilemap(5); + schedule_bg_copy_tilemap_to_vram(0); + schedule_bg_copy_tilemap_to_vram(1); + Subtask_ReturnToTMCaseMain(taskId); +} + +static void Task_SelectTMAction_Type1(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + if (!itemid_is_unique(BagGetItemIdByPocketPosition(POCKET_TM_CASE, data[1]))) + { + sTMCaseDynamicResources->savedCallback = c2_8123744; + Task_BeginFadeOutFromTMCase(taskId); + } + else + { + PrintError_ItemCantBeHeld(taskId); + } +} + +static void Task_SelectTMAction_Type3(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + if (!itemid_is_unique(BagGetItemIdByPocketPosition(POCKET_TM_CASE, data[1]))) + { + sTMCaseDynamicResources->savedCallback = sub_808CE60; + Task_BeginFadeOutFromTMCase(taskId); + } + else + { + PrintError_ItemCantBeHeld(taskId); + } +} + +static void Task_SelectTMAction_FromSellMenu(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + if (itemid_get_market_price(gSpecialVar_ItemId) == 0) + { + CopyItemName(gSpecialVar_ItemId, gStringVar1); + StringExpandPlaceholders(gStringVar4, gText_OhNoICantBuyThat); + TMCase_PrintMessageWithFollowupTask(taskId, sub_80BF8E4(), gStringVar4, Subtask_CloseContextMenuAndReturnToMain); + } + else + { + data[8] = 1; + if (data[2] == 1) + { + HandlePrintMoneyOnHand(); + Task_AskConfirmSaleWithAmount(taskId); + } + else + { + if (data[2] > 99) + data[2] = 99; + CopyItemName(gSpecialVar_ItemId, gStringVar1); + StringExpandPlaceholders(gStringVar4, gText_HowManyWouldYouLikeToSell); + TMCase_PrintMessageWithFollowupTask(taskId, sub_80BF8E4(), gStringVar4, Task_InitQuantitySelectUI); + } + } +} + +static void Task_AskConfirmSaleWithAmount(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + ConvertIntToDecimalStringN(gStringVar3, itemid_get_market_price(BagGetItemIdByPocketPosition(POCKET_TM_CASE, data[1])) / 2 * data[8], STR_CONV_MODE_LEFT_ALIGN, 6); + StringExpandPlaceholders(gStringVar4, gText_ICanPayThisMuch_WouldThatBeOkay); + TMCase_PrintMessageWithFollowupTask(taskId, sub_80BF8E4(), gStringVar4, Task_PlaceYesNoBox); +} + +static void Task_PlaceYesNoBox(u8 taskId) +{ + HandleCreateYesNoMenu(taskId, &sYesNoFuncTable); +} + +static void Task_SaleOfTMsCancelled(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + sub_810F4D8(8, 0); + sub_810F260(6, 0); + PutWindowTilemap(0); + PutWindowTilemap(1); + PutWindowTilemap(3); + PutWindowTilemap(4); + PutWindowTilemap(5); + schedule_bg_copy_tilemap_to_vram(0); + schedule_bg_copy_tilemap_to_vram(1); + PrintListMenuCursorByID_WithColorIdx(data[0], 1); + Subtask_ReturnToTMCaseMain(taskId); +} + +static void Task_InitQuantitySelectUI(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + TMCase_SetWindowBorder1(7); + ConvertIntToDecimalStringN(gStringVar1, 1, STR_CONV_MODE_LEADING_ZEROS, 2); + StringExpandPlaceholders(gStringVar4, gText_TimesStrVar1); + AddTextPrinterParameterized_ColorByIndex(7, 0, gStringVar4, 4, 10, 1, 0, 0, 1); + SellTM_PrintQuantityAndSalePrice(1, itemid_get_market_price(BagGetItemIdByPocketPosition(POCKET_TM_CASE, data[1])) / 2 * data[8]); + HandlePrintMoneyOnHand(); + CreateTMCaseScrollIndicatorArrowPair_SellQuantitySelect(); + schedule_bg_copy_tilemap_to_vram(0); + schedule_bg_copy_tilemap_to_vram(1); + gTasks[taskId].func = Task_QuantitySelect_HandleInput; +} + +static void SellTM_PrintQuantityAndSalePrice(s16 quantity, s32 amount) +{ + FillWindowPixelBuffer(7, 0x11); + ConvertIntToDecimalStringN(gStringVar1, quantity, STR_CONV_MODE_LEADING_ZEROS, 2); + StringExpandPlaceholders(gStringVar4, gText_TimesStrVar1); + AddTextPrinterParameterized_ColorByIndex(7, 0, gStringVar4, 4, 10, 1, 0, 0, 1); + PrintMoneyAmount(7, 0x38, 0x0A, amount, 0); +} + +static void Task_QuantitySelect_HandleInput(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + if (sub_80BF848(&data[8], data[2]) == 1) + { + SellTM_PrintQuantityAndSalePrice(data[8], itemid_get_market_price(BagGetItemIdByPocketPosition(POCKET_TM_CASE, data[1])) / 2 * data[8]); + } + else if (JOY_NEW(A_BUTTON)) + { + PlaySE(SE_SELECT); + sub_810F4D8(7, 0); + schedule_bg_copy_tilemap_to_vram(0); + schedule_bg_copy_tilemap_to_vram(1); + RemoveTMCaseScrollIndicatorArrowPair(); + Task_AskConfirmSaleWithAmount(taskId); + } + else if (JOY_NEW(B_BUTTON)) + { + PlaySE(SE_SELECT); + sub_810F4D8(7, 0); + sub_810F4D8(8, 0); + sub_810F260(6, 0); + PutWindowTilemap(3); + PutWindowTilemap(0); + PutWindowTilemap(1); + schedule_bg_copy_tilemap_to_vram(0); + schedule_bg_copy_tilemap_to_vram(1); + RemoveTMCaseScrollIndicatorArrowPair(); + PrintListMenuCursorByID_WithColorIdx(data[0], 1); + Subtask_ReturnToTMCaseMain(taskId); + } +} + +static void Task_PrintSaleConfirmedText(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + PutWindowTilemap(0); + schedule_bg_copy_tilemap_to_vram(0); + CopyItemName(gSpecialVar_ItemId, gStringVar1); + ConvertIntToDecimalStringN(gStringVar3, itemid_get_market_price(BagGetItemIdByPocketPosition(POCKET_TM_CASE, data[1])) / 2 * data[8], STR_CONV_MODE_LEFT_ALIGN, 6); + StringExpandPlaceholders(gStringVar4, gText_TurnedOverItemsWorthYen); + TMCase_PrintMessageWithFollowupTask(taskId, 2, gStringVar4, Task_DoSaleOfTMs); +} + +static void Task_DoSaleOfTMs(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + PlaySE(0xF8); + RemoveBagItem(gSpecialVar_ItemId, data[8]); + AddMoney(&gSaveBlock1Ptr->money, itemid_get_market_price(gSpecialVar_ItemId) / 2 * data[8]); + sub_809C09C(gSpecialVar_ItemId, data[8], 2); + DestroyListMenu(data[0], &sTMCaseStaticResources.scrollOffset, &sTMCaseStaticResources.selectedRow); + TMCaseSetup_GetTMCount(); + TMCaseSetup_InitListMenuPositions(); + InitTMCaseListMenuItems(); + data[0] = ListMenuInit(&gMultiuseListMenuTemplate, sTMCaseStaticResources.scrollOffset, sTMCaseStaticResources.selectedRow); + PrintListMenuCursorByID_WithColorIdx(data[0], 2); + PrintMoneyAmountInMoneyBox(8, GetMoney(&gSaveBlock1Ptr->money), 0); + gTasks[taskId].func = Task_AfterSale_ReturnToList; +} + +static void Task_AfterSale_ReturnToList(u8 taskId) +{ + if (JOY_NEW(A_BUTTON) || JOY_NEW(B_BUTTON)) + { + PlaySE(SE_SELECT); + sub_810F4D8(8, 0); + sub_810F260(6, 0); + PutWindowTilemap(1); + PutWindowTilemap(3); + PutWindowTilemap(4); + PutWindowTilemap(5); + Subtask_CloseContextMenuAndReturnToMain(taskId); + } +} + +void PokeDude_InitTMCase(void) +{ + sPokeDudePackBackup = AllocZeroed(sizeof(*sPokeDudePackBackup)); + memcpy(sPokeDudePackBackup->bagPocket_TMHM, gSaveBlock1Ptr->bagPocket_TMHM, sizeof(gSaveBlock1Ptr->bagPocket_TMHM)); + memcpy(sPokeDudePackBackup->bagPocket_KeyItems, gSaveBlock1Ptr->bagPocket_KeyItems, sizeof(gSaveBlock1Ptr->bagPocket_KeyItems)); + sPokeDudePackBackup->unk_160 = sTMCaseStaticResources.selectedRow; + sPokeDudePackBackup->unk_162 = sTMCaseStaticResources.scrollOffset; + ClearItemSlots(gSaveBlock1Ptr->bagPocket_TMHM, NELEMS(gSaveBlock1Ptr->bagPocket_TMHM)); + ClearItemSlots(gSaveBlock1Ptr->bagPocket_KeyItems, NELEMS(gSaveBlock1Ptr->bagPocket_KeyItems)); + ResetTMCaseCursorPos(); + AddBagItem(ITEM_TM01, 1); + AddBagItem(ITEM_TM03, 1); + AddBagItem(ITEM_TM09, 1); + AddBagItem(ITEM_TM35, 1); + InitTMCase(4, CB2_ReturnToTeachyTV, 0); +} + +static void Task_TMCaseDude1(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + if (!gPaletteFade.active) + { + data[8] = 0; + data[9] = 0; + gTasks[taskId].func = Task_TMCaseDude_Playback; + } +} + +static void Task_TMCaseDude_Playback(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + if (JOY_NEW(B_BUTTON)) + { + if (data[8] < 21) + { + data[8] = 21; + sub_815AC20(); + } + } + + switch (data[8]) + { + case 0: + BeginNormalPaletteFade(0xFFFF8405, 4, 0, 6, 0); + FillBG2RowWithPalette_2timesNplus1(1); + data[8]++; + break; + case 1: + case 11: + if (!gPaletteFade.active) + { + data[9]++; + if (data[9] > 0x65) + { + data[9] = 0; + data[8]++; + } + } + break; + case 2: + case 3: + case 4: + case 12: + case 13: + case 14: + if (data[9] == 0) + { + gMain.newKeys = 0; + gMain.newAndRepeatedKeys = DPAD_DOWN; + ListMenuHandleInput(data[0]); + } + data[9]++; + if (data[9] > 0x65) + { + data[9] = 0; + data[8]++; + } + break; + case 5: + case 6: + case 7: + case 15: + case 16: + case 17: + if (data[9] == 0) + { + gMain.newKeys = 0; + gMain.newAndRepeatedKeys = DPAD_UP; + ListMenuHandleInput(data[0]); + } + data[9]++; + if (data[9] > 0x65) + { + data[9] = 0; + data[8]++; + } + break; + case 8: + FillBG2RowWithPalette_2timesNplus1(1); + TMCase_PrintMessageWithFollowupTask(taskId, 4, gPokeDudeText_TMTypes, 0); + gTasks[taskId].func = Task_TMCaseDude_Playback; + data[8]++; + break; + case 9: + case 19: + RunTextPrinters(); + if (!IsTextPrinterActive(6)) + data[8]++; + break; + case 10: + if (JOY_NEW(A_BUTTON | B_BUTTON)) + { + FillBG2RowWithPalette_2timesNplus1(0); + BeginNormalPaletteFade(0x00000400, 0, 6, 0, 0); + sub_810F260(6, 0); + schedule_bg_copy_tilemap_to_vram(1); + data[8]++; + } + break; + case 18: + FillBG2RowWithPalette_2timesNplus1(1); + TMCase_PrintMessageWithFollowupTask(taskId, 4, gPokeDudeText_ReadTMDescription, NULL); + gTasks[taskId].func = Task_TMCaseDude_Playback; // this function + data[8]++; + break; + case 20: + if (JOY_NEW(A_BUTTON | B_BUTTON)) + data[8]++; + break; + case 21: + if (!gPaletteFade.active) + { + memcpy(gSaveBlock1Ptr->bagPocket_TMHM, sPokeDudePackBackup->bagPocket_TMHM, sizeof(gSaveBlock1Ptr->bagPocket_TMHM)); + memcpy(gSaveBlock1Ptr->bagPocket_KeyItems, sPokeDudePackBackup->bagPocket_KeyItems, sizeof(gSaveBlock1Ptr->bagPocket_KeyItems)); + DestroyListMenu(data[0], NULL, NULL); + sTMCaseStaticResources.selectedRow = sPokeDudePackBackup->unk_160; + sTMCaseStaticResources.scrollOffset = sPokeDudePackBackup->unk_162; + Free(sPokeDudePackBackup); + CpuFastCopy(gPlttBufferFaded, gPlttBufferUnfaded, 0x400); + sub_8108CF0(); + BeginNormalPaletteFade(0xFFFFFFFF, -2, 0, 16, 0); + data[8]++; + } + break; + default: + if (!gPaletteFade.active) + { + SetMainCallback2(sTMCaseStaticResources.savedCallback); + RemoveTMCaseScrollIndicatorArrowPair(); + DestroyTMCaseBuffers(); + DestroyTask(taskId); + } + break; + } +} + +static void InitWindowTemplatesAndPals(void) +{ + u8 i; + + InitWindows(sWindowTemplates); + DeactivateAllTextPrinters(); + sub_815001C(0, 0x5B, 0xE0); + sub_814FEAC(0, 0x64, 0xB0); + sub_814FF2C(0, 0x78, 0xD0); + LoadPalette(gTMCaseMainWindowPalette, 0xF0, 0x20); + LoadPalette(gTMCaseMainWindowPalette, 0xA0, 0x20); + LoadPalette(sPal3Override, 0xF6, 0x04); + LoadPalette(sPal3Override, 0xD6, 0x04); + sub_8107D38(0xc0, 0x01); + for (i = 0; i < 9; i++) + FillWindowPixelBuffer(i, 0x00); + PutWindowTilemap(0); + PutWindowTilemap(1); + PutWindowTilemap(3); + PutWindowTilemap(4); + PutWindowTilemap(5); + schedule_bg_copy_tilemap_to_vram(0); +} + +static void AddTextPrinterParameterized_ColorByIndex(u8 windowId, u8 fontId, const u8 * str, u8 x, u8 y, u8 letterSpacing, u8 lineSpacing, u8 speed, u8 colorIdx) +{ + AddTextPrinterParametrized2(windowId, fontId, x, y, letterSpacing, lineSpacing, &sTextColors[colorIdx], speed, str); +} + +static void TMCase_SetWindowBorder1(u8 windowId) +{ + SetWindowBorderStyle(windowId, FALSE, 0x5B, 0x0E); +} + +static void TMCase_SetWindowBorder2(u8 windowId) +{ + SetWindowBorderStyle(windowId, FALSE, 0x78, 0x0D); +} + +static void TMCase_PrintMessageWithFollowupTask(u8 taskId, u8 windowId, const u8 * str, TaskFunc func) +{ + DisplayMessageAndContinueTask(taskId, 6, 0x64, 0x0B, windowId, GetTextSpeedSetting(), str, func); + schedule_bg_copy_tilemap_to_vram(1); +} + +static void PrintStringTMCaseOnWindow3(void) +{ + u32 distance = 72 - GetStringWidth(1, gText_TMCase, 0); + box_print(3, 1, distance / 2, 1, &sTextColors[0], 0, gText_TMCase); +} + +static void DrawMoveInfoUIMarkers(void) +{ + blit_move_info_icon(4, 19, 0, 0); + blit_move_info_icon(4, 20, 0, 12); + blit_move_info_icon(4, 21, 0, 24); + blit_move_info_icon(4, 22, 0, 36); + CopyWindowToVram(4, 2); +} + +static void TMCase_MoveCursor_UpdatePrintedTMInfo(u16 itemId) +{ + u8 i; + u16 move; + const u8 * str; + + FillWindowPixelRect(5, 0, 0, 0, 40, 48); + if (itemId == ITEM_NONE) + { + for (i = 0; i < 4; i++) + { + AddTextPrinterParameterized_ColorByIndex(5, 3, gText_ThreeHyphens, 7, 12 * i, 0, 0, 0xFF, 3); + } + CopyWindowToVram(5, 2); + } + else + { + move = ItemIdToBattleMoveId(itemId); + blit_move_info_icon(5, gBattleMoves[move].type + 1, 0, 0); + if (gBattleMoves[move].power < 2) + str = gText_ThreeHyphens; + else + { + ConvertIntToDecimalStringN(gStringVar1, gBattleMoves[move].power, STR_CONV_MODE_RIGHT_ALIGN, 3); + str = gStringVar1; + } + AddTextPrinterParameterized_ColorByIndex(5, 3, str, 7, 12, 0, 0, 0xFF, 3); + if (gBattleMoves[move].accuracy == 0) + str = gText_ThreeHyphens; + else + { + ConvertIntToDecimalStringN(gStringVar1, gBattleMoves[move].accuracy, STR_CONV_MODE_RIGHT_ALIGN, 3); + str = gStringVar1; + } + AddTextPrinterParameterized_ColorByIndex(5, 3, str, 7, 24, 0, 0, 0xFF, 3); + ConvertIntToDecimalStringN(gStringVar1, gBattleMoves[move].pp, STR_CONV_MODE_RIGHT_ALIGN, 3); + AddTextPrinterParameterized_ColorByIndex(5, 3, gStringVar1, 7, 36, 0, 0, 0xFF, 3); + CopyWindowToVram(5, 2); + } +} + +static void PlaceHMTileInWindow(u8 windowId, u8 x, u8 y) +{ + BlitBitmapToWindow(windowId, gUnknown_8E99118, x, y, 16, 12); +} + +static void HandlePrintMoneyOnHand(void) +{ + PrintMoneyAmountInMoneyBoxWithBorder(8, 0x78, 0xD, GetMoney(&gSaveBlock1Ptr->money)); +} + +static void HandleCreateYesNoMenu(u8 taskId, const struct YesNoFuncTable *ptrs) +{ + CreateYesNoMenuWithCallbacks(taskId, &sYesNoWindowTemplate, 2, 0, 2, 0x5B, 0x0E, ptrs); +} + +static u8 AddTMContextMenu(u8 * a0, u8 a1) +{ + if (*a0 == 0xFF) + { + *a0 = AddWindow(&sTMContextWindowTemplates[a1]); + TMCase_SetWindowBorder1(*a0); + schedule_bg_copy_tilemap_to_vram(0); + } + return *a0; +} + +static void RemoveTMContextMenu(u8 * a0) +{ + sub_810F4D8(*a0, FALSE); + ClearWindowTilemap(*a0); + RemoveWindow(*a0); + schedule_bg_copy_tilemap_to_vram(0); + *a0 = 0xFF; +} + +static u8 CreateTMSprite(u16 itemId) +{ + u8 spriteId = CreateSprite(&sTMSpriteTemplate, 0x29, 0x2E, 0); + u8 r5; + if (itemId == ITEM_NONE) + { + UpdateTMSpritePosition(&gSprites[spriteId], 0xFF); + return spriteId; + } + else + { + r5 = itemId - 33; + SetTMSpriteAnim(&gSprites[spriteId], r5); + TintTMSpriteByType(gBattleMoves[ItemIdToBattleMoveId(itemId)].type); + UpdateTMSpritePosition(&gSprites[spriteId], r5); + return spriteId; + } +} + +static void SetTMSpriteAnim(struct Sprite * sprite, u8 idx) +{ + if (idx >= 50) + StartSpriteAnim(sprite, 1); + else + StartSpriteAnim(sprite, 0); +} + +static void TintTMSpriteByType(u8 type) +{ + u8 palIndex = IndexOfSpritePaletteTag(TM_CASE_TM_TAG) << 4; + LoadPalette(sTMSpritePaletteBuffer + sTMSpritePaletteOffsetByType[type], 0x100 | palIndex, 0x20); + if (sTMCaseStaticResources.tmCaseMenuType == 4) + { + BlendPalettes(1 << (0x10 + palIndex), 4, RGB_BLACK); + } +} + +static void UpdateTMSpritePosition(struct Sprite * sprite, u8 var) +{ + s32 x, y; + if (var == 0xFF) + { + x = 0x1B; + y = 0x36; + sprite->pos2.y = 0x14; + } + else + { + if (var >= 50) + var -= 50; + else + var += 8; + x = 0x29 - (((0xE00 * var) / 58) >> 8); + y = 0x2E + (((0x800 * var) / 58) >> 8); + } + sprite->pos1.x = x; + sprite->pos1.y = y; +} + +static void InitSelectedTMSpriteData(u8 spriteId, u16 itemId) +{ + gSprites[spriteId].data[0] = itemId; + gSprites[spriteId].data[1] = 0; + gSprites[spriteId].callback = SpriteCB_MoveTMSpriteInCase; +} + +static void SpriteCB_MoveTMSpriteInCase(struct Sprite * sprite) +{ + switch (sprite->data[1]) + { + case 0: + if (sprite->pos2.y >= 20) + { + if (sprite->data[0] != ITEM_NONE) + { + sprite->data[1]++; + TintTMSpriteByType(gBattleMoves[ItemIdToBattleMoveId(sprite->data[0])].type); + sprite->data[0] -= ITEM_TM01; + SetTMSpriteAnim(sprite, sprite->data[0]); + UpdateTMSpritePosition(sprite, sprite->data[0]); + } + else + sprite->callback = SpriteCallbackDummy; + } + else + { + sprite->pos2.y += 10; + } + break; + case 1: + if (sprite->pos2.y <= 0) + sprite->callback = SpriteCallbackDummy; + else + sprite->pos2.y -= 10; + } +} + +static void LoadTMTypePalettes(void) +{ + struct SpritePalette spritePalette; + + sTMSpritePaletteBuffer = Alloc(0x110 * sizeof(u16)); + LZDecompressWram(gUnknown_8E84F20, sTMSpritePaletteBuffer); + LZDecompressWram(gUnknown_8E85068, sTMSpritePaletteBuffer + 0x100); + spritePalette.data = sTMSpritePaletteBuffer + 0x110; + spritePalette.tag = TM_CASE_TM_TAG; + LoadSpritePalette(&spritePalette); +} diff --git a/src/trainer_tower.c b/src/trainer_tower.c index ef34c1629..e914d7ac6 100644 --- a/src/trainer_tower.c +++ b/src/trainer_tower.c @@ -1336,7 +1336,7 @@ void sub_815E720(void) sub_815EC0C(); windowId = AddWindow(gUnknown_847A218); sub_80F6E9C(); - sub_80F6F1C(windowId, FALSE); + DrawStdWindowFrame(windowId, FALSE); AddTextPrinterParameterized(windowId, 2, gUnknown_83FE982, 0x4A, 0, 0xFF, NULL); for (i = 0; i < 4; i++) diff --git a/src/vs_seeker.c b/src/vs_seeker.c index 579800576..9cf6a6e04 100644 --- a/src/vs_seeker.c +++ b/src/vs_seeker.c @@ -663,7 +663,7 @@ static void Task_VsSeeker_3(u8 taskId) { if (sVsSeeker->responseCode == 2) StartAllRespondantIdleMovements(); - sub_80F6F54(0, 1); + ClearDialogWindowAndFrame(0, 1); sub_80696C0(); ScriptContext2_Disable(); DestroyTask(taskId); diff --git a/src/window.c b/src/window.c index e760fc8e4..71cfa6898 100644 --- a/src/window.c +++ b/src/window.c @@ -320,7 +320,7 @@ void PutWindowRectTilemap(u8 windowId, u8 x, u8 y, u8 width, u8 height) } } -void BlitBitmapToWindow(u8 windowId, u8 *pixels, u16 x, u16 y, u16 width, u16 height) +void BlitBitmapToWindow(u8 windowId, const u8 *pixels, u16 x, u16 y, u16 width, u16 height) { BlitBitmapRectToWindow(windowId, pixels, 0, 0, width, height, x, y, width, height); } |