summaryrefslogtreecommitdiff
path: root/src/easy_chat_2.c
diff options
context:
space:
mode:
authorultima-soul <akshayjhanji@hotmail.com>2020-03-13 00:32:04 -0700
committerultima-soul <akshayjhanji@hotmail.com>2020-03-13 00:32:04 -0700
commit99e4de062ae43aa978ad4f1a8cd70bc739c64c9d (patch)
tree1164d31577e6ebddc1cb313d40bb69ce0d426170 /src/easy_chat_2.c
parent339c2914affc3c62ac9a5725aa1a0c7ccc3161ca (diff)
parent6af8c04d8fa6aaeaeb6c8b919e7770a65b9a883d (diff)
Merge branch 'master' into event_object_movement
Diffstat (limited to 'src/easy_chat_2.c')
-rw-r--r--src/easy_chat_2.c1363
1 files changed, 1363 insertions, 0 deletions
diff --git a/src/easy_chat_2.c b/src/easy_chat_2.c
new file mode 100644
index 000000000..4b3c70b67
--- /dev/null
+++ b/src/easy_chat_2.c
@@ -0,0 +1,1363 @@
+#include "global.h"
+#include "gflib.h"
+#include "easy_chat.h"
+#include "event_data.h"
+#include "menu.h"
+#include "mevent.h"
+#include "overworld.h"
+#include "strings.h"
+#include "task.h"
+#include "constants/songs.h"
+
+#define EZCHAT_TASK_STATE 0
+#define EZCHAT_TASK_TYPE 1
+#define EZCHAT_TASK_WORDS 2
+#define EZCHAT_TASK_MAINCALLBACK 4
+#define EZCHAT_TASK_UNK06 6
+#define EZCHAT_TASK_SIZE 7
+
+struct EasyChatScreenTemplate
+{
+ u8 type;
+ u8 numColumns;
+ u8 numRows;
+ u8 frameId;
+ const u8 *titleText;
+ const u8 *instructionsText1;
+ const u8 *instructionsText2;
+ const u8 *confirmText1;
+ const u8 *confirmText2;
+};
+
+struct EasyChatScreen
+{
+ /*0x00*/ u8 type;
+ /*0x01*/ u8 templateId;
+ /*0x02*/ u8 numColumns;
+ /*0x03*/ u8 numRows;
+ /*0x04*/ u8 state;
+ /*0x05*/ s8 mainCursorColumn;
+ /*0x06*/ s8 mainCursorRow;
+ /*0x07*/ u8 numWords;
+ /*0x08*/ u8 stateBackup;
+ /*0x09*/ bool8 isAlphaMode;
+ /*0x0A*/ s8 selectGroupCursorX;
+ /*0x0B*/ s8 selectGroupCursorY;
+ /*0x0C*/ u8 selectGroupRowsAbove;
+ /*0x0D*/ u8 selectGroupNumRows;
+ /*0x0E*/ u8 selectWordRowsAbove;
+ /*0x0F*/ u8 selectWordNumRows;
+ /*0x10*/ s8 selectWordCursorX;
+ /*0x11*/ s8 selectWordCursorY;
+ /*0x14*/ u16 *words;
+ /*0x18*/ u16 ecWordBuffer[9];
+};
+
+static EWRAM_DATA struct EasyChatScreen * sEasyChatScreen = NULL;
+
+static void CB2_EasyChatScreen(void);
+static void Task_InitEasyChat(u8 taskId);
+static void Task_RunEasyChat(u8 taskId);
+static bool8 Task_InitEasyChatInternal(u8 taskId);
+static void DismantleEasyChat(MainCallback cb);
+static void CompareProfileResponseWithPassphrase(void);
+static void CompareQuestionnaireResponseWithPassphrase(void);
+static bool8 EasyChat_AllocateResources(u8 type, u16 *words);
+static void EasyChat_FreeResources(void);
+static u16 EasyChatScreen_HandleJoypad(void);
+static u16 HandleJoypad_SelectField(void);
+static u16 HandleJoypad_SelectFooter(void);
+static u16 HandleJoypad_SelectGroup(void);
+static u16 HandleJoypad_SelectWord(void);
+static u16 Cancel_HandleYesNoMenu(void);
+static u16 Confirm_HandleYesNoMenu(void);
+static u16 DelAll_HandleYesNoMenu(void);
+static u16 Cancel_CreateYesNoMenu(void);
+static u16 DelAll_CreateYesNoMenu(void);
+static u16 Confirm_CreateYesNoMenu(void);
+static u8 GetStateBackup(void);
+static int OpenSelectedGroup(void);
+static int BackOutFromGroupToFieldSelect(void);
+static int ToggleGroupAlphaMode(void);
+static int DeleteSelectedWord(void);
+static int PlaceSelectedWord(void);
+static void CommitECWords(void);
+static void DeleteAllECFields(void);
+static void SetEasyChatWordToField(u16 word);
+static bool8 HasECMessageChanged(void);
+static u16 SelectGroupCursorAction(u32 action);
+static int UpdateSelectGroupCursorPos_OutsideBlueBox_GroupMode(u32 action);
+static int UpdateSelectGroupCursorPos_OutsideBlueBox_AlphaMode(u32 action);
+static int UpdateSelectGroupCursorPos_InsideBlueBox(u32 action);
+static void GroupCursorMoveToBlueBox(void);
+static void GroupCursorWrapAroundLeft(void);
+static u16 SelectWordCursorAction(u32 action);
+static u16 GetSelectedFieldIndex(void);
+static u16 GetSelectedGroupIndex(void);
+static int GetSelectedLetter(void);
+static u16 GetSelectWordCursorPos(void);
+static u8 GetMaxGroupCursorXinAlphaMode(u8 unkB);
+static void MoveGroupCursorXToMaxCol(void);
+static void MoveWordCursorXToMaxCol(void);
+static bool8 GroupSelectCursorXPosTooFarRight(void);
+static bool8 WordSelectCursorXPosTooFarRight(void);
+static bool8 IsPhraseDifferentThanPlayerInput(const u16 *wordsToCompare, u8 numWords);
+static u8 GetEasyChatScreenTemplateId(u8 type);
+static bool32 IsEcWordBufferUninitialized(void);
+
+void DoEasyChatScreen(u8 type, u16 *words, MainCallback callback)
+{
+ u8 taskId;
+ ResetTasks();
+ taskId = CreateTask(Task_InitEasyChat, 0);
+ gTasks[taskId].data[EZCHAT_TASK_TYPE] = type;
+ SetWordTaskArg(taskId, EZCHAT_TASK_WORDS, (uintptr_t)words);
+ SetWordTaskArg(taskId, EZCHAT_TASK_MAINCALLBACK, (uintptr_t)callback);
+ SetMainCallback2(CB2_EasyChatScreen);
+}
+
+static void CB2_EasyChatScreen(void)
+{
+ RunTasks();
+ AnimateSprites();
+ BuildOamBuffer();
+ UpdatePaletteFade();
+}
+
+static void VBlankCallback_EasyChatScreen(void)
+{
+ TransferPlttBuffer();
+ LoadOam();
+ ProcessSpriteCopyRequests();
+}
+
+static void SetEasyChatTaskFunc(u8 taskId, TaskFunc func)
+{
+ gTasks[taskId].func = func;
+ gTasks[taskId].data[EZCHAT_TASK_STATE] = 0;
+}
+
+static void Task_InitEasyChat(u8 taskId)
+{
+ if (!IsUpdateLinkStateCBActive())
+ {
+ while (Task_InitEasyChatInternal(taskId))
+ ;
+ }
+ else
+ {
+ if (Task_InitEasyChatInternal(taskId) == TRUE)
+ return;
+ }
+ SetEasyChatTaskFunc(taskId, Task_RunEasyChat);
+}
+
+static void Task_RunEasyChat(u8 taskId)
+{
+ u16 action;
+ s16 *data;
+
+ data = gTasks[taskId].data;
+ switch (data[EZCHAT_TASK_STATE])
+ {
+ case 0:
+ SetVBlankCallback(VBlankCallback_EasyChatScreen);
+ BlendPalettes(0xFFFFFFFF, 16, RGB_BLACK);
+ BeginNormalPaletteFade(0xFFFFFFFF, -1, 16, 0, RGB_BLACK);
+ data[EZCHAT_TASK_STATE]++;
+ break;
+ case 1:
+ action = EasyChatScreen_HandleJoypad();
+ if (action == 23)
+ {
+ BeginNormalPaletteFade(0xFFFFFFFF, -1, 0, 16, RGB_BLACK);
+ data[EZCHAT_TASK_STATE] = 3;
+ }
+ else if (action != 0)
+ {
+ PlaySE(SE_SELECT);
+ EasyChatInterfaceCommand_Setup(action);
+ data[EZCHAT_TASK_STATE]++;
+ }
+ break;
+ case 2:
+ if (!EasyChatInterfaceCommand_Run())
+ data[EZCHAT_TASK_STATE] = 1;
+ break;
+ case 3:
+ if (!gPaletteFade.active)
+ {
+ if (data[EZCHAT_TASK_TYPE] == EASY_CHAT_TYPE_QUESTIONNAIRE)
+ CompareQuestionnaireResponseWithPassphrase();
+ if (data[EZCHAT_TASK_TYPE] == EASY_CHAT_TYPE_PROFILE)
+ {
+ FlagSet(FLAG_SYS_SET_TRAINER_CARD_PROFILE);
+ CompareProfileResponseWithPassphrase();
+ }
+ DismantleEasyChat((MainCallback)GetWordTaskArg(taskId, EZCHAT_TASK_MAINCALLBACK));
+ }
+ break;
+ }
+}
+
+static bool8 Task_InitEasyChatInternal(u8 taskId)
+{
+ s16 *data;
+
+ data = gTasks[taskId].data;
+ switch (data[EZCHAT_TASK_STATE])
+ {
+ case 0:
+ SetVBlankCallback(NULL);
+ ResetSpriteData();
+ FreeAllSpritePalettes();
+ ResetPaletteFade();
+ break;
+ case 1:
+ if (!InitEasyChatSelection())
+ {
+ DismantleEasyChat((MainCallback)GetWordTaskArg(taskId, EZCHAT_TASK_MAINCALLBACK));
+ }
+ break;
+ case 2:
+ if (!EasyChat_AllocateResources(data[EZCHAT_TASK_TYPE], (u16 *)GetWordTaskArg(taskId, EZCHAT_TASK_WORDS)))
+ {
+ DismantleEasyChat((MainCallback)GetWordTaskArg(taskId, EZCHAT_TASK_MAINCALLBACK));
+ }
+ break;
+ case 3:
+ if (!InitEasyChatGraphicsWork())
+ {
+ DismantleEasyChat((MainCallback)GetWordTaskArg(taskId, EZCHAT_TASK_MAINCALLBACK));
+ }
+ break;
+ case 4:
+ if (LoadEasyChatGraphics())
+ {
+ return TRUE;
+ }
+ break;
+ default:
+ return FALSE;
+ }
+ data[EZCHAT_TASK_STATE]++;
+ return TRUE;
+}
+
+static void DismantleEasyChat(MainCallback callback)
+{
+ DestroyEasyChatSelectionData();
+ EasyChat_FreeResources();
+ DestroyEasyChatGraphicsResources();
+ FreeAllWindowBuffers();
+ SetMainCallback2(callback);
+}
+
+void ShowEasyChatScreen(void)
+{
+ u16 *words;
+ switch (gSpecialVar_0x8004)
+ {
+ case EASY_CHAT_TYPE_PROFILE:
+ words = gSaveBlock1Ptr->easyChatProfile;
+ break;
+ case EASY_CHAT_TYPE_BATTLE_START:
+ words = gSaveBlock1Ptr->easyChatBattleStart;
+ break;
+ case EASY_CHAT_TYPE_BATTLE_WON:
+ words = gSaveBlock1Ptr->easyChatBattleWon;
+ break;
+ case EASY_CHAT_TYPE_BATTLE_LOST:
+ words = gSaveBlock1Ptr->easyChatBattleLost;
+ break;
+ case EASY_CHAT_TYPE_QUESTIONNAIRE:
+ words = GetMEventProfileECWordsMaybe();
+ break;
+ case EASY_CHAT_TYPE_MAIL:
+ words = gSaveBlock1Ptr->mail[gSpecialVar_0x8005].words;
+ break;
+ default:
+ return;
+ }
+ DoEasyChatScreen(gSpecialVar_0x8004, words, sub_80568C4);
+}
+
+static const u16 sECPhrase_MysteryEventIsExciting[] = {
+ EC_WORD_MYSTERY,
+ EC_WORD_EVENT,
+ EC_WORD_IS,
+ EC_WORD_EXCITING
+};
+
+static void CompareProfileResponseWithPassphrase(void)
+{
+ gSpecialVar_0x8004 = IsPhraseDifferentThanPlayerInput(sECPhrase_MysteryEventIsExciting, NELEMS(sECPhrase_MysteryEventIsExciting));
+}
+
+static const u16 sECPhrase_LinkTogetherWithAll[] = {
+ EC_WORD_LINK,
+ EC_WORD_TOGETHER,
+ EC_WORD_WITH,
+ EC_WORD_ALL
+};
+
+static void CompareQuestionnaireResponseWithPassphrase(void)
+{
+ gSpecialVar_0x8004 = IsPhraseDifferentThanPlayerInput(sECPhrase_LinkTogetherWithAll, NELEMS(sECPhrase_LinkTogetherWithAll));
+}
+
+static const struct EasyChatScreenTemplate sEasyChatScreenTemplates[] = {
+ {
+ .type = EASY_CHAT_TYPE_PROFILE,
+ .numColumns = 2,
+ .numRows = 2,
+ .frameId = 0,
+ .titleText = gUnknown_8418A2B,
+ .instructionsText1 = gUnknown_84186D1,
+ .instructionsText2 = gUnknown_84186EF,
+ .confirmText1 = gUnknown_841880E,
+ .confirmText2 = gUnknown_8418902
+ }, {
+ .type = EASY_CHAT_TYPE_BATTLE_START,
+ .numColumns = 2,
+ .numRows = 3,
+ .frameId = 1,
+ .titleText = gUnknown_8418A33,
+ .instructionsText1 = gUnknown_8418706,
+ .instructionsText2 = gUnknown_8418725,
+ .confirmText1 = gUnknown_841881B,
+ .confirmText2 = gUnknown_8418902
+ }, {
+ .type = EASY_CHAT_TYPE_BATTLE_WON,
+ .numColumns = 2,
+ .numRows = 3,
+ .frameId = 1,
+ .titleText = gUnknown_8418A4A,
+ .instructionsText1 = gUnknown_8418706,
+ .instructionsText2 = gUnknown_8418725,
+ .confirmText1 = gUnknown_841883E,
+ .confirmText2 = gUnknown_8418902
+ }, {
+ .type = EASY_CHAT_TYPE_BATTLE_LOST,
+ .numColumns = 2,
+ .numRows = 3,
+ .frameId = 1,
+ .titleText = gUnknown_8418A61,
+ .instructionsText1 = gUnknown_8418706,
+ .instructionsText2 = gUnknown_8418725,
+ .confirmText1 = gUnknown_841885F,
+ .confirmText2 = gUnknown_8418902
+ }, {
+ .type = EASY_CHAT_TYPE_MAIL,
+ .numColumns = 2,
+ .numRows = 5,
+ .frameId = 2,
+ .titleText = NULL,
+ .instructionsText1 = gUnknown_8418780,
+ .instructionsText2 = gUnknown_841879E,
+ .confirmText1 = gUnknown_841888C,
+ .confirmText2 = gUnknown_8418902
+ }, {
+ .type = EASY_CHAT_TYPE_MAIL_NO_CONFIRM,
+ .numColumns = 2,
+ .numRows = 2,
+ .frameId = 0,
+ .instructionsText1 = gUnknown_8418780,
+ .instructionsText2 = gUnknown_841879E,
+ }, {
+ .type = EASY_CHAT_TYPE_BARD_SONG,
+ .numColumns = 2,
+ .numRows = 3,
+ .frameId = 1,
+ .titleText = gUnknown_8418A77,
+ .instructionsText1 = gUnknown_84187B2,
+ .instructionsText2 = gUnknown_84187D1,
+ .confirmText1 = gUnknown_84188AC,
+ .confirmText2 = gUnknown_8418902
+ }, {
+ .type = EASY_CHAT_TYPE_INTERVIEW,
+ .numColumns = 2,
+ .numRows = 3,
+ .frameId = 1,
+ .titleText = gUnknown_8418AA1,
+ .instructionsText1 = gUnknown_8418745,
+ .instructionsText2 = gUnknown_8418763,
+ .confirmText1 = gUnknown_8418881,
+ .confirmText2 = gUnknown_8418902
+ }, {
+ .type = EASY_CHAT_TYPE_TRENDY_PHRASE,
+ .numColumns = 2,
+ .numRows = 1,
+ .frameId = 3,
+ .titleText = gUnknown_8418A87,
+ .instructionsText1 = gUnknown_84188B9,
+ .instructionsText2 = gUnknown_84188D6,
+ .confirmText1 = gUnknown_84188F0,
+ .confirmText2 = gUnknown_8418902
+ }, {
+ .type = EASY_CHAT_TYPE_QUESTIONNAIRE,
+ .numColumns = 2,
+ .numRows = 2,
+ .frameId = 0,
+ .titleText = gUnknown_8418AB2,
+ .instructionsText1 = gUnknown_84186D1,
+ .instructionsText2 = gUnknown_84187EE,
+ .confirmText1 = gUnknown_8418881,
+ .confirmText2 = gUnknown_8418902
+ }
+};
+
+static bool8 EasyChat_AllocateResources(u8 type, u16 *words)
+{
+ u8 templateId;
+ int i;
+
+ sEasyChatScreen = malloc(sizeof(*sEasyChatScreen));
+ if (sEasyChatScreen == NULL)
+ return FALSE;
+
+ sEasyChatScreen->type = type;
+ sEasyChatScreen->words = words;
+ sEasyChatScreen->state = 0;
+ sEasyChatScreen->mainCursorColumn = 0;
+ sEasyChatScreen->mainCursorRow = 0;
+ sEasyChatScreen->isAlphaMode = FALSE;
+ templateId = GetEasyChatScreenTemplateId(type);
+
+ sEasyChatScreen->numColumns = sEasyChatScreenTemplates[templateId].numColumns;
+ sEasyChatScreen->numRows = sEasyChatScreenTemplates[templateId].numRows;
+ sEasyChatScreen->numWords = sEasyChatScreen->numColumns * sEasyChatScreen->numRows;
+ sEasyChatScreen->templateId = templateId;
+ if (sEasyChatScreen->numWords > 9)
+ sEasyChatScreen->numWords = 9;
+
+ CpuCopy16(words, sEasyChatScreen->ecWordBuffer, sEasyChatScreen->numWords * sizeof(u16));
+ sEasyChatScreen->selectGroupNumRows = (GetNumDisplayableGroups() - 1) / 2 + 1;
+ return TRUE;
+}
+
+static void EasyChat_FreeResources(void)
+{
+ if (sEasyChatScreen != NULL)
+ Free(sEasyChatScreen);
+}
+
+static u16 EasyChatScreen_HandleJoypad(void)
+{
+ switch (sEasyChatScreen->state)
+ {
+ case 0:
+ return HandleJoypad_SelectField();
+ case 1:
+ return HandleJoypad_SelectFooter();
+ case 2:
+ return HandleJoypad_SelectGroup();
+ case 3:
+ return HandleJoypad_SelectWord();
+ case 4:
+ return Cancel_HandleYesNoMenu();
+ case 5:
+ return DelAll_HandleYesNoMenu();
+ case 6:
+ return Confirm_HandleYesNoMenu();
+ }
+ return 0;
+}
+
+static u16 HandleJoypad_SelectField(void)
+{
+ do
+ {
+ if (JOY_NEW(A_BUTTON))
+ {
+ sEasyChatScreen->state = 2;
+ sEasyChatScreen->selectGroupCursorX = 0;
+ sEasyChatScreen->selectGroupCursorY = 0;
+ sEasyChatScreen->selectGroupRowsAbove = 0;
+ return 9;
+ }
+ else if (JOY_NEW(B_BUTTON))
+ {
+ return Cancel_CreateYesNoMenu();
+ }
+ else if (JOY_NEW(START_BUTTON))
+ {
+ return Confirm_CreateYesNoMenu();
+ }
+ else if (JOY_NEW(DPAD_UP))
+ {
+ sEasyChatScreen->mainCursorRow--;
+ break;
+ }
+ else if (JOY_NEW(DPAD_LEFT))
+ {
+ sEasyChatScreen->mainCursorColumn--;
+ break;
+ }
+ else if (JOY_NEW(DPAD_DOWN))
+ {
+ sEasyChatScreen->mainCursorRow++;
+ break;
+ }
+ else if (JOY_NEW(DPAD_RIGHT))
+ {
+ sEasyChatScreen->mainCursorColumn++;
+ break;
+ }
+
+ return 0;
+ } while (0);
+
+ if (sEasyChatScreen->mainCursorRow < 0)
+ sEasyChatScreen->mainCursorRow = sEasyChatScreenTemplates[sEasyChatScreen->templateId].numRows;
+
+ if (sEasyChatScreen->mainCursorRow > sEasyChatScreenTemplates[sEasyChatScreen->templateId].numRows)
+ sEasyChatScreen->mainCursorRow = 0;
+
+ if (sEasyChatScreen->mainCursorRow == sEasyChatScreenTemplates[sEasyChatScreen->templateId].numRows)
+ {
+ if (sEasyChatScreen->mainCursorColumn > 2)
+ sEasyChatScreen->mainCursorColumn = 2;
+
+ sEasyChatScreen->state = 1;
+ return 3;
+ }
+
+ if (sEasyChatScreen->mainCursorColumn < 0)
+ sEasyChatScreen->mainCursorColumn = sEasyChatScreenTemplates[sEasyChatScreen->templateId].numColumns - 1;
+
+ if (sEasyChatScreen->mainCursorColumn >= sEasyChatScreenTemplates[sEasyChatScreen->templateId].numColumns)
+ sEasyChatScreen->mainCursorColumn = 0;
+
+ if (GetEasyChatScreenFrameId() == 2 && sEasyChatScreen->mainCursorColumn == 1 && sEasyChatScreen->mainCursorRow == 4)
+ sEasyChatScreen->mainCursorColumn = 0;
+
+ return 2;
+}
+
+static u16 HandleJoypad_SelectFooter(void)
+{
+ do
+ {
+ if (JOY_NEW(A_BUTTON))
+ {
+ switch (sEasyChatScreen->mainCursorColumn)
+ {
+ case 0:
+ return DelAll_CreateYesNoMenu();
+ case 1:
+ return Cancel_CreateYesNoMenu();
+ case 2:
+ return Confirm_CreateYesNoMenu();
+ }
+ }
+
+ if (JOY_NEW(B_BUTTON))
+ {
+ return Cancel_CreateYesNoMenu();
+ }
+ else if (JOY_NEW(START_BUTTON))
+ {
+ return Confirm_CreateYesNoMenu();
+ }
+ else if (JOY_NEW(DPAD_UP))
+ {
+ sEasyChatScreen->mainCursorRow--;
+ break;
+ }
+ else if (JOY_NEW(DPAD_LEFT))
+ {
+ sEasyChatScreen->mainCursorColumn--;
+ break;
+ }
+ else if (JOY_NEW(DPAD_DOWN))
+ {
+ sEasyChatScreen->mainCursorRow = 0;
+ break;
+ }
+ else if (JOY_NEW(DPAD_RIGHT))
+ {
+ sEasyChatScreen->mainCursorColumn++;
+ break;
+ }
+
+ return 0;
+ } while (0);
+
+ if (sEasyChatScreen->mainCursorRow == sEasyChatScreenTemplates[sEasyChatScreen->templateId].numRows)
+ {
+ if (sEasyChatScreen->mainCursorColumn < 0)
+ sEasyChatScreen->mainCursorColumn = 2;
+
+ if (sEasyChatScreen->mainCursorColumn >= 3)
+ sEasyChatScreen->mainCursorColumn = 0;
+
+ return 3;
+ }
+
+ if (sEasyChatScreen->mainCursorColumn >= sEasyChatScreenTemplates[sEasyChatScreen->templateId].numColumns)
+ sEasyChatScreen->mainCursorColumn = sEasyChatScreenTemplates[sEasyChatScreen->templateId].numColumns - 1;
+
+ if (GetEasyChatScreenFrameId() == 2 && sEasyChatScreen->mainCursorColumn == 1 && sEasyChatScreen->mainCursorRow == 4)
+ sEasyChatScreen->mainCursorColumn = 0;
+
+ sEasyChatScreen->state = 0;
+ return 2;
+}
+
+static u16 HandleJoypad_SelectGroup(void)
+{
+ if (JOY_NEW(B_BUTTON))
+ return BackOutFromGroupToFieldSelect();
+
+ if (JOY_NEW(A_BUTTON))
+ {
+ if (sEasyChatScreen->selectGroupCursorX != -1)
+ return OpenSelectedGroup();
+
+ switch (sEasyChatScreen->selectGroupCursorY)
+ {
+ case 0:
+ return ToggleGroupAlphaMode();
+ case 1:
+ return DeleteSelectedWord();
+ case 2:
+ return BackOutFromGroupToFieldSelect();
+ }
+ }
+
+ if (JOY_NEW(SELECT_BUTTON))
+ return ToggleGroupAlphaMode();
+
+ if (JOY_REPT(DPAD_UP))
+ return SelectGroupCursorAction(2);
+
+ if (JOY_REPT(DPAD_DOWN))
+ return SelectGroupCursorAction(3);
+
+ if (JOY_REPT(DPAD_LEFT))
+ return SelectGroupCursorAction(1);
+
+ if (JOY_REPT(DPAD_RIGHT))
+ return SelectGroupCursorAction(0);
+
+ return 0;
+}
+
+static u16 HandleJoypad_SelectWord(void)
+{
+ if (JOY_NEW(B_BUTTON))
+ {
+ sEasyChatScreen->state = 2;
+ return 13;
+ }
+
+ if (JOY_NEW(A_BUTTON))
+ return PlaceSelectedWord();
+
+ if (JOY_NEW(START_BUTTON))
+ return SelectWordCursorAction(4);
+
+ if (JOY_NEW(SELECT_BUTTON))
+ return SelectWordCursorAction(5);
+
+ if (JOY_REPT(DPAD_UP))
+ return SelectWordCursorAction(2);
+
+ if (JOY_REPT(DPAD_DOWN))
+ return SelectWordCursorAction(3);
+
+ if (JOY_REPT(DPAD_LEFT))
+ return SelectWordCursorAction(1);
+
+ if (JOY_REPT(DPAD_RIGHT))
+ return SelectWordCursorAction(0);
+
+ return 0;
+}
+
+static u16 Cancel_HandleYesNoMenu(void)
+{
+ u8 var0;
+
+ switch (Menu_ProcessInputNoWrapClearOnChoose())
+ {
+ case MENU_B_PRESSED: // B Button
+ case 1: // No
+ sEasyChatScreen->state = GetStateBackup();
+ return 7;
+ case 0: // Yes
+ gSpecialVar_Result = 0;
+
+ return 23;
+ default:
+ return 0;
+ }
+}
+
+static u16 Confirm_HandleYesNoMenu(void)
+{
+ switch (Menu_ProcessInputNoWrapClearOnChoose())
+ {
+ case MENU_B_PRESSED: // B Button
+ case 1: // No
+ sEasyChatScreen->state = GetStateBackup();
+ return 7;
+ case 0: // Yes
+ gSpecialVar_Result = HasECMessageChanged();
+ CommitECWords();
+ return 23;
+ default:
+ return 0;
+ }
+}
+
+static u16 DelAll_HandleYesNoMenu(void)
+{
+ switch (Menu_ProcessInputNoWrapClearOnChoose())
+ {
+ case MENU_B_PRESSED: // B Button
+ case 1: // No
+ sEasyChatScreen->state = 1;
+ return 7;
+ case 0: // Yes
+ DeleteAllECFields();
+ sEasyChatScreen->state = 1;
+ return 8;
+ default:
+ return 0;
+ }
+}
+
+static u16 Cancel_CreateYesNoMenu(void)
+{
+ sEasyChatScreen->stateBackup = sEasyChatScreen->state;
+ sEasyChatScreen->state = 4;
+ return 5;
+}
+
+static u16 DelAll_CreateYesNoMenu(void)
+{
+ sEasyChatScreen->stateBackup = sEasyChatScreen->state;
+ sEasyChatScreen->state = 5;
+ return 4;
+}
+
+static u16 Confirm_CreateYesNoMenu(void)
+{
+ sEasyChatScreen->stateBackup = sEasyChatScreen->state;
+ if (IsEcWordBufferUninitialized())
+ {
+ sEasyChatScreen->state = 4;
+ return 5;
+ }
+ else
+ {
+ sEasyChatScreen->state = 6;
+ return 6;
+ }
+}
+
+static u8 GetStateBackup(void)
+{
+ return sEasyChatScreen->stateBackup;
+}
+
+static int OpenSelectedGroup(void)
+{
+ u16 numDisplayedWords;
+
+ if (!sEasyChatScreen->isAlphaMode)
+ {
+ u8 groupId = GetSelectedGroupByIndex(GetSelectedGroupIndex());
+ GetUnlockedECWords(FALSE, groupId);
+ }
+ else
+ {
+ GetUnlockedECWords(TRUE, GetSelectedLetter());
+ }
+
+ numDisplayedWords = GetNumDisplayedWords();
+ if (numDisplayedWords == 0)
+ return 0;
+
+ sEasyChatScreen->selectWordNumRows = (numDisplayedWords - 1) / 2;
+ sEasyChatScreen->selectWordRowsAbove = 0;
+ sEasyChatScreen->selectWordCursorX = 0;
+ sEasyChatScreen->selectWordCursorY = 0;
+ sEasyChatScreen->state = 3;
+ return 11;
+}
+
+static int BackOutFromGroupToFieldSelect(void)
+{
+ sEasyChatScreen->state = 0;
+ return 10;
+}
+
+static int ToggleGroupAlphaMode(void)
+{
+ sEasyChatScreen->selectGroupCursorX = 0;
+ sEasyChatScreen->selectGroupCursorY = 0;
+ sEasyChatScreen->selectGroupRowsAbove = 0;
+ if (!sEasyChatScreen->isAlphaMode)
+ sEasyChatScreen->isAlphaMode = TRUE;
+ else
+ sEasyChatScreen->isAlphaMode = FALSE;
+
+ return 22;
+}
+
+static int DeleteSelectedWord(void)
+{
+ SetEasyChatWordToField(0xFFFF);
+ return 1;
+}
+
+static int PlaceSelectedWord(void)
+{
+ u16 easyChatWord = GetDisplayedWordByIndex(GetSelectWordCursorPos());
+ SetEasyChatWordToField(easyChatWord);
+ sEasyChatScreen->state = 0;
+ return 12;
+}
+
+static void CommitECWords(void)
+{
+ u16 i;
+ for (i = 0; i < sEasyChatScreen->numWords; i++)
+ sEasyChatScreen->words[i] = sEasyChatScreen->ecWordBuffer[i];
+}
+
+static void DeleteAllECFields(void)
+{
+ u16 i;
+ for (i = 0; i < sEasyChatScreen->numWords; i++)
+ sEasyChatScreen->ecWordBuffer[i] = 0xFFFF;
+}
+
+static void SetEasyChatWordToField(u16 easyChatWord)
+{
+ u16 index = GetSelectedFieldIndex();
+ sEasyChatScreen->ecWordBuffer[index] = easyChatWord;
+}
+
+static bool8 HasECMessageChanged(void)
+{
+ u16 i;
+ for (i = 0; i < sEasyChatScreen->numWords; i++)
+ {
+ if (sEasyChatScreen->ecWordBuffer[i] != sEasyChatScreen->words[i])
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static u16 SelectGroupCursorAction(u32 action)
+{
+ if (sEasyChatScreen->selectGroupCursorX != -1)
+ {
+ if (!sEasyChatScreen->isAlphaMode)
+ return UpdateSelectGroupCursorPos_OutsideBlueBox_GroupMode(action);
+ else
+ return UpdateSelectGroupCursorPos_OutsideBlueBox_AlphaMode(action);
+ }
+ else
+ {
+ return UpdateSelectGroupCursorPos_InsideBlueBox(action);
+ }
+}
+
+static int UpdateSelectGroupCursorPos_OutsideBlueBox_GroupMode(u32 arg0)
+{
+ switch (arg0)
+ {
+ case 2:
+ if (sEasyChatScreen->selectGroupCursorY != -sEasyChatScreen->selectGroupRowsAbove)
+ {
+ if (sEasyChatScreen->selectGroupCursorY)
+ {
+ sEasyChatScreen->selectGroupCursorY--;
+ return 14;
+ }
+ else
+ {
+ sEasyChatScreen->selectGroupRowsAbove--;
+ return 16;
+ }
+ }
+ break;
+ case 3:
+ if (sEasyChatScreen->selectGroupCursorY + sEasyChatScreen->selectGroupRowsAbove < sEasyChatScreen->selectGroupNumRows - 1)
+ {
+ int var0;
+ if (sEasyChatScreen->selectGroupCursorY < 3)
+ {
+ sEasyChatScreen->selectGroupCursorY++;
+ var0 = 14;
+ }
+ else
+ {
+ sEasyChatScreen->selectGroupRowsAbove++;
+ var0 = 15;
+ }
+
+ MoveGroupCursorXToMaxCol();
+ return var0;
+ }
+ break;
+ case 1:
+ if (sEasyChatScreen->selectGroupCursorX)
+ sEasyChatScreen->selectGroupCursorX--;
+ else
+ GroupCursorMoveToBlueBox();
+
+ return 14;
+ case 0:
+ if (sEasyChatScreen->selectGroupCursorX < 1)
+ {
+ sEasyChatScreen->selectGroupCursorX++;
+ if (GroupSelectCursorXPosTooFarRight())
+ GroupCursorMoveToBlueBox();
+ }
+ else
+ {
+ GroupCursorMoveToBlueBox();
+ }
+ return 14;
+ }
+
+ return 0;
+}
+
+static int UpdateSelectGroupCursorPos_OutsideBlueBox_AlphaMode(u32 arg0)
+{
+ switch (arg0)
+ {
+ case 2:
+ if (sEasyChatScreen->selectGroupCursorY > 0)
+ sEasyChatScreen->selectGroupCursorY--;
+ else
+ sEasyChatScreen->selectGroupCursorY = 3;
+
+ MoveGroupCursorXToMaxCol();
+ return 14;
+ case 3:
+ if (sEasyChatScreen->selectGroupCursorY < 3)
+ sEasyChatScreen->selectGroupCursorY++;
+ else
+ sEasyChatScreen->selectGroupCursorY = 0;
+
+ MoveGroupCursorXToMaxCol();
+ return 14;
+ case 0:
+ sEasyChatScreen->selectGroupCursorX++;
+ if (GroupSelectCursorXPosTooFarRight())
+ GroupCursorMoveToBlueBox();
+
+ return 14;
+ case 1:
+ sEasyChatScreen->selectGroupCursorX--;
+ if (sEasyChatScreen->selectGroupCursorX < 0)
+ GroupCursorMoveToBlueBox();
+
+ return 14;
+ }
+
+ return 0;
+}
+
+static int UpdateSelectGroupCursorPos_InsideBlueBox(u32 arg0)
+{
+ switch (arg0)
+ {
+ case 2:
+ if (sEasyChatScreen->selectGroupCursorY)
+ sEasyChatScreen->selectGroupCursorY--;
+ else
+ sEasyChatScreen->selectGroupCursorY = 2;
+
+ return 14;
+ case 3:
+ if (sEasyChatScreen->selectGroupCursorY < 2)
+ sEasyChatScreen->selectGroupCursorY++;
+ else
+ sEasyChatScreen->selectGroupCursorY = 0;
+
+ return 14;
+ case 1:
+ sEasyChatScreen->selectGroupCursorY++;
+ GroupCursorWrapAroundLeft();
+ return 14;
+ case 0:
+ sEasyChatScreen->selectGroupCursorX = 0;
+ sEasyChatScreen->selectGroupCursorY++;
+ return 14;
+ }
+
+ return 0;
+}
+
+static void GroupCursorMoveToBlueBox(void)
+{
+ sEasyChatScreen->selectGroupCursorX = 0xFF;
+ if (sEasyChatScreen->selectGroupCursorY)
+ sEasyChatScreen->selectGroupCursorY--;
+}
+
+static void GroupCursorWrapAroundLeft(void)
+{
+ if (!sEasyChatScreen->isAlphaMode)
+ {
+ sEasyChatScreen->selectGroupCursorX = 1;
+ MoveGroupCursorXToMaxCol();
+ }
+ else
+ {
+ sEasyChatScreen->selectGroupCursorX = GetMaxGroupCursorXinAlphaMode(sEasyChatScreen->selectGroupCursorY);
+ }
+}
+
+static u16 SelectWordCursorAction(u32 arg0)
+{
+ u16 result;
+ switch (arg0)
+ {
+ case 2: // up
+ if (sEasyChatScreen->selectWordCursorY + sEasyChatScreen->selectWordRowsAbove > 0)
+ {
+ if (sEasyChatScreen->selectWordCursorY > 0)
+ {
+ sEasyChatScreen->selectWordCursorY--;
+ result = 17;
+ }
+ else
+ {
+ sEasyChatScreen->selectWordRowsAbove--;
+ result = 18;
+ }
+
+ MoveWordCursorXToMaxCol();
+ return result;
+ }
+ break;
+ case 3: // down
+ if (sEasyChatScreen->selectWordCursorY + sEasyChatScreen->selectWordRowsAbove < sEasyChatScreen->selectWordNumRows)
+ {
+ if (sEasyChatScreen->selectWordCursorY < 3)
+ {
+ sEasyChatScreen->selectWordCursorY++;
+ result = 17;
+ }
+ else
+ {
+ sEasyChatScreen->selectWordRowsAbove++;
+ result = 19;
+ }
+
+ MoveWordCursorXToMaxCol();
+ return result;
+ }
+ break;
+ case 1: // left
+ if (sEasyChatScreen->selectWordCursorX > 0)
+ sEasyChatScreen->selectWordCursorX--;
+ else
+ sEasyChatScreen->selectWordCursorX = 1;
+
+ MoveWordCursorXToMaxCol();
+ return 17;
+ case 0: // right
+ if (sEasyChatScreen->selectWordCursorX < 1)
+ {
+ sEasyChatScreen->selectWordCursorX++;
+ if (WordSelectCursorXPosTooFarRight())
+ sEasyChatScreen->selectWordCursorX = 0;
+ }
+ else
+ {
+ sEasyChatScreen->selectWordCursorX = 0;
+ }
+ return 17;
+ case 4: // pg up
+ if (sEasyChatScreen->selectWordRowsAbove)
+ {
+ if (sEasyChatScreen->selectWordRowsAbove > 3)
+ sEasyChatScreen->selectWordRowsAbove -= 4;
+ else
+ sEasyChatScreen->selectWordRowsAbove = 0;
+
+ return 20;
+ }
+ break;
+ case 5: // pg dn
+ if (sEasyChatScreen->selectWordRowsAbove <= sEasyChatScreen->selectWordNumRows - 4)
+ {
+ sEasyChatScreen->selectWordRowsAbove += 4;
+ if (sEasyChatScreen->selectWordRowsAbove > sEasyChatScreen->selectWordNumRows - 3)
+ sEasyChatScreen->selectWordRowsAbove = sEasyChatScreen->selectWordNumRows + -3u;
+
+ MoveWordCursorXToMaxCol();
+ return 21;
+ }
+ break;
+ }
+
+ return 0;
+}
+
+static u16 GetSelectedFieldIndex(void)
+{
+ return (sEasyChatScreen->mainCursorRow * sEasyChatScreen->numColumns) + sEasyChatScreen->mainCursorColumn;
+}
+
+static u16 GetSelectedGroupIndex(void)
+{
+ return 2 * (sEasyChatScreen->selectGroupCursorY + sEasyChatScreen->selectGroupRowsAbove) + sEasyChatScreen->selectGroupCursorX;
+}
+
+static const u8 sAlphabetLayout[][7] = {
+ { 1, 2, 3, 4, 5, 6},
+ { 7, 8, 9, 10, 11, 12},
+ {13, 14, 15, 16, 17, 18, 19},
+ {20, 21, 22, 23, 24, 25, 26}
+};
+
+static int GetSelectedLetter(void)
+{
+ int col = sEasyChatScreen->selectGroupCursorX < NELEMS(*sAlphabetLayout) ? sEasyChatScreen->selectGroupCursorX : 0;
+ int row = sEasyChatScreen->selectGroupCursorY < NELEMS(sAlphabetLayout) ? sEasyChatScreen->selectGroupCursorY : 0;
+ return sAlphabetLayout[row][col];
+}
+
+static u16 GetSelectWordCursorPos(void)
+{
+ return 2 * (sEasyChatScreen->selectWordCursorY + sEasyChatScreen->selectWordRowsAbove) + sEasyChatScreen->selectWordCursorX;
+}
+
+static u8 GetMaxGroupCursorXinAlphaMode(u8 arg0)
+{
+ switch (arg0)
+ {
+ case 0:
+ default:
+ return 6;
+ case 1:
+ return 5;
+ }
+}
+
+static void MoveGroupCursorXToMaxCol(void)
+{
+ while (GroupSelectCursorXPosTooFarRight())
+ {
+ if (sEasyChatScreen->selectGroupCursorX)
+ sEasyChatScreen->selectGroupCursorX--;
+ else
+ break;
+ }
+}
+
+static void MoveWordCursorXToMaxCol(void)
+{
+ while (WordSelectCursorXPosTooFarRight())
+ {
+ if (sEasyChatScreen->selectWordCursorX)
+ sEasyChatScreen->selectWordCursorX--;
+ else
+ break;
+ }
+}
+
+static bool8 GroupSelectCursorXPosTooFarRight(void)
+{
+ if (!sEasyChatScreen->isAlphaMode)
+ return GetSelectedGroupIndex() >= GetNumDisplayableGroups() ? TRUE : FALSE;
+ else
+ return sEasyChatScreen->selectGroupCursorX > GetMaxGroupCursorXinAlphaMode(sEasyChatScreen->selectGroupCursorY) ? TRUE : FALSE;
+}
+
+static bool8 WordSelectCursorXPosTooFarRight(void)
+{
+ return GetSelectWordCursorPos() >= GetNumDisplayedWords() ? TRUE : FALSE;
+}
+
+u8 GetEasyChatScreenFrameId(void)
+{
+ return sEasyChatScreenTemplates[sEasyChatScreen->templateId].frameId;
+}
+
+const u8 *GetTitleText(void)
+{
+ return sEasyChatScreenTemplates[sEasyChatScreen->templateId].titleText;
+}
+
+u16 *GetEasyChatWordBuffer(void)
+{
+ return sEasyChatScreen->ecWordBuffer;
+}
+
+u8 GetNumRows(void)
+{
+ return sEasyChatScreen->numRows;
+}
+
+u8 GetNumColumns(void)
+{
+ return sEasyChatScreen->numColumns;
+}
+
+u8 GetMainCursorColumn(void)
+{
+ return sEasyChatScreen->mainCursorColumn;
+}
+
+u8 GetMainCursorRow(void)
+{
+ return sEasyChatScreen->mainCursorRow;
+}
+
+void GetEasyChatInstructionsText(const u8 **str1, const u8 **str2)
+{
+ *str1 = sEasyChatScreenTemplates[sEasyChatScreen->templateId].instructionsText1;
+ *str2 = sEasyChatScreenTemplates[sEasyChatScreen->templateId].instructionsText2;
+}
+
+void GetEasyChatConfirmText(const u8 **str1, const u8 **str2)
+{
+ *str1 = sEasyChatScreenTemplates[sEasyChatScreen->templateId].confirmText1;
+ *str2 = sEasyChatScreenTemplates[sEasyChatScreen->templateId].confirmText2;
+}
+
+void GetEasyChatConfirmCancelText(const u8 **str1, const u8 **str2)
+{
+ switch (sEasyChatScreen->type)
+ {
+ case EASY_CHAT_TYPE_MAIL:
+ *str1 = gUnknown_84189EE;
+ *str2 = NULL;
+ break;
+ default:
+ *str1 = gUnknown_84189E0;
+ *str2 = NULL;
+ break;
+ }
+
+}
+
+void GetEasyChatConfirmDeletionText(const u8 **str1, const u8 **str2)
+{
+ *str1 = gUnknown_8418937;
+ *str2 = gUnknown_8418956;
+}
+
+void GetECSelectGroupCursorCoords(u8 *Xp, u8 *Yp)
+{
+ *Xp = sEasyChatScreen->selectGroupCursorX;
+ *Yp = sEasyChatScreen->selectGroupCursorY;
+}
+
+bool8 IsEasyChatAlphaMode(void)
+{
+ return sEasyChatScreen->isAlphaMode;
+}
+
+u8 GetECSelectGroupRowsAbove(void)
+{
+ return sEasyChatScreen->selectGroupRowsAbove;
+}
+
+void GetECSelectWordCursorCoords(s8 *Xp, s8 *Yp)
+{
+ *Xp = sEasyChatScreen->selectWordCursorX;
+ *Yp = sEasyChatScreen->selectWordCursorY;
+}
+
+u8 GetECSelectWordRowsAbove(void)
+{
+ return sEasyChatScreen->selectWordRowsAbove;
+}
+
+u8 GetECSelectWordNumRows(void)
+{
+ return sEasyChatScreen->selectWordNumRows;
+}
+
+u8 unref_sub_80FFE60(void)
+{
+ return 0;
+}
+
+bool32 ShouldDrawECUpArrow(void)
+{
+ switch (sEasyChatScreen->state)
+ {
+ case 2:
+ if (!sEasyChatScreen->isAlphaMode && sEasyChatScreen->selectGroupRowsAbove != 0)
+ return TRUE;
+ break;
+ case 3:
+ if (sEasyChatScreen->selectWordRowsAbove != 0)
+ return TRUE;
+ break;
+ }
+
+ return FALSE;
+}
+
+bool32 ShouldDrawECDownArrow(void)
+{
+ switch (sEasyChatScreen->state)
+ {
+ case 2:
+ if (!sEasyChatScreen->isAlphaMode && sEasyChatScreen->selectGroupRowsAbove + 4 <= sEasyChatScreen->selectGroupNumRows - 1)
+ return TRUE;
+ break;
+ case 3:
+ if (sEasyChatScreen->selectWordRowsAbove + 4 <= sEasyChatScreen->selectWordNumRows)
+ return TRUE;
+ break;
+ }
+
+ return FALSE;
+}
+
+static bool8 IsPhraseDifferentThanPlayerInput(const u16 *phrase, u8 phraseLength)
+{
+ u8 i;
+
+ for (i = 0; i < phraseLength; i++)
+ {
+ if (phrase[i] != sEasyChatScreen->ecWordBuffer[i])
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static u8 GetEasyChatScreenTemplateId(u8 type)
+{
+ u32 i;
+
+ for (i = 0; i < NELEMS(sEasyChatScreenTemplates); i++)
+ {
+ if (sEasyChatScreenTemplates[i].type == type)
+ return i;
+ }
+
+ return 0;
+}
+
+static bool32 IsEcWordBufferUninitialized(void)
+{
+ int i;
+
+ for (i = 0; i < sEasyChatScreen->numWords; i++)
+ {
+ if (sEasyChatScreen->ecWordBuffer[i] != 0xFFFF)
+ return FALSE;
+ }
+
+ return TRUE;
+}