summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorProjectRevoTPP <projectrevotpp@hotmail.com>2017-09-09 02:26:54 -0400
committerProjectRevoTPP <projectrevotpp@hotmail.com>2017-09-09 02:26:54 -0400
commit753a09f3c7b33c10ed80d514d90f6b646fb1becb (patch)
tree82306d1734104cbb970caa986242e4dc6c050494 /src
parentf9259ba70d93fdd758075a3c79fd0fe9b65bf185 (diff)
parent99dc97f6aa48646c90def102ce2632be8c45eab9 (diff)
merge
Diffstat (limited to 'src')
-rw-r--r--src/battle/battle_4.c20
-rw-r--r--src/battle/battle_party_menu.c9
-rw-r--r--src/engine/cable_club.c922
-rw-r--r--src/engine/record_mixing.c4
-rw-r--r--src/engine/trainer_card.c2
-rw-r--r--src/field/bard_music.c76
-rw-r--r--src/field/choose_party.c5
-rw-r--r--src/field/daycare.c6
-rw-r--r--src/field/easy_chat.c28
-rw-r--r--src/field/field_ground_effect.c595
-rw-r--r--src/field/mauville_man.c1311
-rw-r--r--src/field/mauville_old_man.c247
-rw-r--r--src/field/party_menu.c11
-rw-r--r--src/field/trader.c47
-rw-r--r--src/field/tv.c22
-rw-r--r--src/libs/m4a_4.c2
-rw-r--r--src/pokemon/mail.c2
-rw-r--r--src/pokemon/pokemon_1.c28
-rw-r--r--src/pokemon/pokemon_3.c2
-rw-r--r--src/pokemon/pokemon_menu.c1197
-rw-r--r--src/scene/evolution_graphics.c9
-rw-r--r--src/scene/evolution_scene.c3966
-rw-r--r--src/scene/new_game.c4
-rw-r--r--src/strings.c4
24 files changed, 7922 insertions, 597 deletions
diff --git a/src/battle/battle_4.c b/src/battle/battle_4.c
index a796ace94..d8141bad1 100644
--- a/src/battle/battle_4.c
+++ b/src/battle/battle_4.c
@@ -82,7 +82,7 @@ extern void (*gBattleMainFunc)(void);
extern struct Window gUnknown_03004210;
extern const u8 gUnknown_08400D7A[];
extern u8 gPlayerPartyCount;
-extern u16 word_2024E82; //move to learn
+extern u16 gMoveToLearn; //move to learn
extern const u8 gTrainerMoney[];
extern u16 gRandomMove;
extern u8* gBattleScriptsEffectsTable[];
@@ -129,7 +129,7 @@ u16 sub_803FBFC(u8 a);
u8 GetBankByPlayerAI(u8 ID);
void sub_8012258(u8);
void sub_80157C4(u8 bank); //update sent pokes in battle
-//sub_803B7C8 teach poke a move
+//MonTryLearningNewMove teach poke a move
u16 GiveMoveToBattleMon(struct BattlePokemon *mon, u16 move);
void IncrementGameStat(u8 index);
u8 GetScaledHPFraction(s16 hp, s16 maxhp, u8 scale);
@@ -11460,9 +11460,9 @@ void atk59_learnmove_inbattle(void)
u8* loc1 = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
u8* loc2 = BSScriptReadPtr(gBattlescriptCurrInstr + 5);
- u16 ret = sub_803B7C8(&gPlayerParty[BATTLE_STRUCT->expGetterID], BSScriptRead8(gBattlescriptCurrInstr + 9));
+ u16 ret = MonTryLearningNewMove(&gPlayerParty[BATTLE_STRUCT->expGetterID], BSScriptRead8(gBattlescriptCurrInstr + 9));
while (ret == 0xFFFE)
- ret = sub_803B7C8(&gPlayerParty[BATTLE_STRUCT->expGetterID], 0);
+ ret = MonTryLearningNewMove(&gPlayerParty[BATTLE_STRUCT->expGetterID], 0);
if (ret == 0)
{
@@ -11549,7 +11549,7 @@ static void atk5A(void)
case 2:
if (!gPaletteFade.active)
{
- sub_809D9F0(gPlayerParty, BATTLE_STRUCT->expGetterID, gPlayerPartyCount - 1, ReshowBattleScreenAfterMenu, word_2024E82);
+ sub_809D9F0(gPlayerParty, BATTLE_STRUCT->expGetterID, gPlayerPartyCount - 1, ReshowBattleScreenAfterMenu, gMoveToLearn);
BATTLE_STRUCT->atk5A_StateTracker++;
}
break;
@@ -11584,18 +11584,18 @@ static void atk5A(void)
}
ptr[0] = 0xFF;
RemoveMonPPBonus(&gPlayerParty[BATTLE_STRUCT->expGetterID], move_pos);
- SetMonMoveSlot(&gPlayerParty[BATTLE_STRUCT->expGetterID], word_2024E82, move_pos);
+ SetMonMoveSlot(&gPlayerParty[BATTLE_STRUCT->expGetterID], gMoveToLearn, move_pos);
if (gBattlePartyID[0] == BATTLE_STRUCT->expGetterID && !(gBattleMons[0].status2 & STATUS2_TRANSFORMED)
&& !(gDisableStructs[0].unk18_b & gBitTable[move_pos]))
{
RemoveBattleMonPPBonus(&gBattleMons[0], move_pos);
- SetBattleMonMoveSlot(&gBattleMons[0], word_2024E82, move_pos);
+ SetBattleMonMoveSlot(&gBattleMons[0], gMoveToLearn, move_pos);
}
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && gBattlePartyID[2] == BATTLE_STRUCT->expGetterID && !(gBattleMons[2].status2 & STATUS2_TRANSFORMED)
&& !(gDisableStructs[2].unk18_b & gBitTable[move_pos]))
{
RemoveBattleMonPPBonus(&gBattleMons[2], move_pos);
- SetBattleMonMoveSlot(&gBattleMons[2], word_2024E82, move_pos);
+ SetBattleMonMoveSlot(&gBattleMons[2], gMoveToLearn, move_pos);
}
}
}
@@ -12653,8 +12653,8 @@ void sub_8024CEC(void)
{
gBattleTextBuff2[0] = 0xFD;
gBattleTextBuff2[1] = 2;
- gBattleTextBuff2[2] = (word_2024E82);
- gBattleTextBuff2[3] = uBYTE1_16(word_2024E82);
+ gBattleTextBuff2[2] = (gMoveToLearn);
+ gBattleTextBuff2[3] = uBYTE1_16(gMoveToLearn);
gBattleTextBuff2[4] = 0xFF;
}
diff --git a/src/battle/battle_party_menu.c b/src/battle/battle_party_menu.c
index 73b847713..49e0b8432 100644
--- a/src/battle/battle_party_menu.c
+++ b/src/battle/battle_party_menu.c
@@ -35,23 +35,16 @@ extern void PartyMenuDrawHPBars(void);
extern u8 sub_806B58C(u8);
extern u8 GetItemEffectType();
extern void sub_806E750(u8, const struct PartyPopupMenu *, const struct PartyMenuItem *, int);
-extern u16 sub_806BD80();
-extern u8 sub_806CA38();
extern void sub_806D5A4(void);
extern void sub_802E414(void);
extern void sub_80A6DCC(void);
extern void sub_806AF4C();
-extern u8 sub_80F9344(void);
-extern u8 sub_806B124(void);
-extern void sub_806C994();
-extern void sub_806BF74();
extern void sub_806AEDC(void);
extern TaskFunc PartyMenuGetPopupMenuFunc(u8, const struct PartyPopupMenu *, const struct PartyMenuItem *, u8);
extern void sub_806E7D0(u8, const struct PartyPopupMenu *);
extern u8 *sub_8040D08();
extern void sub_8040B8C(void);
extern void sub_806E6F0();
-extern void sub_806D538();
extern void nullsub_14();
extern void OpenPartyMenu();
extern u8 sub_803FBBC(void);
@@ -586,7 +579,7 @@ static void Task_809538C(void)
{
do
{
- if (sub_806B124() == 1)
+ if (sub_806B124() == TRUE)
{
sub_806C994(EWRAM_1B000.unk260, gUnknown_020384F0);
sub_806BF74(EWRAM_1B000.unk260, 0);
diff --git a/src/engine/cable_club.c b/src/engine/cable_club.c
index 20b087f4e..b81905cc5 100644
--- a/src/engine/cable_club.c
+++ b/src/engine/cable_club.c
@@ -1,229 +1,350 @@
#include "global.h"
+#include "battle.h"
+#include "battle_records.h"
#include "cable_club.h"
#include "field_message_box.h"
+#include "field_weather.h"
#include "link.h"
+#include "load_save.h"
+#include "m4a.h"
#include "main.h"
+#include "menu.h"
+#include "palette.h"
+#include "record_mixing.h"
+#include "rom4.h"
#include "script.h"
+#include "script_pokemon_80C4.h"
#include "songs.h"
#include "sound.h"
+#include "start_menu.h"
#include "string_util.h"
+#include "strings2.h"
#include "task.h"
#include "text.h"
#include "trainer_card.h"
extern u16 gScriptResult;
extern struct TrainerCard gTrainerCards[4];
-
extern u8 gUnknown_03004860;
extern u8 gFieldLinkPlayerCount;
-
-extern u8 gUnknown_081A4932[];
+extern u16 gSpecialVar_0x8004;
+extern u16 gSpecialVar_0x8005;
+extern u16 gSpecialVar_0x8006;
+extern u16 gBattleTypeFlags;
+extern const u8 gUnknown_081A4932[];
extern const u8 gUnknown_081A4975[];
-
+extern const u8 gUnknown_081A49B6[];
+extern const u8 gUnknown_081A490C[];
+extern const u8* const gTrainerCardColorNames[];
+extern struct
+{
+ u8 field0;
+ u8 field1;
+} gUnknown_020297D8;
+
+static void sub_8082F20(u8 taskId);
+static void sub_8082F68(u8 taskId);
+static void sub_8082FEC(u8 taskId);
+static void sub_808303C(u8 taskId);
static void sub_80830E4(u8 taskId);
+static void sub_8083188(u8 taskId);
static void sub_8083288(u8 taskId);
static void sub_8083314(u8 taskId);
+static void sub_80833C4(u8 taskId);
+static void sub_80833EC(u8 taskId);
+static void sub_8083418(u8 taskId);
+static bool8 sub_8083444(u8 taskId);
+static void sub_808353C(u8 taskId);
+static void sub_8083710(u8 taskId);
+static void sub_8083760(u8 taskId);
+static void sub_80837B4(u8 taskId);
+static void sub_80837EC(u8 taskId);
+static void sub_808382C(u8 taskId);
+static void sub_8083958(void);
+static void sub_80839DC(u8 taskId);
+static void sub_8083AAC(u8 taskId);
+static void sub_8083B44(u8 taskId);
+static void sub_8083B6C(void);
+static void sub_8083CA4(u8 taskId);
+
+extern void sub_80831F8(u8 taskId);
+extern void call_map_music_set_to_zero(void);
+extern void sub_810FEFC(void);
+extern void sub_8047CD8(void);
+extern void sub_805559C(void);
+extern void sub_8055574(void);
+extern s32 sub_80554F8(void);
+extern void sub_805465C(void);
+
+static void sub_8082CD4(u8 arg0, u8 arg1)
+{
+ if (FindTaskIdByFunc(sub_8082F20) == 0xFF)
+ {
+ u8 taskId = CreateTask(sub_8082F20, 80);
+
+ gTasks[taskId].data[1] = arg0;
+ gTasks[taskId].data[2] = arg1;
+ }
+}
+
+static void sub_8082D18(u32 value)
+{
+ ConvertIntToDecimalStringN(gStringVar1, value, STR_CONV_MODE_LEFT_ALIGN, 1);
+ MenuDrawTextWindow(18, 10, 28, 13);
+ sub_8072BD8(gOtherText_PLink, 19, 11, 72);
+}
+
+static void sub_8082D4C()
+{
+ MenuZeroFillWindowRect(18, 10, 28, 13);
+}
+
+static void sub_8082D60(u8 taskId, u8 arg1)
+{
+ s16 *data = &gTasks[taskId].data[3];
+
+ if (arg1 != *data)
+ {
+ if (arg1 <= 1)
+ sub_8082D4C();
+ else
+ sub_8082D18(arg1);
+ *data = arg1;
+ }
+}
+
+static u32 sub_8082D9C(u8 minPlayers, u8 maxPlayers)
+{
+ int playerCount;
+
+ switch (GetLinkPlayerDataExchangeStatusTimed())
+ {
+ case EXCHANGE_COMPLETE:
+ playerCount = GetLinkPlayerCount_2();
+ if (minPlayers <= playerCount && playerCount <= maxPlayers)
+ return 1;
+ ConvertIntToDecimalStringN(gStringVar1, playerCount, STR_CONV_MODE_LEFT_ALIGN, 1);
+ return 4;
+ case EXCHANGE_TIMED_OUT:
+ return 0;
+ case EXCHANGE_IN_PROGRESS:
+ return 3;
+ default:
+ return 0;
+ }
+}
+
+static bool32 sub_8082DF4(u8 taskId)
+{
+ if (HasLinkErrorOccurred() == TRUE)
+ {
+ gTasks[taskId].func = sub_8083418;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static bool32 sub_8082E28(u8 taskId)
+{
+ if ((gMain.newKeys & B_BUTTON)
+ && IsLinkConnectionEstablished() == FALSE)
+ {
+ gTasks[taskId].func = sub_80833EC;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static bool32 sub_8082E6C(u8 taskId)
+{
+ if (IsLinkConnectionEstablished())
+ SetSuppressLinkErrorMessage(TRUE);
+
+ if (gMain.newKeys & B_BUTTON)
+ {
+ gTasks[taskId].func = sub_80833EC;
+ return TRUE;
+ }
+ return FALSE;
+}
-void sub_808303C(u8 taskId) {
- s32 linkPlayerCount;
- s16 *taskData;
+static bool32 sub_8082EB8(u8 taskId)
+{
+ if (GetSioMultiSI() == 1)
+ {
+ gTasks[taskId].func = sub_8083418;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void unref_sub_8082EEC(u8 taskId)
+{
+ gTasks[taskId].data[0]++;
+ if (gTasks[taskId].data[0] == 10)
+ {
+ sub_8007E9C(2);
+ DestroyTask(taskId);
+ }
+}
+
+static void sub_8082F20(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+
+ if (data[0] == 0)
+ {
+ OpenLinkTimed();
+ sub_80082EC();
+ ResetLinkPlayers();
+ }
+ else if (data[0] > 9)
+ {
+ gTasks[taskId].func = sub_8082F68;
+ }
+ data[0]++;
+}
- taskData = gTasks[taskId].data;
+static void sub_8082F68(u8 taskId)
+{
+ u32 playerCount = GetLinkPlayerCount_2();
- linkPlayerCount = GetLinkPlayerCount_2();
+ if (sub_8082E28(taskId) == TRUE
+ || sub_8082E6C(taskId) == TRUE
+ || playerCount < 2)
+ return;
- if (sub_8082E28(taskId) == 1 ||
- sub_8082EB8(taskId) == 1 ||
- sub_8082DF4(taskId) == 1)
+ SetSuppressLinkErrorMessage(TRUE);
+ gTasks[taskId].data[3] = 0;
+ if (IsLinkMaster() == TRUE)
{
+ PlaySE(SE_PIN);
+ ShowFieldAutoScrollMessage(gUnknown_081A4932);
+ gTasks[taskId].func = sub_8082FEC;
+ }
+ else
+ {
+ PlaySE(SE_BOO);
+ ShowFieldAutoScrollMessage(gUnknown_081A49B6);
+ gTasks[taskId].func = sub_80831F8;
+ }
+}
+
+static void sub_8082FEC(u8 taskId)
+{
+ if (sub_8082E28(taskId) == TRUE
+ || sub_8082EB8(taskId) == TRUE
+ || sub_8082DF4(taskId) == TRUE)
return;
+
+ if (GetFieldMessageBoxMode() == FIELD_MESSAGE_BOX_HIDDEN)
+ {
+ gTasks[taskId].data[3] = 0;
+ gTasks[taskId].func = sub_808303C;
}
+}
+
+static void sub_808303C(u8 taskId)
+{
+ s16 *taskData = gTasks[taskId].data;
+ s32 linkPlayerCount = GetLinkPlayerCount_2();
+
+ if (sub_8082E28(taskId) == TRUE
+ || sub_8082EB8(taskId) == TRUE
+ || sub_8082DF4(taskId) == TRUE)
+ return;
sub_8082D60(taskId, linkPlayerCount);
if (!(gMain.newKeys & A_BUTTON))
- {
return;
- }
#if ENGLISH
if (linkPlayerCount < taskData[1])
- {
return;
- }
sub_80081C8(linkPlayerCount);
sub_8082D4C();
- ConvertIntToDecimalStringN(gStringVar1, linkPlayerCount, STR_CONV_MODE_LEFT_ALIGN, 1); // r5
- ShowFieldAutoScrollMessage((u8 *) gUnknown_081A4975);
+ ConvertIntToDecimalStringN(gStringVar1, linkPlayerCount, STR_CONV_MODE_LEFT_ALIGN, 1);
+ ShowFieldAutoScrollMessage((u8 *)gUnknown_081A4975);
gTasks[taskId].func = sub_80830E4;
#elif GERMAN
- if ((gLinkType == 0x2255 && (u32) linkPlayerCount > 1) ||
- (gLinkType != 0x2255 && taskData[1] <= linkPlayerCount))
+ if ((gLinkType == 0x2255 && (u32)linkPlayerCount > 1)
+ || (gLinkType != 0x2255 && taskData[1] <= linkPlayerCount))
{
sub_80081C8(linkPlayerCount);
sub_8082D4C();
- ConvertIntToDecimalStringN(gStringVar1, linkPlayerCount, STR_CONV_MODE_LEFT_ALIGN, 1); // r5
- ShowFieldAutoScrollMessage((u8 *) gUnknown_081A4975);
+ ConvertIntToDecimalStringN(gStringVar1, linkPlayerCount, STR_CONV_MODE_LEFT_ALIGN, 1);
+ ShowFieldAutoScrollMessage((u8 *)gUnknown_081A4975);
gTasks[taskId].func = sub_80830E4;
}
#endif
}
-#ifdef NONMATCHING
-static void sub_80830E4(u8 taskId) {
- if (sub_8082E28(taskId) == 1 ||
- sub_8082EB8(taskId) == 1 ||
- sub_8082DF4(taskId) == 1 ||
- GetFieldMessageBoxMode())
- {
+static void sub_80830E4(u8 taskId)
+{
+ if (sub_8082E28(taskId) == TRUE
+ || sub_8082EB8(taskId) == TRUE
+ || sub_8082DF4(taskId) == TRUE)
return;
- }
- if (sub_800820C() == GetLinkPlayerCount_2() &&
- !(gMain.heldKeys & B_BUTTON))
+ if (GetFieldMessageBoxMode() == FIELD_MESSAGE_BOX_HIDDEN)
{
- ShowFieldAutoScrollMessage(gUnknown_081A4932);
- gTasks[taskId].func = sub_8082FEC;
- return;
+ if (sub_800820C() != GetLinkPlayerCount_2())
+ {
+ ShowFieldAutoScrollMessage(gUnknown_081A4932);
+ gTasks[taskId].func = sub_8082FEC;
+ }
+ else if (gMain.heldKeys & B_BUTTON)
+ {
+ ShowFieldAutoScrollMessage(gUnknown_081A4932);
+ gTasks[taskId].func = sub_8082FEC;
+ }
+ else if (gMain.heldKeys & A_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ sub_8007F4C();
+ gTasks[taskId].func = sub_8083188;
+ }
}
-
- if (gMain.heldKeys & A_BUTTON)
- {
- PlaySE(SE_SELECT);
- sub_8007F4C();
- gTasks[(u32) taskId].func = sub_8083188;
- }
-}
-#else
-__attribute__((naked))
-static void sub_80830E4(u8 taskId) {
- asm(".syntax unified\n\
- push {r4-r6,lr}\n\
- lsls r0, 24\n\
- lsrs r5, r0, 24\n\
- adds r6, r5, 0\n\
- adds r0, r5, 0\n\
- bl sub_8082E28\n\
- cmp r0, 0x1\n\
- beq _08083178\n\
- adds r0, r5, 0\n\
- bl sub_8082EB8\n\
- cmp r0, 0x1\n\
- beq _08083178\n\
- adds r0, r5, 0\n\
- bl sub_8082DF4\n\
- cmp r0, 0x1\n\
- beq _08083178\n\
- bl GetFieldMessageBoxMode\n\
- lsls r0, 24\n\
- cmp r0, 0\n\
- bne _08083178\n\
- bl sub_800820C\n\
- adds r4, r0, 0\n\
- bl GetLinkPlayerCount_2\n\
- lsls r4, 24\n\
- lsls r0, 24\n\
- cmp r4, r0\n\
- bne _08083132\n\
- ldr r0, _08083148 @ =gMain\n\
- ldrh r1, [r0, 0x2C]\n\
- movs r0, 0x2\n\
- ands r0, r1\n\
- cmp r0, 0\n\
- beq _08083158\n\
-_08083132:\n\
- ldr r0, _0808314C @ =gUnknown_081A4932\n\
- bl ShowFieldAutoScrollMessage\n\
- ldr r1, _08083150 @ =gTasks\n\
- lsls r0, r5, 2\n\
- adds r0, r5\n\
- lsls r0, 3\n\
- adds r0, r1\n\
- ldr r1, _08083154 @ =sub_8082FEC\n\
- str r1, [r0]\n\
- b _08083178\n\
- .align 2, 0\n\
-_08083148: .4byte gMain\n\
-_0808314C: .4byte gUnknown_081A4932\n\
-_08083150: .4byte gTasks\n\
-_08083154: .4byte sub_8082FEC\n\
-_08083158:\n\
- movs r0, 0x1\n\
- ands r0, r1\n\
- cmp r0, 0\n\
- beq _08083178\n\
- movs r0, 0x5\n\
- bl PlaySE\n\
- bl sub_8007F4C\n\
- ldr r0, _08083180 @ =gTasks\n\
- lsls r1, r6, 2\n\
- adds r1, r6\n\
- lsls r1, 3\n\
- adds r1, r0\n\
- ldr r0, _08083184 @ =sub_8083188\n\
- str r0, [r1]\n\
-_08083178:\n\
- pop {r4-r6}\n\
- pop {r0}\n\
- bx r0\n\
- .align 2, 0\n\
-_08083180: .4byte gTasks\n\
-_08083184: .4byte sub_8083188\n\
- .syntax divided\n");
}
-#endif
-
-void sub_8083188(u8 taskId) {
- u8 local1, local2;
- u16 *result;
- local1 = gTasks[taskId].data[1];
- local2 = gTasks[taskId].data[2];
+static void sub_8083188(u8 taskId)
+{
+ u8 local1 = gTasks[taskId].data[1];
+ u8 local2 = gTasks[taskId].data[2];
-
- if (sub_8082DF4(taskId) == 1 ||
- sub_8083444(taskId) == 1)
- {
+ if (sub_8082DF4(taskId) == TRUE
+ || sub_8083444(taskId) == TRUE)
return;
- }
if (GetLinkPlayerCount_2() != sub_800820C())
{
gTasks[taskId].func = sub_8083418;
- return;
}
-
- result = &gScriptResult;
- *result = sub_8082D9C(local1, local2);
- if (*result)
+ else
{
- gTasks[taskId].func = sub_8083288;
+ gScriptResult = sub_8082D9C(local1, local2);
+ if (gScriptResult != 0)
+ gTasks[taskId].func = sub_8083288;
}
}
-void sub_80831F8(u8 taskId) {
+void sub_80831F8(u8 taskId)
+{
u8 local1, local2;
- u16 *result;
local1 = gTasks[taskId].data[1];
local2 = gTasks[taskId].data[2];
- if (sub_8082E28(taskId) == 1 ||
- sub_8082DF4(taskId) == 1)
- {
+ if (sub_8082E28(taskId) == TRUE
+ || sub_8082DF4(taskId) == TRUE)
return;
- }
- result = &gScriptResult;
- *result = sub_8082D9C(local1, local2);
- if (*result == 0)
- {
+ gScriptResult = sub_8082D9C(local1, local2);
+ if (gScriptResult == 0)
return;
- }
-
-
- if (*result == 3)
+ if (gScriptResult == 3)
{
sub_800832C();
HideFieldMessageBox();
@@ -234,16 +355,15 @@ void sub_80831F8(u8 taskId) {
gFieldLinkPlayerCount = GetLinkPlayerCount_2();
gUnknown_03004860 = GetMultiplayerId();
sub_80081C8(gFieldLinkPlayerCount);
- sub_8093390((struct TrainerCard *) gBlockSendBuffer);
+ sub_8093390((struct TrainerCard *)gBlockSendBuffer);
gTasks[taskId].func = sub_8083314;
}
}
-static void sub_8083288(u8 taskId) {
- if (sub_8082DF4(taskId) == 1)
- {
+static void sub_8083288(u8 taskId)
+{
+ if (sub_8082DF4(taskId) == TRUE)
return;
- }
if (gScriptResult == 3)
{
@@ -256,26 +376,22 @@ static void sub_8083288(u8 taskId) {
gFieldLinkPlayerCount = GetLinkPlayerCount_2();
gUnknown_03004860 = GetMultiplayerId();
sub_80081C8(gFieldLinkPlayerCount);
- sub_8093390((struct TrainerCard *) gBlockSendBuffer);
+ sub_8093390((struct TrainerCard *)gBlockSendBuffer);
gTasks[taskId].func = sub_8083314;
sub_8007E9C(2);
}
}
-static void sub_8083314(u8 taskId) {
+static void sub_8083314(u8 taskId)
+{
u8 index;
-
struct TrainerCard *trainerCards;
- if (sub_8082DF4(taskId) == 1)
- {
+ if (sub_8082DF4(taskId) == TRUE)
return;
- }
if (GetBlockReceivedStatus() != sub_8008198())
- {
return;
- }
index = 0;
trainerCards = gTrainerCards;
@@ -296,14 +412,12 @@ static void sub_8083314(u8 taskId) {
u16 linkType;
linkType = gLinkType;
// FIXME: sub_8082D4C doesn't take any arguments
- sub_8082D4C(0x00004411, linkType);
+ sub_8082D4C(0x4411, linkType);
#elif GERMAN
if (gLinkType != 0x4411)
{
if (gLinkType == 0x6601)
- {
deUnkValue2 = 1;
- }
}
sub_8082D4C();
#endif
@@ -315,3 +429,477 @@ static void sub_8083314(u8 taskId) {
sub_800832C();
gTasks[taskId].func = sub_80833C4;
}
+
+static void sub_80833C4(u8 taskId)
+{
+ if (gReceivedRemoteLinkPlayers == FALSE)
+ {
+ sub_8082D4C();
+ EnableBothScriptContexts();
+ DestroyTask(taskId);
+ }
+}
+
+static void sub_80833EC(u8 taskId)
+{
+ gScriptResult = 5;
+ sub_8082D4C();
+ HideFieldMessageBox();
+ EnableBothScriptContexts();
+ DestroyTask(taskId);
+}
+
+static void sub_8083418(u8 taskId)
+{
+ gScriptResult = 6;
+ sub_8082D4C();
+ HideFieldMessageBox();
+ EnableBothScriptContexts();
+ DestroyTask(taskId);
+}
+
+static bool8 sub_8083444(u8 taskId)
+{
+ gTasks[taskId].data[4]++;
+ if (gTasks[taskId].data[4] > 600)
+ {
+ gTasks[taskId].func = sub_8083418;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void sub_808347C(u8 arg0)
+{
+ u32 r3 = 2;
+ u32 r2 = 2;
+
+ switch (gSpecialVar_0x8004)
+ {
+ case 1:
+ r3 = 2;
+ gLinkType = 0x2233;
+ break;
+ case 2:
+ r3 = 2;
+ gLinkType = 0x2244;
+ break;
+ case 5:
+ r3 = 4;
+ r2 = 4;
+ gLinkType = 0x2255;
+ break;
+ }
+
+ sub_8082CD4(r3, r2);
+}
+
+void sub_80834E4(void)
+{
+ gLinkType = 0x1133;
+ gBattleTypeFlags = 0;
+ sub_8082CD4(2, 2);
+}
+
+void sub_808350C(void)
+{
+ gScriptResult = 0;
+ gLinkType = 0x3311;
+ gBattleTypeFlags = 0;
+ sub_8082CD4(2, 4);
+}
+
+static void sub_808353C(u8 taskId)
+{
+ int playerCount;
+ int i;
+
+ switch (gTasks[taskId].data[0])
+ {
+ case 0:
+ if (gScriptResult == 1)
+ {
+ playerCount = GetLinkPlayerCount();
+ for (i = 0; i < playerCount; i++)
+ {
+ if (gLinkPlayers[i].language == LANGUAGE_JAPANESE)
+ {
+ gScriptResult = 7;
+ sub_8008480();
+ gTasks[taskId].data[0] = 1;
+ return;
+ }
+ }
+ }
+ EnableBothScriptContexts();
+ DestroyTask(taskId);
+ break;
+ case 1:
+ if (gReceivedRemoteLinkPlayers == FALSE)
+ {
+ EnableBothScriptContexts();
+ DestroyTask(taskId);
+ }
+ break;
+ }
+}
+
+void sub_80835D8(void)
+{
+ int taskId = FindTaskIdByFunc(sub_808353C);
+
+ if (taskId == 0xFF)
+ {
+ taskId = CreateTask(sub_808353C, 80);
+ gTasks[taskId].data[0] = 0;
+ }
+}
+
+void sub_8083614(void)
+{
+ gLinkType = 0x4411;
+ gBattleTypeFlags = 0;
+ sub_8082CD4(2, 4);
+}
+
+void sub_808363C(void)
+{
+ gLinkType = 0x6601;
+ gBattleTypeFlags = 0;
+ sub_8082CD4(4, 4);
+}
+
+u8 sub_8083664(void)
+{
+ if (FuncIsActiveTask(sub_8083710) != FALSE)
+ return 0xFF;
+
+ switch (gSpecialVar_0x8004)
+ {
+ case 1:
+ gLinkType = 0x2233;
+ break;
+ case 2:
+ gLinkType = 0x2244;
+ break;
+ case 5:
+ gLinkType = 0x2255;
+ break;
+ case 3:
+ gLinkType = 0x1111;
+ break;
+ case 4:
+ gLinkType = 0x3322;
+ break;
+ }
+
+ return CreateTask(sub_8083710, 80);
+}
+
+static void sub_8083710(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+
+ if (data[0] == 0)
+ {
+ OpenLink();
+ ResetLinkPlayers();
+ CreateTask(sub_8083C50, 80);
+ }
+ else if (data[0] >= 10)
+ {
+ gTasks[taskId].func = sub_8083760;
+ }
+ data[0]++;
+}
+
+static void sub_8083760(u8 taskId)
+{
+ if (GetLinkPlayerCount_2() >= 2)
+ {
+ if (IsLinkMaster() == TRUE)
+ gTasks[taskId].func = sub_80837B4;
+ else
+ gTasks[taskId].func = sub_80837EC;
+ }
+}
+
+static void sub_80837B4(u8 taskId)
+{
+ if (sub_800820C() == GetLinkPlayerCount_2())
+ {
+ sub_8007F4C();
+ gTasks[taskId].func = sub_80837EC;
+ }
+}
+
+static void sub_80837EC(u8 taskId)
+{
+ if (gReceivedRemoteLinkPlayers == TRUE
+ && IsLinkPlayerDataExchangeComplete() == TRUE)
+ {
+ sub_800826C();
+ sub_8007B14();
+ DestroyTask(taskId);
+ }
+}
+
+void sub_8083820(void)
+{
+ InitSaveDialog();
+}
+
+static void sub_808382C(u8 taskId)
+{
+ struct Task* task = &gTasks[taskId];
+
+ switch (task->data[0])
+ {
+ case 0:
+ fade_screen(1, 0);
+ gLinkType = 0x2211;
+ ClearLinkCallback_2();
+ task->data[0]++;
+ break;
+ case 1:
+ if (!gPaletteFade.active)
+ task->data[0]++;
+ break;
+ case 2:
+ task->data[1]++;
+ if (task->data[1] > 20)
+ task->data[0]++;
+ break;
+ case 3:
+ sub_800832C();
+ task->data[0]++;
+ break;
+ case 4:
+ if (!gReceivedRemoteLinkPlayers)
+ task->data[0]++;
+ break;
+ case 5:
+ if (gLinkPlayers[0].trainerId & 1)
+ current_map_music_set__default_for_battle(BGM_BATTLE32);
+ else
+ current_map_music_set__default_for_battle(BGM_BATTLE20);
+
+ switch (gSpecialVar_0x8004)
+ {
+ case 1:
+ gBattleTypeFlags = BATTLE_TYPE_TRAINER | BATTLE_TYPE_LINK;
+ break;
+ case 2:
+ gBattleTypeFlags = BATTLE_TYPE_TRAINER | BATTLE_TYPE_LINK | BATTLE_TYPE_DOUBLE;
+ break;
+ case 5:
+ ReducePlayerPartyToThree();
+ gBattleTypeFlags = BATTLE_TYPE_TRAINER | BATTLE_TYPE_LINK | BATTLE_TYPE_DOUBLE | BATTLE_TYPE_MULTI;
+ break;
+ }
+
+ SetMainCallback2(sub_800E7C4);
+ gMain.savedCallback = sub_8083958;
+ DestroyTask(taskId);
+ break;
+ }
+}
+
+static void sub_8083958(void)
+{
+ call_map_music_set_to_zero();
+ LoadPlayerParty();
+ SavePlayerBag();
+ sub_810FEFC();
+
+ if (gSpecialVar_0x8004 != 5)
+ UpdateLinkBattleRecords(gUnknown_03004860 ^ 1);
+
+ gMain.savedCallback = sub_805465C;
+ SetMainCallback2(sub_8071B28);
+}
+
+void sub_80839A4(void)
+{
+ if (gSpecialVar_0x8004 == 1 || gSpecialVar_0x8004 == 2 || gSpecialVar_0x8004 == 5)
+ {
+ LoadPlayerParty();
+ SavePlayerBag();
+ }
+ copy_saved_warp2_bank_and_enter_x_to_warp1(0x7F);
+}
+
+void sub_80839D0(void)
+{
+ sub_805559C();
+}
+
+static void sub_80839DC(u8 taskId)
+{
+ struct Task* task = &gTasks[taskId];
+
+ switch (task->data[0])
+ {
+ case 0:
+ ShowFieldMessage(gUnknown_081A490C);
+ task->data[0] = 1;
+ break;
+ case 1:
+ if (IsFieldMessageBoxHidden())
+ {
+ sub_8055574();
+ sub_8007270(gSpecialVar_0x8005);
+ task->data[0] = 2;
+ }
+ break;
+ case 2:
+ switch (sub_80554F8())
+ {
+ case 0:
+ break;
+ case 1:
+ HideFieldMessageBox();
+ task->data[0] = 0;
+ SwitchTaskToFollowupFunc(taskId);
+ break;
+ case 2:
+ task->data[0] = 3;
+ break;
+ }
+ break;
+ case 3:
+ sub_8055588();
+ HideFieldMessageBox();
+ MenuZeroFillScreen();
+ DestroyTask(taskId);
+ EnableBothScriptContexts();
+ break;
+ }
+}
+
+void sub_8083A84(TaskFunc followupFunc)
+{
+ u8 taskId = CreateTask(sub_80839DC, 80);
+ SetTaskFuncWithFollowupFunc(taskId, sub_80839DC, followupFunc);
+ ScriptContext1_Stop();
+}
+
+static void sub_8083AAC(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ switch (task->data[0])
+ {
+ case 0:
+ ScriptContext2_Enable();
+ fade_screen(1, 0);
+ ClearLinkCallback_2();
+ task->data[0]++;
+ break;
+ case 1:
+ if (!gPaletteFade.active)
+ task->data[0]++;
+ break;
+ case 2:
+ gUnknown_020297D8.field0 = 0;
+ gUnknown_020297D8.field1 = 0;
+ m4aMPlayAllStop();
+ sub_800832C();
+ task->data[0]++;
+ break;
+ case 3:
+ if (!gReceivedRemoteLinkPlayers)
+ {
+ SetMainCallback2(sub_8047CD8);
+ DestroyTask(taskId);
+ }
+ break;
+ }
+}
+
+static void sub_8083B44(u8 taskId)
+{
+ sub_8083B6C();
+ DestroyTask(taskId);
+}
+
+void sub_8083B5C(void)
+{
+ sub_8083A84(sub_8083B44);
+}
+
+static void sub_8083B6C(void)
+{
+ CreateTask(sub_8083AAC, 80);
+}
+
+void sub_8083B80(void)
+{
+ sub_8083B6C();
+ ScriptContext1_Stop();
+}
+
+void sub_8083B90(void)
+{
+ gLinkType = 0x2211;
+ sub_8083A84(sub_808382C);
+}
+
+void unref_sub_8083BB0(void)
+{
+ u8 taskId = CreateTask(sub_80839DC, 80);
+ SetTaskFuncWithFollowupFunc(taskId, sub_80839DC, Task_RecordMixing_Main);
+ ScriptContext1_Stop();
+}
+
+void sub_8083BDC(void)
+{
+ sub_8093130(gSpecialVar_0x8006, c2_exit_to_overworld_1_continue_scripts_restart_music);
+}
+
+bool32 sub_8083BF4(u8 linkPlayerIndex)
+{
+ u32 trainerCardColorIndex;
+
+ gSpecialVar_0x8006 = linkPlayerIndex;
+ StringCopy(gStringVar1, gLinkPlayers[linkPlayerIndex].name);
+
+ trainerCardColorIndex = sub_80934C4(linkPlayerIndex);
+ if (trainerCardColorIndex == 0)
+ return FALSE;
+
+ StringCopy(gStringVar2, gTrainerCardColorNames[trainerCardColorIndex - 1]);
+ return TRUE;
+}
+
+void sub_8083C50(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ task->data[0]++;
+ if (task->data[0] > 300)
+ {
+ CloseLink();
+ SetMainCallback2(CB2_LinkError);
+ DestroyTask(taskId);
+ }
+
+ if (gReceivedRemoteLinkPlayers)
+ DestroyTask(taskId);
+}
+
+static void sub_8083CA4(u8 taskId)
+{
+ if (!gReceivedRemoteLinkPlayers)
+ {
+ EnableBothScriptContexts();
+ DestroyTask(taskId);
+ }
+}
+
+void unref_sub_8083CC8(u8 taskId)
+{
+ sub_800832C();
+ gTasks[taskId].func = sub_8083CA4;
+} \ No newline at end of file
diff --git a/src/engine/record_mixing.c b/src/engine/record_mixing.c
index d1083910c..30bcb29d1 100644
--- a/src/engine/record_mixing.c
+++ b/src/engine/record_mixing.c
@@ -10,7 +10,7 @@
#include "items.h"
#include "load_save.h"
#include "link.h"
-#include "mauville_old_man.h"
+#include "mauville_man.h"
#include "menu.h"
#include "mystery_event_script.h"
#include "rng.h"
@@ -40,7 +40,7 @@ static u8 gUnknown_0300071C[4];
void *recordMixingSecretBases = &gSaveBlock1.secretBases;
void *recordMixingTvShows = &gSaveBlock1.tvShows;
void *gUnknown_083D0274 = &gSaveBlock1.unknown_2ABC;
-void *gUnknown_083D0278 = &gSaveBlock1.oldMan;
+void *gUnknown_083D0278 = &gSaveBlock1.mauvilleMan;
void *recordMixingEasyChatPairs = &gSaveBlock1.easyChatPairs;
struct RecordMixing_UnknownStruct *gUnknown_083D0280 = &gUnknown_02038738;
void *gUnknown_083D0284 = &gSaveBlock2.filler_A8;
diff --git a/src/engine/trainer_card.c b/src/engine/trainer_card.c
index 626c5a7bf..e64ec1c86 100644
--- a/src/engine/trainer_card.c
+++ b/src/engine/trainer_card.c
@@ -509,7 +509,7 @@ static void sub_8093688(void)
ewram0.var_5 = 0;
ewram0.var_6 = 0;
for (i = 0; i < 4; i++)
- sub_80EB3FC(ewram0.var_20[i], ewram0.var_64.var_28[i]);
+ EasyChat_GetWordText(ewram0.var_20[i], ewram0.var_64.var_28[i]);
sub_80936D4();
}
diff --git a/src/field/bard_music.c b/src/field/bard_music.c
index a31568475..daf003233 100644
--- a/src/field/bard_music.c
+++ b/src/field/bard_music.c
@@ -1,71 +1,43 @@
#include "global.h"
+#include "bard_music.h"
#include "easy_chat.h"
struct BardSound
{
- u8 pad_00[48];
-};
-
-struct UnkBard
-{
/*0x00*/ u8 var00;
/*0x01*/ s8 var01;
/*0x02*/ u16 var02;
- /*0x04*/ u16 var04;
+ /*0x04*/ u16 volume;
/*0x06*/ u16 var06;
};
-struct UnkBard3
-{
- /*0x00*/ u16 var00;
- /*0x02*/ u16 var02;
- /*0x04*/ s16 var04;
- /*0x06*/ u16 var06;
-};
-
-struct UnkBard2
-{
- /*0x00*/ u8 var00;
- /*0x01*/ u8 var01;
- /*0x02*/ u8 var02;
- /*0x03*/ u8 var03;
- /*0x04*/ u16 var04;
- u8 pad06[4];
- /*0x0A*/ u16 var0A;
- u8 pad0C[12];
- /*0x18*/ struct UnkBard3 var18[6];
-};
-
-extern struct BardSound *gBardMusicTable[];
+extern const struct BardSound (*const gBardMusicTable[])[][6];
extern s16 *gUnknown_08417068[];
extern u32 gUnknown_084170F4[];
-static s16 sub_814A2B8(u32 arg0, u32 arg1)
+static s16 CalcWordPitch(u32 arg0, u32 songPos)
{
- return gUnknown_08417068[arg0][arg1];
+ return gUnknown_08417068[arg0][songPos];
}
#if ENGLISH
-struct BardSound *sub_814A2D0(u16 arg0, u16 arg1)
+const struct BardSound *GetWordSounds(u16 group, u16 word)
{
- struct BardSound *sounds = gBardMusicTable[arg0];
+ const struct BardSound (*sounds)[][6] = gBardMusicTable[group];
- return &sounds[arg1];
+ return (*sounds)[word];
}
#elif GERMAN
-struct BardSound *sub_814A2D0(u16 arg0, u16 arg1)
+const struct BardSound *GetWordSounds(u16 group, u16 word)
{
- u32 index;
- struct BardSound *sounds;
-
- sounds = gBardMusicTable[arg0];
- index = de_sub_80EB748(arg0, arg1);
+ const struct BardSound (*sounds)[][6] = gBardMusicTable[group];
+ u32 index = de_sub_80EB748(group, word);
- return &sounds[index];
+ return (*sounds)[index];
}
#endif
-s32 sub_814A2EC(struct UnkBard2 *dest, struct UnkBard *src, u16 arg2)
+s32 GetWordPhonemes(struct BardSong *song, const struct BardSound *src, u16 arg2)
{
s32 i;
s32 j;
@@ -73,25 +45,25 @@ s32 sub_814A2EC(struct UnkBard2 *dest, struct UnkBard *src, u16 arg2)
for (i = 0; i < 6; i++)
{
- dest->var18[i].var00 = src[i].var00;
+ song->phonemes[i].sound = src[i].var00;
if (src[i].var00 != 0xFF)
{
- s32 r1 = src[i].var01 +gUnknown_084170F4[src[i].var00];
+ s32 length = src[i].var01 + gUnknown_084170F4[src[i].var00];
- dest->var18[i].var02 = r1;
- dest->var18[i].var06 = src[i].var04;
- dest->var04 += r1;
+ song->phonemes[i].length = length;
+ song->phonemes[i].volume = src[i].volume;
+ song->var04 += length;
}
}
for (j = 0, thirty = 30; j < i; j++)
- dest->var18[j].var04 = sub_814A2B8(thirty + arg2, j);
+ song->phonemes[j].pitch = CalcWordPitch(thirty + arg2, j);
- dest->var00++;
- dest->var01 = 0;
- dest->var02 = 0;
- dest->var03 = 0;
- dest->var0A = 0;
+ song->currWord++;
+ song->currPhoneme = 0;
+ song->phonemeTimer = 0;
+ song->state = 0;
+ song->voiceInflection = 0;
//warning: no return statement in function returning non-void
}
diff --git a/src/field/choose_party.c b/src/field/choose_party.c
index 7b2c833e1..27181cf74 100644
--- a/src/field/choose_party.c
+++ b/src/field/choose_party.c
@@ -6,6 +6,7 @@
#include "name_string_util.h"
#include "palette.h"
#include "party_menu.h"
+#include "pokemon_menu.h"
#include "pokemon.h"
#include "pokemon_summary_screen.h"
#include "rom4.h"
@@ -50,10 +51,8 @@ extern void PartyMenuPrintMonsLevelOrStatus(void);
extern void PrintPartyMenuMonNicknames(void);
extern void sub_806BC3C(u8, u8);
extern u8 sub_806B58C(u8);
-extern void sub_806D538();
extern u16 sub_806BE38();
extern u8 sub_806CA38();
-extern void sub_808B5B4();
extern TaskFunc PartyMenuGetPopupMenuFunc(u8, const struct PartyPopupMenu *, const struct PartyMenuItem *, u8);
extern u8 sub_806B124();
extern void sub_806C994();
@@ -84,8 +83,6 @@ extern void PartyMenuDoPutNicknameTilemap(u16, u8, u8, u8, const u8 *);
extern void box_print(u8, int, const u8 *);
extern void sub_806BCE8(void);
extern void sub_806E750(u8, const struct PartyPopupMenu *, const struct PartyMenuItem *, int);
-extern u16 sub_806BD80();
-extern void sub_806BF74();
static void ClearPartySelection(void);
static bool8 IsMonAllowedInBattleTower(struct Pokemon *);
diff --git a/src/field/daycare.c b/src/field/daycare.c
index cded18207..7f688016a 100644
--- a/src/field/daycare.c
+++ b/src/field/daycare.c
@@ -209,7 +209,7 @@ void sub_80414C0(struct BoxPokemon * daycare_data)
}
u8 TryIncrementMonLevel(struct Pokemon *);
-extern u16 word_2024E82;
+extern u16 gMoveToLearn;
void sub_804151C(struct Pokemon * mon)
{
@@ -221,10 +221,10 @@ void sub_804151C(struct Pokemon * mon)
if(TryIncrementMonLevel(mon) == FALSE) goto end;
r6 = 1;
- while((temp = sub_803B7C8(mon, r6)) != 0){
+ while((temp = MonTryLearningNewMove(mon, r6)) != 0){
r6 = 0;
if(temp == 0xffff){
- DeleteFirstMoveAndGiveMoveToMon(mon, word_2024E82);
+ DeleteFirstMoveAndGiveMoveToMon(mon, gMoveToLearn);
}
}
}
diff --git a/src/field/easy_chat.c b/src/field/easy_chat.c
index cca8c1355..dd33e69c3 100644
--- a/src/field/easy_chat.c
+++ b/src/field/easy_chat.c
@@ -19,8 +19,8 @@ extern const u8 gEasyChatGroupSizes[];
extern u16 gSpecialVar_0x8004;
-
-u8 *sub_80EB3FC(u8 *dst, u16 word)
+// returns the end of the destination buffer text
+u8 *EasyChat_GetWordText(u8 *dst, u16 word)
{
u16 group;
u16 wordIndex;
@@ -32,13 +32,13 @@ u8 *sub_80EB3FC(u8 *dst, u16 word)
if (word == 0xFFFF)
{
- dst[0] = EOS;
+ *dst = EOS;
return dst;
}
else
{
- group = word >> 9;
- wordIndex = word & 0x1FF;
+ group = EC_GROUP(word);
+ wordIndex = EC_INDEX(word);
switch (group)
{
case EC_GROUP_POKEMON: // 0
@@ -59,7 +59,7 @@ u8 *sub_80EB3FC(u8 *dst, u16 word)
dst = StringCopy(dst, src);
break;
}
- dst[0] = EOS;
+ *dst = EOS;
return dst;
}
}
@@ -77,7 +77,7 @@ u8 *ConvertEasyChatWordsToString(u8 *dst, u16 *words, u16 arg2, u16 arg3)
for (n = 0; n < i1; n++)
{
- dst = sub_80EB3FC(dst, words[0]);
+ dst = EasyChat_GetWordText(dst, words[0]);
if (words[0] != 0xFFFF)
{
@@ -90,7 +90,7 @@ u8 *ConvertEasyChatWordsToString(u8 *dst, u16 *words, u16 arg2, u16 arg3)
word = words[0];
words++;
- dst = sub_80EB3FC(dst, word);
+ dst = EasyChat_GetWordText(dst, word);
dst[0] = CHAR_NEWLINE;
dst++;
@@ -115,7 +115,7 @@ u8 *sub_80EB544(u8 *dst, u16 *words, u16 arg2, u16 arg3)
for (n = 0; n < i1; n++)
{
- dst = sub_80EB3FC(dst, words[0]);
+ dst = EasyChat_GetWordText(dst, words[0]);
if (words[0] != 0xFFFF)
{
@@ -128,7 +128,7 @@ u8 *sub_80EB544(u8 *dst, u16 *words, u16 arg2, u16 arg3)
word = words[0];
words++;
- dst = sub_80EB3FC(dst, word);
+ dst = EasyChat_GetWordText(dst, word);
// Only difference with ConvertEasyChatWordsToString
dst[0] = (i == 0) ? CHAR_NEWLINE : CHAR_PROMPT_SCROLL;
@@ -144,7 +144,7 @@ u8 *sub_80EB544(u8 *dst, u16 *words, u16 arg2, u16 arg3)
u16 unref_sub_80EB5E0(u16 arg0)
{
- u8 *chars;
+ const u8 *chars;
u16 i;
u16 length;
int group, word;
@@ -153,8 +153,8 @@ u16 unref_sub_80EB5E0(u16 arg0)
if (arg0 == 0xFFFF)
return 0;
- group = arg0 >> 9;
- word = arg0 & 0x1FF;
+ group = EC_GROUP(arg0);
+ word = EC_INDEX(arg0);
switch (group)
{
case EC_GROUP_POKEMON: // 0
@@ -321,7 +321,7 @@ void sub_80EB83C(void)
group = EC_GROUP_LIFESTYLE;
local2 = sub_80EB784(group);
- sub_80EB3FC(gStringVar2, local2);
+ EasyChat_GetWordText(gStringVar2, local2);
}
u8 sub_80EB868(u8 arg0)
diff --git a/src/field/field_ground_effect.c b/src/field/field_ground_effect.c
index 42862d0ff..b9935463b 100644
--- a/src/field/field_ground_effect.c
+++ b/src/field/field_ground_effect.c
@@ -1,11 +1,38 @@
#include "global.h"
#include "field_ground_effect.h"
+#include "field_effect.h"
+#include "field_effect_helpers.h"
+#include "field_map_obj_helpers.h"
#include "fieldmap.h"
#include "metatile_behavior.h"
-extern u32 gUnknown_08376008[];
+static void nullsub(struct MapObject *mapObj, struct Sprite *sprite, u8);
+static void DoTracksGroundEffect_Footprints(struct MapObject *mapObj, struct Sprite *sprite, u8);
+static void DoTracksGroundEffect_BikeTireTracks(
+ struct MapObject *mapObj, struct Sprite *sprite, u8);
+void GroundEffect_SpawnOnTallGrass(struct MapObject *mapObj, struct Sprite *sprite);
+void sub_8063E94(struct MapObject *mapObj, struct Sprite *sprite);
+void sub_8063EE0(struct MapObject *mapObj, struct Sprite *sprite);
+void sub_8063F2C(struct MapObject *mapObj, struct Sprite *sprite);
+void GroundEffect_WaterReflection(struct MapObject *mapObj, struct Sprite *sprite);
+void GroundEffect_IceReflection(struct MapObject *mapObj, struct Sprite *sprite);
+void GroundEffect_FlowingWater(struct MapObject *mapObj, struct Sprite *sprite);
+void sub_8063FA0(struct MapObject *mapObj, struct Sprite *sprite);
+void sub_8063FCC(struct MapObject *mapObj, struct Sprite *sprite);
+void GroundEffect_Ripple(struct MapObject *mapObj, struct Sprite *sprite);
+void GroundEffect_StepOnPuddle(struct MapObject *mapObj, struct Sprite *sprite);
+void GroundEffect_SandPile(struct MapObject *mapObj, struct Sprite *sprite);
+void GroundEffect_JumpOnTallGrass(struct MapObject *mapObj, struct Sprite *sprite);
+void GroundEffect_JumpOnLongGrass(struct MapObject *mapObj, struct Sprite *sprite);
+void GroundEffect_JumpOnShallowWater(struct MapObject *mapObj, struct Sprite *sprite);
+void GroundEffect_JumpOnWater(struct MapObject *mapObj, struct Sprite *sprite);
+void GroundEffect_JumpLandingDust(struct MapObject *mapObj, struct Sprite *sprite);
+void GroundEffect_ShortGrass(struct MapObject *mapObj, struct Sprite *sprite);
+void GroundEffect_HotSprings(struct MapObject *mapObj, struct Sprite *sprite);
+void GroundEffect_Seaweed(struct MapObject *mapObj, struct Sprite *sprite);
+u8 GetReflectionTypeByMetatileBehavior(u32 behavior);
-void GetAllGroundEffectFlags_OnSpawn(struct MapObject *mapObj, u32 *flags)
+static void GetAllGroundEffectFlags_OnSpawn(struct MapObject *mapObj, u32 *flags)
{
FieldObjectUpdateMetatileBehaviors(mapObj);
GetGroundEffectFlags_Reflection(mapObj, flags);
@@ -17,7 +44,7 @@ void GetAllGroundEffectFlags_OnSpawn(struct MapObject *mapObj, u32 *flags)
GetGroundEffectFlags_HotSprings(mapObj, flags);
}
-void GetAllGroundEffectFlags_OnBeginStep(struct MapObject *mapObj, u32 *flags)
+static void GetAllGroundEffectFlags_OnBeginStep(struct MapObject *mapObj, u32 *flags)
{
FieldObjectUpdateMetatileBehaviors(mapObj);
GetGroundEffectFlags_Reflection(mapObj, flags);
@@ -31,7 +58,7 @@ void GetAllGroundEffectFlags_OnBeginStep(struct MapObject *mapObj, u32 *flags)
GetGroundEffectFlags_HotSprings(mapObj, flags);
}
-void GetAllGroundEffectFlags_OnFinishStep(struct MapObject *mapObj, u32 *flags)
+static void GetAllGroundEffectFlags_OnFinishStep(struct MapObject *mapObj, u32 *flags)
{
FieldObjectUpdateMetatileBehaviors(mapObj);
GetGroundEffectFlags_ShallowFlowingWater(mapObj, flags);
@@ -101,7 +128,7 @@ void GetGroundEffectFlags_Tracks(struct MapObject *mapObj, u32 *flags)
*flags |= 0x100;
}
else if (MetatileBehavior_IsSandOrDeepSand(mapObj->mapobj_unk_1F)
- || MetatileBehavior_IsUnusedFootprintMetatile(mapObj->mapobj_unk_1F))
+ || MetatileBehavior_IsUnusedFootprintMetatile(mapObj->mapobj_unk_1F))
{
*flags |= 0x80;
}
@@ -110,7 +137,7 @@ void GetGroundEffectFlags_Tracks(struct MapObject *mapObj, u32 *flags)
void GetGroundEffectFlags_SandPile(struct MapObject *mapObj, u32 *flags)
{
if (MetatileBehavior_IsDeepSand(mapObj->mapobj_unk_1E)
- && MetatileBehavior_IsDeepSand(mapObj->mapobj_unk_1F))
+ && MetatileBehavior_IsDeepSand(mapObj->mapobj_unk_1F))
{
if (!mapObj->mapobj_bit_20)
{
@@ -127,8 +154,10 @@ void GetGroundEffectFlags_SandPile(struct MapObject *mapObj, u32 *flags)
void GetGroundEffectFlags_ShallowFlowingWater(struct MapObject *mapObj, u32 *flags)
{
- if ((MetatileBehavior_IsShallowFlowingWater(mapObj->mapobj_unk_1E) && MetatileBehavior_IsShallowFlowingWater(mapObj->mapobj_unk_1F))
- || (MetatileBehavior_IsPacifidlogLog(mapObj->mapobj_unk_1E) && MetatileBehavior_IsPacifidlogLog(mapObj->mapobj_unk_1F)))
+ if ((MetatileBehavior_IsShallowFlowingWater(mapObj->mapobj_unk_1E)
+ && MetatileBehavior_IsShallowFlowingWater(mapObj->mapobj_unk_1F))
+ || (MetatileBehavior_IsPacifidlogLog(mapObj->mapobj_unk_1E)
+ && MetatileBehavior_IsPacifidlogLog(mapObj->mapobj_unk_1F)))
{
if (!mapObj->mapobj_bit_19)
{
@@ -146,7 +175,7 @@ void GetGroundEffectFlags_ShallowFlowingWater(struct MapObject *mapObj, u32 *fla
void GetGroundEffectFlags_Puddle(struct MapObject *mapObj, u32 *flags)
{
if (MetatileBehavior_IsPuddle(mapObj->mapobj_unk_1E)
- && MetatileBehavior_IsPuddle(mapObj->mapobj_unk_1F))
+ && MetatileBehavior_IsPuddle(mapObj->mapobj_unk_1F))
{
*flags |= 0x400;
}
@@ -161,7 +190,7 @@ void GetGroundEffectFlags_Ripple(struct MapObject *mapObj, u32 *flags)
void GetGroundEffectFlags_ShortGrass(struct MapObject *mapObj, u32 *flags)
{
if (MetatileBehavior_IsShortGrass(mapObj->mapobj_unk_1E)
- && MetatileBehavior_IsShortGrass(mapObj->mapobj_unk_1F))
+ && MetatileBehavior_IsShortGrass(mapObj->mapobj_unk_1F))
{
if (!mapObj->mapobj_bit_18)
{
@@ -179,7 +208,7 @@ void GetGroundEffectFlags_ShortGrass(struct MapObject *mapObj, u32 *flags)
void GetGroundEffectFlags_HotSprings(struct MapObject *mapObj, u32 *flags)
{
if (MetatileBehavior_IsHotSprings(mapObj->mapobj_unk_1E)
- && MetatileBehavior_IsHotSprings(mapObj->mapobj_unk_1F))
+ && MetatileBehavior_IsHotSprings(mapObj->mapobj_unk_1F))
{
if (!mapObj->mapobj_bit_21)
{
@@ -204,8 +233,7 @@ void GetGroundEffectFlags_JumpLanding(struct MapObject *mapObj, u32 *flags)
{
typedef bool8 (*MetatileFunc)(u8);
- static const MetatileFunc metatileFuncs[] =
- {
+ static const MetatileFunc metatileFuncs[] = {
MetatileBehavior_IsTallGrass,
MetatileBehavior_IsLongGrass,
MetatileBehavior_IsPuddle,
@@ -214,14 +242,13 @@ void GetGroundEffectFlags_JumpLanding(struct MapObject *mapObj, u32 *flags)
MetatileBehavior_IsATile,
};
- static const u32 jumpLandingFlags[] =
- {
- 0x00001000, // Landing in tall grass
- 0x00002000, // Landing in long grass
- 0x00004000, // Landing on puddle
- 0x00008000, // Landing on surfable water or underwater
- 0x00004000, // Landing on shallow flowing water
- 0x00010000, // Landing on any other type of ground
+ static const u32 jumpLandingFlags[] = {
+ 0x00001000, // Landing in tall grass
+ 0x00002000, // Landing in long grass
+ 0x00004000, // Landing on puddle
+ 0x00008000, // Landing on surfable water or underwater
+ 0x00004000, // Landing on shallow flowing water
+ 0x00010000, // Landing on any other type of ground
};
if (mapObj->mapobj_bit_5 && !mapObj->mapobj_bit_25)
@@ -238,3 +265,529 @@ void GetGroundEffectFlags_JumpLanding(struct MapObject *mapObj, u32 *flags)
}
}
}
+
+u8 FieldObjectCheckForReflectiveSurface(struct MapObject *mapObj)
+{
+ const struct MapObjectGraphicsInfo *info = GetFieldObjectGraphicsInfo(mapObj->graphicsId);
+
+ // ceil div by tile width?
+ s16 width = (info->width + 8) >> 4;
+ s16 height = (info->height + 8) >> 4;
+ s16 i;
+ s16 j;
+ u8 result;
+ u8 b;
+ s16 one;
+
+#define RETURN_REFLECTION_TYPE_AT(x, y) \
+ b = MapGridGetMetatileBehaviorAt(x, y); \
+ result = GetReflectionTypeByMetatileBehavior(b); \
+ if (result != 0) \
+ return result;
+
+ for (i = 0, one = 1; i < height; i++)
+ {
+ RETURN_REFLECTION_TYPE_AT(mapObj->coords2.x, mapObj->coords2.y + one + i)
+ RETURN_REFLECTION_TYPE_AT(mapObj->coords3.x, mapObj->coords3.y + one + i)
+ for (j = 1; j < width; j++)
+ {
+ RETURN_REFLECTION_TYPE_AT(mapObj->coords2.x + j, mapObj->coords2.y + one + i)
+ RETURN_REFLECTION_TYPE_AT(mapObj->coords2.x - j, mapObj->coords2.y + one + i)
+ RETURN_REFLECTION_TYPE_AT(mapObj->coords3.x + j, mapObj->coords3.y + one + i)
+ RETURN_REFLECTION_TYPE_AT(mapObj->coords3.x - j, mapObj->coords3.y + one + i)
+ }
+ }
+ return 0;
+
+#undef RETURN_REFLECTION_TYPE_AT
+}
+
+u8 GetReflectionTypeByMetatileBehavior(u32 behavior)
+{
+ if (MetatileBehavior_IsIce(behavior))
+ return 1;
+ else if (MetatileBehavior_IsReflective(behavior))
+ return 2;
+ else
+ return 0;
+}
+
+u8 GetLedgeJumpDirection(s16 x, s16 y, u8 z)
+{
+ static bool8 (*const unknown_08376040[])(u8) = {
+ MetatileBehavior_IsJumpSouth,
+ MetatileBehavior_IsJumpNorth,
+ MetatileBehavior_IsJumpWest,
+ MetatileBehavior_IsJumpEast,
+ };
+
+ u8 b;
+ u8 index = z;
+
+ if (index == 0)
+ return 0;
+ else if (index > 4)
+ index -= 4;
+
+ index--;
+ b = MapGridGetMetatileBehaviorAt(x, y);
+
+ if (unknown_08376040[index](b) == 1)
+ return index + 1;
+
+ return 0;
+}
+
+void FieldObjectSetSpriteOamTableForLongGrass(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ if (mapObj->mapobj_bit_4)
+ return;
+
+ if (!MetatileBehavior_IsLongGrass(mapObj->mapobj_unk_1E))
+ return;
+
+ if (!MetatileBehavior_IsLongGrass(mapObj->mapobj_unk_1F))
+ return;
+
+ sprite->subspriteTableNum = 4;
+
+ if (ZCoordToPriority(mapObj->elevation) == 1)
+ sprite->subspriteTableNum = 5;
+}
+
+bool8 IsZCoordMismatchAt(u8 z, s16 x, s16 y)
+{
+ u8 mapZ;
+
+ if (z == 0)
+ return FALSE;
+
+ mapZ = MapGridGetZCoordAt(x, y);
+
+ if (mapZ == 0 || mapZ == 0xF)
+ return FALSE;
+
+ if (mapZ != z)
+ return TRUE;
+
+ return FALSE;
+}
+
+static const u8 sUnknown_08376050[] = {
+ 0x73, 0x73, 0x53, 0x73, 0x53, 0x73, 0x53, 0x73, 0x53, 0x73, 0x53, 0x73, 0x53, 0x00, 0x00, 0x73
+};
+
+// Each byte corresponds to a sprite priority for a field object.
+// This is directly the inverse of gFieldObjectPriorities_08376070.
+static const u8 sFieldObjectPriorities_08376060[] = {
+ 2, 2, 2, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 0, 0, 2
+};
+
+// Each byte corresponds to a sprite priority for a field object.
+// This is the inverse of gFieldObjectPriorities_08376060.
+// 1 = Above player sprite
+// 2 = Below player sprite
+static const u8 sFieldObjectPriorities_08376070[] = {
+ 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 0, 0, 1,
+};
+
+void FieldObjectUpdateZCoordAndPriority(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ if (mapObj->mapobj_bit_26)
+ return;
+
+ FieldObjectUpdateZCoord(mapObj);
+
+ sprite->subspriteTableNum = sFieldObjectPriorities_08376070[mapObj->elevation];
+ sprite->oam.priority = sFieldObjectPriorities_08376060[mapObj->elevation];
+}
+
+void InitObjectPriorityByZCoord(struct Sprite *sprite, u8 z)
+{
+ sprite->subspriteTableNum = sFieldObjectPriorities_08376070[z];
+ sprite->oam.priority = sFieldObjectPriorities_08376060[z];
+}
+
+u8 ZCoordToPriority(u8 z)
+{
+ return sFieldObjectPriorities_08376060[z];
+}
+
+void FieldObjectUpdateZCoord(struct MapObject *mapObj)
+{
+ u8 z = MapGridGetZCoordAt(mapObj->coords2.x, mapObj->coords2.y);
+ u8 z2 = MapGridGetZCoordAt(mapObj->coords3.x, mapObj->coords3.y);
+
+ if (z == 0xF || z2 == 0xF)
+ return;
+
+ mapObj->mapobj_unk_0B_0 = z;
+
+ if (z != 0 && z != 0xF)
+ mapObj->elevation = z;
+}
+
+void SetObjectSubpriorityByZCoord(u8 a, struct Sprite *sprite, u8 b)
+{
+ s32 tmp = sprite->centerToCornerVecY;
+ u32 tmpa = *(u16 *)&sprite->pos1.y;
+ u32 tmpb = *(u16 *)&gSpriteCoordOffsetY;
+ s32 tmp2 = (tmpa - tmp) + tmpb;
+ u16 tmp3 = (0x10 - ((((u32)tmp2 + 8) & 0xFF) >> 4)) * 2;
+ sprite->subpriority = tmp3 + sUnknown_08376050[a] + b;
+}
+
+void FieldObjectUpdateSubpriority(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ if (mapObj->mapobj_bit_26)
+ return;
+
+ SetObjectSubpriorityByZCoord(mapObj->elevation, sprite, 1);
+}
+
+bool8 AreZCoordsCompatible(u8 a, u8 b)
+{
+ if (a == 0 || b == 0)
+ return TRUE;
+
+ if (a != b)
+ return FALSE;
+
+ return TRUE;
+}
+
+void GroundEffect_SpawnOnTallGrass(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ u8 *ptr;
+
+ gUnknown_0202FF84[0] = mapObj->coords2.x;
+ gUnknown_0202FF84[1] = mapObj->coords2.y;
+ gUnknown_0202FF84[2] = mapObj->elevation;
+ gUnknown_0202FF84[3] = 2;
+ gUnknown_0202FF84[4] = (mapObj->localId << 8) | mapObj->mapNum;
+ gUnknown_0202FF84[5] = mapObj->mapGroup;
+
+ ptr = (u8 *)&gSaveBlock1;
+ gUnknown_0202FF84[6] = ((u8)gSaveBlock1.location.mapNum << 8)
+ | (u8)gSaveBlock1.location.mapGroup;
+
+ gUnknown_0202FF84[7] = 1;
+ FieldEffectStart(4);
+}
+
+void sub_8063E94(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ u8 *ptr;
+
+ gUnknown_0202FF84[0] = mapObj->coords2.x;
+ gUnknown_0202FF84[1] = mapObj->coords2.y;
+ gUnknown_0202FF84[2] = mapObj->elevation;
+ gUnknown_0202FF84[3] = 2;
+ gUnknown_0202FF84[4] = (mapObj->localId << 8) | mapObj->mapNum;
+ gUnknown_0202FF84[5] = mapObj->mapGroup;
+
+ ptr = (u8 *)&gSaveBlock1;
+ gUnknown_0202FF84[6] = ((u8)gSaveBlock1.location.mapNum << 8)
+ | (u8)gSaveBlock1.location.mapGroup;
+
+ gUnknown_0202FF84[7] = 0;
+ FieldEffectStart(4);
+}
+
+void sub_8063EE0(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ u8 *ptr;
+
+ gUnknown_0202FF84[0] = mapObj->coords2.x;
+ gUnknown_0202FF84[1] = mapObj->coords2.y;
+ gUnknown_0202FF84[2] = mapObj->elevation;
+ gUnknown_0202FF84[3] = 2;
+ gUnknown_0202FF84[4] = (mapObj->localId << 8) | mapObj->mapNum;
+ gUnknown_0202FF84[5] = mapObj->mapGroup;
+
+ ptr = (u8 *)&gSaveBlock1;
+ gUnknown_0202FF84[6] = ((u8)gSaveBlock1.location.mapNum << 8)
+ | (u8)gSaveBlock1.location.mapGroup;
+
+ gUnknown_0202FF84[7] = 1;
+ FieldEffectStart(17);
+}
+
+void sub_8063F2C(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ u8 *ptr;
+
+ gUnknown_0202FF84[0] = mapObj->coords2.x;
+ gUnknown_0202FF84[1] = mapObj->coords2.y;
+ gUnknown_0202FF84[2] = mapObj->elevation;
+ gUnknown_0202FF84[3] = 2;
+ gUnknown_0202FF84[4] = (mapObj->localId << 8) | mapObj->mapNum;
+ gUnknown_0202FF84[5] = mapObj->mapGroup;
+
+ ptr = (u8 *)&gSaveBlock1;
+ gUnknown_0202FF84[6] = ((u8)gSaveBlock1.location.mapNum << 8)
+ | (u8)gSaveBlock1.location.mapGroup;
+
+ gUnknown_0202FF84[7] = 0;
+ FieldEffectStart(17);
+}
+
+void GroundEffect_WaterReflection(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ SetUpReflection(mapObj, sprite, 0);
+}
+
+void GroundEffect_IceReflection(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ SetUpReflection(mapObj, sprite, 1);
+}
+
+void GroundEffect_FlowingWater(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ oe_exec_and_other_stuff(FLDEFF_FEET_IN_FLOWING_WATER, mapObj);
+}
+
+static void (*const gUnknown_08376080[])(struct MapObject *mapObj, struct Sprite *sprite, u8 a) = {
+ nullsub, DoTracksGroundEffect_Footprints, DoTracksGroundEffect_BikeTireTracks,
+};
+
+void sub_8063FA0(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ const struct MapObjectGraphicsInfo *info = GetFieldObjectGraphicsInfo(mapObj->graphicsId);
+ gUnknown_08376080[info->tracks](mapObj, sprite, 0);
+}
+
+void sub_8063FCC(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ const struct MapObjectGraphicsInfo *info = GetFieldObjectGraphicsInfo(mapObj->graphicsId);
+ gUnknown_08376080[info->tracks](mapObj, sprite, 1);
+}
+
+static void nullsub(struct MapObject *mapObj, struct Sprite *sprite, u8 a)
+{
+}
+
+static void DoTracksGroundEffect_Footprints(struct MapObject *mapObj, struct Sprite *sprite, u8 a)
+{
+ // First half-word is a Field Effect script id. (gFieldEffectScriptPointers)
+ u16 sandFootprints_FieldEffectData[2] = { 0xD, 0x18 };
+
+ gUnknown_0202FF84[0] = mapObj->coords3.x;
+ gUnknown_0202FF84[1] = mapObj->coords3.y;
+ gUnknown_0202FF84[2] = 149;
+ gUnknown_0202FF84[3] = 2;
+ gUnknown_0202FF84[4] = mapObj->mapobj_unk_18;
+ FieldEffectStart(sandFootprints_FieldEffectData[a]);
+}
+
+static void DoTracksGroundEffect_BikeTireTracks(
+ struct MapObject *mapObj, struct Sprite *sprite, u8 a)
+{
+ // Specifies which bike track shape to show next.
+ // For example, when the bike turns from up to right, it will show
+ // a track that curves to the right.
+ // Each 4-byte row corresponds to the initial direction of the bike, and
+ // each byte in that row is for the next direction of the bike in the order
+ // of down, up, left, right.
+ static const u8 bikeTireTracks_Transitions[4][4] = {
+ 1, 2, 7, 8,
+ 1, 2, 6, 5,
+ 5, 8, 3, 4,
+ 6, 7, 3, 4,
+ };
+
+ if (mapObj->coords2.x != mapObj->coords3.x || mapObj->coords2.y != mapObj->coords3.y)
+ {
+ gUnknown_0202FF84[0] = mapObj->coords3.x;
+ gUnknown_0202FF84[1] = mapObj->coords3.y;
+ gUnknown_0202FF84[2] = 149;
+ gUnknown_0202FF84[3] = 2;
+ gUnknown_0202FF84[4] =
+ bikeTireTracks_Transitions[mapObj->mapobj_unk_20][mapObj->mapobj_unk_18 - 5];
+ FieldEffectStart(FLDEFF_BIKE_TIRE_TRACKS);
+ }
+}
+
+void GroundEffect_Ripple(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ DoRippleFieldEffect(mapObj, sprite);
+}
+
+void GroundEffect_StepOnPuddle(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ oe_exec_and_other_stuff(FLDEFF_SPLASH, mapObj);
+}
+
+void GroundEffect_SandPile(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ oe_exec_and_other_stuff(FLDEFF_SAND_PILE, mapObj);
+}
+
+void GroundEffect_JumpOnTallGrass(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ u8 spriteId;
+
+ gUnknown_0202FF84[0] = mapObj->coords2.x;
+ gUnknown_0202FF84[1] = mapObj->coords2.y;
+ gUnknown_0202FF84[2] = mapObj->elevation;
+ gUnknown_0202FF84[3] = 2;
+ FieldEffectStart(FLDEFF_JUMP_TALL_GRASS);
+
+ spriteId = sub_8126FF0(
+ mapObj->localId, mapObj->mapNum, mapObj->mapGroup, mapObj->coords2.x, mapObj->coords2.y);
+
+ if (spriteId == MAX_SPRITES)
+ GroundEffect_SpawnOnTallGrass(mapObj, sprite);
+}
+
+void GroundEffect_JumpOnLongGrass(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ gUnknown_0202FF84[0] = mapObj->coords2.x;
+ gUnknown_0202FF84[1] = mapObj->coords2.y;
+ gUnknown_0202FF84[2] = mapObj->elevation;
+ gUnknown_0202FF84[3] = 2;
+ FieldEffectStart(FLDEFF_JUMP_LONG_GRASS);
+}
+
+void GroundEffect_JumpOnShallowWater(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ gUnknown_0202FF84[0] = mapObj->coords2.x;
+ gUnknown_0202FF84[1] = mapObj->coords2.y;
+ gUnknown_0202FF84[2] = mapObj->elevation;
+ gUnknown_0202FF84[3] = sprite->oam.priority;
+ FieldEffectStart(FLDEFF_JUMP_SMALL_SPLASH);
+}
+
+void GroundEffect_JumpOnWater(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ gUnknown_0202FF84[0] = mapObj->coords2.x;
+ gUnknown_0202FF84[1] = mapObj->coords2.y;
+ gUnknown_0202FF84[2] = mapObj->elevation;
+ gUnknown_0202FF84[3] = sprite->oam.priority;
+ FieldEffectStart(FLDEFF_JUMP_BIG_SPLASH);
+}
+
+void GroundEffect_JumpLandingDust(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ gUnknown_0202FF84[0] = mapObj->coords2.x;
+ gUnknown_0202FF84[1] = mapObj->coords2.y;
+ gUnknown_0202FF84[2] = mapObj->elevation;
+ gUnknown_0202FF84[3] = sprite->oam.priority;
+ FieldEffectStart(FLDEFF_DUST);
+}
+
+void GroundEffect_ShortGrass(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ oe_exec_and_other_stuff(FLDEFF_SHORT_GRASS, mapObj);
+}
+
+void GroundEffect_HotSprings(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ oe_exec_and_other_stuff(FLDEFF_HOT_SPRINGS_WATER, mapObj);
+}
+
+void GroundEffect_Seaweed(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ gUnknown_0202FF84[0] = mapObj->coords2.x;
+ gUnknown_0202FF84[1] = mapObj->coords2.y;
+ FieldEffectStart(FLDEFF_BUBBLES);
+}
+
+static void (*const gUnknown_083760A0[])(struct MapObject *mapObj, struct Sprite *sprite) = {
+ GroundEffect_SpawnOnTallGrass,
+ sub_8063E94,
+ sub_8063EE0,
+ sub_8063F2C,
+ GroundEffect_WaterReflection,
+ GroundEffect_IceReflection,
+ GroundEffect_FlowingWater,
+ sub_8063FA0,
+ sub_8063FCC,
+ GroundEffect_Ripple,
+ GroundEffect_StepOnPuddle,
+ GroundEffect_SandPile,
+ GroundEffect_JumpOnTallGrass,
+ GroundEffect_JumpOnLongGrass,
+ GroundEffect_JumpOnShallowWater,
+ GroundEffect_JumpOnWater,
+ GroundEffect_JumpLandingDust,
+ GroundEffect_ShortGrass,
+ GroundEffect_HotSprings,
+ GroundEffect_Seaweed
+};
+
+void sub_8064218(struct MapObject *mapObj, struct Sprite *sprite, u32 flags)
+{
+ u8 i;
+ for (i = 0; i < ARRAY_COUNT(gUnknown_083760A0); i++, flags >>= 1)
+ if (flags & 1)
+ gUnknown_083760A0[i](mapObj, sprite);
+}
+
+void filters_out_some_ground_effects(struct MapObject *mapObj, u32 *flags)
+{
+ if (mapObj->mapobj_bit_4)
+ {
+ mapObj->mapobj_bit_18 = 0;
+ mapObj->mapobj_bit_20 = 0;
+ mapObj->mapobj_bit_19 = 0;
+ mapObj->mapobj_bit_21 = 0;
+ *flags &= 0xFFF9F7BD;
+ }
+}
+
+void FilterOutStepOnPuddleGroundEffectIfJumping(struct MapObject *mapObj, u32 *flags)
+{
+ if (mapObj->mapobj_bit_5)
+ *flags &= 0xFFFFFBFF;
+}
+
+void DoGroundEffects_OnSpawn(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ u32 flags;
+
+ if (mapObj->mapobj_bit_2)
+ {
+ flags = 0;
+ FieldObjectUpdateZCoordAndPriority(mapObj, sprite);
+ GetAllGroundEffectFlags_OnSpawn(mapObj, &flags);
+ FieldObjectSetSpriteOamTableForLongGrass(mapObj, sprite);
+ sub_8064218(mapObj, sprite, flags);
+ mapObj->mapobj_bit_2 = 0;
+ mapObj->mapobj_bit_4 = 0;
+ }
+}
+
+void DoGroundEffects_OnBeginStep(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ u32 flags;
+
+ if (mapObj->mapobj_bit_2)
+ {
+ flags = 0;
+ FieldObjectUpdateZCoordAndPriority(mapObj, sprite);
+ GetAllGroundEffectFlags_OnBeginStep(mapObj, &flags);
+ FieldObjectSetSpriteOamTableForLongGrass(mapObj, sprite);
+ filters_out_some_ground_effects(mapObj, &flags);
+ sub_8064218(mapObj, sprite, flags);
+ mapObj->mapobj_bit_2 = 0;
+ mapObj->mapobj_bit_4 = 0;
+ }
+}
+
+void DoGroundEffects_OnFinishStep(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ u32 flags;
+
+ if (mapObj->mapobj_bit_3)
+ {
+ flags = 0;
+ FieldObjectUpdateZCoordAndPriority(mapObj, sprite);
+ GetAllGroundEffectFlags_OnFinishStep(mapObj, &flags);
+ FieldObjectSetSpriteOamTableForLongGrass(mapObj, sprite);
+ FilterOutStepOnPuddleGroundEffectIfJumping(mapObj, &flags);
+ sub_8064218(mapObj, sprite, flags);
+ mapObj->mapobj_bit_3 = 0;
+ mapObj->mapobj_bit_5 = 0;
+ }
+}
diff --git a/src/field/mauville_man.c b/src/field/mauville_man.c
new file mode 100644
index 000000000..4a77717f1
--- /dev/null
+++ b/src/field/mauville_man.c
@@ -0,0 +1,1311 @@
+#include "global.h"
+#include "bard_music.h"
+#include "mauville_man.h"
+#include "easy_chat.h"
+#include "event_data.h"
+#include "field_message_box.h"
+#include "m4a.h"
+#include "menu.h"
+#include "rom4.h"
+#include "rng.h"
+#include "script.h"
+#include "songs.h"
+#include "sound.h"
+#include "string_util.h"
+#include "strings.h"
+#include "task.h"
+#include "trader.h"
+
+#define MACRO1(a) (((a) % 4) + (((a) / 8) & 1))
+
+extern struct MusicPlayerInfo gMPlay_SE2;
+
+extern u16 gScriptResult;
+extern u16 gSpecialVar_0x8004;
+
+extern const u8 gTextStoryteller_Story1Title[];
+extern const u8 gTextStoryteller_Story1Action[];
+extern const u8 gTextStoryteller_Story1Text[];
+extern const u8 gTextStoryteller_Story2Title[];
+extern const u8 gTextStoryteller_Story2Action[];
+extern const u8 gTextStoryteller_Story2Text[];
+extern const u8 gTextStoryteller_Story3Title[];
+extern const u8 gTextStoryteller_Story3Action[];
+extern const u8 gTextStoryteller_Story3Text[];
+extern const u8 gTextStoryteller_Story4Title[];
+extern const u8 gTextStoryteller_Story4Action[];
+extern const u8 gTextStoryteller_Story4Text[];
+extern const u8 gTextStoryteller_Story5Title[];
+extern const u8 gTextStoryteller_Story5Action[];
+extern const u8 gTextStoryteller_Story5Text[];
+extern const u8 gTextStoryteller_Story6Title[];
+extern const u8 gTextStoryteller_Story6Action[];
+extern const u8 gTextStoryteller_Story6Text[];
+extern const u8 gTextStoryteller_Story7Title[];
+extern const u8 gTextStoryteller_Story7Action[];
+extern const u8 gTextStoryteller_Story7Text[];
+extern const u8 gTextStoryteller_Story8Title[];
+extern const u8 gTextStoryteller_Story8Action[];
+extern const u8 gTextStoryteller_Story8Text[];
+extern const u8 gTextStoryteller_Story9Title[];
+extern const u8 gTextStoryteller_Story9Action[];
+extern const u8 gTextStoryteller_Story9Text[];
+extern const u8 gTextStoryteller_Story10Title[];
+extern const u8 gTextStoryteller_Story10Action[];
+extern const u8 gTextStoryteller_Story10Text[];
+extern const u8 gTextStoryteller_Story11Title[];
+extern const u8 gTextStoryteller_Story11Action[];
+extern const u8 gTextStoryteller_Story11Text[];
+extern const u8 gTextStoryteller_Story12Title[];
+extern const u8 gTextStoryteller_Story12Action[];
+extern const u8 gTextStoryteller_Story12Text[];
+extern const u8 gTextStoryteller_Story13Title[];
+extern const u8 gTextStoryteller_Story13Action[];
+extern const u8 gTextStoryteller_Story13Text[];
+extern const u8 gTextStoryteller_Story14Title[];
+extern const u8 gTextStoryteller_Story14Action[];
+extern const u8 gTextStoryteller_Story14Text[];
+extern const u8 gTextStoryteller_Story15Title[];
+extern const u8 gTextStoryteller_Story15Action[];
+extern const u8 gTextStoryteller_Story15Text[];
+extern const u8 gTextStoryteller_Story16Title[];
+extern const u8 gTextStoryteller_Story16Action[];
+extern const u8 gTextStoryteller_Story16Text[];
+extern const u8 gTextStoryteller_Story17Title[];
+extern const u8 gTextStoryteller_Story17Action[];
+extern const u8 gTextStoryteller_Story17Text[];
+extern const u8 gTextStoryteller_Story18Title[];
+extern const u8 gTextStoryteller_Story18Action[];
+extern const u8 gTextStoryteller_Story18Text[];
+extern const u8 gTextStoryteller_Story19Title[];
+extern const u8 gTextStoryteller_Story19Action[];
+extern const u8 gTextStoryteller_Story19Text[];
+extern const u8 gTextStoryteller_Story20Title[];
+extern const u8 gTextStoryteller_Story20Action[];
+extern const u8 gTextStoryteller_Story20Text[];
+extern const u8 gTextStoryteller_Story21Title[];
+extern const u8 gTextStoryteller_Story21Action[];
+extern const u8 gTextStoryteller_Story21Text[];
+extern const u8 gTextStoryteller_Story22Title[];
+extern const u8 gTextStoryteller_Story22Action[];
+extern const u8 gTextStoryteller_Story22Text[];
+extern const u8 gTextStoryteller_Story23Title[];
+extern const u8 gTextStoryteller_Story23Action[];
+extern const u8 gTextStoryteller_Story23Text[];
+extern const u8 gTextStoryteller_Story24Title[];
+extern const u8 gTextStoryteller_Story24Action[];
+extern const u8 gTextStoryteller_Story24Text[];
+extern const u8 gTextStoryteller_Story25Title[];
+extern const u8 gTextStoryteller_Story25Action[];
+extern const u8 gTextStoryteller_Story25Text[];
+extern const u8 gTextStoryteller_Story26Title[];
+extern const u8 gTextStoryteller_Story26Action[];
+extern const u8 gTextStoryteller_Story26Text[];
+extern const u8 gTextStoryteller_Story27Title[];
+extern const u8 gTextStoryteller_Story27Action[];
+extern const u8 gTextStoryteller_Story27Text[];
+extern const u8 gTextStoryteller_Story28Title[];
+extern const u8 gTextStoryteller_Story28Action[];
+extern const u8 gTextStoryteller_Story28Text[];
+extern const u8 gTextStoryteller_Story29Title[];
+extern const u8 gTextStoryteller_Story29Action[];
+extern const u8 gTextStoryteller_Story29Text[];
+extern const u8 gTextStoryteller_Story30Title[];
+extern const u8 gTextStoryteller_Story30Action[];
+extern const u8 gTextStoryteller_Story30Text[];
+extern const u8 gTextStoryteller_Story31Title[];
+extern const u8 gTextStoryteller_Story31Action[];
+extern const u8 gTextStoryteller_Story31Text[];
+extern const u8 gTextStoryteller_Story32Title[];
+extern const u8 gTextStoryteller_Story32Action[];
+extern const u8 gTextStoryteller_Story32Text[];
+extern const u8 gTextStoryteller_Story33Title[];
+extern const u8 gTextStoryteller_Story33Action[];
+extern const u8 gTextStoryteller_Story33Text[];
+extern const u8 gTextStoryteller_Story34Title[];
+extern const u8 gTextStoryteller_Story34Action[];
+extern const u8 gTextStoryteller_Story34Text[];
+extern const u8 gTextStoryteller_Story35Title[];
+extern const u8 gTextStoryteller_Story35Action[];
+extern const u8 gTextStoryteller_Story35Text[];
+extern const u8 gTextStoryteller_Story36Title[];
+extern const u8 gTextStoryteller_Story36Action[];
+extern const u8 gTextStoryteller_Story36Text[];
+
+extern struct BardSong gUnknown_03005DA0;
+
+EWRAM_DATA static u16 gUnknown_020388BC = 0; // set but not used?
+
+static const u16 sDefaultBardSongLyrics[] =
+{
+#ifdef ENGLISH
+ EC_WORD_SISTER,
+ EC_WORD_EATS,
+ EC_WORD_SWEETS,
+ EC_WORD_VORACIOUS,
+ EC_WORD_AND,
+ EC_WORD_DROOLING,
+#else
+ EC_WORD_SISTER,
+ EC_WORD_MUST_BE,
+ EC_WORD_SWEETS,
+ EC_WORD_VORACIOUS,
+ EC_WORD_DROOLING,
+ EC_WORD_THICK,
+#endif
+};
+
+static const u8 *const sGiddyAdjectives[] =
+{
+ OtherText_SoPretty,
+ OtherText_SoDarling,
+ OtherText_SoRelaxed,
+ OtherText_SoSunny,
+ OtherText_SoDesirable,
+ OtherText_SoExciting,
+ OtherText_SoAmusing,
+ OtherText_SoMagical,
+};
+
+static const u8 *const sGiddyQuestions[] =
+{
+ OtherText_WantVacationNicePlace,
+ OtherText_BoughtCrayonsIsNice,
+ OtherText_IfWeCouldFloat,
+ OtherText_SandWashesAwayMakeSad,
+ OtherText_WhatsBottomSeaLike,
+ OtherText_SeeSettingSun,
+ OtherText_LyingInGreenGrass,
+ OtherText_SecretBasesWonderful,
+};
+
+static void sub_80F7DC0(void);
+static void Task_BardSong(u8);
+static void StartBardSong(u8);
+static void StorytellerSetup(void);
+static void sub_80F8428(void);
+
+static void SetupBard(void)
+{
+ u16 i;
+ struct MauvilleManBard *bard = &gSaveBlock1.mauvilleMan.bard;
+
+ bard->id = MAUVILLE_MAN_BARD;
+ bard->hasChangedSong = FALSE;
+ for (i = 0; i < 6; i++)
+ bard->songLyrics[i] = sDefaultBardSongLyrics[i];
+}
+
+static void SetupHipster(void)
+{
+ struct MauvilleManHipster *hipster = &gSaveBlock1.mauvilleMan.hipster;
+
+ hipster->id = MAUVILLE_MAN_HIPSTER;
+ hipster->alreadySpoken = FALSE;
+}
+
+static void SetupStoryteller(void)
+{
+ StorytellerSetup();
+}
+
+static void SetupGiddy(void)
+{
+ struct MauvilleManGiddy *giddy = &gSaveBlock1.mauvilleMan.giddy;
+
+ giddy->id = MAUVILLE_MAN_GIDDY;
+ giddy->taleCounter = 0;
+}
+
+static void SetupTrader(void)
+{
+ TraderSetup();
+}
+
+void SetupMauvilleOldMan(void)
+{
+ u16 trainerId = (gSaveBlock2.playerTrainerId[1] << 8) | gSaveBlock2.playerTrainerId[0];
+
+ // Determine man based on the last digit of the player's trainer ID.
+ switch ((trainerId % 10) / 2)
+ {
+ case MAUVILLE_MAN_BARD:
+ SetupBard();
+ break;
+ case MAUVILLE_MAN_HIPSTER:
+ SetupHipster();
+ break;
+ case MAUVILLE_MAN_TRADER:
+ SetupTrader();
+ break;
+ case MAUVILLE_MAN_STORYTELLER:
+ SetupStoryteller();
+ break;
+ case MAUVILLE_MAN_GIDDY:
+ SetupGiddy();
+ break;
+ }
+ sub_80F83D0();
+}
+
+static u8 GetCurrentMauvilleOldMan(void)
+{
+ struct MauvilleManCommon *common = &gSaveBlock1.mauvilleMan.common;
+
+ return common->id;
+}
+
+void ScrSpecial_GetCurrentMauvilleMan(void)
+{
+ gScriptResult = GetCurrentMauvilleOldMan();
+}
+
+void ScrSpecial_HasBardSongBeenChanged(void)
+{
+ u16 *scriptResult = &gScriptResult; // why??
+ struct MauvilleManBard *bard = &gSaveBlock1.mauvilleMan.bard;
+
+ *scriptResult = bard->hasChangedSong;
+}
+
+void ScrSpecial_SaveBardSongLyrics(void)
+{
+ u16 i;
+ struct MauvilleManBard *bard = &gSaveBlock1.mauvilleMan.bard;
+
+ StringCopy(bard->playerName, gSaveBlock2.playerName);
+
+ for (i = 0; i < 4; i++)
+ bard->playerTrainerId[i] = gSaveBlock2.playerTrainerId[i];
+
+ for (i = 0; i < 6; i++)
+ bard->songLyrics[i] = bard->temporaryLyrics[i];
+
+ bard->hasChangedSong = TRUE;
+}
+
+// Copies lyrics into gStringVar4
+void PrepareSongText(void)
+{
+ struct MauvilleManBard *bard = &gSaveBlock1.mauvilleMan.bard;
+ u16 specialVar = gSpecialVar_0x8004; // It's a bit odd to use this temp variable, but it seems needed to match.
+ u16 *lyrics;
+ u16 lineNum;
+ u8 *wordEnd;
+ u8 *str;
+
+ lyrics = bard->temporaryLyrics;
+ if (specialVar == 0)
+ lyrics = bard->songLyrics;
+ wordEnd = gStringVar4;
+ str = wordEnd;
+ // Put three words on each line
+ for (lineNum = 0; lineNum < 2; lineNum++)
+ {
+ wordEnd = EasyChat_GetWordText(wordEnd, *(lyrics++));
+ while (wordEnd != str)
+ {
+ if (*str == CHAR_SPACE)
+ *str = CHAR_SONG_WORD_SEPARATOR;
+ str++;
+ }
+
+ str++;
+ *(wordEnd++) = CHAR_SPACE;
+
+ wordEnd = EasyChat_GetWordText(wordEnd, *(lyrics++));
+ while (wordEnd != str)
+ {
+ if (*str == CHAR_SPACE)
+ *str = CHAR_SONG_WORD_SEPARATOR;
+ str++;
+ }
+
+ str++;
+ *(wordEnd++) = CHAR_NEWLINE;
+
+ wordEnd = EasyChat_GetWordText(wordEnd, *(lyrics++));
+ while (wordEnd != str)
+ {
+ if (*str == CHAR_SPACE)
+ *str = CHAR_SONG_WORD_SEPARATOR;
+ str++;
+ }
+
+ if (lineNum == 0)
+ {
+ *(wordEnd++) = EXT_CTRL_CODE_BEGIN;
+ *(wordEnd++) = 15;
+ }
+ }
+}
+
+void ScrSpecial_PlayBardSong(void)
+{
+ StartBardSong(gSpecialVar_0x8004);
+ MenuDisplayMessageBox();
+ ScriptContext1_Stop();
+}
+
+void ScrSpecial_GetHipsterSpokenFlag(void)
+{
+ u16 *scriptResult = &gScriptResult; // again??
+ struct MauvilleManHipster *hipster = &gSaveBlock1.mauvilleMan.hipster;
+
+ *scriptResult = hipster->alreadySpoken;
+}
+
+void ScrSpecial_SetHipsterSpokenFlag(void)
+{
+ struct MauvilleManHipster *hipster = &gSaveBlock1.mauvilleMan.hipster;
+
+ hipster->alreadySpoken = TRUE;
+}
+
+void ScrSpecial_HipsterTeachWord(void)
+{
+ u16 var = sub_80EB8EC();
+
+ if (var == 0xFFFF)
+ {
+ gScriptResult = FALSE;
+ }
+ else
+ {
+ EasyChat_GetWordText(gStringVar1, var);
+ gScriptResult = TRUE;
+ }
+}
+
+void ScrSpecial_GiddyShouldTellAnotherTale(void)
+{
+ struct MauvilleManGiddy *giddy = &gSaveBlock1.mauvilleMan.giddy;
+
+ if (giddy->taleCounter == 10)
+ {
+ gScriptResult = FALSE;
+ giddy->taleCounter = 0;
+ }
+ else
+ {
+ gScriptResult = TRUE;
+ }
+}
+
+void ScrSpecial_GenerateGiddyLine(void)
+{
+ struct MauvilleManGiddy *giddy = &gSaveBlock1.mauvilleMan.giddy;
+
+ if (giddy->taleCounter == 0)
+ sub_80F7DC0();
+
+ if (giddy->randomWords[giddy->taleCounter] != 0xFFFF) // is not the last element of the array?
+ {
+ u8 *stringPtr;
+ u32 adjective = Random();
+
+ adjective %= 8;
+ stringPtr = EasyChat_GetWordText(gStringVar4, giddy->randomWords[giddy->taleCounter]);
+ stringPtr = StringCopy(stringPtr, gOtherText_Is);
+ stringPtr = StringCopy(stringPtr, sGiddyAdjectives[adjective]);
+ StringCopy(stringPtr, gOtherText_DontYouAgree);
+ }
+ else
+ {
+ StringCopy(gStringVar4, sGiddyQuestions[giddy->questionList[giddy->questionNum++]]);
+ }
+
+ if (!(Random() % 10))
+ giddy->taleCounter = 10;
+ else
+ giddy->taleCounter++;
+
+ gScriptResult = TRUE;
+}
+
+#ifdef NONMATCHING
+static void sub_80F7DC0(void)
+{
+ u16 arr[][2] =
+ {
+ { 0x0, 0},
+ { 0xC, 0},
+ { 0xD, 0},
+ {0x12, 0},
+ {0x13, 0},
+ {0x15, 0},
+ };
+ u16 i;
+ u16 r10;
+ u16 r7;
+
+ for (i = 0; i < 8; i++)
+ {
+ struct MauvilleManGiddy *giddy = &gSaveBlock1.mauvilleMan.giddy;
+
+ //gSaveBlock1.mauvilleMan.giddy.questionList[i] = i;
+ giddy->questionList[i] = i;
+ }
+
+ // Scramble questions
+ for (i = 0; i < 8; i++)
+ {
+ struct MauvilleManGiddy *giddy = &gSaveBlock1.mauvilleMan.giddy;
+
+ /*
+ u16 r1 = Random() % (i + 1);
+ u8 r7 = gSaveBlock1.mauvilleMan.giddy.questionList[i];
+ gSaveBlock1.mauvilleMan.giddy.questionList[i] = gSaveBlock1.mauvilleMan.giddy.questionList[r1];
+ gSaveBlock1.mauvilleMan.giddy.questionList[r1] = r7;
+ */
+ u16 r1 = Random() % (i + 1);
+ u8 r7 = giddy->questionList[i];
+ giddy->questionList[i] = giddy->questionList[r1];
+ giddy->questionList[r1] = r7;
+ }
+
+ r10 = 0;
+ for (i = 0; i < 6; i++)
+ {
+ arr[i][1] = sub_80EAE88(arr[i][0]);
+ r10 += arr[i][1];
+ }
+
+ {
+ struct MauvilleManGiddy *giddy = &gSaveBlock1.mauvilleMan.giddy;
+ giddy->questionNum = 0;
+ }
+ //gSaveBlock1.mauvilleMan.giddy.questionNum = 0;
+
+ r7 = 0;
+ for (i = 0; i < 10; i++)
+ {
+ struct MauvilleManGiddy *giddy = &gSaveBlock1.mauvilleMan.giddy;
+
+ u16 var = Random() % 10;
+ if (var < 3 && r7 < 8)
+ {
+ //gSaveBlock1.mauvilleMan.giddy.randomWords[i] = 0xFFFF;
+ giddy->randomWords[i] = 0xFFFF;
+ r7++;
+ }
+ //_080F7E90
+ else
+ {
+ s16 r2 = Random() % r10;
+
+ u16 r1 = 0;
+
+ while (i < 6) // comparing the wrong variable
+ {
+ r2 = arr[r1][1] - r2;
+ if (r2 <= 0)
+ break;
+ r1++;
+ }
+
+ if (r1 == 6)
+ r1 = 0;
+ //gSaveBlock1.mauvilleMan.giddy.randomWords[i] = sub_80EB784(arr[r1][0]);
+ giddy->randomWords[i] = sub_80EB784(arr[r1][0]);
+ }
+ }
+}
+#else
+
+static const u16 gUnknown_083E53C8[][2] =
+{
+ { 0x0, 0},
+ { 0xC, 0},
+ { 0xD, 0},
+ {0x12, 0},
+ {0x13, 0},
+ {0x15, 0},
+};
+
+__attribute__((naked))
+static void sub_80F7DC0(void)
+{
+ asm(".syntax unified\n\
+ push {r4-r7,lr}\n\
+ mov r7, r10\n\
+ mov r6, r9\n\
+ mov r5, r8\n\
+ push {r5-r7}\n\
+ sub sp, 0x18\n\
+ ldr r1, _080F7E84 @ =gUnknown_083E53C8\n\
+ mov r0, sp\n\
+ movs r2, 0x18\n\
+ bl memcpy\n\
+ movs r5, 0\n\
+ movs r0, 0x2\n\
+ add r0, sp\n\
+ mov r8, r0\n\
+ ldr r1, _080F7E88 @ =gSaveBlock1 + 0x2D94\n\
+ adds r1, 0x18\n\
+ adds r3, r1, 0\n\
+_080F7DE4:\n\
+ adds r0, r3, r5\n\
+ strb r5, [r0]\n\
+ adds r0, r5, 0x1\n\
+ lsls r0, 16\n\
+ lsrs r5, r0, 16\n\
+ cmp r5, 0x7\n\
+ bls _080F7DE4\n\
+ movs r5, 0\n\
+ ldr r2, _080F7E88 @ =gSaveBlock1 + 0x2D94\n\
+ adds r2, 0x4\n\
+ mov r9, r2\n\
+ adds r6, r1, 0\n\
+_080F7DFC:\n\
+ bl Random\n\
+ lsls r0, 16\n\
+ lsrs r0, 16\n\
+ adds r4, r5, 0x1\n\
+ adds r1, r4, 0\n\
+ bl __modsi3\n\
+ lsls r0, 16\n\
+ lsrs r1, r0, 16\n\
+ adds r2, r6, r5\n\
+ ldrb r7, [r2]\n\
+ adds r1, r6, r1\n\
+ ldrb r0, [r1]\n\
+ strb r0, [r2]\n\
+ strb r7, [r1]\n\
+ lsls r4, 16\n\
+ lsrs r5, r4, 16\n\
+ cmp r5, 0x7\n\
+ bls _080F7DFC\n\
+ movs r3, 0\n\
+ mov r10, r3\n\
+ movs r5, 0\n\
+_080F7E2A:\n\
+ lsls r4, r5, 2\n\
+ mov r1, sp\n\
+ adds r0, r1, r4\n\
+ ldrb r0, [r0]\n\
+ bl sub_80EAE88\n\
+ add r4, r8\n\
+ strh r0, [r4]\n\
+ add r0, r10\n\
+ lsls r0, 16\n\
+ lsrs r0, 16\n\
+ mov r10, r0\n\
+ adds r0, r5, 0x1\n\
+ lsls r0, 16\n\
+ lsrs r5, r0, 16\n\
+ cmp r5, 0x5\n\
+ bls _080F7E2A\n\
+ movs r0, 0\n\
+ ldr r2, _080F7E88 @ =gSaveBlock1 + 0x2D94\n\
+ strb r0, [r2, 0x2]\n\
+ movs r7, 0\n\
+ movs r5, 0\n\
+_080F7E56:\n\
+ bl Random\n\
+ lsls r0, 16\n\
+ lsrs r0, 16\n\
+ movs r1, 0xA\n\
+ bl __umodsi3\n\
+ lsls r0, 16\n\
+ lsrs r1, r0, 16\n\
+ cmp r1, 0x2\n\
+ bhi _080F7E90\n\
+ cmp r7, 0x7\n\
+ bhi _080F7E90\n\
+ lsls r0, r5, 1\n\
+ add r0, r9\n\
+ ldr r1, _080F7E8C @ =0x0000ffff\n\
+ strh r1, [r0]\n\
+ adds r0, r7, 0x1\n\
+ lsls r0, 16\n\
+ lsrs r7, r0, 16\n\
+ adds r4, r5, 0x1\n\
+ b _080F7EE2\n\
+ .align 2, 0\n\
+_080F7E84: .4byte gUnknown_083E53C8\n\
+_080F7E88: .4byte gSaveBlock1 + 0x2D94\n\
+_080F7E8C: .4byte 0x0000ffff\n\
+_080F7E90:\n\
+ bl Random\n\
+ lsls r0, 16\n\
+ lsrs r0, 16\n\
+ mov r1, r10\n\
+ bl __umodsi3\n\
+ lsls r0, 16\n\
+ lsrs r2, r0, 16\n\
+ movs r1, 0\n\
+ adds r4, r5, 0x1\n\
+ lsls r6, r5, 1\n\
+ cmp r5, 0x5\n\
+ bhi _080F7ECC\n\
+ mov r3, r8\n\
+ ldrh r0, [r3]\n\
+ b _080F7EC2\n\
+_080F7EB2:\n\
+ adds r0, r1, 0x1\n\
+ lsls r0, 16\n\
+ lsrs r1, r0, 16\n\
+ cmp r5, 0x5\n\
+ bhi _080F7ECC\n\
+ lsls r0, r1, 2\n\
+ adds r0, r3, r0\n\
+ ldrh r0, [r0]\n\
+_080F7EC2:\n\
+ subs r0, r2, r0\n\
+ lsls r0, 16\n\
+ lsrs r2, r0, 16\n\
+ cmp r0, 0\n\
+ bgt _080F7EB2\n\
+_080F7ECC:\n\
+ cmp r1, 0x6\n\
+ bne _080F7ED2\n\
+ movs r1, 0\n\
+_080F7ED2:\n\
+ lsls r0, r1, 2\n\
+ add r0, sp\n\
+ ldrh r0, [r0]\n\
+ bl sub_80EB784\n\
+ mov r2, r9\n\
+ adds r1, r2, r6\n\
+ strh r0, [r1]\n\
+_080F7EE2:\n\
+ lsls r0, r4, 16\n\
+ lsrs r5, r0, 16\n\
+ cmp r5, 0x9\n\
+ bls _080F7E56\n\
+ add sp, 0x18\n\
+ pop {r3-r5}\n\
+ mov r8, r3\n\
+ mov r9, r4\n\
+ mov r10, r5\n\
+ pop {r4-r7}\n\
+ pop {r0}\n\
+ bx r0\n\
+ .syntax divided\n");
+}
+#endif
+
+static void sub_80F7EFC(void)
+{
+ struct MauvilleManBard *bard = &gSaveBlock1.mauvilleMan.bard;
+
+ bard->hasChangedSong = FALSE;
+}
+
+static void sub_80F7F0C(void)
+{
+ struct MauvilleManHipster *hipster = &gSaveBlock1.mauvilleMan.hipster;
+
+ hipster->alreadySpoken = FALSE;
+}
+
+static void sub_80F7F18(void)
+{
+ sub_8109A20();
+}
+
+static void sub_80F7F24(void)
+{
+ sub_80F8428();
+}
+
+void sub_80F7F30(void)
+{
+ switch (GetCurrentMauvilleOldMan())
+ {
+ case MAUVILLE_MAN_BARD:
+ sub_80F7EFC();
+ break;
+ case MAUVILLE_MAN_HIPSTER:
+ sub_80F7F0C();
+ break;
+ case MAUVILLE_MAN_STORYTELLER:
+ sub_80F7F24();
+ break;
+ case MAUVILLE_MAN_TRADER:
+ sub_80F7F18();
+ break;
+ case MAUVILLE_MAN_GIDDY:
+ break;
+ }
+ sub_80F83D0();
+}
+
+#define tState data[0]
+#define tCharIndex data[3]
+#define tCurrWord data[4]
+#define tUseTemporaryLyrics data[5]
+
+static void StartBardSong(bool8 useTemporaryLyrics)
+{
+ u8 taskId = CreateTask(Task_BardSong, 0x50);
+
+ gTasks[taskId].tUseTemporaryLyrics = useTemporaryLyrics;
+}
+
+static void BardSing(struct Task *task, struct BardSong *song)
+{
+ switch (task->tState)
+ {
+ case 0: // Initialize song
+ {
+ struct MauvilleManBard *bard = &gSaveBlock1.mauvilleMan.bard;
+ u16 *lyrics;
+ s32 i;
+
+ // Copy lyrics
+ if (gSpecialVar_0x8004 == 0)
+ lyrics = bard->songLyrics;
+ else
+ lyrics = bard->temporaryLyrics;
+ for (i = 0; i < 6; i++)
+ song->lyrics[i] = lyrics[i];
+
+ // Clear phonemes
+ for (i = 0; i < 6; i++)
+ {
+ song->phonemes[i].sound = 0xFFFF;
+ song->phonemes[i].length = 0;
+ song->phonemes[i].pitch = 0;
+ song->phonemes[i].volume = 0;
+ }
+ song->currWord = 0;
+ song->currPhoneme = 0;
+ song->var04 = 0;
+ }
+ break;
+ case 1: // Wait for BGM to end
+ break;
+ case 2: // Initialize word
+ {
+ u16 word = song->lyrics[song->currWord];
+ const struct BardSound *sounds = GetWordSounds(EC_GROUP(word), EC_INDEX(word));
+
+ song->var04 = 0;
+ GetWordPhonemes(song, sounds, MACRO1(word));
+ }
+ break;
+ case 3:
+ case 4:
+ {
+ struct BardPhoneme *phoneme = &song->phonemes[song->currPhoneme];
+
+ switch (song->state)
+ {
+ case 0:
+ if (song->phonemeTimer == 0) // Timer has expired. Move to next phoneme
+ {
+ if (song->currPhoneme == 6 || phoneme->sound == 0xFF)
+ {
+ song->state = 0xFE;
+ break;
+ }
+ song->phonemeTimer = phoneme->length;
+ if (phoneme->sound <= 50)
+ {
+ u16 num = phoneme->sound / 3;
+
+ m4aSongNumStart(249 + num * 3);
+ }
+ song->state = 1;
+ }
+ else
+ {
+ if (song->voiceInflection > 10)
+ song->volume -= 2;
+ if (song->voiceInflection & 1)
+ song->pitch += 64;
+ else
+ song->pitch -= 64;
+ m4aMPlayVolumeControl(&gMPlay_SE2, 0xFFFF, song->volume);
+ m4aMPlayPitchControl(&gMPlay_SE2, 0xFFFF, song->pitch);
+ song->voiceInflection++;
+ }
+ song->phonemeTimer--;
+ break;
+ case 1:
+ song->currPhoneme++;
+ song->state = 0;
+ if (phoneme->sound <= 50)
+ {
+ song->volume = 0x100 + phoneme->volume * 16;
+ m4aMPlayVolumeControl(&gMPlay_SE2, 0xFFFF, song->volume);
+ song->pitch = 0x200 + phoneme->pitch;
+ m4aMPlayPitchControl(&gMPlay_SE2, 0xFFFF, song->pitch);
+ }
+ break;
+ case 0xFE:
+ m4aMPlayStop(&gMPlay_SE2);
+ song->state = 0xFF;
+ break;
+ }
+ }
+ break;
+ case 5:
+ break;
+ }
+}
+
+static void Task_BardSong(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId]; // r5
+
+ BardSing(task, &gUnknown_03005DA0);
+ switch (task->tState)
+ {
+ case 0: // Initialize song
+ PrepareSongText();
+ InitWindowFromConfig(gMenuWindowPtr, &gWindowConfig_81E6CE4);
+ sub_8002EB0(gMenuWindowPtr, gStringVar4, 2, 4, 15);
+ task->data[1] = 0;
+ task->data[2] = 0;
+ task->tCharIndex = 0;
+ task->tCurrWord = 0;
+ FadeOutBGMTemporarily(4);
+ task->tState = 1;
+ break;
+ case 1: // Wait for BGM to end
+ if (IsBGMPausedOrStopped())
+ task->tState = 2;
+ break;
+ case 2: // Initialize word
+ {
+ struct MauvilleManBard *bard = &gSaveBlock1.mauvilleMan.bard;
+ u8 *str = gStringVar4 + task->tCharIndex;
+ u16 wordLen = 0;
+ // Can't get it to match without hacking
+ u32 temp;
+ register s16 zero asm("r1");
+
+ while (*str != CHAR_SPACE
+ && *str != CHAR_NEWLINE
+ && *str != EXT_CTRL_CODE_BEGIN
+ && *str != EOS)
+ {
+ str++;
+ wordLen++;
+ }
+ if (!task->tUseTemporaryLyrics)
+ gUnknown_020388BC = MACRO1(bard->songLyrics[task->tCurrWord]);
+ else
+ gUnknown_020388BC = MACRO1(bard->temporaryLyrics[task->tCurrWord]);
+ temp = gUnknown_03005DA0.var04 / wordLen;
+ zero = 0;
+ gUnknown_03005DA0.var04 = temp;
+ if (gUnknown_03005DA0.var04 <= 0)
+ gUnknown_03005DA0.var04 = 1;
+ task->tCurrWord++;
+ if (task->data[2] == 0)
+ task->tState = 3;
+ else
+ task->tState = 5;
+ task->data[1] = zero;
+ }
+ break;
+ case 5:
+ if (task->data[2] == 0)
+ task->tState = 3;
+ else
+ task->data[2]--;
+ break;
+ case 3:
+ if (gStringVar4[task->tCharIndex] == EOS)
+ {
+ FadeInNewBGM(BGM_POKECEN, 6);
+ m4aMPlayFadeOutTemporarily(&gMPlay_SE2, 2);
+ EnableBothScriptContexts();
+ DestroyTask(taskId);
+ }
+ else if (gStringVar4[task->tCharIndex] == CHAR_SPACE)
+ {
+ sub_8003418(gMenuWindowPtr);
+ task->tCharIndex++;
+ task->tState = 2;
+ task->data[2] = 0;
+ }
+ else if (gStringVar4[task->tCharIndex] == CHAR_NEWLINE)
+ {
+ task->tCharIndex++;
+ task->tState = 2;
+ task->data[2] = 0;
+ }
+ else if (gStringVar4[task->tCharIndex] == EXT_CTRL_CODE_BEGIN)
+ {
+ task->tCharIndex += 2; // skip over control codes
+ task->tState = 2;
+ task->data[2] = 8;
+ }
+ else if (gStringVar4[task->tCharIndex] == CHAR_SONG_WORD_SEPARATOR)
+ {
+ gStringVar4[task->tCharIndex] = CHAR_SPACE; // restore it back to a space
+ sub_8003418(gMenuWindowPtr);
+ task->tCharIndex++;
+ task->data[2] = 0;
+ }
+ else
+ {
+ switch (task->data[1])
+ {
+ case 0:
+ sub_8003418(gMenuWindowPtr);
+ task->data[1]++;
+ break;
+ case 1:
+ task->data[1]++;
+ break;
+ case 2:
+ task->tCharIndex++;
+ task->data[1] = 0;
+ task->data[2] = gUnknown_03005DA0.var04;
+ task->tState = 4;
+ break;
+ }
+ }
+ break;
+ case 4:
+ task->data[2]--;
+ if (task->data[2] == 0)
+ task->tState = 3;
+ break;
+ }
+}
+
+void sub_80F83D0(void)
+{
+ VarSet(0x4010, 0x45 + GetCurrentMauvilleOldMan());
+}
+
+struct Story
+{
+ u8 stat;
+ u8 minVal;
+ const u8 *title;
+ const u8 *action;
+ const u8 *fullText;
+};
+
+static const struct Story sStorytellerStories[] =
+{
+ {0x32, 1, gTextStoryteller_Story1Title, gTextStoryteller_Story1Action, gTextStoryteller_Story1Text},
+ {0x02, 1, gTextStoryteller_Story2Title, gTextStoryteller_Story2Action, gTextStoryteller_Story2Text},
+ {0x03, 1, gTextStoryteller_Story3Title, gTextStoryteller_Story3Action, gTextStoryteller_Story3Text},
+ {0x04, 1, gTextStoryteller_Story4Title, gTextStoryteller_Story4Action, gTextStoryteller_Story4Text},
+ {0x06, 1, gTextStoryteller_Story5Title, gTextStoryteller_Story5Action, gTextStoryteller_Story5Text},
+ {0x09, 1, gTextStoryteller_Story6Title, gTextStoryteller_Story6Action, gTextStoryteller_Story6Text},
+ {0x0B, 1, gTextStoryteller_Story7Title, gTextStoryteller_Story7Action, gTextStoryteller_Story7Text},
+ {0x0C, 1, gTextStoryteller_Story8Title, gTextStoryteller_Story8Action, gTextStoryteller_Story8Text},
+ {0x0D, 1, gTextStoryteller_Story9Title, gTextStoryteller_Story9Action, gTextStoryteller_Story9Text},
+ {0x0E, 1, gTextStoryteller_Story10Title, gTextStoryteller_Story10Action, gTextStoryteller_Story10Text},
+ {0x0F, 1, gTextStoryteller_Story11Title, gTextStoryteller_Story11Action, gTextStoryteller_Story11Text},
+ {0x10, 1, gTextStoryteller_Story12Title, gTextStoryteller_Story12Action, gTextStoryteller_Story12Text},
+ {0x11, 1, gTextStoryteller_Story13Title, gTextStoryteller_Story13Action, gTextStoryteller_Story13Text},
+ {0x12, 1, gTextStoryteller_Story14Title, gTextStoryteller_Story14Action, gTextStoryteller_Story14Text},
+ {0x13, 1, gTextStoryteller_Story15Title, gTextStoryteller_Story15Action, gTextStoryteller_Story15Text},
+ {0x14, 1, gTextStoryteller_Story16Title, gTextStoryteller_Story16Action, gTextStoryteller_Story16Text},
+ {0x1A, 1, gTextStoryteller_Story17Title, gTextStoryteller_Story17Action, gTextStoryteller_Story17Text},
+ {0x1B, 1, gTextStoryteller_Story18Title, gTextStoryteller_Story18Action, gTextStoryteller_Story18Text},
+ {0x1C, 1, gTextStoryteller_Story19Title, gTextStoryteller_Story19Action, gTextStoryteller_Story19Text},
+ {0x1D, 2, gTextStoryteller_Story20Title, gTextStoryteller_Story20Action, gTextStoryteller_Story20Text},
+ {0x1E, 1, gTextStoryteller_Story21Title, gTextStoryteller_Story21Action, gTextStoryteller_Story21Text},
+ {0x21, 1, gTextStoryteller_Story22Title, gTextStoryteller_Story22Action, gTextStoryteller_Story22Text},
+ {0x24, 1, gTextStoryteller_Story23Title, gTextStoryteller_Story23Action, gTextStoryteller_Story23Text},
+ {0x25, 1, gTextStoryteller_Story24Title, gTextStoryteller_Story24Action, gTextStoryteller_Story24Text},
+ {0x26, 1, gTextStoryteller_Story25Title, gTextStoryteller_Story25Action, gTextStoryteller_Story25Text},
+ {0x27, 1, gTextStoryteller_Story26Title, gTextStoryteller_Story26Action, gTextStoryteller_Story26Text},
+ {0x28, 1, gTextStoryteller_Story27Title, gTextStoryteller_Story27Action, gTextStoryteller_Story27Text},
+ {0x29, 1, gTextStoryteller_Story28Title, gTextStoryteller_Story28Action, gTextStoryteller_Story28Text},
+ {0x2A, 1, gTextStoryteller_Story29Title, gTextStoryteller_Story29Action, gTextStoryteller_Story29Text},
+ {0x2B, 1, gTextStoryteller_Story30Title, gTextStoryteller_Story30Action, gTextStoryteller_Story30Text},
+ {0x2C, 1, gTextStoryteller_Story31Title, gTextStoryteller_Story31Action, gTextStoryteller_Story31Text},
+ {0x2D, 1, gTextStoryteller_Story32Title, gTextStoryteller_Story32Action, gTextStoryteller_Story32Text},
+ {0x2E, 1, gTextStoryteller_Story33Title, gTextStoryteller_Story33Action, gTextStoryteller_Story33Text},
+ {0x2F, 1, gTextStoryteller_Story34Title, gTextStoryteller_Story34Action, gTextStoryteller_Story34Text},
+ {0x30, 1, gTextStoryteller_Story35Title, gTextStoryteller_Story35Action, gTextStoryteller_Story35Text},
+ {0x31, 1, gTextStoryteller_Story36Title, gTextStoryteller_Story36Action, gTextStoryteller_Story36Text},
+};
+
+static void StorytellerSetup(void)
+{
+ struct MauvilleManStoryteller *storyteller = &gSaveBlock1.mauvilleMan.storyteller;
+ s32 i;
+
+ storyteller->id = MAUVILLE_MAN_STORYTELLER;
+ storyteller->alreadyRecorded = FALSE;
+ for (i = 0; i < 4; i++)
+ {
+ storyteller->gameStatIDs[i] = 0;
+ storyteller->trainerNames[0][i] = EOS; // Maybe they meant storyteller->trainerNames[i][0] instead?
+ }
+}
+
+static void sub_80F8428(void)
+{
+ struct MauvilleManStoryteller *storyteller = &gSaveBlock1.mauvilleMan.storyteller;
+
+ storyteller->id = MAUVILLE_MAN_STORYTELLER;
+ storyteller->alreadyRecorded = FALSE;
+}
+
+static u32 StorytellerGetGameStat(u8 stat)
+{
+ if (stat == NUM_GAME_STATS)
+ stat = 0;
+ return GetGameStat(stat);
+}
+
+static const struct Story *GetStoryByStat(u32 stat)
+{
+ s32 i;
+
+ for (i = 0; i < 36; i++)
+ {
+ if (sStorytellerStories[i].stat == stat)
+ return &sStorytellerStories[i];
+ }
+ return &sStorytellerStories[35];
+}
+
+static const u8 *GetStoryTitleByStat(u32 stat)
+{
+ return GetStoryByStat(stat)->title;
+}
+
+static const u8 *GetStoryTextByStat(u32 stat)
+{
+ return GetStoryByStat(stat)->fullText;
+}
+
+static const u8 *GetStoryActionByStat(u32 stat)
+{
+ return GetStoryByStat(stat)->action;
+}
+
+static u8 GetFreeStorySlot(void)
+{
+ u8 i;
+
+ for (i = 0; i < 4; i++)
+ {
+ struct MauvilleManStoryteller *storyteller = &gSaveBlock1.mauvilleMan.storyteller;
+
+ if (storyteller->gameStatIDs[i] == 0)
+ break;
+ }
+ return i;
+}
+
+static u32 StorytellerGetRecordedTrainerStat(u32 trainer)
+{
+ u8 *ptr = gSaveBlock1.mauvilleMan.storyteller.statValues[trainer];
+
+ return ptr[0] | (ptr[1] << 8) | (ptr[2] << 16) | (ptr[3] << 24);
+}
+
+static void StorytellerSetRecordedTrainerStat(u32 trainer, u32 val)
+{
+ u8 *ptr = gSaveBlock1.mauvilleMan.storyteller.statValues[trainer];
+
+ ptr[0] = val;
+ ptr[1] = val >> 8;
+ ptr[2] = val >> 16;
+ ptr[3] = val >> 24;
+}
+
+static bool32 HasTrainerStatIncreased(u32 trainer)
+{
+ struct MauvilleManStoryteller *storyteller = &gSaveBlock1.mauvilleMan.storyteller;
+
+ if (StorytellerGetGameStat(storyteller->gameStatIDs[trainer]) > StorytellerGetRecordedTrainerStat(trainer))
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static void GetStoryByStattellerPlayerName(u32 player, void *dst)
+{
+ u8 *name = gSaveBlock1.mauvilleMan.storyteller.trainerNames[player];
+
+ memset(dst, EOS, 8);
+ memcpy(dst, name, 7);
+}
+
+static void StorytellerSetPlayerName(u32 player, const u8 *src)
+{
+ u8 *name = gSaveBlock1.mauvilleMan.storyteller.trainerNames[player];
+ u8 len = StringLength(src);
+
+ memset(name, EOS, 7);
+ StringCopyN(name, src, len);
+}
+
+static void StorytellerRecordNewStat(u32 player, u32 stat)
+{
+ struct MauvilleManStoryteller *storyteller = &gSaveBlock1.mauvilleMan.storyteller;
+
+ storyteller->gameStatIDs[player] = stat;
+ StorytellerSetPlayerName(player, gSaveBlock2.playerName);
+ StorytellerSetRecordedTrainerStat(player, StorytellerGetGameStat(stat));
+ ConvertIntToDecimalStringN(gStringVar1, StorytellerGetGameStat(stat), 0, 10);
+ StringCopy(gStringVar2, GetStoryActionByStat(stat));
+}
+
+static void ScrambleStatList(u8 *arr, s32 count)
+{
+ s32 i;
+
+ for (i = 0; i < count; i++)
+ arr[i] = i;
+ for (i = 0; i < count; i++)
+ {
+ u32 a = Random() % count;
+ u32 b = Random() % count;
+ u8 temp = arr[a];
+ arr[a] = arr[b];
+ arr[b] = temp;
+ }
+}
+
+// What purpose does this struct even serve? Only the length field is used.
+static const struct {u32 length; struct MauvilleManStoryteller *unused1; u32 unused2;} sStorytellerStuff =
+{
+ 36,
+ &gSaveBlock1.mauvilleMan.storyteller, // unused
+ 12, // unused
+};
+
+static bool8 StorytellerInitializeRandomStat(void)
+{
+ u8 arr[sStorytellerStuff.length];
+ s32 i;
+ s32 j;
+
+ ScrambleStatList(arr, 36);
+ for (i = 0; i < 36; i++)
+ {
+ u8 stat = sStorytellerStories[arr[i]].stat;
+ u8 minVal = sStorytellerStories[arr[i]].minVal;
+ struct MauvilleManStoryteller *storyteller = &gSaveBlock1.mauvilleMan.storyteller;
+
+ for (j = 0; j < 4; j++)
+ {
+ if (gSaveBlock1.mauvilleMan.storyteller.gameStatIDs[j] == stat)
+ break;
+ }
+ if (j == 4 && StorytellerGetGameStat(stat) >= minVal)
+ {
+ storyteller->alreadyRecorded = TRUE;
+ StorytellerRecordNewStat(GetFreeStorySlot(), stat);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static void StorytellerDisplayStory(u32 player)
+{
+ struct MauvilleManStoryteller *storyteller = &gSaveBlock1.mauvilleMan.storyteller;
+ u8 stat = storyteller->gameStatIDs[player];
+
+ ConvertIntToDecimalStringN(gStringVar1, StorytellerGetRecordedTrainerStat(player), 0, 10);
+ StringCopy(gStringVar2, GetStoryActionByStat(stat));
+ GetStoryByStattellerPlayerName(player, gStringVar3);
+ ShowFieldMessage(GetStoryTextByStat(stat));
+}
+
+static void PrintStoryList(void)
+{
+ s32 i;
+
+ MenuDrawTextWindow(0, 0, 25, 4 + GetFreeStorySlot() * 2);
+ for (i = 0; i < 4; i++)
+ {
+ struct MauvilleManStoryteller *storyteller = &gSaveBlock1.mauvilleMan.storyteller;
+ u8 stat = storyteller->gameStatIDs[i];
+
+ if (stat == 0)
+ break;
+ MenuPrint(GetStoryTitleByStat(stat), 1, 2 + i * 2);
+ }
+ MenuPrint(gPCText_Cancel, 1, 2 + i * 2);
+}
+
+static u8 gUnknown_03000748;
+
+static void Task_StoryListMenu(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+ s32 selection;
+
+ switch (task->data[0])
+ {
+ case 0:
+ PrintStoryList();
+ InitMenu(0, 1, 2, GetFreeStorySlot() + 1, 0, 24);
+ task->data[0]++;
+ break;
+ case 1:
+ selection = ProcessMenuInput();
+ if (selection == -2)
+ break;
+ if (selection == -1 || selection == GetFreeStorySlot())
+ {
+ gScriptResult = 0;
+ }
+ else
+ {
+ gScriptResult = 1;
+ gUnknown_03000748 = selection;
+ }
+ HandleDestroyMenuCursors();
+ MenuZeroFillWindowRect(0, 0, 25, 12);
+ DestroyTask(taskId);
+ EnableBothScriptContexts();
+ break;
+ }
+}
+
+// Sets gScriptResult to TRUE if player selected a story
+void ScrSpecial_StorytellerStoryListMenu(void)
+{
+ CreateTask(Task_StoryListMenu, 0x50);
+}
+
+void ScrSpecial_StorytellerDisplayStory(void)
+{
+ StorytellerDisplayStory(gUnknown_03000748);
+}
+
+u8 ScrSpecial_StorytellerGetFreeStorySlot(void)
+{
+ return GetFreeStorySlot();
+}
+
+// Returns TRUE if stat has increased
+bool8 ScrSpecial_StorytellerUpdateStat(void)
+{
+ struct MauvilleManStoryteller *storyteller = &gSaveBlock1.mauvilleMan.storyteller;
+ u8 r4 = storyteller->gameStatIDs[gUnknown_03000748];
+
+ if (HasTrainerStatIncreased(gUnknown_03000748) == TRUE)
+ {
+ StorytellerRecordNewStat(gUnknown_03000748, r4);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 ScrSpecial_HasStorytellerAlreadyRecorded(void)
+{
+ struct MauvilleManStoryteller *storyteller = &gSaveBlock1.mauvilleMan.storyteller;
+
+ if (storyteller->alreadyRecorded == FALSE)
+ return FALSE;
+ else
+ return TRUE;
+}
+
+bool8 ScrSpecial_StorytellerInitializeRandomStat(void)
+{
+ return StorytellerInitializeRandomStat();
+}
diff --git a/src/field/mauville_old_man.c b/src/field/mauville_old_man.c
deleted file mode 100644
index 93684fc60..000000000
--- a/src/field/mauville_old_man.c
+++ /dev/null
@@ -1,247 +0,0 @@
-#include "global.h"
-#include "mauville_old_man.h"
-#include "easy_chat.h"
-#include "menu.h"
-#include "rng.h"
-#include "script.h"
-#include "string_util.h"
-#include "strings.h"
-#include "trader.h"
-
-extern u16 gScriptResult;
-extern u16 gSpecialVar_0x8004;
-
-extern u32 gUnknown_083E5388[];
-extern u32 gUnknown_083E53A8[];
-
-extern u16 gUnknown_083E537C[];
-
-void sub_80F7A34(void)
-{
- u16 i;
- OldMan *oldMan = &gSaveBlock1.oldMan;
-
- oldMan->oldMan1.unk_2D94 = 0;
- oldMan->oldMan1.unk_2DBD = 0;
-
- for(i = 0; i < 6; i++)
- oldMan->oldMan1.mauvilleOldMan_ecArray[i] = gUnknown_083E537C[i];
-}
-
-void sub_80F7A6C(void)
-{
- struct UnkMauvilleOldManStruct *bard = &gSaveBlock1.oldMan.oldMan1;
-
- bard->unk_2D94 = 1;
- bard->unk_2D95 = 0;
-}
-
-void sub_80F7A7C(void)
-{
- sub_80F83F8();
-}
-
-void sub_80F7A88(void)
-{
- OldMan *oldMan = &gSaveBlock1.oldMan;
-
- oldMan->oldMan1.unk_2D94 = 4;
- oldMan->oldMan1.unk_2D95 = 0;
-}
-
-void sub_80F7A98(void)
-{
- sub_81099CC();
-}
-
-void SetMauvilleOldMan(void)
-{
- u32 var = ((u16)((gSaveBlock2.playerTrainerId[1] << 8 | gSaveBlock2.playerTrainerId[0])) % 10) / 2;
-
- switch(var)
- {
- case 0:
- sub_80F7A34();
- break;
- case 1:
- sub_80F7A6C();
- break;
- case 2:
- sub_80F7A98();
- break;
- case 3:
- sub_80F7A7C();
- break;
- case 4:
- sub_80F7A88();
- break;
- }
- sub_80F83D0();
-}
-
-u8 GetCurrentMauvilleOldMan(void)
-{
- OldMan *oldMan = &gSaveBlock1.oldMan;
-
- return oldMan->oldMan1.unk_2D94;
-}
-
-void sub_80F7B14(void)
-{
- gScriptResult = GetCurrentMauvilleOldMan();
-}
-
-void sub_80F7B2C(void)
-{
- u16 *scriptPtr = &gScriptResult; // why??
- OldMan *oldMan = &gSaveBlock1.oldMan;
-
- *scriptPtr = oldMan->oldMan1.unk_2DBD;
-}
-
-void sub_80F7B40(void)
-{
- u16 i;
- OldMan *oldMan = &gSaveBlock1.oldMan;
- //struct UnkMauvilleOldManStruct *oldManStruct = &gSaveBlock1.oldManStruct;
-
- StringCopy(oldMan->oldMan1.playerName, gSaveBlock2.playerName);
-
- for(i = 0; i < 4; i++)
- oldMan->oldMan1.playerTrainerId[i] = gSaveBlock2.playerTrainerId[i];
-
- for(i = 0; i < 6; i++)
- oldMan->oldMan1.mauvilleOldMan_ecArray[i] = oldMan->oldMan1.mauvilleOldMan_ecArray2[i];
-
- oldMan->oldMan1.unk_2DBD = 1;
-}
-
-void sub_80F7BA0(void)
-{
- struct UnkMauvilleOldManStruct *oldMan = &gSaveBlock1.oldMan.oldMan1;
- u16 specialVar = gSpecialVar_0x8004; // It's a bit odd to use this temp variable, but it seems needed to match.
- u16 *r5;
- u16 i;
- u8 *ptr;
- u8 *r4;
-
- r5 = oldMan->mauvilleOldMan_ecArray2;
- if (specialVar == 0)
- r5 = oldMan->mauvilleOldMan_ecArray;
- ptr = gStringVar4;
- r4 = ptr;
- for (i = 0; i < 2; i++)
- {
- ptr = sub_80EB3FC(ptr, *(r5++));
- while (ptr != r4)
- {
- if (*r4 == 0)
- *r4 = 0x37;
- r4++;
- }
- r4++;
- *(ptr++) = 0;
- ptr = sub_80EB3FC(ptr, *(r5++));
- while (ptr != r4)
- {
- if (*r4 == 0)
- *r4 = 0x37;
- r4++;
- }
- r4++;
- *(ptr++) = 0xFE;
- ptr = sub_80EB3FC(ptr, *(r5++));
- while (ptr != r4)
- {
- if (*r4 == 0)
- *r4 = 0x37;
- r4++;
- }
- //_080F7C2A
- if (i == 0)
- {
- *(ptr++) = EXT_CTRL_CODE_BEGIN;
- *(ptr++) = 0xF;
- }
- }
-}
-
-void sub_80F7C54(void)
-{
- sub_80F7F80(gSpecialVar_0x8004);
- MenuDisplayMessageBox();
- ScriptContext1_Stop();
-}
-
-void sub_80F7C70(void)
-{
- u16 *scriptPtr = &gScriptResult; // again??
- OldMan *oldMan = &gSaveBlock1.oldMan;
-
- *scriptPtr = oldMan->oldMan1.unk_2D95;
-}
-
-void sub_80F7C84(void)
-{
- OldMan *oldMan = &gSaveBlock1.oldMan;
-
- oldMan->oldMan1.unk_2D95 = 1;
-}
-
-void sub_80F7C90(void)
-{
- u16 var = sub_80EB8EC();
-
- if(var == 0xFFFF)
- {
- gScriptResult = FALSE;
- }
- else
- {
- sub_80EB3FC(gStringVar1, var);
- gScriptResult = TRUE;
- }
-}
-
-void sub_80F7CC8(void)
-{
- OldMan *oldMan = &gSaveBlock1.oldMan;
-
- if(oldMan->oldMan1.unk_2D95 == 10)
- {
- gScriptResult = FALSE;
- oldMan->oldMan1.unk_2D95 = 0;
- }
- else
- gScriptResult = TRUE;
-}
-
-void sub_80F7CF4(void)
-{
- struct UnkMauvilleOldManStruct2 *oldMan = &gSaveBlock1.oldMan.oldMan2;
-
- if(oldMan->unk1 == 0)
- sub_80F7DC0();
-
- if(oldMan->mauvilleOldMan_ecArray[oldMan->unk1] != 0xFFFF) // is not the last element of the array?
- {
- u8 *stringPtr;
- u32 random = Random();
-
- random %= 8;
- stringPtr = sub_80EB3FC(gStringVar4, oldMan->mauvilleOldMan_ecArray[oldMan->unk1]);
- stringPtr = StringCopy(stringPtr, gOtherText_Is);
- stringPtr = StringCopy(stringPtr, (u8 *)gUnknown_083E5388[random]);
- StringCopy(stringPtr, gOtherText_DontYouAgree);
- }
- else
- {
- StringCopy(gStringVar4, (u8 *)gUnknown_083E53A8[oldMan->mauvilleOldMan_ecArray2[oldMan->unk2++]]);
- }
- if(!(Random() % 10))
- oldMan->unk1 = 10;
- else
- oldMan->unk1++;
-
- gScriptResult = TRUE;
-}
diff --git a/src/field/party_menu.c b/src/field/party_menu.c
index 1fcd2cdda..39477e293 100644
--- a/src/field/party_menu.c
+++ b/src/field/party_menu.c
@@ -33,15 +33,6 @@
#include "species.h"
#include "party_menu.h"
-#define DATA_COUNT (6)
-
-struct Unk2001000
-{
- u8 unk0;
- u8 unk1;
- u8 unk2;
-};
-
struct Unk201C000
{
/*0x00*/ struct Pokemon *pokemon;
@@ -68,8 +59,6 @@ struct UnknownStruct5
u16 *unk4;
};
-extern u8 ewram[];
-#define ewram01000 (*(struct Unk2001000 *)(ewram + 0x01000))
#define ewram1C000 (*(struct Unk201C000 *)(ewram + 0x1C000))
#define ewram1F000 (*(struct Unk201F000 *)(ewram + 0x1F000))
diff --git a/src/field/trader.c b/src/field/trader.c
index ea06058e9..61f48fad8 100644
--- a/src/field/trader.c
+++ b/src/field/trader.c
@@ -3,6 +3,7 @@
#include "decoration_inventory.h"
#include "event_data.h"
#include "main.h"
+#include "mauville_man.h"
#include "menu.h"
#include "menu_helpers.h"
#include "script.h"
@@ -36,7 +37,7 @@ void sub_810993C(void)
{
u8 i, j;
u8 buffer[12];
- struct MauvilleOldManTrader *trader = &gSaveBlock1.oldMan.trader;
+ struct MauvilleManTrader *trader = &gSaveBlock1.mauvilleMan.trader;
for (i = 0; i < 3; i++)
{
@@ -55,13 +56,13 @@ void sub_810993C(void)
}
}
-void sub_81099CC(void)
+void TraderSetup(void)
{
u8 i;
- struct MauvilleOldManTrader *trader = &gSaveBlock1.oldMan.trader;
+ struct MauvilleManTrader *trader = &gSaveBlock1.mauvilleMan.trader;
- trader->unk0 = 2;
- trader->unk31 = 0;
+ trader->id = MAUVILLE_MAN_TRADER;
+ trader->alreadyTraded = FALSE;
for (i = 0; i < 4; i++)
{
@@ -74,8 +75,8 @@ void sub_81099CC(void)
void sub_8109A20(void)
{
- struct MauvilleOldManTrader *trader = &gSaveBlock1.oldMan.trader;
- trader->unk31 = 0;
+ struct MauvilleManTrader *trader = &gSaveBlock1.mauvilleMan.trader;
+ trader->alreadyTraded = FALSE;
}
void sub_8109A30(u8 value)
@@ -83,12 +84,12 @@ void sub_8109A30(u8 value)
VarSet(VAR_RECYCLE_GOODS, value);
}
-void sub_8109A48(u8 taskId)
+void CreateAvailableDecorationsMenu(u8 taskId)
{
u8 i;
u8 numChoices = 1;
u8 numDecorations = 0;
- struct MauvilleOldManTrader *trader = &gSaveBlock1.oldMan.trader;
+ struct MauvilleManTrader *trader = &gSaveBlock1.mauvilleMan.trader;
for (i = 0; i < 4; i++)
{
@@ -139,9 +140,9 @@ void sub_8109B34(u8 taskId, u8 decorationId)
EnableBothScriptContexts();
}
-void sub_8109B7C(u8 taskId)
+void Task_HandleGetDecorationMenuInput(u8 taskId)
{
- struct MauvilleOldManTrader *trader = &gSaveBlock1.oldMan.trader;
+ struct MauvilleManTrader *trader = &gSaveBlock1.mauvilleMan.trader;
if (gMain.newKeys & DPAD_UP)
{
@@ -174,13 +175,13 @@ void sub_8109B7C(u8 taskId)
}
}
-void sub_8109C44(void)
+void ScrSpecial_GetTraderTradedFlag(void)
{
- struct MauvilleOldManTrader *trader = &gSaveBlock1.oldMan.trader;
- gScriptResult = trader->unk31;
+ struct MauvilleManTrader *trader = &gSaveBlock1.mauvilleMan.trader;
+ gScriptResult = trader->alreadyTraded;
}
-void sub_8109C58(void)
+void ScrSpecial_DoesPlayerHaveNoDecorations(void)
{
u8 i;
@@ -195,7 +196,7 @@ void sub_8109C58(void)
gScriptResult = TRUE;
}
-void sub_8109C90(void)
+void ScrSpecial_IsDecorationFull(void)
{
gScriptResult = FALSE;
if (gDecorations[gSpecialVar_0x8004].category != gDecorations[gSpecialVar_0x8006].category
@@ -206,7 +207,7 @@ void sub_8109C90(void)
}
}
-void sub_8109CF0(void)
+void ScrSpecial_TraderMenuGiveDecoration(void)
{
CreateTask(sub_80FE7A8, 0);
}
@@ -242,20 +243,20 @@ void sub_8109DAC(u8 taskId)
EnableBothScriptContexts();
}
-void sub_8109DE0(void)
+void ScrSpecial_TraderDoDecorationTrade(void)
{
- struct MauvilleOldManTrader *trader = &gSaveBlock1.oldMan.trader;
+ struct MauvilleManTrader *trader = &gSaveBlock1.mauvilleMan.trader;
sub_81340A8(gSpecialVar_0x8006);
IsThereStorageSpaceForDecoration(gSpecialVar_0x8004);
StringCopy(trader->unk5[gSpecialVar_0x8005], gSaveBlock2.playerName);
trader->unk1[gSpecialVar_0x8005] = gSpecialVar_0x8006;
sub_810993C();
- trader->unk31 = 1;
+ trader->alreadyTraded = TRUE;
}
-void sub_8109E34(void)
+void ScrSpecial_TraderMenuGetDecoration(void)
{
- u8 taskId = CreateTask(sub_8109B7C, 0);
- sub_8109A48(taskId);
+ u8 taskId = CreateTask(Task_HandleGetDecorationMenuInput, 0);
+ CreateAvailableDecorationsMenu(taskId);
}
diff --git a/src/field/tv.c b/src/field/tv.c
index a254bcd5f..996709209 100644
--- a/src/field/tv.c
+++ b/src/field/tv.c
@@ -388,7 +388,7 @@ bool8 GabbyAndTyGetLastQuote(void)
if (gSaveBlock1.gabbyAndTyData.quote == 0xffff)
return FALSE;
- sub_80EB3FC(gStringVar1, gSaveBlock1.gabbyAndTyData.quote);
+ EasyChat_GetWordText(gStringVar1, gSaveBlock1.gabbyAndTyData.quote);
gSaveBlock1.gabbyAndTyData.quote |= 0xffff;
return TRUE;
}
@@ -1624,7 +1624,7 @@ void sub_80BF79C(TVShow *arg0)
break;
i++;
}
- sub_80EB3FC(gStringVar3, arg0->recentHappenings.var04[i]);
+ EasyChat_GetWordText(gStringVar3, arg0->recentHappenings.var04[i]);
}
u8 sub_80BF7E8(struct TVShowNameRaterShow *arg0)
@@ -2575,20 +2575,20 @@ void DoTVShowBravoTrainerPokemonProfile(void)
break;
case 3:
TVShowConvertInternationalString(gStringVar1, bravoTrainer->playerName, bravoTrainer->language);
- sub_80EB3FC(gStringVar2, bravoTrainer->var04[0]);
+ EasyChat_GetWordText(gStringVar2, bravoTrainer->var04[0]);
sub_80BF088(2, bravoTrainer->contestResult + 1);
gUnknown_020387E8 = 5;
break;
case 4:
TVShowConvertInternationalString(gStringVar1, bravoTrainer->playerName, bravoTrainer->language);
- sub_80EB3FC(gStringVar2, bravoTrainer->var04[0]);
+ EasyChat_GetWordText(gStringVar2, bravoTrainer->var04[0]);
sub_80BF088(2, bravoTrainer->contestResult + 1);
gUnknown_020387E8 = 5;
break;
case 5:
TVShowConvertInternationalString(gStringVar1, bravoTrainer->playerName, bravoTrainer->language);
CopyContestCategoryToStringVar(1, bravoTrainer->contestCategory);
- sub_80EB3FC(gStringVar3, bravoTrainer->var04[1]);
+ EasyChat_GetWordText(gStringVar3, bravoTrainer->var04[1]);
if (bravoTrainer->var14)
gUnknown_020387E8 = 6;
else
@@ -2597,7 +2597,7 @@ void DoTVShowBravoTrainerPokemonProfile(void)
case 6:
StringCopy(gStringVar1, gSpeciesNames[bravoTrainer->species]);
StringCopy(gStringVar2, gMoveNames[bravoTrainer->var14]);
- sub_80EB3FC(gStringVar3, bravoTrainer->var04[1]);
+ EasyChat_GetWordText(gStringVar3, bravoTrainer->var04[1]);
gUnknown_020387E8 = 7;
break;
case 7:
@@ -2680,7 +2680,7 @@ void DoTVShowBravoTrainerBattleTowerProfile(void)
gUnknown_020387E8 = 11;
break;
case 11:
- sub_80EB3FC(gStringVar1, bravoTrainerTower->var18[0]);
+ EasyChat_GetWordText(gStringVar1, bravoTrainerTower->var18[0]);
if (bravoTrainerTower->var1b == 0)
gUnknown_020387E8 = 12;
else
@@ -2688,7 +2688,7 @@ void DoTVShowBravoTrainerBattleTowerProfile(void)
break;
case 12:
case 13:
- sub_80EB3FC(gStringVar1, bravoTrainerTower->var18[0]);
+ EasyChat_GetWordText(gStringVar1, bravoTrainerTower->var18[0]);
TVShowConvertInternationalString(gStringVar2, bravoTrainerTower->trainerName, bravoTrainerTower->language);
TVShowConvertInternationalString(gStringVar3, bravoTrainerTower->pokemonName, bravoTrainerTower->language);
gUnknown_020387E8 = 14;
@@ -3106,12 +3106,12 @@ void DoTVShowPokemonFanClubOpinions(void)
case 3:
TVShowConvertInternationalString(gStringVar1, fanclubOpinions->playerName, fanclubOpinions->language);
StringCopy(gStringVar2, gSpeciesNames[fanclubOpinions->var02]);
- sub_80EB3FC(gStringVar3, fanclubOpinions->var1C[0]);
+ EasyChat_GetWordText(gStringVar3, fanclubOpinions->var1C[0]);
gUnknown_020387E8 = 4;
break;
case 4:
TVShowConvertInternationalString(gStringVar1, fanclubOpinions->playerName, fanclubOpinions->language);
- sub_80EB3FC(gStringVar3, fanclubOpinions->var1C[1]);
+ EasyChat_GetWordText(gStringVar3, fanclubOpinions->var1C[1]);
TVShowDone();
break;
}
@@ -3176,7 +3176,7 @@ void DoTVShowInSearchOfTrainers(void)
gUnknown_020387E8 = 8;
break;
case 8:
- sub_80EB3FC(gStringVar1, gSaveBlock1.gabbyAndTyData.quote);
+ EasyChat_GetWordText(gStringVar1, gSaveBlock1.gabbyAndTyData.quote);
StringCopy(gStringVar2, gSpeciesNames[gSaveBlock1.gabbyAndTyData.mon1]);
StringCopy(gStringVar3, gSpeciesNames[gSaveBlock1.gabbyAndTyData.mon2]);
gScriptResult = 1;
diff --git a/src/libs/m4a_4.c b/src/libs/m4a_4.c
index 99195ec00..2e1d140b4 100644
--- a/src/libs/m4a_4.c
+++ b/src/libs/m4a_4.c
@@ -45,7 +45,7 @@ void m4aMPlayVolumeControl(struct MusicPlayerInfo *mplayInfo, u16 trackBits, u16
mplayInfo->ident = ID_NUMBER;
}
-void m4aMPlayPitchControl(struct MusicPlayerInfo *mplayInfo, u16 trackBits, u16 pitch)
+void m4aMPlayPitchControl(struct MusicPlayerInfo *mplayInfo, u16 trackBits, s16 pitch)
{
s32 i;
u32 bit;
diff --git a/src/pokemon/mail.c b/src/pokemon/mail.c
index 658d37976..fb9251a5d 100644
--- a/src/pokemon/mail.c
+++ b/src/pokemon/mail.c
@@ -92,7 +92,7 @@ void HandleReadMail(struct MailStruct *arg0, MainCallback arg1, bool8 arg2)
ewram0.varFF = GAME_LANGUAGE;
ewram0.var100 = 1;
- ewram0.var104 = (MainCallback)sub_80EB3FC;
+ ewram0.var104 = (MainCallback)EasyChat_GetWordText;
ewram0.var108 = (MainCallback)ConvertEasyChatWordsToString;
mailDesign = arg0->itemId - ITEM_ORANGE_MAIL;
diff --git a/src/pokemon/pokemon_1.c b/src/pokemon/pokemon_1.c
index c65bfa185..9c46e54d5 100644
--- a/src/pokemon/pokemon_1.c
+++ b/src/pokemon/pokemon_1.c
@@ -17,9 +17,9 @@
#define LOHALF(n) ((n) & 0xFFFF)
extern u8 unk_2000000[];
-extern u16 word_2024E82;
+extern u16 gMoveToLearn;
-static EWRAM_DATA u8 byte_2024E88 = 0;
+static EWRAM_DATA u8 sLearningMoveTableID = 0;
u8 gPlayerPartyCount;
struct Pokemon gPlayerParty[6];
@@ -583,29 +583,33 @@ void GiveBoxMonInitialMoveset(struct BoxPokemon *boxMon)
}
}
-u16 sub_803B7C8(struct Pokemon *mon, u8 a2)
+u16 MonTryLearningNewMove(struct Pokemon *mon, bool8 firstMove)
{
u32 retVal = 0;
u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL);
u8 level = GetMonData(mon, MON_DATA_LEVEL, NULL);
- if (a2)
+ // since you can learn more than one move per level
+ // the game needs to know whether you decided to
+ // learn it or keep the old set to avoid asking
+ // you to learn the same move over and over again
+ if (firstMove)
{
- byte_2024E88 = retVal;
+ sLearningMoveTableID = 0;
- while ((gLevelUpLearnsets[species][byte_2024E88] & 0xFE00) != (level << 9))
+ while ((gLevelUpLearnsets[species][sLearningMoveTableID] & 0xFE00) != (level << 9))
{
- byte_2024E88++;
- if (gLevelUpLearnsets[species][byte_2024E88] == (u16)-1)
+ sLearningMoveTableID++;
+ if (gLevelUpLearnsets[species][sLearningMoveTableID] == 0xFFFF)
return 0;
}
}
- if ((gLevelUpLearnsets[species][byte_2024E88] & 0xFE00) == (level << 9))
+ if ((gLevelUpLearnsets[species][sLearningMoveTableID] & 0xFE00) == (level << 9))
{
- word_2024E82 = (gLevelUpLearnsets[species][byte_2024E88] & 0x1FF);
- byte_2024E88++;
- retVal = GiveMoveToMon(mon, word_2024E82);
+ gMoveToLearn = (gLevelUpLearnsets[species][sLearningMoveTableID] & 0x1FF);
+ sLearningMoveTableID++;
+ retVal = GiveMoveToMon(mon, gMoveToLearn);
}
return retVal;
diff --git a/src/pokemon/pokemon_3.c b/src/pokemon/pokemon_3.c
index d7cc39546..4f7655a34 100644
--- a/src/pokemon/pokemon_3.c
+++ b/src/pokemon/pokemon_3.c
@@ -1197,7 +1197,7 @@ const struct CompressedSpritePalette *sub_80409C8(u16 species, u32 otId , u32 pe
return &gMonPaletteTable[species];
}
-bool8 IsHMMove2(u16 move)
+bool32 IsHMMove2(u16 move)
{
int i = 0;
while (gHMMoves[i] != 0xFFFF)
diff --git a/src/pokemon/pokemon_menu.c b/src/pokemon/pokemon_menu.c
new file mode 100644
index 000000000..821101569
--- /dev/null
+++ b/src/pokemon/pokemon_menu.c
@@ -0,0 +1,1197 @@
+#include "global.h"
+#include "pokemon.h"
+#include "pokemon_menu.h"
+#include "party_menu.h"
+#include "palette.h"
+#include "menu.h"
+#include "mail_data.h"
+#include "songs.h"
+#include "sound.h"
+#include "main.h"
+#include "rom4.h"
+#include "menu_helpers.h"
+#include "pokemon_summary_screen.h"
+#include "moves.h"
+#include "data2.h"
+#include "strings.h"
+#include "item_use.h"
+#include "item.h"
+#include "event_data.h"
+#include "mail.h"
+#include "field_player_avatar.h"
+#include "fldeff_softboiled.h"
+#include "braille_puzzles.h"
+#include "field_fadetransition.h"
+#include "field_weather.h"
+#include "field_effect.h"
+#include "field_control_avatar.h"
+#include "metatile_behavior.h"
+#include "fieldmap.h"
+#include "item_menu.h"
+#include "player_pc.h"
+
+/*
+Pokemon menu:
+ The menu that appears when you
+ click on a pokemon in
+ overworld 'pokemon' menu
+*/
+
+struct PokeMenuFieldMoveFunc
+{
+ bool8 (*func)(void);
+ u8 field_1;
+};
+
+extern u8 gUnknown_020384F0;
+extern u8 gUnknown_0202E8F4;
+extern u8 gUnknown_0202E8F5;
+extern u8 gUnknown_0202E8F6;
+extern u8 gUnknown_02038561;
+extern u16 gUnknown_0202E8F8;
+extern u8 ewram[];
+extern void (*gUnknown_03004AE4)(u8 taskID, u16 itemID, TaskFunc func);
+extern TaskFunc gUnknown_03005CF0;
+
+void sub_80E62A0(u8 arg0, struct MailStruct* arg1, void* arg2, u8 arg3);
+void sub_808A520(void);
+void sub_80A61D0(void);
+void CB2_InitFlyRegionMap(void);
+u16 GetEvolutionTargetSpecies(struct Pokemon *mon, u8 type, u16 evolutionItem);
+bool8 SetUpFieldMove_Cut(void);
+bool8 SetUpFieldMove_Flash(void);
+bool8 SetUpFieldMove_RockSmash(void);
+bool8 SetUpFieldMove_Strength(void);
+bool8 SetUpFieldMove_Teleport(void);
+bool8 SetUpFieldMove_Dig(void);
+bool8 SetUpFieldMove_SecretPower(void);
+bool8 SetUpFieldMove_SoftBoiled(void);
+bool8 SetUpFieldMove_SoftBoiled(void);
+bool8 SetUpFieldMove_SweetScent(void);
+
+#define sFieldMovesTerminator 0xFF // note: should be changed to 0xFFFF, because currently it makes it impossible to add a field move with 0xFF index
+
+// this file's functions
+static void sub_808A8A8(void);
+static void sub_808B3EC(void);
+static void sub_8089D94(u8 taskID);
+static void sub_8089E4C(u8 taskID);
+static void sub_808A5BC(u8 taskID);
+static void sub_808A8D4(u8 taskID);
+static void sub_808A73C(u8 taskID);
+static void sub_808A848(u8 taskID);
+static void sub_808AAF0(u8 taskID);
+static void sub_808ABF4(u8 taskID);
+static void sub_808AB34(u8 taskID);
+static void sub_808ABA8(u8 taskID);
+static void sub_808B224(u8 taskID);
+static void sub_808B2EC(u8 taskID);
+static void sub_808B2B4(u8 taskID);
+static void sub_808B25C(u8 taskID);
+static void sub_808B1EC(u8 taskID);
+static void sub_808B338(u8 taskID);
+static void sub_808B4A4(u8 taskID);
+static void sub_808B4EC(u8 taskID);
+static void sub_808B5E4(u8 taskID);
+static void PokemonMenu_Summary(u8 taskID);
+static void PokemonMenu_Switch(u8 taskID);
+static void PokemonMenu_Item(u8 taskID);
+static void PokemonMenu_Cancel(u8 taskID);
+static void PokemonMenu_GiveItem(u8 taskID);
+static void PokemonMenu_TakeItem(u8 taskID);
+static void PokemonMenu_TakeMail(u8 taskID);
+static void PokemonMenu_Mail(u8 taskID);
+static void PokemonMenu_ReadMail(u8 taskID);
+static void PokemonMenu_CancelSubmenu(u8 taskID);
+static void PokemonMenu_FieldMove(u8 taskID);
+static bool8 SetUpFieldMove_Waterfall(void);
+static bool8 SetUpFieldMove_Surf(void);
+static bool8 SetUpFieldMove_Fly(void);
+static bool8 SetUpFieldMove_Dive(void);
+
+// ewram data
+
+EWRAM_DATA static u8 sPokeMenuCursorPos = 0;
+EWRAM_DATA static u8 sPokeMenuOptionsNo = 0;
+EWRAM_DATA static u8 sPokeMenuOptionsOrder[8] = {0}; // 4 possible field moves and 4 default options
+
+// iwram common
+u8 gLastFieldPokeMenuOpened;
+void (*gUnknown_03005CE4)(void);
+
+// const data
+
+static const struct MenuAction sPokemonMenuActions[] =
+{
+ {OtherText_Summary, (void*) PokemonMenu_Summary},
+ {OtherText_Switch2, (void*) PokemonMenu_Switch},
+ {OtherText_Item, (void*) PokemonMenu_Item},
+ {gOtherText_CancelNoTerminator, (void*) PokemonMenu_Cancel},
+ {OtherText_Give2, (void*) PokemonMenu_GiveItem},
+ {OtherText_Take2, (void*) PokemonMenu_TakeItem},
+ {OtherText_Take, (void*) PokemonMenu_TakeMail},
+ {OtherText_Mail, (void*) PokemonMenu_Mail},
+ {OtherText_Read2, (void*) PokemonMenu_ReadMail},
+ {gOtherText_CancelNoTerminator, (void*) PokemonMenu_CancelSubmenu},
+ {gMoveNames[MOVE_CUT], (void*) PokemonMenu_FieldMove},
+ {gMoveNames[MOVE_FLASH], (void*) PokemonMenu_FieldMove},
+ {gMoveNames[MOVE_ROCK_SMASH], (void*) PokemonMenu_FieldMove},
+ {gMoveNames[MOVE_STRENGTH], (void*) PokemonMenu_FieldMove},
+ {gMoveNames[MOVE_SURF], (void*) PokemonMenu_FieldMove},
+ {gMoveNames[MOVE_FLY], (void*) PokemonMenu_FieldMove},
+ {gMoveNames[MOVE_DIVE], (void*) PokemonMenu_FieldMove},
+ {gMoveNames[MOVE_WATERFALL], (void*) PokemonMenu_FieldMove},
+ {gMoveNames[MOVE_TELEPORT], (void*) PokemonMenu_FieldMove},
+ {gMoveNames[MOVE_DIG], (void*) PokemonMenu_FieldMove},
+ {gMoveNames[MOVE_SECRET_POWER], (void*) PokemonMenu_FieldMove},
+ {gMoveNames[MOVE_MILK_DRINK], (void*) PokemonMenu_FieldMove},
+ {gMoveNames[MOVE_SOFT_BOILED], (void*) PokemonMenu_FieldMove},
+ {gMoveNames[MOVE_SWEET_SCENT], (void*) PokemonMenu_FieldMove},
+};
+
+static const u16 sPokeMenuFieldMoves[] =
+{
+ MOVE_CUT, MOVE_FLASH, MOVE_ROCK_SMASH, MOVE_STRENGTH,
+ MOVE_SURF, MOVE_FLY, MOVE_DIVE, MOVE_WATERFALL,
+ MOVE_TELEPORT, MOVE_DIG, MOVE_SECRET_POWER, MOVE_MILK_DRINK,
+ MOVE_SOFT_BOILED, MOVE_SWEET_SCENT, sFieldMovesTerminator,
+};
+
+static const u8 sUnknown_39F572[] = {4, 5, 9, 0};
+static const struct PartyPopupMenu sUnknown_0839F578 = {3, 6, sUnknown_39F572};
+
+static const u8 sUnknown_39F580[] = {8, 6, 9, 0};
+static const struct PartyPopupMenu sUnknown_0839F584 = {3, 9, sUnknown_39F580};
+
+static const struct PokeMenuFieldMoveFunc sFieldMoveFuncs[] =
+{
+ {SetUpFieldMove_Cut, 0x6},
+ {SetUpFieldMove_Flash, 0x9},
+ {SetUpFieldMove_RockSmash, 0x9},
+ {SetUpFieldMove_Strength, 0x9},
+ {SetUpFieldMove_Surf, 0x7},
+ {SetUpFieldMove_Fly, 0x9},
+ {SetUpFieldMove_Dive, 0x9},
+ {SetUpFieldMove_Waterfall, 0x9},
+ {SetUpFieldMove_Teleport, 0x9},
+ {SetUpFieldMove_Dig, 0x9},
+ {SetUpFieldMove_SecretPower, 0x9},
+ {SetUpFieldMove_SoftBoiled, 0x10},
+ {SetUpFieldMove_SoftBoiled, 0x10},
+ {SetUpFieldMove_SweetScent, 0x9},
+};
+
+void sub_8089A70(void)
+{
+ gPaletteFade.bufferTransferDisabled = 1;
+ OpenPartyMenu(0, 0);
+}
+
+static void sub_8089A8C(void)
+{
+ sPokeMenuOptionsNo = 0;
+ // if checking pokemon is an egg, we can't give it an item and it doesn't know any move
+ if (GetMonData(&gPlayerParty[gLastFieldPokeMenuOpened], MON_DATA_IS_EGG))
+ {
+ AppendToList(sPokeMenuOptionsOrder, &sPokeMenuOptionsNo, POKEMENU_SUMMARY);
+ AppendToList(sPokeMenuOptionsOrder, &sPokeMenuOptionsNo, POKEMENU_SWITCH);
+ AppendToList(sPokeMenuOptionsOrder, &sPokeMenuOptionsNo, POKEMENU_CANCEL);
+ }
+ else
+ {
+ u16 moveID, tableID;
+ for (moveID = 0; moveID < 4; moveID++) // 4, max number of possible field moves
+ {
+ for (tableID = 0; sPokeMenuFieldMoves[tableID] != sFieldMovesTerminator; tableID++)
+ {
+ if (GetMonData(&gPlayerParty[gLastFieldPokeMenuOpened], MON_DATA_MOVE1 + moveID) == sPokeMenuFieldMoves[tableID])
+ {
+ u8 fieldID = tableID + POKEMENU_FIRST_FIELD_MOVE_ID;
+ AppendToList(sPokeMenuOptionsOrder, &sPokeMenuOptionsNo, fieldID);
+ break;
+ }
+ }
+ }
+ AppendToList(sPokeMenuOptionsOrder, &sPokeMenuOptionsNo, POKEMENU_SUMMARY);
+
+ // can't switch a pokemon if it's the only one in the party
+ if (GetMonData(&gPlayerParty[1], MON_DATA_SPECIES) != 0)
+ AppendToList(sPokeMenuOptionsOrder, &sPokeMenuOptionsNo, POKEMENU_SWITCH);
+
+ if (ItemIsMail(GetMonData(&gPlayerParty[gLastFieldPokeMenuOpened], MON_DATA_HELD_ITEM)))
+ AppendToList(sPokeMenuOptionsOrder, &sPokeMenuOptionsNo, POKEMENU_MAIL);
+ else
+ AppendToList(sPokeMenuOptionsOrder, &sPokeMenuOptionsNo, POKEMENU_ITEM);
+
+ AppendToList(sPokeMenuOptionsOrder, &sPokeMenuOptionsNo, POKEMENU_CANCEL);
+ }
+}
+
+static void sub_8089BDC(u8 arg0, u8 arg1, u8 arg2, u8 noOfOptions, const struct MenuAction* menuActions, const u8* order, u8 arg6)
+{
+ sub_806D538(5, arg6);
+ MenuDrawTextWindow(arg0, arg1, arg0 + arg2, (noOfOptions * 2) + arg1 + 1);
+ PrintMenuItemsReordered(arg0 + 1, arg1 + 1, noOfOptions, menuActions, order);
+}
+
+void sub_8089C50(u8 arg0, u8 arg1, u8 arg2, u8 noOfOptions, const struct MenuAction* menuActions, const u8* order)
+{
+ sub_8089BDC(arg0, arg1, arg2, noOfOptions, menuActions, order, 1);
+}
+
+static void sub_8089C7C(u8 arg0)
+{
+ u32 r4 = (u8)(18 - (sPokeMenuOptionsNo << 1));
+
+ sub_8089BDC(19, r4, 10, sPokeMenuOptionsNo, sPokemonMenuActions, sPokeMenuOptionsOrder, 3);
+ r4 |= 1;
+ InitMenu(0, 20, r4, sPokeMenuOptionsNo, arg0, 9);
+}
+
+void sub_8089CD4(u8 taskID)
+{
+ if (!gPaletteFade.active)
+ {
+ switch (sub_806BD80(taskID))
+ {
+ case 1:
+ PlaySE(SE_SELECT);
+ gLastFieldPokeMenuOpened = sub_806CA38(taskID);
+ GetMonNickname(&gPlayerParty[gLastFieldPokeMenuOpened], gStringVar1);
+ sub_8089A8C();
+ sPokeMenuCursorPos = 0;
+ sub_8089C7C(0);
+ gTasks[taskID].func = sub_8089D94;
+ sub_808B5B4(taskID);
+ break;
+ case 2:
+ PlaySE(SE_SELECT);
+ BeginNormalPaletteFade(-1, 0, 0, 0x10, 0);
+ gTasks[taskID].func = sub_8089E4C;
+ break;
+ }
+ }
+}
+
+static void sub_8089D94(u8 taskID)
+{
+ if (!gPaletteFade.active)
+ {
+ if ((gMain.newAndRepeatedKeys & DPAD_ANY) == DPAD_UP)
+ {
+ PlaySE(SE_SELECT);
+ sPokeMenuCursorPos = MoveMenuCursor(-1);
+ sub_808B5B4(taskID);
+ }
+ else if ((gMain.newAndRepeatedKeys & DPAD_ANY) == DPAD_DOWN)
+ {
+ PlaySE(SE_SELECT);
+ sPokeMenuCursorPos = MoveMenuCursor(1);
+ sub_808B5B4(taskID);
+ }
+ else if (gMain.newKeys & A_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ sPokemonMenuActions[sPokeMenuOptionsOrder[sPokeMenuCursorPos]].func(taskID);
+ sub_808B5B4(taskID);
+ }
+ else if (gMain.newKeys & B_BUTTON)
+ {
+ PokemonMenu_Cancel(taskID);
+ sub_808B5B4(taskID);
+ }
+ }
+}
+
+static void sub_8089E4C(u8 taskID)
+{
+ if (!gPaletteFade.active)
+ {
+ gLastFieldPokeMenuOpened = 0;
+ SetMainCallback2(sub_805469C);
+ DestroyTask(taskID);
+ }
+}
+
+static void sub_8089E84(void)
+{
+ GetMonNickname(&gPlayerParty[gLastFieldPokeMenuOpened], gStringVar1);
+ sub_8089A8C();
+ sPokeMenuCursorPos = 0;
+ sub_8089C7C(0);
+}
+
+static void sub_8089EBC(void)
+{
+ do
+ {
+ if (sub_806B124() == TRUE)
+ {
+ sub_806C994(EWRAM_1B000.unk260, gUnknown_020384F0);
+ sub_806BF74(EWRAM_1B000.unk260, 0);
+ gLastFieldPokeMenuOpened = gUnknown_020384F0;
+ sub_8089E84();
+ SetMainCallback2(sub_806AEDC);
+ break;
+ }
+ } while (sub_80F9344() != TRUE);
+}
+
+static void sub_8089F14(void)
+{
+ gPaletteFade.bufferTransferDisabled = 1;
+ sub_806AF4C(0, 0xFF, sub_8089D94, 5);
+ SetMainCallback2(sub_8089EBC);
+}
+
+static void sub_8089F44(u8 taskID)
+{
+ if (!gPaletteFade.active)
+ {
+ u8 spriteID = gSprites[gTasks[taskID].data[3] >> 8].data0;
+ DestroyTask(taskID);
+ ewram1B000_alt.unk262 = 1;
+ ShowPokemonSummaryScreen(gPlayerParty, spriteID, gPlayerPartyCount - 1, sub_8089F14, 0);
+ }
+}
+
+static void PokemonMenu_Summary(u8 taskID)
+{
+ BeginNormalPaletteFade(-1, 0, 0, 0x10, 0);
+ gTasks[taskID].func = sub_8089F44;
+}
+
+void sub_808A004(u8 taskID)
+{
+ SetTaskFuncWithFollowupFunc(taskID, sub_806CA60, sub_8089CD4);
+ MenuZeroFillWindowRect(19, 0, 29, 19);
+}
+
+static void PokemonMenu_Switch(u8 taskID)
+{
+ HandleDestroyMenuCursors();
+ ewram01000.unkC = sub_806CD5C;
+ ewram01000.array[53553] = 1;
+ sub_808A004(taskID);
+}
+
+static void sub_808A060(u8 taskID)
+{
+ if (gMain.newKeys == DPAD_UP && sPokeMenuCursorPos != 0)
+ {
+ sPokeMenuCursorPos = MoveMenuCursor(-1);
+ PlaySE(SE_SELECT);
+ }
+ if (gMain.newKeys == DPAD_DOWN && sPokeMenuCursorPos != 2)
+ {
+ sPokeMenuCursorPos = MoveMenuCursor(1);
+ PlaySE(SE_SELECT);
+ }
+ if (gMain.newKeys & A_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ PartyMenuGetPopupMenuFunc(0, &sUnknown_0839F578, (void*) sPokemonMenuActions, sPokeMenuCursorPos)(taskID);
+ }
+ else if (gMain.newKeys & B_BUTTON)
+ {
+ sub_806E7D0(0, &sUnknown_0839F578);
+ PokemonMenu_CancelSubmenu(taskID);
+ }
+}
+
+static void sub_808A100(u8 taskID)
+{
+ sub_806E750(0, &sUnknown_0839F578, (void*)(sPokemonMenuActions), 0);
+ sub_806D538(0xD, 2);
+ gTasks[taskID].func = sub_808A060;
+}
+
+static void PokemonMenu_Item(u8 taskID)
+{
+ HandleDestroyMenuCursors();
+ sPokeMenuCursorPos = 0;
+ MenuZeroFillWindowRect(19, 0, 29, 19);
+ gTasks[taskID].func = sub_808A100;
+}
+
+static void sub_808A180(u8 taskID)
+{
+ if (!gPaletteFade.active)
+ {
+ u8 mailID = GetMonData(&gPlayerParty[sub_806CA38(taskID)], MON_DATA_MAIL);
+ DestroyTask(taskID);
+ sub_80E62A0(4, &gSaveBlock1.mail[mailID], sub_808A520, 3);
+ }
+}
+
+static void sub_808A1E0(u8 taskID)
+{
+ if (gUnknown_0202E8F6 != 1)
+ {
+ SetHeldItemIconVisibility(taskID, sub_806CA38(taskID));
+ sub_806D538(0, 0);
+ gTasks[taskID].func = sub_8089CD4;
+ }
+}
+
+static void sub_808A228(u8 taskID)
+{
+ if (ItemIsMail(gScriptItemId) && gUnknown_0202E8F4 != 0)
+ {
+ BeginNormalPaletteFade(-1, 0, 0, 0x10, 0);
+ gTasks[taskID].func = sub_808A180;
+ }
+ else
+ {
+ MenuZeroFillWindowRect(0, 0, 29, 19);
+ sub_806D538(0, 0);
+ gTasks[taskID].func = sub_8089CD4;
+ }
+}
+
+static void sub_808A2AC(u8 taskID)
+{
+ if (!gPaletteFade.active)
+ PartyMenuTryGiveMonHeldItem(taskID, gScriptItemId, sub_808A228);
+}
+
+static void sub_808A2DC(u8 taskID)
+{
+ u8 mailID = GetMonData(&gPlayerParty[sub_806CA38(taskID)], MON_DATA_MAIL);
+ DestroyTask(taskID);
+ sub_80E62A0(4, &gSaveBlock1.mail[mailID], sub_808A520, 3);
+}
+
+static void sub_808A330(u8 taskID)
+{
+ PartyMenuTryGiveMonHeldItem(taskID, gScriptItemId, sub_808A2DC);
+}
+
+static void sub_808A34C(void)
+{
+ RunTasks();
+}
+
+static void sub_808A358(void)
+{
+ while (1)
+ {
+ if (sub_806B124() == TRUE)
+ {
+ sub_806C994(EWRAM_1B000.unk260, gLastFieldPokeMenuOpened);
+ sub_806BF74(EWRAM_1B000.unk260, 0);
+ SetMainCallback2(sub_806AEDC);
+ break;
+ }
+ if (sub_80F9344() == TRUE)
+ break;
+ }
+}
+
+static void sub_808A3A4(void)
+{
+ while (1)
+ {
+ if (sub_806B124() == TRUE)
+ {
+ sub_806C994(EWRAM_1B000.unk260, gLastFieldPokeMenuOpened);
+ sub_806BF74(EWRAM_1B000.unk260, 0);
+ EWRAM_1B000.unk262 = 3;
+ sub_8089E84();
+ SetMainCallback2(sub_806AEDC);
+ break;
+ }
+ if (sub_80F9344() == TRUE)
+ break;
+ }
+}
+
+void sub_808A3F8(void)
+{
+ if (ItemIsMail(gScriptItemId))
+ {
+ u8 taskID = CreateTask(sub_808A330, 0);
+ gPaletteFade.bufferTransferDisabled = 1;
+ sub_806BD58(taskID, 0);
+ sub_806C994(taskID, gLastFieldPokeMenuOpened);
+ sub_806BF74(taskID, 0);
+ if (!(bool8)(GetMonData(&gPlayerParty[sub_806CA38(taskID)], MON_DATA_HELD_ITEM)))
+ {
+ SetMainCallback2(sub_808A34C);
+ return;
+ }
+ else
+ DestroyTask(taskID);
+ }
+ gPaletteFade.bufferTransferDisabled = 1;
+ if (gScriptItemId)
+ {
+ sub_806AF4C(0, 0xFF, sub_808A2AC, 0xFF);
+ SetMainCallback2(sub_808A358);
+ }
+ else
+ {
+ sub_806AF4C(0, 0xFF, sub_8089D94, 5);
+ SetMainCallback2(sub_808A3A4);
+ }
+}
+
+static void sub_808A4D4(void)
+{
+ while (1)
+ {
+ if (sub_806B124() == TRUE)
+ {
+ sub_806C994(EWRAM_1B000.unk260, gLastFieldPokeMenuOpened);
+ sub_806BF74(EWRAM_1B000.unk260, 0);
+ SetMainCallback2(sub_806AEDC);
+ break;
+ }
+ if (sub_80F9344() == TRUE)
+ break;
+ }
+}
+
+void sub_808A520(void)
+{
+ gPaletteFade.bufferTransferDisabled = 1;
+ if (gScriptResult == 0)
+ {
+ if (gUnknown_0202E8F8)
+ RemoveBagItem(gUnknown_0202E8F8, 1);
+ AddBagItem(GetMonData(&gPlayerParty[gLastFieldPokeMenuOpened], MON_DATA_HELD_ITEM), 1);
+ TakeMailFromMon(&gPlayerParty[gLastFieldPokeMenuOpened]);
+ SetMonData(&gPlayerParty[gLastFieldPokeMenuOpened], MON_DATA_HELD_ITEM, (void*) &gUnknown_0202E8F8);
+ sub_806AF4C(0, 0xFF, sub_8089CD4, 0);
+ }
+ else
+ sub_806AF4C(0, 0xFF, sub_808A5BC, 0xFF);
+ SetMainCallback2(sub_808A4D4);
+}
+
+static void sub_808A5BC(u8 taskID)
+{
+ if (!gPaletteFade.active)
+ {
+ DisplayGiveHeldItemMessage(gLastFieldPokeMenuOpened, gScriptItemId, 0);
+ gTasks[taskID].func = sub_808A1E0;
+ }
+}
+
+static void sub_808A604(u8 taskID)
+{
+ if (!gPaletteFade.active)
+ {
+ SetMainCallback2(sub_80A61D0);
+ DestroyTask(taskID);
+ }
+}
+
+static void PokemonMenu_GiveItem(u8 taskID)
+{
+ gUnknown_0202E8F5 = sub_806CA38(taskID);
+ BeginNormalPaletteFade(-1, 0, 0, 0x10, 0);
+ gTasks[taskID].func = sub_808A604;
+}
+
+static void sub_808A678(u8 taskID)
+{
+ sub_808A8D4(taskID);
+}
+
+static void PokemonMenu_TakeItem(u8 taskID)
+{
+ HandleDestroyMenuCursors();
+ MenuZeroFillWindowRect(19, 0, 29, 19);
+ sub_806D5A4();
+ PartyMenuTryGiveMonHeldItem_806ECE8(taskID, sub_808A678);
+}
+
+static void PokemonMenu_TakeMail(u8 taskID)
+{
+ HandleDestroyMenuCursors();
+ MenuZeroFillWindowRect(19, 0, 29, 19);
+ sub_806D5A4();
+ DoTakeMail(taskID, sub_808A678);
+}
+
+static void PokemonMenu_Mail(u8 taskID)
+{
+ HandleDestroyMenuCursors();
+ sPokeMenuCursorPos = 0;
+ MenuZeroFillWindowRect(19, 0, 29, 19);
+ sub_806E750(0, &sUnknown_0839F584, (void*) sPokemonMenuActions, 0);
+ gTasks[taskID].func = sub_808A73C;
+}
+
+static void sub_808A73C(u8 taskID)
+{
+ if (gMain.newAndRepeatedKeys == DPAD_UP)
+ {
+ PlaySE(SE_SELECT);
+ if (sPokeMenuCursorPos == 0)
+ sPokeMenuCursorPos = MoveMenuCursor(sUnknown_0839F584.unk0 - 1);
+ else
+ sPokeMenuCursorPos = MoveMenuCursor(-1);
+ }
+ if (gMain.newAndRepeatedKeys == DPAD_DOWN)
+ {
+ PlaySE(SE_SELECT);
+ if (sPokeMenuCursorPos == sUnknown_0839F584.unk0 - 1)
+ sPokeMenuCursorPos = MoveMenuCursor(1 - sUnknown_0839F584.unk0);
+ else
+ sPokeMenuCursorPos = MoveMenuCursor(1);
+ }
+ if (gMain.newKeys & A_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ PartyMenuGetPopupMenuFunc(0, &sUnknown_0839F584, (void*) sPokemonMenuActions, sPokeMenuCursorPos)(taskID);
+ }
+ else if (gMain.newKeys & B_BUTTON)
+ {
+ sub_806E7D0(0, &sUnknown_0839F584);
+ PokemonMenu_Cancel(taskID);
+ }
+}
+
+static void PokemonMenu_ReadMail(u8 taskID)
+{
+ BeginNormalPaletteFade(-1, 0, 0, 0x10, 0);
+ gTasks[taskID].func = sub_808A848;
+}
+
+static void sub_808A848(u8 taskID)
+{
+ if (!gPaletteFade.active)
+ {
+ u8 mailID = GetMonData(&gPlayerParty[sub_806CA38(taskID)], MON_DATA_MAIL);
+ DestroyTask(taskID);
+ HandleReadMail(&gSaveBlock1.mail[mailID], sub_808A8A8, 1);
+ }
+}
+
+static void sub_808A8A8(void)
+{
+ gUnknown_020384F0 = gLastFieldPokeMenuOpened;
+ ewram1B000.unk262 = 4;
+ sub_8089F14();
+}
+
+static void sub_808A8D4(u8 taskID)
+{
+ sPokeMenuCursorPos = 0;
+ MenuZeroFillWindowRect(19, 0, 29, 19);
+ sub_806D538(0, 0);
+ gTasks[taskID].func = sub_8089CD4;
+}
+
+static void PokemonMenu_Cancel(u8 taskID)
+{
+ HandleDestroyMenuCursors();
+ PlaySE(SE_SELECT);
+ sub_808A8D4(taskID);
+}
+
+static void PokemonMenu_CancelSubmenu(u8 taskID)
+{
+ HandleDestroyMenuCursors();
+ PlaySE(SE_SELECT);
+ MenuZeroFillWindowRect(19, 0, 29, 19);
+ sub_806D5A4();
+ sub_8089C7C(sPokeMenuCursorPos);
+ gTasks[taskID].func = sub_8089D94;
+}
+
+#define IS_SOFTBOILED_MILKDRINK(ID)((ID == (POKEMENU_MILK_DRINK - POKEMENU_FIRST_FIELD_MOVE_ID) || ID == (POKEMENU_SOFT_BOILED - POKEMENU_FIRST_FIELD_MOVE_ID)))
+#define IS_SURF(ID)((ID == (POKEMENU_SURF - POKEMENU_FIRST_FIELD_MOVE_ID)))
+#define IS_FLY(ID)((ID == (POKEMENU_FLY - POKEMENU_FIRST_FIELD_MOVE_ID)))
+
+#define TASK_FIELD_MOVE_ID 11
+
+static void PokemonMenu_FieldMove(u8 taskID)
+{
+ s16* taskData = gTasks[taskID].data;
+ HandleDestroyMenuCursors();
+ taskData[TASK_FIELD_MOVE_ID] = sPokeMenuOptionsOrder[sPokeMenuCursorPos] - POKEMENU_FIRST_FIELD_MOVE_ID;
+ if (sub_80F9344() == TRUE)
+ {
+ MenuZeroFillWindowRect(19, 0, 29, 19);
+ if (IS_SOFTBOILED_MILKDRINK(taskData[TASK_FIELD_MOVE_ID]))
+ sub_806D538(9, 0);
+ else
+ sub_806D538(sFieldMoveFuncs[taskData[TASK_FIELD_MOVE_ID]].field_1, 0);
+ gTasks[taskID].func = sub_808ABF4;
+ }
+ else if (taskData[TASK_FIELD_MOVE_ID] <= 7 && FlagGet(BADGE01_GET + taskData[TASK_FIELD_MOVE_ID]) != TRUE)
+ {
+ // can't use a field HM move without a proper badge
+ MenuZeroFillWindowRect(19, 0, 29, 19);
+ sub_806D5A4();
+ sub_806E834(gOtherText_CantBeUsedBadge, 1);
+ gTasks[taskID].func = sub_808AAF0;
+ }
+ else
+ {
+ if (sFieldMoveFuncs[taskData[TASK_FIELD_MOVE_ID]].func() == TRUE)
+ {
+ sPokeMenuCursorPos = 0;
+ if (!IS_SOFTBOILED_MILKDRINK(taskData[TASK_FIELD_MOVE_ID]))
+ {
+ gTasks[taskID].func = sub_808AB34;
+ BeginNormalPaletteFade(-1, 0, 0, 0x10, 0);
+ }
+ else
+ sub_8133D28(taskID);
+ }
+ else
+ {
+ MenuZeroFillWindowRect(19, 0, 29, 19);
+ if (IS_SURF(taskData[TASK_FIELD_MOVE_ID]) && TestPlayerAvatarFlags(8))
+ sub_806D538(8, 0);
+ else
+ sub_806D538(sFieldMoveFuncs[taskData[TASK_FIELD_MOVE_ID]].field_1, 0);
+ gTasks[taskID].func = sub_808ABF4;
+ }
+ }
+}
+
+static void sub_808AAF0(u8 taskID)
+{
+ if (gUnknown_0202E8F6 != 1 && (gMain.newKeys & A_BUTTON || gMain.newKeys & B_BUTTON))
+ {
+ MenuZeroFillWindowRect(0, 14, 29, 19);
+ PokemonMenu_Cancel(taskID);
+ }
+}
+
+static void sub_808AB34(u8 taskID)
+{
+ if (!gPaletteFade.active)
+ {
+ if (!IS_FLY(gTasks[taskID].data[TASK_FIELD_MOVE_ID]) || ShouldDoBrailleFlyEffect())
+ SetMainCallback2(c2_exit_to_overworld_2_switch);
+ else
+ SetMainCallback2(CB2_InitFlyRegionMap);
+ DestroyTask(taskID);
+ }
+}
+
+void sub_808AB90(void)
+{
+ pal_fill_black();
+ CreateTask(sub_808ABA8, 8);
+}
+
+static void sub_808ABA8(u8 taskID)
+{
+ if (sub_807D770() == TRUE)
+ {
+ gUnknown_0202FF84[0] = GetMonData(&gPlayerParty[gLastFieldPokeMenuOpened], MON_DATA_SPECIES);
+ gUnknown_03005CE4();
+ DestroyTask(taskID);
+ }
+}
+
+static void sub_808ABF4(u8 taskID)
+{
+ if (gMain.newKeys & A_BUTTON || gMain.newKeys & B_BUTTON)
+ {
+ MenuZeroFillWindowRect(1, 17, 28, 18);
+ PokemonMenu_Cancel(taskID);
+ }
+}
+
+static void sub_808AC2C(void)
+{
+ gUnknown_0202FF84[0] = gLastFieldPokeMenuOpened;
+ FieldEffectStart(FLDEFF_USE_SURF);
+}
+
+static bool8 SetUpFieldMove_Surf(void)
+{
+ if (PartyHasMonWithSurf() == TRUE && IsPlayerFacingSurfableFishableWater() == TRUE)
+ {
+ gFieldCallback = sub_808AB90;
+ gUnknown_03005CE4 = sub_808AC2C;
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+static void sub_808AC8C(void)
+{
+ gUnknown_0202FF84[0] = gLastFieldPokeMenuOpened;
+ FieldEffectStart(FLDEFF_USE_FLY);
+}
+
+static bool8 SetUpFieldMove_Fly(void)
+{
+ if (ShouldDoBrailleFlyEffect())
+ {
+ gFieldCallback = sub_808AB90;
+ gUnknown_03005CE4 = DoBrailleFlyEffect;
+ return TRUE;
+ }
+ if (is_light_level_1_2_3_or_6(gMapHeader.mapType) == 1)
+ {
+ gFieldCallback = sub_808AB90;
+ gUnknown_03005CE4 = sub_808AC8C;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void sub_808AD0C(void)
+{
+ while (1)
+ {
+ if (sub_806B124() == TRUE)
+ {
+ sub_806C994(EWRAM_1B000.unk260, gLastFieldPokeMenuOpened);
+ sub_806BF74(EWRAM_1B000.unk260, 0);
+ SetMainCallback2(sub_806AEDC);
+ break;
+ }
+ if (sub_80F9344() == TRUE)
+ break;
+ }
+}
+
+void sub_808AD58(void)
+{
+ gPaletteFade.bufferTransferDisabled = 1;
+ sub_806AF4C(0, 0xFF, sub_8089CD4, 0);
+ SetMainCallback2(sub_808AD0C);
+}
+
+u16 unref_sub_808AD88(void)
+{
+ return GetMonData(&gPlayerParty[gLastFieldPokeMenuOpened], MON_DATA_SPECIES);
+}
+
+static void sub_808ADAC(void)
+{
+ gUnknown_0202FF84[0] = gLastFieldPokeMenuOpened;
+ FieldEffectStart(FLDEFF_USE_DIVE);
+}
+
+static bool8 SetUpFieldMove_Dive(void)
+{
+ gUnknown_0202FF84[1] = sub_8068F18();
+ if (gUnknown_0202FF84[1])
+ {
+ gFieldCallback = sub_808AB90;
+ gUnknown_03005CE4 = sub_808ADAC;
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+static void sub_808AE08(void)
+{
+ gUnknown_0202FF84[0] = gLastFieldPokeMenuOpened;
+ FieldEffectStart(FLDEFF_USE_WATERFALL);
+}
+
+static bool8 SetUpFieldMove_Waterfall(void)
+{
+ s16 x, y;
+ GetXYCoordsOneStepInFrontOfPlayer(&x, &y);
+ if (MetatileBehavior_IsWaterfall(MapGridGetMetatileBehaviorAt(x, y)) == TRUE
+ && IsPlayerSurfingNorth() == TRUE)
+ {
+ gFieldCallback = sub_808AB90;
+ gUnknown_03005CE4 = sub_808AE08;
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+static void sub_808AE8C(void)
+{
+ u8 i;
+ u8 arg = gScriptItemId - 33;
+ for (i = 0; i < 6; i++)
+ {
+ if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES))
+ {
+ sub_806D668(i);
+ if (GetMonData(&gPlayerParty[i], MON_DATA_IS_EGG) || !CanMonLearnTMHM(&gPlayerParty[i], arg))
+ sub_806BC3C(i, 0x9A);
+ else if (pokemon_has_move(&gPlayerParty[i], ItemIdToBattleMoveId(gScriptItemId)))
+ sub_806BC3C(i, 0xA8);
+ else
+ sub_806BC3C(i, 0x8C);
+ }
+ }
+}
+
+static void sub_808AF20(void)
+{
+ u8 i;
+ for (i = 0; i < 6; i++)
+ {
+ if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES))
+ {
+ if (GetMonData(&gPlayerParty[i], MON_DATA_IS_EGG) || !GetEvolutionTargetSpecies(&gPlayerParty[i], 3, gScriptItemId))
+ {
+ sub_806D668(i);
+ sub_806BC3C(i, 0);
+ }
+ }
+ }
+}
+
+static void sub_808AF80(void)
+{
+ while (1)
+ {
+ if (sub_806B124() == TRUE)
+ {
+ if (gUnknown_02038561 == 0)
+ {
+ switch (CheckIfItemIsTMHMOrEvolutionStone(gScriptItemId))
+ {
+ case 1:
+ sub_808AE8C();
+ break;
+ case 2:
+ sub_808AF20();
+ break;
+ }
+ }
+ if (gLastFieldPokeMenuOpened > 5 || !GetMonData(&gPlayerParty[gLastFieldPokeMenuOpened], MON_DATA_SPECIES))
+ gLastFieldPokeMenuOpened = 0;
+ sub_806C994(ewram1B000.unk260, gLastFieldPokeMenuOpened);
+ sub_806BF74(ewram1B000.unk260, 0);
+ SetMainCallback2(sub_806AEDC);
+ break;
+ }
+ if (sub_80F9344() == TRUE)
+ break;
+ }
+}
+
+void sub_808B020(void)
+{
+ gPaletteFade.bufferTransferDisabled = 1;
+ switch (gUnknown_02038561)
+ {
+ case 0:
+ if (CheckIfItemIsTMHMOrEvolutionStone(gScriptItemId) == 1)
+ sub_806AF4C(0, 0, sub_808B0C0, 20);
+ else
+ sub_806AF4C(0, 0, sub_808B0C0, 3);
+ break;
+ case 4:
+ sub_806AF4C(0, 0, sub_808B1EC, 0xFF);
+ break;
+ case 1:
+ case 3:
+ sub_806AF4C(0, 0, sub_808B0C0, 4);
+ break;
+ }
+ SetMainCallback2(sub_808AF80);
+}
+
+void sub_808B0C0(u8 taskID)
+{
+ if (!gPaletteFade.active)
+ {
+ switch (sub_806BD80(taskID))
+ {
+ case 1:
+ gLastFieldPokeMenuOpened = sub_806CA38(taskID);
+ if (GetMonData(&gPlayerParty[gLastFieldPokeMenuOpened], MON_DATA_IS_EGG))
+ PlaySE(SE_HAZURE);
+ else
+ {
+ sub_806D5A4();
+ if (gUnknown_02038561 == 0)
+ gUnknown_03004AE4(taskID, gScriptItemId, sub_808B224);
+ if (gUnknown_02038561 == 1)
+ {
+ PlaySE(SE_SELECT);
+ PartyMenuTryGiveMonHeldItem(taskID, gScriptItemId, sub_808B2EC);
+ }
+ if (gUnknown_02038561 == 3)
+ {
+ PlaySE(SE_SELECT);
+ PartyMenuTryGiveMonMail(taskID, sub_808B2B4);
+ }
+ }
+ break;
+ case 2:
+ gLastFieldPokeMenuOpened = sub_806CA38(taskID);
+ PlaySE(SE_SELECT);
+ BeginNormalPaletteFade(-1, 0, 0, 0x10, 0);
+ if (gUnknown_02038561 == 0 || gUnknown_02038561 == 1)
+ gTasks[taskID].func = sub_808B25C;
+ if (gUnknown_02038561 == 3)
+ gTasks[taskID].func = sub_808B2B4;
+ break;
+ }
+ }
+}
+
+static void sub_808B1EC(u8 taskID)
+{
+ if (!gPaletteFade.active)
+ gUnknown_03004AE4(taskID, gScriptItemId, sub_808B224);
+}
+
+static void sub_808B224(u8 taskID)
+{
+ BeginNormalPaletteFade(-1, 0, 0, 0x10, 0);
+ gTasks[taskID].func = sub_808B25C;
+}
+
+static void sub_808B25C(u8 taskID)
+{
+ if (!gPaletteFade.active)
+ {
+ SetMainCallback2(sub_80A5B40);
+ DestroyTask(taskID);
+ }
+}
+
+static void sub_808B288(u8 taskID)
+{
+ if (!gPaletteFade.active)
+ {
+ SetMainCallback2(Mailbox_ReturnToMailListAfterDeposit);
+ DestroyTask(taskID);
+ }
+}
+
+static void sub_808B2B4(u8 taskID)
+{
+ BeginNormalPaletteFade(-1, 0, 0, 0x10, 0);
+ gTasks[taskID].func = sub_808B288;
+}
+
+static void sub_808B2EC(u8 taskID)
+{
+ if (gUnknown_0202E8F4 == 2)
+ {
+ BeginNormalPaletteFade(-1, 0, 0, 0x10, 0);
+ gTasks[taskID].func = sub_808B338;
+ }
+ else
+ sub_808B224(taskID);
+}
+
+static void sub_808B338(u8 taskID)
+{
+ if (!gPaletteFade.active)
+ {
+ u8 mailID;
+
+ gLastFieldPokeMenuOpened = sub_806CA38(taskID);
+ mailID = GetMonData(&gPlayerParty[gLastFieldPokeMenuOpened], MON_DATA_MAIL);
+ DestroyTask(taskID);
+ sub_80E62A0(4, &gSaveBlock1.mail[mailID], sub_808B3EC, 3);
+ }
+}
+
+static void sub_808B3A0(void)
+{
+ while (1)
+ {
+ if (sub_806B124() == TRUE)
+ {
+ sub_806C994(EWRAM_1B000.unk260, gLastFieldPokeMenuOpened);
+ sub_806BF74(EWRAM_1B000.unk260, 0);
+ SetMainCallback2(sub_806AEDC);
+ break;
+ }
+ if (sub_80F9344() == TRUE)
+ break;
+ }
+}
+
+static void sub_808B3EC(void)
+{
+ IntrCallback callback;
+
+ gPaletteFade.bufferTransferDisabled = 1;
+ if (gScriptResult == 0)
+ {
+ if (gUnknown_0202E8F8)
+ RemoveBagItem(gUnknown_0202E8F8, 1);
+ AddBagItem(GetMonData(&gPlayerParty[gLastFieldPokeMenuOpened], MON_DATA_HELD_ITEM), 1);
+ TakeMailFromMon(&gPlayerParty[gLastFieldPokeMenuOpened]);
+ SetMonData(&gPlayerParty[gLastFieldPokeMenuOpened], MON_DATA_HELD_ITEM, (void*) &gUnknown_0202E8F8);
+ CreateTask(sub_808B25C, 5);
+ gPaletteFade.bufferTransferDisabled = 0;
+ callback = sub_806AEDC;
+ }
+ else
+ {
+ sub_806AF4C(0, 0, sub_808B4A4, 0xFF);
+ callback = sub_808B3A0;
+ }
+ SetMainCallback2(callback);
+}
+
+static void sub_808B4A4(u8 taskID)
+{
+ if (!gPaletteFade.active)
+ {
+ DisplayGiveHeldItemMessage(gLastFieldPokeMenuOpened, gScriptItemId, 1);
+ gTasks[taskID].func = sub_808B4EC;
+ }
+}
+
+static void sub_808B4EC(u8 taskID)
+{
+ if (gUnknown_0202E8F6 != 1)
+ sub_808B224(taskID);
+}
+
+void sub_808B508(u8 taskID)
+{
+ sub_808B224(taskID);
+}
+
+static void sub_808B518(void)
+{
+ while (1)
+ {
+ if (sub_806B124() == TRUE)
+ {
+ sub_806C994(EWRAM_1B000.unk260, gUnknown_020384F0);
+ sub_806BF74(EWRAM_1B000.unk260, 0);
+ SetMainCallback2(sub_806AEDC);
+ break;
+ }
+ if (sub_80F9344() == TRUE)
+ break;
+ }
+}
+
+void sub_808B564(void)
+{
+ gPaletteFade.bufferTransferDisabled = 1;
+ if (sub_809FA30() != 4)
+ sub_806AF4C(0, 0, TaughtMove, 0xFF);
+ else
+ sub_806AF4C(0, 0, StopTryingToTeachMove_806F588, 0xFF);
+ SetMainCallback2(sub_808B518);
+}
+
+void sub_808B5B4(u32 taskID)
+{
+ gUnknown_03005CF0 = gTasks[taskID].func;
+ gTasks[taskID].func = sub_808B5E4;
+ sub_808B5E4(taskID);
+}
+
+static void sub_808B5E4(u8 taskID)
+{
+ if (sub_8055870() != TRUE)
+ gTasks[taskID].func = gUnknown_03005CF0;
+}
diff --git a/src/scene/evolution_graphics.c b/src/scene/evolution_graphics.c
index a47e63a59..1fd5bf8fa 100644
--- a/src/scene/evolution_graphics.c
+++ b/src/scene/evolution_graphics.c
@@ -1,4 +1,5 @@
#include "global.h"
+#include "evolution_graphics.h"
#include "sprite.h"
#include "trig.h"
#include "rng.h"
@@ -376,10 +377,10 @@ static void EvoTask_DestroyPostSet1Task(u8 taskID)
DestroyTask(taskID);
}
-u8 LaunchTask_PostEvoSparklesSet2AndFlash(u16 arg0)
+u8 LaunchTask_PostEvoSparklesSet2AndFlash(u16 species)
{
u8 taskID = CreateTask(EvoTask_BeginPostSparklesSet2_AndFlash, 0);
- gTasks[taskID].data[2] = arg0;
+ gTasks[taskID].data[2] = species;
return taskID;
}
@@ -424,10 +425,10 @@ static void EvoTask_DestroyPostSet2AndFlashTask(u8 taskID)
DestroyTask(taskID);
}
-u8 LaunchTask_PostEvoSparklesSet2AndFlash_Trade(u16 arg0)
+u8 LaunchTask_PostEvoSparklesSet2AndFlash_Trade(u16 species)
{
u8 taskID = CreateTask(EvoTask_BeginPostSparklesSet2_AndFlash_Trade, 0);
- gTasks[taskID].data[2] = arg0;
+ gTasks[taskID].data[2] = species;
return taskID;
}
diff --git a/src/scene/evolution_scene.c b/src/scene/evolution_scene.c
new file mode 100644
index 000000000..eeeb04f56
--- /dev/null
+++ b/src/scene/evolution_scene.c
@@ -0,0 +1,3966 @@
+#include "global.h"
+#include "task.h"
+#include "evolution_scene.h"
+#include "evolution_graphics.h"
+#include "palette.h"
+#include "main.h"
+#include "text.h"
+#include "text_window.h"
+#include "pokemon.h"
+#include "string_util.h"
+#include "battle.h"
+#include "unknown_task.h"
+#include "data2.h"
+#include "decompress.h"
+#include "m4a.h"
+#include "trade.h"
+#include "menu.h"
+#include "pokedex.h"
+#include "species.h"
+#include "sound.h"
+#include "songs.h"
+#include "rom4.h"
+#include "battle_message.h"
+#include "pokemon_summary_screen.h"
+#include "menu_cursor.h"
+#include "strings2.h"
+
+struct EvoInfo
+{
+ u8 preEvoSpriteID;
+ u8 postEvoSpriteID;
+ u8 evoTaskID;
+ u8 field_3;
+
+ u8 unk4[0x40];
+ u8 unk44[0x40];
+ u8 unk84[0x40];
+
+ u8 unkC4[0x40][0x20]; // 0x20148C4
+ u8 unk8C4[0x40][0x20]; // 0x20150C4
+ u8 unk10C4[0x40][0x20]; // 0x20158C4
+ u8 unk18C4[0x40][0x20]; // 0x20160C4
+ u8 unk20C4[0x40][0x20]; // 0x20168C4
+ u8 unk28C4[0x40][0x20]; // 0x20170C4
+ u8 unk30C4[0x40][0x20]; // 0x20178C4
+ u8 unk38C4[0x40][0x20]; // 0x20180C4
+
+ u8 *unk40C4[0x40][0x20]; // 0x20188C4
+
+ u16 unk60C4[0x40][0x20]; // 0x201A8C4
+ u16 unk70C4[0x40][0x20]; // 0x201B8C4
+ u16 unk80C4[0x40][0x20]; // 0x201C8C4
+ u16 unk90C4[0x40][0x20]; // 0x201D8C4
+
+ u8 unkA0C4; // 0x201E8C4
+};
+
+#define sEvoInfo ((*(struct EvoInfo*)(ewram + 0x14800)))
+
+void EvolutionRenameMon(struct Pokemon *mon, u16 oldSpecies, u16 newSpecies);
+void sub_8024CEC(void);
+void sub_8023A80(void);
+void sub_802BC6C(void);
+void sub_8023AD8(void);
+void nullsub_6(void);
+bool32 IsHMMove2(u16 move);
+
+extern struct Window gUnknown_03004210;
+extern u16 gUnknown_030042A4;
+extern u16 gUnknown_030042A0;
+extern u16 gUnknown_030042C0;
+extern u16 gUnknown_030041B4;
+extern u16 gUnknown_03004288;
+extern u16 gUnknown_03004280;
+extern u16 gUnknown_030041B0;
+extern u16 gUnknown_030041B8;
+extern u8 gBattleTerrain;
+extern u8 gReservedSpritePaletteCount;
+extern u16 gMoveToLearn;
+extern struct SpriteTemplate gUnknown_02024E8C;
+extern u8 gUnk_2009000[]; // won't match if I 'ewram' it
+extern bool8 gAffineAnimsDisabled;
+extern u8 gDisplayedStringBattle[];
+extern u8 gBattleTextBuff2[];
+
+extern u8 gBattleCommunication[];
+#define sEvoCursorPos gBattleCommunication[1] // when learning a new move
+#define sEvoGraphicsTaskID gBattleCommunication[2]
+
+extern const u8 gUnknown_08400C4A[];
+extern const u8 gUnknown_08400C60[];
+extern const u8 gUnknown_08400C8D[];
+extern void * const gUnknown_081FAF4C[];
+extern const u8* const gBattleStringsTable[];
+
+// this file's functions
+static void Task_EvolutionScene(u8 taskID);
+static void Task_TradeEvolutionScene(u8 taskID);
+static void CB2_EvolutionSceneUpdate(void);
+static void CB2_TradeEvolutionSceneUpdate(void);
+static void EvoDummyFunc(void);
+static void EvoDummyFunc2(void);
+static void VBlankCB_EvolutionScene(void);
+static void VBlankCB_TradeEvolutionScene(void);
+static void sub_81150D8(void);
+
+// iwram common
+MainCallback gCB2_AfterEvolution;
+
+// const data
+static const u8 sUnknownShedinjaJpnString[] = _("ヌケニン");
+static const u8 sUnusedString0[] = _("{COLOR DARK_GREY}{HIGHLIGHT WHITE2}{SHADOW LIGHT_GREY}");
+static const u8 sUnusedString1[] = _("▶\n ");
+static const u8 sUnusedString2[] = _(" \n▶");
+static const u8 sUnusedString3[] = _(" \n ");
+static const u8 sPadding[9] = {0};
+
+// code
+
+static void CB2_BeginEvolutionScene(void)
+{
+ UpdatePaletteFade();
+ RunTasks();
+}
+
+#define tState data[0]
+#define tMonPtrHI data[1]
+#define tMonPtrLO data[2]
+#define tPreEvoSpecies data[3]
+#define tPostEvoSpecies data[4]
+#define tCanStop data[5] // in first fast data[5] only checks that
+#define tBits data[5] // in the second task, it works as a bitfield
+#define tLearnsFirstMove data[6]
+#define tLearnMoveState data[8]
+#define tData9 data[9]
+#define tData10 data[10]
+#define tEvoWasStopped data[11]
+#define tPartyID data[12]
+
+#define TASK_BIT_CAN_STOP 0x1
+#define TASK_BIT_LEARN_MOVE 0x80
+
+static void Task_BeginEvolutionScene(u8 taskID)
+{
+ struct Pokemon* mon = NULL;
+ switch (gTasks[taskID].tState)
+ {
+ case 0:
+ BeginNormalPaletteFade(-1, 0, 0, 0x10, 0);
+ gTasks[taskID].tState++;
+ break;
+ case 1:
+ if (!gPaletteFade.active)
+ {
+ u16 speciesToEvolve;
+ bool8 canStopEvo;
+ u8 partyID;
+
+ mon = (struct Pokemon*)(gTasks[taskID].tMonPtrHI | (gTasks[taskID].tMonPtrLO << 0x10));
+ speciesToEvolve = gTasks[taskID].tPostEvoSpecies;
+ canStopEvo = gTasks[taskID].tCanStop;
+ partyID = gTasks[taskID].tPartyID;
+
+ DestroyTask(taskID);
+ EvolutionScene(mon, speciesToEvolve, canStopEvo, partyID);
+ }
+ break;
+ }
+}
+
+void BeginEvolutionScene(struct Pokemon* mon, u16 speciesToEvolve, bool8 canStopEvo, u8 partyID)
+{
+ u8 taskID = CreateTask(Task_BeginEvolutionScene, 0);
+ gTasks[taskID].tState = 0;
+ gTasks[taskID].tMonPtrHI = (u32)(mon);
+ gTasks[taskID].tMonPtrLO = (u32)(mon) >> 0x10;
+ gTasks[taskID].tPostEvoSpecies = speciesToEvolve;
+ gTasks[taskID].tCanStop = canStopEvo;
+ gTasks[taskID].tPartyID = partyID;
+ SetMainCallback2(CB2_BeginEvolutionScene);
+}
+
+void EvolutionScene(struct Pokemon* mon, u16 speciesToEvolve, bool8 canStopEvo, u8 partyID)
+{
+ u8 name[20];
+ u16 currSpecies;
+ u32 TiD, PiD;
+ const struct CompressedSpritePalette** pokePal;
+ u8 ID;
+ SetHBlankCallback(NULL);
+ SetVBlankCallback(NULL);
+ CpuFill32(0, (void*)(VRAM), VRAM_SIZE);
+
+ REG_MOSAIC = 0;
+ REG_WIN0H = 0;
+ REG_WIN0V = 0;
+ REG_WIN1H = 0;
+ REG_WIN1V = 0;
+ REG_WININ = 0;
+ REG_WINOUT = 0;
+
+ SetUpWindowConfig(&gWindowConfig_81E6C58);
+ ResetPaletteFade();
+
+ gUnknown_030042A4 = 0;
+ gUnknown_030042A0 = 0;
+ gUnknown_030042C0 = 0;
+ gUnknown_030041B4 = 0;
+ gUnknown_03004288 = 0;
+ gUnknown_03004280 = 0;
+ gUnknown_030041B0 = 256;
+ gUnknown_030041B8 = 0;
+
+ InitWindowFromConfig(&gUnknown_03004210, &gWindowConfig_81E6C58);
+ gBattleTerrain = 9;
+
+ sub_800D6D4();
+ sub_800DAB8();
+ ResetSpriteData();
+ remove_some_task();
+ ResetTasks();
+ FreeAllSpritePalettes();
+
+ gReservedSpritePaletteCount = 4;
+
+ GetMonData(mon, MON_DATA_NICKNAME, name);
+ StringCopy10(gStringVar1, name);
+ StringCopy(gStringVar2, gSpeciesNames[speciesToEvolve]);
+
+ // preEvo sprite
+ currSpecies = GetMonData(mon, MON_DATA_SPECIES);
+ TiD = GetMonData(mon, MON_DATA_OT_ID);
+ PiD = GetMonData(mon, MON_DATA_PERSONALITY);
+ DecompressPicFromTable_2(&gMonFrontPicTable[currSpecies],
+ gMonFrontPicCoords[currSpecies].coords,
+ gMonFrontPicCoords[currSpecies].y_offset,
+ (void*)(0x2000000),
+ gUnknown_081FAF4C[1], currSpecies);
+ pokePal = (void*) sub_80409C8(currSpecies, TiD, PiD);
+ LoadCompressedPalette(*pokePal, 0x110, 0x20);
+
+ GetMonSpriteTemplate_803C56C(currSpecies, 1);
+ gUnknown_02024E8C.affineAnims = gDummySpriteAffineAnimTable;
+ sEvoInfo.preEvoSpriteID = ID = CreateSprite(&gUnknown_02024E8C, 120, 64, 30);
+
+ gSprites[ID].callback = nullsub_37;
+ gSprites[ID].oam.paletteNum = 1;
+ gSprites[ID].invisible = 1;
+
+ // postEvo sprite
+ DecompressPicFromTable_2(&gMonFrontPicTable[speciesToEvolve],
+ gMonFrontPicCoords[speciesToEvolve].coords,
+ gMonFrontPicCoords[speciesToEvolve].y_offset,
+ (void*)(0x2000000),
+ gUnknown_081FAF4C[3], speciesToEvolve);
+ pokePal = (void*) sub_80409C8(speciesToEvolve, TiD, PiD);
+ LoadCompressedPalette(*pokePal, 0x120, 0x20);
+
+ GetMonSpriteTemplate_803C56C(speciesToEvolve, 3);
+ gUnknown_02024E8C.affineAnims = gDummySpriteAffineAnimTable;
+ sEvoInfo.postEvoSpriteID = ID = CreateSprite(&gUnknown_02024E8C, 120, 64, 30);
+ gSprites[ID].callback = nullsub_37;
+ gSprites[ID].oam.paletteNum = 2;
+ gSprites[ID].invisible = 1;
+
+ LoadEvoSparkleSpriteAndPal();
+
+ sEvoInfo.evoTaskID = ID = CreateTask(Task_EvolutionScene, 0);
+ gTasks[ID].tState = 0;
+ gTasks[ID].tPreEvoSpecies = currSpecies;
+ gTasks[ID].tPostEvoSpecies = speciesToEvolve;
+ gTasks[ID].tMonPtrHI = (u32)(mon);
+ gTasks[ID].tMonPtrLO = (u32)(mon) >> 0x10;
+ gTasks[ID].tCanStop = canStopEvo;
+ gTasks[ID].tLearnsFirstMove = TRUE;
+ gTasks[ID].tEvoWasStopped = FALSE;
+ gTasks[ID].tPartyID = partyID;
+
+ memcpy(gUnk_2009000, &gPlttBufferUnfaded[0x20], 0x60);
+
+ REG_DISPCNT = DISPCNT_OBJ_ON | DISPCNT_BG_ALL_ON | DISPCNT_OBJ_1D_MAP;
+ SetHBlankCallback(EvoDummyFunc);
+ SetVBlankCallback(VBlankCB_EvolutionScene);
+ m4aMPlayAllStop();
+ SetMainCallback2(CB2_EvolutionSceneUpdate);
+}
+
+static void CB2_EvolutionSceneLoadGraphics(void)
+{
+ u8 ID;
+ const struct CompressedSpritePalette** pokePal;
+ u16 postEvoSpecies;
+ u32 TiD, PiD;
+ struct Pokemon* Mon = &gPlayerParty[gTasks[sEvoInfo.evoTaskID].tPartyID];
+
+ postEvoSpecies = gTasks[sEvoInfo.evoTaskID].tPostEvoSpecies;
+ TiD = GetMonData(Mon, MON_DATA_OT_ID);
+ PiD = GetMonData(Mon, MON_DATA_PERSONALITY);
+
+ SetHBlankCallback(NULL);
+ SetVBlankCallback(NULL);
+ CpuFill32(0, (void*)(VRAM), VRAM_SIZE);
+
+ REG_MOSAIC = 0;
+ REG_WIN0H = 0;
+ REG_WIN0V = 0;
+ REG_WIN1H = 0;
+ REG_WIN1V = 0;
+ REG_WININ = 0;
+ REG_WINOUT = 0;
+ SetUpWindowConfig(&gWindowConfig_81E6C58);
+ ResetPaletteFade();
+ gUnknown_030042A4 = 0;
+ gUnknown_030042A0 = 0;
+ gUnknown_030042C0 = 0;
+ gUnknown_030041B4 = 0;
+ gUnknown_03004288 = 0;
+ gUnknown_03004280 = 0;
+ gUnknown_030041B0 = 256;
+ gUnknown_030041B8 = 0;
+
+ InitWindowFromConfig(&gUnknown_03004210, &gWindowConfig_81E6C58);
+ gBattleTerrain = 9;
+
+ sub_800D6D4();
+ sub_800DAB8();
+ ResetSpriteData();
+ FreeAllSpritePalettes();
+ gReservedSpritePaletteCount = 4;
+
+ DecompressPicFromTable_2(&gMonFrontPicTable[postEvoSpecies],
+ gMonFrontPicCoords[postEvoSpecies].coords,
+ gMonFrontPicCoords[postEvoSpecies].y_offset,
+ (void*)(0x2000000),
+ gUnknown_081FAF4C[3], postEvoSpecies);
+ pokePal = (void*) sub_80409C8(postEvoSpecies, TiD, PiD);
+ LoadCompressedPalette(*pokePal, 0x120, 0x20);
+
+ GetMonSpriteTemplate_803C56C(postEvoSpecies, 3);
+ gUnknown_02024E8C.affineAnims = gDummySpriteAffineAnimTable;
+ sEvoInfo.postEvoSpriteID = ID = CreateSprite(&gUnknown_02024E8C, 120, 64, 30);
+
+ gSprites[ID].callback = nullsub_37;
+ gSprites[ID].oam.paletteNum = 2;
+
+ REG_DISPCNT = DISPCNT_OBJ_ON | DISPCNT_BG_ALL_ON | DISPCNT_OBJ_1D_MAP;
+ SetHBlankCallback(EvoDummyFunc);
+ SetVBlankCallback(VBlankCB_EvolutionScene);
+ SetMainCallback2(CB2_EvolutionSceneUpdate);
+ BeginNormalPaletteFade(-1, 0, 0x10, 0, 0);
+}
+
+static void CB2_TradeEvolutionSceneLoadGraphics(void)
+{
+ struct Pokemon* Mon = &gPlayerParty[gTasks[sEvoInfo.evoTaskID].tPartyID];
+ u16 postEvoSpecies = gTasks[sEvoInfo.evoTaskID].tPostEvoSpecies;
+
+ switch (gMain.state)
+ {
+ case 0:
+ REG_DISPCNT = 0;
+ SetHBlankCallback(NULL);
+ SetVBlankCallback(NULL);
+ ResetSpriteData();
+ FreeAllSpritePalettes();
+ gReservedSpritePaletteCount = 4;
+ gUnknown_030042A4 = 0;
+ gUnknown_030042A0 = 0;
+ gUnknown_030042C0 = 0;
+ gUnknown_030041B4 = 0;
+ gUnknown_03004288 = 0;
+ gUnknown_03004280 = 0;
+ gUnknown_030041B0 = 256;
+ gUnknown_030041B8 = 0;
+ gMain.state++;
+ break;
+ case 1:
+ SetUpWindowConfig(&gWindowConfig_81E6F84);
+ InitWindowFromConfig(&gUnknown_03004828->field_4, &gWindowConfig_81E6F84);
+ gMain.state++;
+ break;
+ case 2:
+ LoadTextWindowGraphics(&gUnknown_03004828->field_4);
+ gUnknown_03004828->field_34 = SetTextWindowBaseTileNum(2);
+ LoadTextWindowGraphics(&gUnknown_03004828->field_4);
+ MenuZeroFillScreen();
+ ResetPaletteFade();
+ gMain.state++;
+ SetHBlankCallback(EvoDummyFunc);
+ SetVBlankCallback(VBlankCB_TradeEvolutionScene);
+ break;
+ case 3:
+ sub_804E22C();
+ gMain.state++;
+ break;
+ case 4:
+ {
+ const struct CompressedSpritePalette** pokePal;
+ u32 TiD = GetMonData(Mon, MON_DATA_OT_ID);
+ u32 PiD = GetMonData(Mon, MON_DATA_PERSONALITY);
+ DecompressPicFromTable_2(&gMonFrontPicTable[postEvoSpecies],
+ gMonFrontPicCoords[postEvoSpecies].coords,
+ gMonFrontPicCoords[postEvoSpecies].y_offset,
+ (void*)(0x2000000),
+ gUnknown_081FAF4C[3], postEvoSpecies);
+ pokePal = (void*) sub_80409C8(postEvoSpecies, TiD, PiD);
+ LoadCompressedPalette(*pokePal, 0x120, 0x20);
+ gMain.state++;
+ }
+ break;
+ case 5:
+ {
+ u8 ID;
+
+ GetMonSpriteTemplate_803C56C(postEvoSpecies, 3);
+ gUnknown_02024E8C.affineAnims = gDummySpriteAffineAnimTable;
+ sEvoInfo.postEvoSpriteID = ID = CreateSprite(&gUnknown_02024E8C, 120, 64, 30);
+
+ gSprites[ID].callback = nullsub_37;
+ gSprites[ID].oam.paletteNum = 2;
+ gMain.state++;
+ }
+ break;
+ case 6:
+ BeginNormalPaletteFade(-1, 0, 0x10, 0, 0);
+ SetMainCallback2(CB2_TradeEvolutionSceneUpdate);
+ REG_DISPCNT = DISPCNT_OBJ_ON | DISPCNT_BG0_ON | DISPCNT_BG1_ON | DISPCNT_OBJ_1D_MAP;
+ break;
+ }
+}
+
+void TradeEvolutionScene(struct Pokemon* mon, u16 speciesToEvolve, u8 preEvoSpriteID, u8 partyID)
+{
+ u8 name[20];
+ u16 currSpecies;
+ u32 TiD, PiD;
+ const struct CompressedSpritePalette** pokePal;
+ u8 ID;
+
+ GetMonData(mon, MON_DATA_NICKNAME, name);
+ StringCopy10(gStringVar1, name);
+ StringCopy(gStringVar2, gSpeciesNames[speciesToEvolve]);
+
+ gAffineAnimsDisabled = TRUE;
+
+ // preEvo sprite
+ currSpecies = GetMonData(mon, MON_DATA_SPECIES);
+ PiD = GetMonData(mon, MON_DATA_PERSONALITY);
+ TiD = GetMonData(mon, MON_DATA_OT_ID);
+ sEvoInfo.preEvoSpriteID = preEvoSpriteID;
+ DecompressPicFromTable_2(&gMonFrontPicTable[speciesToEvolve],
+ gMonFrontPicCoords[speciesToEvolve].coords,
+ gMonFrontPicCoords[speciesToEvolve].y_offset,
+ (void*)(0x2000000),
+ gUnknown_081FAF4C[1], speciesToEvolve);
+ pokePal = (void*) sub_80409C8(speciesToEvolve, TiD, PiD);
+ LoadCompressedPalette(*pokePal, 0x120, 0x20);
+
+ GetMonSpriteTemplate_803C56C(speciesToEvolve, 1);
+ gUnknown_02024E8C.affineAnims = gDummySpriteAffineAnimTable;
+ sEvoInfo.postEvoSpriteID = ID = CreateSprite(&gUnknown_02024E8C, 120, 64, 30);
+
+ gSprites[ID].callback = nullsub_37;
+ gSprites[ID].oam.paletteNum = 2;
+ gSprites[ID].invisible = 1;
+
+ LoadEvoSparkleSpriteAndPal();
+
+ sEvoInfo.evoTaskID = ID = CreateTask(Task_TradeEvolutionScene, 0);
+ gTasks[ID].tState = 0;
+ gTasks[ID].tPreEvoSpecies = currSpecies;
+ gTasks[ID].tPostEvoSpecies = speciesToEvolve;
+ gTasks[ID].tMonPtrHI = (u32)(mon);
+ gTasks[ID].tMonPtrLO = (u32)(mon) >> 0x10;
+ gTasks[ID].tLearnsFirstMove = TRUE;
+ gTasks[ID].tEvoWasStopped = FALSE;
+ gTasks[ID].tPartyID = partyID;
+
+ SetMainCallback2(CB2_TradeEvolutionSceneUpdate);
+}
+
+static void CB2_EvolutionSceneUpdate(void)
+{
+ AnimateSprites();
+ BuildOamBuffer();
+ sub_800374C(&gUnknown_03004210);
+ UpdatePaletteFade();
+ RunTasks();
+}
+
+static void CB2_TradeEvolutionSceneUpdate(void)
+{
+ AnimateSprites();
+ BuildOamBuffer();
+ sub_80035AC(&gUnknown_03004828->field_4);
+ UpdatePaletteFade();
+ RunTasks();
+}
+
+static void CreateShedinja(u16 preEvoSpecies, struct Pokemon* mon)
+{
+ u32 data = 0;
+ if (gEvolutionTable[preEvoSpecies].evolutions[0].method == EVO_LEVEL_NINJASK && gPlayerPartyCount < 6)
+ {
+ s32 i;
+ struct Pokemon* Shedinja = &gPlayerParty[gPlayerPartyCount];
+ const struct EvolutionData* EvoTable;
+ const struct EvolutionData* Evos;
+
+ CopyMon(Shedinja, mon, sizeof(struct Pokemon));
+ SetMonData(Shedinja, MON_DATA_SPECIES, (void*)(&gEvolutionTable[preEvoSpecies].evolutions[1].targetSpecies));
+ SetMonData(Shedinja, MON_DATA_NICKNAME, (void*)(gSpeciesNames[gEvolutionTable[preEvoSpecies].evolutions[1].targetSpecies]));
+ SetMonData(Shedinja, MON_DATA_HELD_ITEM, (void*)(&data));
+ SetMonData(Shedinja, MON_DATA_MARKINGS, (void*)(&data));
+ SetMonData(Shedinja, MON_DATA_10, (void*)(&data));
+ for (i = MON_DATA_COOL_RIBBON; i < MON_DATA_COOL_RIBBON + 5; i++)
+ SetMonData(Shedinja, i, (void*)(&data));
+ for (i = MON_DATA_CHAMPION_RIBBON; i <= MON_DATA_FATEFUL_ENCOUNTER; i++)
+ SetMonData(Shedinja, i, (void*)(&data));
+ SetMonData(Shedinja, MON_DATA_STATUS, (void*)(&data));
+ data = 0xFF;
+ SetMonData(Shedinja, MON_DATA_MAIL, (void*)(&data));
+
+ CalculateMonStats(Shedinja);
+ CalculatePlayerPartyCount();
+
+ // can't match it otherwise, ehh
+ EvoTable = gEvolutionTable;
+ Evos = EvoTable + preEvoSpecies;
+ GetNationalPokedexFlag(SpeciesToNationalPokedexNum(Evos->evolutions[1].targetSpecies), 2);
+ GetNationalPokedexFlag(SpeciesToNationalPokedexNum(Evos->evolutions[1].targetSpecies), 3);
+
+ if (GetMonData(Shedinja, MON_DATA_SPECIES) == SPECIES_SHEDINJA
+ && GetMonData(Shedinja, MON_DATA_LANGUAGE) == LANGUAGE_JAPANESE
+ && GetMonData(mon, MON_DATA_SPECIES) == SPECIES_NINJASK)
+ SetMonData(Shedinja, MON_DATA_NICKNAME, sUnknownShedinjaJpnString);
+ }
+}
+
+static void Task_EvolutionScene(u8 taskID)
+{
+ u32 var;
+ struct Pokemon* mon = (struct Pokemon*)(gTasks[taskID].tMonPtrHI | (gTasks[taskID].tMonPtrLO << 0x10));
+
+ // check if B Button was held, so the evolution gets stopped
+ if (gMain.heldKeys == B_BUTTON && gTasks[taskID].tState == 8 && gTasks[taskID].tBits & TASK_BIT_CAN_STOP)
+ {
+ gTasks[taskID].tState = 16;
+ if (gTasks[sEvoGraphicsTaskID].isActive)
+ gTasks[sEvoGraphicsTaskID].EvoGraphicsTaskEvoStop = TRUE;
+ }
+ switch (gTasks[taskID].tState)
+ {
+ case 0:
+ BeginNormalPaletteFade(-1, 0, 0x10, 0, 0);
+ gSprites[sEvoInfo.preEvoSpriteID].invisible = 0;
+ gTasks[taskID].tState++;
+ break;
+ case 1: // print 'whoa, poke is evolving!!!' msg
+ if (!gPaletteFade.active)
+ {
+ StringExpandPlaceholders(gStringVar4, gUnknown_08400C4A);
+ sub_8002EB0(&gUnknown_03004210, gStringVar4, 144, 2, 15);
+ gTasks[taskID].tState++;
+ }
+ break;
+ case 2: // wait for string, play cry
+ if (gUnknown_03004210.state == 0)
+ {
+ PlayCry1(gTasks[taskID].tPreEvoSpecies, 0);
+ gTasks[taskID].tState++;
+ }
+ break;
+ case 3: // wait for cry, play tu du SE
+ if (IsCryFinished())
+ {
+ PlaySE(BGM_ME_SHINKA);
+ gTasks[taskID].tState++;
+ }
+ break;
+ case 4: // play evolution music and fade screen black
+ if (!IsSEPlaying())
+ {
+ PlayNewMapMusic(BGM_SHINKA);
+ gTasks[taskID].tState++;
+ BeginNormalPaletteFade(0x1C, 4, 0, 0x10, 0);
+ }
+ break;
+ case 5: // after screen fade, preapre evo sparkles
+ if (!gPaletteFade.active)
+ {
+ sEvoGraphicsTaskID = LaunchTask_PreEvoSparklesSet1(17);
+ gTasks[taskID].tState++;
+ }
+ break;
+ case 6: // another set of evo sparkles
+ if (!gTasks[sEvoGraphicsTaskID].isActive)
+ {
+ gTasks[taskID].tState++;
+ sEvoInfo.field_3 = 1;
+ sEvoGraphicsTaskID = LaunchTask_PreEvoSparklesSet2();
+ }
+ break;
+ case 7: // launch task that flashes pre evo with post evo sprites
+ if (!gTasks[sEvoGraphicsTaskID].isActive)
+ {
+ sEvoGraphicsTaskID = sub_8149E7C(sEvoInfo.preEvoSpriteID, sEvoInfo.postEvoSpriteID);
+ gTasks[taskID].tState++;
+ }
+ break;
+ case 8: // wait for the above task to finish
+ if (--sEvoInfo.field_3 == 0)
+ {
+ sEvoInfo.field_3 = 3;
+ if (!gTasks[sEvoGraphicsTaskID].isActive)
+ gTasks[taskID].tState++;
+ }
+ break;
+ case 9: // post evo sparkles
+ sEvoGraphicsTaskID = LaunchTask_PostEvoSparklesSet1();
+ gTasks[taskID].tState++;
+ break;
+ case 10:
+ if (!gTasks[sEvoGraphicsTaskID].isActive)
+ {
+ sEvoGraphicsTaskID = LaunchTask_PostEvoSparklesSet2AndFlash(gTasks[taskID].tPostEvoSpecies);
+ gTasks[taskID].tState++;
+ }
+ break;
+ case 11: // play tu du sound after evolution
+ if (!gTasks[sEvoGraphicsTaskID].isActive)
+ {
+ PlaySE(SE_EXP);
+ gTasks[taskID].tState++;
+ }
+ break;
+ case 12: // play poke cry after evolution and return screed to pre-fade state
+ if (IsSEPlaying())
+ {
+ m4aMPlayAllStop();
+ PlayCry1(gTasks[taskID].tPostEvoSpecies, 0);
+ memcpy(&gPlttBufferUnfaded[0x20], gUnk_2009000, 0x60);
+ BeginNormalPaletteFade(0x1C, 0, 0x10, 0, 0);
+ gTasks[taskID].tState++;
+ }
+ break;
+ case 13: // congratulations string and rename prompt
+ if (IsCryFinished() && !gPaletteFade.active)
+ {
+ StringExpandPlaceholders(gStringVar4, gUnknown_08400C60);
+ sub_8002EB0(&gUnknown_03004210, gStringVar4, 144, 2, 15);
+ PlayBGM(BGM_FANFA5);
+ gTasks[taskID].tState++;
+ SetMonData(mon, MON_DATA_SPECIES, (void*)(&gTasks[taskID].tPostEvoSpecies));
+ CalculateMonStats(mon);
+ EvolutionRenameMon(mon, gTasks[taskID].tPreEvoSpecies, gTasks[taskID].tPostEvoSpecies);
+ GetNationalPokedexFlag(SpeciesToNationalPokedexNum(gTasks[taskID].tPostEvoSpecies), 2);
+ GetNationalPokedexFlag(SpeciesToNationalPokedexNum(gTasks[taskID].tPostEvoSpecies), 3);
+ IncrementGameStat(14);
+ }
+ break;
+ case 14: // check if it wants to learn a new move
+ if (gUnknown_03004210.state == 0)
+ {
+ var = MonTryLearningNewMove(mon, gTasks[taskID].tLearnsFirstMove);
+ if (var != 0 && !gTasks[taskID].tEvoWasStopped)
+ {
+ u8 text[20];
+
+ sub_8053E90();
+ gTasks[taskID].tBits |= TASK_BIT_LEARN_MOVE;
+ gTasks[taskID].tLearnsFirstMove = FALSE;
+ gTasks[taskID].tLearnMoveState = 0;
+ GetMonData(mon, MON_DATA_NICKNAME, text);
+ StringCopy10(gBattleTextBuff1, text);
+ if (var == 0xFFFF) // no place to learn it
+ gTasks[taskID].tState = 21;
+ else if (var == 0xFFFE) // it already knows that move
+ break;
+ else
+ gTasks[taskID].tState = 19; // has less than 4 moves, so it's been learned
+ }
+ else // no move to learn
+ {
+ BeginNormalPaletteFade(-1, 0, 0, 0x10, 0);
+ gTasks[taskID].tState++;
+ }
+ }
+ break;
+ case 15: // task has finished, return
+ if (!gPaletteFade.active)
+ {
+ if (!(gTasks[taskID].tBits & TASK_BIT_LEARN_MOVE))
+ sub_8053E90();
+ if (!gTasks[taskID].tEvoWasStopped)
+ CreateShedinja(gTasks[taskID].tPreEvoSpecies, mon);
+ DestroyTask(taskID);
+ SetMainCallback2(gCB2_AfterEvolution);
+ }
+ break;
+ case 16: // evolution has been canceled, stop music and re-fade palette
+ if (!gTasks[sEvoGraphicsTaskID].isActive)
+ {
+ m4aMPlayAllStop();
+ BeginNormalPaletteFade(0x6001C, 0, 0x10, 0, 0x7FFF);
+ gTasks[taskID].tState++;
+ }
+ break;
+ case 17: // play cry of the pokemon trying to evolve again, evolution has been stopped
+ if (!gPaletteFade.active)
+ {
+ PlayCry1(gTasks[taskID].tPreEvoSpecies, 0);
+ gTasks[taskID].tState++;
+ }
+ break;
+ case 18: // after the cry, print the string 'WHOA IT DID NOT EVOLVE!!!'
+ if (IsCryFinished())
+ {
+ StringExpandPlaceholders(gStringVar4, gUnknown_08400C8D);
+ sub_8002EB0(&gUnknown_03004210, gStringVar4, 144, 2, 15);
+ gTasks[taskID].tEvoWasStopped = TRUE;
+ gTasks[taskID].tState = 14;
+ }
+ break;
+ case 19: // pokemon learned a new move, print string and play a fanfare
+ if (gUnknown_03004210.state == 0 && !IsSEPlaying())
+ {
+ sub_8024CEC();
+ PlayFanfare(BGM_FANFA1);
+ StrCpyDecodeToDisplayedStringBattle(gBattleStringsTable[3]);
+ sub_8002EB0(&gUnknown_03004210, gDisplayedStringBattle, 144, 2, 15);
+ gTasks[taskID].tLearnsFirstMove = 0x40; // re-used as a counter
+ gTasks[taskID].tState++;
+ }
+ break;
+ case 20: // wait a bit and check if can learn another move
+ if (gUnknown_03004210.state == 0 && !IsSEPlaying() && --gTasks[taskID].tLearnsFirstMove == 0)
+ gTasks[taskID].tState = 14;
+ break;
+ case 21: // try to learn a new move
+ switch (gTasks[taskID].tLearnMoveState)
+ {
+ case 0:
+ if (gUnknown_03004210.state == 0 && !IsSEPlaying())
+ {
+ sub_8024CEC();
+ StrCpyDecodeToDisplayedStringBattle(gBattleStringsTable[4]);
+ sub_8002EB0(&gUnknown_03004210, gDisplayedStringBattle, 144, 2, 15);
+ gTasks[taskID].tLearnMoveState++;
+ }
+ break;
+ case 1:
+ if (gUnknown_03004210.state == 0 && !IsSEPlaying())
+ {
+ StrCpyDecodeToDisplayedStringBattle(gBattleStringsTable[5]);
+ sub_8002EB0(&gUnknown_03004210, gDisplayedStringBattle, 144, 2, 15);
+ gTasks[taskID].tLearnMoveState++;
+ }
+ break;
+ case 2:
+ if (gUnknown_03004210.state != 0)
+ break;
+ if (!IsSEPlaying())
+ {
+ StrCpyDecodeToDisplayedStringBattle(gBattleStringsTable[6]);
+ sub_8002EB0(&gUnknown_03004210, gDisplayedStringBattle, 144, 2, 15);
+ gTasks[taskID].tData9 = 5;
+ gTasks[taskID].tData10 = 9;
+ gTasks[taskID].tLearnMoveState++;
+ }
+ case 3:
+ if (gUnknown_03004210.state == 0 && !IsSEPlaying())
+ {
+ sub_8023A80();
+ gTasks[taskID].tLearnMoveState++;
+ sEvoCursorPos = 0;
+ sub_802BC6C();
+ }
+ break;
+ case 4:
+ if (gMain.newKeys & DPAD_UP && sEvoCursorPos != 0)
+ {
+ PlaySE(SE_SELECT);
+ nullsub_6();
+ sEvoCursorPos = 0;
+ sub_802BC6C();
+ }
+ if (gMain.newKeys & DPAD_DOWN && sEvoCursorPos == 0)
+ {
+ PlaySE(SE_SELECT);
+ nullsub_6();
+ sEvoCursorPos = 1;
+ sub_802BC6C();
+ }
+ if (gMain.newKeys & A_BUTTON)
+ {
+ sub_8023AD8();
+ StrCpyDecodeToDisplayedStringBattle(gBattleStringsTable[292]);
+ sub_8002EB0(&gUnknown_03004210, gDisplayedStringBattle, 144, 2, 15);
+ PlaySE(SE_SELECT);
+ if (sEvoCursorPos != 0)
+ gTasks[taskID].tLearnMoveState = gTasks[taskID].tData10;
+ else
+ {
+ gTasks[taskID].tLearnMoveState = gTasks[taskID].tData9;
+ if (gTasks[taskID].tLearnMoveState == 5)
+ BeginNormalPaletteFade(-1, 0, 0, 0x10, 0);
+ }
+ }
+ if (gMain.newKeys & B_BUTTON)
+ {
+ sub_8023AD8();
+ StrCpyDecodeToDisplayedStringBattle(gBattleStringsTable[292]);
+ sub_8002EB0(&gUnknown_03004210, gDisplayedStringBattle, 144, 2, 15);
+ PlaySE(SE_SELECT);
+ gTasks[taskID].tLearnMoveState = gTasks[taskID].tData10;
+ }
+ break;
+ case 5:
+ if (!gPaletteFade.active)
+ {
+ sub_809D9F0(gPlayerParty, gTasks[taskID].tPartyID,
+ gPlayerPartyCount - 1, CB2_EvolutionSceneLoadGraphics,
+ gMoveToLearn);
+ gTasks[taskID].tLearnMoveState++;
+ }
+ break;
+ case 6:
+ if (!gPaletteFade.active && gMain.callback2 == CB2_EvolutionSceneUpdate)
+ {
+ var = sub_809FA30(); // moveID
+ if (var == 4)
+ gTasks[taskID].tLearnMoveState = 9;
+ else
+ {
+ u16 move = GetMonData(mon, var + MON_DATA_MOVE1);
+ if (IsHMMove2(move))
+ {
+ StrCpyDecodeToDisplayedStringBattle(gBattleStringsTable[307]);
+ sub_8002EB0(&gUnknown_03004210, gDisplayedStringBattle, 144, 2, 15);
+ gTasks[taskID].tLearnMoveState = 11;
+ }
+ else
+ {
+ gBattleTextBuff2[0] = 0xFD;
+ gBattleTextBuff2[1] = 2;
+ gBattleTextBuff2[2] = move;
+ gBattleTextBuff2[3] = (move & 0xFF00) >> 8;
+ gBattleTextBuff2[4] = EOS;
+ RemoveMonPPBonus(mon, var);
+ SetMonMoveSlot(mon, gMoveToLearn, var);
+ StrCpyDecodeToDisplayedStringBattle(gBattleStringsTable[207]);
+ sub_8002EB0(&gUnknown_03004210, gDisplayedStringBattle, 144, 2, 15);
+ gTasks[taskID].tLearnMoveState++;
+ }
+ }
+ }
+ break;
+ case 7:
+ if (gUnknown_03004210.state == 0 && !IsSEPlaying())
+ {
+ StrCpyDecodeToDisplayedStringBattle(gBattleStringsTable[7]);
+ sub_8002EB0(&gUnknown_03004210, gDisplayedStringBattle, 144, 2, 15);
+ gTasks[taskID].tLearnMoveState++;
+ }
+ break;
+ case 8:
+ if (gUnknown_03004210.state == 0 && !IsSEPlaying())
+ {
+ StrCpyDecodeToDisplayedStringBattle(gBattleStringsTable[208]);
+ sub_8002EB0(&gUnknown_03004210, gDisplayedStringBattle, 144, 2, 15);
+ gTasks[taskID].tState = 19;
+ }
+ break;
+ case 9:
+ StrCpyDecodeToDisplayedStringBattle(gBattleStringsTable[8]);
+ sub_8002EB0(&gUnknown_03004210, gDisplayedStringBattle, 144, 2, 15);
+ gTasks[taskID].tData9 = 10;
+ gTasks[taskID].tData10 = 0;
+ gTasks[taskID].tLearnMoveState = 3;
+ break;
+ case 10:
+ StrCpyDecodeToDisplayedStringBattle(gBattleStringsTable[9]);
+ sub_8002EB0(&gUnknown_03004210, gDisplayedStringBattle, 144, 2, 15);
+ gTasks[taskID].tState = 14;
+ break;
+ case 11:
+ if (gUnknown_03004210.state == 0 && !IsSEPlaying())
+ gTasks[taskID].tLearnMoveState = 5;
+ break;
+ }
+ break;
+ }
+}
+
+static void Task_TradeEvolutionScene(u8 taskID)
+{
+ u32 var;
+ struct Pokemon* mon = (struct Pokemon*)(gTasks[taskID].tMonPtrHI | (gTasks[taskID].tMonPtrLO << 0x10));
+
+ switch (gTasks[taskID].tState)
+ {
+ case 0:
+ StringExpandPlaceholders(gStringVar4, gUnknown_08400C4A);
+ sub_8002EB0(&gUnknown_03004828->field_4, gStringVar4, gUnknown_03004828->field_34, 2, 15);
+ gTasks[taskID].tState++;
+ break;
+ case 1:
+ if (gUnknown_03004828->field_4.state == 0)
+ {
+ PlayCry1(gTasks[taskID].tPreEvoSpecies, 0);
+ gTasks[taskID].tState++;
+ }
+ break;
+ case 2:
+ if (IsCryFinished())
+ {
+ m4aSongNumStop(BGM_SHINKA);
+ PlaySE(BGM_ME_SHINKA);
+ gTasks[taskID].tState++;
+ }
+ break;
+ case 3:
+ if (!IsSEPlaying())
+ {
+ PlayBGM(BGM_SHINKA);
+ gTasks[taskID].tState++;
+ BeginNormalPaletteFade(0x1C, 4, 0, 0x10, 0);
+ }
+ break;
+ case 4:
+ if (!gPaletteFade.active)
+ {
+ REG_DISPCNT = DISPCNT_OBJ_ON | DISPCNT_BG0_ON | DISPCNT_BG1_ON | DISPCNT_OBJ_1D_MAP;
+ sEvoGraphicsTaskID = LaunchTask_PreEvoSparklesSet1(17);
+ gTasks[taskID].tState++;
+ }
+ break;
+ case 5:
+ if (!gTasks[sEvoGraphicsTaskID].isActive)
+ {
+ gTasks[taskID].tState++;
+ sEvoInfo.field_3 = 1;
+ sEvoGraphicsTaskID = LaunchTask_PreEvoSparklesSet2();
+ }
+ break;
+ case 6:
+ if (!gTasks[sEvoGraphicsTaskID].isActive)
+ {
+ sEvoGraphicsTaskID = sub_8149E7C(sEvoInfo.preEvoSpriteID, sEvoInfo.postEvoSpriteID);
+ gTasks[taskID].tState++;
+ }
+ break;
+ case 7:
+ if (--sEvoInfo.field_3 == 0)
+ {
+ sEvoInfo.field_3 = 3;
+ if (!gTasks[sEvoGraphicsTaskID].isActive)
+ gTasks[taskID].tState++;
+ }
+ break;
+ case 8:
+ sEvoGraphicsTaskID = LaunchTask_PostEvoSparklesSet1();
+ gTasks[taskID].tState++;
+ break;
+ case 9:
+ if (!gTasks[sEvoGraphicsTaskID].isActive)
+ {
+ sEvoGraphicsTaskID = LaunchTask_PostEvoSparklesSet2AndFlash_Trade(gTasks[taskID].tPostEvoSpecies);
+ gTasks[taskID].tState++;
+ }
+ break;
+ case 10:
+ if (!gTasks[sEvoGraphicsTaskID].isActive)
+ {
+ PlaySE(SE_EXP);
+ gTasks[taskID].tState++;
+ }
+ break;
+ case 11:
+ if (IsSEPlaying())
+ {
+ PlayCry1(gTasks[taskID].tPostEvoSpecies, 0);
+ memcpy(&gPlttBufferUnfaded[0x20], gUnk_2009000, 0x60);
+ BeginNormalPaletteFade(1, 0, 0x10, 0, 0);
+ gTasks[taskID].tState++;
+ }
+ break;
+ case 12:
+ if (IsCryFinished() && !gPaletteFade.active)
+ {
+ StringExpandPlaceholders(gStringVar4, gUnknown_08400C60);
+ sub_8002EB0(&gUnknown_03004828->field_4, gStringVar4, gUnknown_03004828->field_34, 2, 15);
+ PlayFanfare(BGM_FANFA5);
+ gTasks[taskID].tState++;
+ SetMonData(mon, MON_DATA_SPECIES, (void*)(&gTasks[taskID].tPostEvoSpecies));
+ CalculateMonStats(mon);
+ EvolutionRenameMon(mon, gTasks[taskID].tPreEvoSpecies, gTasks[taskID].tPostEvoSpecies);
+ GetNationalPokedexFlag(SpeciesToNationalPokedexNum(gTasks[taskID].tPostEvoSpecies), 2);
+ GetNationalPokedexFlag(SpeciesToNationalPokedexNum(gTasks[taskID].tPostEvoSpecies), 3);
+ IncrementGameStat(14);
+ }
+ break;
+ case 13:
+ if (gUnknown_03004828->field_4.state == 0 && IsFanfareTaskInactive() == TRUE)
+ {
+ var = MonTryLearningNewMove(mon, gTasks[taskID].tLearnsFirstMove);
+ if (var != 0 && !gTasks[taskID].tEvoWasStopped)
+ {
+ u8 text[20];
+
+ gTasks[taskID].tBits |= TASK_BIT_LEARN_MOVE;
+ gTasks[taskID].tLearnsFirstMove = FALSE;
+ gTasks[taskID].tLearnMoveState = 0;
+ GetMonData(mon, MON_DATA_NICKNAME, text);
+ StringCopy10(gBattleTextBuff1, text);
+ if (var == 0xFFFF)
+ gTasks[taskID].tState = 17;
+ else if (var == 0xFFFE)
+ break;
+ else
+ gTasks[taskID].tState = 15;
+ }
+ else
+ {
+ PlayBGM(BGM_SHINKA);
+ sub_8002EB0(&gUnknown_03004828->field_4, gOtherText_LinkStandby2, gUnknown_03004828->field_34, 2, 15);
+ gTasks[taskID].tState++;
+ }
+ }
+ break;
+ case 14:
+ if (gUnknown_03004828->field_4.state == 0)
+ {
+ DestroyTask(taskID);
+ SetMainCallback2(gCB2_AfterEvolution);
+ }
+ break;
+ case 15:
+ if (gUnknown_03004828->field_4.state == 0 && !IsSEPlaying())
+ {
+ sub_8024CEC();
+ PlayFanfare(BGM_FANFA1);
+ StrCpyDecodeToDisplayedStringBattle(gBattleStringsTable[3]);
+ sub_8002EB0(&gUnknown_03004828->field_4, gDisplayedStringBattle, gUnknown_03004828->field_34, 2, 15);
+ gTasks[taskID].tLearnsFirstMove = 0x40; // re-used as a counter
+ gTasks[taskID].tState++;
+ }
+ break;
+ case 16:
+ if (gUnknown_03004828->field_4.state == 0 && IsFanfareTaskInactive() == TRUE && --gTasks[taskID].tLearnsFirstMove == 0)
+ gTasks[taskID].tState = 13;
+ break;
+ case 17:
+ switch (gTasks[taskID].tLearnMoveState)
+ {
+ case 0:
+ if (gUnknown_03004828->field_4.state == 0 && !IsSEPlaying())
+ {
+ sub_8024CEC();
+ StrCpyDecodeToDisplayedStringBattle(gBattleStringsTable[4]);
+ sub_8002EB0(&gUnknown_03004828->field_4, gDisplayedStringBattle, gUnknown_03004828->field_34, 2, 15);
+ gTasks[taskID].tLearnMoveState++;
+ }
+ break;
+ case 1:
+ if (gUnknown_03004828->field_4.state == 0 && !IsSEPlaying())
+ {
+ StrCpyDecodeToDisplayedStringBattle(gBattleStringsTable[5]);
+ sub_8002EB0(&gUnknown_03004828->field_4, gDisplayedStringBattle, gUnknown_03004828->field_34, 2, 15);
+ gTasks[taskID].tLearnMoveState++;
+ }
+ break;
+ case 2:
+ if (gUnknown_03004828->field_4.state != 0)
+ break;
+ if (!IsSEPlaying())
+ {
+ StrCpyDecodeToDisplayedStringBattle(gBattleStringsTable[6]);
+ sub_8002EB0(&gUnknown_03004828->field_4, gDisplayedStringBattle, gUnknown_03004828->field_34, 2, 15);
+ gTasks[taskID].tData9 = 5;
+ gTasks[taskID].tData10 = 9;
+ gTasks[taskID].tLearnMoveState++;
+ }
+ case 3:
+ if (gUnknown_03004828->field_4.state == 0 && !IsSEPlaying())
+ {
+ DrawTextWindow(&gUnknown_03004828->field_4, 24, 8, 29, 13);
+ sEvoCursorPos = 0;
+ InitWindow(&gUnknown_03004828->field_4, gOtherText_YesNoAndPlayer, gUnknown_03004828->field_34 + 128, 25, 9);
+ sub_8002F44(&gUnknown_03004828->field_4);
+ sub_814A5C0(0, 0xFFFF, 0xC, 0x2D9F, 0x20);
+ sub_81150D8();
+ gTasks[taskID].tLearnMoveState++;
+ sEvoCursorPos = 0;
+ }
+ break;
+ case 4:
+ if (gMain.newKeys & DPAD_UP && sEvoCursorPos != 0)
+ {
+ PlaySE(SE_SELECT);
+ EvoDummyFunc2();
+ sEvoCursorPos = 0;
+ sub_81150D8();
+ }
+ if (gMain.newKeys & DPAD_DOWN && sEvoCursorPos == 0)
+ {
+ PlaySE(SE_SELECT);
+ EvoDummyFunc2();
+ sEvoCursorPos = 1;
+ sub_81150D8();
+ }
+ if (gMain.newKeys & A_BUTTON)
+ {
+ ZeroFillWindowRect(&gUnknown_03004828->field_4, 0x18, 8, 0x1D, 0xD);
+ DestroyMenuCursor();
+ StrCpyDecodeToDisplayedStringBattle(gBattleStringsTable[292]);
+ sub_8002EB0(&gUnknown_03004828->field_4, gDisplayedStringBattle, gUnknown_03004828->field_34, 2, 15);
+ PlaySE(SE_SELECT);
+ if (sEvoCursorPos != 0)
+ gTasks[taskID].tLearnMoveState = gTasks[taskID].tData10;
+ else
+ {
+ gTasks[taskID].tLearnMoveState = gTasks[taskID].tData9;
+ if (gTasks[taskID].tLearnMoveState == 5)
+ BeginNormalPaletteFade(-1, 0, 0, 0x10, 0);
+ }
+ }
+ if (gMain.newKeys & B_BUTTON)
+ {
+ ZeroFillWindowRect(&gUnknown_03004828->field_4, 0x18, 8, 0x1D, 0xD);
+ DestroyMenuCursor();
+ StrCpyDecodeToDisplayedStringBattle(gBattleStringsTable[292]);
+ sub_8002EB0(&gUnknown_03004828->field_4, gDisplayedStringBattle, gUnknown_03004828->field_34, 2, 15);
+ PlaySE(SE_SELECT);
+ gTasks[taskID].tLearnMoveState = gTasks[taskID].tData10;
+ }
+ break;
+ case 5:
+ if (!gPaletteFade.active)
+ {
+ sub_809D9F0(gPlayerParty, gTasks[taskID].tPartyID,
+ gPlayerPartyCount - 1, CB2_TradeEvolutionSceneLoadGraphics,
+ gMoveToLearn);
+ gTasks[taskID].tLearnMoveState++;
+ }
+ break;
+ case 6:
+ if (!gPaletteFade.active && gMain.callback2 == CB2_TradeEvolutionSceneUpdate)
+ {
+ var = sub_809FA30(); // moveID
+ if (var == 4)
+ gTasks[taskID].tLearnMoveState = 9;
+ else
+ {
+ u16 move = GetMonData(mon, var + MON_DATA_MOVE1);
+ if (IsHMMove2(move))
+ {
+ StrCpyDecodeToDisplayedStringBattle(gBattleStringsTable[307]);
+ sub_8002EB0(&gUnknown_03004828->field_4, gDisplayedStringBattle, gUnknown_03004828->field_34, 2, 15);
+ gTasks[taskID].tLearnMoveState = 11;
+ }
+ else
+ {
+ gBattleTextBuff2[0] = 0xFD;
+ gBattleTextBuff2[1] = 2;
+ gBattleTextBuff2[2] = move;
+ gBattleTextBuff2[3] = (move & 0xFF00) >> 8;
+ gBattleTextBuff2[4] = EOS;
+ RemoveMonPPBonus(mon, var);
+ SetMonMoveSlot(mon, gMoveToLearn, var);
+ StrCpyDecodeToDisplayedStringBattle(gBattleStringsTable[207]);
+ sub_8002EB0(&gUnknown_03004828->field_4, gDisplayedStringBattle, gUnknown_03004828->field_34, 2, 15);
+ gTasks[taskID].tLearnMoveState++;
+ }
+ }
+ }
+ break;
+ case 7:
+ if (gUnknown_03004828->field_4.state == 0 && !IsSEPlaying())
+ {
+ StrCpyDecodeToDisplayedStringBattle(gBattleStringsTable[7]);
+ sub_8002EB0(&gUnknown_03004828->field_4, gDisplayedStringBattle, gUnknown_03004828->field_34, 2, 15);
+ gTasks[taskID].tLearnMoveState++;
+ }
+ break;
+ case 8:
+ if (gUnknown_03004828->field_4.state == 0 && !IsSEPlaying())
+ {
+ StrCpyDecodeToDisplayedStringBattle(gBattleStringsTable[208]);
+ sub_8002EB0(&gUnknown_03004828->field_4, gDisplayedStringBattle, gUnknown_03004828->field_34, 2, 15);
+ gTasks[taskID].tState = 15;
+ }
+ break;
+ case 9:
+ StrCpyDecodeToDisplayedStringBattle(gBattleStringsTable[8]);
+ sub_8002EB0(&gUnknown_03004828->field_4, gDisplayedStringBattle, gUnknown_03004828->field_34, 2, 15);
+ gTasks[taskID].tData9 = 10;
+ gTasks[taskID].tData10 = 0;
+ gTasks[taskID].tLearnMoveState = 3;
+ break;
+ case 10:
+ StrCpyDecodeToDisplayedStringBattle(gBattleStringsTable[9]);
+ sub_8002EB0(&gUnknown_03004828->field_4, gDisplayedStringBattle, gUnknown_03004828->field_34, 2, 15);
+ gTasks[taskID].tState = 13;
+ break;
+ case 11:
+ if (gUnknown_03004828->field_4.state == 0 && !IsSEPlaying())
+ gTasks[taskID].tLearnMoveState = 5;
+ break;
+ }
+ break;
+ }
+}
+
+/*
+DizzyEgg, 27.08.2017
+NOTE:
+ Functions below are all unused.
+ What's more, they do NOT exist in Emerald.
+ That's why I think there is no reason to decompile those,
+ as they probably were prototypes for the evolution
+ functions.
+*/
+
+/*
+void unref_sub_8113B50(u8 *a, u8 *b)
+{
+ //u8 *sp0 = a;
+ //u8 *sp4 = b;
+#define sp0 a
+#define sp4 b
+ s32 sp8;
+ s32 spC = 0;
+ u32 sp10 = 0;
+ s32 sp14;
+ s32 r6;
+ u32 r8;
+
+ for (sp8 = 0; sp8 < 64; sp8++)
+ {
+ sEvoInfo.unk84[sp8] = 0;
+ sEvoInfo.unk4[sp8] = 0;
+ sEvoInfo.unk44[sp8] = 0;
+ for (r6 = 0; r6 < 32; r6++)
+ {
+ sEvoInfo.unk10C4[sp8][r6] = 0;
+ sEvoInfo.unk18C4[sp8][r6] = 0;
+ sEvoInfo.unk20C4[sp8][r6] = 0;
+ sEvoInfo.unk28C4[sp8][r6] = 0;
+ sEvoInfo.unkC4[sp8][r6] = 0;
+ sEvoInfo.unk8C4[sp8][r6] = 0;
+ sEvoInfo.unk30C4[sp8][r6] = 0;
+ sEvoInfo.unk38C4[sp8][r6] = 0;
+
+ sEvoInfo.unk60C4[sp8][r6] = 0;
+ sEvoInfo.unk70C4[sp8][r6] = 0;
+ sEvoInfo.unk80C4[sp8][r6] = 0;
+ sEvoInfo.unk90C4[sp8][r6] = 0;
+ }
+ }
+
+ sEvoInfo.unkA0C4 = 64;
+ r8 = 0;
+ for (sp8 = 0; sp8 < 64; sp8++)
+ {
+ //_08113C32
+ u32 r3 = 0;
+ u8 *r2 = sp0 + r8;
+
+ for (r6 = 0; r6 < 64; r6++)
+ {
+ sEvoInfo.unk40C4[sp8][r6 >> 1] = r2;
+ switch (r3)
+ {
+ case 0:
+ switch (r6 & 1)
+ {
+ case 0:
+ if (*r2 & 0xF)
+ {
+ sEvoInfo.unk10C4[sp8][sEvoInfo.unk4[sp8]] = r6;
+ r3 = 1;
+ }
+ break;
+ case 1:
+ if (*r2 & 0xF0)
+ {
+ sEvoInfo.unk10C4[sp8][sEvoInfo.unk4[sp8]] = r6;
+ r3 = 1;
+ }
+ break;
+ }
+ break;
+ case 1:
+ switch (r6 & r3)
+ {
+ case 0:
+ if (*r2 & 0xF)
+ {
+ sEvoInfo.unk18C4[sp8][sEvoInfo.unk4[sp8]] = r6 - 1;
+ sEvoInfo.unk4[sp8]++;
+ r3 = 0;
+ }
+ break;
+ case 1:
+ if (*r2 & 0xF0)
+ {
+ sEvoInfo.unk18C4[sp8][sEvoInfo.unk4[sp8]] = r6 - 1;
+ sEvoInfo.unk4[sp8]++;
+ r3 = 0;
+ }
+ break;
+ }
+ }
+ //if (!((r6 + 1) & 7))
+ if ((r6 + 1) % 8 == 0)
+ r2 += 0x1D;
+ else if (r6 & 1)
+ r2 += 1;
+ }
+ if (r3)
+ {
+ sEvoInfo.unk18C4[sp8][sEvoInfo.unk4[sp8]] = r6;
+ sEvoInfo.unk4[sp8]++;
+ }
+ //_08113D26
+ if (!((sp8 + 1) & 7))
+ r8 += 0xE4;
+ else
+ r8 += 4;
+ }
+ //_08113D4A
+ r8 = 0;
+ for (sp8 = 0; sp8 < 64; sp8++)
+ {
+ //_08113D6A
+ u32 r3 = 0;
+ u8 *r2 = sp4 + r8;
+
+ for (r6 = 0; r6 < 64; r6++)
+ {
+ switch (r3)
+ {
+ case 0:
+ switch (r6 & 1)
+ {
+ case 0:
+ if (*r2 & 0xF)
+ {
+ sEvoInfo.unk20C4[sp8][sEvoInfo.unk44[sp8]] = r6;
+ r3 = 1;
+ }
+ break;
+ case 1:
+ if (*r2 & 0xF0)
+ {
+ sEvoInfo.unk20C4[sp8][sEvoInfo.unk44[sp8]] = r6;
+ r3 = 1;
+ }
+ break;
+ }
+ break;
+ case 1:
+ switch (r6 & r3)
+ {
+ case 0:
+ if (*r2 & 0xF)
+ {
+ sEvoInfo.unk28C4[sp8][sEvoInfo.unk44[sp8]] = r6 - 1;
+ sEvoInfo.unk44[sp8]++;
+ r3 = 0;
+ }
+ break;
+ case 1:
+ if (*r2 & 0xF0)
+ {
+ sEvoInfo.unk28C4[sp8][sEvoInfo.unk44[sp8]] = r6 - 1;
+ sEvoInfo.unk44[sp8]++;
+ r3 = 0;
+ }
+ break;
+ }
+ }
+ //_08113DE4
+ if (!((r6 + 1) & 7))
+ r2 += 0x1D;
+ else if (r6 & 1)
+ r2 += 1;
+
+ }
+ if (r3)
+ {
+ sEvoInfo.unk28C4[sp8][sEvoInfo.unk44[sp8]] = r6;
+ sEvoInfo.unk44[sp8]++;
+ }
+ //if (!((sp8 + 1) & 7))
+ if ((sp8 + 1) % 8 == 0)
+ r8 += 0xE4;
+ else
+ r8 += 4;
+ }
+
+ for (sp8 = 0; sp8 < 0x40; sp8++) //_08113E3A
+ {
+ if (sEvoInfo.unk4[sp8] < sEvoInfo.unk44[sp8])
+ {
+ for (spC = 0; spC < sEvoInfo.unk4[sp8]; spC++)
+ {
+ sp14 = 0x100;
+
+ for (r6 = 0; r6 < sEvoInfo.unk44[sp8]; r6++)
+ {
+ s32 r3;
+
+ //_08113EA4
+ if (sEvoInfo.unk10C4[sp8][spC] > sEvoInfo.unk20C4[sp8][r6])
+ r3 = sEvoInfo.unk10C4[sp8][spC] - sEvoInfo.unk20C4[sp8][r6];
+ else
+ r3 = sEvoInfo.unk20C4[sp8][r6] - sEvoInfo.unk10C4[sp8][spC];
+
+ if (sEvoInfo.unk18C4[sp8][spC] > sEvoInfo.unk28C4[sp8][spC])
+ r3 += sEvoInfo.unk18C4[sp8][spC] - sEvoInfo.unk28C4[sp8][spC];
+ else
+ r3 += sEvoInfo.unk28C4[sp8][spC] - sEvoInfo.unk18C4[sp8][spC];
+
+ if (sp14 >= r3 && sEvoInfo.unkC4[sp8][r6] == 0 && sEvoInfo.unk8C4[sp8][r6] == 0)
+ {
+ sp10 = r6;
+ sp14 = r3;
+ }
+ }
+ //_08113F3E
+ sub_81141F0(spC, sp10, sp8);
+ }
+ //_08113F54
+
+ for (r6 = 0; r6 < sEvoInfo.unk44[sp8]; r6++)
+ {
+ if (sEvoInfo.unkC4[sp8][r6] == 0 && sEvoInfo.unk8C4[sp8][r6] == 0)
+ sub_811430C(r6, sp8);
+ }
+ }
+ //_08113F9E
+ if (sEvoInfo.unk4[sp8] == sEvoInfo.unk44[sp8])
+ {
+ for (r6 = 0; r6 < sEvoInfo.unk4[sp8]; r6++)
+ sub_81141F0(r6, r6, sp8);
+ }
+ //_08113FCC
+ if (sEvoInfo.unk4[sp8] > sEvoInfo.unk44[sp8])
+ {
+ for (sp10 = 0; sp10 < sEvoInfo.unk44[sp8]; sp10++)
+ {
+ sp14 = 0x100;
+
+ for (r6 = 0; r6 < sEvoInfo.unk4[sp8]; r6++)
+ {
+ s32 r3;
+
+ if (sEvoInfo.unk10C4[sp8][r6] > sEvoInfo.unk20C4[sp8][sp10])
+ r3 = sEvoInfo.unk10C4[sp8][r6] - sEvoInfo.unk20C4[sp8][sp10];
+ else
+ r3 = sEvoInfo.unk20C4[sp8][sp10] - sEvoInfo.unk10C4[sp8][r6];
+
+ if (sEvoInfo.unk18C4[sp8][r6] > sEvoInfo.unk28C4[sp8][sp10])
+ r3 += sEvoInfo.unk18C4[sp8][r6] - sEvoInfo.unk28C4[sp8][sp10];
+ else
+ r3 += sEvoInfo.unk28C4[sp8][sp10] - sEvoInfo.unk18C4[sp8][r6];
+
+ //r3 = abs(sEvoInfo.unk10C4[sp8][r6] - sEvoInfo.unk20C4[sp8][sp10]);
+ //r3 += abs(sEvoInfo.unk18C4[sp8][r6] - sEvoInfo.unk28C4[sp8][sp10]);
+
+ if (sp14 > r3 && sEvoInfo.unkC4[sp8][r6] == 0)
+ {
+ spC = r6;
+ sp14 = r3;
+ }
+ }
+ //_081140C4
+ sEvoInfo.unk30C4[sp8][spC] = sEvoInfo.unk20C4[sp8][sp10];
+ sEvoInfo.unk38C4[sp8][spC] = sEvoInfo.unk28C4[sp8][sp10];
+ sEvoInfo.unkC4[sp8][spC] = 1;
+ }
+ //_08114104
+ for (r6 = 0; r6 < sEvoInfo.unk4[sp8]; r6++)
+ {
+ sEvoInfo.unk20C4[sp8][r6] = sEvoInfo.unk30C4[sp8][r6];
+ sEvoInfo.unk28C4[sp8][r6] = sEvoInfo.unk38C4[sp8][r6];
+ if (sEvoInfo.unkC4[sp8][r6] != 0)
+ {
+ sEvoInfo.unkC4[sp8][r6] = 0;
+ sub_81141F0(r6, r6, sp8);
+ }
+ else
+ {
+ // Ugh, can't get this part right
+ //u8 *ptr1 = &sEvoInfo.unk10C4[sp8][r6];
+ //u8 *ptr2 = &sEvoInfo.unk18C4[sp8][r6];
+ //s32 r2 = *ptr1 + (*ptr2 - *ptr1) / 2;
+
+ //u8 r0_ = sEvoInfo.unk10C4[sp8][r6];
+ //u8 r2_ = sEvoInfo.unk18C4[sp8][r6];
+ //s32 r2 = (r0_ - r2_) / 2;
+
+ s32 r2 = (sEvoInfo.unk18C4[sp8][r6] - sEvoInfo.unk10C4[sp8][r6]);
+ s32 r2_ = sEvoInfo.unk10C4[sp8][r6];
+
+ sEvoInfo.unk20C4[sp8][r6] = sEvoInfo.unk28C4[sp8][r6] = r2_ + r2 / 2;
+ sEvoInfo.unk28C4[sp8][r6]++;
+ sub_81141F0(r6, r6, sp8);
+ }
+ }
+ }
+ //_081141C4
+ }
+#undef sp0
+#undef sp4
+}
+*/
+__attribute__((naked))
+void unref_sub_8113B50()
+{
+ asm(".syntax unified\n\
+ push {r4-r7,lr}\n\
+ mov r7, r10\n\
+ mov r6, r9\n\
+ mov r5, r8\n\
+ push {r5-r7}\n\
+ sub sp, 0x3C\n\
+ str r0, [sp]\n\
+ str r1, [sp, 0x4]\n\
+ movs r0, 0\n\
+ str r0, [sp, 0xC]\n\
+ movs r1, 0\n\
+ str r1, [sp, 0x10]\n\
+ movs r2, 0\n\
+ str r2, [sp, 0x8]\n\
+ ldr r3, _08113C60 @ =0x02014800\n\
+ mov r12, r3\n\
+ ldr r4, _08113C64 @ =0x000018c4\n\
+ add r4, r12\n\
+ mov r10, r4\n\
+ ldr r5, _08113C68 @ =0x000020c4\n\
+ add r5, r12\n\
+ mov r8, r5\n\
+_08113B7C:\n\
+ adds r0, r3, 0\n\
+ adds r0, 0x84\n\
+ ldr r1, [sp, 0x8]\n\
+ adds r0, r1, r0\n\
+ strb r2, [r0]\n\
+ adds r0, r3, 0x4\n\
+ adds r0, r1, r0\n\
+ strb r2, [r0]\n\
+ ldr r4, _08113C6C @ =0x02014844\n\
+ adds r0, r1, r4\n\
+ strb r2, [r0]\n\
+ movs r6, 0\n\
+ lsls r1, 5\n\
+ mov r9, r1\n\
+ ldr r5, [sp, 0x8]\n\
+ lsls r4, r5, 6\n\
+_08113B9C:\n\
+ mov r0, r9\n\
+ adds r1, r6, r0\n\
+ ldr r5, _08113C70 @ =0x020158c4\n\
+ adds r0, r1, r5\n\
+ strb r2, [r0]\n\
+ mov r5, r10\n\
+ adds r0, r1, r5\n\
+ strb r2, [r0]\n\
+ mov r5, r8\n\
+ adds r0, r1, r5\n\
+ strb r2, [r0]\n\
+ ldr r5, _08113C74 @ =0x020170c4\n\
+ adds r0, r1, r5\n\
+ strb r2, [r0]\n\
+ adds r7, r3, 0\n\
+ adds r7, 0xC4\n\
+ adds r0, r1, r7\n\
+ strb r2, [r0]\n\
+ ldr r5, _08113C78 @ =0x000008c4\n\
+ adds r0, r3, r5\n\
+ adds r0, r1, r0\n\
+ strb r2, [r0]\n\
+ ldr r5, _08113C7C @ =0x000030c4\n\
+ adds r0, r3, r5\n\
+ adds r0, r1, r0\n\
+ strb r2, [r0]\n\
+ ldr r5, _08113C80 @ =0x000038c4\n\
+ adds r0, r3, r5\n\
+ adds r1, r0\n\
+ strb r2, [r1]\n\
+ lsls r1, r6, 1\n\
+ adds r1, r4\n\
+ ldr r5, _08113C84 @ =0x000060c4\n\
+ adds r0, r3, r5\n\
+ adds r0, r1, r0\n\
+ strh r2, [r0]\n\
+ ldr r5, _08113C88 @ =0x000070c4\n\
+ adds r0, r3, r5\n\
+ adds r0, r1, r0\n\
+ strh r2, [r0]\n\
+ ldr r5, _08113C8C @ =0x000080c4\n\
+ adds r0, r3, r5\n\
+ adds r0, r1, r0\n\
+ strh r2, [r0]\n\
+ ldr r5, _08113C90 @ =0x000090c4\n\
+ adds r0, r3, r5\n\
+ adds r1, r0\n\
+ strh r2, [r1]\n\
+ adds r6, 0x1\n\
+ cmp r6, 0x1F\n\
+ ble _08113B9C\n\
+ ldr r0, [sp, 0x8]\n\
+ adds r0, 0x1\n\
+ str r0, [sp, 0x8]\n\
+ cmp r0, 0x3F\n\
+ ble _08113B7C\n\
+ ldr r1, _08113C94 @ =0x0000a0c4\n\
+ add r1, r12\n\
+ movs r0, 0x40\n\
+ strb r0, [r1]\n\
+ movs r1, 0\n\
+ mov r8, r1\n\
+ movs r2, 0\n\
+ str r2, [sp, 0x8]\n\
+ movs r3, 0x80\n\
+ lsls r3, 5\n\
+ adds r3, r7\n\
+ mov r12, r3\n\
+ movs r4, 0xC0\n\
+ lsls r4, 5\n\
+ adds r4, r7\n\
+ mov r9, r4\n\
+ movs r5, 0\n\
+ adds r4, r7, 0\n\
+ subs r4, 0xC0\n\
+_08113C32:\n\
+ movs r3, 0\n\
+ ldr r2, [sp]\n\
+ add r2, r8\n\
+ movs r6, 0\n\
+ ldr r0, [sp, 0x8]\n\
+ adds r0, 0x1\n\
+ str r0, [sp, 0x30]\n\
+ ldr r1, [sp, 0x8]\n\
+ lsls r1, 7\n\
+ mov r10, r1\n\
+ movs r7, 0x1\n\
+ negs r7, r7\n\
+_08113C4A:\n\
+ asrs r0, r6, 1\n\
+ lsls r0, 2\n\
+ add r0, r10\n\
+ ldr r1, _08113C98 @ =0x020188c4\n\
+ adds r0, r1\n\
+ str r2, [r0]\n\
+ cmp r3, 0\n\
+ beq _08113C9C\n\
+ cmp r3, 0x1\n\
+ beq _08113CC6\n\
+ b _08113CF4\n\
+ .align 2, 0\n\
+_08113C60: .4byte 0x02014800\n\
+_08113C64: .4byte 0x000018c4\n\
+_08113C68: .4byte 0x000020c4\n\
+_08113C6C: .4byte 0x02014844\n\
+_08113C70: .4byte 0x020158c4\n\
+_08113C74: .4byte 0x020170c4\n\
+_08113C78: .4byte 0x000008c4\n\
+_08113C7C: .4byte 0x000030c4\n\
+_08113C80: .4byte 0x000038c4\n\
+_08113C84: .4byte 0x000060c4\n\
+_08113C88: .4byte 0x000070c4\n\
+_08113C8C: .4byte 0x000080c4\n\
+_08113C90: .4byte 0x000090c4\n\
+_08113C94: .4byte 0x0000a0c4\n\
+_08113C98: .4byte 0x020188c4\n\
+_08113C9C:\n\
+ movs r0, 0x1\n\
+ ands r0, r6\n\
+ cmp r0, 0\n\
+ beq _08113CAA\n\
+ cmp r0, 0x1\n\
+ beq _08113CB0\n\
+ b _08113CF4\n\
+_08113CAA:\n\
+ ldrb r1, [r2]\n\
+ movs r0, 0xF\n\
+ b _08113CB4\n\
+_08113CB0:\n\
+ ldrb r1, [r2]\n\
+ movs r0, 0xF0\n\
+_08113CB4:\n\
+ ands r0, r1\n\
+ cmp r0, 0\n\
+ beq _08113CF4\n\
+ ldrb r0, [r4]\n\
+ adds r0, r5\n\
+ add r0, r12\n\
+ strb r6, [r0]\n\
+ movs r3, 0x1\n\
+ b _08113CF4\n\
+_08113CC6:\n\
+ adds r0, r6, 0\n\
+ ands r0, r3\n\
+ cmp r0, 0\n\
+ beq _08113CD4\n\
+ cmp r0, 0x1\n\
+ beq _08113CDA\n\
+ b _08113CF4\n\
+_08113CD4:\n\
+ ldrb r1, [r2]\n\
+ movs r0, 0xF\n\
+ b _08113CDE\n\
+_08113CDA:\n\
+ ldrb r1, [r2]\n\
+ movs r0, 0xF0\n\
+_08113CDE:\n\
+ ands r0, r1\n\
+ cmp r0, 0\n\
+ bne _08113CF4\n\
+ ldrb r0, [r4]\n\
+ adds r0, r5\n\
+ add r0, r9\n\
+ strb r7, [r0]\n\
+ ldrb r0, [r4]\n\
+ adds r0, 0x1\n\
+ strb r0, [r4]\n\
+ movs r3, 0\n\
+_08113CF4:\n\
+ adds r0, r6, 0x1\n\
+ movs r1, 0x7\n\
+ ands r0, r1\n\
+ cmp r0, 0\n\
+ bne _08113D02\n\
+ adds r2, 0x1D\n\
+ b _08113D0C\n\
+_08113D02:\n\
+ movs r0, 0x1\n\
+ ands r0, r6\n\
+ cmp r0, 0\n\
+ beq _08113D0C\n\
+ adds r2, 0x1\n\
+_08113D0C:\n\
+ adds r7, 0x1\n\
+ adds r6, 0x1\n\
+ cmp r6, 0x3F\n\
+ ble _08113C4A\n\
+ cmp r3, 0\n\
+ beq _08113D26\n\
+ ldrb r0, [r4]\n\
+ adds r0, r5\n\
+ add r0, r9\n\
+ strb r6, [r0]\n\
+ ldrb r0, [r4]\n\
+ adds r0, 0x1\n\
+ strb r0, [r4]\n\
+_08113D26:\n\
+ movs r0, 0x7\n\
+ ldr r2, [sp, 0x30]\n\
+ ands r2, r0\n\
+ cmp r2, 0\n\
+ bne _08113D36\n\
+ movs r3, 0xE4\n\
+ add r8, r3\n\
+ b _08113D3A\n\
+_08113D36:\n\
+ movs r0, 0x4\n\
+ add r8, r0\n\
+_08113D3A:\n\
+ adds r5, 0x20\n\
+ adds r4, 0x1\n\
+ ldr r1, [sp, 0x8]\n\
+ adds r1, 0x1\n\
+ str r1, [sp, 0x8]\n\
+ cmp r1, 0x3F\n\
+ bgt _08113D4A\n\
+ b _08113C32\n\
+_08113D4A:\n\
+ movs r2, 0\n\
+ mov r8, r2\n\
+ movs r3, 0\n\
+ str r3, [sp, 0x8]\n\
+ ldr r0, _08113D84 @ =0x02014844\n\
+ movs r4, 0x82\n\
+ lsls r4, 6\n\
+ adds r4, r0\n\
+ mov r10, r4\n\
+ movs r5, 0xA2\n\
+ lsls r5, 6\n\
+ adds r7, r0, r5\n\
+ movs r5, 0\n\
+ adds r4, r0, 0\n\
+ movs r0, 0x1\n\
+ mov r9, r0\n\
+_08113D6A:\n\
+ movs r3, 0\n\
+ ldr r2, [sp, 0x4]\n\
+ add r2, r8\n\
+ movs r6, 0\n\
+ ldr r1, [sp, 0x8]\n\
+ adds r1, 0x1\n\
+ str r1, [sp, 0x30]\n\
+_08113D78:\n\
+ cmp r3, 0\n\
+ beq _08113D88\n\
+ cmp r3, 0x1\n\
+ beq _08113DB4\n\
+ b _08113DE4\n\
+ .align 2, 0\n\
+_08113D84: .4byte 0x02014844\n\
+_08113D88:\n\
+ adds r0, r6, 0\n\
+ mov r1, r9\n\
+ ands r0, r1\n\
+ cmp r0, 0\n\
+ beq _08113D98\n\
+ cmp r0, 0x1\n\
+ beq _08113D9E\n\
+ b _08113DE4\n\
+_08113D98:\n\
+ ldrb r1, [r2]\n\
+ movs r0, 0xF\n\
+ b _08113DA2\n\
+_08113D9E:\n\
+ ldrb r1, [r2]\n\
+ movs r0, 0xF0\n\
+_08113DA2:\n\
+ ands r0, r1\n\
+ cmp r0, 0\n\
+ beq _08113DE4\n\
+ ldrb r0, [r4]\n\
+ adds r0, r5\n\
+ add r0, r10\n\
+ strb r6, [r0]\n\
+ movs r3, 0x1\n\
+ b _08113DE4\n\
+_08113DB4:\n\
+ adds r0, r6, 0\n\
+ ands r0, r3\n\
+ cmp r0, 0\n\
+ beq _08113DC2\n\
+ cmp r0, 0x1\n\
+ beq _08113DC8\n\
+ b _08113DE4\n\
+_08113DC2:\n\
+ ldrb r1, [r2]\n\
+ movs r0, 0xF\n\
+ b _08113DCC\n\
+_08113DC8:\n\
+ ldrb r1, [r2]\n\
+ movs r0, 0xF0\n\
+_08113DCC:\n\
+ ands r0, r1\n\
+ cmp r0, 0\n\
+ bne _08113DE4\n\
+ ldrb r0, [r4]\n\
+ adds r0, r5\n\
+ adds r0, r7\n\
+ subs r1, r6, 0x1\n\
+ strb r1, [r0]\n\
+ ldrb r0, [r4]\n\
+ adds r0, 0x1\n\
+ strb r0, [r4]\n\
+ movs r3, 0\n\
+_08113DE4:\n\
+ adds r1, r6, 0x1\n\
+ movs r0, 0x7\n\
+ ands r0, r1\n\
+ cmp r0, 0\n\
+ bne _08113DF2\n\
+ adds r2, 0x1D\n\
+ b _08113DFC\n\
+_08113DF2:\n\
+ mov r0, r9\n\
+ ands r6, r0\n\
+ cmp r6, 0\n\
+ beq _08113DFC\n\
+ adds r2, 0x1\n\
+_08113DFC:\n\
+ adds r6, r1, 0\n\
+ cmp r6, 0x3F\n\
+ ble _08113D78\n\
+ cmp r3, 0\n\
+ beq _08113E14\n\
+ ldrb r0, [r4]\n\
+ adds r0, r5\n\
+ adds r0, r7\n\
+ strb r6, [r0]\n\
+ ldrb r0, [r4]\n\
+ adds r0, 0x1\n\
+ strb r0, [r4]\n\
+_08113E14:\n\
+ movs r0, 0x7\n\
+ ldr r1, [sp, 0x30]\n\
+ ands r1, r0\n\
+ cmp r1, 0\n\
+ bne _08113E24\n\
+ movs r2, 0xE4\n\
+ add r8, r2\n\
+ b _08113E28\n\
+_08113E24:\n\
+ movs r3, 0x4\n\
+ add r8, r3\n\
+_08113E28:\n\
+ adds r5, 0x20\n\
+ adds r4, 0x1\n\
+ ldr r0, [sp, 0x8]\n\
+ adds r0, 0x1\n\
+ str r0, [sp, 0x8]\n\
+ cmp r0, 0x3F\n\
+ ble _08113D6A\n\
+ movs r1, 0\n\
+ str r1, [sp, 0x8]\n\
+_08113E3A:\n\
+ ldr r3, [sp, 0x8]\n\
+ ldr r4, _08113EBC @ =0x02014804\n\
+ adds r2, r3, r4\n\
+ ldr r5, _08113EC0 @ =0x02014844\n\
+ adds r1, r3, r5\n\
+ ldrb r0, [r2]\n\
+ adds r3, 0x1\n\
+ str r3, [sp, 0x30]\n\
+ ldrb r1, [r1]\n\
+ cmp r0, r1\n\
+ bcc _08113E52\n\
+ b _08113F9E\n\
+_08113E52:\n\
+ movs r0, 0\n\
+ str r0, [sp, 0xC]\n\
+ ldrb r2, [r2]\n\
+ cmp r0, r2\n\
+ bge _08113F54\n\
+ ldr r0, _08113EC4 @ =0x02014800\n\
+ adds r0, 0x4\n\
+ ldr r1, [sp, 0x8]\n\
+ adds r0, r1, r0\n\
+ str r0, [sp, 0x18]\n\
+_08113E66:\n\
+ movs r2, 0x80\n\
+ lsls r2, 1\n\
+ str r2, [sp, 0x14]\n\
+ movs r6, 0\n\
+ ldr r3, [sp, 0x8]\n\
+ ldr r4, _08113EC0 @ =0x02014844\n\
+ adds r0, r3, r4\n\
+ ldr r5, [sp, 0xC]\n\
+ adds r5, 0x1\n\
+ str r5, [sp, 0x34]\n\
+ ldrb r0, [r0]\n\
+ cmp r6, r0\n\
+ bge _08113F3E\n\
+ ldr r0, _08113EC4 @ =0x02014800\n\
+ mov r10, r0\n\
+ lsls r0, r3, 5\n\
+ ldr r2, [sp, 0xC]\n\
+ adds r1, r2, r0\n\
+ mov r9, r0\n\
+ ldr r0, _08113EC4 @ =0x02014800\n\
+ adds r0, 0xC4\n\
+ mov r3, r9\n\
+ adds r7, r3, r0\n\
+ mov r5, r9\n\
+ ldr r4, _08113EC4 @ =0x02014800\n\
+ ldr r2, _08113EC8 @ =0x000010c4\n\
+ adds r0, r4, r2\n\
+ adds r1, r0\n\
+ mov r8, r1\n\
+ ldrb r3, [r1]\n\
+ str r3, [sp, 0x1C]\n\
+_08113EA4:\n\
+ ldr r0, _08113ECC @ =0x000020c4\n\
+ add r0, r10\n\
+ adds r0, r5, r0\n\
+ ldr r4, [sp, 0x1C]\n\
+ ldrb r1, [r0]\n\
+ cmp r4, r1\n\
+ bls _08113ED0\n\
+ mov r2, r8\n\
+ ldrb r1, [r2]\n\
+ ldrb r0, [r0]\n\
+ b _08113ED6\n\
+ .align 2, 0\n\
+_08113EBC: .4byte 0x02014804\n\
+_08113EC0: .4byte 0x02014844\n\
+_08113EC4: .4byte 0x02014800\n\
+_08113EC8: .4byte 0x000010c4\n\
+_08113ECC: .4byte 0x000020c4\n\
+_08113ED0:\n\
+ ldrb r1, [r0]\n\
+ mov r3, r8\n\
+ ldrb r0, [r3]\n\
+_08113ED6:\n\
+ subs r3, r1, r0\n\
+ ldr r1, [sp, 0xC]\n\
+ add r1, r9\n\
+ ldr r0, _08113EFC @ =0x000018c4\n\
+ add r0, r10\n\
+ adds r4, r1, r0\n\
+ ldr r0, _08113F00 @ =0x000028c4\n\
+ add r0, r10\n\
+ adds r2, r5, r0\n\
+ ldrb r0, [r4]\n\
+ ldr r1, _08113F04 @ =0x02014800\n\
+ mov r12, r1\n\
+ ldrb r1, [r2]\n\
+ cmp r0, r1\n\
+ bls _08113F08\n\
+ adds r1, r0, 0\n\
+ ldrb r0, [r2]\n\
+ b _08113F0C\n\
+ .align 2, 0\n\
+_08113EFC: .4byte 0x000018c4\n\
+_08113F00: .4byte 0x000028c4\n\
+_08113F04: .4byte 0x02014800\n\
+_08113F08:\n\
+ ldrb r1, [r2]\n\
+ ldrb r0, [r4]\n\
+_08113F0C:\n\
+ subs r1, r0\n\
+ adds r3, r1\n\
+ ldr r2, [sp, 0x14]\n\
+ cmp r2, r3\n\
+ ble _08113F2C\n\
+ ldrb r0, [r7]\n\
+ cmp r0, 0\n\
+ bne _08113F2C\n\
+ ldr r0, _08114050 @ =0x000008c4\n\
+ add r0, r12\n\
+ adds r0, r5, r0\n\
+ ldrb r0, [r0]\n\
+ cmp r0, 0\n\
+ bne _08113F2C\n\
+ str r6, [sp, 0x10]\n\
+ str r3, [sp, 0x14]\n\
+_08113F2C:\n\
+ adds r7, 0x1\n\
+ adds r5, 0x1\n\
+ adds r6, 0x1\n\
+ ldr r3, [sp, 0x8]\n\
+ ldr r4, _08114054 @ =0x02014844\n\
+ adds r0, r3, r4\n\
+ ldrb r0, [r0]\n\
+ cmp r6, r0\n\
+ blt _08113EA4\n\
+_08113F3E:\n\
+ ldr r0, [sp, 0xC]\n\
+ ldr r1, [sp, 0x10]\n\
+ ldr r2, [sp, 0x8]\n\
+ bl sub_81141F0\n\
+ ldr r5, [sp, 0x34]\n\
+ str r5, [sp, 0xC]\n\
+ ldr r0, [sp, 0x18]\n\
+ ldrb r0, [r0]\n\
+ cmp r5, r0\n\
+ blt _08113E66\n\
+_08113F54:\n\
+ movs r6, 0\n\
+ ldr r2, _08114058 @ =0x02014800\n\
+ ldr r1, [sp, 0x8]\n\
+ ldr r3, _08114054 @ =0x02014844\n\
+ adds r0, r1, r3\n\
+ adds r4, r2, 0\n\
+ mov r12, r4\n\
+ ldrb r0, [r0]\n\
+ cmp r6, r0\n\
+ bge _08113F9E\n\
+ mov r0, r12\n\
+ adds r0, 0x44\n\
+ adds r4, r1, r0\n\
+_08113F6E:\n\
+ ldr r5, [sp, 0x8]\n\
+ lsls r0, r5, 5\n\
+ adds r1, r6, r0\n\
+ adds r0, r2, 0\n\
+ adds r0, 0xC4\n\
+ adds r0, r1, r0\n\
+ ldrb r0, [r0]\n\
+ cmp r0, 0\n\
+ bne _08113F94\n\
+ ldr r3, _08114050 @ =0x000008c4\n\
+ adds r0, r2, r3\n\
+ adds r0, r1, r0\n\
+ ldrb r0, [r0]\n\
+ cmp r0, 0\n\
+ bne _08113F94\n\
+ adds r0, r6, 0\n\
+ adds r1, r5, 0\n\
+ bl sub_811430C\n\
+_08113F94:\n\
+ adds r6, 0x1\n\
+ ldr r2, _08114058 @ =0x02014800\n\
+ ldrb r5, [r4]\n\
+ cmp r6, r5\n\
+ blt _08113F6E\n\
+_08113F9E:\n\
+ ldr r0, [sp, 0x8]\n\
+ ldr r1, _0811405C @ =0x02014804\n\
+ adds r2, r0, r1\n\
+ ldr r3, _08114054 @ =0x02014844\n\
+ adds r1, r0, r3\n\
+ ldrb r0, [r2]\n\
+ ldrb r1, [r1]\n\
+ cmp r0, r1\n\
+ bne _08113FCC\n\
+ movs r6, 0\n\
+ ldrb r4, [r2]\n\
+ cmp r6, r4\n\
+ bge _08113FCC\n\
+ adds r4, r2, 0\n\
+_08113FBA:\n\
+ adds r0, r6, 0\n\
+ adds r1, r6, 0\n\
+ ldr r2, [sp, 0x8]\n\
+ bl sub_81141F0\n\
+ adds r6, 0x1\n\
+ ldrb r5, [r4]\n\
+ cmp r6, r5\n\
+ blt _08113FBA\n\
+_08113FCC:\n\
+ ldr r0, [sp, 0x8]\n\
+ ldr r1, _0811405C @ =0x02014804\n\
+ adds r2, r0, r1\n\
+ ldr r3, _08114054 @ =0x02014844\n\
+ adds r1, r0, r3\n\
+ ldrb r0, [r2]\n\
+ ldr r4, _08114058 @ =0x02014800\n\
+ ldrb r5, [r1]\n\
+ cmp r0, r5\n\
+ bhi _08113FE2\n\
+ b _081141C4\n\
+_08113FE2:\n\
+ movs r0, 0\n\
+ str r0, [sp, 0x10]\n\
+ ldrb r1, [r1]\n\
+ cmp r0, r1\n\
+ blt _08113FEE\n\
+ b _08114104\n\
+_08113FEE:\n\
+ str r2, [sp, 0x2C]\n\
+ ldr r1, [sp, 0x8]\n\
+ lsls r1, 5\n\
+ mov r9, r1\n\
+ adds r0, r4, 0\n\
+ adds r0, 0x44\n\
+ ldr r2, [sp, 0x8]\n\
+ adds r0, r2, r0\n\
+ str r0, [sp, 0x20]\n\
+ mov r3, r9\n\
+ str r3, [sp, 0x24]\n\
+_08114004:\n\
+ movs r4, 0x80\n\
+ lsls r4, 1\n\
+ str r4, [sp, 0x14]\n\
+ movs r6, 0\n\
+ ldr r5, [sp, 0x10]\n\
+ adds r5, 0x1\n\
+ str r5, [sp, 0x38]\n\
+ ldr r0, [sp, 0x2C]\n\
+ ldrb r0, [r0]\n\
+ cmp r6, r0\n\
+ bge _081140C4\n\
+ ldr r1, [sp, 0x10]\n\
+ ldr r2, [sp, 0x24]\n\
+ adds r1, r2\n\
+ mov r10, r1\n\
+ ldr r0, _08114058 @ =0x02014800\n\
+ adds r0, 0xC4\n\
+ adds r2, r0\n\
+ mov r8, r2\n\
+ ldr r7, [sp, 0x24]\n\
+ ldr r3, _08114058 @ =0x02014800\n\
+ ldr r4, _08114060 @ =0x000010c4\n\
+ adds r0, r3, r4\n\
+ adds r5, r7, r0\n\
+ ldr r0, _08114064 @ =0x020168c4\n\
+ add r0, r10\n\
+ mov r12, r0\n\
+ ldrb r1, [r0]\n\
+ str r1, [sp, 0x28]\n\
+_0811403E:\n\
+ ldrb r0, [r5]\n\
+ ldr r2, [sp, 0x28]\n\
+ cmp r0, r2\n\
+ bls _08114068\n\
+ adds r1, r0, 0\n\
+ mov r3, r12\n\
+ ldrb r0, [r3]\n\
+ b _0811406E\n\
+ .align 2, 0\n\
+_08114050: .4byte 0x000008c4\n\
+_08114054: .4byte 0x02014844\n\
+_08114058: .4byte 0x02014800\n\
+_0811405C: .4byte 0x02014804\n\
+_08114060: .4byte 0x000010c4\n\
+_08114064: .4byte 0x020168c4\n\
+_08114068:\n\
+ mov r4, r12\n\
+ ldrb r1, [r4]\n\
+ ldrb r0, [r5]\n\
+_0811406E:\n\
+ subs r3, r1, r0\n\
+ ldr r1, _0811408C @ =0x02014800\n\
+ ldr r2, _08114090 @ =0x000018c4\n\
+ adds r0, r1, r2\n\
+ adds r4, r7, r0\n\
+ ldr r2, _08114094 @ =0x020170c4\n\
+ add r2, r10\n\
+ ldrb r0, [r4]\n\
+ ldrb r1, [r2]\n\
+ cmp r0, r1\n\
+ bls _08114098\n\
+ adds r1, r0, 0\n\
+ ldrb r0, [r2]\n\
+ b _0811409C\n\
+ .align 2, 0\n\
+_0811408C: .4byte 0x02014800\n\
+_08114090: .4byte 0x000018c4\n\
+_08114094: .4byte 0x020170c4\n\
+_08114098:\n\
+ ldrb r1, [r2]\n\
+ ldrb r0, [r4]\n\
+_0811409C:\n\
+ subs r1, r0\n\
+ adds r3, r1\n\
+ ldr r2, [sp, 0x14]\n\
+ cmp r2, r3\n\
+ ble _081140B2\n\
+ mov r4, r8\n\
+ ldrb r0, [r4]\n\
+ cmp r0, 0\n\
+ bne _081140B2\n\
+ str r6, [sp, 0xC]\n\
+ str r3, [sp, 0x14]\n\
+_081140B2:\n\
+ movs r0, 0x1\n\
+ add r8, r0\n\
+ adds r7, 0x1\n\
+ adds r5, 0x1\n\
+ adds r6, 0x1\n\
+ ldr r1, [sp, 0x2C]\n\
+ ldrb r1, [r1]\n\
+ cmp r6, r1\n\
+ blt _0811403E\n\
+_081140C4:\n\
+ ldr r3, [sp, 0xC]\n\
+ add r3, r9\n\
+ ldr r2, _08114164 @ =0x02014800\n\
+ ldr r4, _08114168 @ =0x000030c4\n\
+ adds r1, r2, r4\n\
+ adds r1, r3, r1\n\
+ ldr r2, [sp, 0x10]\n\
+ add r2, r9\n\
+ ldr r5, _0811416C @ =0x020168c4\n\
+ adds r0, r2, r5\n\
+ ldrb r0, [r0]\n\
+ strb r0, [r1]\n\
+ ldr r0, _08114164 @ =0x02014800\n\
+ ldr r4, _08114170 @ =0x000038c4\n\
+ adds r1, r0, r4\n\
+ adds r1, r3, r1\n\
+ ldr r5, _08114174 @ =0x020170c4\n\
+ adds r2, r5\n\
+ ldrb r0, [r2]\n\
+ strb r0, [r1]\n\
+ ldr r0, _08114164 @ =0x02014800\n\
+ adds r0, 0xC4\n\
+ adds r3, r0\n\
+ movs r0, 0x1\n\
+ strb r0, [r3]\n\
+ ldr r0, [sp, 0x38]\n\
+ str r0, [sp, 0x10]\n\
+ ldr r1, [sp, 0x20]\n\
+ ldrb r1, [r1]\n\
+ cmp r0, r1\n\
+ bge _08114104\n\
+ b _08114004\n\
+_08114104:\n\
+ movs r6, 0\n\
+ ldr r4, _08114164 @ =0x02014800\n\
+ ldr r2, [sp, 0x8]\n\
+ ldr r3, _08114178 @ =0x02014804\n\
+ adds r0, r2, r3\n\
+ ldrb r0, [r0]\n\
+ cmp r6, r0\n\
+ bge _081141C4\n\
+ adds r7, r4, 0\n\
+ mov r9, r6\n\
+ movs r5, 0xC4\n\
+ adds r5, r7\n\
+ mov r8, r5\n\
+_0811411E:\n\
+ ldr r1, [sp, 0x8]\n\
+ lsls r0, r1, 5\n\
+ adds r2, r6, r0\n\
+ ldr r3, _0811417C @ =0x000020c4\n\
+ adds r0, r7, r3\n\
+ adds r0, r2\n\
+ mov r10, r0\n\
+ ldr r5, _08114168 @ =0x000030c4\n\
+ adds r0, r7, r5\n\
+ adds r0, r2, r0\n\
+ ldrb r0, [r0]\n\
+ mov r1, r10\n\
+ strb r0, [r1]\n\
+ ldr r3, _08114180 @ =0x000028c4\n\
+ adds r0, r7, r3\n\
+ adds r3, r2, r0\n\
+ ldr r5, _08114170 @ =0x000038c4\n\
+ adds r0, r7, r5\n\
+ adds r0, r2, r0\n\
+ ldrb r0, [r0]\n\
+ strb r0, [r3]\n\
+ mov r0, r8\n\
+ adds r1, r2, r0\n\
+ ldrb r0, [r1]\n\
+ cmp r0, 0\n\
+ beq _08114184\n\
+ mov r2, r9\n\
+ strb r2, [r1]\n\
+ adds r0, r6, 0\n\
+ adds r1, r6, 0\n\
+ ldr r2, [sp, 0x8]\n\
+ bl sub_81141F0\n\
+ b _081141B4\n\
+ .align 2, 0\n\
+_08114164: .4byte 0x02014800\n\
+_08114168: .4byte 0x000030c4\n\
+_0811416C: .4byte 0x020168c4\n\
+_08114170: .4byte 0x000038c4\n\
+_08114174: .4byte 0x020170c4\n\
+_08114178: .4byte 0x02014804\n\
+_0811417C: .4byte 0x000020c4\n\
+_08114180: .4byte 0x000028c4\n\
+_08114184:\n\
+ ldr r5, _081141E0 @ =0x000010c4\n\
+ adds r1, r4, r5\n\
+ adds r1, r2, r1\n\
+ ldr r5, _081141E4 @ =0x000018c4\n\
+ adds r0, r4, r5\n\
+ adds r0, r2, r0\n\
+ ldrb r0, [r0]\n\
+ ldrb r2, [r1]\n\
+ subs r0, r2\n\
+ lsrs r1, r0, 31\n\
+ adds r0, r1\n\
+ asrs r0, 1\n\
+ adds r2, r0\n\
+ strb r2, [r3]\n\
+ mov r0, r10\n\
+ strb r2, [r0]\n\
+ ldrb r0, [r3]\n\
+ subs r0, 0x1\n\
+ strb r0, [r3]\n\
+ adds r0, r6, 0\n\
+ adds r1, r6, 0\n\
+ ldr r2, [sp, 0x8]\n\
+ bl sub_81141F0\n\
+_081141B4:\n\
+ adds r6, 0x1\n\
+ ldr r4, _081141E8 @ =0x02014800\n\
+ ldr r1, [sp, 0x8]\n\
+ ldr r2, _081141EC @ =0x02014804\n\
+ adds r0, r1, r2\n\
+ ldrb r0, [r0]\n\
+ cmp r6, r0\n\
+ blt _0811411E\n\
+_081141C4:\n\
+ ldr r3, [sp, 0x30]\n\
+ str r3, [sp, 0x8]\n\
+ cmp r3, 0x3F\n\
+ bgt _081141CE\n\
+ b _08113E3A\n\
+_081141CE:\n\
+ add sp, 0x3C\n\
+ pop {r3-r5}\n\
+ mov r8, r3\n\
+ mov r9, r4\n\
+ mov r10, r5\n\
+ pop {r4-r7}\n\
+ pop {r0}\n\
+ bx r0\n\
+ .align 2, 0\n\
+_081141E0: .4byte 0x000010c4\n\
+_081141E4: .4byte 0x000018c4\n\
+_081141E8: .4byte 0x02014800\n\
+_081141EC: .4byte 0x02014804\n\
+ .syntax divided");
+}
+
+void sub_81141F0(s32 a, s32 b, s32 c)
+{
+ u32 r7;
+
+ sEvoInfo.unk30C4[c][b] = sEvoInfo.unk10C4[c][a];
+ sEvoInfo.unk38C4[c][b] = sEvoInfo.unk18C4[c][a];
+
+ r7 = 0;
+ if (sEvoInfo.unk10C4[c][a] < sEvoInfo.unk20C4[c][b])
+ {
+ sEvoInfo.unkC4[c][b] = 4;
+ r7 = sEvoInfo.unk20C4[c][b] - sEvoInfo.unk10C4[c][a];
+ }
+ else if (sEvoInfo.unk10C4[c][a] > sEvoInfo.unk20C4[c][b])
+ {
+ sEvoInfo.unkC4[c][b] = 1;
+ r7 = sEvoInfo.unk10C4[c][a] - sEvoInfo.unk20C4[c][b];
+ }
+ sEvoInfo.unk80C4[c][b] = r7 * 16;
+
+ r7 = 0;
+ if (sEvoInfo.unk18C4[c][a] < sEvoInfo.unk28C4[c][b])
+ {
+ sEvoInfo.unk8C4[c][b] = 3;
+ r7 = sEvoInfo.unk28C4[c][b] - sEvoInfo.unk18C4[c][a];
+ }
+ else if (sEvoInfo.unk18C4[c][a] > sEvoInfo.unk28C4[c][b])
+ {
+ sEvoInfo.unk8C4[c][b] = 2;
+ r7 = sEvoInfo.unk18C4[c][a] - sEvoInfo.unk28C4[c][b];
+ }
+ sEvoInfo.unk90C4[c][b] = r7 * 16;
+
+ sEvoInfo.unk84[c]++;
+}
+
+void sub_811430C(u32 a, u32 b)
+{
+ u8 r2 = sEvoInfo.unk28C4[b][a];
+ u8 r3 = sEvoInfo.unk20C4[b][a];
+ s32 r7 = r2 - r3;
+
+ sEvoInfo.unk30C4[b][a] = sEvoInfo.unk38C4[b][a] = r3 + r7 / 2;
+ sEvoInfo.unkC4[b][a] = 5;
+ sEvoInfo.unk8C4[b][a] = 7;
+ sEvoInfo.unk84[b]++;
+ r7 = sEvoInfo.unk30C4[b][a] - sEvoInfo.unk20C4[b][a];
+ sEvoInfo.unk80C4[b][a] = r7 * 16;
+ r7 = sEvoInfo.unk28C4[b][a] - sEvoInfo.unk38C4[b][a];
+ sEvoInfo.unk90C4[b][a] = r7 * 16;
+}
+
+__attribute__((naked))
+void unref_sub_81143CC()
+{
+ asm(".syntax unified\n\
+ push {r4-r7,lr}\n\
+ mov r7, r10\n\
+ mov r6, r9\n\
+ mov r5, r8\n\
+ push {r5-r7}\n\
+ sub sp, 0x14\n\
+ movs r0, 0x1\n\
+ str r0, [sp, 0x4]\n\
+ ldr r0, _08114408 @ =0x02014800\n\
+ ldr r2, _0811440C @ =0x0000a0c4\n\
+ adds r1, r0, r2\n\
+ ldrb r3, [r1]\n\
+ adds r4, r0, 0\n\
+ cmp r3, 0\n\
+ beq _081143EE\n\
+ subs r0, r3, 0x1\n\
+ strb r0, [r1]\n\
+_081143EE:\n\
+ movs r5, 0\n\
+ str r5, [sp]\n\
+_081143F2:\n\
+ movs r3, 0\n\
+ adds r2, r4, 0\n\
+ adds r0, r4, 0\n\
+ adds r0, 0x84\n\
+ ldr r1, [sp]\n\
+ adds r0, r1, r0\n\
+ adds r1, 0x1\n\
+ str r1, [sp, 0x8]\n\
+ bl _08114D84\n\
+ .align 2, 0\n\
+_08114408: .4byte 0x02014800\n\
+_0811440C: .4byte 0x0000a0c4\n\
+_08114410:\n\
+ ldr r5, [sp]\n\
+ lsls r0, r5, 5\n\
+ adds r1, r3, r0\n\
+ adds r2, 0xC4\n\
+ adds r1, r2\n\
+ ldrb r2, [r1]\n\
+ mov r8, r0\n\
+ adds r0, r3, 0x1\n\
+ mov r10, r0\n\
+ cmp r2, 0xC\n\
+ bls _08114428\n\
+ b _081148D2\n\
+_08114428:\n\
+ lsls r0, r2, 2\n\
+ ldr r1, _08114434 @ =_08114438\n\
+ adds r0, r1\n\
+ ldr r0, [r0]\n\
+ mov pc, r0\n\
+ .align 2, 0\n\
+_08114434: .4byte _08114438\n\
+ .align 2, 0\n\
+_08114438:\n\
+ .4byte _081148D2\n\
+ .4byte _0811446C\n\
+ .4byte _081144F0\n\
+ .4byte _0811457C\n\
+ .4byte _08114600\n\
+ .4byte _0811468C\n\
+ .4byte _081146C8\n\
+ .4byte _08114704\n\
+ .4byte _08114740\n\
+ .4byte _0811477C\n\
+ .4byte _081147D0\n\
+ .4byte _08114810\n\
+ .4byte _08114858\n\
+_0811446C:\n\
+ movs r1, 0\n\
+ str r1, [sp, 0x4]\n\
+ lsls r0, r3, 1\n\
+ ldr r2, [sp]\n\
+ lsls r1, r2, 6\n\
+ adds r0, r1\n\
+ ldr r5, _081144E0 @ =0x000060c4\n\
+ adds r2, r4, r5\n\
+ adds r2, r0, r2\n\
+ ldr r5, _081144E4 @ =0x000080c4\n\
+ adds r1, r4, r5\n\
+ adds r0, r1\n\
+ ldrh r1, [r0]\n\
+ ldrh r0, [r2]\n\
+ adds r1, r0\n\
+ movs r0, 0xFF\n\
+ lsls r0, 8\n\
+ ands r0, r1\n\
+ lsrs r5, r0, 8\n\
+ movs r0, 0xFF\n\
+ ands r1, r0\n\
+ strh r1, [r2]\n\
+ movs r6, 0\n\
+ adds r1, r3, 0x1\n\
+ mov r10, r1\n\
+ ldr r2, [sp, 0x4]\n\
+ cmp r2, r5\n\
+ blt _081144A6\n\
+ b _081148D2\n\
+_081144A6:\n\
+ mov r9, r4\n\
+ mov r4, r8\n\
+ adds r7, r3, r4\n\
+ ldr r0, _081144E8 @ =0x000030c4\n\
+ add r0, r9\n\
+ adds r4, r7, r0\n\
+ ldr r0, _081144EC @ =0x000020c4\n\
+ add r0, r9\n\
+ adds r2, r7, r0\n\
+_081144B8:\n\
+ ldrb r0, [r4]\n\
+ subs r0, 0x1\n\
+ strb r0, [r4]\n\
+ ldrb r1, [r4]\n\
+ ldr r0, [sp]\n\
+ str r2, [sp, 0xC]\n\
+ str r3, [sp, 0x10]\n\
+ bl sub_8114DB4\n\
+ ldrb r0, [r4]\n\
+ ldr r2, [sp, 0xC]\n\
+ ldr r3, [sp, 0x10]\n\
+ ldrb r1, [r2]\n\
+ cmp r0, r1\n\
+ bne _081144D8\n\
+ b _081148A0\n\
+_081144D8:\n\
+ adds r6, 0x1\n\
+ cmp r6, r5\n\
+ blt _081144B8\n\
+ b _081148D2\n\
+ .align 2, 0\n\
+_081144E0: .4byte 0x000060c4\n\
+_081144E4: .4byte 0x000080c4\n\
+_081144E8: .4byte 0x000030c4\n\
+_081144EC: .4byte 0x000020c4\n\
+_081144F0:\n\
+ movs r2, 0\n\
+ str r2, [sp, 0x4]\n\
+ ldr r4, _08114568 @ =0x02014800\n\
+ lsls r0, r3, 1\n\
+ ldr r5, [sp]\n\
+ lsls r1, r5, 6\n\
+ adds r0, r1\n\
+ ldr r1, _0811456C @ =0x000060c4\n\
+ adds r2, r4, r1\n\
+ adds r2, r0, r2\n\
+ ldr r5, _08114570 @ =0x000080c4\n\
+ adds r1, r4, r5\n\
+ adds r0, r1\n\
+ ldrh r1, [r0]\n\
+ ldrh r0, [r2]\n\
+ adds r1, r0\n\
+ movs r0, 0xFF\n\
+ lsls r0, 8\n\
+ ands r0, r1\n\
+ lsrs r5, r0, 8\n\
+ movs r0, 0xFF\n\
+ ands r1, r0\n\
+ strh r1, [r2]\n\
+ movs r6, 0\n\
+ adds r1, r3, 0x1\n\
+ mov r10, r1\n\
+ ldr r2, [sp, 0x4]\n\
+ cmp r2, r5\n\
+ blt _0811452C\n\
+ b _081148D2\n\
+_0811452C:\n\
+ mov r9, r4\n\
+ mov r4, r8\n\
+ adds r7, r3, r4\n\
+ ldr r0, _08114574 @ =0x000030c4\n\
+ add r0, r9\n\
+ adds r4, r7, r0\n\
+ ldr r0, _08114578 @ =0x000020c4\n\
+ add r0, r9\n\
+ adds r2, r7, r0\n\
+_0811453E:\n\
+ ldrb r0, [r4]\n\
+ ldrb r1, [r2]\n\
+ cmp r0, r1\n\
+ bne _08114548\n\
+ b _081148B8\n\
+_08114548:\n\
+ adds r1, r0, 0\n\
+ ldr r0, [sp]\n\
+ str r2, [sp, 0xC]\n\
+ str r3, [sp, 0x10]\n\
+ bl sub_8114DF0\n\
+ ldrb r0, [r4]\n\
+ subs r0, 0x1\n\
+ strb r0, [r4]\n\
+ adds r6, 0x1\n\
+ ldr r2, [sp, 0xC]\n\
+ ldr r3, [sp, 0x10]\n\
+ cmp r6, r5\n\
+ blt _0811453E\n\
+ b _081148D2\n\
+ .align 2, 0\n\
+_08114568: .4byte 0x02014800\n\
+_0811456C: .4byte 0x000060c4\n\
+_08114570: .4byte 0x000080c4\n\
+_08114574: .4byte 0x000030c4\n\
+_08114578: .4byte 0x000020c4\n\
+_0811457C:\n\
+ movs r2, 0\n\
+ str r2, [sp, 0x4]\n\
+ lsls r0, r3, 1\n\
+ ldr r5, [sp]\n\
+ lsls r1, r5, 6\n\
+ adds r0, r1\n\
+ ldr r1, _081145F0 @ =0x000060c4\n\
+ adds r2, r4, r1\n\
+ adds r2, r0, r2\n\
+ ldr r5, _081145F4 @ =0x000080c4\n\
+ adds r1, r4, r5\n\
+ adds r0, r1\n\
+ ldrh r1, [r0]\n\
+ ldrh r0, [r2]\n\
+ adds r1, r0\n\
+ movs r0, 0xFF\n\
+ lsls r0, 8\n\
+ ands r0, r1\n\
+ lsrs r5, r0, 8\n\
+ movs r0, 0xFF\n\
+ ands r1, r0\n\
+ strh r1, [r2]\n\
+ movs r6, 0\n\
+ adds r1, r3, 0x1\n\
+ mov r10, r1\n\
+ ldr r2, [sp, 0x4]\n\
+ cmp r2, r5\n\
+ blt _081145B6\n\
+ b _081148D2\n\
+_081145B6:\n\
+ mov r9, r4\n\
+ mov r4, r8\n\
+ adds r7, r3, r4\n\
+ ldr r0, _081145F8 @ =0x000030c4\n\
+ add r0, r9\n\
+ adds r4, r7, r0\n\
+ ldr r0, _081145FC @ =0x000020c4\n\
+ add r0, r9\n\
+ adds r2, r7, r0\n\
+_081145C8:\n\
+ ldrb r0, [r4]\n\
+ adds r0, 0x1\n\
+ strb r0, [r4]\n\
+ ldrb r1, [r4]\n\
+ ldr r0, [sp]\n\
+ str r2, [sp, 0xC]\n\
+ str r3, [sp, 0x10]\n\
+ bl sub_8114DB4\n\
+ ldrb r0, [r4]\n\
+ ldr r2, [sp, 0xC]\n\
+ ldr r3, [sp, 0x10]\n\
+ ldrb r1, [r2]\n\
+ cmp r0, r1\n\
+ bne _081145E8\n\
+ b _081148AC\n\
+_081145E8:\n\
+ adds r6, 0x1\n\
+ cmp r6, r5\n\
+ blt _081145C8\n\
+ b _081148D2\n\
+ .align 2, 0\n\
+_081145F0: .4byte 0x000060c4\n\
+_081145F4: .4byte 0x000080c4\n\
+_081145F8: .4byte 0x000030c4\n\
+_081145FC: .4byte 0x000020c4\n\
+_08114600:\n\
+ movs r2, 0\n\
+ str r2, [sp, 0x4]\n\
+ ldr r4, _08114678 @ =0x02014800\n\
+ lsls r0, r3, 1\n\
+ ldr r5, [sp]\n\
+ lsls r1, r5, 6\n\
+ adds r0, r1\n\
+ ldr r1, _0811467C @ =0x000060c4\n\
+ adds r2, r4, r1\n\
+ adds r2, r0, r2\n\
+ ldr r5, _08114680 @ =0x000080c4\n\
+ adds r1, r4, r5\n\
+ adds r0, r1\n\
+ ldrh r1, [r0]\n\
+ ldrh r0, [r2]\n\
+ adds r1, r0\n\
+ movs r0, 0xFF\n\
+ lsls r0, 8\n\
+ ands r0, r1\n\
+ lsrs r5, r0, 8\n\
+ movs r0, 0xFF\n\
+ ands r1, r0\n\
+ strh r1, [r2]\n\
+ movs r6, 0\n\
+ adds r1, r3, 0x1\n\
+ mov r10, r1\n\
+ ldr r2, [sp, 0x4]\n\
+ cmp r2, r5\n\
+ blt _0811463C\n\
+ b _081148D2\n\
+_0811463C:\n\
+ mov r9, r4\n\
+ mov r4, r8\n\
+ adds r7, r3, r4\n\
+ ldr r0, _08114684 @ =0x000030c4\n\
+ add r0, r9\n\
+ adds r4, r7, r0\n\
+ ldr r0, _08114688 @ =0x000020c4\n\
+ add r0, r9\n\
+ adds r2, r7, r0\n\
+_0811464E:\n\
+ ldrb r0, [r4]\n\
+ ldrb r1, [r2]\n\
+ cmp r0, r1\n\
+ bne _08114658\n\
+ b _081148B8\n\
+_08114658:\n\
+ adds r1, r0, 0\n\
+ ldr r0, [sp]\n\
+ str r2, [sp, 0xC]\n\
+ str r3, [sp, 0x10]\n\
+ bl sub_8114DF0\n\
+ ldrb r0, [r4]\n\
+ adds r0, 0x1\n\
+ strb r0, [r4]\n\
+ adds r6, 0x1\n\
+ ldr r2, [sp, 0xC]\n\
+ ldr r3, [sp, 0x10]\n\
+ cmp r6, r5\n\
+ blt _0811464E\n\
+ b _081148D2\n\
+ .align 2, 0\n\
+_08114678: .4byte 0x02014800\n\
+_0811467C: .4byte 0x000060c4\n\
+_08114680: .4byte 0x000080c4\n\
+_08114684: .4byte 0x000030c4\n\
+_08114688: .4byte 0x000020c4\n\
+_0811468C:\n\
+ movs r2, 0\n\
+ str r2, [sp, 0x4]\n\
+ ldr r5, _081146C0 @ =0x02014800\n\
+ mov r0, r8\n\
+ adds r4, r3, r0\n\
+ ldr r1, _081146C4 @ =0x000030c4\n\
+ adds r0, r5, r1\n\
+ adds r0, r4, r0\n\
+ ldrb r1, [r0]\n\
+ ldr r0, [sp]\n\
+ str r3, [sp, 0x10]\n\
+ bl sub_8114E48\n\
+ lsls r0, 24\n\
+ ldr r3, [sp, 0x10]\n\
+ adds r2, r3, 0x1\n\
+ mov r10, r2\n\
+ cmp r0, 0\n\
+ bne _081146B4\n\
+ b _081148D2\n\
+_081146B4:\n\
+ adds r0, r5, 0\n\
+ adds r0, 0xC4\n\
+ adds r0, r4, r0\n\
+ movs r1, 0x9\n\
+ strb r1, [r0]\n\
+ b _081148D2\n\
+ .align 2, 0\n\
+_081146C0: .4byte 0x02014800\n\
+_081146C4: .4byte 0x000030c4\n\
+_081146C8:\n\
+ movs r4, 0\n\
+ str r4, [sp, 0x4]\n\
+ ldr r5, _081146FC @ =0x02014800\n\
+ mov r0, r8\n\
+ adds r4, r3, r0\n\
+ ldr r1, _08114700 @ =0x000030c4\n\
+ adds r0, r5, r1\n\
+ adds r0, r4, r0\n\
+ ldrb r1, [r0]\n\
+ ldr r0, [sp]\n\
+ str r3, [sp, 0x10]\n\
+ bl sub_8114E48\n\
+ lsls r0, 24\n\
+ ldr r3, [sp, 0x10]\n\
+ adds r2, r3, 0x1\n\
+ mov r10, r2\n\
+ cmp r0, 0\n\
+ bne _081146F0\n\
+ b _081148D2\n\
+_081146F0:\n\
+ adds r0, r5, 0\n\
+ adds r0, 0xC4\n\
+ adds r0, r4, r0\n\
+ movs r1, 0xA\n\
+ strb r1, [r0]\n\
+ b _081148D2\n\
+ .align 2, 0\n\
+_081146FC: .4byte 0x02014800\n\
+_08114700: .4byte 0x000030c4\n\
+_08114704:\n\
+ movs r4, 0\n\
+ str r4, [sp, 0x4]\n\
+ ldr r5, _08114738 @ =0x02014800\n\
+ mov r0, r8\n\
+ adds r4, r3, r0\n\
+ ldr r1, _0811473C @ =0x000030c4\n\
+ adds r0, r5, r1\n\
+ adds r0, r4, r0\n\
+ ldrb r1, [r0]\n\
+ ldr r0, [sp]\n\
+ str r3, [sp, 0x10]\n\
+ bl sub_8114E48\n\
+ lsls r0, 24\n\
+ ldr r3, [sp, 0x10]\n\
+ adds r2, r3, 0x1\n\
+ mov r10, r2\n\
+ cmp r0, 0\n\
+ bne _0811472C\n\
+ b _081148D2\n\
+_0811472C:\n\
+ adds r0, r5, 0\n\
+ adds r0, 0xC4\n\
+ adds r0, r4, r0\n\
+ movs r1, 0xB\n\
+ strb r1, [r0]\n\
+ b _081148D2\n\
+ .align 2, 0\n\
+_08114738: .4byte 0x02014800\n\
+_0811473C: .4byte 0x000030c4\n\
+_08114740:\n\
+ movs r4, 0\n\
+ str r4, [sp, 0x4]\n\
+ ldr r5, _08114774 @ =0x02014800\n\
+ mov r0, r8\n\
+ adds r4, r3, r0\n\
+ ldr r1, _08114778 @ =0x000030c4\n\
+ adds r0, r5, r1\n\
+ adds r0, r4, r0\n\
+ ldrb r1, [r0]\n\
+ ldr r0, [sp]\n\
+ str r3, [sp, 0x10]\n\
+ bl sub_8114E48\n\
+ lsls r0, 24\n\
+ ldr r3, [sp, 0x10]\n\
+ adds r2, r3, 0x1\n\
+ mov r10, r2\n\
+ cmp r0, 0\n\
+ bne _08114768\n\
+ b _081148D2\n\
+_08114768:\n\
+ adds r0, r5, 0\n\
+ adds r0, 0xC4\n\
+ adds r0, r4, r0\n\
+ movs r1, 0xC\n\
+ strb r1, [r0]\n\
+ b _081148D2\n\
+ .align 2, 0\n\
+_08114774: .4byte 0x02014800\n\
+_08114778: .4byte 0x000030c4\n\
+_0811477C:\n\
+ movs r4, 0\n\
+ str r4, [sp, 0x4]\n\
+ ldr r6, _081147B4 @ =0x02014800\n\
+ mov r0, r8\n\
+ adds r5, r3, r0\n\
+ ldr r1, _081147B8 @ =0x000030c4\n\
+ adds r4, r6, r1\n\
+ adds r4, r5, r4\n\
+ ldrb r1, [r4]\n\
+ ldr r0, [sp]\n\
+ str r3, [sp, 0x10]\n\
+ bl sub_8114DB4\n\
+ ldr r2, _081147BC @ =0x000020c4\n\
+ adds r0, r6, r2\n\
+ adds r0, r5, r0\n\
+ ldrb r1, [r4]\n\
+ ldr r3, [sp, 0x10]\n\
+ ldrb r0, [r0]\n\
+ cmp r1, r0\n\
+ bne _081147C0\n\
+ adds r0, r6, 0\n\
+ adds r0, 0xC4\n\
+ adds r0, r5, r0\n\
+ mov r4, sp\n\
+ ldrb r4, [r4, 0x4]\n\
+ strb r4, [r0]\n\
+ b _08114844\n\
+ .align 2, 0\n\
+_081147B4: .4byte 0x02014800\n\
+_081147B8: .4byte 0x000030c4\n\
+_081147BC: .4byte 0x000020c4\n\
+_081147C0:\n\
+ adds r0, r6, 0\n\
+ adds r0, 0xC4\n\
+ adds r0, r5, r0\n\
+ movs r1, 0x1\n\
+ strb r1, [r0]\n\
+ adds r0, r3, 0x1\n\
+ mov r10, r0\n\
+ b _081148D2\n\
+_081147D0:\n\
+ movs r1, 0\n\
+ str r1, [sp, 0x4]\n\
+ ldr r6, _08114804 @ =0x02014800\n\
+ mov r2, r8\n\
+ adds r5, r3, r2\n\
+ ldr r0, _08114808 @ =0x000030c4\n\
+ adds r4, r6, r0\n\
+ adds r4, r5, r4\n\
+ ldrb r1, [r4]\n\
+ ldr r0, [sp]\n\
+ str r3, [sp, 0x10]\n\
+ bl sub_8114DF0\n\
+ ldr r1, _0811480C @ =0x000020c4\n\
+ adds r0, r6, r1\n\
+ adds r0, r5, r0\n\
+ ldrb r1, [r4]\n\
+ ldr r3, [sp, 0x10]\n\
+ ldrb r0, [r0]\n\
+ cmp r1, r0\n\
+ beq _08114882\n\
+ adds r0, r6, 0\n\
+ adds r0, 0xC4\n\
+ adds r0, r5, r0\n\
+ movs r1, 0x2\n\
+ b _08114842\n\
+ .align 2, 0\n\
+_08114804: .4byte 0x02014800\n\
+_08114808: .4byte 0x000030c4\n\
+_0811480C: .4byte 0x000020c4\n\
+_08114810:\n\
+ movs r0, 0\n\
+ str r0, [sp, 0x4]\n\
+ ldr r6, _0811484C @ =0x02014800\n\
+ mov r1, r8\n\
+ adds r5, r3, r1\n\
+ ldr r2, _08114850 @ =0x000030c4\n\
+ adds r4, r6, r2\n\
+ adds r4, r5, r4\n\
+ ldrb r1, [r4]\n\
+ ldr r0, [sp]\n\
+ str r3, [sp, 0x10]\n\
+ bl sub_8114DB4\n\
+ ldr r1, _08114854 @ =0x000020c4\n\
+ adds r0, r6, r1\n\
+ adds r0, r5, r0\n\
+ ldrb r1, [r4]\n\
+ ldr r3, [sp, 0x10]\n\
+ ldrb r0, [r0]\n\
+ cmp r1, r0\n\
+ beq _08114882\n\
+ adds r0, r6, 0\n\
+ adds r0, 0xC4\n\
+ adds r0, r5, r0\n\
+ movs r1, 0x3\n\
+_08114842:\n\
+ strb r1, [r0]\n\
+_08114844:\n\
+ adds r5, r3, 0x1\n\
+ mov r10, r5\n\
+ b _081148D2\n\
+ .align 2, 0\n\
+_0811484C: .4byte 0x02014800\n\
+_08114850: .4byte 0x000030c4\n\
+_08114854: .4byte 0x000020c4\n\
+_08114858:\n\
+ movs r0, 0\n\
+ str r0, [sp, 0x4]\n\
+ ldr r6, _08114894 @ =0x02014800\n\
+ mov r1, r8\n\
+ adds r5, r3, r1\n\
+ ldr r2, _08114898 @ =0x000030c4\n\
+ adds r4, r6, r2\n\
+ adds r4, r5, r4\n\
+ ldrb r1, [r4]\n\
+ ldr r0, [sp]\n\
+ str r3, [sp, 0x10]\n\
+ bl sub_8114DF0\n\
+ ldr r1, _0811489C @ =0x000020c4\n\
+ adds r0, r6, r1\n\
+ adds r0, r5, r0\n\
+ ldrb r1, [r4]\n\
+ ldr r3, [sp, 0x10]\n\
+ ldrb r0, [r0]\n\
+ cmp r1, r0\n\
+ bne _081148C4\n\
+_08114882:\n\
+ adds r0, r6, 0\n\
+ adds r0, 0xC4\n\
+ adds r0, r5, r0\n\
+ mov r2, sp\n\
+ ldrb r2, [r2, 0x4]\n\
+ strb r2, [r0]\n\
+ adds r4, r3, 0x1\n\
+ mov r10, r4\n\
+ b _081148D2\n\
+ .align 2, 0\n\
+_08114894: .4byte 0x02014800\n\
+_08114898: .4byte 0x000030c4\n\
+_0811489C: .4byte 0x000020c4\n\
+_081148A0:\n\
+ mov r0, r9\n\
+ adds r0, 0xC4\n\
+ adds r0, r7, r0\n\
+ movs r5, 0\n\
+ strb r5, [r0]\n\
+ b _081148D2\n\
+_081148AC:\n\
+ mov r0, r9\n\
+ adds r0, 0xC4\n\
+ adds r0, r7, r0\n\
+ movs r1, 0\n\
+ strb r1, [r0]\n\
+ b _081148D2\n\
+_081148B8:\n\
+ mov r0, r9\n\
+ adds r0, 0xC4\n\
+ adds r0, r7, r0\n\
+ movs r1, 0\n\
+ strb r1, [r0]\n\
+ b _081148D2\n\
+_081148C4:\n\
+ adds r0, r6, 0\n\
+ adds r0, 0xC4\n\
+ adds r0, r5, r0\n\
+ movs r1, 0x4\n\
+ strb r1, [r0]\n\
+ adds r2, r3, 0x1\n\
+ mov r10, r2\n\
+_081148D2:\n\
+ ldr r0, _081148F4 @ =0x02014800\n\
+ mov r4, r8\n\
+ adds r1, r3, r4\n\
+ ldr r5, _081148F8 @ =0x000008c4\n\
+ adds r2, r0, r5\n\
+ adds r1, r2\n\
+ ldrb r1, [r1]\n\
+ adds r4, r0, 0\n\
+ cmp r1, 0xC\n\
+ bls _081148E8\n\
+ b _08114D76\n\
+_081148E8:\n\
+ lsls r0, r1, 2\n\
+ ldr r1, _081148FC @ =_08114900\n\
+ adds r0, r1\n\
+ ldr r0, [r0]\n\
+ mov pc, r0\n\
+ .align 2, 0\n\
+_081148F4: .4byte 0x02014800\n\
+_081148F8: .4byte 0x000008c4\n\
+_081148FC: .4byte _08114900\n\
+ .align 2, 0\n\
+_08114900:\n\
+ .4byte _08114D76\n\
+ .4byte _08114934\n\
+ .4byte _081149B8\n\
+ .4byte _08114A3C\n\
+ .4byte _08114AC0\n\
+ .4byte _08114B44\n\
+ .4byte _08114B7C\n\
+ .4byte _08114BB4\n\
+ .4byte _08114BEC\n\
+ .4byte _08114C24\n\
+ .4byte _08114C78\n\
+ .4byte _08114CB8\n\
+ .4byte _08114CF8\n\
+_08114934:\n\
+ movs r0, 0\n\
+ str r0, [sp, 0x4]\n\
+ lsls r0, r3, 1\n\
+ ldr r2, [sp]\n\
+ lsls r1, r2, 6\n\
+ adds r0, r1\n\
+ ldr r5, _081149A8 @ =0x000070c4\n\
+ adds r2, r4, r5\n\
+ adds r2, r0, r2\n\
+ ldr r5, _081149AC @ =0x000090c4\n\
+ adds r1, r4, r5\n\
+ adds r0, r1\n\
+ ldrh r1, [r0]\n\
+ ldrh r0, [r2]\n\
+ adds r1, r0\n\
+ movs r0, 0xFF\n\
+ lsls r0, 8\n\
+ ands r0, r1\n\
+ lsrs r5, r0, 8\n\
+ movs r0, 0xFF\n\
+ ands r1, r0\n\
+ strh r1, [r2]\n\
+ movs r6, 0\n\
+ ldr r1, [sp, 0x4]\n\
+ cmp r1, r5\n\
+ blt _0811496A\n\
+ b _08114D76\n\
+_0811496A:\n\
+ mov r9, r4\n\
+ mov r2, r8\n\
+ adds r7, r3, r2\n\
+ ldr r0, _081149B0 @ =0x000038c4\n\
+ add r0, r9\n\
+ adds r4, r7, r0\n\
+ movs r3, 0\n\
+ ldr r0, _081149B4 @ =0x000028c4\n\
+ add r0, r9\n\
+ adds r2, r7, r0\n\
+_0811497E:\n\
+ ldrb r0, [r4]\n\
+ subs r0, 0x1\n\
+ strb r0, [r4]\n\
+ ldrb r1, [r4]\n\
+ ldr r0, [sp]\n\
+ str r2, [sp, 0xC]\n\
+ str r3, [sp, 0x10]\n\
+ bl sub_8114DB4\n\
+ ldrb r0, [r4]\n\
+ ldr r2, [sp, 0xC]\n\
+ ldr r3, [sp, 0x10]\n\
+ ldrb r1, [r2]\n\
+ cmp r0, r1\n\
+ bne _0811499E\n\
+ b _08114D4C\n\
+_0811499E:\n\
+ adds r6, 0x1\n\
+ cmp r6, r5\n\
+ blt _0811497E\n\
+ b _08114D76\n\
+ .align 2, 0\n\
+_081149A8: .4byte 0x000070c4\n\
+_081149AC: .4byte 0x000090c4\n\
+_081149B0: .4byte 0x000038c4\n\
+_081149B4: .4byte 0x000028c4\n\
+_081149B8:\n\
+ movs r2, 0\n\
+ str r2, [sp, 0x4]\n\
+ ldr r4, _08114A28 @ =0x02014800\n\
+ lsls r0, r3, 1\n\
+ ldr r5, [sp]\n\
+ lsls r1, r5, 6\n\
+ adds r0, r1\n\
+ ldr r1, _08114A2C @ =0x000070c4\n\
+ adds r2, r4, r1\n\
+ adds r2, r0, r2\n\
+ ldr r5, _08114A30 @ =0x000090c4\n\
+ adds r1, r4, r5\n\
+ adds r0, r1\n\
+ ldrh r1, [r0]\n\
+ ldrh r0, [r2]\n\
+ adds r1, r0\n\
+ movs r0, 0xFF\n\
+ lsls r0, 8\n\
+ ands r0, r1\n\
+ lsrs r5, r0, 8\n\
+ movs r0, 0xFF\n\
+ ands r1, r0\n\
+ strh r1, [r2]\n\
+ movs r6, 0\n\
+ ldr r1, [sp, 0x4]\n\
+ cmp r1, r5\n\
+ blt _081149F0\n\
+ b _08114D76\n\
+_081149F0:\n\
+ mov r9, r4\n\
+ mov r2, r8\n\
+ adds r7, r3, r2\n\
+ ldr r0, _08114A34 @ =0x000038c4\n\
+ add r0, r9\n\
+ adds r4, r7, r0\n\
+ ldr r0, _08114A38 @ =0x000028c4\n\
+ add r0, r9\n\
+ adds r2, r7, r0\n\
+_08114A02:\n\
+ ldrb r0, [r4]\n\
+ ldrb r1, [r2]\n\
+ cmp r0, r1\n\
+ bne _08114A0C\n\
+ b _08114D3C\n\
+_08114A0C:\n\
+ adds r1, r0, 0\n\
+ ldr r0, [sp]\n\
+ str r2, [sp, 0xC]\n\
+ bl sub_8114DF0\n\
+ ldrb r0, [r4]\n\
+ subs r0, 0x1\n\
+ strb r0, [r4]\n\
+ adds r6, 0x1\n\
+ ldr r2, [sp, 0xC]\n\
+ cmp r6, r5\n\
+ blt _08114A02\n\
+ b _08114D76\n\
+ .align 2, 0\n\
+_08114A28: .4byte 0x02014800\n\
+_08114A2C: .4byte 0x000070c4\n\
+_08114A30: .4byte 0x000090c4\n\
+_08114A34: .4byte 0x000038c4\n\
+_08114A38: .4byte 0x000028c4\n\
+_08114A3C:\n\
+ movs r2, 0\n\
+ str r2, [sp, 0x4]\n\
+ lsls r0, r3, 1\n\
+ ldr r5, [sp]\n\
+ lsls r1, r5, 6\n\
+ adds r0, r1\n\
+ ldr r1, _08114AB0 @ =0x000070c4\n\
+ adds r2, r4, r1\n\
+ adds r2, r0, r2\n\
+ ldr r5, _08114AB4 @ =0x000090c4\n\
+ adds r1, r4, r5\n\
+ adds r0, r1\n\
+ ldrh r1, [r0]\n\
+ ldrh r0, [r2]\n\
+ adds r1, r0\n\
+ movs r0, 0xFF\n\
+ lsls r0, 8\n\
+ ands r0, r1\n\
+ lsrs r5, r0, 8\n\
+ movs r0, 0xFF\n\
+ ands r1, r0\n\
+ strh r1, [r2]\n\
+ movs r6, 0\n\
+ ldr r1, [sp, 0x4]\n\
+ cmp r1, r5\n\
+ blt _08114A72\n\
+ b _08114D76\n\
+_08114A72:\n\
+ mov r9, r4\n\
+ mov r2, r8\n\
+ adds r7, r3, r2\n\
+ ldr r0, _08114AB8 @ =0x000038c4\n\
+ add r0, r9\n\
+ adds r4, r7, r0\n\
+ movs r3, 0\n\
+ ldr r0, _08114ABC @ =0x000028c4\n\
+ add r0, r9\n\
+ adds r2, r7, r0\n\
+_08114A86:\n\
+ ldrb r0, [r4]\n\
+ adds r0, 0x1\n\
+ strb r0, [r4]\n\
+ ldrb r1, [r4]\n\
+ ldr r0, [sp]\n\
+ str r2, [sp, 0xC]\n\
+ str r3, [sp, 0x10]\n\
+ bl sub_8114DB4\n\
+ ldrb r0, [r4]\n\
+ ldr r2, [sp, 0xC]\n\
+ ldr r3, [sp, 0x10]\n\
+ ldrb r1, [r2]\n\
+ cmp r0, r1\n\
+ bne _08114AA6\n\
+ b _08114D4C\n\
+_08114AA6:\n\
+ adds r6, 0x1\n\
+ cmp r6, r5\n\
+ blt _08114A86\n\
+ b _08114D76\n\
+ .align 2, 0\n\
+_08114AB0: .4byte 0x000070c4\n\
+_08114AB4: .4byte 0x000090c4\n\
+_08114AB8: .4byte 0x000038c4\n\
+_08114ABC: .4byte 0x000028c4\n\
+_08114AC0:\n\
+ movs r2, 0\n\
+ str r2, [sp, 0x4]\n\
+ ldr r4, _08114B30 @ =0x02014800\n\
+ lsls r0, r3, 1\n\
+ ldr r5, [sp]\n\
+ lsls r1, r5, 6\n\
+ adds r0, r1\n\
+ ldr r1, _08114B34 @ =0x000070c4\n\
+ adds r2, r4, r1\n\
+ adds r2, r0, r2\n\
+ ldr r5, _08114B38 @ =0x000090c4\n\
+ adds r1, r4, r5\n\
+ adds r0, r1\n\
+ ldrh r1, [r0]\n\
+ ldrh r0, [r2]\n\
+ adds r1, r0\n\
+ movs r0, 0xFF\n\
+ lsls r0, 8\n\
+ ands r0, r1\n\
+ lsrs r5, r0, 8\n\
+ movs r0, 0xFF\n\
+ ands r1, r0\n\
+ strh r1, [r2]\n\
+ movs r6, 0\n\
+ ldr r1, [sp, 0x4]\n\
+ cmp r1, r5\n\
+ blt _08114AF8\n\
+ b _08114D76\n\
+_08114AF8:\n\
+ mov r9, r4\n\
+ mov r2, r8\n\
+ adds r7, r3, r2\n\
+ ldr r0, _08114B3C @ =0x000038c4\n\
+ add r0, r9\n\
+ adds r4, r7, r0\n\
+ ldr r0, _08114B40 @ =0x000028c4\n\
+ add r0, r9\n\
+ adds r2, r7, r0\n\
+_08114B0A:\n\
+ ldrb r0, [r4]\n\
+ ldrb r1, [r2]\n\
+ cmp r0, r1\n\
+ bne _08114B14\n\
+ b _08114D5C\n\
+_08114B14:\n\
+ adds r1, r0, 0\n\
+ ldr r0, [sp]\n\
+ str r2, [sp, 0xC]\n\
+ bl sub_8114DF0\n\
+ ldrb r0, [r4]\n\
+ adds r0, 0x1\n\
+ strb r0, [r4]\n\
+ adds r6, 0x1\n\
+ ldr r2, [sp, 0xC]\n\
+ cmp r6, r5\n\
+ blt _08114B0A\n\
+ b _08114D76\n\
+ .align 2, 0\n\
+_08114B30: .4byte 0x02014800\n\
+_08114B34: .4byte 0x000070c4\n\
+_08114B38: .4byte 0x000090c4\n\
+_08114B3C: .4byte 0x000038c4\n\
+_08114B40: .4byte 0x000028c4\n\
+_08114B44:\n\
+ movs r2, 0\n\
+ str r2, [sp, 0x4]\n\
+ ldr r5, _08114B70 @ =0x02014800\n\
+ mov r0, r8\n\
+ adds r4, r3, r0\n\
+ ldr r1, _08114B74 @ =0x000038c4\n\
+ adds r0, r5, r1\n\
+ adds r0, r4, r0\n\
+ ldrb r1, [r0]\n\
+ ldr r0, [sp]\n\
+ bl sub_8114E48\n\
+ lsls r0, 24\n\
+ cmp r0, 0\n\
+ bne _08114B64\n\
+ b _08114D76\n\
+_08114B64:\n\
+ ldr r2, _08114B78 @ =0x000008c4\n\
+ adds r0, r5, r2\n\
+ adds r0, r4, r0\n\
+ movs r1, 0x9\n\
+ b _08114D74\n\
+ .align 2, 0\n\
+_08114B70: .4byte 0x02014800\n\
+_08114B74: .4byte 0x000038c4\n\
+_08114B78: .4byte 0x000008c4\n\
+_08114B7C:\n\
+ movs r4, 0\n\
+ str r4, [sp, 0x4]\n\
+ ldr r5, _08114BA8 @ =0x02014800\n\
+ mov r0, r8\n\
+ adds r4, r3, r0\n\
+ ldr r1, _08114BAC @ =0x000038c4\n\
+ adds r0, r5, r1\n\
+ adds r0, r4, r0\n\
+ ldrb r1, [r0]\n\
+ ldr r0, [sp]\n\
+ bl sub_8114E48\n\
+ lsls r0, 24\n\
+ cmp r0, 0\n\
+ bne _08114B9C\n\
+ b _08114D76\n\
+_08114B9C:\n\
+ ldr r2, _08114BB0 @ =0x000008c4\n\
+ adds r0, r5, r2\n\
+ adds r0, r4, r0\n\
+ movs r1, 0xA\n\
+ b _08114D74\n\
+ .align 2, 0\n\
+_08114BA8: .4byte 0x02014800\n\
+_08114BAC: .4byte 0x000038c4\n\
+_08114BB0: .4byte 0x000008c4\n\
+_08114BB4:\n\
+ movs r4, 0\n\
+ str r4, [sp, 0x4]\n\
+ ldr r5, _08114BE0 @ =0x02014800\n\
+ mov r0, r8\n\
+ adds r4, r3, r0\n\
+ ldr r1, _08114BE4 @ =0x000038c4\n\
+ adds r0, r5, r1\n\
+ adds r0, r4, r0\n\
+ ldrb r1, [r0]\n\
+ ldr r0, [sp]\n\
+ bl sub_8114E48\n\
+ lsls r0, 24\n\
+ cmp r0, 0\n\
+ bne _08114BD4\n\
+ b _08114D76\n\
+_08114BD4:\n\
+ ldr r2, _08114BE8 @ =0x000008c4\n\
+ adds r0, r5, r2\n\
+ adds r0, r4, r0\n\
+ movs r1, 0xB\n\
+ b _08114D74\n\
+ .align 2, 0\n\
+_08114BE0: .4byte 0x02014800\n\
+_08114BE4: .4byte 0x000038c4\n\
+_08114BE8: .4byte 0x000008c4\n\
+_08114BEC:\n\
+ movs r4, 0\n\
+ str r4, [sp, 0x4]\n\
+ ldr r5, _08114C18 @ =0x02014800\n\
+ mov r0, r8\n\
+ adds r4, r3, r0\n\
+ ldr r1, _08114C1C @ =0x000038c4\n\
+ adds r0, r5, r1\n\
+ adds r0, r4, r0\n\
+ ldrb r1, [r0]\n\
+ ldr r0, [sp]\n\
+ bl sub_8114E48\n\
+ lsls r0, 24\n\
+ cmp r0, 0\n\
+ bne _08114C0C\n\
+ b _08114D76\n\
+_08114C0C:\n\
+ ldr r2, _08114C20 @ =0x000008c4\n\
+ adds r0, r5, r2\n\
+ adds r0, r4, r0\n\
+ movs r1, 0xC\n\
+ b _08114D74\n\
+ .align 2, 0\n\
+_08114C18: .4byte 0x02014800\n\
+_08114C1C: .4byte 0x000038c4\n\
+_08114C20: .4byte 0x000008c4\n\
+_08114C24:\n\
+ movs r4, 0\n\
+ str r4, [sp, 0x4]\n\
+ ldr r6, _08114C58 @ =0x02014800\n\
+ mov r0, r8\n\
+ adds r5, r3, r0\n\
+ ldr r1, _08114C5C @ =0x000038c4\n\
+ adds r4, r6, r1\n\
+ adds r4, r5, r4\n\
+ ldrb r1, [r4]\n\
+ ldr r0, [sp]\n\
+ bl sub_8114DB4\n\
+ ldr r2, _08114C60 @ =0x000028c4\n\
+ adds r0, r6, r2\n\
+ adds r0, r5, r0\n\
+ ldrb r1, [r4]\n\
+ ldrb r0, [r0]\n\
+ cmp r1, r0\n\
+ bne _08114C68\n\
+ ldr r4, _08114C64 @ =0x000008c4\n\
+ adds r0, r6, r4\n\
+ adds r0, r5, r0\n\
+ mov r5, sp\n\
+ ldrb r5, [r5, 0x4]\n\
+ strb r5, [r0]\n\
+ b _08114D76\n\
+ .align 2, 0\n\
+_08114C58: .4byte 0x02014800\n\
+_08114C5C: .4byte 0x000038c4\n\
+_08114C60: .4byte 0x000028c4\n\
+_08114C64: .4byte 0x000008c4\n\
+_08114C68:\n\
+ ldr r1, _08114C74 @ =0x000008c4\n\
+ adds r0, r6, r1\n\
+ adds r0, r5, r0\n\
+ movs r1, 0x1\n\
+ b _08114D74\n\
+ .align 2, 0\n\
+_08114C74: .4byte 0x000008c4\n\
+_08114C78:\n\
+ movs r2, 0\n\
+ str r2, [sp, 0x4]\n\
+ ldr r6, _08114CA8 @ =0x02014800\n\
+ mov r4, r8\n\
+ adds r5, r3, r4\n\
+ ldr r0, _08114CAC @ =0x000038c4\n\
+ adds r4, r6, r0\n\
+ adds r4, r5, r4\n\
+ ldrb r1, [r4]\n\
+ ldr r0, [sp]\n\
+ bl sub_8114DF0\n\
+ ldr r1, _08114CB0 @ =0x000028c4\n\
+ adds r0, r6, r1\n\
+ adds r0, r5, r0\n\
+ ldrb r1, [r4]\n\
+ ldrb r0, [r0]\n\
+ cmp r1, r0\n\
+ beq _08114D1E\n\
+ ldr r1, _08114CB4 @ =0x000008c4\n\
+ adds r0, r6, r1\n\
+ adds r0, r5, r0\n\
+ movs r1, 0x2\n\
+ b _08114D74\n\
+ .align 2, 0\n\
+_08114CA8: .4byte 0x02014800\n\
+_08114CAC: .4byte 0x000038c4\n\
+_08114CB0: .4byte 0x000028c4\n\
+_08114CB4: .4byte 0x000008c4\n\
+_08114CB8:\n\
+ movs r2, 0\n\
+ str r2, [sp, 0x4]\n\
+ ldr r6, _08114CE8 @ =0x02014800\n\
+ mov r4, r8\n\
+ adds r5, r3, r4\n\
+ ldr r0, _08114CEC @ =0x000038c4\n\
+ adds r4, r6, r0\n\
+ adds r4, r5, r4\n\
+ ldrb r1, [r4]\n\
+ ldr r0, [sp]\n\
+ bl sub_8114DB4\n\
+ ldr r1, _08114CF0 @ =0x000028c4\n\
+ adds r0, r6, r1\n\
+ adds r0, r5, r0\n\
+ ldrb r1, [r4]\n\
+ ldrb r0, [r0]\n\
+ cmp r1, r0\n\
+ beq _08114D1E\n\
+ ldr r1, _08114CF4 @ =0x000008c4\n\
+ adds r0, r6, r1\n\
+ adds r0, r5, r0\n\
+ movs r1, 0x3\n\
+ b _08114D74\n\
+ .align 2, 0\n\
+_08114CE8: .4byte 0x02014800\n\
+_08114CEC: .4byte 0x000038c4\n\
+_08114CF0: .4byte 0x000028c4\n\
+_08114CF4: .4byte 0x000008c4\n\
+_08114CF8:\n\
+ movs r2, 0\n\
+ str r2, [sp, 0x4]\n\
+ ldr r6, _08114D2C @ =0x02014800\n\
+ mov r4, r8\n\
+ adds r5, r3, r4\n\
+ ldr r0, _08114D30 @ =0x000038c4\n\
+ adds r4, r6, r0\n\
+ adds r4, r5, r4\n\
+ ldrb r1, [r4]\n\
+ ldr r0, [sp]\n\
+ bl sub_8114DF0\n\
+ ldr r1, _08114D34 @ =0x000028c4\n\
+ adds r0, r6, r1\n\
+ adds r0, r5, r0\n\
+ ldrb r1, [r4]\n\
+ ldrb r0, [r0]\n\
+ cmp r1, r0\n\
+ bne _08114D6C\n\
+_08114D1E:\n\
+ ldr r2, _08114D38 @ =0x000008c4\n\
+ adds r0, r6, r2\n\
+ adds r0, r5, r0\n\
+ mov r4, sp\n\
+ ldrb r4, [r4, 0x4]\n\
+ strb r4, [r0]\n\
+ b _08114D76\n\
+ .align 2, 0\n\
+_08114D2C: .4byte 0x02014800\n\
+_08114D30: .4byte 0x000038c4\n\
+_08114D34: .4byte 0x000028c4\n\
+_08114D38: .4byte 0x000008c4\n\
+_08114D3C:\n\
+ ldr r0, _08114D48 @ =0x000008c4\n\
+ add r0, r9\n\
+ adds r0, r7, r0\n\
+ movs r1, 0\n\
+ b _08114D74\n\
+ .align 2, 0\n\
+_08114D48: .4byte 0x000008c4\n\
+_08114D4C:\n\
+ ldr r0, _08114D58 @ =0x000008c4\n\
+ add r0, r9\n\
+ adds r0, r7, r0\n\
+ strb r3, [r0]\n\
+ b _08114D76\n\
+ .align 2, 0\n\
+_08114D58: .4byte 0x000008c4\n\
+_08114D5C:\n\
+ ldr r0, _08114D68 @ =0x000008c4\n\
+ add r0, r9\n\
+ adds r0, r7, r0\n\
+ movs r1, 0\n\
+ b _08114D74\n\
+ .align 2, 0\n\
+_08114D68: .4byte 0x000008c4\n\
+_08114D6C:\n\
+ ldr r1, _08114DAC @ =0x000008c4\n\
+ adds r0, r6, r1\n\
+ adds r0, r5, r0\n\
+ movs r1, 0x4\n\
+_08114D74:\n\
+ strb r1, [r0]\n\
+_08114D76:\n\
+ mov r3, r10\n\
+ ldr r2, _08114DB0 @ =0x02014800\n\
+ adds r0, r2, 0\n\
+ adds r0, 0x84\n\
+ ldr r4, [sp]\n\
+ adds r0, r4, r0\n\
+ adds r4, r2, 0\n\
+_08114D84:\n\
+ ldrb r0, [r0]\n\
+ cmp r3, r0\n\
+ bge _08114D8E\n\
+ bl _08114410\n\
+_08114D8E:\n\
+ ldr r5, [sp, 0x8]\n\
+ str r5, [sp]\n\
+ cmp r5, 0x3F\n\
+ bgt _08114D9A\n\
+ bl _081143F2\n\
+_08114D9A:\n\
+ ldr r0, [sp, 0x4]\n\
+ add sp, 0x14\n\
+ pop {r3-r5}\n\
+ mov r8, r3\n\
+ mov r9, r4\n\
+ mov r10, r5\n\
+ pop {r4-r7}\n\
+ pop {r1}\n\
+ bx r1\n\
+ .align 2, 0\n\
+_08114DAC: .4byte 0x000008c4\n\
+_08114DB0: .4byte 0x02014800\n\
+ .syntax divided");
+}
+
+void sub_8114DB4(u32 a, u8 b)
+{
+ u8 *r2 = sEvoInfo.unk40C4[a][b / 2];
+
+ if (b % 2 != 0)
+ *r2 |= 0xF0;
+ else
+ *r2 |= 0x0F;
+}
+
+void sub_8114DF0(u32 a, u8 b)
+{
+ u8 *r2 = sEvoInfo.unk40C4[a][b / 2];
+ u8 *r1 = r2 + 0x6000;
+
+ if (b % 2 != 0)
+ {
+ if (!(*r1 & 0xF0))
+ *r2 &= 0x0F;
+ }
+ else
+ {
+ if (!(*r1 & 0x0F))
+ *r2 &= 0xF0;
+ }
+}
+
+__attribute__((naked))
+void sub_8114E48()
+{
+ asm(".syntax unified\n\
+ push {r4-r7,lr}\n\
+ adds r4, r0, 0\n\
+ lsls r1, 24\n\
+ lsrs r6, r1, 24\n\
+ ldr r1, _08114E6C @ =0x02014800\n\
+ ldr r2, _08114E70 @ =0x0000a0c4\n\
+ adds r0, r1, r2\n\
+ ldrb r0, [r0]\n\
+ adds r5, r1, 0\n\
+ cmp r0, 0\n\
+ bne _08114E60\n\
+ b _08114F5E\n\
+_08114E60:\n\
+ movs r1, 0\n\
+ movs r3, 0\n\
+ cmp r4, 0\n\
+ bne _08114E74\n\
+ movs r1, 0x1\n\
+ b _08114EA6\n\
+ .align 2, 0\n\
+_08114E6C: .4byte 0x02014800\n\
+_08114E70: .4byte 0x0000a0c4\n\
+_08114E74:\n\
+ subs r0, r4, 0x1\n\
+ lsls r0, 5\n\
+ adds r2, r3, r0\n\
+ adds r0, r5, 0\n\
+ adds r0, 0xC4\n\
+ adds r0, r2, r0\n\
+ ldrb r0, [r0]\n\
+ cmp r0, 0\n\
+ bne _08114EA6\n\
+ ldr r7, _08114EC4 @ =0x000008c4\n\
+ adds r0, r5, r7\n\
+ adds r0, r2, r0\n\
+ ldrb r0, [r0]\n\
+ cmp r0, 0\n\
+ bne _08114EA6\n\
+ adds r3, 0x1\n\
+ cmp r3, 0x1F\n\
+ bgt _08114EA6\n\
+ cmp r4, 0\n\
+ bne _08114E74\n\
+ lsls r0, r1, 24\n\
+ movs r1, 0x80\n\
+ lsls r1, 17\n\
+ adds r0, r1\n\
+ lsrs r1, r0, 24\n\
+_08114EA6:\n\
+ cmp r3, 0x20\n\
+ bne _08114EB4\n\
+ lsls r0, r1, 24\n\
+ movs r2, 0x80\n\
+ lsls r2, 17\n\
+ adds r0, r2\n\
+ lsrs r1, r0, 24\n\
+_08114EB4:\n\
+ movs r3, 0\n\
+ cmp r4, 0x3F\n\
+ bne _08114EC8\n\
+ lsls r0, r1, 24\n\
+ movs r7, 0x80\n\
+ lsls r7, 17\n\
+ adds r0, r7\n\
+ b _08114EF8\n\
+ .align 2, 0\n\
+_08114EC4: .4byte 0x000008c4\n\
+_08114EC8:\n\
+ adds r0, r4, 0x1\n\
+ lsls r0, 5\n\
+ adds r2, r3, r0\n\
+ adds r0, r5, 0\n\
+ adds r0, 0xC4\n\
+ adds r0, r2, r0\n\
+ ldrb r0, [r0]\n\
+ cmp r0, 0\n\
+ bne _08114EFA\n\
+ ldr r7, _08114F64 @ =0x000008c4\n\
+ adds r0, r5, r7\n\
+ adds r0, r2, r0\n\
+ ldrb r0, [r0]\n\
+ cmp r0, 0\n\
+ bne _08114EFA\n\
+ adds r3, 0x1\n\
+ cmp r3, 0x1F\n\
+ bgt _08114EFA\n\
+ cmp r4, 0x3F\n\
+ bne _08114EC8\n\
+ lsls r0, r1, 24\n\
+ movs r1, 0x80\n\
+ lsls r1, 17\n\
+ adds r0, r1\n\
+_08114EF8:\n\
+ lsrs r1, r0, 24\n\
+_08114EFA:\n\
+ cmp r3, 0x20\n\
+ bne _08114F08\n\
+ lsls r0, r1, 24\n\
+ movs r2, 0x80\n\
+ lsls r2, 17\n\
+ adds r0, r2\n\
+ lsrs r1, r0, 24\n\
+_08114F08:\n\
+ cmp r1, 0x2\n\
+ beq _08114F5E\n\
+ subs r0, r6, 0x2\n\
+ lsls r0, 24\n\
+ lsrs r1, r0, 24\n\
+ cmp r0, 0\n\
+ bge _08114F18\n\
+ movs r1, 0\n\
+_08114F18:\n\
+ adds r0, r6, 0x2\n\
+ lsls r0, 24\n\
+ lsrs r2, r0, 24\n\
+ asrs r0, 24\n\
+ cmp r0, 0x3F\n\
+ ble _08114F26\n\
+ movs r2, 0x3F\n\
+_08114F26:\n\
+ lsls r1, 24\n\
+ asrs r3, r1, 24\n\
+ lsls r0, r2, 24\n\
+ asrs r2, r0, 24\n\
+ adds r6, r1, 0\n\
+ adds r7, r0, 0\n\
+ cmp r3, r2\n\
+ bge _08114F7C\n\
+ cmp r4, 0\n\
+ beq _08114F7C\n\
+ subs r0, r4, 0x1\n\
+ lsls r5, r0, 7\n\
+ ldr r0, _08114F68 @ =0x020188c4\n\
+ mov r12, r0\n\
+_08114F42:\n\
+ asrs r0, r3, 1\n\
+ lsls r0, 2\n\
+ adds r0, r5\n\
+ add r0, r12\n\
+ ldr r1, [r0]\n\
+ movs r0, 0x1\n\
+ ands r0, r3\n\
+ cmp r0, 0\n\
+ beq _08114F6C\n\
+ ldrb r1, [r1]\n\
+ movs r0, 0xF0\n\
+_08114F58:\n\
+ ands r0, r1\n\
+ cmp r0, 0\n\
+ beq _08114F72\n\
+_08114F5E:\n\
+ movs r0, 0x1\n\
+ b _08114FCA\n\
+ .align 2, 0\n\
+_08114F64: .4byte 0x000008c4\n\
+_08114F68: .4byte 0x020188c4\n\
+_08114F6C:\n\
+ ldrb r1, [r1]\n\
+ movs r0, 0xF\n\
+ b _08114F58\n\
+_08114F72:\n\
+ adds r3, 0x1\n\
+ cmp r3, r2\n\
+ bge _08114F7C\n\
+ cmp r4, 0\n\
+ bne _08114F42\n\
+_08114F7C:\n\
+ asrs r3, r6, 24\n\
+ asrs r1, r7, 24\n\
+ cmp r3, r1\n\
+ bge _08114FC8\n\
+ cmp r4, 0x3F\n\
+ beq _08114FC8\n\
+ adds r0, r4, 0x1\n\
+ lsls r5, r0, 7\n\
+ ldr r6, _08114FB0 @ =0x020188c4\n\
+ adds r2, r1, 0\n\
+_08114F90:\n\
+ asrs r0, r3, 1\n\
+ lsls r0, 2\n\
+ adds r0, r5\n\
+ adds r0, r6\n\
+ ldr r1, [r0]\n\
+ movs r0, 0x1\n\
+ ands r0, r3\n\
+ cmp r0, 0\n\
+ beq _08114FB4\n\
+ ldrb r1, [r1]\n\
+ movs r0, 0xF0\n\
+ ands r0, r1\n\
+ cmp r0, 0\n\
+ beq _08114FBE\n\
+ b _08114F5E\n\
+ .align 2, 0\n\
+_08114FB0: .4byte 0x020188c4\n\
+_08114FB4:\n\
+ ldrb r1, [r1]\n\
+ movs r0, 0xF\n\
+ ands r0, r1\n\
+ cmp r0, 0\n\
+ bne _08114F5E\n\
+_08114FBE:\n\
+ adds r3, 0x1\n\
+ cmp r3, r2\n\
+ bge _08114FC8\n\
+ cmp r4, 0x3F\n\
+ bne _08114F90\n\
+_08114FC8:\n\
+ movs r0, 0\n\
+_08114FCA:\n\
+ pop {r4-r7}\n\
+ pop {r1}\n\
+ bx r1\n\
+ .syntax divided");
+}
+
+// Functions below are vblank callbacks and are used
+
+static void EvoDummyFunc(void)
+{
+
+}
+
+static void VBlankCB_EvolutionScene(void)
+{
+ REG_BG0CNT = BGCNT_SCREENBASE(24) | BGCNT_16COLOR | BGCNT_TXT256x256 | BGCNT_AFF512x512 | BGCNT_PRIORITY(3); // 0x9803
+ REG_BG0HOFS = gUnknown_030042A4;
+ REG_BG0VOFS = gUnknown_030042A0;
+ REG_BG1HOFS = gUnknown_030042C0;
+ REG_BG1VOFS = gUnknown_030041B4;
+ REG_BG2HOFS = gUnknown_03004288;
+ REG_BG2VOFS = gUnknown_03004280;
+ REG_BG3HOFS = gUnknown_030041B0;
+ REG_BG3VOFS = gUnknown_030041B8;
+ LoadOam();
+ ProcessSpriteCopyRequests();
+ TransferPlttBuffer();
+ sub_8089668();
+}
+
+static void VBlankCB_TradeEvolutionScene(void)
+{
+ REG_BG0HOFS = gUnknown_030042A4;
+ REG_BG0VOFS = gUnknown_030042A0;
+ REG_BG1HOFS = gUnknown_030042C0;
+ REG_BG1VOFS = gUnknown_030041B4;
+ REG_BG2HOFS = gUnknown_03004288;
+ REG_BG2VOFS = gUnknown_03004280;
+ REG_BG3HOFS = gUnknown_030041B0;
+ REG_BG3VOFS = gUnknown_030041B8;
+ LoadOam();
+ ProcessSpriteCopyRequests();
+ TransferPlttBuffer();
+ sub_8089668();
+}
+
+static void sub_81150D8(void)
+{
+ sub_814A880(200, 72 + (sEvoCursorPos * 16));
+}
+
+static void EvoDummyFunc2(void)
+{
+
+}
diff --git a/src/scene/new_game.c b/src/scene/new_game.c
index 226ac9bb7..46df14acd 100644
--- a/src/scene/new_game.c
+++ b/src/scene/new_game.c
@@ -11,7 +11,7 @@
#include "item_menu.h"
#include "lottery_corner.h"
#include "mail_data.h"
-#include "mauville_old_man.h"
+#include "mauville_man.h"
#include "play_time.h"
#include "player_pc.h"
#include "pokeblock.h"
@@ -157,7 +157,7 @@ void NewGameInitData(void)
ClearPokeblocks();
ClearDecorationInventories();
InitEasyChatPhrases();
- SetMauvilleOldMan();
+ SetupMauvilleOldMan();
InitDewfordTrend();
ResetFanClub();
ResetLotteryCorner();
diff --git a/src/strings.c b/src/strings.c
index 219c5bec1..6c8dce9d6 100644
--- a/src/strings.c
+++ b/src/strings.c
@@ -861,7 +861,7 @@ const u8 gOtherText_AtBattleStart[] = _("At the battle’s start.");
const u8 gOtherText_UponWinningBattle[] = _("Upon winning a battle.");
const u8 gOtherText_UponLosingBattle[] = _("Upon losing a battle.");
-// mauville_old_man?
+// mauville_man?
const u8 gOtherText_TheBardsSong[] = _("The BARD’s Song");
const u8 gOtherText_WhatsHipHappening[] = _("What’s hip and happening?");
const u8 gOtherText_Interview[] = _("Interview");
@@ -1781,7 +1781,7 @@ const u8 gOtherText_AtBattleStart[] = _("Zum Kampfbeginn");
const u8 gOtherText_UponWinningBattle[] = _("Über den Sieg");
const u8 gOtherText_UponLosingBattle[] = _("Über die Niederlage");
-// mauville_old_man?
+// mauville_man?
const u8 gOtherText_TheBardsSong[] = _("Das BARDEN-Lied");
const u8 gOtherText_WhatsHipHappening[] = _("Was ist hip? Was ist top?");
const u8 gOtherText_Interview[] = _("Interview");