summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMarcus Huderle <huderlem@gmail.com>2019-02-26 11:17:41 -0600
committerhuderlem <huderlem@gmail.com>2019-02-26 14:50:02 -0600
commitb60611c38e904dac5c83f76fc2fbb880baaf0d33 (patch)
treec83f052c5f21d03a35967a5242d2039948cd3c1c /src
parent7742e28dad96fd908d87a3412d0127be10f65ed0 (diff)
Finish decompiling easy_chat.c code
Diffstat (limited to 'src')
-rw-r--r--src/easy_chat.c464
1 files changed, 443 insertions, 21 deletions
diff --git a/src/easy_chat.c b/src/easy_chat.c
index 3fdc88823..6a103dd7b 100644
--- a/src/easy_chat.c
+++ b/src/easy_chat.c
@@ -141,9 +141,26 @@ struct EasyChatGroup
u16 numEnabledWords;
};
+struct Unk203A120
+{
+ u16 unk0;
+ u16 unk2[EC_NUM_GROUPS];
+ u16 unk2E[27];
+ u16 unk64[27][270];
+ u8 filler3958[0x2C];
+ u16 unk3984[0x10E];
+ u16 unk3BA0;
+}; /*size = 0x3BA4*/
+
+struct EasyChatWordsByLetter
+{
+ const u16 *words;
+ int numWords;
+};
+
EWRAM_DATA struct EasyChatScreen *gEasyChatScreen = NULL;
EWRAM_DATA struct Unk203A11C *gUnknown_0203A11C = 0;
-EWRAM_DATA void *gUnknown_0203A120 = 0;
+EWRAM_DATA struct Unk203A120 *gUnknown_0203A120 = 0;
static void sub_811A2C0(u8);
static void sub_811A278(void);
@@ -178,9 +195,9 @@ static bool8 sub_811BFA4(void);
static void sub_811C13C(void);
static void sub_811C158(u16);
static bool8 sub_811C170(void);
-bool8 sub_811F28C(void);
-void sub_811F2B8(void);
-u8 sub_811F3AC(void);
+static bool8 sub_811F28C(void);
+static void sub_811F2B8(void);
+static u8 sub_811F3AC(void);
int sub_811BA3C(void);
int sub_811B184(void);
int sub_811B264(void);
@@ -202,13 +219,13 @@ static int sub_811BDB0(void);
static int sub_811BD2C(void);
int sub_811BCF4(void);
static u16 sub_811B8E8(void);
-int sub_811F3B8(u8);
-void sub_811F548(int, u16);
+static u8 sub_811F3B8(u8);
+static void sub_811F548(int, u16);
static int sub_811B908(void);
-u16 sub_811F5B0(void);
+static u16 sub_811F5B0(void);
static void sub_811B488(u16);
u16 sub_811B940(void);
-u16 sub_811F578(u16);
+static u16 sub_811F578(u16);
int sub_811BF88(int);
static u16 sub_811B8C8(void);
static int sub_811B568(u32);
@@ -310,7 +327,7 @@ static void sub_811DD84(void);
static void sub_811D6F4(void);
static void sub_811D758(void);
static void sub_811D794(void);
-const u8 *sub_811F424(u8);
+static const u8 *GetEasyChatWordGroupName(u8);
static void sub_811D864(u8, u8);
static void sub_811D950(u8, u8);
static void sub_811DADC(u8);
@@ -319,9 +336,16 @@ static void sub_811E0EC(s8, s8);
static void sub_811E1A4(s8, s8);
static void sub_811E2DC(struct Sprite *);
static void sub_811E34C(u8, u8);
-bool8 sub_811F0F8(void);
-u16 sub_811F108(void);
-u8 *CopyEasyChatWordPadded(u8 *, u16, u16);
+static bool8 sub_811F0F8(void);
+static u16 sub_811F108(void);
+static void sub_811F2D4(void);
+static void sub_811F46C(void);
+static u8 *CopyEasyChatWordPadded(u8 *, u16, u16);
+static u8 sub_811F860(u16);
+static u16 sub_811F5C4(u16);
+static u16 sub_811F6B8(u16);
+bool8 sub_811F764(u16, u8);
+static int sub_811F838(u16);
extern const struct {
u16 word;
@@ -356,6 +380,13 @@ extern const u8 gUnknown_08597D08[];
extern const u8 gUnknown_08597E60[][4];
extern const u8 *const gUnknown_08597E6C[][4];
extern const struct EasyChatGroup gEasyChatGroups[];
+extern const u16 gUnknown_0859E62C[];
+extern const u16 gUnknown_0859E634[];
+extern const u16 gUnknown_0859E640[];
+extern const u16 gUnknown_0859E64C[];
+extern const u8 *const gEasyChatGroupNamePointers[];
+extern const struct EasyChatWordsByLetter gEasyChatWordsByLetterPointers[];
+extern const u16 gUnknown_0859E658[1];
void sub_811A20C(u8 kind, u16 *words, MainCallback callback, u8 sizeParam)
{
@@ -1248,8 +1279,8 @@ static int sub_811B2B0(void)
if (gEasyChatScreen->unk_09 == 0)
{
- u8 var0 = sub_811F3B8(sub_811B8E8());
- sub_811F548(0, var0);
+ u8 groupId = sub_811F3B8(sub_811B8E8());
+ sub_811F548(0, groupId);
}
else
{
@@ -3265,14 +3296,14 @@ static void sub_811D6F4(void)
{
for (x = 0; x < 2; x++)
{
- u8 index = sub_811F3B8(i++);
- if (index == 22)
+ u8 groupId = sub_811F3B8(i++);
+ if (groupId == EC_NUM_GROUPS)
{
sub_811DDAC(sub_811BBBC(), 0);
return;
}
- sub_811D028(2, 1, sub_811F424(index), x * 84 + 10, y, 0xFF, NULL);
+ sub_811D028(2, 1, GetEasyChatWordGroupName(groupId), x * 84 + 10, y, 0xFF, NULL);
}
y += 16;
@@ -4077,7 +4108,7 @@ static void sub_811E948(void)
PutWindowTilemap(windowId);
}
-bool8 sub_811EA28(u8 groupId)
+static bool8 sub_811EA28(u8 groupId)
{
switch (groupId)
{
@@ -4397,10 +4428,10 @@ void sub_811EF6C(void)
CopyEasyChatWord(gStringVar2, easyChatWord);
}
-u8 sub_811EF98(u8 additionalPhraseId)
+static bool8 sub_811EF98(u8 additionalPhraseId)
{
int byteOffset = additionalPhraseId / 8;
- int shift = additionalPhraseId & 0x7;
+ int shift = additionalPhraseId % 8;
return (gSaveBlock1Ptr->additionalPhrases[byteOffset] >> shift) & 1;
}
@@ -4409,7 +4440,7 @@ void sub_811EFC0(u8 additionalPhraseId)
if (additionalPhraseId < 33)
{
int byteOffset = additionalPhraseId / 8;
- int shift = additionalPhraseId & 0x7;
+ int shift = additionalPhraseId % 8;
gSaveBlock1Ptr->additionalPhrases[byteOffset] |= 1 << shift;
}
}
@@ -4427,3 +4458,394 @@ u8 sub_811EFF0(void)
return numAdditionalPhrasesUnlocked;
}
+
+u16 sub_811F01C(void)
+{
+ u16 i;
+ u16 additionalPhraseId;
+ u8 numAdditionalPhrasesUnlocked = sub_811EFF0();
+ if (numAdditionalPhrasesUnlocked == 33)
+ return 0xFFFF;
+
+ additionalPhraseId = Random() % (33 - numAdditionalPhrasesUnlocked);
+ for (i = 0; i < 33; i++)
+ {
+ if (!sub_811EF98(i))
+ {
+ if (additionalPhraseId)
+ {
+ additionalPhraseId--;
+ }
+ else
+ {
+ sub_811EFC0(i);
+ return EC_WORD(EC_GROUP_TRENDY_SAYING, i);
+ }
+ }
+ }
+
+ return 0xFFFF;
+}
+
+u16 sub_811F090(void)
+{
+ u16 i;
+ u16 additionalPhraseId = sub_811EFF0();
+ if (additionalPhraseId == 0)
+ return 0xFFFF;
+
+ additionalPhraseId = Random() % additionalPhraseId;
+ for (i = 0; i < 33; i++)
+ {
+ if (sub_811EF98(i))
+ {
+ if (additionalPhraseId)
+ additionalPhraseId--;
+ else
+ return EC_WORD(EC_GROUP_TRENDY_SAYING, i);
+ }
+ }
+
+ return 0xFFFF;
+}
+
+static bool8 sub_811F0F8(void)
+{
+ return IsNationalPokedexEnabled();
+}
+
+static u16 sub_811F108(void)
+{
+ u16 i;
+ u16 numWords;
+ const u16 *species;
+ u16 index = EasyChat_GetNumWordsInGroup(EC_GROUP_POKEMON);
+ if (index == 0)
+ return 0xFFFF;
+
+ index = Random() % index;
+ species = gEasyChatGroups[EC_GROUP_POKEMON].wordData.valueList;
+ numWords = gEasyChatGroups[EC_GROUP_POKEMON].numWords;
+ for (i = 0; i < numWords; i++)
+ {
+ u16 dexNum = SpeciesToNationalPokedexNum(*species);
+ if (GetSetPokedexFlag(dexNum, FLAG_GET_SEEN))
+ {
+ if (index)
+ index--;
+ else
+ return EC_WORD(EC_GROUP_POKEMON, *species);
+ }
+
+ species++;
+ }
+
+ return 0xFFFF;
+}
+
+void InitEasyChatPhrases(void)
+{
+ u16 i, j;
+
+ for (i = 0; i < 4; i++)
+ gSaveBlock1Ptr->unk2BB0[i] = gUnknown_0859E62C[i];
+
+ for (i = 0; i < 6; i++)
+ gSaveBlock1Ptr->unk2BBC[i] = gUnknown_0859E634[i];
+
+ for (i = 0; i < 6; i++)
+ gSaveBlock1Ptr->unk2BC8[i] = gUnknown_0859E640[i];
+
+ for (i = 0; i < 6; i++)
+ gSaveBlock1Ptr->unk2BD4[i] = gUnknown_0859E64C[i];
+
+ for (i = 0; i < MAIL_COUNT; i++)
+ {
+ for (j = 0; j < MAIL_WORDS_COUNT; j++)
+ gSaveBlock1Ptr->mail[i].words[j] = 0xFFFF;
+ }
+
+ // BUG: This is supposed to clear 64 bits, but this loop is clearing 64 bytes.
+ // However, this bug has no resulting effect on gameplay because only the
+ // Mauville old man data is corrupted, which is initialized directly after
+ // this function is called when starting a new game.
+ for (i = 0; i < 64; i++)
+ gSaveBlock1Ptr->additionalPhrases[i] = 0;
+}
+
+static bool8 sub_811F28C(void)
+{
+ gUnknown_0203A120 = Alloc(sizeof(*gUnknown_0203A120));
+ if (!gUnknown_0203A120)
+ return FALSE;
+
+ sub_811F2D4();
+ sub_811F46C();
+ return TRUE;
+}
+
+static void sub_811F2B8(void)
+{
+ if (gUnknown_0203A120)
+ FREE_AND_SET_NULL(gUnknown_0203A120);
+}
+
+static void sub_811F2D4(void)
+{
+ int i;
+
+ gUnknown_0203A120->unk0 = 0;
+ if (GetNationalPokedexCount(FLAG_GET_SEEN))
+ gUnknown_0203A120->unk2[gUnknown_0203A120->unk0++] = EC_GROUP_POKEMON;
+
+ for (i = EC_GROUP_TRAINER; i <= EC_GROUP_ADJECTIVES; i++)
+ gUnknown_0203A120->unk2[gUnknown_0203A120->unk0++] = i;
+
+ if (FlagGet(FLAG_SYS_GAME_CLEAR))
+ {
+ gUnknown_0203A120->unk2[gUnknown_0203A120->unk0++] = EC_GROUP_EVENTS;
+ gUnknown_0203A120->unk2[gUnknown_0203A120->unk0++] = EC_GROUP_MOVE_1;
+ gUnknown_0203A120->unk2[gUnknown_0203A120->unk0++] = EC_GROUP_MOVE_2;
+ }
+
+ if (FlagGet(FLAG_SYS_HIPSTER_MEET))
+ gUnknown_0203A120->unk2[gUnknown_0203A120->unk0++] = EC_GROUP_TRENDY_SAYING;
+
+ if (IsNationalPokedexEnabled())
+ gUnknown_0203A120->unk2[gUnknown_0203A120->unk0++] = EC_GROUP_POKEMON_2;
+}
+
+static u8 sub_811F3AC(void)
+{
+ return gUnknown_0203A120->unk0;
+}
+
+static u8 sub_811F3B8(u8 index)
+{
+ if (index >= gUnknown_0203A120->unk0)
+ return EC_NUM_GROUPS;
+ else
+ return gUnknown_0203A120->unk2[index];
+}
+
+u8 *unref_sub_811F3E0(u8 *dest, u8 groupId, u16 totalChars)
+{
+ u16 i;
+ u8 *str = StringCopy(dest, gEasyChatGroupNamePointers[groupId]);
+ for (i = str - dest; i < totalChars; i++)
+ {
+ *str = CHAR_SPACE;
+ str++;
+ }
+
+ *str = EOS;
+ return str;
+}
+
+static const u8 *GetEasyChatWordGroupName(u8 groupId)
+{
+ return gEasyChatGroupNamePointers[groupId];
+}
+
+static u8 *CopyEasyChatWordPadded(u8 *dest, u16 easyChatWord, u16 totalChars)
+{
+ u16 i;
+ u8 *str = CopyEasyChatWord(dest, easyChatWord);
+ for (i = str - dest; i < totalChars; i++)
+ {
+ *str = CHAR_SPACE;
+ str++;
+ }
+
+ *str = EOS;
+ return str;
+}
+
+static void sub_811F46C(void)
+{
+ int i, j, k;
+ int numWords;
+ const u16 *words;
+ u16 numToProcess;
+ int index;
+
+ for (i = 0; i < 27; i++)
+ {
+ numWords = gEasyChatWordsByLetterPointers[i].numWords;
+ words = gEasyChatWordsByLetterPointers[i].words;
+ gUnknown_0203A120->unk2E[i] = 0;
+ index = 0;
+ for (j = 0; j < numWords; j++)
+ {
+ if (*words == 0xFFFF)
+ {
+ words++;
+ numToProcess = *words;
+ words++;
+ j += 1 + numToProcess;
+ }
+ else
+ {
+ numToProcess = 1;
+ }
+
+ for (k = 0; k < numToProcess; k++)
+ {
+ if (sub_811F860(words[k]))
+ {
+ gUnknown_0203A120->unk64[i][index++] = words[k];
+ gUnknown_0203A120->unk2E[i]++;
+ break;
+ }
+ }
+
+ words += numToProcess;
+ }
+ }
+}
+
+static void sub_811F548(int arg0, u16 groupId)
+{
+ if (!arg0)
+ gUnknown_0203A120->unk3BA0 = sub_811F5C4(groupId);
+ else
+ gUnknown_0203A120->unk3BA0 = sub_811F6B8(groupId);
+}
+
+static u16 sub_811F578(u16 arg0)
+{
+ if (arg0 >= gUnknown_0203A120->unk3BA0)
+ return 0xFFFF;
+ else
+ return gUnknown_0203A120->unk3984[arg0];
+}
+
+static u16 sub_811F5B0(void)
+{
+ return gUnknown_0203A120->unk3BA0;
+}
+
+static u16 sub_811F5C4(u16 groupId)
+{
+ u32 i;
+ int totalWords;
+ const u16 *list;
+ const struct EasyChatWordInfo *wordInfo;
+ u16 numWords = gEasyChatGroups[groupId].numWords;
+
+ if (groupId == EC_GROUP_POKEMON || groupId == EC_GROUP_POKEMON_2
+ || groupId == EC_GROUP_MOVE_1 || groupId == EC_GROUP_MOVE_2)
+ {
+ list = gEasyChatGroups[groupId].wordData.valueList;
+ for (i = 0, totalWords = 0; i < numWords; i++)
+ {
+ if (sub_811F764(list[i], groupId))
+ gUnknown_0203A120->unk3984[totalWords++] = EC_WORD(groupId, list[i]);
+ }
+
+ return totalWords;
+ }
+ else
+ {
+ wordInfo = gEasyChatGroups[groupId].wordData.words;
+ for (i = 0, totalWords = 0; i < numWords; i++)
+ {
+ u16 alphabeticalOrder = wordInfo[i].alphabeticalOrder;
+ if (sub_811F764(alphabeticalOrder, groupId))
+ gUnknown_0203A120->unk3984[totalWords++] = EC_WORD(groupId, alphabeticalOrder);
+ }
+
+ return totalWords;
+ }
+}
+
+static u16 sub_811F6B8(u16 alphabeticalGroup)
+{
+ u16 i;
+ u16 totalWords;
+
+ for (i = 0, totalWords = 0; i < gUnknown_0203A120->unk2E[alphabeticalGroup]; i++)
+ gUnknown_0203A120->unk3984[totalWords++] = gUnknown_0203A120->unk64[alphabeticalGroup][i];
+
+ return totalWords;
+}
+
+static bool8 sub_811F72C(u8 arg0)
+{
+ int i;
+ for (i = 0; i < gUnknown_0203A120->unk0; i++)
+ {
+ if (gUnknown_0203A120->unk2[i] == arg0)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+bool8 sub_811F764(u16 wordIndex, u8 groupId)
+{
+ switch (groupId)
+ {
+ case EC_GROUP_POKEMON:
+ return GetSetPokedexFlag(SpeciesToNationalPokedexNum(wordIndex), FLAG_GET_SEEN);
+ case EC_GROUP_POKEMON_2:
+ if (sub_811F838(wordIndex))
+ GetSetPokedexFlag(SpeciesToNationalPokedexNum(wordIndex), FLAG_GET_SEEN);
+ return TRUE;
+ case EC_GROUP_MOVE_1:
+ case EC_GROUP_MOVE_2:
+ return TRUE;
+ case EC_GROUP_TRENDY_SAYING:
+ return sub_811EF98(wordIndex);
+ default:
+ return gEasyChatGroups[groupId].wordData.words[wordIndex].enabled;
+ }
+}
+
+static int sub_811F838(u16 species)
+{
+ u32 i;
+ for (i = 0; i < ARRAY_COUNT(gUnknown_0859E658); i++)
+ {
+ if (gUnknown_0859E658[i] == species)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static u8 sub_811F860(u16 easyChatWord)
+{
+ u8 groupId = EC_GROUP(easyChatWord);
+ u32 index = EC_INDEX(easyChatWord);
+ if (!sub_811F72C(groupId))
+ return FALSE;
+ else
+ return sub_811F764(index, groupId);
+}
+
+void InitializeEasyChatWordArray(u16 *words, u16 length)
+{
+ u16 i;
+ for (i = length - 1; i != 0xFFFF; i--)
+ *(words++) = 0xFFFF;
+}
+
+void sub_811F8BC(void)
+{
+ int i;
+ u16 *words = GetSaveBlock1Field3564();
+ for (i = 0; i < 4; i++)
+ words[i] = 0xFFFF;
+}
+
+bool32 sub_811F8D8(int easyChatWord)
+{
+ int groupId = EC_GROUP(easyChatWord);
+ int mask = 0x7F;
+ int index = EC_INDEX(easyChatWord);
+ if (!sub_811EA28(groupId & mask))
+ return FALSE;
+ else
+ return sub_811F764(index, groupId & mask);
+}