diff --git a/asm/battle_tower.s b/asm/battle_tower.s index 6cee2dc0a..788061f2b 100644 --- a/asm/battle_tower.s +++ b/asm/battle_tower.s @@ -3746,7 +3746,7 @@ _08163FF4: ldr r0, [r6] ldr r1, =0x0000064c adds r0, r1 - bl sub_8164F70 + bl CalcEmeraldBattleTowerChecksum bl sub_8163E90 pop {r3,r4} mov r8, r3 @@ -5484,8 +5484,8 @@ _08164F52: .pool thumb_func_end sub_8164ED8 - thumb_func_start sub_8164F70 -sub_8164F70: @ 8164F70 + thumb_func_start CalcEmeraldBattleTowerChecksum +CalcEmeraldBattleTowerChecksum: @ 8164F70 push {r4,lr} adds r2, r0, 0 adds r2, 0xE8 @@ -5504,7 +5504,7 @@ _08164F7E: pop {r4} pop {r0} bx r0 - thumb_func_end sub_8164F70 + thumb_func_end CalcEmeraldBattleTowerChecksum thumb_func_start sub_8164F94 sub_8164F94: @ 8164F94 @@ -6750,7 +6750,7 @@ _08165988: ldr r1, [sp, 0x10] bl CpuSet adds r0, r5, 0 - bl sub_8164F70 + bl CalcEmeraldBattleTowerChecksum movs r0, 0x1 _081659BE: add sp, 0x14 diff --git a/asm/fldeff_80F9BCC.s b/asm/fldeff_80F9BCC.s index e31375f9f..8f1e198b8 100644 --- a/asm/fldeff_80F9BCC.s +++ b/asm/fldeff_80F9BCC.s @@ -2431,8 +2431,8 @@ sub_80FAFF8: @ 80FAFF8 .pool thumb_func_end sub_80FAFF8 - thumb_func_start sub_80FB00C -sub_80FB00C: @ 80FB00C + thumb_func_start CreateRecordMixingSprite +CreateRecordMixingSprite: @ 80FB00C push {r4,r5,lr} ldr r0, =gUnknown_0858E864 bl LoadSpritePalette @@ -2478,10 +2478,10 @@ _080FB06E: pop {r4,r5} pop {r1} bx r1 - thumb_func_end sub_80FB00C + thumb_func_end CreateRecordMixingSprite - thumb_func_start sub_80FB074 -sub_80FB074: @ 80FB074 + thumb_func_start DestroyRecordMixingSprite +DestroyRecordMixingSprite: @ 80FB074 push {r4-r7,lr} ldr r4, =gSprites adds r7, r4, 0 @@ -2509,6 +2509,6 @@ _080FB098: pop {r0} bx r0 .pool - thumb_func_end sub_80FB074 + thumb_func_end DestroyRecordMixingSprite .align 2, 0 @ Don't pad with nop. diff --git a/constants/item_data_constants.inc b/constants/item_data_constants.inc deleted file mode 100644 index f0badc467..000000000 --- a/constants/item_data_constants.inc +++ /dev/null @@ -1,5 +0,0 @@ - .set POCKET_ITEMS, 0x01 - .set POCKET_POKE_BALLS, 0x02 - .set POCKET_TM_HM, 0x03 - .set POCKET_BERRIES, 0x04 - .set BAG_KEYITEMS, 0x05 diff --git a/include/battle_tower.h b/include/battle_tower.h index 7bacf5249..9d4553132 100644 --- a/include/battle_tower.h +++ b/include/battle_tower.h @@ -1,7 +1,8 @@ #ifndef GUARD_BATTLE_TOWER_H #define GUARD_BATTLE_TOWER_H -struct RSBattleTowerRecord { +struct RSBattleTowerRecord +{ /*0x00*/ u8 battleTowerLevelType; // 0 = level 50, 1 = level 100 /*0x01*/ u8 trainerClass; /*0x02*/ u16 winStreak; @@ -15,30 +16,16 @@ struct RSBattleTowerRecord { /*0xA4*/ u16 unk_11c8; }; -struct EmeraldBattleTowerRecord { - /*0x00*/ u8 battleTowerLevelType; // 0 = level 50, 1 = level 100 - /*0x01*/ u8 trainerClass; - /*0x02*/ u16 winStreak; - /*0x04*/ u8 name[8]; - /*0x0C*/ u8 trainerId[4]; - /*0x10*/ struct { - u16 easyChat[6]; - } greeting; - /*0x1C*/ u8 filler_1c[0x18]; - /*0x34*/ struct UnknownPokemonStruct party[4]; - /*0xe4*/ u8 language; - u8 filler_e5[7]; -}; - -union BattleTowerRecord { +union BattleTowerRecord +{ struct RSBattleTowerRecord ruby_sapphire; struct EmeraldBattleTowerRecord emerald; }; u16 sub_8164FCC(u8, u8); -void sub_81659DC(union BattleTowerRecord *a0, union BattleTowerRecord *a1); +void sub_81659DC(struct RSBattleTowerRecord *a0, struct RSBattleTowerRecord *a1); bool32 sub_816587C(union BattleTowerRecord *, union BattleTowerRecord *); -bool32 sub_8164F70(union BattleTowerRecord *); +void CalcEmeraldBattleTowerChecksum(struct EmeraldBattleTowerRecord *); void sub_81628A0(union BattleTowerRecord *); #endif //GUARD_BATTLE_TOWER_H diff --git a/include/fldeff_80F9BCC.h b/include/fldeff_80F9BCC.h index 4169e328d..ba775cd6d 100644 --- a/include/fldeff_80F9BCC.h +++ b/include/fldeff_80F9BCC.h @@ -9,8 +9,8 @@ void sub_80FA5E4(s16 id, s16 x, s16 y); void sub_80FA794(s16 x, s16 y); -void sub_80FB00C(void); -void sub_80FB074(void); +void CreateRecordMixingSprite(void); +void DestroyRecordMixingSprite(void); void overworld_poison_effect(void); bool8 sub_80FADE4(u16, u8); diff --git a/include/global.h b/include/global.h index b869da813..f9e0aa66e 100644 --- a/include/global.h +++ b/include/global.h @@ -103,6 +103,8 @@ enum LanguageId #define VARS_COUNT 256 #define MAIL_COUNT 16 #define SECRET_BASES_COUNT 20 +#define TV_SHOWS_COUNT 25 +#define POKE_NEWS_COUNT 16 #define PC_ITEMS_COUNT 50 #define BAG_ITEMS_COUNT 30 #define BAG_KEYITEMS_COUNT 30 @@ -263,6 +265,49 @@ struct UnkRecordMixingStruct u8 field_38[10]; }; +struct UnknownPokemonStruct +{ + u16 species; + u16 heldItem; + u16 moves[4]; + u8 level; + u8 ppBonuses; + u8 hpEV; + u8 attackEV; + u8 defenseEV; + u8 speedEV; + u8 spAttackEV; + u8 spDefenseEV; + u32 otId; + u32 hpIV:5; + u32 attackIV:5; + u32 defenseIV:5; + u32 speedIV:5; + u32 spAttackIV:5; + u32 spDefenseIV:5; + u32 gap:1; + u32 altAbility:1; + u32 personality; + u8 nickname[POKEMON_NAME_LENGTH + 1]; + u8 friendship; +}; + +struct EmeraldBattleTowerRecord +{ + /*0x00*/ u8 battleTowerLevelType; // 0 = level 50, 1 = level 100 + /*0x01*/ u8 trainerClass; + /*0x02*/ u16 winStreak; + /*0x04*/ u8 name[8]; + /*0x0C*/ u8 trainerId[4]; + /*0x10*/ struct { + u16 easyChat[6]; + } greeting; + /*0x1C*/ u8 filler_1c[0x18]; + /*0x34*/ struct UnknownPokemonStruct party[4]; + /*0xE4*/ u8 language; + /*0xE8*/ u32 checksum; +}; + struct SaveBlock2 { /*0x00*/ u8 playerName[PLAYER_NAME_LENGTH]; @@ -302,7 +347,7 @@ struct SaveBlock2 // All below could be a one giant struct - /*0x64C*/ u8 field_64C[236]; + /*0x64C*/ struct EmeraldBattleTowerRecord battleTower; /*0x738*/ struct UnknownSaveBlock2Struct field_738[5]; // No idea here, it's probably wrong, no clue. /*0xBD4*/ u16 field_BD4; /*0xBD6*/ u16 field_BD6; @@ -763,8 +808,8 @@ struct SaveBlock1 /*0x????*/ u8 decorDoll[40]; /*0x????*/ u8 decorCushion[10]; /*0x27CA*/ u8 padding_27CA[2]; - /*0x27CC*/ TVShow tvShows[25]; - /*0x2B50*/ PokeNews pokeNews[16]; + /*0x27CC*/ TVShow tvShows[TV_SHOWS_COUNT]; + /*0x2B50*/ PokeNews pokeNews[POKE_NEWS_COUNT]; /*0x2B90*/ u16 outbreakPokemonSpecies; /*0x2B92*/ u8 outbreakLocationMapNum; /*0x2B93*/ u8 outbreakLocationMapGroup; diff --git a/include/mauville_old_man.h b/include/mauville_old_man.h index b1f10314a..e318ac8bb 100644 --- a/include/mauville_old_man.h +++ b/include/mauville_old_man.h @@ -19,8 +19,8 @@ void ScrSpecial_SetMauvilleOldManMapObjGfx(void); u8 sub_81201C8(void); void sub_8120B70(OldMan *dest); void sub_8120670(void); -void sub_8120D34(union OldMan * oldMan, u32 r1, u32 r6); -void sub_8120CD0(union OldMan * oldMan, u32 unused, u32 a2); +void SanitizeReceivedRubyOldMan(union OldMan * oldMan, u32 r1, u32 r6); +void SanitizeReceivedEmeraldOldMan(union OldMan * oldMan, u32 unused, u32 a2); void ResetMauvilleOldManFlag(void); #endif // GUARD_MAUVILLE_OLD_MAN_H diff --git a/include/mystery_event_script.h b/include/mystery_event_script.h index 0857c7188..991cab53a 100644 --- a/include/mystery_event_script.h +++ b/include/mystery_event_script.h @@ -6,6 +6,5 @@ bool32 sub_8153884(u32 *a0); u32 RunMysteryEventScript(u8 *script); void SetMysteryEventScriptStatus(u32 val); u16 GetRecordMixingGift(void); -u16 GetRecordMixingGift(void); #endif // GUARD_MYSTERY_EVENT_SCRIPT_H diff --git a/include/pokemon.h b/include/pokemon.h index b6b0d6d36..37028821a 100644 --- a/include/pokemon.h +++ b/include/pokemon.h @@ -240,33 +240,6 @@ struct PokemonStorage /*0x83C2*/ u8 boxWallpapers[14]; }; -struct UnknownPokemonStruct -{ - u16 species; - u16 heldItem; - u16 moves[4]; - u8 level; - u8 ppBonuses; - u8 hpEV; - u8 attackEV; - u8 defenseEV; - u8 speedEV; - u8 spAttackEV; - u8 spDefenseEV; - u32 otId; - u32 hpIV:5; - u32 attackIV:5; - u32 defenseIV:5; - u32 speedIV:5; - u32 spAttackIV:5; - u32 spDefenseIV:5; - u32 gap:1; - u32 altAbility:1; - u32 personality; - u8 nickname[POKEMON_NAME_LENGTH + 1]; - u8 friendship; -}; - struct UnknownPokemonSubStruct2 { u16 species; diff --git a/include/record_mixing.h b/include/record_mixing.h index 900951516..3cd4d649e 100644 --- a/include/record_mixing.h +++ b/include/record_mixing.h @@ -26,12 +26,10 @@ struct UnkRecordMixingStruct2 struct UnkRecordMixingStruct2b field_120[2]; }; - - // Exported RAM declarations // Exported ROM declarations - +void sub_80E6BE8(void); void sub_80E8260(struct UnkRecordMixingStruct2 *arg0); #endif //GUARD_RECORD_MIXING_H diff --git a/include/tv.h b/include/tv.h index 1b3423275..17be8c43c 100644 --- a/include/tv.h +++ b/include/tv.h @@ -16,7 +16,7 @@ void sub_80EED10(void); void sub_80EED34(void); void sub_80EED60(u16 delta); void sub_80F01B8(void); -void sub_80F01E8(void *src, u32 size, u8 masterIdx); +void ReceiveTvShowsData(void *src, u32 size, u8 masterIdx); void sub_80EE4DC(struct Pokemon *pokemon, u8 ribbonMonDataIdx); u32 GetPlayerIDAsU32(void); bool8 GetPriceReduction(u8 newsKind); @@ -30,7 +30,7 @@ void sub_80EEA70(void); void sub_80EDB44(void); void sub_80EDC60(const u16 *words); void sub_80EDA80(void); -void sub_80F0C7C(void *src, u32 size, u8 masterIdx); +void ReceivePokeNewsData(void *src, u32 size, u8 masterIdx); void sub_80F0BB8(void); void sub_80ED950(bool8 flag); void sub_80EEC80(void); diff --git a/src/daycare.c b/src/daycare.c index 17928324f..5a6aa2b40 100644 --- a/src/daycare.c +++ b/src/daycare.c @@ -47,7 +47,7 @@ extern void sub_81B9328(void); extern void CB2_ReturnToField(void); // this file's functions -static void ClearDaycareMonMisc(struct DaycareMiscMon *misc); +static void ClearDaycareMonMail(struct DayCareMail *mail); static void SetInitialEggData(struct Pokemon *mon, u16 species, struct DayCare *daycare); static u8 GetDaycareCompatibilityScore(struct DayCare *daycare); static void DaycarePrintMonInfo(u8 windowId, s32 daycareSlotId, u8 y); @@ -179,13 +179,13 @@ static void StorePokemonInDaycare(struct Pokemon *mon, struct DaycareMon *daycar { u8 mailId; - StringCopy(daycareMon->misc.OT_name, gSaveBlock2Ptr->playerName); - GetMonNick(mon, daycareMon->misc.monName); - StripExtCtrlCodes(daycareMon->misc.monName); - daycareMon->misc.gameLanguage = LANGUAGE_ENGLISH; - daycareMon->misc.monLanguage = GetMonData(mon, MON_DATA_LANGUAGE); + StringCopy(daycareMon->mail.OT_name, gSaveBlock2Ptr->playerName); + GetMonNick(mon, daycareMon->mail.monName); + StripExtCtrlCodes(daycareMon->mail.monName); + daycareMon->mail.gameLanguage = LANGUAGE_ENGLISH; + daycareMon->mail.monLanguage = GetMonData(mon, MON_DATA_LANGUAGE); mailId = GetMonData(mon, MON_DATA_MAIL); - daycareMon->misc.mail = gSaveBlock1Ptr->mail[mailId]; + daycareMon->mail.message = gSaveBlock1Ptr->mail[mailId]; TakeMailFromMon(mon); } @@ -219,10 +219,10 @@ static void ShiftDaycareSlots(struct DayCare *daycare) daycare->mons[0].mon = daycare->mons[1].mon; ZeroBoxMonData(&daycare->mons[1].mon); - daycare->mons[0].misc = daycare->mons[1].misc; + daycare->mons[0].mail = daycare->mons[1].mail; daycare->mons[0].steps = daycare->mons[1].steps; daycare->mons[1].steps = 0; - ClearDaycareMonMisc(&daycare->mons[1].misc); + ClearDaycareMonMail(&daycare->mons[1].mail); } } @@ -277,10 +277,10 @@ static u16 TakeSelectedPokemonFromDaycare(struct DaycareMon *daycareMon) } gPlayerParty[PARTY_SIZE - 1] = pokemon; - if (daycareMon->misc.mail.itemId) + if (daycareMon->mail.message.itemId) { - GiveMailToMon2(&gPlayerParty[PARTY_SIZE - 1], &daycareMon->misc.mail); - ClearDaycareMonMisc(&daycareMon->misc); + GiveMailToMon2(&gPlayerParty[PARTY_SIZE - 1], &daycareMon->mail.message); + ClearDaycareMonMail(&daycareMon->mail); } ZeroBoxMonData(&daycareMon->mon); @@ -364,23 +364,23 @@ u8 GetNumLevelsGainedFromDaycare(void) return 0; } -static void ClearDaycareMonMisc(struct DaycareMiscMon *misc) +static void ClearDaycareMonMail(struct DayCareMail *mail) { s32 i; for (i = 0; i < OT_NAME_LENGTH + 1; i++) - misc->OT_name[i] = 0; + mail->OT_name[i] = 0; for (i = 0; i < POKEMON_NAME_LENGTH + 1; i++) - misc->monName[i] = 0; + mail->monName[i] = 0; - ClearMailStruct(&misc->mail); + ClearMailStruct(&mail->message); } static void ClearDaycareMon(struct DaycareMon *daycareMon) { ZeroBoxMonData(&daycareMon->mon); daycareMon->steps = 0; - ClearDaycareMonMisc(&daycareMon->misc); + ClearDaycareMonMail(&daycareMon->mail); } static void ClearAllDaycareData(struct DayCare *daycare) diff --git a/src/dewford_trend.c b/src/dewford_trend.c index 3ceec6563..44b42c123 100644 --- a/src/dewford_trend.c +++ b/src/dewford_trend.c @@ -158,7 +158,7 @@ static void sub_8122804(struct EasyChatPair *s, u16 b, u8 c) } } -void sub_812287C(void *a, u32 b, u8 unused) +void ReceiveEasyChatPairsData(void *a, u32 b, u8 unused) { u16 i, j, r3, players; struct EasyChatPair *buffer1, *buffer2, *src, *dst, *foo_of_buffer2; diff --git a/src/mauville_old_man.c b/src/mauville_old_man.c index 70a934615..2ce8a271d 100644 --- a/src/mauville_old_man.c +++ b/src/mauville_old_man.c @@ -793,11 +793,11 @@ void sub_8120C0C(union OldMan * oldMan, u32 r8, u32 r7, u32 r3) } } -void sub_8120CD0(union OldMan * oldMan, u32 unused, u32 a2) +void SanitizeReceivedEmeraldOldMan(union OldMan * oldMan, u32 version, u32 language) { u8 sp00[8]; s32 i; - if (oldMan->common.id == MAUVILLE_MAN_STORYTELLER && a2 == LANGUAGE_JAPANESE) + if (oldMan->common.id == MAUVILLE_MAN_STORYTELLER && language == LANGUAGE_JAPANESE) { struct MauvilleManStoryteller * storyteller = &oldMan->storyteller; @@ -816,9 +816,10 @@ void sub_8120CD0(union OldMan * oldMan, u32 unused, u32 a2) } } -void sub_8120D34(union OldMan * oldMan, u32 r1, u32 r6) +void SanitizeReceivedRubyOldMan(union OldMan * oldMan, u32 version, u32 language) { - u32 r2 = (r1 == LANGUAGE_JAPANESE || r1 == LANGUAGE_ENGLISH) ? 1 : 0; + bool32 isRuby = (version == VERSION_SAPPHIRE || version == VERSION_RUBY); + switch (oldMan->common.id) { case MAUVILLE_MAN_TRADER: @@ -826,7 +827,7 @@ void sub_8120D34(union OldMan * oldMan, u32 r1, u32 r6) struct MauvilleOldManTrader * trader = &oldMan->trader; s32 i; - if (r2) + if (isRuby) { for (i = 0; i < 4; i++) { @@ -837,7 +838,7 @@ void sub_8120D34(union OldMan * oldMan, u32 r1, u32 r6) trader->language[i] = LANGUAGE_JAPANESE; } else - trader->language[i] = r6; + trader->language[i] = language; } } else @@ -858,12 +859,12 @@ void sub_8120D34(union OldMan * oldMan, u32 r1, u32 r6) struct MauvilleManStoryteller * storyteller = &oldMan->storyteller; s32 i; - if (r2) + if (isRuby) { for (i = 0; i < 4; i++) { if (storyteller->gameStatIDs[i] != 0) - storyteller->language[i] = r6; + storyteller->language[i] = language; } } } @@ -872,9 +873,9 @@ void sub_8120D34(union OldMan * oldMan, u32 r1, u32 r6) { struct MauvilleManBard * bard = &oldMan->bard; - if (r2) + if (isRuby) { - bard->language = r6; + bard->language = language; } } break; @@ -882,9 +883,9 @@ void sub_8120D34(union OldMan * oldMan, u32 r1, u32 r6) { struct MauvilleManHipster * hipster = &oldMan->hipster; - if (r2) + if (isRuby) { - hipster->language = r6; + hipster->language = language; } } break; @@ -892,9 +893,9 @@ void sub_8120D34(union OldMan * oldMan, u32 r1, u32 r6) { struct MauvilleManGiddy * giddy = &oldMan->giddy; - if (r2) + if (isRuby) { - giddy->language = r6; + giddy->language = language; } } break; diff --git a/src/record_mixing.c b/src/record_mixing.c index 9a47d4112..19a8b0889 100644 --- a/src/record_mixing.c +++ b/src/record_mixing.c @@ -34,13 +34,37 @@ #include "daycare.h" #include "international_string_util.h" +extern void ReceiveSecretBasesData(struct SecretBaseRecord *, size_t, u8); +extern void ReceiveEasyChatPairsData(struct EasyChatPair *, size_t, u8); + // Static type declarations +struct UnknownRecMixingStruct +{ + u32 field_0; + u16 field_4; + u8 field_6[9]; +}; + +struct UnknownRecMixingStruct2 +{ + u32 field_0; + u16 field_4; + u16 field_6; + u16 field_8; + u8 field_A[16]; +}; + +struct UnknownRecMixingStruct3 +{ + u8 field_0[0x810]; +}; + struct PlayerRecordsRS { - struct SecretBaseRecord secretBases[20]; - TVShow tvShows[25]; - PokeNews pokeNews[16]; + struct SecretBaseRecord secretBases[SECRET_BASES_COUNT]; + TVShow tvShows[TV_SHOWS_COUNT]; + PokeNews pokeNews[POKE_NEWS_COUNT]; OldMan oldMan; struct EasyChatPair easyChatPairs[5]; struct RecordMixingDayCareMail dayCareMail; @@ -48,71 +72,75 @@ struct PlayerRecordsRS u16 filler11C8[0x32]; }; -struct PlayerRecords +struct PlayerRecordsEmerald { - /* 0x0000 */ struct SecretBaseRecord secretBases[20]; - /* 0x0c80 */ TVShow tvShows[25]; - /* 0x1004 */ PokeNews pokeNews[16]; + /* 0x0000 */ struct SecretBaseRecord secretBases[SECRET_BASES_COUNT]; + /* 0x0c80 */ TVShow tvShows[TV_SHOWS_COUNT]; + /* 0x1004 */ PokeNews pokeNews[POKE_NEWS_COUNT]; /* 0x1044 */ OldMan oldMan; - /* 0x1084 */ struct EasyChatPair easyChatPair[5]; + /* 0x1084 */ struct EasyChatPair easyChatPairs[5]; /* 0x10ac */ struct RecordMixingDayCareMail dayCareMail; - /* 0x1124 */ union BattleTowerRecord battleTowerRecord; + /* 0x1124 */ struct EmeraldBattleTowerRecord battleTowerRecord; /* 0x1210 */ u16 unk_1210; /* 0x1214 */ LilycoveLady lilycoveLady; /* 0x1254 */ struct UnkRecordMixingStruct unk_1254[2]; /* 0x12dc */ struct UnkRecordMixingStruct2 unk_12dc; /* 0x1434 */ u8 field_1434[0x10]; -}; // 1444 +}; // 0x1444 + +union PlayerRecords +{ + struct PlayerRecordsRS ruby; + struct PlayerRecordsEmerald emerald; +}; // Static RAM declarations -IWRAM_DATA bool8 gUnknown_03001130; -IWRAM_DATA struct SecretBaseRecord *gUnknown_03001134; -IWRAM_DATA TVShow *gUnknown_03001138; -IWRAM_DATA PokeNews *gUnknown_0300113C; -IWRAM_DATA OldMan *gUnknown_03001140; -IWRAM_DATA struct EasyChatPair *gUnknown_03001144; -IWRAM_DATA struct RecordMixingDayCareMail *gUnknown_03001148; -IWRAM_DATA void *gUnknown_0300114C; // gSaveBlock2Ptr->field_64C -IWRAM_DATA LilycoveLady *gUnknown_03001150; -IWRAM_DATA void *gUnknown_03001154; // gSaveBlock2Ptr->field_0DC; -IWRAM_DATA void *gUnknown_03001158; // gSaveBlock2Ptr->field_64C -IWRAM_DATA u32 gUnknown_0300115C; -IWRAM_DATA u8 gUnknown_03001160; -IWRAM_DATA u32 filler_03001164; -IWRAM_DATA u32 gUnknown_03001168[3]; +static IWRAM_DATA bool8 gUnknown_03001130; +static IWRAM_DATA struct SecretBaseRecord *sSecretBasesSave; +static IWRAM_DATA TVShow *sTvShowsSave; +static IWRAM_DATA PokeNews *sPokeNewsSave; +static IWRAM_DATA OldMan *sOldManSave; +static IWRAM_DATA struct EasyChatPair *sEasyChatPairsSave; +static IWRAM_DATA struct RecordMixingDayCareMail *gUnknown_03001148; +static IWRAM_DATA void *sBattleTowerSave; +static IWRAM_DATA LilycoveLady *sLilycoveLadySave; +static IWRAM_DATA void *gUnknown_03001154; // gSaveBlock2Ptr->field_0DC; +static IWRAM_DATA void *sBattleTowerSave_Duplicate; +static IWRAM_DATA u32 sRecordStructSize; +static IWRAM_DATA u8 gUnknown_03001160; +static IWRAM_DATA u32 filler_03001164; +static IWRAM_DATA u32 gUnknown_03001168[3]; -EWRAM_DATA struct RecordMixingDayCareMail gUnknown_02039F9C = {}; -EWRAM_DATA struct PlayerRecords *gUnknown_0203A014 = NULL; -EWRAM_DATA struct PlayerRecords *gUnknown_0203A018 = NULL; +static EWRAM_DATA struct RecordMixingDayCareMail gUnknown_02039F9C = {0}; +static EWRAM_DATA union PlayerRecords *sReceivedRecords = NULL; +static EWRAM_DATA union PlayerRecords *sSentRecord = NULL; // Static ROM declarations -static void sub_80E715C(u8 taskId); +static void Task_RecordMixing_Main(u8 taskId); static void sub_80E7324(u8 taskId); -static void sub_80E756C(u8 taskId); -static void sub_80E7630(u8 taskId); -static void sub_80E77D4(u8 taskId); -static void *sub_80E77FC(const u16 *asShort); -static void sub_80E7808(void *records, u16 *a1); -static u8 sub_80E7810(void); -static void *sub_80E7820(u8); -static void sub_80E78C4(OldMan *, size_t, u8); -static void sub_80E7948(union BattleTowerRecord *, size_t, u8); -static void sub_80E7A14(LilycoveLady *, size_t, u8); +static void Task_SendPacket(u8 taskId); +static void Task_CopyReceiveBuffer(u8 taskId); +static void Task_SendPacket_SwitchToReceive(u8 taskId); +static void *LoadPtrFromTaskData(const u16 *asShort); +static void StorePtrInTaskData(void *records, u16 *a1); +static u8 GetMultiplayerId_(void); +static void *GetPlayerRecvBuffer(u8); +static void ReceiveOldManData(OldMan *, size_t, u8); +static void ReceiveBattleTowerData(void *battleTowerRecord, size_t, u8); +static void ReceiveLilycoveLadyData(LilycoveLady *, size_t, u8); static void sub_80E7B2C(const u8 *); -static void sub_80E7B60(struct RecordMixingDayCareMail *, size_t, u8, TVShow *); +static void ReceiveDaycareMailData(struct RecordMixingDayCareMail *, size_t, u8, TVShow *); static void sub_80E7F68(u16 *item, u8 which); static void sub_80E7FF8(u8 taskId); static void sub_80E8110(struct UnkRecordMixingStruct *arg0, struct UnkRecordMixingStruct *arg1); static void sub_80E8468(struct UnkRecordMixingStruct *arg0, size_t arg1, u32 arg2); static void sub_80E89AC(struct UnkRecordMixingStruct2 *arg0, size_t arg1, u32 arg2); static void sub_80E89F8(struct RecordMixingDayCareMail *dst); -static void sub_80E8A54(struct RecordMixingDayCareMail *src); -static void sub_80E8AC0(union BattleTowerRecord *); -void sub_80EAF80(struct SecretBaseRecord *, size_t, u8); -void sub_812287C(struct EasyChatPair *, size_t, u8); -static void nullsub_1405(union BattleTowerRecord *src); +static void SanitizeDayCareMailForRuby(struct RecordMixingDayCareMail *src); +static void SanitizeEmeraldBattleTowerRecord(struct EmeraldBattleTowerRecord *arg0); +static void SanitizeRubyBattleTowerRecord(struct RSBattleTowerRecord *src); // .rodata @@ -153,242 +181,244 @@ static const u8 gUnknown_0858CFBE[3][4] = // .text +#define BUFFER_CHUNK_SIZE 200 + void sub_80E6BE8(void) { - sub_80B37D4(sub_80E715C); + sub_80B37D4(Task_RecordMixing_Main); } -void sub_80E6BF8(void) +// these variables were const in R/S, but had to become changeable because of saveblocks changing RAM position +static void SetSrcLookupPointers(void) { - gUnknown_03001134 = gSaveBlock1Ptr->secretBases; - gUnknown_03001138 = gSaveBlock1Ptr->tvShows; - gUnknown_0300113C = gSaveBlock1Ptr->pokeNews; - gUnknown_03001140 = &gSaveBlock1Ptr->oldMan; - gUnknown_03001144 = gSaveBlock1Ptr->easyChatPairs; + sSecretBasesSave = gSaveBlock1Ptr->secretBases; + sTvShowsSave = gSaveBlock1Ptr->tvShows; + sPokeNewsSave = gSaveBlock1Ptr->pokeNews; + sOldManSave = &gSaveBlock1Ptr->oldMan; + sEasyChatPairsSave = gSaveBlock1Ptr->easyChatPairs; gUnknown_03001148 = &gUnknown_02039F9C; - gUnknown_0300114C = gSaveBlock2Ptr->field_64C; - gUnknown_03001150 = &gSaveBlock1Ptr->lilycoveLady; + sBattleTowerSave = &gSaveBlock2Ptr->battleTower; + sLilycoveLadySave = &gSaveBlock1Ptr->lilycoveLady; gUnknown_03001154 = gSaveBlock2Ptr->field_DC; - gUnknown_03001158 = gSaveBlock2Ptr->field_64C; + sBattleTowerSave_Duplicate = &gSaveBlock2Ptr->battleTower; } -void sub_80E6CA0(struct PlayerRecords *dest) +static void PrepareUnknownExchangePacket(struct PlayerRecordsRS *dest) { - memcpy(dest->secretBases, gUnknown_03001134, sizeof(struct SecretBaseRecord) * 20); - memcpy(dest->tvShows, gUnknown_03001138, sizeof(TVShow) * 25); + memcpy(dest->secretBases, sSecretBasesSave, sizeof(dest->secretBases)); + memcpy(dest->tvShows, sTvShowsSave, sizeof(dest->tvShows)); sub_80F14F8(dest->tvShows); - memcpy(dest->pokeNews, gUnknown_0300113C, sizeof(PokeNews) * 16); - memcpy(&dest->oldMan, gUnknown_03001140, sizeof(OldMan)); - memcpy(dest->easyChatPair, gUnknown_03001144, sizeof(struct EasyChatPair) * 5); + memcpy(dest->pokeNews, sPokeNewsSave, sizeof(dest->pokeNews)); + memcpy(&dest->oldMan, sOldManSave, sizeof(dest->oldMan)); + memcpy(dest->easyChatPairs, sEasyChatPairsSave, sizeof(dest->easyChatPairs)); sub_80E89F8(&dest->dayCareMail); - sub_81659DC(gUnknown_0300114C, &dest->battleTowerRecord); + sub_81659DC(sBattleTowerSave, &dest->battleTowerRecord); + if (GetMultiplayerId() == 0) - { - dest->battleTowerRecord.ruby_sapphire.unk_11c8 = GetRecordMixingGift(); - } + dest->battleTowerRecord.unk_11c8 = GetRecordMixingGift(); } -void sub_80E6D54(struct PlayerRecords *dest) +static void PrepareExchangePacketForRubySapphire(struct PlayerRecordsRS *dest) { - memcpy(dest->secretBases, gUnknown_03001134, sizeof(struct SecretBaseRecord) * 20); + memcpy(dest->secretBases, sSecretBasesSave, sizeof(dest->secretBases)); sub_80EB18C(dest->secretBases); - memcpy(dest->tvShows, gUnknown_03001138, sizeof(TVShow) * 25); + memcpy(dest->tvShows, sTvShowsSave, sizeof(dest->tvShows)); sub_80F1208(dest->tvShows); - memcpy(dest->pokeNews, gUnknown_0300113C, sizeof(PokeNews) * 16); - memcpy(&dest->oldMan, gUnknown_03001140, sizeof(OldMan)); + memcpy(dest->pokeNews, sPokeNewsSave, sizeof(dest->pokeNews)); + memcpy(&dest->oldMan, sOldManSave, sizeof(dest->oldMan)); sub_8120B70(&dest->oldMan); - memcpy(dest->easyChatPair, gUnknown_03001144, sizeof(struct EasyChatPair) * 5); + memcpy(dest->easyChatPairs, sEasyChatPairsSave, sizeof(dest->easyChatPairs)); sub_80E89F8(&dest->dayCareMail); - sub_80E8A54(&dest->dayCareMail); - sub_81659DC(gUnknown_0300114C, &dest->battleTowerRecord); - nullsub_1405(&dest->battleTowerRecord); + SanitizeDayCareMailForRuby(&dest->dayCareMail); + sub_81659DC(sBattleTowerSave, &dest->battleTowerRecord); + SanitizeRubyBattleTowerRecord(&dest->battleTowerRecord); + if (GetMultiplayerId() == 0) - { - dest->battleTowerRecord.ruby_sapphire.unk_11c8 = GetRecordMixingGift(); - } + dest->battleTowerRecord.unk_11c8 = GetRecordMixingGift(); } -void sub_80E6E24(void) +static void PrepareExchangePacket(void) { sub_80E9914(); sub_80F0BB8(); - sub_80E6BF8(); + SetSrcLookupPointers(); + if (Link_AnyPartnersPlayingRubyOrSapphire()) { - if (sub_800A03C() == FALSE) - { - sub_80E6CA0(gUnknown_0203A018); - } + if (sub_800A03C() == 0) + PrepareUnknownExchangePacket(&sSentRecord->ruby); else - { - sub_80E6D54(gUnknown_0203A018); - } + PrepareExchangePacketForRubySapphire(&sSentRecord->ruby); } else { - memcpy(gUnknown_0203A018->secretBases, gUnknown_03001134, sizeof(struct SecretBaseRecord) * 20); - memcpy(gUnknown_0203A018->tvShows, gUnknown_03001138, sizeof(TVShow) * 25); - memcpy(gUnknown_0203A018->pokeNews, gUnknown_0300113C, sizeof(PokeNews) * 16); - memcpy(&gUnknown_0203A018->oldMan, gUnknown_03001140, sizeof(OldMan)); - memcpy(&gUnknown_0203A018->lilycoveLady, gUnknown_03001150, sizeof(LilycoveLady)); - memcpy(gUnknown_0203A018->easyChatPair, gUnknown_03001144, sizeof(struct EasyChatPair) * 5); - sub_80E89F8(&gUnknown_0203A018->dayCareMail); - memcpy(&gUnknown_0203A018->battleTowerRecord, gUnknown_0300114C, 0xec); - sub_80E8AC0(&gUnknown_0203A018->battleTowerRecord); + memcpy(sSentRecord->emerald.secretBases, sSecretBasesSave, sizeof(sSentRecord->emerald.secretBases)); + memcpy(sSentRecord->emerald.tvShows, sTvShowsSave, sizeof(sSentRecord->emerald.tvShows)); + memcpy(sSentRecord->emerald.pokeNews, sPokeNewsSave, sizeof(sSentRecord->emerald.pokeNews)); + memcpy(&sSentRecord->emerald.oldMan, sOldManSave, sizeof(sSentRecord->emerald.oldMan)); + memcpy(&sSentRecord->emerald.lilycoveLady, sLilycoveLadySave, sizeof(sSentRecord->emerald.lilycoveLady)); + memcpy(sSentRecord->emerald.easyChatPairs, sEasyChatPairsSave, sizeof(sSentRecord->emerald.easyChatPairs)); + sub_80E89F8(&sSentRecord->emerald.dayCareMail); + memcpy(&sSentRecord->emerald.battleTowerRecord, sBattleTowerSave, sizeof(sSentRecord->emerald.battleTowerRecord)); + SanitizeEmeraldBattleTowerRecord(&sSentRecord->emerald.battleTowerRecord); + if (GetMultiplayerId() == 0) - { - gUnknown_0203A018->unk_1210 = GetRecordMixingGift(); - } - sub_80E8110(gUnknown_0203A018->unk_1254, gUnknown_03001154); - sub_80E8260(&gUnknown_0203A018->unk_12dc); + sSentRecord->emerald.unk_1210 = GetRecordMixingGift(); + + sub_80E8110(sSentRecord->emerald.unk_1254, gUnknown_03001154); + sub_80E8260(&sSentRecord->emerald.unk_12dc); } } -void sub_80E6F60(u32 which) +static void ReceiveExchangePacket(u32 which) { if (Link_AnyPartnersPlayingRubyOrSapphire()) { // Ruby/Sapphire - sub_80E7B2C((void *)gUnknown_0203A014[0].tvShows); - sub_80EAF80(gUnknown_0203A014[0].secretBases, sizeof(struct PlayerRecordsRS), which); - sub_80E7B60(&gUnknown_0203A014[0].dayCareMail, sizeof(struct PlayerRecordsRS), which, gUnknown_0203A014[0].tvShows); - sub_80E7948(&gUnknown_0203A014[0].battleTowerRecord, sizeof(struct PlayerRecordsRS), which); - sub_80F01E8(gUnknown_0203A014[0].tvShows, sizeof(struct PlayerRecordsRS), which); - sub_80F0C7C(gUnknown_0203A014[0].pokeNews, sizeof(struct PlayerRecordsRS), which); - sub_80E78C4(&gUnknown_0203A014[0].oldMan, sizeof(struct PlayerRecordsRS), which); - sub_812287C(gUnknown_0203A014[0].easyChatPair, sizeof(struct PlayerRecordsRS), which); - sub_80E7F68(&gUnknown_0203A014[0].battleTowerRecord.ruby_sapphire.unk_11c8, which); + sub_80E7B2C((void *)sReceivedRecords->ruby.tvShows); + ReceiveSecretBasesData(sReceivedRecords->ruby.secretBases, sizeof(struct PlayerRecordsRS), which); + ReceiveDaycareMailData(&sReceivedRecords->ruby.dayCareMail, sizeof(struct PlayerRecordsRS), which, sReceivedRecords->ruby.tvShows); + ReceiveBattleTowerData(&sReceivedRecords->ruby.battleTowerRecord, sizeof(struct PlayerRecordsRS), which); + ReceiveTvShowsData(sReceivedRecords->ruby.tvShows, sizeof(struct PlayerRecordsRS), which); + ReceivePokeNewsData(sReceivedRecords->ruby.pokeNews, sizeof(struct PlayerRecordsRS), which); + ReceiveOldManData(&sReceivedRecords->ruby.oldMan, sizeof(struct PlayerRecordsRS), which); + ReceiveEasyChatPairsData(sReceivedRecords->ruby.easyChatPairs, sizeof(struct PlayerRecordsRS), which); + sub_80E7F68(&sReceivedRecords->ruby.battleTowerRecord.unk_11c8, which); } else { // Emerald - sub_80E7B2C((void *)gUnknown_0203A014[0].tvShows); - sub_80EAF80(gUnknown_0203A014[0].secretBases, sizeof(struct PlayerRecords), which); - sub_80F01E8(gUnknown_0203A014[0].tvShows, sizeof(struct PlayerRecords), which); - sub_80F0C7C(gUnknown_0203A014[0].pokeNews, sizeof(struct PlayerRecords), which); - sub_80E78C4(&gUnknown_0203A014[0].oldMan, sizeof(struct PlayerRecords), which); - sub_812287C(gUnknown_0203A014[0].easyChatPair, sizeof(struct PlayerRecords), which); - sub_80E7B60(&gUnknown_0203A014[0].dayCareMail, sizeof(struct PlayerRecords), which, gUnknown_0203A014[0].tvShows); - sub_80E7948(&gUnknown_0203A014[0].battleTowerRecord, sizeof(struct PlayerRecords), which); - sub_80E7F68(&gUnknown_0203A014[0].unk_1210, which); - sub_80E7A14(&gUnknown_0203A014[0].lilycoveLady, sizeof(struct PlayerRecords), which); - sub_80E8468(gUnknown_0203A014[0].unk_1254, sizeof(struct PlayerRecords), (u8) which); - sub_80E89AC(&gUnknown_0203A014[0].unk_12dc, sizeof(struct PlayerRecords), (u8) which); + sub_80E7B2C((void *)sReceivedRecords->emerald.tvShows); + ReceiveSecretBasesData(sReceivedRecords->emerald.secretBases, sizeof(struct PlayerRecordsEmerald), which); + ReceiveTvShowsData(sReceivedRecords->emerald.tvShows, sizeof(struct PlayerRecordsEmerald), which); + ReceivePokeNewsData(sReceivedRecords->emerald.pokeNews, sizeof(struct PlayerRecordsEmerald), which); + ReceiveOldManData(&sReceivedRecords->emerald.oldMan, sizeof(struct PlayerRecordsEmerald), which); + ReceiveEasyChatPairsData(sReceivedRecords->emerald.easyChatPairs, sizeof(struct PlayerRecordsEmerald), which); + ReceiveDaycareMailData(&sReceivedRecords->emerald.dayCareMail, sizeof(struct PlayerRecordsEmerald), which, sReceivedRecords->emerald.tvShows); + ReceiveBattleTowerData(&sReceivedRecords->emerald.battleTowerRecord, sizeof(struct PlayerRecordsEmerald), which); + sub_80E7F68(&sReceivedRecords->emerald.unk_1210, which); + ReceiveLilycoveLadyData(&sReceivedRecords->emerald.lilycoveLady, sizeof(struct PlayerRecordsEmerald), which); + sub_80E8468(sReceivedRecords->emerald.unk_1254, sizeof(struct PlayerRecordsEmerald), (u8) which); + sub_80E89AC(&sReceivedRecords->emerald.unk_12dc, sizeof(struct PlayerRecordsEmerald), (u8) which); } } -void sub_80E70F4(const u8 *src) +static void PrintTextOnRecordMixing(const u8 *src) { NewMenuHelpers_DrawDialogueFrame(0, 0); PrintTextOnWindow(0, 1, src, 0, 1, 0, NULL); CopyWindowToVram(0, 3); } -void sub_80E7128(u8 taskId) +#define tCounter data[0] + +static void Task_RecordMixing_SoundEffect(u8 taskId) { - if (++ gTasks[taskId].data[0] == 50) + if (++gTasks[taskId].tCounter == 50) { PlaySE(SE_W213); - gTasks[taskId].data[0] = 0; + gTasks[taskId].tCounter = 0; } } -static void sub_80E715C(u8 taskId) +#undef tCounter + +#define tState data[0] +#define tSndEffTaskId data[15] + +static void Task_RecordMixing_Main(u8 taskId) { - s16 *data; + s16 *data = gTasks[taskId].data; - data = gTasks[taskId].data; - switch (data[0]) + switch (tState) { - case 0: - gUnknown_0203A018 = malloc(sizeof(struct PlayerRecords)); - gUnknown_0203A014 = malloc(sizeof(struct PlayerRecords) * 4); - sub_8009628(gSpecialVar_0x8005); - VarSet(VAR_TEMP_0, 1); - gUnknown_03001130 = FALSE; - sub_80E6E24(); - sub_80FB00C(); - data[0] = 1; - data[10] = CreateTask(sub_80E7324, 80); - data[15] = CreateTask(sub_80E7128, 81); - break; - case 1: - if (!gTasks[data[10]].isActive) + case 0: // init + sSentRecord = malloc(sizeof(union PlayerRecords)); + sReceivedRecords = malloc(sizeof(union PlayerRecords) * 4); + sub_8009628(gSpecialVar_0x8005); + VarSet(VAR_TEMP_0, 1); + gUnknown_03001130 = FALSE; + PrepareExchangePacket(); + CreateRecordMixingSprite(); + tState = 1; + data[10] = CreateTask(sub_80E7324, 80); + tSndEffTaskId = CreateTask(Task_RecordMixing_SoundEffect, 81); + break; + case 1: // wait for sub_80E7324 + if (!gTasks[data[10]].isActive) + { + tState = 2; + FlagSet(FLAG_SYS_MIX_RECORD); + DestroyRecordMixingSprite(); + DestroyTask(tSndEffTaskId); + } + break; + case 2: + data[10] = CreateTask(sub_80E7FF8, 10); + tState = 3; + PlaySE(SE_W226); + break; + case 3: // wait for sub_80E7FF8 + if (!gTasks[data[10]].isActive) + { + tState = 4; + if (gWirelessCommType == 0) + data[10] = sub_80B3050(); + + PrintTextOnRecordMixing(gText_RecordMixingComplete); + data[8] = 0; + } + break; + case 4: // wait 60 frames + if (++data[8] > 60) + tState = 5; + break; + case 5: + if (!gTasks[data[10]].isActive) + { + free(sReceivedRecords); + free(sSentRecord); + sub_808729C(); + if (gWirelessCommType != 0) { - data[0] = 2; - FlagSet(FLAG_SYS_MIX_RECORD); - sub_80FB074(); - DestroyTask(data[15]); + CreateTask(sub_80AF2B4, 10); } - break; - case 2: - data[10] = CreateTask(sub_80E7FF8, 10); - data[0] = 3; - PlaySE(SE_W226); - break; - case 3: - if (!gTasks[data[10]].isActive) - { - data[0] = 4; - if (gWirelessCommType == 0) - { - data[10] = sub_80B3050(); - } - sub_80E70F4(gText_RecordMixingComplete); - data[8] = 0; - } - break; - case 4: - if (++ data[8] > 60) - { - data[0] = 5; - } - break; - case 5: - if (!gTasks[data[10]].isActive) - { - free(gUnknown_0203A014); - free(gUnknown_0203A018); - sub_808729C(); - if (gWirelessCommType != 0) - { - CreateTask(sub_80AF2B4, 10); - } - sub_8197434(0, 1); - DestroyTask(taskId); - EnableBothScriptContexts(); - } - break; + sub_8197434(0, 1); + DestroyTask(taskId); + EnableBothScriptContexts(); + } + break; } } +#undef tState +#undef tSndEffTaskId + static void sub_80E7324(u8 taskId) { - u8 r4; - u8 taskId2; - struct Task *task; + struct Task *task = &gTasks[taskId]; - task = &gTasks[taskId]; switch (task->data[0]) { - case 0: - sub_80E70F4(gText_MixingRecords); - task->data[8] = 0x708; - task->data[0] = 400; - ClearLinkCallback_2(); - break; - case 100: - if (++ task->data[12] > 20) - { - task->data[12] = 0; - task->data[0] = 101; - } - break; - case 101: - r4 = GetLinkPlayerCount_2(); + case 0: + PrintTextOnRecordMixing(gText_MixingRecords); + task->data[8] = 0x708; + task->data[0] = 400; + ClearLinkCallback_2(); + break; + case 100: // wait 20 frames + if (++task->data[12] > 20) + { + task->data[12] = 0; + task->data[0] = 101; + } + break; + case 101: + { + u8 players = GetLinkPlayerCount_2(); if (IsLinkMaster() == TRUE) { - if (r4 == sub_800AA48()) + if (players == sub_800AA48()) { PlaySE(SE_PIN); task->data[0] = 201; @@ -400,272 +430,248 @@ static void sub_80E7324(u8 taskId) PlaySE(SE_BOO); task->data[0] = 301; } - break; - case 201: - if (sub_800AA48() == GetLinkPlayerCount_2() && ++ task->data[12] > (GetLinkPlayerCount_2() * 30)) - { - sub_800A620(); - task->data[0] = 1; - } - break; - case 301: - if (sub_800AA48() == GetLinkPlayerCount_2()) - { - task->data[0] = 1; - } - break; - case 400: - if (++ task->data[12] > 20) - { - task->data[0] = 1; - task->data[12] = 0; - } - break; - case 1: - if (gReceivedRemoteLinkPlayers != 0) - { - ConvertIntToDecimalStringN(gStringVar1, sub_80E7810(), STR_CONV_MODE_LEADING_ZEROS, 2); - task->data[0] = 5; - } - break; - case 2: + } + break; + case 201: + if (sub_800AA48() == GetLinkPlayerCount_2() && ++task->data[12] > (GetLinkPlayerCount_2() * 30)) + { + sub_800A620(); + task->data[0] = 1; + } + break; + case 301: + if (sub_800AA48() == GetLinkPlayerCount_2()) + task->data[0] = 1; + break; + case 400: // wait 20 frames + if (++task->data[12] > 20) + { + task->data[0] = 1; + task->data[12] = 0; + } + break; + case 1: // wait for handshake + if (gReceivedRemoteLinkPlayers != 0) + { + ConvertIntToDecimalStringN(gStringVar1, GetMultiplayerId_(), STR_CONV_MODE_LEADING_ZEROS, 2); + task->data[0] = 5; + } + break; + case 2: + { + u8 subTaskId; + task->data[6] = GetLinkPlayerCount_2(); task->data[0] = 0; - task->data[5] = sub_80E7810(); - task->func = sub_80E756C; + task->data[5] = GetMultiplayerId_(); + task->func = Task_SendPacket; if (Link_AnyPartnersPlayingRubyOrSapphire()) { - sub_80E7808(gUnknown_0203A018, (u16 *)&task->data[2]); - taskId2 = CreateTask(sub_80E7630, 80); - task->data[10] = taskId2; - gTasks[taskId2].data[0] = taskId; - sub_80E7808(gUnknown_0203A014, (u16 *)&gTasks[taskId2].data[5]); - gUnknown_0300115C = sizeof(struct PlayerRecordsRS); + StorePtrInTaskData(sSentRecord, (u16 *)&task->data[2]); + subTaskId = CreateTask(Task_CopyReceiveBuffer, 80); + task->data[10] = subTaskId; + gTasks[subTaskId].data[0] = taskId; + StorePtrInTaskData(sReceivedRecords, (u16 *)&gTasks[subTaskId].data[5]); + sRecordStructSize = sizeof(struct PlayerRecordsRS); } else { - sub_80E7808(gUnknown_0203A018, (u16 *)&task->data[2]); - taskId2 = CreateTask(sub_80E7630, 80); - task->data[10] = taskId2; - gTasks[taskId2].data[0] = taskId; - sub_80E7808(gUnknown_0203A014, (u16 *)&gTasks[taskId2].data[5]); - gUnknown_0300115C = sizeof(struct PlayerRecords); - } - break; - case 5: - if (++ task->data[10] > 60) - { - task->data[10] = 0; - task->data[0] = 2; - } - break; - } -} - -static void sub_80E756C(u8 taskId) -{ - struct Task *task; - void *dest; - - task = &gTasks[taskId]; - switch (task->data[0]) - { - case 0: - dest = sub_80E77FC(&task->data[2]) + task->data[4] * 200; - memcpy(gBlockSendBuffer, dest, 200); - task->data[0] ++; - break; - case 1: - if (GetMultiplayerId() == 0) - { - sub_800A4D8(1); - } - task->data[0] ++; - break; - case 2: - break; - case 3: - task->data[4] ++; - if (task->data[4] == gUnknown_0300115C / 200 + 1) - { - task->data[0] ++; - } - else - { - task->data[0] = 0; - } - break; - case 4: - if (!gTasks[task->data[10]].isActive) - { - task->func = sub_80E77D4; - } - break; - } -} - -static void sub_80E7630(u8 taskId) -{ - struct Task *task; - u8 status; - u8 counter; - u8 i; - void *dest; - void *src; - - task = &gTasks[taskId]; - status = GetBlockReceivedStatus(); - counter = 0; - if (status == sub_800A9D8()) - { - for (i = 0; i < GetLinkPlayerCount(); i ++) - { - if ((status >> i) & 0x01) - { - dest = sub_80E77FC((u16 *)&task->data[5]) + task->data[i + 1] * 200 + gUnknown_0300115C * i; - src = sub_80E7820(i); - if ((task->data[i + 1] + 1) * 200 > gUnknown_0300115C) - { - memcpy(dest, src, gUnknown_0300115C - task->data[i + 1] * 200); - } - else - { - memcpy(dest, src, 200); - } - ResetBlockReceivedFlag(i); - task->data[i + 1] ++; - if (task->data[i + 1] == gUnknown_0300115C / 200 + 1) - { - counter ++; - } + StorePtrInTaskData(sSentRecord, (u16 *)&task->data[2]); + subTaskId = CreateTask(Task_CopyReceiveBuffer, 80); + task->data[10] = subTaskId; + gTasks[subTaskId].data[0] = taskId; + StorePtrInTaskData(sReceivedRecords, (u16 *)&gTasks[subTaskId].data[5]); + sRecordStructSize = sizeof(struct PlayerRecordsEmerald); } } - gTasks[task->data[0]].data[0] ++; + break; + case 5: // wait 60 frames + if (++task->data[10] > 60) + { + task->data[10] = 0; + task->data[0] = 2; + } + break; } - if (counter == GetLinkPlayerCount()) +} + +static void Task_SendPacket(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + // does this send the data 24 times? + + switch (task->data[0]) { - DestroyTask(taskId); + case 0: // Copy record data to send buffer + { + void *recordData = LoadPtrFromTaskData(&task->data[2]) + task->data[4] * BUFFER_CHUNK_SIZE; + + memcpy(gBlockSendBuffer, recordData, BUFFER_CHUNK_SIZE); + task->data[0]++; + } + break; + case 1: + if (GetMultiplayerId() == 0) + sub_800A4D8(1); + task->data[0]++; + break; + case 2: + break; + case 3: + task->data[4]++; + if (task->data[4] == sRecordStructSize / 200 + 1) + task->data[0]++; + else + task->data[0] = 0; + break; + case 4: + if (!gTasks[task->data[10]].isActive) + task->func = Task_SendPacket_SwitchToReceive; + break; } } +static void Task_CopyReceiveBuffer(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + u8 status = GetBlockReceivedStatus(); + u8 handledPlayers = 0; + + if (status == sub_800A9D8()) + { + u8 i; + + for (i = 0; i < GetLinkPlayerCount(); i++) + { + void *dest; + void *src; + + if ((status >> i) & 1) + { + dest = LoadPtrFromTaskData((u16 *)&task->data[5]) + task->data[i + 1] * BUFFER_CHUNK_SIZE + sRecordStructSize * i; + src = GetPlayerRecvBuffer(i); + if ((task->data[i + 1] + 1) * BUFFER_CHUNK_SIZE > sRecordStructSize) + memcpy(dest, src, sRecordStructSize - task->data[i + 1] * BUFFER_CHUNK_SIZE); + else + memcpy(dest, src, BUFFER_CHUNK_SIZE); + ResetBlockReceivedFlag(i); + task->data[i + 1]++; + if (task->data[i + 1] == sRecordStructSize / BUFFER_CHUNK_SIZE + 1) + handledPlayers++; + } + } + gTasks[task->data[0]].data[0]++; + } + + if (handledPlayers == GetLinkPlayerCount()) + DestroyTask(taskId); +} + static void sub_80E776C(u8 taskId) { - struct Task *task; + struct Task *task = &gTasks[taskId]; - task = &gTasks[taskId]; if (!gTasks[task->data[10]].isActive) - { DestroyTask(taskId); - } } -static void sub_80E77A0(u8 taskId) +static void Task_ReceivePacket(u8 taskId) { - struct Task *task; + struct Task *task = &gTasks[taskId]; - task = &gTasks[taskId]; task->func = sub_80E776C; if (gUnknown_03001130 == TRUE) - { - sub_80E6F60(task->data[5]); - } + ReceiveExchangePacket(task->data[5]); } -static void sub_80E77D4(u8 taskId) +static void Task_SendPacket_SwitchToReceive(u8 taskId) { - gTasks[taskId].func = sub_80E77A0; + gTasks[taskId].func = Task_ReceivePacket; gUnknown_03001130 = TRUE; } -static void *sub_80E77FC(const u16 *asShort) +static void *LoadPtrFromTaskData(const u16 *asShort) { return (void *)(asShort[0] | (asShort[1] << 16)); } -static void sub_80E7808(void *records, u16 *asShort) +static void StorePtrInTaskData(void *records, u16 *asShort) { asShort[0] = (u32)records; asShort[1] = ((u32)records >> 16); } -static u8 sub_80E7810(void) +static u8 GetMultiplayerId_(void) { return GetMultiplayerId(); } -static void *sub_80E7820(u8 id) +static void *GetPlayerRecvBuffer(u8 id) { return gBlockRecvBuffer[id]; } -void sub_80E7830(u32 *data) +static void ShufflePlayerIndices(u32 *data) { u32 i; u32 linkTrainerId; + u32 players = GetLinkPlayerCount(); - switch ((u32)GetLinkPlayerCount()) + switch (players) { - case 2: - for (i = 0; i < 2; i ++) - { - data[i] = gUnknown_0858CF8C[i]; - } - break; - case 3: - linkTrainerId = GetLinkPlayerTrainerId(0) % 2; - for (i = 0; i < 3; i ++) - { - data[i] = gUnknown_0858CF8E[linkTrainerId][i]; - } - break; - case 4: - linkTrainerId = GetLinkPlayerTrainerId(0) % 9; - for (i = 0; i < 4; i ++) - { - data[i] = gUnknown_0858CF94[linkTrainerId][i]; - } - break; + case 2: + for (i = 0; i < 2; i++) + data[i] = gUnknown_0858CF8C[i]; + break; + case 3: + linkTrainerId = GetLinkPlayerTrainerId(0) % 2; + for (i = 0; i < 3; i++) + data[i] = gUnknown_0858CF8E[linkTrainerId][i]; + break; + case 4: + linkTrainerId = GetLinkPlayerTrainerId(0) % 9; + for (i = 0; i < 4; i++) + data[i] = gUnknown_0858CF94[linkTrainerId][i]; + break; } } -static void sub_80E78C4(OldMan *oldMan, size_t recordSize, u8 which) +static void ReceiveOldManData(OldMan *oldMan, size_t recordSize, u8 which) { u8 version; u16 language; OldMan *dest; u32 mixIndices[4]; - sub_80E7830(mixIndices); + ShufflePlayerIndices(mixIndices); dest = (void *)oldMan + recordSize * mixIndices[which]; version = gLinkPlayers[mixIndices[which]].version; language = gLinkPlayers[mixIndices[which]].language; + if (Link_AnyPartnersPlayingRubyOrSapphire()) - { - sub_8120D34(dest, version, language); - } + SanitizeReceivedRubyOldMan(dest, version, language); else - { - sub_8120CD0(dest, version, language); - } - memcpy(gUnknown_03001140, (void *)oldMan + recordSize * mixIndices[which], sizeof(OldMan)); + SanitizeReceivedEmeraldOldMan(dest, version, language); + + memcpy(sOldManSave, (void *)oldMan + recordSize * mixIndices[which], sizeof(OldMan)); ResetMauvilleOldManFlag(); } -static void sub_80E7948(union BattleTowerRecord *battleTowerRecord, size_t recordSize, u8 which) +static void ReceiveBattleTowerData(void *battleTowerRecord, size_t recordSize, u8 which) { - union BattleTowerRecord *dest; + struct EmeraldBattleTowerRecord *dest; struct UnknownPokemonStruct *btPokemon; u32 mixIndices[4]; s32 i; - sub_80E7830(mixIndices); + ShufflePlayerIndices(mixIndices); if (Link_AnyPartnersPlayingRubyOrSapphire()) { if (sub_816587C((void *)battleTowerRecord + recordSize * mixIndices[which], (void *)battleTowerRecord + recordSize * which) == TRUE) { dest = (void *)battleTowerRecord + recordSize * which; - dest->emerald.language = gLinkPlayers[mixIndices[which]].language; - sub_8164F70(dest); + dest->language = gLinkPlayers[mixIndices[which]].language; + CalcEmeraldBattleTowerChecksum(dest); } } else @@ -674,38 +680,37 @@ static void sub_80E7948(union BattleTowerRecord *battleTowerRecord, size_t recor dest = (void *)battleTowerRecord + recordSize * which; for (i = 0; i < 4; i ++) { - btPokemon = &dest->emerald.party[i]; + btPokemon = &dest->party[i]; if (btPokemon->species != SPECIES_NONE && IsStringJapanese(btPokemon->nickname)) - { ConvertInternationalString(btPokemon->nickname, LANGUAGE_JAPANESE); - } } - sub_8164F70(dest); + CalcEmeraldBattleTowerChecksum(dest); } sub_81628A0((void *)battleTowerRecord + recordSize * which); } -static void sub_80E7A14(LilycoveLady *lilycoveLady, size_t recordSize, u8 which) +static void ReceiveLilycoveLadyData(LilycoveLady *lilycoveLady, size_t recordSize, u8 which) { LilycoveLady *dest; u32 mixIndices[4]; - sub_80E7830(mixIndices); - memcpy((void *)lilycoveLady + recordSize * which, gUnknown_03001150, sizeof(LilycoveLady)); + ShufflePlayerIndices(mixIndices); + memcpy((void *)lilycoveLady + recordSize * which, sLilycoveLadySave, sizeof(LilycoveLady)); + if (GetLilycoveLadyId() == 0) { dest = malloc(sizeof(LilycoveLady)); if (dest == NULL) - { return; - } - memcpy(dest, gUnknown_03001150, sizeof(LilycoveLady)); + + memcpy(dest, sLilycoveLadySave, sizeof(LilycoveLady)); } else { dest = NULL; } - memcpy(gUnknown_03001150, (void *)lilycoveLady + recordSize * mixIndices[which], sizeof(LilycoveLady)); + + memcpy(sLilycoveLadySave, (void *)lilycoveLady + recordSize * mixIndices[which], sizeof(LilycoveLady)); sub_818DA78(); if (dest != NULL) { @@ -735,13 +740,12 @@ static void sub_80E7AA4(struct RecordMixingDayCareMail *src, size_t recordSize, static void sub_80E7B2C(const u8 *src) { u8 sum; - int i; + s32 i; sum = 0; for (i = 0; i < 256; i ++) - { sum += src[i]; - } + gUnknown_03001160 = sum; } @@ -751,7 +755,7 @@ static u8 sub_80E7B54(void) } #ifdef NONMATCHING -static void sub_80E7B60(struct RecordMixingDayCareMail *src, size_t recordSize, u8 which, TVShow *shows) +static void ReceiveDaycareMailData(struct RecordMixingDayCareMail *src, size_t recordSize, u8 which, TVShow *shows) { // r9 = which u16 i; @@ -929,7 +933,8 @@ static void sub_80E7B60(struct RecordMixingDayCareMail *src, size_t recordSize, SeedRng(oldSeed); } #else -__attribute__((naked)) static void sub_80E7B60(struct RecordMixingDayCareMail *src, size_t recordSize, u8 which, TVShow *shows) +NAKED +static void ReceiveDaycareMailData(struct RecordMixingDayCareMail *src, size_t recordSize, u8 which, TVShow *shows) { asm_unified("\tpush {r4-r7,lr}\n" "\tmov r7, r10\n" @@ -1464,9 +1469,7 @@ static void sub_80E7F68(u16 *item, u8 which) VarSet(VAR_TEMP_1, *item); StringCopy(gStringVar1, gLinkPlayers[0].name); if (*item == ITEM_EON_TICKET) - { FlagSet(FLAG_SYS_HAS_EON_TICKET); - } } else { @@ -1477,84 +1480,77 @@ static void sub_80E7F68(u16 *item, u8 which) static void sub_80E7FF8(u8 taskId) { - struct Task *task; + struct Task *task = &gTasks[taskId]; - task = &gTasks[taskId]; switch (task->data[0]) { - case 0: + case 0: + task->data[0]++; + break; + case 1: + if (Link_AnyPartnersPlayingRubyOrSapphire()) + task->data[0]++; + else + task->data[0] = 6; + break; + case 2: + sub_8076D5C(); + sub_8153430(); + task->data[0] ++; + break; + case 3: + if (sub_8153474()) + { + sav2_gender2_inplace_and_xFE(); + task->data[0] = 4; + task->data[1] = 0; + } + break; + case 4: + if (++task->data[1] > 10) + { + sub_800AC34(); task->data[0] ++; - break; - case 1: - if (Link_AnyPartnersPlayingRubyOrSapphire()) + } + break; + case 5: + if (gReceivedRemoteLinkPlayers == 0) + DestroyTask(taskId); + break; + case 6: + if (!sub_801048C(0)) + { + CreateTask(sub_8153688, 5); + task->data[0] ++; + } + break; + case 7: + if (!FuncIsActiveTask(sub_8153688)) + { + if (gWirelessCommType) { - task->data[0] ++; + sub_801048C(1); + task->data[0] = 8; } else { - task->data[0] = 6; - } - break; - case 2: - sub_8076D5C(); - sub_8153430(); - task->data[0] ++; - break; - case 3: - if (sub_8153474()) - { - sav2_gender2_inplace_and_xFE(); task->data[0] = 4; - task->data[1] = 0; } - break; - case 4: - if (++ task->data[1] > 10) - { - sub_800AC34(); - task->data[0] ++; - } - break; - case 5: - if (gReceivedRemoteLinkPlayers == 0) - { - DestroyTask(taskId); - } - break; - case 6: - if (!sub_801048C(0)) - { - CreateTask(sub_8153688, 5); - task->data[0] ++; - } - break; - case 7: - if (!FuncIsActiveTask(sub_8153688)) - { - if (gWirelessCommType) - { - sub_801048C(1); - task->data[0] = 8; - } - else - { - task->data[0] = 4; - } - } - break; - case 8: - sub_800ADF8(); - task->data[0] ++; - break; - case 9: - if (sub_800A520()) - { - DestroyTask(taskId); - } - break; + } + break; + case 8: + sub_800ADF8(); + task->data[0] ++; + break; + case 9: + if (sub_800A520()) + DestroyTask(taskId); + break; } } +// New Emerald functions + static void sub_80E8110(struct UnkRecordMixingStruct *dst, struct UnkRecordMixingStruct *src) { s32 i, id; @@ -1650,7 +1646,7 @@ void sub_80E8260(struct UnkRecordMixingStruct2 *dst) } } -bool32 sub_80E841C(struct UnkRecordMixingStruct *arg0, struct UnkRecordMixingStruct *arg1) +static bool32 sub_80E841C(struct UnkRecordMixingStruct *arg0, struct UnkRecordMixingStruct *arg1) { s32 i; @@ -1670,11 +1666,11 @@ static void sub_80E8468(struct UnkRecordMixingStruct *arg0, size_t arg1, u32 arg { s32 i, r7, r8; struct UnkRecordMixingStruct *structPtr; - u32 data[4]; + u32 mixIndices[4]; u32 structId; - sub_80E7830(data); - structPtr = (void*)(arg0) + (arg1 * data[arg2]); + ShufflePlayerIndices(mixIndices); + structPtr = (void*)(arg0) + (arg1 * mixIndices[arg2]); r7 = 0; r8 = 0; for (i = 0; i < 2; i++) @@ -1704,29 +1700,8 @@ static void sub_80E8468(struct UnkRecordMixingStruct *arg0, size_t arg1, u32 arg } } -struct UnknownRecMixingStruct -{ - u32 field_0; - u16 field_4; - u8 field_6[9]; -}; - -struct UnknownRecMixingStruct2 -{ - u32 field_0; - u16 field_4; - u16 field_6; - u16 field_8; - u8 field_A[16]; -}; - -struct UnknownRecMixingStruct3 -{ - u8 field_0[0x810]; -}; - NAKED -void sub_80E8578(struct UnknownRecMixingStruct3 *arg0, struct UnkRecordMixingStruct2 *arg1, size_t arg2, u32 arg3, u32 arg4) +static void sub_80E8578(struct UnknownRecMixingStruct3 *arg0, struct UnkRecordMixingStruct2 *arg1, size_t arg2, u32 arg3, u32 arg4) { asm_unified(" push {r4-r7,lr}\n\ mov r7, r10\n\ @@ -2130,7 +2105,7 @@ _080E8864:\n\ "); } -void sub_80E8880(struct UnknownRecMixingStruct *arg0, struct UnknownRecMixingStruct *arg1) +static void sub_80E8880(struct UnknownRecMixingStruct *arg0, struct UnknownRecMixingStruct *arg1) { s32 i, j; @@ -2155,7 +2130,7 @@ void sub_80E8880(struct UnknownRecMixingStruct *arg0, struct UnknownRecMixingStr } } -void sub_80E88CC(struct UnknownRecMixingStruct2 *arg0, struct UnknownRecMixingStruct2 *arg1) +static void sub_80E88CC(struct UnknownRecMixingStruct2 *arg0, struct UnknownRecMixingStruct2 *arg1) { s32 i, j; @@ -2181,7 +2156,7 @@ void sub_80E88CC(struct UnknownRecMixingStruct2 *arg0, struct UnknownRecMixingSt } NAKED -void sub_80E8924(struct UnknownRecMixingStruct3 *arg0) +static void sub_80E8924(struct UnknownRecMixingStruct3 *arg0) { asm_unified("push {r4-r7,lr}\n\ mov r7, r10\n\ @@ -2270,7 +2245,7 @@ static void sub_80E89F8(struct RecordMixingDayCareMail *dst) *dst = *gUnknown_03001148; } -static void sub_80E8A54(struct RecordMixingDayCareMail *src) +static void SanitizeDayCareMailForRuby(struct RecordMixingDayCareMail *src) { s32 i; @@ -2287,21 +2262,21 @@ static void sub_80E8A54(struct RecordMixingDayCareMail *src) } } -static void nullsub_1405(union BattleTowerRecord *src) +static void SanitizeRubyBattleTowerRecord(struct RSBattleTowerRecord *src) { } -static void sub_80E8AC0(union BattleTowerRecord *arg0) +static void SanitizeEmeraldBattleTowerRecord(struct EmeraldBattleTowerRecord *dst) { s32 i; for (i = 0; i < 4; i++) { - struct UnknownPokemonStruct *towerMon = &arg0->emerald.party[i]; + struct UnknownPokemonStruct *towerMon = &dst->party[i]; if (towerMon->species != 0) StripExtCtrlCodes(towerMon->nickname); } - sub_8164F70(arg0); + CalcEmeraldBattleTowerChecksum(dst); } diff --git a/src/secret_base.c b/src/secret_base.c index d86b99345..44e980c43 100644 --- a/src/secret_base.c +++ b/src/secret_base.c @@ -1673,7 +1673,7 @@ void sub_80EAEF4(struct SecretBaseRecordMixer *mixers) sub_80EABA4(&mixers[2], 0); } -void sub_80EAF80(void *records, size_t recordSize, u8 linkIdx) +void ReceiveSecretBasesData(void *records, size_t recordSize, u8 linkIdx) { struct SecretBaseRecordMixer mixers[3]; u16 i; diff --git a/src/tv.c b/src/tv.c index 77b7d4a75..e69f6f411 100644 --- a/src/tv.c +++ b/src/tv.c @@ -3606,7 +3606,7 @@ void sub_80F01B8(void) FlagSet(0x396); } -void sub_80F01E8(void *src, u32 size, u8 masterIdx) +void ReceiveTvShowsData(void *src, u32 size, u8 masterIdx) { u8 i; u16 version; @@ -4434,7 +4434,7 @@ static void sub_80F0C04(void) } } -void sub_80F0C7C(void *src, u32 size, u8 masterIdx) +void ReceivePokeNewsData(void *src, u32 size, u8 masterIdx) { u8 i; PokeNews (*rmBuffer2)[4][16];