summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/coord_event_weather.c47
-rw-r--r--src/fame_checker.c10
-rw-r--r--src/main.c4
-rw-r--r--src/menu2.c851
-rw-r--r--src/mevent_8145654.c4
-rw-r--r--src/oak_speech.c1891
-rw-r--r--src/roamer.c240
-rw-r--r--src/scanline_effect.c262
-rw-r--r--src/scrcmd.c6
-rw-r--r--src/sound.c18
-rw-r--r--src/text.c10
-rw-r--r--src/tm_case.c1537
-rw-r--r--src/trainer_tower.c2
-rw-r--r--src/vs_seeker.c2
-rw-r--r--src/window.c2
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);
}