diff options
Diffstat (limited to 'arm9/src')
-rw-r--r-- | arm9/src/msgdata.c | 400 | ||||
-rw-r--r-- | arm9/src/nutdata.c | 14 | ||||
-rw-r--r-- | arm9/src/pokemon.c | 27 | ||||
-rw-r--r-- | arm9/src/string_util.c | 4 | ||||
-rw-r--r-- | arm9/src/unk_0201B8B8.c | 33 |
5 files changed, 456 insertions, 22 deletions
diff --git a/arm9/src/msgdata.c b/arm9/src/msgdata.c new file mode 100644 index 00000000..ae33e0f5 --- /dev/null +++ b/arm9/src/msgdata.c @@ -0,0 +1,400 @@ +#include "global.h" +#include "filesystem.h" +#include "msgdata.h" +#include "heap.h" +#include "MI_memory.h" +#include "string16.h" +#include "proto.h" + +#pragma thumb on + +static void * LoadSingleElementFromNarc(NarcId narc_id, s32 file_id, u32 heap_id); +static void FreeMsgDataRawData(void * data); +static void ReadMsgData_ExistingTable_ExistingArray(struct MsgDataTable * table, u32 num, u16 * dest); +static void ReadMsgData_NewNarc_ExistingArray(NarcId narc_id, u32 group, u32 num, u32 heap_id, u16 * dest); +static void CopyEncryptedMessage16(u16 * dest, const u16 * src, struct MsgDataAlloc * param); +static void ReadMsgData_ExistingTable_ExistingString(struct MsgDataTable * table, u32 num, struct String * dest); +static struct String * ReadMsgData_ExistingTable_NewString(struct MsgDataTable * table, u32 num, u32 heap_id); +static void ReadMsgData_ExistingNarc_ExistingString(NARC * narc, u32 group, u32 num, u32 heap_id, struct String * dest); +static struct String * ReadMsgData_ExistingNarc_NewString(NARC * narc, u32 group, u32 num, u32 heap_id); +static u16 GetMsgCount_ExistingTable(struct MsgDataTable * tbl); +static u16 GetMsgCount_TableFromNarc(NarcId narc_id, s32 file_id); + +static void * LoadSingleElementFromNarc(NarcId narc_id, s32 file_id, u32 heap_id) +{ + return AllocAndReadWholeNarcMemberByIdPair(narc_id, file_id, heap_id); +} + +static void FreeMsgDataRawData(void * data) +{ + FreeToHeap(data); +} + +inline static void Decrypt1(struct MsgDataAlloc * arg0, u32 arg1, u32 seed) +{ + seed = seed * 765 * (arg1 + 1) & 0xffff; + seed |= seed << 16; + arg0->offset ^= seed; + arg0->length ^= seed; +} + +inline static void Decrypt2(u16 * arg0, u32 count, u32 arg2) +{ + u16 seed = (u16)((arg2 + 1) * 596947); + + while (count-- > 0) + { + *arg0 ^= seed; + arg0++; + seed += 18749; + } +} + +static void ReadMsgData_ExistingTable_ExistingArray(struct MsgDataTable * table, u32 num, u16 * dest) +{ + struct MsgDataAlloc sp0; + + if (num < table->count) + { + sp0 = table->alloc[num]; + Decrypt1(&sp0, num, table->key); + + CopyEncryptedMessage16(dest, (const u16 *)((u8 *)table + sp0.offset), &sp0); + Decrypt2(dest, sp0.length, num); + } + else + { + GF_ASSERT(0); + } +} + +static void ReadMsgData_NewNarc_ExistingArray(NarcId narc_id, u32 group, u32 num, u32 heap_id, u16 * dest) +{ + NARC * narc = NARC_ctor(narc_id, heap_id); + u16 header[2]; + struct MsgDataAlloc alloc; + if (narc != NULL) + { + NARC_ReadFromMember(narc, group, 0, 4, header); + NARC_ReadFromMember(narc, group, 8 * num + 4, 8, &alloc); + Decrypt1(&alloc, num, header[1]); + NARC_ReadFromMember(narc, group, alloc.offset, 2 * alloc.length, dest); + Decrypt2(dest, alloc.length, num); + NARC_dtor(narc); + } +} + +static void CopyEncryptedMessage16(u16 * dest, const u16 * src, struct MsgDataAlloc * param) +{ + MI_CpuCopy16(src, dest, 2 * param->length); +} + +static void ReadMsgData_ExistingTable_ExistingString(struct MsgDataTable * table, u32 num, struct String * dest) +{ + struct MsgDataAlloc alloc; + u16 * buf; + if (num < table->count) + { + alloc = table->alloc[num]; + Decrypt1(&alloc, num, table->key); + buf = AllocFromHeapAtEnd(0, 2 * alloc.length); + if (buf != NULL) + { + MI_CpuCopy16((char *)table + alloc.offset, buf, 2 * alloc.length); + Decrypt2(buf, alloc.length, num); + FUN_02021E8C(dest, buf, alloc.length); + FreeToHeap(buf); + } + } + else + { + GF_ASSERT(0); + StringSetEmpty(dest); + } +} + +static struct String * ReadMsgData_ExistingTable_NewString(struct MsgDataTable * table, u32 num, u32 heap_id) +{ + struct MsgDataAlloc alloc; + u16 * buf; + struct String * dest; + if (num < table->count) + { + alloc = table->alloc[num]; + Decrypt1(&alloc, num, table->key); + buf = AllocFromHeapAtEnd(heap_id, 2 * alloc.length); + if (buf != NULL) + { + MI_CpuCopy16((char *)table + alloc.offset, buf, 2 * alloc.length); + Decrypt2(buf, alloc.length, num); + dest = String_ctor(alloc.length, heap_id); + if (dest != NULL) + FUN_02021E8C(dest, buf, alloc.length); + FreeToHeap(buf); + return dest; + } + else + { + return NULL; + } + } + else + { + GF_ASSERT(0); + return String_ctor(4, heap_id); + } +} + +void ReadMsgData_NewNarc_ExistingString(NarcId narc_id, u32 group, u32 num, u32 heap_id, struct String * dest) +{ + NARC * narc = NARC_ctor(narc_id, heap_id); + if (narc != NULL) + { + ReadMsgData_ExistingNarc_ExistingString(narc, group, num, heap_id, dest); + NARC_dtor(narc); + } +} + +static void ReadMsgData_ExistingNarc_ExistingString(NARC * narc, u32 group, u32 num, u32 heap_id, struct String * dest) +{ + u16 * buf; + u32 size; + u16 sp10[2]; + struct MsgDataAlloc alloc; + + NARC_ReadFromMember(narc, group, 0, 4, sp10); + if (num < sp10[0]) + { + NARC_ReadFromMember(narc, group, 8 * num + 4, 8, &alloc); + Decrypt1(&alloc, num, sp10[1]); + size = alloc.length * 2; + buf = AllocFromHeapAtEnd(heap_id, size); + if (buf != NULL) + { + NARC_ReadFromMember(narc, group, alloc.offset, size, buf); + Decrypt2(buf, alloc.length, num); + FUN_02021E8C(dest, buf, alloc.length); + FreeToHeap(buf); + return; + } + } + else + { + GF_ASSERT(0); + StringSetEmpty(dest); + } +} + +struct String * ReadMsgData_NewNarc_NewString(NarcId narc_id, u32 group, u32 num, u32 heap_id) +{ + NARC * narc = NARC_ctor(narc_id, heap_id); + struct String * string; + if (narc != NULL) + { + string = ReadMsgData_ExistingNarc_NewString(narc, group, num, heap_id); + NARC_dtor(narc); + } + else + { + string = String_ctor(4, heap_id); + } + return string; +} + +static struct String * ReadMsgData_ExistingNarc_NewString(NARC * narc, u32 group, u32 num, u32 heap_id) +{ + struct String * dest; + u16 * buf; + u32 size; + u16 sp10[2]; + struct MsgDataAlloc alloc; + + NARC_ReadFromMember(narc, group, 0, 4, sp10); + if (num < sp10[0]) + { + NARC_ReadFromMember(narc, group, 8 * num + 4, 8, &alloc); + Decrypt1(&alloc, num, sp10[1]); + dest = String_ctor(alloc.length, heap_id); + if (dest != NULL) + { + size = alloc.length * 2; + buf = AllocFromHeapAtEnd(heap_id, size); + if (buf != NULL) + { + NARC_ReadFromMember(narc, group, alloc.offset, size, buf); + Decrypt2(buf, alloc.length, num); + FUN_02021E8C(dest, buf, alloc.length); + FreeToHeap(buf); + } + } + return dest; + } + else + { + GF_ASSERT(0); + return String_ctor(4, heap_id); + } +} + +static u16 GetMsgCount_ExistingTable(struct MsgDataTable * tbl) +{ + return tbl->count; +} + +static u16 GetMsgCount_TableFromNarc(NarcId narc_id, s32 file_id) +{ + u16 n[2]; + ReadFromNarcMemberByIdPair(&n, narc_id, file_id, 0, 4); + return n[0]; +} + +struct MsgData * NewMsgDataFromNarc(u32 type, NarcId narc_id, s32 file_id, u32 heap_id) +{ + struct MsgData * msgData = AllocFromHeapAtEnd(heap_id, sizeof(struct MsgData)); + if (msgData != NULL) + { + if (type == 0) + { + msgData->data.raw = LoadSingleElementFromNarc(narc_id, file_id, heap_id); + if (msgData->data.raw == NULL) + { + FreeToHeap(msgData); + return NULL; + } + } + else + { + msgData->data.narc = NARC_ctor(narc_id, heap_id); + } + msgData->type = (u16)type; + msgData->narc_id = (u16)narc_id; + msgData->file_id = (u16)file_id; + msgData->heap_id = (u16)heap_id; + } + return msgData; +} + +void DestroyMsgData(struct MsgData * msgData) +{ + if (msgData != NULL) + { + switch (msgData->type) + { + case 0: + FreeMsgDataRawData(msgData->data.raw); + break; + case 1: + NARC_dtor(msgData->data.narc); + break; + } + FreeToHeap(msgData); + } +} + +void ReadMsgDataIntoString(struct MsgData * msgData, u32 msg_no, struct String * dest) +{ + switch (msgData->type) + { + case 0: + ReadMsgData_ExistingTable_ExistingString(msgData->data.raw, msg_no, dest); + break; + case 1: + ReadMsgData_ExistingNarc_ExistingString(msgData->data.narc, msgData->file_id, msg_no, msgData->heap_id, dest); + break; + } +} + +struct String * NewString_ReadMsgData(struct MsgData * msgData, u32 msg_no) +{ + switch (msgData->type) + { + case 0: + return ReadMsgData_ExistingTable_NewString(msgData->data.raw, msg_no, msgData->heap_id); + case 1: + return ReadMsgData_ExistingNarc_NewString(msgData->data.narc, msgData->file_id, msg_no, msgData->heap_id); + default: + return NULL; + } +} + +u16 MsgDataGetCount(struct MsgData * msgData) +{ + switch (msgData->type) + { + case 0: + return GetMsgCount_ExistingTable(msgData->data.raw); + case 1: + return GetMsgCount_TableFromNarc((NarcId)msgData->narc_id, msgData->file_id); + default: + return 0; + } +} + +void ReadMsgDataIntoU16Array(struct MsgData * msgData, u32 msg_no, u16 * dest) +{ + switch (msgData->type) + { + case 0: + ReadMsgData_ExistingTable_ExistingArray(msgData->data.raw, msg_no, dest); + break; + case 1: + ReadMsgData_NewNarc_ExistingArray((NarcId)msgData->narc_id, msgData->file_id, msg_no, msgData->heap_id, dest); + break; + } +} + +void GetSpeciesNameIntoArray(u16 species, u32 heap_id, u16 * dest) +{ + struct MsgData * msgData = NewMsgDataFromNarc(1, NARC_MSGDATA_MSG, 362, heap_id); + ReadMsgDataIntoU16Array(msgData, species, dest); + DestroyMsgData(msgData); +} + +struct String * ReadMsgData_ExpandPlaceholders(u32 * a0, struct MsgData * msgData, u32 msgno, u32 a3) +{ + struct String * ret = NULL; + struct String * r4 = String_ctor(1024, 0); + struct String * r5; + if (r4 != NULL) + { + r5 = NewString_ReadMsgData(msgData, msgno); + if (r5 != NULL) + { + StringExpandPlaceholders(a0, r4, r5); + ret = StringDup(r4, a3); + String_dtor(r5); + } + String_dtor(r4); + } + return ret; +} + +struct String * GetMoveName(u32 move, u32 heapno) +{ + struct MsgData * msgData = NewMsgDataFromNarc(1, NARC_MSGDATA_MSG, 588, heapno); + struct String * ret; + if (msgData != NULL) + { + ret = String_ctor(16, heapno); + if (ret != NULL) + { + ReadMsgDataIntoString(msgData, move, ret); + } + DestroyMsgData(msgData); + return ret; + } + return NULL; +} + +struct String * GetSpeciesName(u16 species, u32 heap_id) +{ + struct String * ret; + struct MsgData * msgData = NewMsgDataFromNarc(1, NARC_MSGDATA_MSG, 362, heap_id); + if (msgData != NULL) + { + ret = NewString_ReadMsgData(msgData, species); + DestroyMsgData(msgData); + return ret; + } + return NULL; +} diff --git a/arm9/src/nutdata.c b/arm9/src/nutdata.c index 09542052..a8f916e2 100644 --- a/arm9/src/nutdata.c +++ b/arm9/src/nutdata.c @@ -1,7 +1,7 @@ #include "global.h" #include "filesystem.h" #include "itemtool.h" -#include "msg_data.h" +#include "msgdata.h" #pragma thumb on @@ -20,12 +20,12 @@ void CloseNutsDataNarc(NARC * narc) NARC_dtor(narc); } -struct NutData * LoadNutDataSingle(u32 berry_idx, u32 heap_id) +struct NutData * LoadNutDataSingle(s32 berry_idx, u32 heap_id) { return AllocAndReadWholeNarcMemberByIdPair(NARC_ITEMTOOL_ITEMDATA_NUTS_DATA, berry_idx, heap_id); } -struct NutData * LoadNutDataSingleByItemId(u32 item_id, u32 heap_id) +struct NutData * LoadNutDataSingleByItemId(s32 item_id, u32 heap_id) { return LoadNutDataSingle(item_id - FIRST_BERRY_IDX, heap_id); } @@ -61,18 +61,18 @@ u32 GetNutAttr(struct NutData * nut, u32 attr) } } -u16 * GetNutName(u32 berry_idx, u32 heap_id) +struct String * GetNutName(u32 berry_idx, u32 heap_id) { struct MsgData * msgData = NewMsgDataFromNarc(1, NARC_MSGDATA_MSG, 373, heap_id); - u16 * ret = FUN_0200A914(msgData, berry_idx); + struct String * ret = NewString_ReadMsgData(msgData, berry_idx); DestroyMsgData(msgData); return ret; } -u16 * GetNutDesc(u32 berry_idx, u32 heap_id) +struct String * GetNutDesc(u32 berry_idx, u32 heap_id) { struct MsgData * msgData = NewMsgDataFromNarc(1, NARC_MSGDATA_MSG, 372, heap_id); - u16 * ret = FUN_0200A914(msgData, berry_idx); + struct String * ret = NewString_ReadMsgData(msgData, berry_idx); DestroyMsgData(msgData); return ret; } diff --git a/arm9/src/pokemon.c b/arm9/src/pokemon.c index 8df597a6..a15d20c1 100644 --- a/arm9/src/pokemon.c +++ b/arm9/src/pokemon.c @@ -10,6 +10,7 @@ #include "move_data.h" #include "string_util.h" #include "text.h" +#include "msgdata.h" #include "constants/abilities.h" #include "constants/items.h" #include "constants/moves.h" @@ -843,7 +844,7 @@ u32 GetBoxMonDataInternal(struct BoxPokemon * boxmon, int attr, void * dest) break; case MON_DATA_NICKNAME: if (boxmon->checksum_fail) - GetSpeciesName(SPECIES_MANAPHY_EGG, 0, dest); + GetSpeciesNameIntoArray(SPECIES_MANAPHY_EGG, 0, dest); else { u16 * dest16 = (u16 *)dest; @@ -860,9 +861,9 @@ u32 GetBoxMonDataInternal(struct BoxPokemon * boxmon, int attr, void * dest) case MON_DATA_NICKNAME_3: if (boxmon->checksum_fail) { - u16 * buffer = FUN_0200AA50(SPECIES_MANAPHY_EGG, 0); - FUN_02021A74(dest, buffer); - FUN_02021A20(buffer); + struct String * buffer = GetSpeciesName(SPECIES_MANAPHY_EGG, 0); + StringCopy(dest, buffer); + String_dtor(buffer); } else { @@ -978,7 +979,7 @@ u32 GetBoxMonDataInternal(struct BoxPokemon * boxmon, int attr, void * dest) } break; case MON_DATA_SPECIES_NAME: - GetSpeciesName(blockA->species, 0, dest); + GetSpeciesNameIntoArray(blockA->species, 0, dest); break; } return ret; @@ -1090,7 +1091,7 @@ void SetBoxMonDataInternal(struct BoxPokemon * boxmon, int attr, void * value) u16 namebuf[POKEMON_NAME_LENGTH + 1]; u16 namebuf2[POKEMON_NAME_LENGTH + 1]; u16 namebuf3[POKEMON_NAME_LENGTH + 1]; - u16 * speciesName; + struct String * speciesName; PokemonDataBlockA *blockA = &GetSubstruct(boxmon, boxmon->pid, 0)->blockA; PokemonDataBlockB *blockB = &GetSubstruct(boxmon, boxmon->pid, 1)->blockB; @@ -1309,7 +1310,7 @@ void SetBoxMonDataInternal(struct BoxPokemon * boxmon, int attr, void * value) blockB->Unused = VALUE(u16); break; case MON_DATA_NICKNAME_2: - GetSpeciesName(blockA->species, 0, namebuf); + GetSpeciesNameIntoArray(blockA->species, 0, namebuf); blockB->isNicknamed = StringNotEqual(namebuf, value); // fallthrough case MON_DATA_NICKNAME: @@ -1319,7 +1320,7 @@ void SetBoxMonDataInternal(struct BoxPokemon * boxmon, int attr, void * value) } break; case MON_DATA_NICKNAME_4: - GetSpeciesName(blockA->species, 0, namebuf2); + GetSpeciesNameIntoArray(blockA->species, 0, namebuf2); FUN_02021EF0(value, namebuf3, POKEMON_NAME_LENGTH + 1); blockB->isNicknamed = StringNotEqual(namebuf2, namebuf3); // fallthrough @@ -1420,9 +1421,9 @@ void SetBoxMonDataInternal(struct BoxPokemon * boxmon, int attr, void * value) blockB->spdefIV = (VALUE(u32) >> 25) & 0x1F; break; case MON_DATA_SPECIES_NAME: - speciesName = FUN_0200AA50(blockA->species, 0); + speciesName = GetSpeciesName(blockA->species, 0); FUN_02021EF0(speciesName, blockC->nickname, POKEMON_NAME_LENGTH + 1); - FUN_02021A20(speciesName); + String_dtor(speciesName); break; } #undef VALUE @@ -3682,13 +3683,13 @@ BOOL FUN_0206A9AC(struct BoxPokemon * boxmon, struct SaveBlock2 * sb2, u32 heap_ u32 myGender = FUN_020239CC(sb2); u32 otGender = GetBoxMonData(boxmon, MON_DATA_MET_GENDER, NULL); struct String * r7 = FUN_020239A0(sb2, heap_id); - struct String * r6 = FUN_020219F4(OT_NAME_LENGTH + 1, heap_id); + struct String * r6 = String_ctor(OT_NAME_LENGTH + 1, heap_id); BOOL ret = FALSE; GetBoxMonData(boxmon, MON_DATA_OT_NAME_2, r6); if (myId == otId && myGender == otGender && FUN_02021CE0(r7, r6) == 0) ret = TRUE; - FUN_02021A20(r6); - FUN_02021A20(r7); + String_dtor(r6); + String_dtor(r7); return ret; } diff --git a/arm9/src/string_util.c b/arm9/src/string_util.c index 54ad61fc..19ed5fa3 100644 --- a/arm9/src/string_util.c +++ b/arm9/src/string_util.c @@ -32,7 +32,7 @@ const s32 gPowersOfTen[] = { 1000000000,
};
-THUMB_FUNC void StringCopy(u16 *dest, const u16 *src)
+THUMB_FUNC void CopyU16StringArray(u16 *dest, const u16 *src)
{
u16 c = *src;
while (c != EOS) {
@@ -44,7 +44,7 @@ THUMB_FUNC void StringCopy(u16 *dest, const u16 *src) *dest = EOS;
}
-THUMB_FUNC u16 *StringCopyN(u16 *dest, const u16 *src, u32 num)
+THUMB_FUNC u16 *CopyU16StringArrayN(u16 *dest, const u16 *src, u32 num)
{
u32 copied = 0;
if (num > copied) {
diff --git a/arm9/src/unk_0201B8B8.c b/arm9/src/unk_0201B8B8.c new file mode 100644 index 00000000..abb92067 --- /dev/null +++ b/arm9/src/unk_0201B8B8.c @@ -0,0 +1,33 @@ +#include "global.h" +#include "unk_0201B8B88.h" + +#pragma thumb on + +const u16 * FUN_0201B8B8(const u16 * r4) +{ + GF_ASSERT(*r4 == 0xFFFE); + if (*r4 == 0xFFFE) { + u16 r0 = r4[2]; + r4 += 3; + r4 += r0; + } + return r4; +} + +u16 FUN_0201B8E0(const u16 * r4) +{ + GF_ASSERT(*r4 == 0xFFFE); + return r4[1]; +} + +BOOL FUN_0201B8F8(const u16 * r4) +{ + return (FUN_0201B8E0(r4) & 0xFF00) == 0x100; +} + +u16 FUN_0201B914(const u16 * r5, u32 r4) +{ + GF_ASSERT(*r5 == 0xFFFE); + GF_ASSERT(r4 < r5[2]); + return r5[3 + r4]; +} |