From 667c6eba270e2d862acd70be358f480c017dd86e Mon Sep 17 00:00:00 2001 From: citrusbolt Date: Mon, 19 Feb 2024 12:43:38 -0700 Subject: [PATCH 1/4] Start going through `unk_200C5DC.c` --- payload/include/all.h | 24 ++-- payload/include/constants/flags.h | 1 + payload/include/global.h | 2 + payload/include/libpmagb/save.h | 1 + payload/include/unk_200C5DC.h | 9 +- payload/src/all.c | 2 +- payload/src/all4.c | 12 +- payload/src/main.c | 12 +- payload/src/unk_200C5DC.c | 200 +++++++++++++++--------------- payload/sym_common.txt | 4 +- 10 files changed, 139 insertions(+), 128 deletions(-) diff --git a/payload/include/all.h b/payload/include/all.h index b24efb1..444b3e4 100644 --- a/payload/include/all.h +++ b/payload/include/all.h @@ -1,18 +1,18 @@ #ifndef GUARD_ALL_H #define GUARD_ALL_H -struct UnkStruct868 +struct ExternalEventData2 { - u32 a0; - u32 a4; - u32 a8_0:24; - u32 a11_0:1; - u32 a11_1:1; - u32 a11_2:1; - u32 a11_3:1; - u32 a11_4:4; - u32 a12:24; - u32 a15:8; + u32 unknownExternalDataFields1; + u32 unknownExternalDataFields2; + u32 currentPokeCoupons:24; + u32 gotGoldPokeCouponTitleReward:1; + u32 gotSilverPokeCouponTitleReward:1; + u32 gotBronzePokeCouponTitleReward:1; + u32 receivedAgetoCelebi:1; + u32 unknownExternalDataFields3:4; + u32 totalEarnedPokeCoupons:24; + u32 unknownExternalDataFields4:8; }; struct UnkStruct81C @@ -75,7 +75,7 @@ struct UnkStruct_02024960 u8 unk_85A; u8 unk_85B; u8 ALIGNED(4) field85C[12]; // Aligned for u32 copy - struct UnkStruct868 unk868; + struct ExternalEventData2 externalEventData; u8 unk_878; u8 unk_879; u8 unk_87A; diff --git a/payload/include/constants/flags.h b/payload/include/constants/flags.h index efd5b9e..2be0299 100644 --- a/payload/include/constants/flags.h +++ b/payload/include/constants/flags.h @@ -3,6 +3,7 @@ #define SYSTEM_FLAGS 0x800 +#define FLAG_SYS_POKEDEX_GET (SYSTEM_FLAGS + 0x01) #define FLAG_SYS_GAME_CLEAR (SYSTEM_FLAGS + 0x04) #define FLAG_SYS_NATIONAL_DEX (SYSTEM_FLAGS + 0x36) #define FLAG_SYS_RIBBON_GET (SYSTEM_FLAGS + 0x3B) diff --git a/payload/include/global.h b/payload/include/global.h index 9c3df43..9d45fd0 100644 --- a/payload/include/global.h +++ b/payload/include/global.h @@ -39,6 +39,8 @@ #define PLAYER_NAME_LENGTH 7 #define ABILITY_NAME_LENGTH 12 #define MAX_MON_MOVES 4 +#define TRAINER_ID_LENGTH 4 +#define GIFT_RIBBONS_COUNT 11 #define CONTEST_CATEGORY_COOL 0 #define CONTEST_CATEGORY_BEAUTY 1 diff --git a/payload/include/libpmagb/save.h b/payload/include/libpmagb/save.h index c2eed79..10bff01 100644 --- a/payload/include/libpmagb/save.h +++ b/payload/include/libpmagb/save.h @@ -7,6 +7,7 @@ #define SAVE_STATUS_EMPTY 0 #define SAVE_STATUS_OK 1 +#define SAVE_STATUS_CORRUPT 2 #define SAVE_STATUS_NO_FLASH 4 #define SAVE_STATUS_ERROR 0xFF diff --git a/payload/include/unk_200C5DC.h b/payload/include/unk_200C5DC.h index e5c51d4..0b7ec5b 100644 --- a/payload/include/unk_200C5DC.h +++ b/payload/include/unk_200C5DC.h @@ -1,12 +1,17 @@ #ifndef GUARD_unk_200C5DC_H #define GUARD_unk_200C5DC_H +#define CONTINUE_GAME_WARP (1 << 0) +#define POKECENTER_SAVEWARP (1 << 1) +#define LOBBY_SAVEWARP (1 << 2) +#define CHAMPION_SAVEWARP (1 << 7) + struct UnkStruct_020251F0 { volatile u32 *field0; u32 field4; u8 field8[2]; - vu8 field10; + vu8 state; u8 field11; u8 field12; u8 field13; @@ -37,7 +42,7 @@ extern volatile struct UnkStruct_020251F0 gUnknown_020251F0; void SetSpeciesCaughtFlag(u32 species, struct Pokemon *mon); u8 GetPlayerMapType(void); u8 *sub_0200CB34(u32 id); -struct Struct_gUnknown_02023F50 *sub_0200C9C0(u8 *sav2, u8 *sav1, u32 arg2); +struct PlayerLinkInfo *SetPlayerLinkInfo(u8 *sav2, u8 *sav1, u32 saveStatus); s32 StringCompare(const u8 *str1, const u8 *str2); u8 *StringCopy(u8 *dst, const u8 *src); u16 GetStringSizeHandleExtCtrlCodes(u8 *str); diff --git a/payload/src/all.c b/payload/src/all.c index 05bf86f..bf35834 100644 --- a/payload/src/all.c +++ b/payload/src/all.c @@ -101,7 +101,7 @@ static u8 gScreenIsFadedOut; static u8 sPadding[2]; static u16 sSomeWindowBaseBlock; -extern u8 gUnknown_020217B4; +extern u8 gSaveStatus; extern u8 gStringBuffers[][32]; extern const u8 gFont1JapanGfx[]; extern const u8 gFont0JapanGfx[]; diff --git a/payload/src/all4.c b/payload/src/all4.c index b5036f2..af9c1b4 100644 --- a/payload/src/all4.c +++ b/payload/src/all4.c @@ -41,7 +41,7 @@ struct Unk2021A20Str extern struct Unk2021A20Str gUnknown_02021A20; // Error related -extern u8 gUnknown_020217B4; +extern u8 gSaveStatus; extern u8 gRomDetection_IsEnglishROM; extern u8 gUnknown_020217B8; extern const struct Window gFont0LatinInfo; @@ -82,15 +82,15 @@ static inline void PrintErrorMsg(struct Window *win, u32 msgId) static void sub_0200472C(void) { - switch (gUnknown_020217B4) + switch (gSaveStatus) { - case 2: + case SAVE_STATUS_CORRUPT: PrintErrorMsg(gMessageWindowPtr, 6); break; - case 0xFF: + case SAVE_STATUS_ERROR: PrintErrorMsg(gMessageWindowPtr, 7); break; - case 0: + case SAVE_STATUS_EMPTY: PrintErrorMsg(gMessageWindowPtr, 8); break; default: @@ -146,7 +146,7 @@ u32 sub_020047D4(void) gUnknown_02024960.unk_87A = 0; gUnknown_02024960.unk84C_00 = 0; FadeIn(); - if (gUnknown_020217B4 == 2 || gUnknown_020217B4 == 0xFF || gUnknown_020217B4 == 0) + if (gSaveStatus == SAVE_STATUS_CORRUPT || gSaveStatus == SAVE_STATUS_ERROR || gSaveStatus == SAVE_STATUS_EMPTY) { // Game stuck while (1) diff --git a/payload/src/main.c b/payload/src/main.c index d9ecd2c..c1886bb 100644 --- a/payload/src/main.c +++ b/payload/src/main.c @@ -25,7 +25,7 @@ struct RomHeader extern void sub_0200D9EC(void); extern const struct RomHeader gRomHeader; -extern u8 gUnknown_020217B4; +extern u8 gSaveStatus; extern u8 gUnknown_020217B8; extern IntrFunc *gTimer1InterruptFunction; @@ -104,7 +104,7 @@ void GF_Main(void) InitFlash(2, gTimer1InterruptFunction); SaveBlocksInit(); SetSaveSectorPtrs(); - gUnknown_020217B4 = ReadSaveBlockChunks(); + gSaveStatus = ReadSaveBlockChunks(); gUnknown_020217B8 = sub_0200043C(); @@ -115,7 +115,7 @@ void GF_Main(void) REG_DISPSTAT = 8; REG_DISPCNT &= (0xFF7F); REG_IME = 1; - sub_0200C9C0(gSaveBlock2Ptr, gSaveBlock1Ptr, gUnknown_020217B4); + SetPlayerLinkInfo(gSaveBlock2Ptr, gSaveBlock1Ptr, gSaveStatus); sub_0200D924(gRomHeader.unkA8); @@ -164,7 +164,7 @@ NAKED void GF_Main(void) bl InitFlash\t\n\ bl SaveBlocksInit\t\n\ bl SetSaveSectorPtrs\t\n\ - ldr r4, =gUnknown_020217B4\t\n\ + ldr r4, =gSaveStatus\t\n\ bl ReadSaveBlockChunks\t\n\ strb r0, [r4]\t\n\ ldr r5, =gUnknown_020217B8\t\n\ @@ -231,9 +231,9 @@ _0200032C:\t\n\ ldr r0, [r0]\t\n\ ldr r1, =gSaveBlock1Ptr\t\n\ ldr r1, [r1]\t\n\ - ldr r2, =gUnknown_020217B4\t\n\ + ldr r2, =gSaveStatus\t\n\ ldrb r2, [r2]\t\n\ - bl sub_0200C9C0\t\n\ + bl SetPlayerLinkInfo\t\n\ adds r0, r6, #0\t\n\ bl sub_0200D924\t\n\ ldr r0, =sub_0200D9EC\t\n\ diff --git a/payload/src/unk_200C5DC.c b/payload/src/unk_200C5DC.c index 5afda06..cb331f7 100644 --- a/payload/src/unk_200C5DC.c +++ b/payload/src/unk_200C5DC.c @@ -1,5 +1,6 @@ #include "global.h" #include "libpmagb/agb_rom.h" +#include "libpmagb/save.h" #include "gflib/characters.h" #include "gflib/keys.h" #include "gflib/init.h" @@ -10,11 +11,12 @@ #include "unk_200C5DC.h" #include "rom_info.h" #include "constants/items.h" +#include "constants/maps.h" // This file's functions u8 GetPlayerMapType(void); -u8 USRom_GetPlayerMapType(struct SaveBlock1 *sav1); -bool8 sub_0200CD88(void); +u8 GetRSPlayerMapType(struct SaveBlock1 *sav1); +bool8 CheckIfPokedexIsObtained(void); bool32 IsFRLG(void); u8 ExtCtrlCodeGetLength(u8 c); @@ -159,75 +161,75 @@ void SetSpeciesCaughtFlag(u32 species, struct Pokemon *mon) GetSetPokedexFlag(nationalDexNo, FLAG_SET_CAUGHT); } -struct Struct_gUnknown_02023F50 +struct PlayerLinkInfo { - u32 field0_0:1; - u32 field0_1:1; - u32 field0_2:1; - u32 field0_3:1; - u32 field0_4:4; - u32 field1_0:2; + u32 hasPokedex:1; + u32 isInPokeCenter:1; + u32 isFRLG:1; + u32 isChampion:1; + u32 language:4; + u32 errorCode:2; u32 unused:15; - u8 field4[8]; - u32 field12; - u8 field16[4]; + u8 playerName[PLAYER_NAME_LENGTH + 1]; + u32 playerGender; + u8 playerTrainerId[TRAINER_ID_LENGTH]; struct Pokemon party[PARTY_SIZE]; - u8 giftRibbons[11]; + u8 giftRibbons[GIFT_RIBBONS_COUNT]; }; -extern struct Struct_gUnknown_02023F50 gUnknown_02023F50; +extern struct PlayerLinkInfo gPlayerLinkInfo; -struct Struct_gUnknown_02023F50 *sub_0200C9C0(u8 *sav2, u8 *sav1, u32 arg2) +struct PlayerLinkInfo *SetPlayerLinkInfo(u8 *sav2, u8 *sav1, u32 saveStatus) { s32 i; - struct Struct_gUnknown_02023F50* structPtr = &gUnknown_02023F50; + struct PlayerLinkInfo* structPtr = &gPlayerLinkInfo; - CpuFill16(0, &gUnknown_02023F50, sizeof(struct Struct_gUnknown_02023F50)); - if (arg2 == 1) + CpuFill16(0, &gPlayerLinkInfo, sizeof(struct PlayerLinkInfo)); + if (saveStatus == SAVE_STATUS_OK) { u8 *saveData; if (!gAgbPmRomParams->blockLinkColoXD) { - structPtr->field0_0 = sub_0200CD88(); - structPtr->field0_1 = ((GetPlayerMapType() & 2) != 0); - structPtr->field0_2 = IsFRLG(); - structPtr->field0_3 = ((GetPlayerMapType() & 0x80) != 0); - structPtr->field0_4 = gAgbPmRomParams->language; + structPtr->hasPokedex = CheckIfPokedexIsObtained(); + structPtr->isInPokeCenter = ((GetPlayerMapType() & POKECENTER_SAVEWARP) != 0); + structPtr->isFRLG = IsFRLG(); + structPtr->isChampion = ((GetPlayerMapType() & CHAMPION_SAVEWARP) != 0); + structPtr->language = gAgbPmRomParams->language; } saveData = &sav2[gAgbPmRomParams->playerNameOffset]; - StringCopy(structPtr->field4, saveData); + StringCopy(structPtr->playerName, saveData); saveData = &sav2[gAgbPmRomParams->playerGenderOffset]; - structPtr->field12 = *saveData; + structPtr->playerGender = *saveData; saveData = &sav2[gAgbPmRomParams->trainerIdOffset]; for (i = 0; i < 4; i++) - structPtr->field16[i] = saveData[i]; + structPtr->playerTrainerId[i] = saveData[i]; for (i = 0; i < PARTY_SIZE; i++) CpuCopy16(&gPlayerPartyPtr[i], &structPtr->party[i], sizeof(struct Pokemon)); - for (i = 0; i < 11; i++) + for (i = 0; i < GIFT_RIBBONS_COUNT; i++) structPtr->giftRibbons[i] = gGiftRibbonsPtr[i]; } - else if (arg2 == 2) + else if (saveStatus == SAVE_STATUS_CORRUPT) { - structPtr->field1_0 = 1; + structPtr->errorCode = 1; } - else if (arg2 == 0xFF) + else if (saveStatus == SAVE_STATUS_ERROR) { - structPtr->field1_0 = 2; + structPtr->errorCode = 2; } - else if (arg2 == 0) + else if (saveStatus == SAVE_STATUS_EMPTY) { - structPtr->field1_0 = 3; + structPtr->errorCode = 3; } return structPtr; } -struct Struct_gUnknown_02023F50 *sub_0200CB2C(void) +struct PlayerLinkInfo *GetPlayerLinkInfo(void) { - return &gUnknown_02023F50; + return &gPlayerLinkInfo; } extern u8 gUnknown_020241D0[][320]; @@ -294,28 +296,28 @@ extern void SoftReset(u32); void DetectROM(void) { - u32 val, r4, r3; + u32 gameCode, rsVersion, notEnglishRS; gRomDetection_IsRubySapphire = FALSE; gRomDetection_IsEnglishROM = FALSE; - r4 = 0; - val = *(u32 *)(0x80000AC); - switch (val) + rsVersion = 0; + gameCode = *(u32 *)(0x80000AC); + switch (gameCode) { default: - r3 = TRUE; + notEnglishRS = TRUE; gRomDetection_IsEnglishROM = TRUE; break; case 0x45565841: // AXVE gRomDetection_IsEnglishROM = TRUE; - r4 = 2; - r3 = FALSE; + rsVersion = VERSION_RUBY; + notEnglishRS = FALSE; gRomDetection_IsRubySapphire = TRUE; break; case 0x45505841: // AXPE gRomDetection_IsEnglishROM = TRUE; - r4 = 1; - r3 = FALSE; + rsVersion = VERSION_SAPPHIRE; + notEnglishRS = FALSE; gRomDetection_IsRubySapphire = TRUE; break; case 0x46505841: // AXPF @@ -326,16 +328,16 @@ void DetectROM(void) case 0x49505841: // AXPI case 0x53505841: // AXPS case 0x53565841: // AXVS - r3 = TRUE; + notEnglishRS = TRUE; gRomDetection_IsRubySapphire = TRUE; break; } - if (r3) + if (notEnglishRS) { gAgbPmRomParams = (void*)(0x8000100); } - else if (r4 == 2) + else if (rsVersion == VERSION_RUBY) { if (*(u8*)(0x80000BC) == 0) gAgbPmRomParams = &gAgbPmRomParams_AXVE_rev0; @@ -350,7 +352,7 @@ void DetectROM(void) gAgbPmRomParams = &gAgbPmRomParams_AXPE_rev2; } - if (r3 == 1) + if (notEnglishRS == TRUE) { if (gAgbPmRomParams->language == LANGUAGE_ENGLISH) gRomDetection_IsEnglishROM = TRUE; @@ -368,9 +370,9 @@ u8 GetPlayerMapType(void) } else { - ret = USRom_GetPlayerMapType(gSaveBlock1Ptr); - if (ret & 1) - ret |= 0x80; + ret = GetRSPlayerMapType(gSaveBlock1Ptr); + if (ret & CONTINUE_GAME_WARP) + ret |= CHAMPION_SAVEWARP; } return ret; } @@ -380,13 +382,13 @@ static void UNUSED sub_0200CD84(void) } -u8 sub_0200CD88(void) +u8 CheckIfPokedexIsObtained(void) { bool32 val; if (!gRomDetection_IsRubySapphire) val = ((*((u8 *)(gSaveBlock2Ptr) + gAgbPmRomParams->gcnLinkFlagsOffset) & 1)); else - val = CheckFlag(0x801); + val = CheckFlag(FLAG_SYS_POKEDEX_GET); if (!val) return FALSE; @@ -465,26 +467,26 @@ s32 StringCompare(const u8 *str1, const u8 *str2) u8 ExtCtrlCodeGetLength(u8 c) { u8 len = 0; - if (c <= 22) + if (c <= EXT_CTRL_CODE_ENG) len = gExtCtrlCodeLengths[c]; return len; } -u8 USRom_GetPlayerMapType(struct SaveBlock1 *sav1) +u8 GetRSPlayerMapType(struct SaveBlock1 *sav1) { s32 i; u16 mapGroup = sav1->location.mapGroup; u16 map = (mapGroup << 8) + sav1->location.mapNum; - for (i = 0; gRSPokemonCenterMaps[i] != 0xFFFF; i++) + for (i = 0; gRSPokemonCenterMaps[i] != MAP_UNDEFINED; i++) { if (gRSPokemonCenterMaps[i] == map) - return 2; + return POKECENTER_SAVEWARP; } - for (i = 0; gRSSpecialAreaMaps[i] != 0xFFFF; i++) + for (i = 0; gRSSpecialAreaMaps[i] != MAP_UNDEFINED; i++) { if (gRSSpecialAreaMaps[i] == map) - return 4; + return LOBBY_SAVEWARP; } return 0; } @@ -492,11 +494,11 @@ u8 USRom_GetPlayerMapType(struct SaveBlock1 *sav1) void sub_0200CF50(u32 val) { u32 a, b, c; - switch (gUnknown_020251F0.field10) + switch (gUnknown_020251F0.state) { case 0: gUnknown_02024960.unk84C_1 = (u8)(val & 0x7); - gUnknown_020251F0.field10++; + gUnknown_020251F0.state++; break; case 1: gUnknown_02024960.unk84C_2 = val & 0x0000FFFF; @@ -512,7 +514,7 @@ void sub_0200CF50(u32 val) gUnknown_02024960.field854 = (void*) &gPlayerPartyPtr[gUnknown_02024960.unk84C_1]; gUnknown_020251F0.field4 = 100; gUnknown_020251F0.field28 = 0; - gUnknown_020251F0.field10++; + gUnknown_020251F0.state++; break; case 2: gUnknown_02024960.field854[gUnknown_020251F0.field28 / 4] = val; @@ -522,7 +524,7 @@ void sub_0200CF50(u32 val) gUnknown_020251F0.field0 = (void *) gUnknown_02024960.field85C; gUnknown_020251F0.field4 = sizeof(gUnknown_02024960.field85C); gUnknown_020251F0.field28 = 0; - gUnknown_020251F0.field10++; + gUnknown_020251F0.state++; } break; case 3: @@ -540,7 +542,7 @@ void sub_0200CF50(u32 val) void sub_0200D08C(u32 val) { s32 i; - switch (gUnknown_020251F0.field10) + switch (gUnknown_020251F0.state) { case 0: gUnknown_020251F0.field0[gUnknown_020251F0.field28 / 4] = val; @@ -558,7 +560,7 @@ void sub_0200D08C(u32 val) gUnknown_020251F0.field28 = 0; gUnknown_020251F0.field0 = (void *) gUnknown_02024960.unk24; gUnknown_020251F0.field4 = gUnknown_02024960.unk_879 * 340; - gUnknown_020251F0.field10++; + gUnknown_020251F0.state++; } break; case 1: @@ -569,7 +571,7 @@ void sub_0200D08C(u32 val) gUnknown_020251F0.field28 = 0; gUnknown_020251F0.field0 = (void*) gUnknown_02024960.unk81C; gUnknown_020251F0.field4 = gUnknown_02024960.unk7 * sizeof(struct UnkStruct81C); - gUnknown_020251F0.field10++; + gUnknown_020251F0.state++; } break; case 2: @@ -599,41 +601,41 @@ void sub_0200D1AC(u32 val) u8 *ptr = (u8 *)(gSaveBlock1Ptr) + gAgbPmRomParams->externalEventDataOffset; // Note: cast is needed here to make the code match. The whole struct is declared as volatile, but unkStruct isn't treated as volatile in this function. // It's possible only certain members of gUnknown_02024960 were volatile. - struct UnkStruct868 *unkStruct = (struct UnkStruct868 *) &gUnknown_02024960.unk868; + struct ExternalEventData2 *externalEventData = (struct ExternalEventData2 *) &gUnknown_02024960.externalEventData; - switch (gUnknown_020251F0.field10) + switch (gUnknown_020251F0.state) { case 0: - unkStruct->a8_0 = val; - gUnknown_020251F0.field10++; + externalEventData->currentPokeCoupons = val; + gUnknown_020251F0.state++; break; case 1: - unkStruct->a12 = val; - gUnknown_020251F0.field10++; + externalEventData->totalEarnedPokeCoupons = val; + gUnknown_020251F0.state++; break; case 2: - unkStruct->a11_3 = 0; - unkStruct->a11_2 = 0; - unkStruct->a11_1 = 0; - unkStruct->a11_0 = 0; + externalEventData->receivedAgetoCelebi = 0; + externalEventData->gotBronzePokeCouponTitleReward = 0; + externalEventData->gotSilverPokeCouponTitleReward = 0; + externalEventData->gotGoldPokeCouponTitleReward = 0; if (val & 1) - unkStruct->a11_0 = 1; + externalEventData->gotGoldPokeCouponTitleReward = 1; if (val & 2) - unkStruct->a11_1 = 1; + externalEventData->gotSilverPokeCouponTitleReward = 1; if (val & 4) - unkStruct->a11_2 = 1; + externalEventData->gotBronzePokeCouponTitleReward = 1; if (val & 8) - unkStruct->a11_3 = 1; + externalEventData->receivedAgetoCelebi = 1; - CopyN(sizeof(*unkStruct), ptr, (void*) unkStruct); - gUnknown_020251F0.field10++; + CopyN(sizeof(*externalEventData), ptr, (void*) externalEventData); + gUnknown_020251F0.state++; break; case 3: gUnknown_02024960.unk_85B = val >> 16; gUnknown_020251F0.field4 = val & 0xFFFF; gUnknown_020251F0.field28 = 0; gUnknown_020251F0.field0 = (void *) gPcItemsPtr; - gUnknown_020251F0.field10++; + gUnknown_020251F0.state++; break; case 4: gUnknown_020251F0.field0[gUnknown_020251F0.field28++] = val; @@ -649,7 +651,7 @@ void sub_0200D1AC(u32 val) gUnknown_020251F0.field4 = 100; gUnknown_020251F0.field28 = 0; gUnknown_020251F0.field0 = (void *) GetPtrToEmptyPartySlot(); - gUnknown_020251F0.field10++; + gUnknown_020251F0.state++; } } break; @@ -661,7 +663,7 @@ void sub_0200D1AC(u32 val) gUnknown_020251F0.field4 = sizeof(gUnknown_02024960.field85C); gUnknown_020251F0.field28 = 0; gUnknown_020251F0.field0 = (void *) gUnknown_02024960.field85C; - gUnknown_020251F0.field10++; + gUnknown_020251F0.state++; } break; case 6: @@ -723,7 +725,7 @@ bool32 sub_0200D394(u32 val) } else if (val == 0x99) { - gUnknown_020251F0.field0 = (void *)sub_0200CB2C(); + gUnknown_020251F0.field0 = (void *)GetPlayerLinkInfo(); REG_JOY_TRANS = val; gUnknown_020251F0.field4 = 0x278; gUnknown_020251F0.field28 = r6; @@ -750,7 +752,7 @@ bool32 sub_0200D394(u32 val) gUnknown_020251F0.field0 = (void*) &gUnknown_02024960; gUnknown_020251F0.field4 = 0x24; gUnknown_020251F0.field28 = r6; - gUnknown_020251F0.field10 = r6; + gUnknown_020251F0.state = r6; gUnknown_02024960.unk_87A = r6; } else if (val == 0x55) @@ -759,7 +761,7 @@ bool32 sub_0200D394(u32 val) gUnknown_02024960.unk84C_01 = 0; REG_JOY_TRANS = val; gUnknown_020251F0.field17 = val; - gUnknown_020251F0.field10 = r6; + gUnknown_020251F0.state = r6; } else if (val == 0x44) { @@ -772,7 +774,7 @@ bool32 sub_0200D394(u32 val) { REG_JOY_TRANS = val; gUnknown_020251F0.field17 = val; - gUnknown_020251F0.field10 = 0; + gUnknown_020251F0.state = 0; } else if (val == 0x60) { @@ -825,24 +827,24 @@ void sub_0200D624(void) bool32 gameClear; u32 joyTransVal; u8 *ptr = (u8 *)(gSaveBlock1Ptr) + gAgbPmRomParams->externalEventDataOffset; - struct UnkStruct868 *unkStruct = (struct UnkStruct868 *) &gUnknown_02024960.unk868; + struct ExternalEventData2 *externalEventData = (struct ExternalEventData2 *) &gUnknown_02024960.externalEventData; - switch (gUnknown_020251F0.field10) + switch (gUnknown_020251F0.state) { case 0: - CopyN(sizeof(*unkStruct), (void*) unkStruct, ptr); - REG_JOY_TRANS = unkStruct->a8_0; - gUnknown_020251F0.field10++; + CopyN(sizeof(*externalEventData), (void*) externalEventData, ptr); + REG_JOY_TRANS = externalEventData->currentPokeCoupons; + gUnknown_020251F0.state++; break; case 1: - REG_JOY_TRANS = unkStruct->a12; - gUnknown_020251F0.field10++; + REG_JOY_TRANS = externalEventData->totalEarnedPokeCoupons; + gUnknown_020251F0.state++; break; case 2: gameClear = CheckGameClear(); - joyTransVal = (unkStruct->a11_0 << 0) | (unkStruct->a11_1 << 1) | (unkStruct->a11_2 << 2) | (unkStruct->a11_3 << 3) | (gameClear << 4); + joyTransVal = (externalEventData->gotGoldPokeCouponTitleReward << 0) | (externalEventData->gotSilverPokeCouponTitleReward << 1) | (externalEventData->gotBronzePokeCouponTitleReward << 2) | (externalEventData->receivedAgetoCelebi << 3) | (gameClear << 4); REG_JOY_TRANS = joyTransVal; - gUnknown_020251F0.field10++; + gUnknown_020251F0.state++; break; case 3: gUnknown_020251F0.field4 = gAgbPmRomParams->pcItemsCount; @@ -851,7 +853,7 @@ void sub_0200D624(void) joyTransVal |= gUnknown_020251F0.field4; REG_JOY_TRANS = joyTransVal; gUnknown_020251F0.field0 = (void *) gPcItemsPtr; - gUnknown_020251F0.field10++; + gUnknown_020251F0.state++; break; case 4: REG_JOY_TRANS = gUnknown_020251F0.field0[gUnknown_020251F0.field28++]; diff --git a/payload/sym_common.txt b/payload/sym_common.txt index 9e109c3..4ed7f0a 100644 --- a/payload/sym_common.txt +++ b/payload/sym_common.txt @@ -1,5 +1,5 @@ -gUnknown_020217B4: +gSaveStatus: .space 0x4 gUnknown_020217B8: @@ -142,7 +142,7 @@ struct { u8 giftRibbons[11]; }; */ -gUnknown_02023F50: +gPlayerLinkInfo: .space 0x278 .align 4 From 07d3fac5f48b693476abf145426588183a8853f9 Mon Sep 17 00:00:00 2001 From: citrusbolt Date: Mon, 19 Feb 2024 15:45:41 -0700 Subject: [PATCH 2/4] Document some of `global.h` --- payload/include/global.h | 207 ++++++++++++++++++++------------------- 1 file changed, 105 insertions(+), 102 deletions(-) diff --git a/payload/include/global.h b/payload/include/global.h index 9d45fd0..d01b3a9 100644 --- a/payload/include/global.h +++ b/payload/include/global.h @@ -124,6 +124,8 @@ enum LanguageId #define BAG_POKEBALLS_COUNT 16 #define BAG_TMHM_COUNT 64 #define BAG_BERRIES_COUNT 46 +#define DECOR_MAX_SECRET_BASE 16 +#define SAVED_TRENDS_COUNT 5 enum { @@ -178,26 +180,31 @@ struct UCoords16 u16 y; }; +struct SecretBaseParty +{ + /*0x1A3C*/ u32 personality[PARTY_SIZE]; + /*0x1A54*/ u16 moves[PARTY_SIZE * MAX_MON_MOVES]; + /*0x1A84*/ u16 species[PARTY_SIZE]; + /*0x1A90*/ u16 heldItems[PARTY_SIZE]; + /*0x1A9C*/ u8 levels[PARTY_SIZE]; + /*0x1AA2*/ u8 EVs[PARTY_SIZE]; +}; + struct SecretBaseRecord { /*0x1A08*/ u8 secretBaseId; - /*0x1A09*/ u8 sbr_field_1_0:4; + /*0x1A09*/ u8 toRegister:4; /*0x1A09*/ u8 gender:1; - /*0x1A09*/ u8 sbr_field_1_5:1; - /*0x1A09*/ u8 sbr_field_1_6:2; + /*0x1A09*/ u8 battledOwnerToday:1; + /*0x1A09*/ u8 registryStatus:2; /*0x1A0A*/ u8 playerName[PLAYER_NAME_LENGTH]; - /*0x1A11*/ u8 trainerId[4]; // byte 0 is used for determining trainer class - /*0x1A16*/ u16 sbr_field_e; - /*0x1A18*/ u8 sbr_field_10; - /*0x1A19*/ u8 sbr_field_11; - /*0x1A1A*/ u8 decorations[16]; - /*0x1A2A*/ u8 decorationPos[16]; - /*0x1A3C*/ u32 partyPersonality[6]; - /*0x1A54*/ u16 partyMoves[6 * 4]; - /*0x1A84*/ u16 partySpecies[6]; - /*0x1A90*/ u16 partyHeldItems[6]; - /*0x1A9C*/ u8 partyLevels[6]; - /*0x1AA2*/ u8 partyEVs[6]; + /*0x1A11*/ u8 trainerId[TRAINER_ID_LENGTH]; // byte 0 is used for determining trainer class + /*0x1A16*/ u16 numSecretBasesReceived; + /*0x1A18*/ u8 numTimesEntered; + /*0x1A19*/ u8 unused; + /*0x1A1A*/ u8 decorations[DECOR_MAX_SECRET_BASE]; + /*0x1A2A*/ u8 decorationPos[DECOR_MAX_SECRET_BASE]; + /*0x1A3C*/ struct SecretBaseParty party; }; #include "constants/game_stat.h" @@ -262,12 +269,12 @@ struct RamScript struct RamScriptData data; }; -struct EasyChatPair +struct DewfordTrend { - u16 unk0_0:7; - u16 unk0_7:7; - u16 unk1_6:1; - u16 unk2; + u16 trendiness:7; + u16 maxTrendiness:7; + u16 gainingTrendiness:1; + u16 rand; u16 words[2]; }; /*size = 0x8*/ @@ -275,8 +282,7 @@ struct TVShowCommon { /*0x00*/ u8 kind; /*0x01*/ bool8 active; - /*0x02*/ u8 pad02[20]; - /*0x16*/ u16 var16[3]; + /*0x02*/ u8 data[26]; /*0x1C*/ u8 srcTrainerId3Lo; /*0x1D*/ u8 srcTrainerId3Hi; /*0x1E*/ u8 srcTrainerId2Lo; @@ -292,7 +298,7 @@ struct TVShowFanClubLetter /*0x00*/ u8 kind; /*0x01*/ bool8 active; /*0x02*/ u16 species; - /*0x04*/ u16 pad04[6]; + /*0x04*/ u16 words[6]; /*0x10*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; /*0x18*/ u8 language; }; @@ -301,35 +307,33 @@ struct TVShowRecentHappenings { /*0x00*/ u8 kind; /*0x01*/ bool8 active; - /*0x02*/ u16 var02; - /*0x04*/ u16 var04[6]; + /*0x02*/ u16 species; + /*0x04*/ u16 words[6]; /*0x10*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; /*0x18*/ u8 language; - /*0x19*/ u8 pad19[10]; + /*0x19*/ u8 unused[10]; }; struct TVShowFanclubOpinions { /*0x00*/ u8 kind; /*0x01*/ bool8 active; - /*0x02*/ u16 var02; - /*0x04*/ u8 var04A:4; - /*0x04*/ u8 var04B:4; + /*0x02*/ u16 species; + /*0x04*/ u8 friendshipHighNybble:4; + /*0x04*/ u8 questionAsked:4; /*0x05*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; /*0x0D*/ u8 language; - /*0x0E*/ u8 var0E; - /*0x0F*/ u8 var0F; - /*0x10*/ u8 var10[8]; - /*0x18*/ u16 var18[2]; - /*0x1C*/ u16 var1C[4]; + /*0x0E*/ u8 pokemonNameLanguage; + /*0x0F*/ u8 unused; + /*0x10*/ u8 nickname[PLAYER_NAME_LENGTH + 1]; + /*0x18*/ u16 words[6]; }; struct TVShowUnknownType04 { /*0x00*/ u8 kind; /*0x01*/ bool8 active; - /*0x02*/ u8 pad02[4]; - /*0x06*/ u16 var06; + /*0x02*/ u8 unused[6]; }; struct TVShowNameRaterShow @@ -337,11 +341,11 @@ struct TVShowNameRaterShow /*0x00*/ u8 kind; /*0x01*/ bool8 active; /*0x02*/ u16 species; - /*0x04*/ u8 pokemonName[11]; - /*0x0F*/ u8 trainerName[11]; + /*0x04*/ u8 pokemonName[POKEMON_NAME_LENGTH + 1]; + /*0x0F*/ u8 trainerName[POKEMON_NAME_LENGTH + 1]; /*0x1A*/ u8 random; /*0x1B*/ u8 random2; - /*0x1C*/ u16 var1C; + /*0x1C*/ u16 randomSpecies; /*0x1E*/ u8 language; /*0x1F*/ u8 pokemonNameLanguage; }; @@ -351,31 +355,31 @@ struct TVShowBravoTrainerPokemonProfiles /*0x00*/ u8 kind; /*0x01*/ bool8 active; /*0x02*/ u16 species; - /*0x04*/ u16 var04[2]; - /*0x08*/ u8 pokemonNickname[11]; + /*0x04*/ u16 words[2]; + /*0x08*/ u8 pokemonNickname[POKEMON_NAME_LENGTH + 1]; /*0x13*/ u8 contestCategory:3; /*0x13*/ u8 contestRank:2; /*0x13*/ u8 contestResult:2; - /*0x13*/ u8 var13_7:1; - /*0x14*/ u16 var14; - /*0x16*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; + /*0x13*/ u8 unused:1; + /*0x14*/ u16 move; + /*0x16*/ u8 playerName[11]; /*0x1E*/ u8 language; - /*0x1F*/ u8 var1f; + /*0x1F*/ u8 pokemonNameLanguage; }; struct TVShowBravoTrainerBattleTowerSpotlight { /*0x00*/ u8 kind; /*0x01*/ bool8 active; - /*0x02*/ u8 trainerName[8]; + /*0x02*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; /*0x0A*/ u16 species; - /*0x0C*/ u8 enemyTrainerName[8]; + /*0x0C*/ u8 enemyTrainerName[PLAYER_NAME_LENGTH + 1]; /*0x14*/ u16 defeatedSpecies; - /*0x16*/ u16 var16; - /*0x18*/ u16 var18[1]; + /*0x16*/ u16 numFights; + /*0x18*/ u16 words[1]; /*0x1A*/ u8 btLevel; - /*0x1B*/ u8 var1b; - /*0x1C*/ u8 var1c; + /*0x1B*/ u8 interviewResponse; + /*0x1C*/ u8 wonTheChallenge; /*0x1D*/ u8 language; }; @@ -385,10 +389,10 @@ struct TVShowPokemonToday /*0x01*/ bool8 active; /*0x02*/ u8 language; /*0x03*/ u8 language2; - /*0x04*/ u8 nickname[11]; + /*0x04*/ u8 nickname[POKEMON_NAME_LENGTH + 1]; /*0x0F*/ u8 ball; /*0x10*/ u16 species; - /*0x12*/ u8 var12; + /*0x12*/ u8 nBallsUsed; /*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; }; @@ -398,7 +402,7 @@ struct TVShowSmartShopper /*0x01*/ bool8 active; /*0x02*/ u8 priceReduced; /*0x03*/ u8 language; - /*0x04*/ u8 pad04[2]; + /*0x04*/ u8 unused[2]; /*0x06*/ u16 itemIds[3]; /*0x0C*/ u16 itemAmounts[3]; /*0x12*/ u8 shopLocation; @@ -410,12 +414,12 @@ struct TVShowPokemonTodayFailed /*0x00*/ u8 kind; /*0x01*/ bool8 active; /*0x02*/ u8 language; - /*0x03*/ u8 pad03[9]; + /*0x03*/ u8 unused[9]; /*0x0c*/ u16 species; /*0x0e*/ u16 species2; - /*0x10*/ u8 var10; - /*0x11*/ u8 var11; - /*0x12*/ u8 var12; + /*0x10*/ u8 nBallsUsed; + /*0x11*/ u8 outcome; + /*0x12*/ u8 location; /*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; }; @@ -423,11 +427,11 @@ struct TVShowPokemonAngler { /*0x00*/ u8 kind; /*0x01*/ bool8 active; - /*0x02*/ u8 var02; - /*0x03*/ u8 var03; - /*0x04*/ u16 var04; + /*0x02*/ u8 nBites; + /*0x03*/ u8 nFails; + /*0x04*/ u16 species; /*0x06*/ u8 language; - u8 pad07[12]; + /*0x07*/ u8 unused[12]; /*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; }; @@ -435,13 +439,13 @@ struct TVShowWorldOfMasters { /*0x00*/ u8 kind; /*0x01*/ bool8 active; - /*0x02*/ u16 var02; - /*0x04*/ u16 var04; - /*0x06*/ u16 var06; - /*0x08*/ u16 var08; - /*0x0a*/ u8 var0a; + /*0x02*/ u16 numPokeCaught; + /*0x04*/ u16 caughtPoke; + /*0x06*/ u16 steps; + /*0x08*/ u16 species; + /*0x0a*/ u8 location; /*0x0b*/ u8 language; - u8 pad0c[7]; + /*0x0c*/ u8 unused[7]; /*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; }; @@ -449,17 +453,17 @@ struct TVShowMassOutbreak { /*0x00*/ u8 kind; /*0x01*/ bool8 active; - /*0x02*/ u8 var02; - /*0x03*/ u8 var03; - /*0x04*/ u16 moves[4]; + /*0x02*/ u8 unused1; + /*0x03*/ u8 unused2; + /*0x04*/ u16 moves[MAX_MON_MOVES]; /*0x0C*/ u16 species; - /*0x0E*/ u16 var0E; + /*0x0E*/ u16 unused3; /*0x10*/ u8 locationMapNum; /*0x11*/ u8 locationMapGroup; - /*0x12*/ u8 var12; + /*0x12*/ u8 unused4; /*0x13*/ u8 probability; /*0x14*/ u8 level; - /*0x15*/ u8 var15; + /*0x15*/ u8 unused5; /*0x16*/ u16 daysLeft; /*0x18*/ u8 language; u8 pad19[11]; @@ -487,7 +491,7 @@ struct MailStruct { /*0x00*/ u16 words[9]; /*0x12*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; - /*0x1A*/ u8 trainerId[4]; + /*0x1A*/ u8 trainerId[TRAINER_ID_LENGTH]; /*0x1E*/ u16 species; /*0x20*/ u16 itemId; }; @@ -506,8 +510,8 @@ struct MauvilleManBard /*0x02*/ u16 songLyrics[6]; /*0x0E*/ u16 temporaryLyrics[6]; /*0x1A*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; - /*0x22*/ u8 filler_2DB6[0x3]; - /*0x25*/ u8 playerTrainerId[4]; + /*0x22*/ u8 unused[0x3]; + /*0x25*/ u8 playerTrainerId[TRAINER_ID_LENGTH]; /*0x29*/ bool8 hasChangedSong; }; /*size = 0x2C*/ @@ -520,8 +524,8 @@ struct MauvilleManHipster struct MauvilleManTrader { u8 id; - u8 unk1[4]; - u8 unk5[4][11]; + u8 decorations[4]; + u8 playerNames[4][POKEMON_NAME_LENGTH + 1]; bool8 alreadyTraded; }; @@ -529,9 +533,9 @@ struct MauvilleManStoryteller { u8 id; bool8 alreadyRecorded; - u8 filler2[2]; + u8 unused[2]; u8 gameStatIDs[4]; - u8 trainerNames[4][7]; + u8 trainerNames[4][PLAYER_NAME_LENGTH]; u8 statValues[4][4]; }; @@ -571,18 +575,17 @@ struct GabbyAndTyData /*2b16*/ u16 quote; /*2b18*/ u8 mapnum; /*2b19*/ u8 battleNum; - /*2b1a*/ u8 valA_0:1; - /*2b1a*/ u8 valA_1:1; - /*2b1a*/ u8 valA_2:1; - /*2b1a*/ u8 valA_3:1; - /*2b1a*/ u8 valA_4:1; - /*2b1a*/ u8 valA_5:3; - /*2b1b*/ u8 valB_0:1; - /*2b1b*/ u8 valB_1:1; - /*2b1b*/ u8 valB_2:1; - /*2b1b*/ u8 valB_3:1; - /*2b1b*/ u8 valB_4:1; - /*2b1b*/ u8 valB_5:3; + /*2b1a*/ u8 battleTookMoreThanOneTurn:1; + /*2b1a*/ u8 playerLostAMon:1; + /*2b1a*/ u8 playerUsedHealingItem:1; + /*2b1a*/ u8 playerThrewABall:1; + /*2b1a*/ u8 onAir:1; + /*2b1a*/ u8 unused1:3; + /*2b1b*/ u8 battleTookMoreThanOneTurn2:1; + /*2b1b*/ u8 playerLostAMon2:1; + /*2b1b*/ u8 playerUsedHealingItem2:1; + /*2b1b*/ u8 playerThrewABall2:1; + /*2b1b*/ u8 unused2:4; }; struct DayCareMail @@ -617,7 +620,7 @@ struct DayCare { struct LinkBattleRecord { - u8 name[8]; + u8 name[PLAYER_NAME_LENGTH + 1]; u16 trainerId; u16 wins; u16 losses; @@ -634,7 +637,7 @@ struct RecordMixingGiftData struct RecordMixingGift { - int checksum; + u32 checksum; struct RecordMixingGiftData data; }; @@ -644,8 +647,8 @@ struct ContestWinner /*0x04*/ u32 otId; // otId /*0x08*/ u16 species; // species /*0x0A*/ u8 contestCategory; - /*0x0B*/ u8 nickname[11]; - /*0x16*/ u8 trainerName[8]; + /*0x0B*/ u8 nickname[POKEMON_NAME_LENGTH + 1]; + /*0x16*/ u8 trainerName[PLAYER_NAME_LENGTH + 1]; }; struct ExternalEventData @@ -700,10 +703,10 @@ struct SaveBlock1 /* 0x02025734 */ { /*0x00*/ struct Coords16 pos; /*0x04*/ struct WarpData location; - /*0x0C*/ struct WarpData warp1; - /*0x14*/ struct WarpData warp2; + /*0x0C*/ struct WarpData continueGameWarp; + /*0x14*/ struct WarpData dynamicWarp; /*0x1C*/ struct WarpData lastHealLocation; - /*0x24*/ struct WarpData warp4; + /*0x24*/ struct WarpData escapeWarp; /*0x2C*/ u16 savedMusic; /*0x2E*/ u8 weather; /*0x2F*/ u8 weatherCycleStage; @@ -711,7 +714,7 @@ struct SaveBlock1 /* 0x02025734 */ /*0x32*/ u16 mapLayoutId; /*0x34*/ u16 mapView[0x100]; /*0x234*/ u8 playerPartyCount; - /*0x238*/ struct Pokemon playerParty[6]; + /*0x238*/ struct Pokemon playerParty[PARTY_SIZE]; /*0x490*/ u32 money; /*0x494*/ u16 coins; /*0x496*/ u16 registeredItem; // registered for use with SELECT button @@ -768,7 +771,7 @@ struct SaveBlock1 /* 0x02025734 */ /*0x2D8C*/ u8 unk2D8C[4]; // What is this? Apparently it's supposed to be 64 bytes in size. /*0x2D90*/ u8 filler_2D90[0x4]; /*0x2D94*/ union MauvilleMan mauvilleMan; - /*0x2DD4*/ struct EasyChatPair easyChatPairs[5]; //Dewford trend [0] and some other stuff + /*0x2DD4*/ struct DewfordTrend dewfordTrends[SAVED_TRENDS_COUNT]; //Dewford trend [0] and some other stuff /*0x2DFC*/ struct ContestWinner contestWinners[8]; /*0x2EFC*/ struct ContestWinner museumPortraits[5]; /*0x2F9C*/ struct DayCare daycare; From 9a019ef6dddb08838dd5eceb187be890c8831559 Mon Sep 17 00:00:00 2001 From: citrusbolt Date: Thu, 29 Feb 2024 20:11:20 -0700 Subject: [PATCH 3/4] Document lots more link data --- payload/include/all.h | 64 ++--- payload/include/global.h | 5 +- payload/include/unk_200C5DC.h | 12 +- payload/src/all.c | 26 +- payload/src/all4.c | 273 +++++++++---------- payload/src/main.c | 16 +- payload/src/unk_200C5DC.c | 487 +++++++++++++++++++--------------- payload/sym_common.txt | 6 +- 8 files changed, 478 insertions(+), 411 deletions(-) diff --git a/payload/include/all.h b/payload/include/all.h index 444b3e4..e8adcca 100644 --- a/payload/include/all.h +++ b/payload/include/all.h @@ -15,69 +15,69 @@ struct ExternalEventData2 u32 unknownExternalDataFields4:8; }; -struct UnkStruct81C +struct MonName { u8 str[10]; - u32 unk826_0:3; - u32 unk826_1:1; - u32 unk826_2:1; - u32 unk826_3:1; - u32 unk826_4:2; + u32 playerId:3; + u32 isJapanese:1; + u32 isNidoranF:1; + u32 isNidoranM:1; + u32 gender:2; }; -struct UnkStruct24 +struct MonData { u16 hp; // 0x24 u32 status:12; // 0x26 - u32 unk27_0:1; - u32 unk27_1:1; - u32 unk27_2:1; - u32 unk27_3:1; - u16 heldItem; // 0x28 + u32 giveMaxPokerusDays:1; + u32 giveMaxPokerusStrain:1; + u32 setMailTo1:1; + u32 preserveHeldItem:1; + u32 heldItem:16; // 0x28 u16 unk2A; u16 moves[MAX_MON_MOVES]; // 0x2C , 0x2E , 0x30, 0x32 u8 pps[MAX_MON_MOVES]; // 0x34-0x37 - u8 unk38[320]; + u8 textBuffer[320]; }; -struct UnkStruct_02024960 +struct MonLinkData { - u32 unk_00:24; + u32 partyCountNibblefield:PARTY_SIZE * 4; // Like a bitfield, but every party member is represented by 4 bits. For example, a party of 4 would be represented by 0x00FFFF u32 unk_03_0:7; u32 unk_03_7:1; u32 unk4:24; u32 unk7:8; - u32 unk8; - u32 unkC; - u16 unk10; + u32 personality; + u32 otId; + u16 species; u16 unk12; - u16 unk14[MAX_MON_MOVES]; - u8 unk1C[MAX_MON_MOVES]; + u16 moves[MAX_MON_MOVES]; + u8 pps[MAX_MON_MOVES]; u16 unk20; u8 unk22_0:4; u8 unk22_4:4; u8 unk23_0:4; u8 unk23_4:4; - struct UnkStruct24 unk24[PARTY_SIZE]; - struct UnkStruct81C unk81C[4]; + struct MonData monData[PARTY_SIZE]; + struct MonName monName[4]; u8 unk84C_00:1; - u8 unk84C_01:1; + u8 transferComplete:1; u8 unk84C_02:1; u8 unk84C_03:1; - u8 unk84C_1:4; - u32 unk84C_2:16; - u32 unk84C_3:8; - u32 unk850_1:8; + u8 monId:4; + u32 species2:16; + u32 speciesLowerByte:8; + u32 speciesUpperByte:8; u32 unk850_2:24; - u32 *field854; + u32 *monPtr; u8 unk_858; u8 unk_859; u8 unk_85A; - u8 unk_85B; - u8 ALIGNED(4) field85C[12]; // Aligned for u32 copy + u8 species3; // Only 1 byte, so can not contain a Hoenn species + u8 ALIGNED(4) giftRibbons[GIFT_RIBBONS_COUNT + 1]; // Aligned for u32 copy struct ExternalEventData2 externalEventData; u8 unk_878; - u8 unk_879; + u8 partyCount; u8 unk_87A; u8 unk_87B; u8 unk_87C; @@ -87,7 +87,7 @@ struct UnkStruct_02024960 u32 unk_880; }; -extern volatile struct UnkStruct_02024960 gUnknown_02024960; +extern volatile struct MonLinkData gMonLinkData; #include "gflib/text.h" diff --git a/payload/include/global.h b/payload/include/global.h index d01b3a9..099208c 100644 --- a/payload/include/global.h +++ b/payload/include/global.h @@ -49,6 +49,9 @@ #define CONTEST_CATEGORY_TOUGH 4 #define CONTEST_CATEGORIES_COUNT 5 +#define GENDER_MALE 0 +#define GENDER_FEMALE 1 + #define min(a, b) ((a) < (b) ? (a) : (b)) #define max(a, b) ((a) >= (b) ? (a) : (b)) @@ -777,7 +780,7 @@ struct SaveBlock1 /* 0x02025734 */ /*0x2F9C*/ struct DayCare daycare; /*0x30B8*/ struct LinkBattleRecord linkBattleRecords[5]; /*0x3108*/ u8 filler_3108[8]; - /*0x3110*/ u8 giftRibbons[11]; + /*0x3110*/ u8 giftRibbons[GIFT_RIBBONS_COUNT]; /*0x311B*/ struct ExternalEventData externalEventData; /*0x312F*/ struct ExternalEventFlags externalEventFlags; /*0x3144*/ struct Roamer roamer; diff --git a/payload/include/unk_200C5DC.h b/payload/include/unk_200C5DC.h index 0b7ec5b..8a90ae1 100644 --- a/payload/include/unk_200C5DC.h +++ b/payload/include/unk_200C5DC.h @@ -6,10 +6,10 @@ #define LOBBY_SAVEWARP (1 << 2) #define CHAMPION_SAVEWARP (1 << 7) -struct UnkStruct_020251F0 +struct TransferData { - volatile u32 *field0; - u32 field4; + volatile u32 *data; + u32 transferSize; u8 field8[2]; vu8 state; u8 field11; @@ -29,7 +29,7 @@ struct UnkStruct_020251F0 u8 fill25; u8 fill26; u8 fill27; - u32 field28; + u32 transferBytes; u32 field32; u32 field36; u32 field40; @@ -37,7 +37,7 @@ struct UnkStruct_020251F0 u32 field48; }; -extern volatile struct UnkStruct_020251F0 gUnknown_020251F0; +extern volatile struct TransferData gTransferData; void SetSpeciesCaughtFlag(u32 species, struct Pokemon *mon); u8 GetPlayerMapType(void); @@ -47,6 +47,6 @@ s32 StringCompare(const u8 *str1, const u8 *str2); u8 *StringCopy(u8 *dst, const u8 *src); u16 GetStringSizeHandleExtCtrlCodes(u8 *str); bool32 SetFlag(s32 flag); -u32 sub_0200CB54(void); +bool32 GetUnknownBoolean(void); #endif // GUARD_unk_200C5DC_H diff --git a/payload/src/all.c b/payload/src/all.c index bf35834..83333fd 100644 --- a/payload/src/all.c +++ b/payload/src/all.c @@ -93,7 +93,7 @@ struct Struct0201F9E u8 a3; }; -EWRAM_DATA volatile struct UnkStruct_02024960 gUnknown_02024960 = {0}; +EWRAM_DATA volatile struct MonLinkData gMonLinkData = {0}; static UNUSED u8 gUnknown_02020A38[8]; static u8 gScreenIsFadedOut; @@ -1100,21 +1100,21 @@ s32 sub_02001A8C(u32 monId) else if ((var & 0xFFFF) == 2) { PlaySE(SONG_SE_FAILURE); - BufferString(0, (void *) gUnknown_02024960.unk81C[var >> 16].str); + BufferString(0, (void *) gMonLinkData.monName[var >> 16].str); sub_020019B4(gUnknown_02021860.unk122, 1); i = 2; } else if ((var & 0xFFFF) == 4) { PlaySE(SONG_SE_FAILURE); - BufferString(0, (void *) gUnknown_02024960.unk81C[var >> 16].str); + BufferString(0, (void *) gMonLinkData.monName[var >> 16].str); sub_020019B4(gUnknown_02021860.unk122, 2); i = 2; } else if ((var & 0xFFFF) == 3) { PlaySE(SONG_SE_FAILURE); - BufferString(0, (void *) gUnknown_02024960.unk81C[var >> 16].str); + BufferString(0, (void *) gMonLinkData.monName[var >> 16].str); sub_020019B4(gUnknown_02021860.unk122, 3); i = 2; } @@ -1134,12 +1134,12 @@ s32 sub_02001A8C(u32 monId) } else { - switch (sub_020064BC(gUnknown_02024960.unk4, gUnknown_02021860.unk11B)) + switch (sub_020064BC(gMonLinkData.unk4, gUnknown_02021860.unk11B)) { case 0: PlaySE(SONG_SE_SELECT); - gUnknown_02024960.unk_87E = gUnknown_02021860.unk11B; - gUnknown_02024960.unk_87B = 2; + gMonLinkData.unk_87E = gUnknown_02021860.unk11B; + gMonLinkData.unk_87B = 2; return -1; case 1: PlaySE(SONG_SE_FAILURE); @@ -1503,8 +1503,8 @@ inline void sub_02002F60(void) bits |= (ret << r6); r6 += 4; } - gUnknown_02024960.unk_880 = bits; - gUnknown_02024960.unk_87F = 1; + gMonLinkData.unk_880 = bits; + gMonLinkData.unk_87F = 1; } s32 sub_020026F4(void) @@ -1671,11 +1671,11 @@ void sub_02002A9C(s32 a0, u32 a1, u32 a2) gUnknown_02021860.unk125 = a2; gUnknown_02021860.unk11A = 0; - if (gUnknown_02024960.unk_858 == 1) + if (gMonLinkData.unk_858 == 1) { gUnknown_02021860.unk11E = 1; } - else if (gUnknown_02024960.unk_858 == 2) + else if (gMonLinkData.unk_858 == 2) { gUnknown_02021860.unk11A = 1; gUnknown_02021860.unk11E = 2; @@ -1693,7 +1693,7 @@ void sub_02002A9C(s32 a0, u32 a1, u32 a2) break; case 1: gUnknown_02021860.unk118 = 1; - gUnknown_02021860.unk123 = gUnknown_02024960.unk_859; + gUnknown_02021860.unk123 = gMonLinkData.unk_859; if (gUnknown_02021860.unk123 == 0 || gUnknown_02021860.unk123 > *gPlayerPartyCountPtr) gUnknown_02021860.unk123 = *gPlayerPartyCountPtr; gUnknown_02021860.unk124 = 0; @@ -1745,7 +1745,7 @@ void NAKED sub_02002A9C(s32 a0, u32 a1, u32 a2) lsls r0, r0, #1\t\n\ adds r2, r3, r0\t\n\ strb r5, [r2]\t\n\ - ldr r1, =gUnknown_02024960\t\n\ + ldr r1, =gMonLinkData\t\n\ ldr r0, =0x00000858\t\n\ adds r6, r1, r0\t\n\ ldrb r0, [r6]\t\n\ diff --git a/payload/src/all4.c b/payload/src/all4.c index af9c1b4..9354500 100644 --- a/payload/src/all4.c +++ b/payload/src/all4.c @@ -126,7 +126,7 @@ u32 sub_020047D4(void) { s32 r5; - gUnknown_02024960.unk_87B = 4; + gMonLinkData.unk_87B = 4; sub_0200465C(); if (gAgbPmRomParams->blockLinkColoXD || !gRomDetection_IsEnglishROM) { @@ -141,10 +141,10 @@ u32 sub_020047D4(void) else ClearWindowCharBuffer(gMessageWindowPtr, 0xFFFF); - gUnknown_02024960.unk_859 = 0; - gUnknown_02024960.unk84C_01 = 0; - gUnknown_02024960.unk_87A = 0; - gUnknown_02024960.unk84C_00 = 0; + gMonLinkData.unk_859 = 0; + gMonLinkData.transferComplete = 0; + gMonLinkData.unk_87A = 0; + gMonLinkData.unk84C_00 = 0; FadeIn(); if (gSaveStatus == SAVE_STATUS_CORRUPT || gSaveStatus == SAVE_STATUS_ERROR || gSaveStatus == SAVE_STATUS_EMPTY) { @@ -160,27 +160,27 @@ u32 sub_020047D4(void) RenderText(gMessageWindowPtr, gText_BerryProgramUpdated); sub_0200472C(); } - if (gUnknown_02024960.unk_87F != 0) + if (gMonLinkData.unk_87F != 0) { - REG_JOY_TRANS = gUnknown_02024960.unk_880; - gUnknown_02024960.unk_87F = 0; + REG_JOY_TRANS = gMonLinkData.unk_880; + gMonLinkData.unk_87F = 0; } r5 = 0; while (r5 == 0) { DelayFrames(1); - if (gUnknown_02024960.unk_859 != 0 && sub_0200CB54() == 1) + if (gMonLinkData.unk_859 != 0 && GetUnknownBoolean() == 1) r5 = 2; - if (gUnknown_02024960.unk84C_00 == 1) + if (gMonLinkData.unk84C_00 == 1) { - gUnknown_02024960.unk84C_00 = 0; + gMonLinkData.unk84C_00 = 0; sub_02006058(); } - if (gUnknown_02024960.unk_87A == 1) + if (gMonLinkData.unk_87A == 1) r5 = 1; - if (gUnknown_02024960.unk_85A == 1) + if (gMonLinkData.unk_85A == 1) { - gUnknown_02024960.unk_85A = 0; + gMonLinkData.unk_85A = 0; sub_02006264(); PrintErrorMsg(gMessageWindowPtr, 1); } @@ -259,11 +259,11 @@ void sub_02004BEC(struct Unk2021A20Str *a0, u32 monId, s32 x, s32 y) const struct CompressedSpriteSheet *monFrontSheet; const struct SpeciesInfo *speciesInfo = gAgbPmRomParams->speciesInfo; - a0->unkC = gUnknown_02024960.unk10; + a0->unkC = gMonLinkData.species; if (a0->unkC == SPECIES_NONE) return; - personality = gUnknown_02024960.unk8; + personality = gMonLinkData.personality; a0->unkE = FixUnownSpecies(a0->unkC, personality); if (a0->unk0 != NULL) MoveSpriteToHead(a0->unk0); @@ -274,12 +274,12 @@ void sub_02004BEC(struct Unk2021A20Str *a0, u32 monId, s32 x, s32 y) buffer = GetPicUncompPtr(); LZ77UnCompVram(monFrontSheet->data, buffer); if (a0->unkC == SPECIES_CASTFORM) - buffer += (gUnknown_02024960.unk12 * 0x800); + buffer += (gMonLinkData.unk12 * 0x800); DrawSpindasSpots(a0->unkC, personality, buffer); CpuCopy16(buffer, (void *)VRAM + 0x12000, 0x800); - LZ77UnCompWram(GetMonPalettePtrBySpeciesIdPersonality(a0->unkC, gUnknown_02024960.unkC, personality)->data, buffer); + LZ77UnCompWram(GetMonPalettePtrBySpeciesIdPersonality(a0->unkC, gMonLinkData.otId, personality)->data, buffer); if (a0->unkC == SPECIES_CASTFORM) - buffer += (gUnknown_02024960.unk12 * 32); + buffer += (gMonLinkData.unk12 * 32); CpuCopy16(buffer, (void *)PLTT + 0x280, 0x20); } @@ -545,14 +545,14 @@ void sub_02005168(s32 id) s32 ppBonuses, ppTotal, ppCurr, type; struct Pokemon *mon = &gPlayerPartyPtr[gUnknown_02020A48]; const struct BattleMove *moves = gAgbPmRomParams->moves; - u32 move = gUnknown_02024960.unk14[id]; + u32 move = gMonLinkData.moves[id]; FillWindowCharBufferRect(gUnknown_02021A20.unk18, 22, 2, 6, 2, 0); type = moves[move].type; RenderTextAt(gUnknown_02021A20.unk18, 176, 16, gTypeNames[type]); FillWindowCharBufferRect(gUnknown_02021A20.unk18, 24, 0, 4, 2, 0); - ppCurr = gUnknown_02024960.unk1C[id]; + ppCurr = gMonLinkData.pps[id]; ppBonuses = GetMonData(mon, MON_DATA_PP_BONUSES, NULL); ppTotal = CalculatePPWithBonus(move, ppBonuses, id); NumToPmString3RightAlign(text, ppCurr); @@ -577,7 +577,7 @@ s32 sub_02005264(s32 monId) for (count = 0, i = 0; i < MAX_MON_MOVES; i++) { - u32 move = gUnknown_02024960.unk14[i]; + u32 move = gMonLinkData.moves[i]; if (move != MOVE_NONE) { CopyMoveName(text, move); @@ -608,52 +608,52 @@ u8 *sub_0200531C(s32 id) u8 *txtPtr = gUnknown_02021A00; CpuFill16(0, txtPtr, 0x20); - if (gUnknown_02024960.unk81C[id].str[0] == EOS) + if (gMonLinkData.monName[id].str[0] == EOS) { txtPtr[0] = EOS; } else { - txtPtr[0] = gUnknown_02024960.unk81C[id].unk826_0 + CHAR_0; + txtPtr[0] = gMonLinkData.monName[id].playerId + CHAR_0; txtPtr[1] = CHAR_P; txtPtr[2] = CHAR_COLON; txtPtr[3] = CHAR_SPACE; len = 4; - if (gUnknown_02024960.unk81C[id].unk826_1) + if (gMonLinkData.monName[id].isJapanese) { txtPtr[4] = EXT_CTRL_CODE_BEGIN; - txtPtr[5] = 0x15; + txtPtr[5] = EXT_CTRL_CODE_JPN; len = 6; } for (i = 0; i < gAgbPmRomParams->pokemonNameLength2; i++) { - if (gUnknown_02024960.unk81C[id].str[i] == EOS) + if (gMonLinkData.monName[id].str[i] == EOS) break; - txtPtr[i + len] = gUnknown_02024960.unk81C[id].str[i]; + txtPtr[i + len] = gMonLinkData.monName[id].str[i]; } i += len; - if (gUnknown_02024960.unk81C[id].unk826_3 || gUnknown_02024960.unk81C[id].unk826_2) + if (gMonLinkData.monName[id].isNidoranM || gMonLinkData.monName[id].isNidoranF) { u32 species; - if (gUnknown_02024960.unk81C[id].unk826_3) + if (gMonLinkData.monName[id].isNidoranM) species = SPECIES_NIDORAN_M; else species = SPECIES_NIDORAN_F; GetSpeciesName(text, species); - if (StringCompare((u8 *)gUnknown_02024960.unk81C[id].str, text) == 0) + if (StringCompare((u8 *)gMonLinkData.monName[id].str, text) == 0) { - if (gUnknown_02024960.unk81C[id].unk826_4 == 0) + if (gMonLinkData.monName[id].gender == GENDER_MALE) txtPtr[i++] = CHAR_MALE; - else if (gUnknown_02024960.unk81C[id].unk826_4 == 1) + else if (gMonLinkData.monName[id].gender == GENDER_FEMALE) txtPtr[i++] = CHAR_FEMALE; } } else { - if (gUnknown_02024960.unk81C[id].unk826_4 == 0) + if (gMonLinkData.monName[id].gender == GENDER_MALE) txtPtr[i++] = CHAR_MALE; - else if (gUnknown_02024960.unk81C[id].unk826_4 == 1) + else if (gMonLinkData.monName[id].gender == GENDER_FEMALE) txtPtr[i++] = CHAR_FEMALE; } txtPtr[i] = EOS; @@ -672,7 +672,7 @@ s32 sub_02005468(void) ClearWindowCharBuffer(gUnknown_02021A20.unk18, 0xFFFF); StringCopy(gStringBuffers[0], sub_0200531C(0)); StringCopy(gStringBuffers[1], sub_0200531C(1)); - if (gUnknown_02024960.unk7 == 4) + if (gMonLinkData.unk7 == 4) { StringCopy(gStringBuffers[2], sub_0200531C(2)); StringCopy(gStringBuffers[3], sub_0200531C(3)); @@ -685,7 +685,7 @@ s32 sub_02005468(void) sub_02004F04(gUnknown_02021A20.unk18, gUnknown_0201FDF4, 4); gBgTilemapBufferTransferScheduled[3] = TRUE; gBgTilemapBufferTransferScheduled[2] = TRUE; - return gUnknown_02024960.unk7; + return gMonLinkData.unk7; } s32 sub_02005548(void) @@ -717,7 +717,7 @@ static inline void sub_2005E68_Inline(void) static inline void sub_2005F08_Inline(u32 unused, s32 moveSlot) { u8 text[28]; - u32 move = gUnknown_02024960.unk14[moveSlot]; + u32 move = gMonLinkData.moves[moveSlot]; if (move != MOVE_NONE) CopyMoveName(text, move); else @@ -819,9 +819,9 @@ bool32 sub_02005704(u32 monId) case 0: sub_2005E68_Inline(); r7->state = sub_02004FB8(gText_BattleOptions, 4); - if (r7->state == 0 && gUnknown_02024960.unk_03_0 == 2) + if (r7->state == 0 && gMonLinkData.unk_03_0 == 2) { - gUnknown_02024960.unk_87B = 0; + gMonLinkData.unk_87B = 0; loop = FALSE; } break; @@ -829,15 +829,15 @@ bool32 sub_02005704(u32 monId) if (sub_0200644C() == 1) { sub_020055D4(gUnknown_02020A48, 0, 14, 1); - gUnknown_02024960.unk_87C = 0; - gUnknown_02024960.unk_87B = 1; + gMonLinkData.unk_87C = 0; + gMonLinkData.unk_87B = 1; r7->state = 0; loop = FALSE; } else if (sub_0200644C() == 2) { - gUnknown_02024960.unk_87C = 0; - gUnknown_02024960.unk_87B = 1; + gMonLinkData.unk_87C = 0; + gMonLinkData.unk_87B = 1; r7->state = 0; loop = FALSE; } @@ -854,8 +854,8 @@ bool32 sub_02005704(u32 monId) { if (sub_2005F44_Inline(gUnknown_02020A48, r7->moveSlot)) { - gUnknown_02024960.unk_87C = r9, - gUnknown_02024960.unk_87B = 1, + gMonLinkData.unk_87C = r9, + gMonLinkData.unk_87B = 1, loop = FALSE; } r7->state = 0; @@ -871,20 +871,20 @@ bool32 sub_02005704(u32 monId) r7->state = 0; if (r9 == 1) { - gUnknown_02024960.unk_87B = 3; + gMonLinkData.unk_87B = 3; loop = FALSE; } break; case 3: FadeOut(); sub_02002C80(); - if (gUnknown_02024960.unk_03_0 == 0) - gUnknown_02024960.unk_858 = 1; + if (gMonLinkData.unk_03_0 == 0) + gMonLinkData.unk_858 = 1; else - gUnknown_02024960.unk_858 = 2; + gMonLinkData.unk_858 = 2; sub_02002A9C(0, monId, 0); r7->state = 0; - if (gUnknown_02024960.unk_87B != 4) + if (gMonLinkData.unk_87B != 4) { loop = FALSE; } @@ -907,8 +907,8 @@ bool32 sub_02005704(u32 monId) { if (sub_2005F44_Inline(gUnknown_02020A48, r7->moveSlot)) { - gUnknown_02024960.unk_87C = r9, - gUnknown_02024960.unk_87B = 1, + gMonLinkData.unk_87C = r9, + gMonLinkData.unk_87B = 1, loop = FALSE; } r7->state = 0; @@ -920,20 +920,20 @@ bool32 sub_02005704(u32 monId) } r2 = 0; - switch (gUnknown_02024960.unk_87B) + switch (gMonLinkData.unk_87B) { case 1: r2 = r7->moveSlot - 1; - r2 |= (((gUnknown_02024960.unk_87C - 1) << 8) & 0xFF00); + r2 |= (((gMonLinkData.unk_87C - 1) << 8) & 0xFF00); break; case 2: - r2 = gUnknown_02024960.unk_87E; + r2 = gMonLinkData.unk_87E; break; } - r2 |= (gUnknown_02024960.unk_87B) << 16; - gUnknown_02024960.unk_880 = r2; - gUnknown_02024960.unk_87F = 1; + r2 |= (gMonLinkData.unk_87B) << 16; + gMonLinkData.unk_880 = r2; + gMonLinkData.unk_87F = 1; if (!IsScreenFadedOut()) FadeOut(); @@ -944,68 +944,68 @@ bool32 sub_02005704(u32 monId) void sub_02005BB8(void) { u16 var; - u32 var_28; + u32 partyCountNibbles; s32 i; CpuFill16(0, gPlayerPartyPtr, sizeof(struct Pokemon) * PARTY_SIZE); - var_28 = gUnknown_02024960.unk_00; - for (i = 0; i < PARTY_SIZE; i++, var_28 >>= 4) + partyCountNibbles = gMonLinkData.partyCountNibblefield; + for (i = 0; i < PARTY_SIZE; i++, partyCountNibbles >>= 4) { - u32 id = var_28 & 0xF; + u32 id = partyCountNibbles & 0xF; if ((id) != 0xF) { CpuCopy16(&gPlayerPartyBakPtr[id], &gPlayerPartyPtr[i], sizeof(struct Pokemon)); - var = gUnknown_02024960.unk24[i].hp; + var = gMonLinkData.monData[i].hp; SetMonData(&gPlayerPartyPtr[i], MON_DATA_HP, &var); - var = gUnknown_02024960.unk24[i].status; + var = gMonLinkData.monData[i].status; SetMonData(&gPlayerPartyPtr[i], MON_DATA_STATUS, &var); var = 0; - if (gUnknown_02024960.unk24[i].unk27_0) + if (gMonLinkData.monData[i].giveMaxPokerusDays) var = 0xF; - if (gUnknown_02024960.unk24[i].unk27_1) + if (gMonLinkData.monData[i].giveMaxPokerusStrain) var |= 0xF0; SetMonData(&gPlayerPartyPtr[i], MON_DATA_POKERUS, &var); - if (gUnknown_02024960.unk24[i].unk27_2) + if (gMonLinkData.monData[i].setMailTo1) { var = 1; SetMonData(&gPlayerPartyPtr[i], MON_DATA_MAIL, &var); } var = 0; - if (gUnknown_02024960.unk24[i].unk27_3) - var = gUnknown_02024960.unk24[i].heldItem; + if (gMonLinkData.monData[i].preserveHeldItem) + var = gMonLinkData.monData[i].heldItem; SetMonData(&gPlayerPartyPtr[i], MON_DATA_HELD_ITEM, &var); - var = gUnknown_02024960.unk24[i].moves[0]; + var = gMonLinkData.monData[i].moves[0]; SetMonData(&gPlayerPartyPtr[i], MON_DATA_MOVE1, &var); - var = gUnknown_02024960.unk24[i].moves[1]; + var = gMonLinkData.monData[i].moves[1]; SetMonData(&gPlayerPartyPtr[i], MON_DATA_MOVE2, &var); - var = gUnknown_02024960.unk24[i].moves[2]; + var = gMonLinkData.monData[i].moves[2]; SetMonData(&gPlayerPartyPtr[i], MON_DATA_MOVE3, &var); - var = gUnknown_02024960.unk24[i].moves[3]; + var = gMonLinkData.monData[i].moves[3]; SetMonData(&gPlayerPartyPtr[i], MON_DATA_MOVE4, &var); - var = gUnknown_02024960.unk24[i].pps[0]; + var = gMonLinkData.monData[i].pps[0]; SetMonData(&gPlayerPartyPtr[i], MON_DATA_PP1, &var); - var = gUnknown_02024960.unk24[i].pps[1]; + var = gMonLinkData.monData[i].pps[1]; SetMonData(&gPlayerPartyPtr[i], MON_DATA_PP2, &var); - var = gUnknown_02024960.unk24[i].pps[2]; + var = gMonLinkData.monData[i].pps[2]; SetMonData(&gPlayerPartyPtr[i], MON_DATA_PP3, &var); - var = gUnknown_02024960.unk24[i].pps[3]; + var = gMonLinkData.monData[i].pps[3]; SetMonData(&gPlayerPartyPtr[i], MON_DATA_PP4, &var); - CpuCopy16((void*) gUnknown_02024960.unk24[i].unk38, sub_0200CB34(i), 320); + CpuCopy16((void*) gMonLinkData.monData[i].textBuffer, sub_0200CB34(i), 320); } } - if (gUnknown_02024960.unk_03_0 != 0) - gUnknown_02024960.unk_858 = 1; + if (gMonLinkData.unk_03_0 != 0) + gMonLinkData.unk_858 = 1; else - gUnknown_02024960.unk_858 = 0; + gMonLinkData.unk_858 = 0; } static s32 UNUSED sub_02005DCC(s32 monId, u32 stringId) @@ -1051,14 +1051,14 @@ bool32 sub_02005FCC(void) { bool32 val = sub_0200A2C8(0); - gUnknown_02024960.unk84C_02 = 0; + gMonLinkData.unk84C_02 = 0; if (!val) { REG_JOY_TRANS = 0; - while (!gUnknown_02024960.unk84C_02) + while (!gMonLinkData.unk84C_02) ; val = sub_0200A2C8(1); - while (gUnknown_02024960.unk84C_03) + while (gMonLinkData.unk84C_03) ; if (!val) @@ -1086,21 +1086,22 @@ static inline u8 Test2(const struct GFRomHeader *rom, void *sav2) return *ptr; } +// Based on the use of SetSpeciesCaughtFlag below, I'm assuming this doesn't end up getting used in standard situations? s32 sub_02006058(void) { s32 i; s32 var; WarningPrint(2); - while (!gUnknown_02024960.unk84C_01) + while (!gMonLinkData.transferComplete) { - if (!gUnknown_020251F0.field12) + if (!gTransferData.field12) return 2; } if (gRomDetection_IsRubySapphire) { - if (!(GetPlayerMapType() & 2)) + if (!(GetPlayerMapType() & POKECENTER_SAVEWARP)) { REG_JOY_TRANS = -1; WarningPrint(5); @@ -1122,7 +1123,7 @@ s32 sub_02006058(void) ErrorPrint(10); } - metGame = GetMonData(&gPlayerPartyPtr[gUnknown_02024960.unk84C_1], MON_DATA_MET_GAME, NULL); + metGame = GetMonData(&gPlayerPartyPtr[gMonLinkData.monId], MON_DATA_MET_GAME, NULL); f = 1 << metGame; if (!(flags & f)) { @@ -1132,17 +1133,17 @@ s32 sub_02006058(void) } WarningPrint(3); - SetSpeciesCaughtFlag(gUnknown_02024960.unk84C_2, &gPlayerPartyPtr[gUnknown_02024960.unk84C_2]); - if ((gUnknown_02024960.unk84C_3 | (gUnknown_02024960.unk850_1 << 8)) != 0) - SetSpeciesCaughtFlag((gUnknown_02024960.unk84C_3 | (gUnknown_02024960.unk850_1 << 8)), - &gPlayerPartyPtr[(gUnknown_02024960.unk84C_3 | (gUnknown_02024960.unk850_1 << 8))]); + SetSpeciesCaughtFlag(gMonLinkData.species2, &gPlayerPartyPtr[gMonLinkData.species2]); // This most likely is going to read way out of bounds as we're using species instead of slot ID + if ((gMonLinkData.speciesLowerByte | (gMonLinkData.speciesUpperByte << 8)) != 0) + SetSpeciesCaughtFlag((gMonLinkData.speciesLowerByte | (gMonLinkData.speciesUpperByte << 8)), + &gPlayerPartyPtr[(gMonLinkData.speciesLowerByte | (gMonLinkData.speciesUpperByte << 8))]); for (i = 0; i < 11; i++) { - if (gGiftRibbonsPtr[i] == 0 && gUnknown_02024960.field85C[i] != 0) + if (gGiftRibbonsPtr[i] == 0 && gMonLinkData.giftRibbons[i] != 0) { - gGiftRibbonsPtr[i] = gUnknown_02024960.field85C[i]; - GiveGiftRibbonToParty(i, gUnknown_02024960.field85C[i]); + gGiftRibbonsPtr[i] = gMonLinkData.giftRibbons[i]; + GiveGiftRibbonToParty(i, gMonLinkData.giftRibbons[i]); } } @@ -1161,9 +1162,9 @@ s32 sub_02006058(void) break; } - gUnknown_02024960.unk84C_00 = 0; - gUnknown_02024960.unk84C_01 = 0; - gUnknown_02024960.unk84C_02 = 0; + gMonLinkData.unk84C_00 = 0; + gMonLinkData.transferComplete = 0; + gMonLinkData.unk84C_02 = 0; return var; } @@ -1173,20 +1174,20 @@ s32 sub_02006264(void) s32 var; WarningPrint(3); - if (gUnknown_02024960.unk_85B != 0) + if (gMonLinkData.species3 != SPECIES_NONE) { (*gPlayerPartyCountPtr)++; - if (!GetSetPokedexFlag(gUnknown_02024960.unk_85B, FLAG_GET_CAUGHT)) + if (!GetSetPokedexFlag(gMonLinkData.species3, FLAG_GET_CAUGHT)) { - GetSetPokedexFlag(gUnknown_02024960.unk_85B, FLAG_SET_SEEN); - GetSetPokedexFlag(gUnknown_02024960.unk_85B, FLAG_SET_CAUGHT); + GetSetPokedexFlag(gMonLinkData.species3, FLAG_SET_SEEN); + GetSetPokedexFlag(gMonLinkData.species3, FLAG_SET_CAUGHT); } - for (i = 0; i < 11; i++) + for (i = 0; i < GIFT_RIBBONS_COUNT; i++) { - if (gGiftRibbonsPtr[i] == 0 && gUnknown_02024960.field85C[i] != 0) + if (gGiftRibbonsPtr[i] == 0 && gMonLinkData.giftRibbons[i] != 0) { - gGiftRibbonsPtr[i] = gUnknown_02024960.field85C[i]; - GiveGiftRibbonToParty(i, gUnknown_02024960.field85C[i]); + gGiftRibbonsPtr[i] = gMonLinkData.giftRibbons[i]; + GiveGiftRibbonToParty(i, gMonLinkData.giftRibbons[i]); } } } @@ -1205,58 +1206,58 @@ s32 sub_02006264(void) break; } - gUnknown_02024960.unk84C_00 = 0; - gUnknown_02024960.unk84C_01 = 0; - gUnknown_02024960.unk84C_02 = 0; + gMonLinkData.unk84C_00 = 0; + gMonLinkData.transferComplete = 0; + gMonLinkData.unk84C_02 = 0; return var; } void sub_02006344(void) { u16 species; - u32 r6 = gUnknown_02024960.unk10; + u32 r6 = gMonLinkData.species; if (r6 != 0) return; - gUnknown_02024960.unk_858 = 2; - gUnknown_02024960.unk8 = GetMonData(&gPlayerPartyPtr[0], MON_DATA_PERSONALITY, NULL); - gUnknown_02024960.unkC = GetMonData(&gPlayerPartyPtr[0], MON_DATA_OT_ID, NULL); + gMonLinkData.unk_858 = 2; + gMonLinkData.personality = GetMonData(&gPlayerPartyPtr[0], MON_DATA_PERSONALITY, NULL); + gMonLinkData.otId = GetMonData(&gPlayerPartyPtr[0], MON_DATA_OT_ID, NULL); species = GetMonData(&gPlayerPartyPtr[0], MON_DATA_SPECIES, NULL); - gUnknown_02024960.unk10 = species; - gUnknown_02024960.unk12 = r6; - gUnknown_02024960.unk14[0] = GetBoxMonMoveBySlot(&gPlayerPartyPtr[0].box, 0); - gUnknown_02024960.unk14[1] = GetBoxMonMoveBySlot(&gPlayerPartyPtr[0].box, 1); - gUnknown_02024960.unk14[2] = GetBoxMonMoveBySlot(&gPlayerPartyPtr[0].box, 2); - gUnknown_02024960.unk14[3] = GetBoxMonMoveBySlot(&gPlayerPartyPtr[0].box, 3); - gUnknown_02024960.unk1C[0] = GetBoxMonPPByMoveSlot(&gPlayerPartyPtr[0].box, 0); - gUnknown_02024960.unk1C[1] = GetBoxMonPPByMoveSlot(&gPlayerPartyPtr[0].box, 1); - gUnknown_02024960.unk1C[2] = GetBoxMonPPByMoveSlot(&gPlayerPartyPtr[0].box, 2); - gUnknown_02024960.unk1C[3] = GetBoxMonPPByMoveSlot(&gPlayerPartyPtr[0].box, 3); + gMonLinkData.species = species; + gMonLinkData.unk12 = r6; + gMonLinkData.moves[0] = GetBoxMonMoveBySlot(&gPlayerPartyPtr[0].box, 0); + gMonLinkData.moves[1] = GetBoxMonMoveBySlot(&gPlayerPartyPtr[0].box, 1); + gMonLinkData.moves[2] = GetBoxMonMoveBySlot(&gPlayerPartyPtr[0].box, 2); + gMonLinkData.moves[3] = GetBoxMonMoveBySlot(&gPlayerPartyPtr[0].box, 3); + gMonLinkData.pps[0] = GetBoxMonPPByMoveSlot(&gPlayerPartyPtr[0].box, 0); + gMonLinkData.pps[1] = GetBoxMonPPByMoveSlot(&gPlayerPartyPtr[0].box, 1); + gMonLinkData.pps[2] = GetBoxMonPPByMoveSlot(&gPlayerPartyPtr[0].box, 2); + gMonLinkData.pps[3] = GetBoxMonPPByMoveSlot(&gPlayerPartyPtr[0].box, 3); } u32 sub_020063FC(void) { - return (gUnknown_02024960.unk23_0) | (gUnknown_02024960.unk23_4 << 16); + return (gMonLinkData.unk23_0) | (gMonLinkData.unk23_4 << 16); } u32 sub_02006414(s32 moveSlot) { - return sub_020064BC(gUnknown_02024960.unk20, moveSlot) & 7; + return sub_020064BC(gMonLinkData.unk20, moveSlot) & 7; } u32 sub_02006430(s32 moveSlot) { - return (sub_020064BC(gUnknown_02024960.unk20, moveSlot) >> 3) & 1; + return (sub_020064BC(gMonLinkData.unk20, moveSlot) >> 3) & 1; } u32 sub_0200644C(void) { - return gUnknown_02024960.unk22_0; + return gMonLinkData.unk22_0; } u32 sub_0200645C(void) { - return gUnknown_02024960.unk22_4 + 1; + return gMonLinkData.unk22_4 + 1; } bool32 IsMonFainted(u32 monId) @@ -1271,15 +1272,15 @@ bool32 IsMonFainted(u32 monId) u32 sub_02006490(void) { - if (gUnknown_02024960.unk_03_0 != 0) - return gUnknown_02024960.unk_03_0 - 1; + if (gMonLinkData.unk_03_0 != 0) + return gMonLinkData.unk_03_0 - 1; else return 0; } u32 sub_020064B0(void) { - return gUnknown_02024960.unk_03_7; + return gMonLinkData.unk_03_7; } u32 sub_020064BC(u32 a0, s32 a1) @@ -1296,18 +1297,18 @@ u32 sub_020064BC(u32 a0, s32 a1) return a0 & 0xF; } -u32 sub_020064D0(s32 a0) +static u32 UNUSED IsPartySlotOccupied(s32 a0) // If return value is 0xF, slot is occupied { - u32 r1 = gUnknown_02024960.unk_00; + u32 partyCountNibbles = gMonLinkData.partyCountNibblefield; if (a0 > 0) { s32 r0 = a0; do { - r1 >>= 4; + partyCountNibbles >>= 4; r0--; } while (r0 != 0); } - return r1 & 0xF; + return partyCountNibbles & 0xF; } diff --git a/payload/src/main.c b/payload/src/main.c index c1886bb..f119d94 100644 --- a/payload/src/main.c +++ b/payload/src/main.c @@ -52,18 +52,18 @@ bool8 sub_0200023C(void) u32 r0; sub_02006490(); - if (gUnknown_02024960.unk_03_0 == 0) + if (gMonLinkData.unk_03_0 == 0) { - gUnknown_02024960.unk_858 = 1; + gMonLinkData.unk_858 = 1; } else { - gUnknown_02024960.unk_858 = 2; + gMonLinkData.unk_858 = 2; } sub_02002A9C(0, sub_02006490(), 1); - r0 = gUnknown_02024960.unk_87E | (gUnknown_02024960.unk_87B << 16); - gUnknown_02024960.unk_880 = r0; - gUnknown_02024960.unk_87F = 1; + r0 = gMonLinkData.unk_87E | (gMonLinkData.unk_87B << 16); + gMonLinkData.unk_880 = r0; + gMonLinkData.unk_87F = 1; return FALSE; } @@ -131,7 +131,7 @@ void GF_Main(void) sub_02005BB8(); if (sub_020064B0() == 0) { - sub_02005704((gUnknown_02024960.unk_03_0 != 0) ? gUnknown_02024960.unk_03_0 - 1 : 0); + sub_02005704((gMonLinkData.unk_03_0 != 0) ? gMonLinkData.unk_03_0 - 1 : 0); } else { @@ -251,7 +251,7 @@ _02000384:\t\n\ bl sub_020064B0\t\n\ cmp r0, #0\t\n\ bne _020003E4\t\n\ - ldr r1, =gUnknown_02024960\t\n\ + ldr r1, =gMonLinkData\t\n\ ldrb r0, [r1, #3]\t\n\ lsls r0, r0, #0x19\t\n\ cmp r0, #0\t\n\ diff --git a/payload/src/unk_200C5DC.c b/payload/src/unk_200C5DC.c index cb331f7..31c5246 100644 --- a/payload/src/unk_200C5DC.c +++ b/payload/src/unk_200C5DC.c @@ -15,12 +15,12 @@ // This file's functions u8 GetPlayerMapType(void); -u8 GetRSPlayerMapType(struct SaveBlock1 *sav1); -bool8 CheckIfPokedexIsObtained(void); -bool32 IsFRLG(void); -u8 ExtCtrlCodeGetLength(u8 c); +static u8 GetRSPlayerMapType(struct SaveBlock1 *sav1); +static bool8 CheckIfPokedexIsObtained(void); +static bool32 IsFRLG(void); +static u8 ExtCtrlCodeGetLength(u8 c); -u8 ItemIdToBallId(u16 ballItem) +u8 UNUSED ItemIdToBallId(u16 ballItem) { switch (ballItem) { @@ -64,6 +64,7 @@ bool32 GetSetPokedexFlag(u16 nationalDexNo, u8 caseID) bit = nationalDexNo % 8; mask = 1 << bit; retVal = FALSE; + switch (caseID) { case FLAG_GET_SEEN: @@ -71,7 +72,9 @@ bool32 GetSetPokedexFlag(u16 nationalDexNo, u8 caseID) { if ((gPokedexPtr->seen[index] & mask) == (gDexSeen2Ptr[index] & mask) && (gPokedexPtr->seen[index] & mask) == (gDexSeen3Ptr[index] & mask)) + { retVal = TRUE; + } else { gPokedexPtr->seen[index] &= ~mask; @@ -87,7 +90,9 @@ bool32 GetSetPokedexFlag(u16 nationalDexNo, u8 caseID) if ((gPokedexPtr->owned[index] & mask) == (gPokedexPtr->seen[index] & mask) && (gPokedexPtr->owned[index] & mask) == (gDexSeen2Ptr[index] & mask) && (gPokedexPtr->owned[index] & mask) == (gDexSeen3Ptr[index] & mask)) + { retVal = TRUE; + } else { gPokedexPtr->owned[index] &= ~mask; @@ -107,6 +112,7 @@ bool32 GetSetPokedexFlag(u16 nationalDexNo, u8 caseID) gPokedexPtr->owned[index] |= mask; break; } + return retVal; } @@ -122,6 +128,7 @@ static inline u16 SpeciesToNationalDexNumInline(u16 species) else { u32 tableId = species - 1; + if (tableId < NUM_SPECIES - 1) return gSpeciesToNationalPokedexNum[tableId]; @@ -129,7 +136,7 @@ static inline u16 SpeciesToNationalDexNumInline(u16 species) } } -u16 SpeciesToNationalDexNum(u16 species) +static u16 SpeciesToNationalDexNum(u16 species) { if (species == SPECIES_NONE) { @@ -138,6 +145,7 @@ u16 SpeciesToNationalDexNum(u16 species) else { u32 tableId = species - 1; + if (tableId < NUM_SPECIES - 1) return gSpeciesToNationalPokedexNum[tableId]; @@ -153,6 +161,7 @@ void SetSpeciesCaughtFlag(u32 species, struct Pokemon *mon) { if (species == SPECIES_UNOWN) gPokedexPtr->unownPersonality = mon->box.personality; + if (species == SPECIES_SPINDA) gPokedexPtr->spindaPersonality = mon->box.personality; } @@ -185,6 +194,7 @@ struct PlayerLinkInfo *SetPlayerLinkInfo(u8 *sav2, u8 *sav1, u32 saveStatus) struct PlayerLinkInfo* structPtr = &gPlayerLinkInfo; CpuFill16(0, &gPlayerLinkInfo, sizeof(struct PlayerLinkInfo)); + if (saveStatus == SAVE_STATUS_OK) { u8 *saveData; @@ -197,6 +207,7 @@ struct PlayerLinkInfo *SetPlayerLinkInfo(u8 *sav2, u8 *sav1, u32 saveStatus) structPtr->isChampion = ((GetPlayerMapType() & CHAMPION_SAVEWARP) != 0); structPtr->language = gAgbPmRomParams->language; } + saveData = &sav2[gAgbPmRomParams->playerNameOffset]; StringCopy(structPtr->playerName, saveData); @@ -204,11 +215,13 @@ struct PlayerLinkInfo *SetPlayerLinkInfo(u8 *sav2, u8 *sav1, u32 saveStatus) structPtr->playerGender = *saveData; saveData = &sav2[gAgbPmRomParams->trainerIdOffset]; - for (i = 0; i < 4; i++) + + for (i = 0; i < TRAINER_ID_LENGTH; i++) structPtr->playerTrainerId[i] = saveData[i]; for (i = 0; i < PARTY_SIZE; i++) CpuCopy16(&gPlayerPartyPtr[i], &structPtr->party[i], sizeof(struct Pokemon)); + for (i = 0; i < GIFT_RIBBONS_COUNT; i++) structPtr->giftRibbons[i] = gGiftRibbonsPtr[i]; } @@ -224,30 +237,31 @@ struct PlayerLinkInfo *SetPlayerLinkInfo(u8 *sav2, u8 *sav1, u32 saveStatus) { structPtr->errorCode = 3; } + return structPtr; } -struct PlayerLinkInfo *GetPlayerLinkInfo(void) +static struct PlayerLinkInfo *GetPlayerLinkInfo(void) { return &gPlayerLinkInfo; } extern u8 gUnknown_020241D0[][320]; -extern u8 gUnknown_02024950; +extern bool8 gUnknownBoolean; // 16 bytes reserved? u8 *sub_0200CB34(u32 id) { return gUnknown_020241D0[id]; } -void sub_0200CB48(u32 val) +static void SetUnknownBoolean(bool32 val) { - gUnknown_02024950 = val; + gUnknownBoolean = val; } -u32 sub_0200CB54(void) +bool32 GetUnknownBoolean(void) { - return gUnknown_02024950; + return gUnknownBoolean; } bool32 SetFlag(s32 flag) @@ -255,13 +269,15 @@ bool32 SetFlag(s32 flag) if (flag != 0) { u8 *flagPtr = &gFlagsPtr[flag / 8]; + if (flagPtr != NULL) *flagPtr |= 1 << (flag % 8); } + return FALSE; } -bool32 ClearFlag(s32 flag) +bool32 UNUSED ClearFlag(s32 flag) { u8 *flagPtr; @@ -269,12 +285,14 @@ bool32 ClearFlag(s32 flag) return FALSE; flagPtr = &gFlagsPtr[flag / 8]; + if (flagPtr != NULL) *flagPtr &= ~(1 << (flag % 8)); + return FALSE; } -bool32 CheckFlag(s32 flag) +static bool32 CheckFlag(s32 flag) { u8 *flagPtr; @@ -282,6 +300,7 @@ bool32 CheckFlag(s32 flag) return FALSE; flagPtr = &gFlagsPtr[flag / 8]; + if (flagPtr != NULL && *flagPtr & (1 << (flag % 8))) return TRUE; @@ -302,6 +321,7 @@ void DetectROM(void) gRomDetection_IsEnglishROM = FALSE; rsVersion = 0; gameCode = *(u32 *)(0x80000AC); + switch (gameCode) { default: @@ -363,28 +383,31 @@ void DetectROM(void) u8 GetPlayerMapType(void) { - u8 ret; + u8 retVal; + if (!gRomDetection_IsRubySapphire) { - ret = *((u8 *)(gSaveBlock2Ptr) + gAgbPmRomParams->warpFlagsOffset); + retVal = *((u8 *)(gSaveBlock2Ptr) + gAgbPmRomParams->warpFlagsOffset); } else { - ret = GetRSPlayerMapType(gSaveBlock1Ptr); - if (ret & CONTINUE_GAME_WARP) - ret |= CHAMPION_SAVEWARP; + retVal = GetRSPlayerMapType(gSaveBlock1Ptr); + if (retVal & CONTINUE_GAME_WARP) + retVal |= CHAMPION_SAVEWARP; } - return ret; + + return retVal; } -static void UNUSED sub_0200CD84(void) +static void UNUSED EmptyFunction(void) { } -u8 CheckIfPokedexIsObtained(void) +static u8 CheckIfPokedexIsObtained(void) { bool32 val; + if (!gRomDetection_IsRubySapphire) val = ((*((u8 *)(gSaveBlock2Ptr) + gAgbPmRomParams->gcnLinkFlagsOffset) & 1)); else @@ -396,7 +419,7 @@ u8 CheckIfPokedexIsObtained(void) return TRUE; } -bool32 IsFRLG(void) +static bool32 IsFRLG(void) { if (gAgbPmRomParams->version == VERSION_FIRE_RED || gAgbPmRomParams->version == VERSION_LEAF_GREEN) return TRUE; @@ -404,20 +427,23 @@ bool32 IsFRLG(void) return FALSE; } -bool32 CheckGameClear(void) +static bool32 CheckGameClear(void) { u8 *flagsPtr = gSaveBlock1Ptr + gAgbPmRomParams->flagsOffset + (gAgbPmRomParams->gameClearFlag / 8); + return (*flagsPtr & (1 << (gAgbPmRomParams->gameClearFlag % 8))) != 0; } u16 GetStringSizeHandleExtCtrlCodes(u8 *str) { u16 i = 0; + while (str[i] != EOS) { if (str[i++] == EXT_CTRL_CODE_BEGIN) i += ExtCtrlCodeGetLength(str[i]); } + return i; } @@ -429,7 +455,9 @@ static inline u8 *StringCopyInline(u8 *dst, const u8 *src) *dst = *src; dst++, src++; } + *dst = EOS; + return dst; } @@ -440,7 +468,9 @@ u8 *StringCopy(u8 *dst, const u8 *src) *dst = *src; dst++, src++; } + *dst = EOS; + return dst; } @@ -448,6 +478,7 @@ u8 *StringAppend(u8 *dst, const u8 *src) { while (*dst != EOS) dst++; + return StringCopyInline(dst, src); } @@ -457,6 +488,7 @@ s32 StringCompare(const u8 *str1, const u8 *str2) { if (*str1 == EOS) return 0; + str1++; str2++; } @@ -464,15 +496,17 @@ s32 StringCompare(const u8 *str1, const u8 *str2) return *str1 - *str2; } -u8 ExtCtrlCodeGetLength(u8 c) +static u8 ExtCtrlCodeGetLength(u8 c) { u8 len = 0; + if (c <= EXT_CTRL_CODE_ENG) len = gExtCtrlCodeLengths[c]; + return len; } -u8 GetRSPlayerMapType(struct SaveBlock1 *sav1) +static u8 GetRSPlayerMapType(struct SaveBlock1 *sav1) { s32 i; u16 mapGroup = sav1->location.mapGroup; @@ -483,57 +517,62 @@ u8 GetRSPlayerMapType(struct SaveBlock1 *sav1) if (gRSPokemonCenterMaps[i] == map) return POKECENTER_SAVEWARP; } + for (i = 0; gRSSpecialAreaMaps[i] != MAP_UNDEFINED; i++) { if (gRSSpecialAreaMaps[i] == map) return LOBBY_SAVEWARP; } + return 0; } -void sub_0200CF50(u32 val) +static void sub_0200CF50(u32 val) { - u32 a, b, c; - switch (gUnknown_020251F0.state) + u32 speciesLower1, speciesLower2, speciesUpper; + + switch (gTransferData.state) { case 0: - gUnknown_02024960.unk84C_1 = (u8)(val & 0x7); - gUnknown_020251F0.state++; + gMonLinkData.monId = (u8)(val & 0x7); + gTransferData.state++; break; case 1: - gUnknown_02024960.unk84C_2 = val & 0x0000FFFF; + gMonLinkData.species2 = val & 0xFFFF; // Weird bitwise operations needed to match. - a = (val >> 16) & 0xFFFF; - b = a & 0xFF; - gUnknown_02024960.unk84C_3 = b; + speciesLower1 = (val >> 16) & 0xFFFF; + speciesLower2 = speciesLower1 & 0xFF; + gMonLinkData.speciesLowerByte = speciesLower2; - c = (((val >> 16) & 0xFFFF) >> 8) & 0xFF; - gUnknown_02024960.unk850_1 = c; + speciesUpper = (((val >> 16) & 0xFFFF) >> 8) & 0xFF; + gMonLinkData.speciesUpperByte = speciesUpper; - gUnknown_02024960.field854 = (void*) &gPlayerPartyPtr[gUnknown_02024960.unk84C_1]; - gUnknown_020251F0.field4 = 100; - gUnknown_020251F0.field28 = 0; - gUnknown_020251F0.state++; + gMonLinkData.monPtr = (void*) &gPlayerPartyPtr[gMonLinkData.monId]; + gTransferData.transferSize = 100; + gTransferData.transferBytes = 0; + gTransferData.state++; break; case 2: - gUnknown_02024960.field854[gUnknown_020251F0.field28 / 4] = val; - gUnknown_020251F0.field28 += 4; - if (gUnknown_020251F0.field28 >= gUnknown_020251F0.field4) + gMonLinkData.monPtr[gTransferData.transferBytes / 4] = val; + gTransferData.transferBytes += 4; + + if (gTransferData.transferBytes >= gTransferData.transferSize) { - gUnknown_020251F0.field0 = (void *) gUnknown_02024960.field85C; - gUnknown_020251F0.field4 = sizeof(gUnknown_02024960.field85C); - gUnknown_020251F0.field28 = 0; - gUnknown_020251F0.state++; + gTransferData.data = (void *) gMonLinkData.giftRibbons; + gTransferData.transferSize = sizeof(gMonLinkData.giftRibbons); + gTransferData.transferBytes = 0; + gTransferData.state++; } break; case 3: - gUnknown_020251F0.field0[gUnknown_020251F0.field28 / 4] = val; - gUnknown_020251F0.field28 += 4; - if (gUnknown_020251F0.field28 >= gUnknown_020251F0.field4) + gTransferData.data[gTransferData.transferBytes / 4] = val; + gTransferData.transferBytes += 4; + + if (gTransferData.transferBytes >= gTransferData.transferSize) { - gUnknown_02024960.unk84C_01 = 1; - gUnknown_020251F0.field17 = 0; + gMonLinkData.transferComplete = 1; + gTransferData.field17 = 0; } break; } @@ -542,45 +581,51 @@ void sub_0200CF50(u32 val) void sub_0200D08C(u32 val) { s32 i; - switch (gUnknown_020251F0.state) + + switch (gTransferData.state) { case 0: - gUnknown_020251F0.field0[gUnknown_020251F0.field28 / 4] = val; - gUnknown_020251F0.field28 += 4; - if (gUnknown_020251F0.field28 >= gUnknown_020251F0.field4) + gTransferData.data[gTransferData.transferBytes / 4] = val; + gTransferData.transferBytes += 4; + + if (gTransferData.transferBytes >= gTransferData.transferSize) { - u32 r3 = gUnknown_02024960.unk_00; - gUnknown_02024960.unk_879 = 0; - for (i = 0; i < 6; i++) + u32 partyCountNibbles = gMonLinkData.partyCountNibblefield; + gMonLinkData.partyCount = 0; + + for (i = 0; i < PARTY_SIZE; i++) { - if ((r3 & 0xF) != 0xF) - gUnknown_02024960.unk_879++; - r3 >>= 4; + if ((partyCountNibbles & 0xF) != 0xF) + gMonLinkData.partyCount++; + partyCountNibbles >>= 4; } - gUnknown_020251F0.field28 = 0; - gUnknown_020251F0.field0 = (void *) gUnknown_02024960.unk24; - gUnknown_020251F0.field4 = gUnknown_02024960.unk_879 * 340; - gUnknown_020251F0.state++; + + gTransferData.transferBytes = 0; + gTransferData.data = (void *) gMonLinkData.monData; + gTransferData.transferSize = gMonLinkData.partyCount * sizeof(struct MonData); + gTransferData.state++; } break; case 1: - gUnknown_020251F0.field0[gUnknown_020251F0.field28 / 4] = val; - gUnknown_020251F0.field28 += 4; - if (gUnknown_020251F0.field28 >= gUnknown_020251F0.field4) + gTransferData.data[gTransferData.transferBytes / 4] = val; + gTransferData.transferBytes += 4; + + if (gTransferData.transferBytes >= gTransferData.transferSize) { - gUnknown_020251F0.field28 = 0; - gUnknown_020251F0.field0 = (void*) gUnknown_02024960.unk81C; - gUnknown_020251F0.field4 = gUnknown_02024960.unk7 * sizeof(struct UnkStruct81C); - gUnknown_020251F0.state++; + gTransferData.transferBytes = 0; + gTransferData.data = (void*) gMonLinkData.monName; + gTransferData.transferSize = gMonLinkData.unk7 * sizeof(struct MonName); + gTransferData.state++; } break; case 2: - gUnknown_020251F0.field0[gUnknown_020251F0.field28 / 4] = val; - gUnknown_020251F0.field28 += 4; - if (gUnknown_020251F0.field28 >= gUnknown_020251F0.field4) + gTransferData.data[gTransferData.transferBytes / 4] = val; + gTransferData.transferBytes += 4; + + if (gTransferData.transferBytes >= gTransferData.transferSize) { - gUnknown_020251F0.field17 = 0; - gUnknown_02024960.unk_87A = 1; + gTransferData.field17 = 0; + gMonLinkData.unk_87A = 1; } break; } @@ -600,79 +645,86 @@ void sub_0200D1AC(u32 val) { u8 *ptr = (u8 *)(gSaveBlock1Ptr) + gAgbPmRomParams->externalEventDataOffset; // Note: cast is needed here to make the code match. The whole struct is declared as volatile, but unkStruct isn't treated as volatile in this function. - // It's possible only certain members of gUnknown_02024960 were volatile. - struct ExternalEventData2 *externalEventData = (struct ExternalEventData2 *) &gUnknown_02024960.externalEventData; + // It's possible only certain members of gMonLinkData were volatile. + struct ExternalEventData2 *externalEventData = (struct ExternalEventData2 *) &gMonLinkData.externalEventData; - switch (gUnknown_020251F0.state) + switch (gTransferData.state) { case 0: externalEventData->currentPokeCoupons = val; - gUnknown_020251F0.state++; + gTransferData.state++; break; case 1: externalEventData->totalEarnedPokeCoupons = val; - gUnknown_020251F0.state++; + gTransferData.state++; break; case 2: externalEventData->receivedAgetoCelebi = 0; externalEventData->gotBronzePokeCouponTitleReward = 0; externalEventData->gotSilverPokeCouponTitleReward = 0; externalEventData->gotGoldPokeCouponTitleReward = 0; + if (val & 1) externalEventData->gotGoldPokeCouponTitleReward = 1; + if (val & 2) externalEventData->gotSilverPokeCouponTitleReward = 1; + if (val & 4) externalEventData->gotBronzePokeCouponTitleReward = 1; + if (val & 8) externalEventData->receivedAgetoCelebi = 1; CopyN(sizeof(*externalEventData), ptr, (void*) externalEventData); - gUnknown_020251F0.state++; + gTransferData.state++; break; case 3: - gUnknown_02024960.unk_85B = val >> 16; - gUnknown_020251F0.field4 = val & 0xFFFF; - gUnknown_020251F0.field28 = 0; - gUnknown_020251F0.field0 = (void *) gPcItemsPtr; - gUnknown_020251F0.state++; + gMonLinkData.species3 = val >> 16; + gTransferData.transferSize = val & 0xFFFF; + gTransferData.transferBytes = 0; + gTransferData.data = (void *) gPcItemsPtr; + gTransferData.state++; break; case 4: - gUnknown_020251F0.field0[gUnknown_020251F0.field28++] = val; - if (gUnknown_020251F0.field28 >= gUnknown_020251F0.field4) + gTransferData.data[gTransferData.transferBytes++] = val; + + if (gTransferData.transferBytes >= gTransferData.transferSize) { - if (gUnknown_02024960.unk_85B == 0) + if (gMonLinkData.species3 == SPECIES_NONE) { - gUnknown_020251F0.field17 = 0; - gUnknown_02024960.unk_85A = 1; + gTransferData.field17 = 0; + gMonLinkData.unk_85A = 1; } else { - gUnknown_020251F0.field4 = 100; - gUnknown_020251F0.field28 = 0; - gUnknown_020251F0.field0 = (void *) GetPtrToEmptyPartySlot(); - gUnknown_020251F0.state++; + gTransferData.transferSize = 100; + gTransferData.transferBytes = 0; + gTransferData.data = (void *) GetPtrToEmptyPartySlot(); + gTransferData.state++; } } break; case 5: - gUnknown_020251F0.field0[gUnknown_020251F0.field28 / 4] = val; - gUnknown_020251F0.field28 += 4; - if (gUnknown_020251F0.field28 >= gUnknown_020251F0.field4) + gTransferData.data[gTransferData.transferBytes / 4] = val; + gTransferData.transferBytes += 4; + + if (gTransferData.transferBytes >= gTransferData.transferSize) { - gUnknown_020251F0.field4 = sizeof(gUnknown_02024960.field85C); - gUnknown_020251F0.field28 = 0; - gUnknown_020251F0.field0 = (void *) gUnknown_02024960.field85C; - gUnknown_020251F0.state++; + gTransferData.transferSize = sizeof(gMonLinkData.giftRibbons); + gTransferData.transferBytes = 0; + gTransferData.data = (void *) gMonLinkData.giftRibbons; + gTransferData.state++; } break; case 6: - gUnknown_020251F0.field0[gUnknown_020251F0.field28 / 4] = val; - gUnknown_020251F0.field28 += 4; - if (gUnknown_020251F0.field28 >= gUnknown_020251F0.field4) + gTransferData.data[gTransferData.transferBytes / 4] = val; + gTransferData.transferBytes += 4; + + if (gTransferData.transferBytes >= gTransferData.transferSize) { - gUnknown_02024960.unk_85A = 1; - gUnknown_020251F0.field17 = 0; + gMonLinkData.unk_85A = 1; + gTransferData.field17 = 0; } break; } @@ -680,41 +732,43 @@ void sub_0200D1AC(u32 val) bool32 sub_0200D394(u32 val) { - u32 r3 = gUnknown_020251F0.field12; + u32 r3 = gTransferData.field12; + if (r3 == 0) { - if (gUnknown_020251F0.field13 != 2) + if (gTransferData.field13 != 2) { RET_FALSE: return FALSE; } - if (val == gUnknown_020251F0.field40) + if (val == gTransferData.field40) { REG_JOYSTAT = 0x10; - gUnknown_020251F0.field36 = val; - gUnknown_020251F0.field12 = 1; - gUnknown_020251F0.field17 = 1; + gTransferData.field36 = val; + gTransferData.field12 = 1; + gTransferData.field17 = 1; } - else if (val == gUnknown_020251F0.field44) + else if (val == gTransferData.field44) { REG_JOYSTAT = r3; - gUnknown_020251F0.field36 = val; - gUnknown_020251F0.field12 = 1; - gUnknown_020251F0.field17 = 0; + gTransferData.field36 = val; + gTransferData.field12 = 1; + gTransferData.field17 = 0; } else { return FALSE; } - gUnknown_020251F0.field13 = 0; - gUnknown_020251F0.field16 = 0; + gTransferData.field13 = 0; + gTransferData.field16 = 0; return TRUE; } else { - s32 r6 = gUnknown_020251F0.field17; + s32 r6 = gTransferData.field17; + switch (r6) { case 0: @@ -725,56 +779,56 @@ bool32 sub_0200D394(u32 val) } else if (val == 0x99) { - gUnknown_020251F0.field0 = (void *)GetPlayerLinkInfo(); + gTransferData.data = (void *)GetPlayerLinkInfo(); REG_JOY_TRANS = val; - gUnknown_020251F0.field4 = 0x278; - gUnknown_020251F0.field28 = r6; - gUnknown_020251F0.field17 = 4; + gTransferData.transferSize = 0x278; + gTransferData.transferBytes = r6; + gTransferData.field17 = 4; } else if (val == 0x88) { - gUnknown_020251F0.field0 = (void *) sub_0200CB34(0); - sub_0200CB48(0); + gTransferData.data = (void *) sub_0200CB34(0); + SetUnknownBoolean(0); REG_JOY_TRANS = val; - gUnknown_020251F0.field4 = 0x780; - gUnknown_020251F0.field28 = r6; - gUnknown_020251F0.field17 = val; + gTransferData.transferSize = 0x780; + gTransferData.transferBytes = r6; + gTransferData.field17 = val; } else if (val == 0x77) { REG_JOY_TRANS = val; - gUnknown_020251F0.field17 = val; + gTransferData.field17 = val; } else if (val == 0x66) { REG_JOY_TRANS = val; - gUnknown_020251F0.field17 = val; - gUnknown_020251F0.field0 = (void*) &gUnknown_02024960; - gUnknown_020251F0.field4 = 0x24; - gUnknown_020251F0.field28 = r6; - gUnknown_020251F0.state = r6; - gUnknown_02024960.unk_87A = r6; + gTransferData.field17 = val; + gTransferData.data = (void*) &gMonLinkData; + gTransferData.transferSize = 0x24; + gTransferData.transferBytes = r6; + gTransferData.state = r6; + gMonLinkData.unk_87A = r6; } else if (val == 0x55) { - gUnknown_02024960.unk84C_00 = 1; - gUnknown_02024960.unk84C_01 = 0; + gMonLinkData.unk84C_00 = 1; + gMonLinkData.transferComplete = 0; REG_JOY_TRANS = val; - gUnknown_020251F0.field17 = val; - gUnknown_020251F0.state = r6; + gTransferData.field17 = val; + gTransferData.state = r6; } else if (val == 0x44) { REG_JOY_TRANS = val; - gUnknown_020251F0.field17 = val; - gUnknown_02024960.unk84C_02 = 1; - gUnknown_02024960.unk84C_03 = 1; + gTransferData.field17 = val; + gMonLinkData.unk84C_02 = 1; + gMonLinkData.unk84C_03 = 1; } else if (val == 0x33 || val == 0x22) { REG_JOY_TRANS = val; - gUnknown_020251F0.field17 = val; - gUnknown_020251F0.state = 0; + gTransferData.field17 = val; + gTransferData.state = 0; } else if (val == 0x60) { @@ -790,21 +844,22 @@ bool32 sub_0200D394(u32 val) } break; case 136: - gUnknown_020251F0.field0[gUnknown_020251F0.field28 / 4] = val; - gUnknown_020251F0.field28 += 4; - if (gUnknown_020251F0.field28 >= gUnknown_020251F0.field4) + gTransferData.data[gTransferData.transferBytes / 4] = val; + gTransferData.transferBytes += 4; + + if (gTransferData.transferBytes >= gTransferData.transferSize) { REG_JOYSTAT = 0; - gUnknown_020251F0.field17 = 0; - gUnknown_020251F0.field12 = 0; - sub_0200CB48(1); + gTransferData.field17 = 0; + gTransferData.field12 = 0; + SetUnknownBoolean(1); } break; case 119: - gUnknown_02024960.unk_858 = val >> 24; - gUnknown_02024960.unk_859 = val; - gUnknown_02024960.unk_878 = 1; - gUnknown_020251F0.field17 = 0; + gMonLinkData.unk_858 = val >> 24; + gMonLinkData.unk_859 = val; + gMonLinkData.unk_878 = 1; + gTransferData.field17 = 0; break; case 102: sub_0200D08C(val); @@ -827,40 +882,41 @@ void sub_0200D624(void) bool32 gameClear; u32 joyTransVal; u8 *ptr = (u8 *)(gSaveBlock1Ptr) + gAgbPmRomParams->externalEventDataOffset; - struct ExternalEventData2 *externalEventData = (struct ExternalEventData2 *) &gUnknown_02024960.externalEventData; + struct ExternalEventData2 *externalEventData = (struct ExternalEventData2 *) &gMonLinkData.externalEventData; - switch (gUnknown_020251F0.state) + switch (gTransferData.state) { case 0: CopyN(sizeof(*externalEventData), (void*) externalEventData, ptr); REG_JOY_TRANS = externalEventData->currentPokeCoupons; - gUnknown_020251F0.state++; + gTransferData.state++; break; case 1: REG_JOY_TRANS = externalEventData->totalEarnedPokeCoupons; - gUnknown_020251F0.state++; + gTransferData.state++; break; case 2: gameClear = CheckGameClear(); joyTransVal = (externalEventData->gotGoldPokeCouponTitleReward << 0) | (externalEventData->gotSilverPokeCouponTitleReward << 1) | (externalEventData->gotBronzePokeCouponTitleReward << 2) | (externalEventData->receivedAgetoCelebi << 3) | (gameClear << 4); REG_JOY_TRANS = joyTransVal; - gUnknown_020251F0.state++; + gTransferData.state++; break; case 3: - gUnknown_020251F0.field4 = gAgbPmRomParams->pcItemsCount; - gUnknown_020251F0.field28 = 0; + gTransferData.transferSize = gAgbPmRomParams->pcItemsCount; + gTransferData.transferBytes = 0; joyTransVal = (*gPlayerPartyCountPtr << 16); - joyTransVal |= gUnknown_020251F0.field4; + joyTransVal |= gTransferData.transferSize; REG_JOY_TRANS = joyTransVal; - gUnknown_020251F0.field0 = (void *) gPcItemsPtr; - gUnknown_020251F0.state++; + gTransferData.data = (void *) gPcItemsPtr; + gTransferData.state++; break; case 4: - REG_JOY_TRANS = gUnknown_020251F0.field0[gUnknown_020251F0.field28++]; - if (gUnknown_020251F0.field28 == gUnknown_020251F0.field4) + REG_JOY_TRANS = gTransferData.data[gTransferData.transferBytes++]; + + if (gTransferData.transferBytes == gTransferData.transferSize) { - gUnknown_020251F0.field17 = 0; - gUnknown_020251F0.field12 = 0; + gTransferData.field17 = 0; + gTransferData.field12 = 0; } break; } @@ -868,11 +924,11 @@ void sub_0200D624(void) bool32 sub_0200D748(void) { - if (gUnknown_020251F0.field12 == 0) + if (gTransferData.field12 == 0) { - if (gUnknown_020251F0.field13 == 1) + if (gTransferData.field13 == 1) { - gUnknown_020251F0.field13 = 2; + gTransferData.field13 = 2; return TRUE; } else @@ -882,27 +938,27 @@ bool32 sub_0200D748(void) } else { - switch (gUnknown_020251F0.field17) + switch (gTransferData.field17) { case 4: - if (gUnknown_020251F0.field28 < gUnknown_020251F0.field4) + if (gTransferData.transferBytes < gTransferData.transferSize) { - REG_JOY_TRANS = gUnknown_020251F0.field0[gUnknown_020251F0.field28 / 4]; - gUnknown_020251F0.field28 += 4; + REG_JOY_TRANS = gTransferData.data[gTransferData.transferBytes / 4]; + gTransferData.transferBytes += 4; } else { REG_JOYSTAT = 0; - gUnknown_020251F0.field17 = 0; - gUnknown_020251F0.field12 = 0; + gTransferData.field17 = 0; + gTransferData.field12 = 0; } break; case 0x33: sub_0200D624(); break; case 0x44: - gUnknown_02024960.unk84C_03 = 0; - gUnknown_020251F0.field17 = 0; + gMonLinkData.unk84C_03 = 0; + gTransferData.field17 = 0; break; case 0x55: case 0x66: @@ -921,32 +977,35 @@ bool32 sub_0200D748(void) void sub_0200D80C(void) { u32 joyCnt = REG_JOYCNT; + if (!(joyCnt & 4) || sub_0200D748() != 0) { if (!(joyCnt & 2)) goto loc_200D850; - gUnknown_020251F0.field11 = 1; + + gTransferData.field11 = 1; + if (sub_0200D394(REG_JOY_RECV) != 0) goto loc_200D850; } REG_JOYSTAT = 0; - gUnknown_020251F0.field12 = 0; - gUnknown_020251F0.field13 = 0; + gTransferData.field12 = 0; + gTransferData.field13 = 0; loc_200D850: if (joyCnt & 1) { u16 UNUSED joyRcv = REG_JOY_RECV; - REG_JOY_TRANS = gUnknown_020251F0.field32; + REG_JOY_TRANS = gTransferData.field32; REG_JOYSTAT = 0; - gUnknown_020251F0.field12 = 0; - gUnknown_020251F0.field13 = 1; - gUnknown_020251F0.field20 = REG_VCOUNT; + gTransferData.field12 = 0; + gTransferData.field13 = 1; + gTransferData.field20 = REG_VCOUNT; } REG_JOYCNT = joyCnt; - gUnknown_020251F0.field15 = 0; + gTransferData.field15 = 0; } void sub_0200D8A4(void) @@ -955,7 +1014,7 @@ void sub_0200D8A4(void) u16 ime = REG_IME; REG_IME = 0; - if (gUnknown_020251F0.field18 == 0) + if (gTransferData.field18 == 0) REG_RCNT = 0x8000; REG_RCNT = 0xC000; REG_JOYSTAT = 0; @@ -965,12 +1024,12 @@ void sub_0200D8A4(void) REG_IF = 0x80; REG_IE |= 0x80; - gUnknown_020251F0.field15 = 0; - gUnknown_020251F0.field12 = 0; - gUnknown_020251F0.field13 = 0; - gUnknown_020251F0.field18 = 0; - gUnknown_020251F0.field17 = 0; - gUnknown_020251F0.field11 = 0; + gTransferData.field15 = 0; + gTransferData.field12 = 0; + gTransferData.field13 = 0; + gTransferData.field18 = 0; + gTransferData.field17 = 0; + gTransferData.field11 = 0; REG_IME = ime; } @@ -981,21 +1040,25 @@ void sub_0200D924(const u8 *headerSth) u16 ime = REG_IME; REG_IME = 0; - for (i = 0; i < sizeof(gUnknown_020251F0); i++) + + for (i = 0; i < sizeof(gTransferData); i++) { - *((u8 *)(&gUnknown_020251F0) + i) = 0; + *((u8 *)(&gTransferData) + i) = 0; } - gUnknown_020251F0.field18 = 1; + + gTransferData.field18 = 1; sub_0200D8A4(); REG_IE |= 0x80; + if (headerSth[0] == 0x54 && headerSth[1] == 0x45 && headerSth[2] == 0x53 && headerSth[3] == 0x54) - gUnknown_020251F0.field14 = 0xFE; + gTransferData.field14 = 0xFE; else - gUnknown_020251F0.field14 = 0x28; - gUnknown_020251F0.field32 = (headerSth[3] << 24) | (headerSth[2] << 16) | (headerSth[1] << 8) | (headerSth[0]); - gUnknown_020251F0.field44 = gUnknown_020251F0.field32; - gUnknown_020251F0.field40 = gUnknown_020251F0.field32 | 0x20202020; - gUnknown_020251F0.field48 = (headerSth[4] << 24) | (headerSth[5] << 16) | (headerSth[6] << 8) | (headerSth[7]); + gTransferData.field14 = 0x28; + + gTransferData.field32 = (headerSth[3] << 24) | (headerSth[2] << 16) | (headerSth[1] << 8) | (headerSth[0]); + gTransferData.field44 = gTransferData.field32; + gTransferData.field40 = gTransferData.field32 | 0x20202020; + gTransferData.field48 = (headerSth[4] << 24) | (headerSth[5] << 16) | (headerSth[6] << 8) | (headerSth[7]); SetIntrFunc(0, sub_0200D80C); REG_IME = ime; @@ -1006,15 +1069,15 @@ bool32 sub_0200D9EC(void) if (*(u8*)(0x80000B2) != 0x96) SoftReset(0); - if (gUnknown_020251F0.field15 <= gUnknown_020251F0.field14) + if (gTransferData.field15 <= gTransferData.field14) { REG_IME = 0; - gUnknown_020251F0.field15++; + gTransferData.field15++; REG_IME = 1; return FALSE; } - gUnknown_020251F0.field16 = 1; + gTransferData.field16 = 1; SoftReset(0); } diff --git a/payload/sym_common.txt b/payload/sym_common.txt index 4ed7f0a..9e2eee7 100644 --- a/payload/sym_common.txt +++ b/payload/sym_common.txt @@ -149,10 +149,10 @@ gPlayerLinkInfo: gUnknown_020241D0: .space 0x780 @ 6 * 320 -gUnknown_02024950: +gUnknownBoolean: .space 0x10 -gUnknown_02024960: +gMonLinkData: .space 0x884 gRomDetection_IsEnglishROM: @@ -164,7 +164,7 @@ gAgbPmRomParams: gRomDetection_IsRubySapphire: .space 0x4 -gUnknown_020251F0: +gTransferData: .space 0x34 .include "agb_flash.o" From e6635c70037dcf9830af3ea7fd364bed941b581c Mon Sep 17 00:00:00 2001 From: citrusbolt Date: Sat, 2 Mar 2024 15:26:27 -0700 Subject: [PATCH 4/4] Document more of `unk_200C5DC.c` --- payload/include/all.h | 6 +- payload/include/gba/io_reg.h | 9 ++ payload/include/unk_200C5DC.h | 25 +++- payload/src/all.c | 210 +++++++++++++++++----------------- payload/src/all4.c | 8 +- payload/src/main.c | 19 +-- payload/src/unk_200C5DC.c | 195 +++++++++++++++---------------- 7 files changed, 249 insertions(+), 223 deletions(-) diff --git a/payload/include/all.h b/payload/include/all.h index e8adcca..ae5bb05 100644 --- a/payload/include/all.h +++ b/payload/include/all.h @@ -34,7 +34,7 @@ struct MonData u32 setMailTo1:1; u32 preserveHeldItem:1; u32 heldItem:16; // 0x28 - u16 unk2A; + u16 unused; u16 moves[MAX_MON_MOVES]; // 0x2C , 0x2E , 0x30, 0x32 u8 pps[MAX_MON_MOVES]; // 0x34-0x37 u8 textBuffer[320]; @@ -46,7 +46,7 @@ struct MonLinkData u32 unk_03_0:7; u32 unk_03_7:1; u32 unk4:24; - u32 unk7:8; + u32 monCount:8; u32 personality; u32 otId; u16 species; @@ -71,7 +71,7 @@ struct MonLinkData u32 unk850_2:24; u32 *monPtr; u8 unk_858; - u8 unk_859; + u8 numMonsToSelect; u8 unk_85A; u8 species3; // Only 1 byte, so can not contain a Hoenn species u8 ALIGNED(4) giftRibbons[GIFT_RIBBONS_COUNT + 1]; // Aligned for u32 copy diff --git a/payload/include/gba/io_reg.h b/payload/include/gba/io_reg.h index f0bbec1..a2dada6 100644 --- a/payload/include/gba/io_reg.h +++ b/payload/include/gba/io_reg.h @@ -699,6 +699,15 @@ #define SIO_MULTI_DI_SHIFT 3 #define SIO_MULTI_DI_MASK 0x1 +// joy bus +#define JOYCNT_RESET (1 << 0) +#define JOYCNT_RECV_CMPLT (1 << 1) +#define JOYCNT_TRAN_CMPLT (1 << 2) +#define JOYCNT_RESET_IRQ (1 << 6) + +#define RCNT_JOYBUS1 (1 << 14) +#define RCNT_JOYBUS2 (1 << 15) + // keys #define A_BUTTON 0x0001 #define B_BUTTON 0x0002 diff --git a/payload/include/unk_200C5DC.h b/payload/include/unk_200C5DC.h index 8a90ae1..bcf1789 100644 --- a/payload/include/unk_200C5DC.h +++ b/payload/include/unk_200C5DC.h @@ -6,6 +6,21 @@ #define LOBBY_SAVEWARP (1 << 2) #define CHAMPION_SAVEWARP (1 << 7) +#define LINK_CMD_RESET 0x00 +#define LINK_CMD_0x01 0x01 +#define LINK_CMD_TRAN_PLAYER_DATA2 0x04 +#define LINK_CMD_RECV_GIFT_DATA 0x22 +#define LINK_CMD_TRAN_GIFT_DATA 0x33 +#define LINK_CMD_0x44 0x44 +#define LINK_CMD_RECV_PARTY_MON 0x55 +#define LINK_CMD_SOFT_RESET_ROM 0x60 +#define LINK_CMD_SOFT_RESET 0x61 +#define LINK_CMD_RECV_MON_DATA 0x66 +#define LINK_CMD_RECV_UNKNOWN 0x77 +#define LINK_CMD_RECV_TEXT 0x88 +#define LINK_CMD_TRAN_PLAYER_DATA1 0x99 +#define LINK_CMD_READ_INPUT 0xAA + struct TransferData { volatile u32 *data; @@ -18,7 +33,7 @@ struct TransferData u8 field14; u8 field15; u8 field16; - u8 field17; + u8 currentCmd; u8 field18; u8 fill19; u8 field20; @@ -30,11 +45,11 @@ struct TransferData u8 fill26; u8 fill27; u32 transferBytes; - u32 field32; + u32 gameCode; u32 field36; - u32 field40; - u32 field44; - u32 field48; + u32 lowerCaseGameCode; + u32 gameCode2; + u32 makerCode; }; extern volatile struct TransferData gTransferData; diff --git a/payload/src/all.c b/payload/src/all.c index 83333fd..f2587ab 100644 --- a/payload/src/all.c +++ b/payload/src/all.c @@ -64,7 +64,7 @@ struct Unk02021860Struct u8 unk118; u8 unk119; u8 unk11A; - u8 unk11B; + u8 selectedMon; u8 filler11C; u8 filler11D; u8 unk11E; @@ -72,8 +72,8 @@ struct Unk02021860Struct u8 unk120; u8 unk121; u8 unk122; - u8 unk123; - u8 unk124; + u8 numMonsToSelect; + u8 numMonsLeftToSelect; u8 unk125; }; @@ -651,7 +651,7 @@ void CreateMonIcon(struct Sprite *sprite) r1 = sprite->data[2] & 1; CopyMonIconToVram(ptr, r1); SetSpritePos(sprite, ptr->unk1, ptr->unk2); - if (gUnknown_02021860.unk11B == ptr->monId) + if (gUnknown_02021860.selectedMon == ptr->monId) { if (gUnknown_02021860.unk121 == 4) AddSpritePos(sprite, 0, -gUnknown_02021860.unk121); @@ -672,10 +672,10 @@ void sub_02000BFC(void) struct Window *win; s32 i; - for (i = 0; i < 6; i++) + for (i = 0; i < PARTY_SIZE; i++) { struct UnkSpriteMonIconStruct *ptr = &gUnknown_02021860.unk0[i]; - if (ptr->unk22 == gUnknown_02021860.unk124) + if (ptr->unk22 == gUnknown_02021860.numMonsLeftToSelect) { ptr->unk22 = 0; win = ptr->win; @@ -692,8 +692,8 @@ void sub_02000BFC(void) TextWindowSetXY(win, 0, 2); RenderText(win, gText_Number); } - gUnknown_02021860.unk124--; - gUnknown_02021860.unk11B = i; + gUnknown_02021860.numMonsLeftToSelect--; + gUnknown_02021860.selectedMon = i; break; } } @@ -744,12 +744,12 @@ void sub_02000D74(struct Unk02021860Struct *a0, const struct Unk02000D74Struct * CopyToBgTilemapBufferRect(3, coords->x, coords->y, r5->unk0, r5->unk1, (u16 *) (VRAM + 0x14000) + r5->unk2); if (r9->statusPrimary != STATUS_PRIMARY_FAINTED) { - if (a0->unk11B == monId) + if (a0->selectedMon == monId) SetBgTilemapBufferPaletteRect(3, coords->x, coords->y, r5->unk0, r5->unk1, 7); } else { - if (a0->unk11B == monId) + if (a0->selectedMon == monId) SetBgTilemapBufferPaletteRect(3, coords->x, coords->y, r5->unk0, r5->unk1, 9); else SetBgTilemapBufferPaletteRect(3, coords->x, coords->y, r5->unk0, r5->unk1, 5); @@ -836,12 +836,12 @@ void sub_02001258(struct Unk02021860Struct *a0, const struct Unk02000D74Struct * CopyToBgTilemapBufferRect(3, coords->x, coords->y, r5->unk0, r5->unk1, (u16 *) (VRAM + 0x14000) + r5->unk2); if (r9->statusPrimary != STATUS_PRIMARY_FAINTED) { - if (a0->unk11B == monId) + if (a0->selectedMon == monId) SetBgTilemapBufferPaletteRect(3, coords->x, coords->y, r5->unk0, r5->unk1, 7); } else { - if (a0->unk11B == monId) + if (a0->selectedMon == monId) SetBgTilemapBufferPaletteRect(3, coords->x, coords->y, r5->unk0, r5->unk1, 9); else SetBgTilemapBufferPaletteRect(3, coords->x, coords->y, r5->unk0, r5->unk1, 5); @@ -916,12 +916,12 @@ void sub_02001738(u32 selectMonsTextId) gUnknown_02021860.unk108 = AddWindow(0, &gUnknown_0201F8B0); SetTextColor(gUnknown_02021860.unk108, 1, 8); ClearWindowCharBuffer(gUnknown_02021860.unk108, 0xFFFF); - if (gUnknown_02021860.unk123 != 0) + if (gUnknown_02021860.numMonsToSelect != 0) { switch (selectMonsTextId) { case 0: - text[0] = gUnknown_02021860.unk123 + CHAR_0; + text[0] = gUnknown_02021860.numMonsToSelect + CHAR_0; text[1] = EOS; BufferString(0, text); RenderText(gUnknown_02021860.unk108, gText_SelectNumberPokemon); @@ -1120,38 +1120,38 @@ s32 sub_02001A8C(u32 monId) } else { - if (IsMonFainted(gUnknown_02021860.unk11B) == TRUE) + if (IsMonFainted(gUnknown_02021860.selectedMon) == TRUE) { PlaySE(SONG_SE_FAILURE); - sub_020019B4(gUnknown_02021860.unk11B, 10); + sub_020019B4(gUnknown_02021860.selectedMon, 10); i = 2; } - else if (gUnknown_02021860.unk122 == gUnknown_02021860.unk11B) + else if (gUnknown_02021860.unk122 == gUnknown_02021860.selectedMon) { PlaySE(SONG_SE_FAILURE); - sub_020019B4(gUnknown_02021860.unk11B, 11); + sub_020019B4(gUnknown_02021860.selectedMon, 11); i = 2; } else { - switch (sub_020064BC(gMonLinkData.unk4, gUnknown_02021860.unk11B)) + switch (sub_020064BC(gMonLinkData.unk4, gUnknown_02021860.selectedMon)) { case 0: PlaySE(SONG_SE_SELECT); - gMonLinkData.unk_87E = gUnknown_02021860.unk11B; + gMonLinkData.unk_87E = gUnknown_02021860.selectedMon; gMonLinkData.unk_87B = 2; return -1; case 1: PlaySE(SONG_SE_FAILURE); - sub_020019B4(gUnknown_02021860.unk11B, 13); + sub_020019B4(gUnknown_02021860.selectedMon, 13); break; case 2: PlaySE(SONG_SE_FAILURE); - sub_020019B4(gUnknown_02021860.unk11B, 11); + sub_020019B4(gUnknown_02021860.selectedMon, 11); break; case 3: PlaySE(SONG_SE_FAILURE); - sub_020019B4(gUnknown_02021860.unk11B, 12); + sub_020019B4(gUnknown_02021860.selectedMon, 12); break; } i = 2; @@ -1161,13 +1161,13 @@ s32 sub_02001A8C(u32 monId) case 4: PlaySE(SONG_SE_SELECT); FadeOut(); - gUnknown_02021860.unk11B = sub_020044F0(gUnknown_02021860.unk11B); - monId = gUnknown_02021860.unk11B; + gUnknown_02021860.selectedMon = sub_020044F0(gUnknown_02021860.selectedMon); + monId = gUnknown_02021860.selectedMon; if (gUnknown_02021860.unk11A == 1) { - if (gUnknown_02021860.unk11B == 0) + if (gUnknown_02021860.selectedMon == 0) gUnknown_02021860.unk11E = 2; - else if (gUnknown_02021860.unk11B == 1) + else if (gUnknown_02021860.selectedMon == 1) gUnknown_02021860.unk11E = 4; } sub_020017E8(&gUnknown_02021860); @@ -1274,7 +1274,7 @@ s32 sub_02001F04(s32 ret) case 3: if (var_24->unk22 == 0) { - if (gUnknown_02021860.unk124 == gUnknown_02021860.unk123) + if (gUnknown_02021860.numMonsLeftToSelect == gUnknown_02021860.numMonsToSelect) { PlaySE(SONG_SE_FAILURE); i = 1; @@ -1282,11 +1282,11 @@ s32 sub_02001F04(s32 ret) else { PlaySE(SONG_SE_SELECT); - var_24->unk22 = ++gUnknown_02021860.unk124; + var_24->unk22 = ++gUnknown_02021860.numMonsLeftToSelect; sub_02002EE0(var_24->win, var_24); REG_JOY_TRANS = 0x1000000; - if (gUnknown_02021860.unk124 == gUnknown_02021860.unk123) - gUnknown_02021860.unk11B = 6; + if (gUnknown_02021860.numMonsLeftToSelect == gUnknown_02021860.numMonsToSelect) + gUnknown_02021860.selectedMon = 6; i = 2; } } @@ -1303,23 +1303,23 @@ s32 sub_02001F04(s32 ret) var_24->unk22 = 0; sub_02002EE0(var_24->win, var_24); REG_JOY_TRANS = 0xFF000000; - gUnknown_02021860.unk124--; + gUnknown_02021860.numMonsLeftToSelect--; i = 2; } break; case 4: PlaySE(SONG_SE_SELECT); FadeOut(); - gUnknown_02021860.unk11B = sub_020044F0(gUnknown_02021860.unk11B); + gUnknown_02021860.selectedMon = sub_020044F0(gUnknown_02021860.selectedMon); if (gUnknown_02021860.unk11A == 1) { - if (gUnknown_02021860.unk11B == 0) + if (gUnknown_02021860.selectedMon == 0) gUnknown_02021860.unk11E = 2; - else if (gUnknown_02021860.unk11B == 1) + else if (gUnknown_02021860.selectedMon == 1) gUnknown_02021860.unk11E = 4; } sub_020017E8(&gUnknown_02021860); - ret = gUnknown_02021860.unk11B; + ret = gUnknown_02021860.selectedMon; var_24 = &gUnknown_02021860.unk0[ret]; i = 0; break; @@ -1360,7 +1360,7 @@ s32 sub_020023E8(void) } if (keys & A_BUTTON) { - if (gUnknown_02021860.unk11B == PARTY_SIZE) + if (gUnknown_02021860.selectedMon == PARTY_SIZE) { if (gUnknown_02021860.unk125 == 0) { @@ -1378,67 +1378,67 @@ s32 sub_020023E8(void) s32 var = 0; PlaySE(SONG_SE_SELECT); - var = sub_02001A8C(gUnknown_02021860.unk11B); + var = sub_02001A8C(gUnknown_02021860.selectedMon); if (var == -1) return -1; } } - monId = gUnknown_02021860.unk11B; + monId = gUnknown_02021860.selectedMon; if (keys & DPAD_UP) { PlaySE(SONG_SE_SELECT); - if (gUnknown_02021860.unk11B == 0) - gUnknown_02021860.unk11B = PARTY_SIZE; - else if (gUnknown_02021860.unk11B == PARTY_SIZE) - gUnknown_02021860.unk11B = gUnknown_02021860.unk120; + if (gUnknown_02021860.selectedMon == 0) + gUnknown_02021860.selectedMon = PARTY_SIZE; + else if (gUnknown_02021860.selectedMon == PARTY_SIZE) + gUnknown_02021860.selectedMon = gUnknown_02021860.unk120; else - gUnknown_02021860.unk11B--; - gUnknown_02021860.unk11E = r9[gUnknown_02021860.unk11B].a2; + gUnknown_02021860.selectedMon--; + gUnknown_02021860.unk11E = r9[gUnknown_02021860.selectedMon].a2; } if (keys & DPAD_DOWN) { PlaySE(SONG_SE_SELECT); - if (gUnknown_02021860.unk11B == gUnknown_02021860.unk120) - gUnknown_02021860.unk11B = PARTY_SIZE; - else if (gUnknown_02021860.unk11B == PARTY_SIZE) - gUnknown_02021860.unk11B = 0; + if (gUnknown_02021860.selectedMon == gUnknown_02021860.unk120) + gUnknown_02021860.selectedMon = PARTY_SIZE; + else if (gUnknown_02021860.selectedMon == PARTY_SIZE) + gUnknown_02021860.selectedMon = 0; else - gUnknown_02021860.unk11B++; - gUnknown_02021860.unk11E = r9[gUnknown_02021860.unk11B].a2; + gUnknown_02021860.selectedMon++; + gUnknown_02021860.unk11E = r9[gUnknown_02021860.selectedMon].a2; } if (keys & DPAD_LEFT) { PlaySE(SONG_SE_SELECT); - if (r9[gUnknown_02021860.unk11B].a1 != 0xFF) + if (r9[gUnknown_02021860.selectedMon].a1 != 0xFF) { - gUnknown_02021860.unk11E = gUnknown_02021860.unk11B; - gUnknown_02021860.unk11B = r9[gUnknown_02021860.unk11B].a1; + gUnknown_02021860.unk11E = gUnknown_02021860.selectedMon; + gUnknown_02021860.selectedMon = r9[gUnknown_02021860.selectedMon].a1; } } if (keys & DPAD_RIGHT) { PlaySE(SONG_SE_SELECT); - switch (r9[gUnknown_02021860.unk11B].a0) + switch (r9[gUnknown_02021860.selectedMon].a0) { case 0xFF: break; case 7: - gUnknown_02021860.unk11B = gUnknown_02021860.unk11E; - if (gUnknown_02021860.unk11B > gUnknown_02021860.unk120) + gUnknown_02021860.selectedMon = gUnknown_02021860.unk11E; + if (gUnknown_02021860.selectedMon > gUnknown_02021860.unk120) { - gUnknown_02021860.unk11B = gUnknown_02021860.unk120; - if (gUnknown_02021860.unk11A == 1 && gUnknown_02021860.unk11B == 1 && monId == 0) - gUnknown_02021860.unk11B = monId; + gUnknown_02021860.selectedMon = gUnknown_02021860.unk120; + if (gUnknown_02021860.unk11A == 1 && gUnknown_02021860.selectedMon == 1 && monId == 0) + gUnknown_02021860.selectedMon = monId; } break; default: - gUnknown_02021860.unk11B = r9[gUnknown_02021860.unk11B].a0; + gUnknown_02021860.selectedMon = r9[gUnknown_02021860.selectedMon].a0; break; } } - if (monId == gUnknown_02021860.unk11B) + if (monId == gUnknown_02021860.selectedMon) continue; if (monId != PARTY_SIZE) @@ -1455,11 +1455,11 @@ s32 sub_020023E8(void) SetBgTilemapBufferPaletteRect(1, 24, 18, 6, 2, 1); } - if (gUnknown_02021860.unk11B != PARTY_SIZE) + if (gUnknown_02021860.selectedMon != PARTY_SIZE) { - r4 = &var_24[gUnknown_02021860.unk11B]; + r4 = &var_24[gUnknown_02021860.selectedMon]; r5 = &gUnknown_0201F9B0[r4->a2]; - if (GetMonStatus(&gPlayerPartyPtr[gUnknown_02021860.unk11B]) != STATUS_PRIMARY_FAINTED) + if (GetMonStatus(&gPlayerPartyPtr[gUnknown_02021860.selectedMon]) != STATUS_PRIMARY_FAINTED) SetBgTilemapBufferPaletteRect(3, r4->a0, r4->a1, r5->unk0, r5->unk1, 7); else SetBgTilemapBufferPaletteRect(3, r4->a0, r4->a1, r5->unk0, r5->unk1, 9); @@ -1496,7 +1496,7 @@ inline void sub_02002F60(void) u32 bits = 0; u32 r6 = 0; - for (i = 1; i < gUnknown_02021860.unk124 + 1; i++) + for (i = 1; i < gUnknown_02021860.numMonsLeftToSelect + 1; i++) { s32 ret = sub_02002F38(i); if (ret != -1) @@ -1523,10 +1523,10 @@ s32 sub_020026F4(void) if (keys == 0) continue; - monId = gUnknown_02021860.unk11B; + monId = gUnknown_02021860.selectedMon; if (keys & B_BUTTON) { - if (gUnknown_02021860.unk124 != 0) + if (gUnknown_02021860.numMonsLeftToSelect != 0) { sub_02000BFC(); PlaySE(SONG_SE_SELECT); @@ -1540,9 +1540,9 @@ s32 sub_020026F4(void) } if (keys & A_BUTTON) { - if (gUnknown_02021860.unk11B == PARTY_SIZE) + if (gUnknown_02021860.selectedMon == PARTY_SIZE) { - if (gUnknown_02021860.unk124 != gUnknown_02021860.unk123) + if (gUnknown_02021860.numMonsLeftToSelect != gUnknown_02021860.numMonsToSelect) { PlaySE(SONG_SE_FAILURE); sub_02001738(1); @@ -1556,7 +1556,7 @@ s32 sub_020026F4(void) } else { - s32 var = sub_02001F04(gUnknown_02021860.unk11B); + s32 var = sub_02001F04(gUnknown_02021860.selectedMon); if (var == -1) return -1; else if (var != monId) @@ -1567,57 +1567,57 @@ s32 sub_020026F4(void) if (keys & DPAD_UP) { PlaySE(SONG_SE_SELECT); - if (gUnknown_02021860.unk11B == 0) - gUnknown_02021860.unk11B = PARTY_SIZE; - else if (gUnknown_02021860.unk11B == PARTY_SIZE) - gUnknown_02021860.unk11B = gUnknown_02021860.unk120; + if (gUnknown_02021860.selectedMon == 0) + gUnknown_02021860.selectedMon = PARTY_SIZE; + else if (gUnknown_02021860.selectedMon == PARTY_SIZE) + gUnknown_02021860.selectedMon = gUnknown_02021860.unk120; else - gUnknown_02021860.unk11B--; - gUnknown_02021860.unk11E = r9[gUnknown_02021860.unk11B].a2; + gUnknown_02021860.selectedMon--; + gUnknown_02021860.unk11E = r9[gUnknown_02021860.selectedMon].a2; } if (keys & DPAD_DOWN) { PlaySE(SONG_SE_SELECT); - if (gUnknown_02021860.unk11B == gUnknown_02021860.unk120) - gUnknown_02021860.unk11B = PARTY_SIZE; - else if (gUnknown_02021860.unk11B == PARTY_SIZE) - gUnknown_02021860.unk11B = 0; + if (gUnknown_02021860.selectedMon == gUnknown_02021860.unk120) + gUnknown_02021860.selectedMon = PARTY_SIZE; + else if (gUnknown_02021860.selectedMon == PARTY_SIZE) + gUnknown_02021860.selectedMon = 0; else - gUnknown_02021860.unk11B++; - gUnknown_02021860.unk11E = r9[gUnknown_02021860.unk11B].a2; + gUnknown_02021860.selectedMon++; + gUnknown_02021860.unk11E = r9[gUnknown_02021860.selectedMon].a2; } if (keys & DPAD_LEFT) { PlaySE(SONG_SE_SELECT); - if (r9[gUnknown_02021860.unk11B].a1 != 0xFF) + if (r9[gUnknown_02021860.selectedMon].a1 != 0xFF) { - gUnknown_02021860.unk11E = gUnknown_02021860.unk11B; - gUnknown_02021860.unk11B = r9[gUnknown_02021860.unk11B].a1; + gUnknown_02021860.unk11E = gUnknown_02021860.selectedMon; + gUnknown_02021860.selectedMon = r9[gUnknown_02021860.selectedMon].a1; } } if (keys & DPAD_RIGHT) { PlaySE(SONG_SE_SELECT); - switch (r9[gUnknown_02021860.unk11B].a0) + switch (r9[gUnknown_02021860.selectedMon].a0) { case 0xFF: break; case 7: - gUnknown_02021860.unk11B = gUnknown_02021860.unk11E; - if (gUnknown_02021860.unk11B > gUnknown_02021860.unk120) + gUnknown_02021860.selectedMon = gUnknown_02021860.unk11E; + if (gUnknown_02021860.selectedMon > gUnknown_02021860.unk120) { - gUnknown_02021860.unk11B = gUnknown_02021860.unk120; - if (gUnknown_02021860.unk11A == 1 && gUnknown_02021860.unk11B == 1 && monId == 0) - gUnknown_02021860.unk11B = monId; + gUnknown_02021860.selectedMon = gUnknown_02021860.unk120; + if (gUnknown_02021860.unk11A == 1 && gUnknown_02021860.selectedMon == 1 && monId == 0) + gUnknown_02021860.selectedMon = monId; } break; default: - gUnknown_02021860.unk11B = r9[gUnknown_02021860.unk11B].a0; + gUnknown_02021860.selectedMon = r9[gUnknown_02021860.selectedMon].a0; break; } } - if (monId == gUnknown_02021860.unk11B) + if (monId == gUnknown_02021860.selectedMon) continue; if (monId != PARTY_SIZE) @@ -1634,11 +1634,11 @@ s32 sub_020026F4(void) SetBgTilemapBufferPaletteRect(1, 24, 18, 6, 2, 1); } - if (gUnknown_02021860.unk11B != PARTY_SIZE) + if (gUnknown_02021860.selectedMon != PARTY_SIZE) { - r4 = &var_24[gUnknown_02021860.unk11B]; + r4 = &var_24[gUnknown_02021860.selectedMon]; r5 = &gUnknown_0201F9B0[r4->a2]; - if (GetMonStatus(&gPlayerPartyPtr[gUnknown_02021860.unk11B]) != STATUS_PRIMARY_FAINTED) + if (GetMonStatus(&gPlayerPartyPtr[gUnknown_02021860.selectedMon]) != STATUS_PRIMARY_FAINTED) SetBgTilemapBufferPaletteRect(3, r4->a0, r4->a1, r5->unk0, r5->unk1, 7); else SetBgTilemapBufferPaletteRect(3, r4->a0, r4->a1, r5->unk0, r5->unk1, 9); @@ -1667,7 +1667,7 @@ void sub_02002A9C(s32 a0, u32 a1, u32 a2) u32 status; gUnknown_02021860.unk122 = a1; - gUnknown_02021860.unk11B = 0; + gUnknown_02021860.selectedMon = 0; gUnknown_02021860.unk125 = a2; gUnknown_02021860.unk11A = 0; @@ -1685,7 +1685,7 @@ void sub_02002A9C(s32 a0, u32 a1, u32 a2) { case 0: gUnknown_02021860.unk118 = 0; - gUnknown_02021860.unk123 = 0; + gUnknown_02021860.numMonsToSelect = 0; sub_020017E8(&gUnknown_02021860); FadeIn(); sub_020023E8(); @@ -1693,10 +1693,10 @@ void sub_02002A9C(s32 a0, u32 a1, u32 a2) break; case 1: gUnknown_02021860.unk118 = 1; - gUnknown_02021860.unk123 = gMonLinkData.unk_859; - if (gUnknown_02021860.unk123 == 0 || gUnknown_02021860.unk123 > *gPlayerPartyCountPtr) - gUnknown_02021860.unk123 = *gPlayerPartyCountPtr; - gUnknown_02021860.unk124 = 0; + gUnknown_02021860.numMonsToSelect = gMonLinkData.numMonsToSelect; + if (gUnknown_02021860.numMonsToSelect == 0 || gUnknown_02021860.numMonsToSelect > *gPlayerPartyCountPtr) + gUnknown_02021860.numMonsToSelect = *gPlayerPartyCountPtr; + gUnknown_02021860.numMonsLeftToSelect = 0; for (i = 0; i < PARTY_SIZE; i++) { gUnknown_02021860.unk0[i].unk22 = 0; @@ -1919,13 +1919,13 @@ void sub_02002C44(void) { CpuFill16(0, &gUnknown_02021860, sizeof(gUnknown_02021860)); gUnknown_02021860.unk11A = 0; - gUnknown_02021860.unk11B = 0; + gUnknown_02021860.selectedMon = 0; gUnknown_02021860.unk11E = 1; } void sub_02002C80(void) { - gUnknown_02021860.unk11B = 0; + gUnknown_02021860.selectedMon = 0; if (gUnknown_02021860.unk11A == 0) gUnknown_02021860.unk11E = 1; else diff --git a/payload/src/all4.c b/payload/src/all4.c index 9354500..725dc3a 100644 --- a/payload/src/all4.c +++ b/payload/src/all4.c @@ -141,7 +141,7 @@ u32 sub_020047D4(void) else ClearWindowCharBuffer(gMessageWindowPtr, 0xFFFF); - gMonLinkData.unk_859 = 0; + gMonLinkData.numMonsToSelect = 0; gMonLinkData.transferComplete = 0; gMonLinkData.unk_87A = 0; gMonLinkData.unk84C_00 = 0; @@ -169,7 +169,7 @@ u32 sub_020047D4(void) while (r5 == 0) { DelayFrames(1); - if (gMonLinkData.unk_859 != 0 && GetUnknownBoolean() == 1) + if (gMonLinkData.numMonsToSelect != 0 && GetUnknownBoolean() == 1) r5 = 2; if (gMonLinkData.unk84C_00 == 1) { @@ -672,7 +672,7 @@ s32 sub_02005468(void) ClearWindowCharBuffer(gUnknown_02021A20.unk18, 0xFFFF); StringCopy(gStringBuffers[0], sub_0200531C(0)); StringCopy(gStringBuffers[1], sub_0200531C(1)); - if (gMonLinkData.unk7 == 4) + if (gMonLinkData.monCount == 4) { StringCopy(gStringBuffers[2], sub_0200531C(2)); StringCopy(gStringBuffers[3], sub_0200531C(3)); @@ -685,7 +685,7 @@ s32 sub_02005468(void) sub_02004F04(gUnknown_02021A20.unk18, gUnknown_0201FDF4, 4); gBgTilemapBufferTransferScheduled[3] = TRUE; gBgTilemapBufferTransferScheduled[2] = TRUE; - return gMonLinkData.unk7; + return gMonLinkData.monCount; } s32 sub_02005548(void) diff --git a/payload/src/main.c b/payload/src/main.c index f119d94..b532d08 100644 --- a/payload/src/main.c +++ b/payload/src/main.c @@ -19,11 +19,12 @@ struct RomHeader { - u8 a0[0xA8]; - u8 unkA8[8]; + u8 nintendoLogo[156]; + u8 gameTitle[12]; + u8 gameCode[8]; }; -extern void sub_0200D9EC(void); +extern void VBlankCB(void); extern const struct RomHeader gRomHeader; extern u8 gSaveStatus; extern u8 gUnknown_020217B8; @@ -33,7 +34,7 @@ extern struct Unk02021860Struct gUnknown_02021860; extern s32 sub_020063FC(void); extern s32 sub_020064BC(u32 a0, u32 a1); extern u32 sub_020044F0(u32 a0); -extern void sub_0200D924(const u8*); +extern void InitLink(const u8* gameCode); void sub_02002A9C(s32 a0, u32 a1, u32 a2); void sub_02002C44(void); @@ -111,15 +112,15 @@ void GF_Main(void) InitSound(); sub_02002C44(); SetKeyRepeatTiming(0x28, 5); - REG_IE = 1; + REG_IE = INTR_FLAG_VBLANK; REG_DISPSTAT = 8; REG_DISPCNT &= (0xFF7F); REG_IME = 1; SetPlayerLinkInfo(gSaveBlock2Ptr, gSaveBlock1Ptr, gSaveStatus); - sub_0200D924(gRomHeader.unkA8); + InitLink(gRomHeader.gameCode); - SetVBlankCallback(sub_0200D9EC); + SetVBlankCallback(VBlankCB); PauseSoundVSync(); GenerateFontHalfrowLookupTable((u32 *) 0x03004000); FadeOut(); @@ -235,8 +236,8 @@ _0200032C:\t\n\ ldrb r2, [r2]\t\n\ bl SetPlayerLinkInfo\t\n\ adds r0, r6, #0\t\n\ - bl sub_0200D924\t\n\ - ldr r0, =sub_0200D9EC\t\n\ + bl InitLink\t\n\ + ldr r0, =VBlankCB\t\n\ bl SetVBlankCallback\t\n\ bl PauseSoundVSync\t\n\ ldr r0, =0x03004000\t\n\ diff --git a/payload/src/unk_200C5DC.c b/payload/src/unk_200C5DC.c index 31c5246..2979519 100644 --- a/payload/src/unk_200C5DC.c +++ b/payload/src/unk_200C5DC.c @@ -527,7 +527,7 @@ static u8 GetRSPlayerMapType(struct SaveBlock1 *sav1) return 0; } -static void sub_0200CF50(u32 val) +static void ReceivePartyMon(u32 val) { u32 speciesLower1, speciesLower2, speciesUpper; @@ -549,7 +549,7 @@ static void sub_0200CF50(u32 val) gMonLinkData.speciesUpperByte = speciesUpper; gMonLinkData.monPtr = (void*) &gPlayerPartyPtr[gMonLinkData.monId]; - gTransferData.transferSize = 100; + gTransferData.transferSize = sizeof(struct Pokemon); gTransferData.transferBytes = 0; gTransferData.state++; break; @@ -572,13 +572,13 @@ static void sub_0200CF50(u32 val) if (gTransferData.transferBytes >= gTransferData.transferSize) { gMonLinkData.transferComplete = 1; - gTransferData.field17 = 0; + gTransferData.currentCmd = LINK_CMD_RESET; } break; } } -void sub_0200D08C(u32 val) +static void ReceiveMonData(u32 val) { s32 i; @@ -614,7 +614,7 @@ void sub_0200D08C(u32 val) { gTransferData.transferBytes = 0; gTransferData.data = (void*) gMonLinkData.monName; - gTransferData.transferSize = gMonLinkData.unk7 * sizeof(struct MonName); + gTransferData.transferSize = gMonLinkData.monCount * sizeof(struct MonName); gTransferData.state++; } break; @@ -624,7 +624,7 @@ void sub_0200D08C(u32 val) if (gTransferData.transferBytes >= gTransferData.transferSize) { - gTransferData.field17 = 0; + gTransferData.currentCmd = LINK_CMD_RESET; gMonLinkData.unk_87A = 1; } break; @@ -641,10 +641,10 @@ static inline void CopyN(s32 n, u8 *dst, const u8 *src) } } -void sub_0200D1AC(u32 val) +static void ReceiveGiftData(u32 val) { u8 *ptr = (u8 *)(gSaveBlock1Ptr) + gAgbPmRomParams->externalEventDataOffset; - // Note: cast is needed here to make the code match. The whole struct is declared as volatile, but unkStruct isn't treated as volatile in this function. + // Note: cast is needed here to make the code match. The whole struct is declared as volatile, but externalEventData isn't treated as volatile in this function. // It's possible only certain members of gMonLinkData were volatile. struct ExternalEventData2 *externalEventData = (struct ExternalEventData2 *) &gMonLinkData.externalEventData; @@ -693,12 +693,12 @@ void sub_0200D1AC(u32 val) { if (gMonLinkData.species3 == SPECIES_NONE) { - gTransferData.field17 = 0; + gTransferData.currentCmd = LINK_CMD_RESET; gMonLinkData.unk_85A = 1; } else { - gTransferData.transferSize = 100; + gTransferData.transferSize = sizeof(struct Pokemon); gTransferData.transferBytes = 0; gTransferData.data = (void *) GetPtrToEmptyPartySlot(); gTransferData.state++; @@ -724,13 +724,13 @@ void sub_0200D1AC(u32 val) if (gTransferData.transferBytes >= gTransferData.transferSize) { gMonLinkData.unk_85A = 1; - gTransferData.field17 = 0; + gTransferData.currentCmd = LINK_CMD_RESET; } break; } } -bool32 sub_0200D394(u32 val) +static bool32 ProcessReceiveCommand(u32 val) { u32 r3 = gTransferData.field12; @@ -742,19 +742,19 @@ bool32 sub_0200D394(u32 val) return FALSE; } - if (val == gTransferData.field40) + if (val == gTransferData.lowerCaseGameCode) { REG_JOYSTAT = 0x10; gTransferData.field36 = val; gTransferData.field12 = 1; - gTransferData.field17 = 1; + gTransferData.currentCmd = LINK_CMD_0x01; } - else if (val == gTransferData.field44) + else if (val == gTransferData.gameCode2) { REG_JOYSTAT = r3; gTransferData.field36 = val; gTransferData.field12 = 1; - gTransferData.field17 = 0; + gTransferData.currentCmd = LINK_CMD_RESET; } else { @@ -767,108 +767,108 @@ bool32 sub_0200D394(u32 val) } else { - s32 r6 = gTransferData.field17; + s32 currentCmd = gTransferData.currentCmd; - switch (r6) + switch (currentCmd) { - case 0: + case LINK_CMD_RESET: val >>= 24; - if (val == 0xAA) + if (val == LINK_CMD_READ_INPUT) { REG_JOY_TRANS = (gHeldKeys << 0x10) | val; } - else if (val == 0x99) + else if (val == LINK_CMD_TRAN_PLAYER_DATA1) { gTransferData.data = (void *)GetPlayerLinkInfo(); REG_JOY_TRANS = val; - gTransferData.transferSize = 0x278; - gTransferData.transferBytes = r6; - gTransferData.field17 = 4; + gTransferData.transferSize = sizeof(struct PlayerLinkInfo); + gTransferData.transferBytes = currentCmd; // 0 + gTransferData.currentCmd = LINK_CMD_TRAN_PLAYER_DATA2; } - else if (val == 0x88) + else if (val == LINK_CMD_RECV_TEXT) { gTransferData.data = (void *) sub_0200CB34(0); SetUnknownBoolean(0); REG_JOY_TRANS = val; - gTransferData.transferSize = 0x780; - gTransferData.transferBytes = r6; - gTransferData.field17 = val; + gTransferData.transferSize = sizeof(*gUnknown_020241D0) * 6; + gTransferData.transferBytes = currentCmd; // 0 + gTransferData.currentCmd = val; } - else if (val == 0x77) + else if (val == LINK_CMD_RECV_UNKNOWN) { REG_JOY_TRANS = val; - gTransferData.field17 = val; + gTransferData.currentCmd = val; } - else if (val == 0x66) + else if (val == LINK_CMD_RECV_MON_DATA) { REG_JOY_TRANS = val; - gTransferData.field17 = val; + gTransferData.currentCmd = val; gTransferData.data = (void*) &gMonLinkData; - gTransferData.transferSize = 0x24; - gTransferData.transferBytes = r6; - gTransferData.state = r6; - gMonLinkData.unk_87A = r6; + gTransferData.transferSize = 0x24; // Everything before monData + gTransferData.transferBytes = currentCmd; // 0 + gTransferData.state = currentCmd; // 0 + gMonLinkData.unk_87A = currentCmd; // 0 } - else if (val == 0x55) + else if (val == LINK_CMD_RECV_PARTY_MON) { gMonLinkData.unk84C_00 = 1; gMonLinkData.transferComplete = 0; REG_JOY_TRANS = val; - gTransferData.field17 = val; - gTransferData.state = r6; + gTransferData.currentCmd = val; + gTransferData.state = currentCmd; // 0 } - else if (val == 0x44) + else if (val == LINK_CMD_0x44) { REG_JOY_TRANS = val; - gTransferData.field17 = val; + gTransferData.currentCmd = val; gMonLinkData.unk84C_02 = 1; gMonLinkData.unk84C_03 = 1; } - else if (val == 0x33 || val == 0x22) + else if (val == LINK_CMD_TRAN_GIFT_DATA || val == LINK_CMD_RECV_GIFT_DATA) { REG_JOY_TRANS = val; - gTransferData.field17 = val; + gTransferData.currentCmd = val; gTransferData.state = 0; } - else if (val == 0x60) + else if (val == LINK_CMD_SOFT_RESET_ROM) { REG_JOY_TRANS = val; REG_IME = 0; SoftResetRom(0); } - else if (val == 0x61) + else if (val == LINK_CMD_SOFT_RESET) { REG_JOY_TRANS = val; REG_IME = 0; SoftReset(0); } break; - case 136: + case LINK_CMD_RECV_TEXT: gTransferData.data[gTransferData.transferBytes / 4] = val; gTransferData.transferBytes += 4; if (gTransferData.transferBytes >= gTransferData.transferSize) { REG_JOYSTAT = 0; - gTransferData.field17 = 0; + gTransferData.currentCmd = LINK_CMD_RESET; gTransferData.field12 = 0; SetUnknownBoolean(1); } break; - case 119: + case LINK_CMD_RECV_UNKNOWN: gMonLinkData.unk_858 = val >> 24; - gMonLinkData.unk_859 = val; + gMonLinkData.numMonsToSelect = val; gMonLinkData.unk_878 = 1; - gTransferData.field17 = 0; + gTransferData.currentCmd = LINK_CMD_RESET; break; - case 102: - sub_0200D08C(val); + case LINK_CMD_RECV_MON_DATA: + ReceiveMonData(val); break; - case 85: - sub_0200CF50(val); + case LINK_CMD_RECV_PARTY_MON: + ReceivePartyMon(val); break; - case 34: - sub_0200D1AC(val); + case LINK_CMD_RECV_GIFT_DATA: + ReceiveGiftData(val); break; default: goto RET_FALSE; // return FALSE doesn't match @@ -877,7 +877,7 @@ bool32 sub_0200D394(u32 val) return TRUE; } -void sub_0200D624(void) +static void TransmitGiftData(void) { bool32 gameClear; u32 joyTransVal; @@ -915,14 +915,14 @@ void sub_0200D624(void) if (gTransferData.transferBytes == gTransferData.transferSize) { - gTransferData.field17 = 0; + gTransferData.currentCmd = LINK_CMD_RESET; gTransferData.field12 = 0; } break; } } -bool32 sub_0200D748(void) +static bool32 ProcessTransmitCommand(void) { if (gTransferData.field12 == 0) { @@ -938,9 +938,9 @@ bool32 sub_0200D748(void) } else { - switch (gTransferData.field17) + switch (gTransferData.currentCmd) { - case 4: + case LINK_CMD_TRAN_PLAYER_DATA2: if (gTransferData.transferBytes < gTransferData.transferSize) { REG_JOY_TRANS = gTransferData.data[gTransferData.transferBytes / 4]; @@ -949,23 +949,24 @@ bool32 sub_0200D748(void) else { REG_JOYSTAT = 0; - gTransferData.field17 = 0; + gTransferData.currentCmd = LINK_CMD_RESET; gTransferData.field12 = 0; } break; - case 0x33: - sub_0200D624(); + case LINK_CMD_RECV_GIFT_DATA: break; - case 0x44: + case LINK_CMD_TRAN_GIFT_DATA: + TransmitGiftData(); + break; + case LINK_CMD_0x44: gMonLinkData.unk84C_03 = 0; - gTransferData.field17 = 0; + gTransferData.currentCmd = LINK_CMD_RESET; break; - case 0x55: - case 0x66: - case 0x60: - case 0x77: - case 0x88: - case 0x22: + case LINK_CMD_RECV_PARTY_MON: + case LINK_CMD_SOFT_RESET_ROM: + case LINK_CMD_RECV_MON_DATA: + case LINK_CMD_RECV_UNKNOWN: + case LINK_CMD_RECV_TEXT: break; default: return FALSE; @@ -974,18 +975,18 @@ bool32 sub_0200D748(void) return TRUE; } -void sub_0200D80C(void) +static void JoyBusVCOuntIntr(void) { u32 joyCnt = REG_JOYCNT; - if (!(joyCnt & 4) || sub_0200D748() != 0) + if (!(joyCnt & JOYCNT_TRAN_CMPLT) || ProcessTransmitCommand() != FALSE) { - if (!(joyCnt & 2)) + if (!(joyCnt & JOYCNT_RECV_CMPLT)) goto loc_200D850; gTransferData.field11 = 1; - if (sub_0200D394(REG_JOY_RECV) != 0) + if (ProcessReceiveCommand(REG_JOY_RECV) != FALSE) goto loc_200D850; } @@ -994,10 +995,10 @@ void sub_0200D80C(void) gTransferData.field13 = 0; loc_200D850: - if (joyCnt & 1) + if (joyCnt & JOYCNT_RESET) { u16 UNUSED joyRcv = REG_JOY_RECV; - REG_JOY_TRANS = gTransferData.field32; + REG_JOY_TRANS = gTransferData.gameCode; REG_JOYSTAT = 0; gTransferData.field12 = 0; gTransferData.field13 = 1; @@ -1008,33 +1009,33 @@ void sub_0200D80C(void) gTransferData.field15 = 0; } -void sub_0200D8A4(void) +static void InitJoyBus(void) { u16 UNUSED joyRcv; u16 ime = REG_IME; REG_IME = 0; if (gTransferData.field18 == 0) - REG_RCNT = 0x8000; - REG_RCNT = 0xC000; + REG_RCNT = RCNT_JOYBUS2; + REG_RCNT = RCNT_JOYBUS1 | RCNT_JOYBUS2; REG_JOYSTAT = 0; joyRcv = REG_JOY_RECV; REG_JOY_TRANS = 0; - REG_JOYCNT = 0x47; - REG_IF = 0x80; - REG_IE |= 0x80; + REG_JOYCNT = JOYCNT_RESET | JOYCNT_RECV_CMPLT | JOYCNT_TRAN_CMPLT | JOYCNT_RESET_IRQ; + REG_IF = INTR_FLAG_SERIAL; + REG_IE |= INTR_FLAG_SERIAL; gTransferData.field15 = 0; gTransferData.field12 = 0; gTransferData.field13 = 0; gTransferData.field18 = 0; - gTransferData.field17 = 0; + gTransferData.currentCmd = LINK_CMD_RESET; gTransferData.field11 = 0; REG_IME = ime; } -void sub_0200D924(const u8 *headerSth) +void InitLink(const u8 *gameCode) { s32 i; u16 ime = REG_IME; @@ -1047,26 +1048,26 @@ void sub_0200D924(const u8 *headerSth) } gTransferData.field18 = 1; - sub_0200D8A4(); - REG_IE |= 0x80; + InitJoyBus(); + REG_IE |= INTR_FLAG_SERIAL; - if (headerSth[0] == 0x54 && headerSth[1] == 0x45 && headerSth[2] == 0x53 && headerSth[3] == 0x54) + if (gameCode[0] == 'T' && gameCode[1] == 'E' && gameCode[2] == 'S' && gameCode[3] == 'T') gTransferData.field14 = 0xFE; else gTransferData.field14 = 0x28; - gTransferData.field32 = (headerSth[3] << 24) | (headerSth[2] << 16) | (headerSth[1] << 8) | (headerSth[0]); - gTransferData.field44 = gTransferData.field32; - gTransferData.field40 = gTransferData.field32 | 0x20202020; - gTransferData.field48 = (headerSth[4] << 24) | (headerSth[5] << 16) | (headerSth[6] << 8) | (headerSth[7]); - SetIntrFunc(0, sub_0200D80C); + gTransferData.gameCode = (gameCode[3] << 24) | (gameCode[2] << 16) | (gameCode[1] << 8) | (gameCode[0]); + gTransferData.gameCode2 = gTransferData.gameCode; + gTransferData.lowerCaseGameCode = gTransferData.gameCode | 0x20202020; // Turns upper case ASCII to lower case + gTransferData.makerCode = (gameCode[4] << 24) | (gameCode[5] << 16) | (gameCode[6] << 8) | (gameCode[7]); + SetIntrFunc(0, JoyBusVCOuntIntr); REG_IME = ime; } -bool32 sub_0200D9EC(void) +bool32 VBlankCB(void) { - if (*(u8*)(0x80000B2) != 0x96) + if (*(u8*)(0x80000B2) != 0x96) // gRomHeader.gameCode[6] != 0x96 SoftReset(0); if (gTransferData.field15 <= gTransferData.field14) @@ -1081,7 +1082,7 @@ bool32 sub_0200D9EC(void) SoftReset(0); } -void UNUSED sub_0200DA38(u8 *dst, const u8 *src, s32 n) +static void UNUSED CopyN2(u8 *dst, const u8 *src, s32 n) { CopyN(n, dst, src); }