diff --git a/data/scripts/mevent_battle_card.inc b/data/scripts/mevent_battle_card.inc index 3a66297e1..536107746 100644 --- a/data/scripts/mevent_battle_card.inc +++ b/data/scripts/mevent_battle_card.inc @@ -1,8 +1,8 @@ MysteryEventScript_BattleCard:: setvaddress MysteryEventScript_BattleCard - vgoto_if_set FLAG_MYSTERY_EVENT_DONE, MysteryEventScript_BattleCardInfo + vgoto_if_set FLAG_MYSTERY_GIFT_DONE, MysteryEventScript_BattleCardInfo setorcopyvar VAR_RESULT, GET_CARD_BATTLES_WON - specialvar VAR_0x8008, GetMysteryEventCardVal + specialvar VAR_0x8008, GetMysteryGiftCardStat compare VAR_0x8008, REQUIRED_CARD_BATTLES vgoto_if_ne MysteryEventScript_BattleCardInfo lock @@ -12,7 +12,7 @@ MysteryEventScript_BattleCard:: waitbuttonpress giveitem ITEM_POTION release - setflag FLAG_MYSTERY_EVENT_DONE + setflag FLAG_MYSTERY_GIFT_DONE end MysteryEventScript_BattleCardInfo: diff --git a/data/scripts/mevent_pichu.inc b/data/scripts/mevent_pichu.inc index 02b47b41f..9256d53a7 100644 --- a/data/scripts/mevent_pichu.inc +++ b/data/scripts/mevent_pichu.inc @@ -1,13 +1,13 @@ MysteryEventScript_SurfPichu:: setvaddress MysteryEventScript_SurfPichu - vgoto_if_unset FLAG_MYSTERY_EVENT_DONE, SurfPichu_GiveIfPossible + vgoto_if_unset FLAG_MYSTERY_GIFT_DONE, SurfPichu_GiveIfPossible returnram SurfPichu_GiveIfPossible: - specialvar VAR_EVENT_PICHU_SLOT, CalculatePlayerPartyCount - compare VAR_EVENT_PICHU_SLOT, PARTY_SIZE + specialvar VAR_GIFT_PICHU_SLOT, CalculatePlayerPartyCount + compare VAR_GIFT_PICHU_SLOT, PARTY_SIZE vgoto_if_eq SurfPichu_FullParty - setflag FLAG_MYSTERY_EVENT_DONE + setflag FLAG_MYSTERY_GIFT_DONE vcall SurfPichu_GiveEgg lock faceplayer @@ -30,17 +30,17 @@ SurfPichu_FullParty: SurfPichu_GiveEgg: giveegg SPECIES_PICHU - setmoneventlegal VAR_EVENT_PICHU_SLOT - setmonmetlocation VAR_EVENT_PICHU_SLOT, METLOC_FATEFUL_ENCOUNTER - compare VAR_EVENT_PICHU_SLOT, 1 + setmoneventlegal VAR_GIFT_PICHU_SLOT + setmonmetlocation VAR_GIFT_PICHU_SLOT, METLOC_FATEFUL_ENCOUNTER + compare VAR_GIFT_PICHU_SLOT, 1 vgoto_if_eq SurfPichu_Slot1 - compare VAR_EVENT_PICHU_SLOT, 2 + compare VAR_GIFT_PICHU_SLOT, 2 vgoto_if_eq SurfPichu_Slot2 - compare VAR_EVENT_PICHU_SLOT, 3 + compare VAR_GIFT_PICHU_SLOT, 3 vgoto_if_eq SurfPichu_Slot3 - compare VAR_EVENT_PICHU_SLOT, 4 + compare VAR_GIFT_PICHU_SLOT, 4 vgoto_if_eq SurfPichu_Slot4 - compare VAR_EVENT_PICHU_SLOT, 5 + compare VAR_GIFT_PICHU_SLOT, 5 vgoto_if_eq SurfPichu_Slot5 return diff --git a/data/scripts/mevent_stamp_card.inc b/data/scripts/mevent_stamp_card.inc index eeb361854..e313aa29d 100644 --- a/data/scripts/mevent_stamp_card.inc +++ b/data/scripts/mevent_stamp_card.inc @@ -1,9 +1,9 @@ MysteryEventScript_StampCard:: setvaddress MysteryEventScript_StampCard setorcopyvar VAR_RESULT, GET_MAX_STAMPS - specialvar VAR_0x8008, GetMysteryEventCardVal + specialvar VAR_0x8008, GetMysteryGiftCardStat setorcopyvar VAR_RESULT, GET_NUM_STAMPS - specialvar VAR_0x8009, GetMysteryEventCardVal + specialvar VAR_0x8009, GetMysteryGiftCardStat subvar VAR_0x8008, VAR_0x8009 buffernumberstring 0, VAR_0x8008 lock diff --git a/data/specials.inc b/data/specials.inc index 297cf7d8a..85c9251c6 100644 --- a/data/specials.inc +++ b/data/specials.inc @@ -400,7 +400,7 @@ gSpecials:: def_special ClearQuizLadyQuestionAndAnswer def_special QuizLadySetCustomQuestion def_special QuizLadyTakePrizeForCustomQuiz - def_special GetMysteryEventCardVal + def_special GetMysteryGiftCardStat def_special QuizLadyRecordCustomQuizData def_special QuizLadySetWaitingForChallenger def_special BufferQuizCorrectAnswer diff --git a/include/constants/flags.h b/include/constants/flags.h index 880d227aa..793fe1135 100644 --- a/include/constants/flags.h +++ b/include/constants/flags.h @@ -338,24 +338,24 @@ #define FLAG_RECEIVED_AURORA_TICKET 0x13A #define FLAG_RECEIVED_MYSTIC_TICKET 0x13B #define FLAG_RECEIVED_OLD_SEA_MAP 0x13C -#define FLAG_MYSTERY_GIFT_UNUSED_1 0x13D // These mystery gift flags are referenced but never set -#define FLAG_MYSTERY_GIFT_UNUSED_2 0x13E -#define FLAG_MYSTERY_GIFT_UNUSED_3 0x13F -#define FLAG_MYSTERY_GIFT_UNUSED_4 0x140 -#define FLAG_MYSTERY_GIFT_UNUSED_5 0x141 -#define FLAG_MYSTERY_GIFT_UNUSED_6 0x142 -#define FLAG_MYSTERY_GIFT_UNUSED_7 0x143 -#define FLAG_MYSTERY_GIFT_UNUSED_8 0x144 -#define FLAG_MYSTERY_GIFT_UNUSED_9 0x145 -#define FLAG_MYSTERY_GIFT_UNUSED_10 0x146 -#define FLAG_MYSTERY_GIFT_UNUSED_11 0x147 -#define FLAG_MYSTERY_GIFT_UNUSED_12 0x148 -#define FLAG_MYSTERY_GIFT_UNUSED_13 0x149 -#define FLAG_MYSTERY_GIFT_UNUSED_14 0x14A -#define FLAG_MYSTERY_GIFT_UNUSED_15 0x14B -#define FLAG_MYSTERY_GIFT_UNUSED_16 0x14C -#define FLAG_MYSTERY_GIFT_UNUSED_17 0x14D -#define NUM_MYSTERY_GIFT_FLAGS (1 + FLAG_MYSTERY_GIFT_UNUSED_17 - FLAG_RECEIVED_AURORA_TICKET) +#define FLAG_WONDER_CARD_UNUSED_1 0x13D // These Wonder Card flags are referenced but never set +#define FLAG_WONDER_CARD_UNUSED_2 0x13E +#define FLAG_WONDER_CARD_UNUSED_3 0x13F +#define FLAG_WONDER_CARD_UNUSED_4 0x140 +#define FLAG_WONDER_CARD_UNUSED_5 0x141 +#define FLAG_WONDER_CARD_UNUSED_6 0x142 +#define FLAG_WONDER_CARD_UNUSED_7 0x143 +#define FLAG_WONDER_CARD_UNUSED_8 0x144 +#define FLAG_WONDER_CARD_UNUSED_9 0x145 +#define FLAG_WONDER_CARD_UNUSED_10 0x146 +#define FLAG_WONDER_CARD_UNUSED_11 0x147 +#define FLAG_WONDER_CARD_UNUSED_12 0x148 +#define FLAG_WONDER_CARD_UNUSED_13 0x149 +#define FLAG_WONDER_CARD_UNUSED_14 0x14A +#define FLAG_WONDER_CARD_UNUSED_15 0x14B +#define FLAG_WONDER_CARD_UNUSED_16 0x14C +#define FLAG_WONDER_CARD_UNUSED_17 0x14D +#define NUM_WONDER_CARD_FLAGS (1 + FLAG_WONDER_CARD_UNUSED_17 - FLAG_RECEIVED_AURORA_TICKET) #define FLAG_MIRAGE_TOWER_VISIBLE 0x14E #define FLAG_CHOSE_ROOT_FOSSIL 0x14F @@ -519,22 +519,22 @@ #define FLAG_UNUSED_0x1E3 0x1E3 // Unused Flag // Mystery Gift Flags (Unknown) -#define FLAG_MYSTERY_EVENT_DONE 0x1E4 -#define FLAG_MYSTERY_EVENT_1 0x1E5 -#define FLAG_MYSTERY_EVENT_2 0x1E6 -#define FLAG_MYSTERY_EVENT_3 0x1E7 -#define FLAG_MYSTERY_EVENT_4 0x1E8 -#define FLAG_MYSTERY_EVENT_5 0x1E9 -#define FLAG_MYSTERY_EVENT_6 0x1EA -#define FLAG_MYSTERY_EVENT_7 0x1EB -#define FLAG_MYSTERY_EVENT_8 0x1EC -#define FLAG_MYSTERY_EVENT_9 0x1ED -#define FLAG_MYSTERY_EVENT_10 0x1EE -#define FLAG_MYSTERY_EVENT_11 0x1EF -#define FLAG_MYSTERY_EVENT_12 0x1F0 -#define FLAG_MYSTERY_EVENT_13 0x1F1 -#define FLAG_MYSTERY_EVENT_14 0x1F2 -#define FLAG_MYSTERY_EVENT_15 0x1F3 +#define FLAG_MYSTERY_GIFT_DONE 0x1E4 +#define FLAG_MYSTERY_GIFT_1 0x1E5 +#define FLAG_MYSTERY_GIFT_2 0x1E6 +#define FLAG_MYSTERY_GIFT_3 0x1E7 +#define FLAG_MYSTERY_GIFT_4 0x1E8 +#define FLAG_MYSTERY_GIFT_5 0x1E9 +#define FLAG_MYSTERY_GIFT_6 0x1EA +#define FLAG_MYSTERY_GIFT_7 0x1EB +#define FLAG_MYSTERY_GIFT_8 0x1EC +#define FLAG_MYSTERY_GIFT_9 0x1ED +#define FLAG_MYSTERY_GIFT_10 0x1EE +#define FLAG_MYSTERY_GIFT_11 0x1EF +#define FLAG_MYSTERY_GIFT_12 0x1F0 +#define FLAG_MYSTERY_GIFT_13 0x1F1 +#define FLAG_MYSTERY_GIFT_14 0x1F2 +#define FLAG_MYSTERY_GIFT_15 0x1F3 // Hidden Items #define FLAG_HIDDEN_ITEMS_START 0x1F4 diff --git a/include/constants/mevent.h b/include/constants/mevent.h index 3478816fd..d659ffb14 100644 --- a/include/constants/mevent.h +++ b/include/constants/mevent.h @@ -1,18 +1,46 @@ #ifndef GUARD_CONSTANTS_MEVENT_H #define GUARD_CONSTANTS_MEVENT_H -// mevent2.c -#define GET_NUM_STAMPS 0 -#define GET_MAX_STAMPS 1 +#define GET_NUM_STAMPS 0 +#define GET_MAX_STAMPS 1 #define GET_CARD_BATTLES_WON 2 +#define GET_CARD_BATTLE_LOST 3 +#define GET_CARD_NUM_TRADES 4 -#define GET_NUM_STAMPS_INTERNAL 3 -#define GET_MAX_STAMPS_INTERNAL 4 -#define GET_CARD_BATTLES_WON_INTERNAL 0 +#define CARD_STAT_BATTLES_WON 0 +#define CARD_STAT_BATTLES_LOST 1 +#define CARD_STAT_NUM_TRADES 2 +#define CARD_STAT_NUM_STAMPS 3 +#define CARD_STAT_MAX_STAMPS 4 + +#define CARD_TYPE_GIFT 0 +#define CARD_TYPE_STAMP 1 // "Stamp Card" +#define CARD_TYPE_LINK_STAT 2 // Referred to as the "Battle Card", shows battle and trade stats +#define CARD_TYPE_COUNT 3 + +#define SEND_TYPE_DISALLOWED 0 +#define SEND_TYPE_ALLOWED 1 +#define SEND_TYPE_ALLOWED_ALWAYS 2 + +// Return values for MysteryGift_CompareCardFlags, handled by gMysteryGiftServerScript_SendWonderCard +#define HAS_NO_CARD 0 +#define HAS_SAME_CARD 1 +#define HAS_DIFF_CARD 2 #define REQUIRED_CARD_BATTLES 3 +#define MAX_CARD_STAMPS 7 + +// Stamps are 32 bits. The first 16 bits are the species +// and the second 16 bits are a number (presumably an ID of some kind) +#define STAMP_SPECIES 0 +#define STAMP_ID 1 + // Number of different types/colors of Wonder Card and News backgrounds #define NUM_WONDER_BGS 8 +#define MAX_WONDER_CARD_STAT 999 + +#define WONDER_CARD_FLAG_OFFSET 1000 + #endif //GUARD_MEVENT_H diff --git a/include/constants/vars.h b/include/constants/vars.h index 2cbe3e9b8..e57b02185 100644 --- a/include/constants/vars.h +++ b/include/constants/vars.h @@ -237,14 +237,14 @@ #define VAR_REGISTER_BIRCH_STATE 0x40DA #define VAR_UNUSED_0x40DB 0x40DB // Unused Var #define VAR_UNUSED_0x40DC 0x40DC // Unused Var -#define VAR_EVENT_PICHU_SLOT 0x40DD -#define VAR_NEVER_READ_0x40DE 0x40DE // Var is written to, but never read -#define VAR_NEVER_READ_0x40DF 0x40DF // Var is written to, but never read -#define VAR_NEVER_READ_0x40E0 0x40E0 // Var is written to, but never read -#define VAR_NEVER_READ_0x40E1 0x40E1 // Var is written to, but never read -#define VAR_NEVER_READ_0x40E2 0x40E2 // Var is written to, but never read -#define VAR_NEVER_READ_0x40E3 0x40E3 // Var is written to, but never read -#define VAR_NEVER_READ_0x40E4 0x40E4 // var is written to, but never read +#define VAR_GIFT_PICHU_SLOT 0x40DD +#define VAR_GIFT_UNUSED_1 0x40DE // Var is written to, but never read +#define VAR_GIFT_UNUSED_2 0x40DF // Var is written to, but never read +#define VAR_GIFT_UNUSED_3 0x40E0 // Var is written to, but never read +#define VAR_GIFT_UNUSED_4 0x40E1 // Var is written to, but never read +#define VAR_GIFT_UNUSED_5 0x40E2 // Var is written to, but never read +#define VAR_GIFT_UNUSED_6 0x40E3 // Var is written to, but never read +#define VAR_GIFT_UNUSED_7 0x40E4 // var is written to, but never read #define VAR_UNUSED_0x40E5 0x40E5 // Unused Var #define VAR_DAILY_SLOTS 0x40E6 #define VAR_DAILY_WILDS 0x40E7 diff --git a/include/event_data.h b/include/event_data.h index 8b4510e39..b1fa69460 100644 --- a/include/event_data.h +++ b/include/event_data.h @@ -13,8 +13,8 @@ bool32 IsMysteryEventEnabled(void); void DisableMysteryGift(void); void EnableMysteryGift(void); bool32 IsMysteryGiftEnabled(void); -void ClearMysteryEventFlags(void); -void ClearMysteryEventVars(void); +void ClearMysteryGiftFlags(void); +void ClearMysteryGiftVars(void); void DisableResetRTC(void); void EnableResetRTC(void); bool32 CanResetRTC(void); diff --git a/include/global.h b/include/global.h index c737be7b8..a6071b2cd 100644 --- a/include/global.h +++ b/include/global.h @@ -837,7 +837,7 @@ struct SaveTrainerHill /*0x3D6E*/ u16 tag:2; }; -struct MysteryEventStruct +struct WonderNewsMetadata { u8 unk_0_0:2; u8 unk_0_2:3; @@ -845,24 +845,24 @@ struct MysteryEventStruct u8 unk_1; }; - struct WonderNews +struct WonderNews { u16 unk_00; - u8 unk_02; + u8 sendType; // SEND_TYPE_* u8 bgType; u8 unk_04[WONDER_NEWS_TEXT_LENGTH]; u8 unk_2C[10][WONDER_NEWS_TEXT_LENGTH]; }; - struct WonderCard +struct WonderCard { u16 flagId; - u16 unk_02; + u16 iconSpecies; u32 unk_04; - u8 unk_08_0:2; + u8 type:2; // CARD_TYPE_* u8 bgType:4; - u8 unk_08_6:2; - u8 unk_09; + u8 sendType:2; // SEND_TYPE_* + u8 maxStamps; u8 unk_0A[WONDER_CARD_TEXT_LENGTH]; u8 unk_32[WONDER_CARD_TEXT_LENGTH]; u8 unk_5A[4][WONDER_CARD_TEXT_LENGTH]; @@ -870,26 +870,26 @@ struct MysteryEventStruct u8 unk_122[WONDER_CARD_TEXT_LENGTH]; }; - struct MEventBuffer_3430 +struct WonderCardMetadata { - u16 unk_00; - u16 unk_02; - u16 unk_04; - u16 unk_06; - u16 unk_08[2][7]; + u16 battlesWon; + u16 battlesLost; + u16 numTrades; + u16 iconSpecies; + u16 stampData[2][7]; }; - struct MysteryGiftSave +struct MysteryGiftSave { u32 newsCrc; struct WonderNews news; u32 cardCrc; struct WonderCard card; - u32 unkCrc; - struct MEventBuffer_3430 unk_3430; + u32 cardMetadataCrc; + struct WonderCardMetadata cardMetadata; u16 questionnaireWords[NUM_QUESTIONNAIRE_WORDS]; - struct MysteryEventStruct unk_340; - u32 unk_344[2][5]; + struct WonderNewsMetadata newsMetadata; + u32 trainerIds[2][5]; // Saved ids for 10 trainers, 5 each for battles and trades }; // 0x36C 0x3598 // For external event data storage. The majority of these may have never been used. @@ -966,7 +966,7 @@ struct SaveBlock1 /*0x848*/ struct Pokeblock pokeblocks[POKEBLOCKS_COUNT]; /*0x988*/ u8 seen1[DEX_FLAGS_NO]; /*0x9BC*/ u16 berryBlenderRecords[3]; - /*0x9C2*/ u8 field_9C2[6]; + /*0x9C2*/ u8 unused_9C2[6]; /*0x9C8*/ u16 trainerRematchStepCounter; /*0x9CA*/ u8 trainerRematches[MAX_REMATCH_ENTRIES]; /*0xA30*/ struct ObjectEvent objectEvents[OBJECT_EVENTS_COUNT]; @@ -986,7 +986,6 @@ struct SaveBlock1 /*0x278E*/ u8 decorationPosters[10]; /*0x2798*/ u8 decorationDolls[40]; /*0x27C0*/ u8 decorationCushions[10]; - /*0x27CA*/ u8 padding_27CA[2]; /*0x27CC*/ TVShow tvShows[TV_SHOWS_COUNT]; /*0x2B50*/ PokeNews pokeNews[POKE_NEWS_COUNT]; /*0x2B90*/ u16 outbreakPokemonSpecies; @@ -1017,7 +1016,7 @@ struct SaveBlock1 /*0x31DC*/ struct Roamer roamer; /*0x31F8*/ struct EnigmaBerry enigmaBerry; /*0x322C*/ struct MysteryGiftSave mysteryGift; - /*0x3598*/ u8 field_3598[0x180]; + /*0x3598*/ u8 unused_3598[0x180]; /*0x3718*/ u32 trainerHillTimes[4]; /*0x3728*/ struct RamScript ramScript; /*0x3B14*/ struct RecordMixingGift recordMixingGift; @@ -1025,7 +1024,7 @@ struct SaveBlock1 /*0x3B58*/ LilycoveLady lilycoveLady; /*0x3B98*/ struct TrainerNameRecord trainerNameRecords[20]; /*0x3C88*/ u8 registeredTexts[UNION_ROOM_KB_ROW_COUNT][21]; - /*0x3D5A*/ u8 filler3D5A[0xA]; + /*0x3D5A*/ u8 unused_3D5A[10]; /*0x3D64*/ struct SaveTrainerHill trainerHill; /*0x3D70*/ struct WaldaPhrase waldaPhrase; // sizeof: 0x3D88 diff --git a/include/main.h b/include/main.h index cad5c0ef9..79d56d31f 100644 --- a/include/main.h +++ b/include/main.h @@ -40,9 +40,10 @@ struct Main /*0x439*/ u8 anyLinkBattlerHasFrontierPass:1; }; +#define GAME_CODE_LENGTH 4 extern const u8 gGameVersion; extern const u8 gGameLanguage; -extern const u8 RomHeaderGameCode[4]; +extern const u8 RomHeaderGameCode[GAME_CODE_LENGTH]; extern const u8 RomHeaderSoftwareVersion; extern u16 gKeyRepeatStartDelay; diff --git a/include/mevent.h b/include/mevent.h index 4fda47fbd..1297b4291 100755 --- a/include/mevent.h +++ b/include/mevent.h @@ -1,6 +1,9 @@ #ifndef GUARD_MEVENT_H #define GUARD_MEVENT_H +#include "main.h" +#include "constants/mevent.h" + struct MEvent_Str_1 { u16 unk_000; @@ -13,51 +16,52 @@ struct MEvent_Str_2 u8 fill_00[0x40]; }; -struct MEventStruct_Unk1442CC +struct MysteryGiftLinkGameData { u32 unk_00; u16 unk_04; u32 unk_08; u16 unk_0C; u32 unk_10; - u16 unk_14; + u16 flagId; u16 questionnaireWords[NUM_QUESTIONNAIRE_WORDS]; - struct MEventBuffer_3430 unk_20; - u8 unk_44; + struct WonderCardMetadata cardMetadata; + u8 maxStamps; u8 playerName[PLAYER_NAME_LENGTH]; u8 playerTrainerId[TRAINER_ID_LENGTH]; u16 easyChatProfile[EASY_CHAT_BATTLE_WORDS_COUNT]; - u8 romHeaderGameCode[4]; + u8 romHeaderGameCode[GAME_CODE_LENGTH]; u8 romHeaderSoftwareVersion; }; -void sub_801AFD8(void); +void ClearMysteryGift(void); struct WonderNews *GetSavedWonderNews(void); struct WonderCard *GetSavedWonderCard(void); -struct MEventBuffer_3430 *sav1_get_mevent_buffer_2(void); -struct MysteryEventStruct *sub_801B044(void); +struct WonderCardMetadata *GetSavedWonderCardMetadata(void); +struct WonderNewsMetadata *GetSavedWonderNewsMetadata(void); u16 *GetQuestionnaireWordsPtr(void); -void ClearSavedWonderNews(void); +void ClearSavedWonderNewsAndRelated(void); +void ClearSavedWonderCardAndRelated(void); bool32 SaveWonderNews(const struct WonderNews *news); -bool32 ValidateSavedWonderNews(void); -bool32 WonderNews_Test_Unk_02(void); -bool32 sub_801B1A4(const u8 *src); -void ClearSavedWonderCard(void); bool32 SaveWonderCard(const struct WonderCard *card); +bool32 ValidateSavedWonderNews(void); bool32 ValidateSavedWonderCard(void); -bool32 WonderCard_Test_Unk_08_6(void); +bool32 IsWonderNewsSameAsSaved(const u8 *src); +bool32 IsSendingSavedWonderNewsAllowed(void); +bool32 IsSendingSavedWonderCardAllowed(void); u16 GetWonderCardFlagID(void); -void WonderCard_ResetInternalReceivedFlag(struct WonderCard *buffer); -bool32 CheckReceivedGiftFromWonderCard(void); -bool32 sub_801B508(const u16 *data); -void sub_801B580(struct MEventStruct_Unk1442CC *data, bool32 a1); -bool32 sub_801B6A0(const struct MEventStruct_Unk1442CC *data, bool32 a1); -u32 sub_801B6EC(const u16 *a0, const struct MEventStruct_Unk1442CC *a1, const void *unused); -u32 sub_801B708(const u16 *a0, const struct MEventStruct_Unk1442CC *a1, const void *unused); -bool32 MysteryGift_DoesQuestionnaireMatch(const struct MEventStruct_Unk1442CC *data, const u16 *words); -u16 MEventStruct_Unk1442CC_GetValueNFrom_unk_20(const struct MEventStruct_Unk1442CC *a0, u32 command); -u16 mevent_081445C0(u32 command); -void ResetReceivedWonderCardFlag(void); -bool32 MEventHandleReceivedWonderCard(u16 a0); +void DisableWonderCardSending(struct WonderCard *card); +bool32 IsSavedWonderCardGiftNotReceived(void); +bool32 MysteryGift_TrySaveStamp(const u16 *stamp); +void MysteryGift_LoadLinkGameData(struct MysteryGiftLinkGameData *data, bool32 a1); +bool32 MysteryGift_ValidateLinkGameData(const struct MysteryGiftLinkGameData *data, bool32 a1); +u32 MysteryGift_CompareCardFlags(const u16 *a0, const struct MysteryGiftLinkGameData *data, const void *unused); +u32 MysteryGift_CheckStamps(const u16 *a0, const struct MysteryGiftLinkGameData *data, const void *unused); +bool32 MysteryGift_DoesQuestionnaireMatch(const struct MysteryGiftLinkGameData *data, const u16 *words); +u16 MysteryGift_GetCardStatFromLinkData(const struct MysteryGiftLinkGameData *data, u32 stat); +u16 MysteryGift_GetCardStat(u32 stat); +void MysteryGift_DisableStats(void); +bool32 MysteryGift_TryEnableStatsByFlagId(u16 flagId); +void TryIncrementMysteryGiftStat(u32 stat, u32 trainerId); #endif //GUARD_MEVENT_H diff --git a/include/mevent2.h b/include/mevent2.h deleted file mode 100644 index 316a9e6de..000000000 --- a/include/mevent2.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef GUARD_MEVENT2_H -#define GUARD_MEVENT2_H - -void RecordIdOfWonderCardSenderByEventType(u32, u32); - -#endif //GUARD_MEVENT2_H diff --git a/include/mevent_client.h b/include/mevent_client.h index f68bb7592..cc189ccc9 100644 --- a/include/mevent_client.h +++ b/include/mevent_client.h @@ -6,11 +6,11 @@ // Return values for client functions called by MysteryGiftClient_Run enum { CLI_RET_INIT, - CLI_RET_1, - CLI_RET_2, - CLI_RET_3, + CLI_RET_ACTIVE, + CLI_RET_YES_NO, + CLI_RET_PRINT_MSG, CLI_RET_ASK_TOSS, - CLI_RET_5, + CLI_RET_COPY_MSG, CLI_RET_END, }; @@ -21,25 +21,47 @@ enum { CLI_RECV, CLI_SEND_LOADED, CLI_COPY_RECV, - CLI_5, + CLI_YES_NO, CLI_COPY_RECV_IF_N, CLI_COPY_RECV_IF, - CLI_8, - CLI_9, - CLI_10, - CLI_11, - CLI_12, + CLI_LOAD_GAME_DATA, + CLI_SAVE_NEWS, + CLI_SAVE_CARD, + CLI_PRINT_MSG, + CLI_COPY_MSG, CLI_ASK_TOSS, CLI_LOAD_TOSS_RESPONSE, - CLI_15, - CLI_16, - CLI_17, + CLI_RUN_GIFT_SCRIPT, + CLI_SAVE_STAMP, + CLI_SAVE_RAM_SCRIPT, CLI_RECV_EREADER_TRAINER, CLI_SEND_STAT, - CLI_20, - CLI_21, + CLI_SEND_READY_END, + CLI_RUN_BUFFER_SCRIPT, }; +// IDs for client messages when ending a script. +// Given as the parameter to CLI_RETURN, and resolved to text in GetClientResultMessage +enum { + CLI_MSG_NOTHING_SENT, + CLI_MSG_RECORD_UPLOADED, + CLI_MSG_CARD_RECEIVED, + CLI_MSG_NEWS_RECEIVED, + CLI_MSG_STAMP_RECEIVED, + CLI_MSG_HAD_CARD, + CLI_MSG_HAD_STAMP, + CLI_MSG_HAD_NEWS, + CLI_MSG_NO_ROOM_STAMPS, + CLI_MSG_COMM_CANCELED, + CLI_MSG_CANT_ACCEPT, + CLI_MSG_COMM_ERROR, + CLI_MSG_TRAINER_RECEIVED, + CLI_MSG_BUFFER_SUCCESS, + CLI_MSG_BUFFER_FAILURE, +}; + +#define CLIENT_MAX_MSG_SIZE 64 + struct MysteryGiftClientCmd { u32 instr; @@ -48,23 +70,23 @@ struct MysteryGiftClientCmd struct MysteryGiftClient { - u32 unk_00; + u32 unused; u32 param; u32 funcId; u32 funcState; u32 cmdidx; void * sendBuffer; void * recvBuffer; - struct MysteryGiftClientCmd * cmdBuffer; - void * buffer; + struct MysteryGiftClientCmd * script; + void * msg; struct MysteryGiftLink link; bool32 isWonderNews; }; void MysteryGiftClient_Create(bool32 isWonderNews); -u32 MysteryGiftClient_Run(u16 * param); +u32 MysteryGiftClient_Run(u16 * endVal); void MysteryGiftClient_AdvanceState(void); -void * mevent_client_get_buffer(void); +void * MysteryGiftClient_GetMsg(void); void MysteryGiftClient_SetParam(u32 value); #endif //GUARD_MEVENT_CLIENT_H diff --git a/include/mevent_news.h b/include/mevent_news.h index 5fa009499..7b4657e14 100755 --- a/include/mevent_news.h +++ b/include/mevent_news.h @@ -1,7 +1,7 @@ #ifndef GUARD_MEVENT_NEWS_H #define GUARD_MEVENT_NEWS_H -void sub_801DBC0(void); -void GenerateRandomNews(u32 a0); +void InitSavedWonderNews(void); +void GenerateRandomWonderNews(u32 a0); #endif //GUARD_MEVENT_NEWS_H diff --git a/include/mevent_server.h b/include/mevent_server.h index 3152280d3..98cb03f6a 100644 --- a/include/mevent_server.h +++ b/include/mevent_server.h @@ -3,34 +3,98 @@ #include "mevent_server_helpers.h" -struct mevent_cmd +// Return values for Server_* functions. +// Other than SVR_RET_END, effectively useless (not checked for). +enum { + SVR_RET_INIT, + SVR_RET_ACTIVE, + SVR_RET_UNUSED, + SVR_RET_END +}; + +// IDs for server script instructions +enum { + SVR_RETURN, + SVR_SEND, + SVR_RECV, + SVR_GOTO, + SVR_GOTO_IF_EQ, + SVR_COPY_GAME_DATA, + SVR_CHECK_GAME_DATA_CARD, + SVR_CHECK_EXISTING_CARD, + SVR_READ_RESPONSE, + SVR_CHECK_EXISTING_STAMPS, + SVR_GET_CARD_STAT, + SVR_CHECK_QUESTIONNAIRE, + SVR_COMPARE, + SVR_LOAD_CARD, + SVR_LOAD_NEWS, + SVR_LOAD_RAM_SCRIPT, + SVR_LOAD_STAMP, + SVR_LOAD_UNK_2, + SVR_LOAD_CLIENT_SCRIPT, + SVR_LOAD_EREADER_TRAINER, + SVR_LOAD_MSG, + SVR_COPY_STAMP, + SVR_COPY_CARD, + SVR_COPY_NEWS, + SVR_SET_RAM_SCRIPT, + SVR_SET_CLIENT_SCRIPT, + SVR_COPY_SAVED_CARD, + SVR_COPY_SAVED_NEWS, + SVR_COPY_SAVED_RAM_SCRIPT, + SVR_LOAD_UNK_1, + SVR_CHECK_GAME_DATA_NEWS, +}; + +// IDs for server messages when ending a script. +// Given as the parameter to SVR_RETURN, and resolved to text in GetServerResultMessage +enum { + SVR_MSG_NOTHING_SENT, + SVR_MSG_RECORD_UPLOADED, + SVR_MSG_CARD_SENT, + SVR_MSG_NEWS_SENT, + SVR_MSG_STAMP_SENT, + SVR_MSG_HAS_CARD, + SVR_MSG_HAS_STAMP, + SVR_MSG_HAS_NEWS, + SVR_MSG_NO_ROOM_STAMPS, + SVR_MSG_CLIENT_CANCELED, + SVR_MSG_CANT_SEND_GIFT_1, + SVR_MSG_COMM_ERROR, + SVR_MSG_GIFT_SENT_1, + SVR_MSG_GIFT_SENT_2, + SVR_MSG_CANT_SEND_GIFT_2, +}; + +struct MysteryGiftServerCmd { u32 instr; - bool32 flag; - const void * parameter; + u32 parameter; + const void * ptr; }; -struct mevent_srv_common +struct MysteryGiftServer { - u32 unk_00; + u32 unused; u32 param; - u32 mainseqno; + u32 funcId; u32 cmdidx; - const struct mevent_cmd * cmdBuffer; + const struct MysteryGiftServerCmd * script; void * recvBuffer; - struct WonderCard * wonder_card; - struct WonderNews * wonder_news; - struct MEventStruct_Unk1442CC * mevent_unk1442cc; - const void * sendBuffer1; - u32 sendBuffer1Size; - const void * sendBuffer2; - u32 sendBuffer2Size; - u32 sendWord; - struct MysteryGiftLink manager; + struct WonderCard * card; + struct WonderNews * news; + struct MysteryGiftLinkGameData * linkGameData; + const void * ramScript; + u32 ramScriptSize; + const void * clientScript; + u32 clientScriptSize; + u32 stamp; + struct MysteryGiftLink link; }; -void mevent_srv_new_wcard(); -void mevent_srv_init_wnews(); -u32 mevent_srv_common_do_exec(u16 * a0); +void MysterGiftServer_CreateForCard(); +void MysterGiftServer_CreateForNews(); +u32 MysterGiftServer_Run(u16 * endVal); #endif //GUARD_MEVENT_SERVER_H diff --git a/include/mevent_server_helpers.h b/include/mevent_server_helpers.h index d2f292a0b..77d966447 100644 --- a/include/mevent_server_helpers.h +++ b/include/mevent_server_helpers.h @@ -1,13 +1,31 @@ #ifndef GUARD_MEVENT_SERVER_HELPERS_H #define GUARD_MEVENT_SERVER_HELPERS_H -#define ME_SEND_BUF_SIZE 0x400 +#define MG_LINK_BUFFER_SIZE 0x400 + +// Send/receive ids for the Client/Server to make sure +// they're sending/receiving the same thing +enum { + MG_LINKID_CLIENT_SCRIPT = 16, + MG_LINKID_GAME_DATA, + MG_LINKID_GAME_STAT, + MG_LINKID_RESPONSE, + MG_LINKID_READY_END, + MG_LINKID_DYNAMIC_MSG, + MG_LINKID_CARD, + MG_LINKID_NEWS, + MG_LINKID_STAMP, + MG_LINKID_RAM_SCRIPT, + MG_LINKID_EREADER_TRAINER, + MG_LINKID_UNK_1, + MG_LINKID_UNK_2, +}; struct MysteryGiftLink { - s32 seqno; - u8 sendPlayerNo; - u8 recvPlayerNo; + s32 state; + u8 sendPlayerId; + u8 recvPlayerId; u16 recvIdent; u16 recvCounter; u16 recvCRC; @@ -22,13 +40,6 @@ struct MysteryGiftLink u32 (*sendFunc)(struct MysteryGiftLink *); }; -struct send_recv_header -{ - u16 ident; - u16 crc; - u16 size; -}; - void MysteryGiftLink_Init(struct MysteryGiftLink *, u32, u32); void MysteryGiftLink_InitSend(struct MysteryGiftLink * manager, u32 ident, const void * src, u32 size); bool32 MysteryGiftLink_Recv(struct MysteryGiftLink * manager); diff --git a/include/mystery_gift.h b/include/mystery_gift.h index 42c7f47ba..73d3b93ea 100644 --- a/include/mystery_gift.h +++ b/include/mystery_gift.h @@ -8,7 +8,7 @@ void CB2_MysteryGiftEReader(void); void PrintMysteryGiftOrEReaderTopMenu(bool8 isJapanese, bool32 usePickOkCancel); void MG_DrawCheckerboardPattern(u32 bg); void MainCB_FreeAllBuffersAndReturnToInitTitleScreen(void); -bool32 MG_PrintTextOnWindow1AndWaitButton(u8 *textState, const u8 *str); +bool32 PrintMysteryGiftMenuMessage(u8 *textState, const u8 *str); void AddTextPrinterToWindow1(const u8 *src); void CB2_InitEReader(void); void CB2_InitMysteryGift(void); diff --git a/include/wonder_transfer.h b/include/wonder_transfer.h index 7532d6b3c..398a2b37b 100644 --- a/include/wonder_transfer.h +++ b/include/wonder_transfer.h @@ -9,7 +9,7 @@ enum { NEWS_INPUT_NONE = 0xFF }; -bool32 WonderCard_Init(struct WonderCard * card, struct MEventBuffer_3430 * r6); +bool32 WonderCard_Init(struct WonderCard * card, struct WonderCardMetadata * r6); bool32 WonderNews_Init(const struct WonderNews * news); s32 WonderCard_Enter(void); s32 WonderNews_Enter(void); diff --git a/src/cable_club.c b/src/cable_club.c index 3a4f723ea..e9100b011 100644 --- a/src/cable_club.c +++ b/src/cable_club.c @@ -18,7 +18,7 @@ #include "overworld.h" #include "palette.h" #include "union_room.h" -#include "mevent2.h" +#include "mevent.h" #include "script.h" #include "script_pokemon_util.h" #include "sound.h" @@ -1004,10 +1004,10 @@ void CB2_ReturnFromCableClubBattle(void) switch (gBattleOutcome) { case B_OUTCOME_WON: - RecordIdOfWonderCardSenderByEventType(0, gLinkPlayers[GetMultiplayerId() ^ 1].trainerId); + TryIncrementMysteryGiftStat(CARD_STAT_BATTLES_WON, gLinkPlayers[GetMultiplayerId() ^ 1].trainerId); break; case B_OUTCOME_LOST: - RecordIdOfWonderCardSenderByEventType(1, gLinkPlayers[GetMultiplayerId() ^ 1].trainerId); + TryIncrementMysteryGiftStat(CARD_STAT_BATTLES_LOST, gLinkPlayers[GetMultiplayerId() ^ 1].trainerId); break; } } diff --git a/src/ereader_screen.c b/src/ereader_screen.c index 31794628b..a76fb09c8 100755 --- a/src/ereader_screen.c +++ b/src/ereader_screen.c @@ -250,7 +250,7 @@ static void Task_EReader(u8 taskId) switch (data->unk8) { case 0: - if (MG_PrintTextOnWindow1AndWaitButton(&data->unk9, gJPText_ReceiveMysteryGiftWithEReader)) + if (PrintMysteryGiftMenuMessage(&data->unk9, gJPText_ReceiveMysteryGiftWithEReader)) data->unk8 = 1; break; case 1: @@ -274,7 +274,7 @@ static void Task_EReader(u8 taskId) } break; case 4: - if (MG_PrintTextOnWindow1AndWaitButton(&data->unk9, gJPText_SelectConnectFromEReaderMenu)) + if (PrintMysteryGiftMenuMessage(&data->unk9, gJPText_SelectConnectFromEReaderMenu)) { AddTextPrinterToWindow1(gJPText_SelectConnectWithGBA); sub_81D505C(&data->unk0); @@ -323,7 +323,7 @@ static void Task_EReader(u8 taskId) } break; case 7: - if (MG_PrintTextOnWindow1AndWaitButton(&data->unk9, gJPText_LinkIsIncorrect)) + if (PrintMysteryGiftMenuMessage(&data->unk9, gJPText_LinkIsIncorrect)) data->unk8 = 4; break; case 8: @@ -439,19 +439,19 @@ static void Task_EReader(u8 taskId) data->unk8 = 26; break; case 23: - if (MG_PrintTextOnWindow1AndWaitButton(&data->unk9, gJPText_CardReadingHasBeenHalted)) + if (PrintMysteryGiftMenuMessage(&data->unk9, gJPText_CardReadingHasBeenHalted)) data->unk8 = 26; break; case 20: - if (MG_PrintTextOnWindow1AndWaitButton(&data->unk9, gJPText_ConnectionErrorCheckLink)) + if (PrintMysteryGiftMenuMessage(&data->unk9, gJPText_ConnectionErrorCheckLink)) data->unk8 = 0; break; case 21: - if (MG_PrintTextOnWindow1AndWaitButton(&data->unk9, gJPText_ConnectionErrorTryAgain)) + if (PrintMysteryGiftMenuMessage(&data->unk9, gJPText_ConnectionErrorTryAgain)) data->unk8 = 0; break; case 22: - if (MG_PrintTextOnWindow1AndWaitButton(&data->unk9, gJPText_WriteErrorUnableToSaveData)) + if (PrintMysteryGiftMenuMessage(&data->unk9, gJPText_WriteErrorUnableToSaveData)) data->unk8 = 0; break; case 26: diff --git a/src/event_data.c b/src/event_data.c index 2bde09012..e2af6c3d0 100644 --- a/src/event_data.c +++ b/src/event_data.c @@ -114,36 +114,36 @@ bool32 IsMysteryGiftEnabled(void) return FlagGet(FLAG_SYS_MYSTERY_GIFT_ENABLE); } -void ClearMysteryEventFlags(void) +void ClearMysteryGiftFlags(void) { - FlagClear(FLAG_MYSTERY_EVENT_DONE); - FlagClear(FLAG_MYSTERY_EVENT_1); - FlagClear(FLAG_MYSTERY_EVENT_2); - FlagClear(FLAG_MYSTERY_EVENT_3); - FlagClear(FLAG_MYSTERY_EVENT_4); - FlagClear(FLAG_MYSTERY_EVENT_5); - FlagClear(FLAG_MYSTERY_EVENT_6); - FlagClear(FLAG_MYSTERY_EVENT_7); - FlagClear(FLAG_MYSTERY_EVENT_8); - FlagClear(FLAG_MYSTERY_EVENT_9); - FlagClear(FLAG_MYSTERY_EVENT_10); - FlagClear(FLAG_MYSTERY_EVENT_11); - FlagClear(FLAG_MYSTERY_EVENT_12); - FlagClear(FLAG_MYSTERY_EVENT_13); - FlagClear(FLAG_MYSTERY_EVENT_14); - FlagClear(FLAG_MYSTERY_EVENT_15); + FlagClear(FLAG_MYSTERY_GIFT_DONE); + FlagClear(FLAG_MYSTERY_GIFT_1); + FlagClear(FLAG_MYSTERY_GIFT_2); + FlagClear(FLAG_MYSTERY_GIFT_3); + FlagClear(FLAG_MYSTERY_GIFT_4); + FlagClear(FLAG_MYSTERY_GIFT_5); + FlagClear(FLAG_MYSTERY_GIFT_6); + FlagClear(FLAG_MYSTERY_GIFT_7); + FlagClear(FLAG_MYSTERY_GIFT_8); + FlagClear(FLAG_MYSTERY_GIFT_9); + FlagClear(FLAG_MYSTERY_GIFT_10); + FlagClear(FLAG_MYSTERY_GIFT_11); + FlagClear(FLAG_MYSTERY_GIFT_12); + FlagClear(FLAG_MYSTERY_GIFT_13); + FlagClear(FLAG_MYSTERY_GIFT_14); + FlagClear(FLAG_MYSTERY_GIFT_15); } -void ClearMysteryEventVars(void) +void ClearMysteryGiftVars(void) { - VarSet(VAR_EVENT_PICHU_SLOT, 0); - VarSet(VAR_NEVER_READ_0x40DE, 0); - VarSet(VAR_NEVER_READ_0x40DF, 0); - VarSet(VAR_NEVER_READ_0x40E0, 0); - VarSet(VAR_NEVER_READ_0x40E1, 0); - VarSet(VAR_NEVER_READ_0x40E2, 0); - VarSet(VAR_NEVER_READ_0x40E3, 0); - VarSet(VAR_NEVER_READ_0x40E4, 0); + VarSet(VAR_GIFT_PICHU_SLOT, 0); + VarSet(VAR_GIFT_UNUSED_1, 0); + VarSet(VAR_GIFT_UNUSED_2, 0); + VarSet(VAR_GIFT_UNUSED_3, 0); + VarSet(VAR_GIFT_UNUSED_4, 0); + VarSet(VAR_GIFT_UNUSED_5, 0); + VarSet(VAR_GIFT_UNUSED_6, 0); + VarSet(VAR_GIFT_UNUSED_7, 0); } void DisableResetRTC(void) diff --git a/src/field_specials.c b/src/field_specials.c index 131099ab7..5d7829d12 100644 --- a/src/field_specials.c +++ b/src/field_specials.c @@ -1651,20 +1651,20 @@ void BufferLottoTicketNumber(void) } } -u16 GetMysteryEventCardVal(void) +u16 GetMysteryGiftCardStat(void) { switch (gSpecialVar_Result) { case GET_NUM_STAMPS: - return mevent_081445C0(GET_NUM_STAMPS_INTERNAL); + return MysteryGift_GetCardStat(CARD_STAT_NUM_STAMPS); case GET_MAX_STAMPS: - return mevent_081445C0(GET_MAX_STAMPS_INTERNAL); + return MysteryGift_GetCardStat(CARD_STAT_MAX_STAMPS); case GET_CARD_BATTLES_WON: - return mevent_081445C0(GET_CARD_BATTLES_WON_INTERNAL); - case 3: // Never occurs - return mevent_081445C0(1); - case 4: // Never occurs - return mevent_081445C0(2); + return MysteryGift_GetCardStat(CARD_STAT_BATTLES_WON); + case GET_CARD_BATTLE_LOST: // Never occurs + return MysteryGift_GetCardStat(CARD_STAT_BATTLES_LOST); + case GET_CARD_NUM_TRADES: // Never occurs + return MysteryGift_GetCardStat(CARD_STAT_NUM_TRADES); default: return 0; } diff --git a/src/mevent2.c b/src/mevent2.c index fd3ec7a67..d781e2119 100755 --- a/src/mevent2.c +++ b/src/mevent2.c @@ -11,23 +11,23 @@ #include "mevent.h" #include "constants/mevent.h" -static EWRAM_DATA bool32 gUnknown_02022C70 = FALSE; +static EWRAM_DATA bool32 sStatsEnabled = FALSE; -static void sub_801B180(void); -static void ClearSavedWonderNewsInternal(void); -static bool32 ValidateWonderNews(const struct WonderNews *news); -static bool32 ValidateWonderCard(const struct WonderCard *card); -static void InitSavedWonderCard(void); -static void sub_801B368(void); -static void sub_801B9F8(void); -static void sub_801BA8C(u32 a0, u32 a1, u32 *a2, int a3); +static void ClearSavedWonderNewsMetadata(void); +static void ClearSavedWonderNews(void); +static void ClearSavedWonderCard(void); +static bool32 ValidateWonderNews(const struct WonderNews *); +static bool32 ValidateWonderCard(const struct WonderCard *); +static void ClearSavedWonderCardMetadata(void); +static void ClearSavedTrainerIds(void); +static void IncrementCardStatForNewTrainer(u32, u32, u32 *, int); #define CALC_CRC(data) CalcCRC16WithTable((void *)&(data), sizeof(data)) -void sub_801AFD8(void) +void ClearMysteryGift(void) { CpuFill32(0, &gSaveBlock1Ptr->mysteryGift, sizeof(gSaveBlock1Ptr->mysteryGift)); - sub_801B180(); + ClearSavedWonderNewsMetadata(); // Clear is redundant, InitSavedWonderNews would be sufficient InitQuestionnaireWords(); } @@ -41,14 +41,14 @@ struct WonderCard *GetSavedWonderCard(void) return &gSaveBlock1Ptr->mysteryGift.card; } -struct MEventBuffer_3430 *sav1_get_mevent_buffer_2(void) +struct WonderCardMetadata *GetSavedWonderCardMetadata(void) { - return &gSaveBlock1Ptr->mysteryGift.unk_3430; + return &gSaveBlock1Ptr->mysteryGift.cardMetadata; } -struct MysteryEventStruct *sub_801B044(void) +struct WonderNewsMetadata *GetSavedWonderNewsMetadata(void) { - return &gSaveBlock1Ptr->mysteryGift.unk_340; + return &gSaveBlock1Ptr->mysteryGift.newsMetadata; } u16 *GetQuestionnaireWordsPtr(void) @@ -56,9 +56,10 @@ u16 *GetQuestionnaireWordsPtr(void) return gSaveBlock1Ptr->mysteryGift.questionnaireWords; } -void ClearSavedWonderNews(void) +// Equivalent to ClearSavedWonderCardAndRelated, but nothing else to clear +void ClearSavedWonderNewsAndRelated(void) { - ClearSavedWonderNewsInternal(); + ClearSavedWonderNews(); } bool32 SaveWonderNews(const struct WonderNews *news) @@ -66,7 +67,7 @@ bool32 SaveWonderNews(const struct WonderNews *news) if (!ValidateWonderNews(news)) return FALSE; - ClearSavedWonderNewsInternal(); + ClearSavedWonderNews(); gSaveBlock1Ptr->mysteryGift.news = *news; gSaveBlock1Ptr->mysteryGift.newsCrc = CALC_CRC(gSaveBlock1Ptr->mysteryGift.news); return TRUE; @@ -90,65 +91,65 @@ static bool32 ValidateWonderNews(const struct WonderNews *data) return TRUE; } -bool32 WonderNews_Test_Unk_02(void) +bool32 IsSendingSavedWonderNewsAllowed(void) { const struct WonderNews *data = &gSaveBlock1Ptr->mysteryGift.news; - if (data->unk_02 == 0) + if (data->sendType == SEND_TYPE_DISALLOWED) return FALSE; return TRUE; } -static void ClearSavedWonderNewsInternal(void) +static void ClearSavedWonderNews(void) { CpuFill32(0, GetSavedWonderNews(), sizeof(gSaveBlock1Ptr->mysteryGift.news)); gSaveBlock1Ptr->mysteryGift.newsCrc = 0; } -static void sub_801B180(void) +static void ClearSavedWonderNewsMetadata(void) { - CpuFill32(0, sub_801B044(), sizeof(struct MysteryEventStruct)); - sub_801DBC0(); + CpuFill32(0, GetSavedWonderNewsMetadata(), sizeof(gSaveBlock1Ptr->mysteryGift.newsMetadata)); + InitSavedWonderNews(); } -bool32 sub_801B1A4(const u8 *src) +bool32 IsWonderNewsSameAsSaved(const u8 *news) { - const u8 *r5 = (const u8 *)&gSaveBlock1Ptr->mysteryGift.news; + const u8 *savedNews = (const u8 *)&gSaveBlock1Ptr->mysteryGift.news; u32 i; if (!ValidateSavedWonderNews()) return FALSE; - for (i = 0; i < sizeof(struct WonderNews); i++) + for (i = 0; i < sizeof(gSaveBlock1Ptr->mysteryGift.news); i++) { - if (r5[i] != src[i]) + if (savedNews[i] != news[i]) return FALSE; } return TRUE; } -void ClearSavedWonderCard(void) +void ClearSavedWonderCardAndRelated(void) { - InitSavedWonderCard(); - sub_801B368(); - sub_801B9F8(); + ClearSavedWonderCard(); + ClearSavedWonderCardMetadata(); + ClearSavedTrainerIds(); ClearRamScript(); - ClearMysteryEventFlags(); - ClearMysteryEventVars(); + ClearMysteryGiftFlags(); + ClearMysteryGiftVars(); ClearEReaderTrainer(&gSaveBlock2Ptr->frontier.ereaderTrainer); } bool32 SaveWonderCard(const struct WonderCard *card) { - struct MEventBuffer_3430 *r2; + struct WonderCardMetadata *metadata; if (!ValidateWonderCard(card)) return FALSE; - ClearSavedWonderCard(); + ClearSavedWonderCardAndRelated(); memcpy(&gSaveBlock1Ptr->mysteryGift.card, card, sizeof(struct WonderCard)); gSaveBlock1Ptr->mysteryGift.cardCrc = CALC_CRC(gSaveBlock1Ptr->mysteryGift.card); - r2 = &gSaveBlock1Ptr->mysteryGift.unk_3430; - r2->unk_06 = (&gSaveBlock1Ptr->mysteryGift.card)->unk_02; + metadata = &gSaveBlock1Ptr->mysteryGift.cardMetadata; + metadata->iconSpecies = (&gSaveBlock1Ptr->mysteryGift.card)->iconSpecies; return TRUE; } @@ -168,37 +169,39 @@ static bool32 ValidateWonderCard(const struct WonderCard *card) { if (card->flagId == 0) return FALSE; - if (card->unk_08_0 > 2) + if (card->type >= CARD_TYPE_COUNT) return FALSE; - if (!(card->unk_08_6 == 0 || card->unk_08_6 == 1 || card->unk_08_6 == 2)) + if (!(card->sendType == SEND_TYPE_DISALLOWED + || card->sendType == SEND_TYPE_ALLOWED + || card->sendType == SEND_TYPE_ALLOWED_ALWAYS)) return FALSE; if (card->bgType >= NUM_WONDER_BGS) return FALSE; - if (card->unk_09 > 7) + if (card->maxStamps > MAX_CARD_STAMPS) return FALSE; return TRUE; } -bool32 WonderCard_Test_Unk_08_6(void) +bool32 IsSendingSavedWonderCardAllowed(void) { const struct WonderCard *card = &gSaveBlock1Ptr->mysteryGift.card; - if (card->unk_08_6 == 0) + if (card->sendType == SEND_TYPE_DISALLOWED) return FALSE; return TRUE; } -static void InitSavedWonderCard(void) +static void ClearSavedWonderCard(void) { CpuFill32(0, &gSaveBlock1Ptr->mysteryGift.card, sizeof(gSaveBlock1Ptr->mysteryGift.card)); gSaveBlock1Ptr->mysteryGift.cardCrc = 0; } -static void sub_801B368(void) +static void ClearSavedWonderCardMetadata(void) { - CpuFill32(0, sav1_get_mevent_buffer_2(), 18 *sizeof(u16)); - gSaveBlock1Ptr->mysteryGift.unkCrc = 0; + CpuFill32(0, GetSavedWonderCardMetadata(), sizeof(gSaveBlock1Ptr->mysteryGift.cardMetadata)); + gSaveBlock1Ptr->mysteryGift.cardMetadataCrc = 0; } u16 GetWonderCardFlagID(void) @@ -209,124 +212,126 @@ u16 GetWonderCardFlagID(void) return 0; } -void WonderCard_ResetInternalReceivedFlag(struct WonderCard *buffer) +void DisableWonderCardSending(struct WonderCard *card) { - if (buffer->unk_08_6 == 1) - buffer->unk_08_6 = 0; + if (card->sendType == SEND_TYPE_ALLOWED) + card->sendType = SEND_TYPE_DISALLOWED; } static bool32 IsWonderCardFlagIDInValidRange(u16 flagId) { - if (flagId >= 1000 && flagId < 1000 + NUM_MYSTERY_GIFT_FLAGS) + if (flagId >= WONDER_CARD_FLAG_OFFSET && flagId < WONDER_CARD_FLAG_OFFSET + NUM_WONDER_CARD_FLAGS) return TRUE; return FALSE; } -static const u16 sMysteryGiftFlags[] = +static const u16 sReceivedGiftFlags[] = { FLAG_RECEIVED_AURORA_TICKET, FLAG_RECEIVED_MYSTIC_TICKET, FLAG_RECEIVED_OLD_SEA_MAP, - FLAG_MYSTERY_GIFT_UNUSED_1, - FLAG_MYSTERY_GIFT_UNUSED_2, - FLAG_MYSTERY_GIFT_UNUSED_3, - FLAG_MYSTERY_GIFT_UNUSED_4, - FLAG_MYSTERY_GIFT_UNUSED_5, - FLAG_MYSTERY_GIFT_UNUSED_6, - FLAG_MYSTERY_GIFT_UNUSED_7, - FLAG_MYSTERY_GIFT_UNUSED_8, - FLAG_MYSTERY_GIFT_UNUSED_9, - FLAG_MYSTERY_GIFT_UNUSED_10, - FLAG_MYSTERY_GIFT_UNUSED_11, - FLAG_MYSTERY_GIFT_UNUSED_12, - FLAG_MYSTERY_GIFT_UNUSED_13, - FLAG_MYSTERY_GIFT_UNUSED_14, - FLAG_MYSTERY_GIFT_UNUSED_15, - FLAG_MYSTERY_GIFT_UNUSED_16, - FLAG_MYSTERY_GIFT_UNUSED_17, + FLAG_WONDER_CARD_UNUSED_1, + FLAG_WONDER_CARD_UNUSED_2, + FLAG_WONDER_CARD_UNUSED_3, + FLAG_WONDER_CARD_UNUSED_4, + FLAG_WONDER_CARD_UNUSED_5, + FLAG_WONDER_CARD_UNUSED_6, + FLAG_WONDER_CARD_UNUSED_7, + FLAG_WONDER_CARD_UNUSED_8, + FLAG_WONDER_CARD_UNUSED_9, + FLAG_WONDER_CARD_UNUSED_10, + FLAG_WONDER_CARD_UNUSED_11, + FLAG_WONDER_CARD_UNUSED_12, + FLAG_WONDER_CARD_UNUSED_13, + FLAG_WONDER_CARD_UNUSED_14, + FLAG_WONDER_CARD_UNUSED_15, + FLAG_WONDER_CARD_UNUSED_16, + FLAG_WONDER_CARD_UNUSED_17, }; -bool32 CheckReceivedGiftFromWonderCard(void) +bool32 IsSavedWonderCardGiftNotReceived(void) { u16 value = GetWonderCardFlagID(); if (!IsWonderCardFlagIDInValidRange(value)) return FALSE; - if (FlagGet(sMysteryGiftFlags[value - 1000]) == TRUE) + // If flag is set, player has received gift from this card + if (FlagGet(sReceivedGiftFlags[value - WONDER_CARD_FLAG_OFFSET]) == TRUE) return FALSE; return TRUE; } -static int sub_801B438(const struct MEventBuffer_3430 *data, int size) +static int GetNumStampsInMetadata(const struct WonderCardMetadata *data, int size) { - int r3 = 0; + int numStamps = 0; int i; for (i = 0; i < size; i++) { - if (data->unk_08[1][i] && data->unk_08[0][i]) - r3++; + if (data->stampData[STAMP_ID][i] && data->stampData[STAMP_SPECIES][i] != SPECIES_NONE) + numStamps++; } - return r3; + return numStamps; } -static bool32 sub_801B460(const struct MEventBuffer_3430 *data1, const u16 *data2, int size) +static bool32 IsStampInMetadata(const struct WonderCardMetadata *metadata, const u16 *stamp, int maxStamps) { int i; - for (i = 0; i < size; i++) + for (i = 0; i < maxStamps; i++) { - if (data1->unk_08[1][i] == data2[1]) + if (metadata->stampData[STAMP_ID][i] == stamp[STAMP_ID]) return TRUE; - if (data1->unk_08[0][i] == data2[0]) + if (metadata->stampData[STAMP_SPECIES][i] == stamp[STAMP_SPECIES]) return TRUE; } return FALSE; } -static bool32 sub_801B4A4(const u16 *data) +static bool32 ValidateStamp(const u16 *stamp) { - if (data[1] == 0) + if (stamp[STAMP_ID] == 0) return FALSE; - if (data[0] == 0) + if (stamp[STAMP_SPECIES] == SPECIES_NONE) return FALSE; - if (data[0] >= NUM_SPECIES) + if (stamp[STAMP_SPECIES] >= NUM_SPECIES) return FALSE; return TRUE; } -static int sub_801B4CC(void) +static int GetNumStampsInSavedCard(void) { - struct WonderCard *data; + struct WonderCard *card; if (!ValidateSavedWonderCard()) return 0; - data = &gSaveBlock1Ptr->mysteryGift.card; - if (data->unk_08_0 != 1) + card = &gSaveBlock1Ptr->mysteryGift.card; + if (card->type != CARD_TYPE_STAMP) return 0; - return sub_801B438(&gSaveBlock1Ptr->mysteryGift.unk_3430, data->unk_09); + return GetNumStampsInMetadata(&gSaveBlock1Ptr->mysteryGift.cardMetadata, card->maxStamps); } -bool32 sub_801B508(const u16 *data) +bool32 MysteryGift_TrySaveStamp(const u16 *stamp) { - struct WonderCard *buffer = &gSaveBlock1Ptr->mysteryGift.card; - int size = buffer->unk_09; + struct WonderCard *card = &gSaveBlock1Ptr->mysteryGift.card; + int maxStamps = card->maxStamps; int i; - if (!sub_801B4A4(data)) + if (!ValidateStamp(stamp)) return FALSE; - if (sub_801B460(&gSaveBlock1Ptr->mysteryGift.unk_3430, data, size)) + if (IsStampInMetadata(&gSaveBlock1Ptr->mysteryGift.cardMetadata, stamp, maxStamps)) return FALSE; - for (i = 0; i < size; i++) + for (i = 0; i < maxStamps; i++) { - if (gSaveBlock1Ptr->mysteryGift.unk_3430.unk_08[1][i] == 0 && gSaveBlock1Ptr->mysteryGift.unk_3430.unk_08[0][i] == 0) + if (gSaveBlock1Ptr->mysteryGift.cardMetadata.stampData[STAMP_ID][i] == 0 + && gSaveBlock1Ptr->mysteryGift.cardMetadata.stampData[STAMP_SPECIES][i] == SPECIES_NONE) { - gSaveBlock1Ptr->mysteryGift.unk_3430.unk_08[1][i] = data[1]; - gSaveBlock1Ptr->mysteryGift.unk_3430.unk_08[0][i] = data[0]; + gSaveBlock1Ptr->mysteryGift.cardMetadata.stampData[STAMP_ID][i] = stamp[STAMP_ID]; + gSaveBlock1Ptr->mysteryGift.cardMetadata.stampData[STAMP_SPECIES][i] = stamp[STAMP_SPECIES]; return TRUE; } } @@ -334,10 +339,10 @@ bool32 sub_801B508(const u16 *data) return FALSE; } -void sub_801B580(struct MEventStruct_Unk1442CC *data, bool32 isWonderNews) +void MysteryGift_LoadLinkGameData(struct MysteryGiftLinkGameData *data, bool32 isWonderNews) { int i; - CpuFill32(0, data, sizeof(struct MEventStruct_Unk1442CC)); + CpuFill32(0, data, sizeof(*data)); data->unk_00 = 0x101; data->unk_04 = 1; data->unk_08 = 1; @@ -355,13 +360,13 @@ void sub_801B580(struct MEventStruct_Unk1442CC *data, bool32 isWonderNews) if (ValidateSavedWonderCard()) { - data->unk_14 = GetSavedWonderCard()->flagId; - data->unk_20 = *sav1_get_mevent_buffer_2(); - data->unk_44 = GetSavedWonderCard()->unk_09; + data->flagId = GetSavedWonderCard()->flagId; + data->cardMetadata = *GetSavedWonderCardMetadata(); + data->maxStamps = GetSavedWonderCard()->maxStamps; } else { - data->unk_14 = 0; + data->flagId = 0; } for (i = 0; i < NUM_QUESTIONNAIRE_WORDS; i++) @@ -372,11 +377,11 @@ void sub_801B580(struct MEventStruct_Unk1442CC *data, bool32 isWonderNews) for (i = 0; i < EASY_CHAT_BATTLE_WORDS_COUNT; i++) data->easyChatProfile[i] = gSaveBlock1Ptr->easyChatProfile[i]; - memcpy(data->romHeaderGameCode, RomHeaderGameCode, 4); + memcpy(data->romHeaderGameCode, RomHeaderGameCode, GAME_CODE_LENGTH); data->romHeaderSoftwareVersion = RomHeaderSoftwareVersion; } -bool32 sub_801B6A0(const struct MEventStruct_Unk1442CC *data, bool32 a1) +bool32 MysteryGift_ValidateLinkGameData(const struct MysteryGiftLinkGameData *data, bool32 forNews) { if (data->unk_00 != 0x101) return FALSE; @@ -387,7 +392,7 @@ bool32 sub_801B6A0(const struct MEventStruct_Unk1442CC *data, bool32 a1) if (!(data->unk_08 & 1)) return FALSE; - if (!a1) + if (!forNews) { if (!(data->unk_0C & 4)) return FALSE; @@ -399,30 +404,43 @@ bool32 sub_801B6A0(const struct MEventStruct_Unk1442CC *data, bool32 a1) return TRUE; } -u32 sub_801B6EC(const u16 *a0, const struct MEventStruct_Unk1442CC *a1, const void *unused) +u32 MysteryGift_CompareCardFlags(const u16 *flagId, const struct MysteryGiftLinkGameData *data, const void *unused) { - if (a1->unk_14 == 0) - return 0; + // Has a Wonder Card already? + if (data->flagId == 0) + return HAS_NO_CARD; - if (*a0 == a1->unk_14) - return 1; + // Has this Wonder Card already? + if (*flagId == data->flagId) + return HAS_SAME_CARD; - return 2; + // Player has a different Wonder Card + return HAS_DIFF_CARD; } -u32 sub_801B708(const u16 *a0, const struct MEventStruct_Unk1442CC *a1, const void *unused) +// This is referenced by the Mystery Gift server, but the instruction it's referenced in is never used, +// so the return values here are never checked by anything. +u32 MysteryGift_CheckStamps(const u16 *stamp, const struct MysteryGiftLinkGameData *data, const void *unused) { - int r4 = a1->unk_44 - sub_801B438(&a1->unk_20, a1->unk_44); - if (r4 == 0) + int stampsMissing = data->maxStamps - GetNumStampsInMetadata(&data->cardMetadata, data->maxStamps); + + // Has full stamp card? + if (stampsMissing == 0) return 1; - if (sub_801B460(&a1->unk_20, a0, a1->unk_44)) + + // Already has stamp? + if (IsStampInMetadata(&data->cardMetadata, stamp, data->maxStamps)) return 3; - if (r4 == 1) + + // Only 1 empty stamp left? + if (stampsMissing == 1) return 4; + + // This is a new stamp return 2; } -bool32 MysteryGift_DoesQuestionnaireMatch(const struct MEventStruct_Unk1442CC *data, const u16 *words) +bool32 MysteryGift_DoesQuestionnaireMatch(const struct MysteryGiftLinkGameData *data, const u16 *words) { int i; for (i = 0; i < NUM_QUESTIONNAIRE_WORDS; i++) @@ -434,127 +452,122 @@ bool32 MysteryGift_DoesQuestionnaireMatch(const struct MEventStruct_Unk1442CC *d return TRUE; } -static int sub_801B770(const struct MEventStruct_Unk1442CC *a0) +static int GetNumStampsInLinkData(const struct MysteryGiftLinkGameData *data) { - return sub_801B438(&a0->unk_20, a0->unk_44); + return GetNumStampsInMetadata(&data->cardMetadata, data->maxStamps); } -u16 MEventStruct_Unk1442CC_GetValueNFrom_unk_20(const struct MEventStruct_Unk1442CC *a0, u32 command) +u16 MysteryGift_GetCardStatFromLinkData(const struct MysteryGiftLinkGameData *data, u32 stat) { - switch (command) + switch (stat) { - case 0: - return a0->unk_20.unk_00; - case 1: - return a0->unk_20.unk_02; - case 2: - return a0->unk_20.unk_04; - case 3: - return sub_801B770(a0); - case 4: - return a0->unk_44; + case CARD_STAT_BATTLES_WON: + return data->cardMetadata.battlesWon; + case CARD_STAT_BATTLES_LOST: + return data->cardMetadata.battlesLost; + case CARD_STAT_NUM_TRADES: + return data->cardMetadata.numTrades; + case CARD_STAT_NUM_STAMPS: + return GetNumStampsInLinkData(data); + case CARD_STAT_MAX_STAMPS: + return data->maxStamps; default: AGB_ASSERT(0); return 0; } } -static void sub_801B7D8(u32 command) +static void IncrementCardStat(u32 statType) { - struct WonderCard *data = &gSaveBlock1Ptr->mysteryGift.card; - if (data->unk_08_0 == 2) + struct WonderCard *card = &gSaveBlock1Ptr->mysteryGift.card; + if (card->type == CARD_TYPE_LINK_STAT) { - u16 *dest = NULL; - switch (command) + u16 *stat = NULL; + switch (statType) { - case 0: - dest = &gSaveBlock1Ptr->mysteryGift.unk_3430.unk_00; + case CARD_STAT_BATTLES_WON: + stat = &gSaveBlock1Ptr->mysteryGift.cardMetadata.battlesWon; break; - case 1: - dest = &gSaveBlock1Ptr->mysteryGift.unk_3430.unk_02; + case CARD_STAT_BATTLES_LOST: + stat = &gSaveBlock1Ptr->mysteryGift.cardMetadata.battlesLost; break; - case 2: - dest = &gSaveBlock1Ptr->mysteryGift.unk_3430.unk_04; + case CARD_STAT_NUM_TRADES: + stat = &gSaveBlock1Ptr->mysteryGift.cardMetadata.numTrades; break; - case 3: - break; - case 4: + case CARD_STAT_NUM_STAMPS: // Unused + case CARD_STAT_MAX_STAMPS: // Unused break; } - if (dest == NULL) - { + if (stat == NULL) AGB_ASSERT(0); - } - else if (++(*dest) > 999) - { - *dest = 999; - } + else if (++(*stat) > MAX_WONDER_CARD_STAT) + *stat = MAX_WONDER_CARD_STAT; } } -u16 mevent_081445C0(u32 command) +u16 MysteryGift_GetCardStat(u32 stat) { - switch (command) + switch (stat) { - case GET_CARD_BATTLES_WON_INTERNAL: + case CARD_STAT_BATTLES_WON: + { + struct WonderCard *card = &gSaveBlock1Ptr->mysteryGift.card; + if (card->type == CARD_TYPE_LINK_STAT) { - struct WonderCard *card = &gSaveBlock1Ptr->mysteryGift.card; - if (card->unk_08_0 == 2) - { - struct MEventBuffer_3430 *buffer = &gSaveBlock1Ptr->mysteryGift.unk_3430; - return buffer->unk_00; - } - break; + struct WonderCardMetadata *metadata = &gSaveBlock1Ptr->mysteryGift.cardMetadata; + return metadata->battlesWon; } - case 1: // Never occurs + break; + } + case CARD_STAT_BATTLES_LOST: + { + struct WonderCard *card = &gSaveBlock1Ptr->mysteryGift.card; + if (card->type == CARD_TYPE_LINK_STAT) { - struct WonderCard *card = &gSaveBlock1Ptr->mysteryGift.card; - if (card->unk_08_0 == 2) - { - struct MEventBuffer_3430 *buffer = &gSaveBlock1Ptr->mysteryGift.unk_3430; - return buffer->unk_02; - } - break; + struct WonderCardMetadata *metadata = &gSaveBlock1Ptr->mysteryGift.cardMetadata; + return metadata->battlesLost; } - case 2: // Never occurs + break; + } + case CARD_STAT_NUM_TRADES: + { + struct WonderCard *card = &gSaveBlock1Ptr->mysteryGift.card; + if (card->type == CARD_TYPE_LINK_STAT) { - struct WonderCard *card = &gSaveBlock1Ptr->mysteryGift.card; - if (card->unk_08_0 == 2) - { - struct MEventBuffer_3430 *buffer = &gSaveBlock1Ptr->mysteryGift.unk_3430; - return buffer->unk_04; - } - break; - } - case GET_NUM_STAMPS_INTERNAL: - { - struct WonderCard *card = &gSaveBlock1Ptr->mysteryGift.card; - if (card->unk_08_0 == 1) - return sub_801B4CC(); - break; - } - case GET_MAX_STAMPS_INTERNAL: - { - struct WonderCard *card = &gSaveBlock1Ptr->mysteryGift.card; - if (card->unk_08_0 == 1) - return card->unk_09; - break; + struct WonderCardMetadata *metadata = &gSaveBlock1Ptr->mysteryGift.cardMetadata; + return metadata->numTrades; } + break; + } + case CARD_STAT_NUM_STAMPS: + { + struct WonderCard *card = &gSaveBlock1Ptr->mysteryGift.card; + if (card->type == CARD_TYPE_STAMP) + return GetNumStampsInSavedCard(); + break; + } + case CARD_STAT_MAX_STAMPS: + { + struct WonderCard *card = &gSaveBlock1Ptr->mysteryGift.card; + if (card->type == CARD_TYPE_STAMP) + return card->maxStamps; + break; + } } AGB_ASSERT(0); return 0; } -void ResetReceivedWonderCardFlag(void) +void MysteryGift_DisableStats(void) { - gUnknown_02022C70 = FALSE; + sStatsEnabled = FALSE; } -bool32 MEventHandleReceivedWonderCard(u16 flagId) +bool32 MysteryGift_TryEnableStatsByFlagId(u16 flagId) { - gUnknown_02022C70 = FALSE; + sStatsEnabled = FALSE; if (flagId == 0) return FALSE; @@ -564,67 +577,80 @@ bool32 MEventHandleReceivedWonderCard(u16 flagId) if (gSaveBlock1Ptr->mysteryGift.card.flagId != flagId) return FALSE; - gUnknown_02022C70 = TRUE; + sStatsEnabled = TRUE; return TRUE; } -void RecordIdOfWonderCardSenderByEventType(u32 a0, u32 a1) +void TryIncrementMysteryGiftStat(u32 stat, u32 trainerId) { - if (gUnknown_02022C70) + if (sStatsEnabled) { - switch (a0) + switch (stat) { - case 2: - sub_801BA8C(2, a1, gSaveBlock1Ptr->mysteryGift.unk_344[1], 5); + case CARD_STAT_NUM_TRADES: + IncrementCardStatForNewTrainer(CARD_STAT_NUM_TRADES, + trainerId, + gSaveBlock1Ptr->mysteryGift.trainerIds[1], + ARRAY_COUNT(gSaveBlock1Ptr->mysteryGift.trainerIds[1])); break; - case 0: - sub_801BA8C(0, a1, gSaveBlock1Ptr->mysteryGift.unk_344[0], 5); + case CARD_STAT_BATTLES_WON: + IncrementCardStatForNewTrainer(CARD_STAT_BATTLES_WON, + trainerId, + gSaveBlock1Ptr->mysteryGift.trainerIds[0], + ARRAY_COUNT(gSaveBlock1Ptr->mysteryGift.trainerIds[0])); break; - case 1: - sub_801BA8C(1, a1, gSaveBlock1Ptr->mysteryGift.unk_344[0], 5); + case CARD_STAT_BATTLES_LOST: + IncrementCardStatForNewTrainer(CARD_STAT_BATTLES_LOST, + trainerId, + gSaveBlock1Ptr->mysteryGift.trainerIds[0], + ARRAY_COUNT(gSaveBlock1Ptr->mysteryGift.trainerIds[0])); break; default: AGB_ASSERT(0); + break; } } } -static void sub_801B9F8(void) +static void ClearSavedTrainerIds(void) { - CpuFill32(0, gSaveBlock1Ptr->mysteryGift.unk_344, sizeof(gSaveBlock1Ptr->mysteryGift.unk_344)); + CpuFill32(0, gSaveBlock1Ptr->mysteryGift.trainerIds, sizeof(gSaveBlock1Ptr->mysteryGift.trainerIds)); } -static bool32 sub_801BA24(u32 a0, u32 *a1, int size) +// Returns TRUE if it's a new trainer id, FALSE if an existing one. +// In either case the given trainerId is saved in element 0 +static bool32 RecordTrainerId(u32 trainerId, u32 *trainerIds, int size) { - int i; - int j; + int i, j; for (i = 0; i < size; i++) { - if (a1[i] == a0) + if (trainerIds[i] == trainerId) break; } if (i == size) { + // New trainer, shift array and insert new id at front for (j = size - 1; j > 0; j--) - a1[j] = a1[j - 1]; + trainerIds[j] = trainerIds[j - 1]; - a1[0] = a0; + trainerIds[0] = trainerId; return TRUE; } else { + // Existing trainer, shift back to old slot and move id to front for (j = i; j > 0; j--) - a1[j] = a1[j - 1]; + trainerIds[j] = trainerIds[j - 1]; - a1[0] = a0; + trainerIds[0] = trainerId; return FALSE; } } -static void sub_801BA8C(u32 a0, u32 a1, u32 *a2, int a3) +static void IncrementCardStatForNewTrainer(u32 stat, u32 trainerId, u32 *trainerIds, int size) { - if (sub_801BA24(a1, a2, a3)) - sub_801B7D8(a0); + if (RecordTrainerId(trainerId, trainerIds, size)) + IncrementCardStat(stat); } diff --git a/src/mevent_client.c b/src/mevent_client.c index 2bcab1e5a..e260f073f 100644 --- a/src/mevent_client.c +++ b/src/mevent_client.c @@ -15,8 +15,8 @@ enum { FUNC_SEND, FUNC_RUN, FUNC_WAIT, - FUNC_6, - FUNC_7, + FUNC_RUN_GIFT_SCRIPT, + FUNC_RUN_BUFF_SCRIPT, }; EWRAM_DATA static struct MysteryGiftClient * sClient = NULL; @@ -25,7 +25,7 @@ static void MysteryGiftClient_Init(struct MysteryGiftClient *, u32, u32); static u32 MysteryGiftClient_CallFunc(struct MysteryGiftClient *); static void MysteryGiftClient_Free(struct MysteryGiftClient *); -extern const struct MysteryGiftClientCmd gUnknown_082F2598[]; +extern const struct MysteryGiftClientCmd gMysteryGiftClientScript_Init[]; void MysteryGiftClient_Create(bool32 isWonderNews) { @@ -55,9 +55,9 @@ void MysteryGiftClient_AdvanceState(void) sClient->funcState++; } -void * mevent_client_get_buffer(void) +void * MysteryGiftClient_GetMsg(void) { - return sClient->buffer; + return sClient->msg; } void MysteryGiftClient_SetParam(u32 val) @@ -65,42 +65,42 @@ void MysteryGiftClient_SetParam(u32 val) sClient->param = val; } -static void MysteryGiftClient_Init(struct MysteryGiftClient * client, u32 sendPlayerNo, u32 recvPlayerNo) +static void MysteryGiftClient_Init(struct MysteryGiftClient * client, u32 sendPlayerId, u32 recvPlayerId) { - client->unk_00 = 0; + client->unused = 0; client->funcId = FUNC_INIT; client->funcState = 0; - client->sendBuffer = AllocZeroed(ME_SEND_BUF_SIZE); - client->recvBuffer = AllocZeroed(ME_SEND_BUF_SIZE); - client->cmdBuffer = AllocZeroed(ME_SEND_BUF_SIZE); - client->buffer = AllocZeroed(0x40); - MysteryGiftLink_Init(&client->link, sendPlayerNo, recvPlayerNo); + client->sendBuffer = AllocZeroed(MG_LINK_BUFFER_SIZE); + client->recvBuffer = AllocZeroed(MG_LINK_BUFFER_SIZE); + client->script = AllocZeroed(MG_LINK_BUFFER_SIZE); + client->msg = AllocZeroed(CLIENT_MAX_MSG_SIZE); + MysteryGiftLink_Init(&client->link, sendPlayerId, recvPlayerId); } static void MysteryGiftClient_Free(struct MysteryGiftClient * client) { Free(client->sendBuffer); Free(client->recvBuffer); - Free(client->cmdBuffer); - Free(client->buffer); + Free(client->script); + Free(client->msg); } static void MysteryGiftClient_CopyRecvScript(struct MysteryGiftClient * client) { - memcpy(client->cmdBuffer, client->recvBuffer, ME_SEND_BUF_SIZE); + memcpy(client->script, client->recvBuffer, MG_LINK_BUFFER_SIZE); client->cmdidx = 0; } -static void MysteryGiftClient_InitSend(struct MysteryGiftClient * client, u32 ident, u32 word) +static void MysteryGiftClient_InitSendWord(struct MysteryGiftClient * client, u32 ident, u32 word) { - CpuFill32(0, client->sendBuffer, ME_SEND_BUF_SIZE); + CpuFill32(0, client->sendBuffer, MG_LINK_BUFFER_SIZE); *(u32 *)client->sendBuffer = word; - MysteryGiftLink_InitSend(&client->link, ident, client->sendBuffer, sizeof(u32)); + MysteryGiftLink_InitSend(&client->link, ident, client->sendBuffer, sizeof(word)); } static u32 Client_Init(struct MysteryGiftClient * client) { - memcpy(client->cmdBuffer, gUnknown_082F2598, ME_SEND_BUF_SIZE); + memcpy(client->script, gMysteryGiftClientScript_Init, MG_LINK_BUFFER_SIZE); client->cmdidx = 0; client->funcId = FUNC_RUN; client->funcState = 0; @@ -120,7 +120,7 @@ static u32 Client_Recv(struct MysteryGiftClient * client) client->funcId = FUNC_RUN; client->funcState = 0; } - return CLI_RET_1; + return CLI_RET_ACTIVE; } static u32 Client_Send(struct MysteryGiftClient * client) @@ -130,13 +130,13 @@ static u32 Client_Send(struct MysteryGiftClient * client) client->funcId = FUNC_RUN; client->funcState = 0; } - return CLI_RET_1; + return CLI_RET_ACTIVE; } static u32 Client_Run(struct MysteryGiftClient * client) { // process command - struct MysteryGiftClientCmd * cmd = &client->cmdBuffer[client->cmdidx]; + struct MysteryGiftClientCmd * cmd = &client->script[client->cmdidx]; client->cmdidx++; switch (cmd->instr) { @@ -158,13 +158,13 @@ static u32 Client_Run(struct MysteryGiftClient * client) client->funcId = FUNC_SEND; client->funcState = 0; break; - case CLI_20: - MysteryGiftLink_InitSend(&client->link, 0x14, client->sendBuffer, 0); + case CLI_SEND_READY_END: + MysteryGiftLink_InitSend(&client->link, MG_LINKID_READY_END, client->sendBuffer, 0); client->funcId = FUNC_SEND; client->funcState = 0; break; case CLI_SEND_STAT: - MysteryGiftClient_InitSend(client, 0x12, GetGameStat(cmd->parameter)); + MysteryGiftClient_InitSendWord(client, MG_LINKID_GAME_STAT, GetGameStat(cmd->parameter)); client->funcId = FUNC_SEND; client->funcState = 0; break; @@ -179,67 +179,71 @@ static u32 Client_Run(struct MysteryGiftClient * client) case CLI_COPY_RECV: MysteryGiftClient_CopyRecvScript(client); break; - case CLI_5: - memcpy(client->buffer, client->recvBuffer, 0x40); + case CLI_YES_NO: + memcpy(client->msg, client->recvBuffer, CLIENT_MAX_MSG_SIZE); client->funcId = FUNC_WAIT; client->funcState = 0; - return CLI_RET_2; - case CLI_11: - memcpy(client->buffer, client->recvBuffer, 0x40); + return CLI_RET_YES_NO; + case CLI_PRINT_MSG: + memcpy(client->msg, client->recvBuffer, CLIENT_MAX_MSG_SIZE); client->funcId = FUNC_WAIT; client->funcState = 0; - return CLI_RET_3; - case CLI_12: - memcpy(client->buffer, client->recvBuffer, 0x40); + return CLI_RET_PRINT_MSG; + case CLI_COPY_MSG: + memcpy(client->msg, client->recvBuffer, CLIENT_MAX_MSG_SIZE); client->funcId = FUNC_WAIT; client->funcState = 0; - return CLI_RET_5; + return CLI_RET_COPY_MSG; case CLI_ASK_TOSS: client->funcId = FUNC_WAIT; client->funcState = 0; return CLI_RET_ASK_TOSS; - case CLI_8: - sub_801B580(client->sendBuffer, client->isWonderNews); - MysteryGiftLink_InitSend(&client->link, 0x11, client->sendBuffer, sizeof(struct MEventStruct_Unk1442CC)); + case CLI_LOAD_GAME_DATA: + MysteryGift_LoadLinkGameData(client->sendBuffer, client->isWonderNews); + MysteryGiftLink_InitSend(&client->link, MG_LINKID_GAME_DATA, client->sendBuffer, sizeof(struct MysteryGiftLinkGameData)); break; case CLI_LOAD_TOSS_RESPONSE: // param here is set by MG_STATE_LINK_ASK_TOSS or MG_STATE_LINK_ASK_TOSS_UNRECEIVED - MysteryGiftClient_InitSend(client, 0x13, client->param); + MysteryGiftClient_InitSendWord(client, MG_LINKID_RESPONSE, client->param); break; - case CLI_10: + case CLI_SAVE_CARD: SaveWonderCard(client->recvBuffer); break; - case CLI_9: - if (!sub_801B1A4(client->recvBuffer)) + case CLI_SAVE_NEWS: + if (!IsWonderNewsSameAsSaved(client->recvBuffer)) { SaveWonderNews(client->recvBuffer); - MysteryGiftClient_InitSend(client, 0x13, 0); + MysteryGiftClient_InitSendWord(client, MG_LINKID_RESPONSE, FALSE); } else - MysteryGiftClient_InitSend(client, 0x13, 1); + { + // Wonder News has already been saved (or is invalid). + // Prepare a signal to indicate it was not saved. + MysteryGiftClient_InitSendWord(client, MG_LINKID_RESPONSE, TRUE); + } break; - case CLI_15: - client->funcId = FUNC_6; + case CLI_RUN_GIFT_SCRIPT: + client->funcId = FUNC_RUN_GIFT_SCRIPT; client->funcState = 0; break; - case CLI_16: - sub_801B508(client->recvBuffer); + case CLI_SAVE_STAMP: + MysteryGift_TrySaveStamp(client->recvBuffer); break; - case CLI_17: + case CLI_SAVE_RAM_SCRIPT: InitRamScript_NoObjectEvent(client->recvBuffer, 1000); break; case CLI_RECV_EREADER_TRAINER: memcpy(&gSaveBlock2Ptr->frontier.ereaderTrainer, client->recvBuffer, sizeof(gSaveBlock2Ptr->frontier.ereaderTrainer)); ValidateEReaderTrainer(); break; - case CLI_21: - memcpy(gDecompressionBuffer, client->recvBuffer, ME_SEND_BUF_SIZE); - client->funcId = FUNC_7; + case CLI_RUN_BUFFER_SCRIPT: + memcpy(gDecompressionBuffer, client->recvBuffer, MG_LINK_BUFFER_SIZE); + client->funcId = FUNC_RUN_BUFF_SCRIPT; client->funcState = 0; break; } - return CLI_RET_1; + return CLI_RET_ACTIVE; } static u32 Client_Wait(struct MysteryGiftClient * client) @@ -249,10 +253,10 @@ static u32 Client_Wait(struct MysteryGiftClient * client) client->funcId = FUNC_RUN; client->funcState = 0; } - return CLI_RET_1; + return CLI_RET_ACTIVE; } -static u32 Client_6(struct MysteryGiftClient * client) +static u32 Client_RunGiftScript(struct MysteryGiftClient * client) { switch (client->funcState) { @@ -268,10 +272,10 @@ static u32 Client_6(struct MysteryGiftClient * client) } break; } - return CLI_RET_1; + return CLI_RET_ACTIVE; } -static u32 Client_7(struct MysteryGiftClient * client) +static u32 Client_RunBufferScript(struct MysteryGiftClient * client) { // exec arbitrary code u32 (*func)(u32 *, struct SaveBlock2 *, struct SaveBlock1 *) = (void *)gDecompressionBuffer; @@ -280,7 +284,7 @@ static u32 Client_7(struct MysteryGiftClient * client) client->funcId = FUNC_RUN; client->funcState = 0; } - return CLI_RET_1; + return CLI_RET_ACTIVE; } static u32 MysteryGiftClient_CallFunc(struct MysteryGiftClient * client) @@ -292,8 +296,8 @@ static u32 MysteryGiftClient_CallFunc(struct MysteryGiftClient * client) [FUNC_SEND] = Client_Send, [FUNC_RUN] = Client_Run, [FUNC_WAIT] = Client_Wait, - [FUNC_6] = Client_6, - [FUNC_7] = Client_7 + [FUNC_RUN_GIFT_SCRIPT] = Client_RunGiftScript, + [FUNC_RUN_BUFF_SCRIPT] = Client_RunBufferScript }; return funcs[client->funcId](client); } diff --git a/src/mevent_news.c b/src/mevent_news.c index 13d50bb0d..0fbb9452d 100644 --- a/src/mevent_news.c +++ b/src/mevent_news.c @@ -4,51 +4,51 @@ #include "event_data.h" #include "mevent_news.h" -static u32 sub_801DCAC(struct MysteryEventStruct *); -static void sub_801DD10(struct MysteryEventStruct *); -static u32 sub_801DD44(struct MysteryEventStruct *); -static void sub_801DCD8(struct MysteryEventStruct *); -static void sub_801DCCC(struct MysteryEventStruct *); +static u32 sub_801DCAC(struct WonderNewsMetadata *); +static void sub_801DD10(struct WonderNewsMetadata *); +static u32 sub_801DD44(struct WonderNewsMetadata *); +static void sub_801DCD8(struct WonderNewsMetadata *); +static void sub_801DCCC(struct WonderNewsMetadata *); -void GenerateRandomNews(u32 a0) +void GenerateRandomWonderNews(u32 a0) { - struct MysteryEventStruct *r5 = sub_801B044(); + struct WonderNewsMetadata *data = GetSavedWonderNewsMetadata(); - r5->unk_0_0 = a0; + data->unk_0_0 = a0; switch (a0) { case 0: break; case 1: case 2: - r5->unk_1 = (Random() % 15) + 16; + data->unk_1 = (Random() % 15) + 16; break; case 3: - r5->unk_1 = (Random() % 15) + 1; + data->unk_1 = (Random() % 15) + 1; break; } } -void sub_801DBC0(void) +void InitSavedWonderNews(void) { - struct MysteryEventStruct *r5 = sub_801B044(); + struct WonderNewsMetadata *data = GetSavedWonderNewsMetadata(); - r5->unk_0_0 = 0; - r5->unk_0_2 = 0; - r5->unk_0_5 = 0; - r5->unk_1 = 0; + data->unk_0_0 = 0; + data->unk_0_2 = 0; + data->unk_0_5 = 0; + data->unk_1 = 0; VarSet(VAR_0x402E, 0); } void sub_801DBDC(void) { u16 *r4 = GetVarPointer(VAR_0x402E); - struct MysteryEventStruct *r2 = sub_801B044(); - struct MysteryEventStruct r0 = *r2; + struct WonderNewsMetadata *data = GetSavedWonderNewsMetadata(); + struct WonderNewsMetadata r0 = *data; if ((u8)r0.unk_0_5 > 4 && ++(*r4) > 0x1f3) { - r2->unk_0_5 = 0; + data->unk_0_5 = 0; *r4 = 0; } } @@ -57,33 +57,33 @@ void sub_801DBDC(void) u16 sub_801DC20(void) { u16 *r6 = &gSpecialVar_Result; - struct MysteryEventStruct *r4 = sub_801B044(); + struct WonderNewsMetadata *data = GetSavedWonderNewsMetadata(); u16 r5; if (!IsMysteryEventEnabled() || !ValidateSavedWonderNews()) return 0; - r5 = sub_801DD44(r4); + r5 = sub_801DD44(data); switch (r5) { case 0: break; case 1: - *r6 = sub_801DCAC(r4); + *r6 = sub_801DCAC(data); break; case 2: - *r6 = sub_801DCAC(r4); + *r6 = sub_801DCAC(data); break; case 3: break; case 4: - *r6 = sub_801DCAC(r4); - sub_801DCD8(r4); + *r6 = sub_801DCAC(data); + sub_801DCD8(data); break; case 5: - *r6 = sub_801DCAC(r4); - sub_801DCCC(r4); + *r6 = sub_801DCAC(data); + sub_801DCCC(data); break; case 6: break; @@ -92,43 +92,43 @@ u16 sub_801DC20(void) return r5; } -static u32 sub_801DCAC(struct MysteryEventStruct *a0) +static u32 sub_801DCAC(struct WonderNewsMetadata *data) { u32 r4; - a0->unk_0_0 = 0; - r4 = a0->unk_1 + 0x84; - a0->unk_1 = 0; - sub_801DD10(a0); + data->unk_0_0 = 0; + r4 = data->unk_1 + 0x84; + data->unk_1 = 0; + sub_801DD10(data); return r4; } -static void sub_801DCCC(struct MysteryEventStruct *a0) +static void sub_801DCCC(struct WonderNewsMetadata *data) { - a0->unk_0_2 = 0; + data->unk_0_2 = 0; } -static void sub_801DCD8(struct MysteryEventStruct *a0) +static void sub_801DCD8(struct WonderNewsMetadata *data) { - a0->unk_0_2++; - if ((u8)a0->unk_0_2 > 4) - a0->unk_0_2 = 4; + data->unk_0_2++; + if ((u8)data->unk_0_2 > 4) + data->unk_0_2 = 4; } -static void sub_801DD10(struct MysteryEventStruct *a0) +static void sub_801DD10(struct WonderNewsMetadata *data) { - a0->unk_0_5++; - if ((u8)a0->unk_0_5 > 5) - a0->unk_0_5 = 5; + data->unk_0_5++; + if ((u8)data->unk_0_5 > 5) + data->unk_0_5 = 5; } -static u32 sub_801DD44(struct MysteryEventStruct *a0) +static u32 sub_801DD44(struct WonderNewsMetadata *data) { - struct MysteryEventStruct r0; - if ((u8)a0->unk_0_5 == 5) + struct WonderNewsMetadata r0; + if ((u8)data->unk_0_5 == 5) return 6; - r0 = *a0; + r0 = *data; switch (r0.unk_0_0) { case 0: diff --git a/src/mevent_scripts.c b/src/mevent_scripts.c index ddeca8f41..23e0d97a5 100644 --- a/src/mevent_scripts.c +++ b/src/mevent_scripts.c @@ -1,195 +1,217 @@ #include "global.h" #include "mevent_client.h" #include "mevent_server.h" +#include "mevent.h" -const u8 gText_CanceledReadingCard[] = _("Canceled reading\nthe Card."); +static const u8 sText_CanceledReadingCard[] = _("Canceled reading\nthe Card."); -const struct MysteryGiftClientCmd gUnknown_082F2598[] = { - {.instr = CLI_RECV, .parameter = 16}, - {.instr = CLI_COPY_RECV} +//================== +// Client scripts +//================== + +const struct MysteryGiftClientCmd gMysteryGiftClientScript_Init[] = { + {CLI_RECV, MG_LINKID_CLIENT_SCRIPT}, + {CLI_COPY_RECV} }; -const struct MysteryGiftClientCmd gUnknown_082F25A8[] = { - {.instr = CLI_8}, - {.instr = CLI_SEND_LOADED}, - {.instr = CLI_RECV, .parameter = 16}, - {.instr = CLI_COPY_RECV} +static const struct MysteryGiftClientCmd sClientScript_SendGameData[] = { + {CLI_LOAD_GAME_DATA}, + {CLI_SEND_LOADED}, + {CLI_RECV, MG_LINKID_CLIENT_SCRIPT}, + {CLI_COPY_RECV} }; -const struct MysteryGiftClientCmd gUnknown_082F25C8[] = { - {.instr = CLI_20}, - {.instr = CLI_RETURN, .parameter = 10} +static const struct MysteryGiftClientCmd sClientScript_CantAccept[] = { + {CLI_SEND_READY_END}, + {CLI_RETURN, CLI_MSG_CANT_ACCEPT} }; -const struct MysteryGiftClientCmd gUnknown_082F25D8[] = { - {.instr = CLI_20}, - {.instr = CLI_RETURN, .parameter = 11} +static const struct MysteryGiftClientCmd sClientScript_CommError[] = { + {CLI_SEND_READY_END}, + {CLI_RETURN, CLI_MSG_COMM_ERROR} }; -const struct MysteryGiftClientCmd gUnknown_082F25E8[] = { - {.instr = CLI_20}, - {.instr = CLI_RETURN, .parameter = 0} +static const struct MysteryGiftClientCmd sClientScript_NothingSent[] = { + {CLI_SEND_READY_END}, + {CLI_RETURN, CLI_MSG_NOTHING_SENT} }; -const struct MysteryGiftClientCmd gUnknown_082F25F8[] = { - {.instr = CLI_RECV, .parameter = 22}, - {.instr = CLI_10}, - {.instr = CLI_RECV, .parameter = 25}, - {.instr = CLI_17}, - {.instr = CLI_20}, - {.instr = CLI_RETURN, .parameter = 2} +static const struct MysteryGiftClientCmd sClientScript_SaveCard[] = { + {CLI_RECV, MG_LINKID_CARD}, + {CLI_SAVE_CARD}, + {CLI_RECV, MG_LINKID_RAM_SCRIPT}, + {CLI_SAVE_RAM_SCRIPT}, + {CLI_SEND_READY_END}, + {CLI_RETURN, CLI_MSG_CARD_RECEIVED} }; -const struct MysteryGiftClientCmd gUnknown_082F2628[] = { - {.instr = CLI_RECV, .parameter = 23}, - {.instr = CLI_9}, - {.instr = CLI_SEND_LOADED}, - {.instr = CLI_RECV, .parameter = 16}, - {.instr = CLI_COPY_RECV} +static const struct MysteryGiftClientCmd sClientScript_SaveNews[] = { + {CLI_RECV, MG_LINKID_NEWS}, + {CLI_SAVE_NEWS}, + {CLI_SEND_LOADED}, // Send whether or not the News was saved (read by sServerScript_SendNews) + {CLI_RECV, MG_LINKID_CLIENT_SCRIPT}, + {CLI_COPY_RECV} }; -const struct MysteryGiftClientCmd gUnknown_082F2650[] = { - {.instr = CLI_20}, - {.instr = CLI_RETURN, .parameter = 7} +static const struct MysteryGiftClientCmd sClientScript_HadNews[] = { + {CLI_SEND_READY_END}, + {CLI_RETURN, CLI_MSG_HAD_NEWS} }; -const struct MysteryGiftClientCmd gUnknown_082F2660[] = { - {.instr = CLI_20}, - {.instr = CLI_RETURN, .parameter = 3} +static const struct MysteryGiftClientCmd sClientScript_NewsReceived[] = { + {CLI_SEND_READY_END}, + {CLI_RETURN, CLI_MSG_NEWS_RECEIVED} }; -const struct MysteryGiftClientCmd gUnknown_082F2670[] = { - {.instr = CLI_ASK_TOSS}, - {.instr = CLI_LOAD_TOSS_RESPONSE}, - {.instr = CLI_SEND_LOADED}, - {.instr = CLI_RECV, .parameter = 16}, - {.instr = CLI_COPY_RECV} +static const struct MysteryGiftClientCmd sClientScript_AskToss[] = { + {CLI_ASK_TOSS}, + {CLI_LOAD_TOSS_RESPONSE}, + {CLI_SEND_LOADED}, + {CLI_RECV, MG_LINKID_CLIENT_SCRIPT}, + {CLI_COPY_RECV} }; -const struct MysteryGiftClientCmd gUnknown_082F2698[] = { - {.instr = CLI_20}, - {.instr = CLI_RETURN, .parameter = 9} +static const struct MysteryGiftClientCmd sClientScript_Canceled[] = { + {CLI_SEND_READY_END}, + {CLI_RETURN, CLI_MSG_COMM_CANCELED} }; -const struct MysteryGiftClientCmd gUnknown_082F26A8[] = { - {.instr = CLI_20}, - {.instr = CLI_RETURN, .parameter = 5} +static const struct MysteryGiftClientCmd sClientScript_HadCard[] = { + {CLI_SEND_READY_END}, + {CLI_RETURN, CLI_MSG_HAD_CARD} }; -const struct MysteryGiftClientCmd gUnknown_082F26B8[] = { - {.instr = CLI_RECV, .parameter = 21}, - {.instr = CLI_12}, - {.instr = CLI_20}, - {.instr = CLI_RETURN, .parameter = 14} +static const struct MysteryGiftClientCmd sClientScript_DynamicError[] = { + {CLI_RECV, MG_LINKID_DYNAMIC_MSG}, + {CLI_COPY_MSG}, + {CLI_SEND_READY_END}, + {CLI_RETURN, CLI_MSG_BUFFER_FAILURE} }; -// Unused -const struct MysteryGiftClientCmd gUnknown_082F26B8_1[] = { - {.instr = CLI_RECV, .parameter = 21}, - {.instr = CLI_12}, - {.instr = CLI_20}, - {.instr = CLI_RETURN, .parameter = 13} +static const struct MysteryGiftClientCmd sClientScript_DynamicSuccess[] = { + {CLI_RECV, MG_LINKID_DYNAMIC_MSG}, + {CLI_COPY_MSG}, + {CLI_SEND_READY_END}, + {CLI_RETURN, CLI_MSG_BUFFER_SUCCESS} }; -const struct mevent_cmd gUnknown_082F26F8[] = { - {.instr = 18, .flag = sizeof(gUnknown_082F25C8), .parameter = gUnknown_082F25C8}, - {.instr = 1}, - {.instr = 2, .flag = 0x14}, - {.instr = 0, .flag = 0x0a}, - {.instr = 18, .flag = sizeof(gUnknown_082F25D8), .parameter = gUnknown_082F25D8}, - {.instr = 1}, - {.instr = 2, .flag = 0x14}, - {.instr = 0, .flag = 0x0b}, - {.instr = 18, .flag = sizeof(gUnknown_082F2698), .parameter = gUnknown_082F2698}, - {.instr = 1}, - {.instr = 2, .flag = 0x14}, - {.instr = 0, .flag = 0x09} + +//================== +// Server scripts +//================== + +// Create arguments for SVR_LOAD_CLIENT_SCRIPT or SVR_LOAD_MSG +// (a script/text size and pointer to send to the client) +#define PTR_ARG(pointer) .parameter = sizeof(pointer), .ptr = pointer + +static const struct MysteryGiftServerCmd sServerScript_CantSend[] = { + {SVR_LOAD_CLIENT_SCRIPT, PTR_ARG(sClientScript_CantAccept)}, + {SVR_SEND}, + {SVR_RECV, MG_LINKID_READY_END}, + {SVR_RETURN, SVR_MSG_CANT_SEND_GIFT_1} }; -const struct mevent_cmd gUnknown_082F2788[] = { - {.instr = 18, .flag = sizeof(gUnknown_082F26B8), .parameter = gUnknown_082F26B8}, - {.instr = 1}, - {.instr = 20, .flag = 0x1b, .parameter = gText_CanceledReadingCard}, - {.instr = 1}, - {.instr = 2, .flag = 0x14}, - {.instr = 0, .flag = 0x09} +static const struct MysteryGiftServerCmd sServerScript_CommError[] = { + {SVR_LOAD_CLIENT_SCRIPT, PTR_ARG(sClientScript_CommError)}, + {SVR_SEND}, + {SVR_RECV, MG_LINKID_READY_END}, + {SVR_RETURN, SVR_MSG_COMM_ERROR} }; -const struct mevent_cmd gUnknown_082F27D0[] = { - {.instr = 18, .flag = sizeof(gUnknown_082F2650), .parameter = gUnknown_082F2650}, - {.instr = 1}, - {.instr = 2, .flag = 0x14}, - {.instr = 0, .flag = 0x07} +static const struct MysteryGiftServerCmd sServerScript_ClientCanceledNews[] = { + {SVR_LOAD_CLIENT_SCRIPT, PTR_ARG(sClientScript_Canceled)}, + {SVR_SEND}, + {SVR_RECV, MG_LINKID_READY_END}, + {SVR_RETURN, SVR_MSG_CLIENT_CANCELED} }; -const struct mevent_cmd gUnknown_082F2800[] = { - {.instr = 18, .flag = sizeof(gUnknown_082F2628), .parameter = gUnknown_082F2628}, - {.instr = 1}, - {.instr = 14}, - {.instr = 1}, - {.instr = 2, .flag = 0x13}, - {.instr = 8}, - {.instr = 4, .flag = 0x01, .parameter = gUnknown_082F27D0}, - {.instr = 18, .flag = sizeof(gUnknown_082F2660), .parameter = gUnknown_082F2660}, - {.instr = 1}, - {.instr = 2, .flag = 0x14}, - {.instr = 0, .flag = 0x03} +static const struct MysteryGiftServerCmd sServerScript_ClientCanceledCard[] = { + {SVR_LOAD_CLIENT_SCRIPT, PTR_ARG(sClientScript_DynamicError)}, + {SVR_SEND}, + {SVR_LOAD_MSG, PTR_ARG(sText_CanceledReadingCard)}, + {SVR_SEND}, + {SVR_RECV, MG_LINKID_READY_END}, + {SVR_RETURN, SVR_MSG_CLIENT_CANCELED} }; -const struct mevent_cmd gUnknown_082F2884[] = { - {.instr = 18, .flag = sizeof(gUnknown_082F25F8), .parameter = gUnknown_082F25F8}, - {.instr = 1}, - {.instr = 13}, - {.instr = 1}, - {.instr = 15}, - {.instr = 1}, - {.instr = 2, .flag = 0x14}, - {.instr = 0, .flag = 0x02} +static const struct MysteryGiftServerCmd sServerScript_HasNews[] = { + {SVR_LOAD_CLIENT_SCRIPT, PTR_ARG(sClientScript_HadNews)}, + {SVR_SEND}, + {SVR_RECV, MG_LINKID_READY_END}, + {SVR_RETURN, SVR_MSG_HAS_NEWS} }; -const struct mevent_cmd gUnknown_082F28E4[] = { - {.instr = 18, .flag = sizeof(gUnknown_082F2670), .parameter = gUnknown_082F2670}, - {.instr = 1}, - {.instr = 2, .flag = 0x13}, - {.instr = 8}, - {.instr = 4, .parameter = gUnknown_082F2884}, - {.instr = 3, .parameter = gUnknown_082F2788} +static const struct MysteryGiftServerCmd sServerScript_SendNews[] = { + {SVR_LOAD_CLIENT_SCRIPT, PTR_ARG(sClientScript_SaveNews)}, + {SVR_SEND}, + {SVR_LOAD_NEWS}, + {SVR_SEND}, + {SVR_RECV, MG_LINKID_RESPONSE}, + {SVR_READ_RESPONSE}, + {SVR_GOTO_IF_EQ, TRUE, sServerScript_HasNews}, // Wonder News was not saved + {SVR_LOAD_CLIENT_SCRIPT, PTR_ARG(sClientScript_NewsReceived)}, + {SVR_SEND}, + {SVR_RECV, MG_LINKID_READY_END}, + {SVR_RETURN, SVR_MSG_NEWS_SENT} }; -const struct mevent_cmd gUnknown_082F292C[] = { - {.instr = 18, .flag = sizeof(gUnknown_082F26A8), .parameter = gUnknown_082F26A8}, - {.instr = 1}, - {.instr = 2, .flag = 0x14}, - {.instr = 0, .flag = 0x05}, - {.instr = 18, .flag = sizeof(gUnknown_082F25E8), .parameter = gUnknown_082F25E8}, - {.instr = 1}, - {.instr = 2, .flag = 0x14}, - {.instr = 0} +static const struct MysteryGiftServerCmd sServerScript_SendCard[] = { + {SVR_LOAD_CLIENT_SCRIPT, PTR_ARG(sClientScript_SaveCard)}, + {SVR_SEND}, + {SVR_LOAD_CARD}, + {SVR_SEND}, + {SVR_LOAD_RAM_SCRIPT}, + {SVR_SEND}, + {SVR_RECV, MG_LINKID_READY_END}, + {SVR_RETURN, SVR_MSG_CARD_SENT} }; -const struct mevent_cmd s_mevent_wonder_news[] = { - {.instr = 27}, - {.instr = 18, .flag = sizeof(gUnknown_082F25A8), .parameter = gUnknown_082F25A8}, - {.instr = 1}, - {.instr = 2, .flag = 0x11}, - {.instr = 5}, - {.instr = 30}, - {.instr = 4, .parameter = gUnknown_082F26F8}, - {.instr = 3, .parameter = gUnknown_082F2800} +static const struct MysteryGiftServerCmd sServerScript_TossPrompt[] = { + {SVR_LOAD_CLIENT_SCRIPT, PTR_ARG(sClientScript_AskToss)}, + {SVR_SEND}, + {SVR_RECV, MG_LINKID_RESPONSE}, + {SVR_READ_RESPONSE}, + {SVR_GOTO_IF_EQ, FALSE, sServerScript_SendCard}, // Tossed old card, send new one + {SVR_GOTO, .ptr = sServerScript_ClientCanceledCard} // Kept old card, cancel new one }; -const struct mevent_cmd s_mevent_wonder_card[] = { - {.instr = 26}, - {.instr = 28}, - {.instr = 18, .flag = sizeof(gUnknown_082F25A8), .parameter = gUnknown_082F25A8}, - {.instr = 1}, - {.instr = 2, .flag = 0x11}, - {.instr = 5}, - {.instr = 6}, - {.instr = 4, .parameter = gUnknown_082F26F8}, - {.instr = 7}, - {.instr = 4, .flag = 0x02, .parameter = gUnknown_082F28E4}, - {.instr = 4, .parameter = gUnknown_082F2884}, - {.instr = 3, .parameter = gUnknown_082F292C} +static const struct MysteryGiftServerCmd sServerScript_HasCard[] = { + {SVR_LOAD_CLIENT_SCRIPT, PTR_ARG(sClientScript_HadCard)}, + {SVR_SEND}, + {SVR_RECV, MG_LINKID_READY_END}, + {SVR_RETURN, SVR_MSG_HAS_CARD} +}; + +static const struct MysteryGiftServerCmd sServerScript_NothingSent[] = { + {SVR_LOAD_CLIENT_SCRIPT, PTR_ARG(sClientScript_NothingSent)}, + {SVR_SEND}, + {SVR_RECV, MG_LINKID_READY_END}, + {SVR_RETURN, SVR_MSG_NOTHING_SENT} +}; + +const struct MysteryGiftServerCmd gMysteryGiftServerScript_SendWonderNews[] = { + {SVR_COPY_SAVED_NEWS}, + {SVR_LOAD_CLIENT_SCRIPT, PTR_ARG(sClientScript_SendGameData)}, + {SVR_SEND}, + {SVR_RECV, MG_LINKID_GAME_DATA}, + {SVR_COPY_GAME_DATA}, + {SVR_CHECK_GAME_DATA_NEWS}, + {SVR_GOTO_IF_EQ, FALSE, sServerScript_CantSend}, + {SVR_GOTO, .ptr = sServerScript_SendNews} +}; + +const struct MysteryGiftServerCmd gMysteryGiftServerScript_SendWonderCard[] = { + {SVR_COPY_SAVED_CARD}, + {SVR_COPY_SAVED_RAM_SCRIPT}, + {SVR_LOAD_CLIENT_SCRIPT, PTR_ARG(sClientScript_SendGameData)}, + {SVR_SEND}, + {SVR_RECV, MG_LINKID_GAME_DATA}, + {SVR_COPY_GAME_DATA}, + {SVR_CHECK_GAME_DATA_CARD}, + {SVR_GOTO_IF_EQ, FALSE, sServerScript_CantSend}, + {SVR_CHECK_EXISTING_CARD}, + {SVR_GOTO_IF_EQ, HAS_DIFF_CARD, sServerScript_TossPrompt}, + {SVR_GOTO_IF_EQ, HAS_NO_CARD, sServerScript_SendCard}, + {SVR_GOTO, .ptr = sServerScript_HasCard} // HAS_SAME_CARD }; diff --git a/src/mevent_server.c b/src/mevent_server.c index 1bae6a3e1..5313e02f7 100644 --- a/src/mevent_server.c +++ b/src/mevent_server.c @@ -5,291 +5,287 @@ #include "mevent_server.h" #include "mevent_server_helpers.h" -EWRAM_DATA struct mevent_srv_common * s_mevent_srv_common_ptr = NULL; +enum { + FUNC_INIT, + FUNC_DONE, + FUNC_RECV, + FUNC_SEND, + FUNC_RUN, +}; -static void mevent_srv_init_common(struct mevent_srv_common *, const void *, u32, u32); -static void mevent_srv_free_resources(struct mevent_srv_common *); -static u32 mevent_srv_exec_common(struct mevent_srv_common *); +EWRAM_DATA static struct MysteryGiftServer * sServer = NULL; -extern const struct mevent_cmd s_mevent_wonder_news[]; -extern const struct mevent_cmd s_mevent_wonder_card[]; +static void MysteryGiftServer_Init(struct MysteryGiftServer *, const void *, u32, u32); +static void MysteryGiftServer_Free(struct MysteryGiftServer *); +static u32 MysteryGiftServer_CallFunc(struct MysteryGiftServer *); -void mevent_srv_init_wnews(void) +extern const struct MysteryGiftServerCmd gMysteryGiftServerScript_SendWonderNews[]; +extern const struct MysteryGiftServerCmd gMysteryGiftServerScript_SendWonderCard[]; + +void MysterGiftServer_CreateForNews(void) { - s_mevent_srv_common_ptr = AllocZeroed(sizeof(struct mevent_srv_common)); - mevent_srv_init_common(s_mevent_srv_common_ptr, s_mevent_wonder_news, 0, 1); + sServer = AllocZeroed(sizeof(*sServer)); + MysteryGiftServer_Init(sServer, gMysteryGiftServerScript_SendWonderNews, 0, 1); } -void mevent_srv_new_wcard(void) +void MysterGiftServer_CreateForCard(void) { - s_mevent_srv_common_ptr = AllocZeroed(sizeof(struct mevent_srv_common)); - mevent_srv_init_common(s_mevent_srv_common_ptr, s_mevent_wonder_card, 0, 1); + sServer = AllocZeroed(sizeof(*sServer)); + MysteryGiftServer_Init(sServer, gMysteryGiftServerScript_SendWonderCard, 0, 1); } -u32 mevent_srv_common_do_exec(u16 * a0) +u32 MysterGiftServer_Run(u16 * endVal) { u32 result; - if (s_mevent_srv_common_ptr == NULL) - return 3; - result = mevent_srv_exec_common(s_mevent_srv_common_ptr); - if (result == 3) + if (sServer == NULL) + return SVR_RET_END; + result = MysteryGiftServer_CallFunc(sServer); + if (result == SVR_RET_END) { - *a0 = s_mevent_srv_common_ptr->param; - mevent_srv_free_resources(s_mevent_srv_common_ptr); - Free(s_mevent_srv_common_ptr); - s_mevent_srv_common_ptr = NULL; + *endVal = sServer->param; + MysteryGiftServer_Free(sServer); + Free(sServer); + sServer = NULL; } return result; } -static void mevent_srv_init_common(struct mevent_srv_common * svr, const void * cmdBuffer, u32 sendPlayerNo, u32 recvPlayerNo) +static void MysteryGiftServer_Init(struct MysteryGiftServer * svr, const void * script, u32 sendPlayerId, u32 recvPlayerId) { - svr->unk_00 = 0; - svr->mainseqno = 0; - svr->wonder_card = AllocZeroed(sizeof(struct WonderCard)); - svr->wonder_news = AllocZeroed(sizeof(struct WonderNews)); - svr->recvBuffer = AllocZeroed(ME_SEND_BUF_SIZE); - svr->mevent_unk1442cc = AllocZeroed(sizeof(struct MEventStruct_Unk1442CC)); - svr->cmdBuffer = cmdBuffer; + svr->unused = 0; + svr->funcId = FUNC_INIT; + svr->card = AllocZeroed(sizeof(*svr->card)); + svr->news = AllocZeroed(sizeof(*svr->news)); + svr->recvBuffer = AllocZeroed(MG_LINK_BUFFER_SIZE); + svr->linkGameData = AllocZeroed(sizeof(*svr->linkGameData)); + svr->script = script; svr->cmdidx = 0; - MysteryGiftLink_Init(&svr->manager, sendPlayerNo, recvPlayerNo); + MysteryGiftLink_Init(&svr->link, sendPlayerId, recvPlayerId); } -static void mevent_srv_free_resources(struct mevent_srv_common * svr) +static void MysteryGiftServer_Free(struct MysteryGiftServer * svr) { - Free(svr->wonder_card); - Free(svr->wonder_news); + Free(svr->card); + Free(svr->news); Free(svr->recvBuffer); - Free(svr->mevent_unk1442cc); + Free(svr->linkGameData); } -void mevent_srv_common_init_send(struct mevent_srv_common * svr, u32 ident, const void * src, u32 size) +static void MysteryGiftServer_InitSend(struct MysteryGiftServer * svr, u32 ident, const void * src, u32 size) { - AGB_ASSERT(size <= ME_SEND_BUF_SIZE); - MysteryGiftLink_InitSend(&svr->manager, ident, src, size); + AGB_ASSERT(size <= MG_LINK_BUFFER_SIZE); + MysteryGiftLink_InitSend(&svr->link, ident, src, size); } -static const void * mevent_first_if_not_null_else_second(const void * a0, const void * a1) +// Given the command pointer parameter and the 'default' normal data. +// If the command's pointer is not empty use that as the send data, otherwise use the default. +static const void * MysteryGiftServer_GetSendData(const void * dynamicData, const void * defaultData) { - if (a0 != NULL) - return a0; + if (dynamicData != NULL) + return dynamicData; else - return a1; + return defaultData; } -static u32 mevent_compare_pointers(const void * a0, const void * a1) +static u32 MysteryGiftServer_Compare(const void * a, const void * b) { - if (a1 < a0) + if (b < a) return 0; - else if (a1 == a0) + else if (b == a) return 1; else return 2; } -static u32 common_mainseq_0(struct mevent_srv_common * svr) +static u32 Server_Init(struct MysteryGiftServer * svr) { - // start - svr->mainseqno = 4; - return 0; + svr->funcId = FUNC_RUN; + return SVR_RET_INIT; } -static u32 common_mainseq_1(struct mevent_srv_common * svr) +static u32 Server_Done(struct MysteryGiftServer * svr) { - // done - return 3; + return SVR_RET_END; } -static u32 common_mainseq_2(struct mevent_srv_common * svr) +static u32 Server_Recv(struct MysteryGiftServer * svr) { - // do recv - if (MysteryGiftLink_Recv(&svr->manager)) - svr->mainseqno = 4; - return 1; + if (MysteryGiftLink_Recv(&svr->link)) + svr->funcId = FUNC_RUN; + return SVR_RET_ACTIVE; } -static u32 common_mainseq_3(struct mevent_srv_common * svr) +static u32 Server_Send(struct MysteryGiftServer * svr) { - // do send - if (MysteryGiftLink_Send(&svr->manager)) - svr->mainseqno = 4; - return 1; + if (MysteryGiftLink_Send(&svr->link)) + svr->funcId = FUNC_RUN; + return SVR_RET_ACTIVE; } -static u32 common_mainseq_4(struct mevent_srv_common * svr) +static u32 Server_Run(struct MysteryGiftServer * svr) { // process command - const struct mevent_cmd * cmd = &svr->cmdBuffer[svr->cmdidx]; + const struct MysteryGiftServerCmd * cmd = &svr->script[svr->cmdidx]; const void * ptr; svr->cmdidx++; switch (cmd->instr) { - case 0: - // end - AGB_ASSERT(cmd->parameter == NULL); - svr->mainseqno = 1; - svr->param = cmd->flag; + case SVR_RETURN: + AGB_ASSERT(cmd->ptr == NULL); + svr->funcId = FUNC_DONE; + svr->param = cmd->parameter; // Set for endVal in MysteryGiftServer_Run break; - case 1: - // wait_send - svr->mainseqno = 3; + case SVR_SEND: + svr->funcId = FUNC_SEND; break; - case 2: - // receive - AGB_ASSERT(cmd->parameter == NULL); - MysteryGiftLink_InitRecv(&svr->manager, cmd->flag, svr->recvBuffer); - svr->mainseqno = 2; + case SVR_RECV: + AGB_ASSERT(cmd->ptr == NULL); + MysteryGiftLink_InitRecv(&svr->link, cmd->parameter, svr->recvBuffer); + svr->funcId = FUNC_RECV; break; - case 3: - // jump - AGB_ASSERT(cmd->flag == FALSE); + case SVR_GOTO: + AGB_ASSERT(cmd->parameter == 0); svr->cmdidx = 0; - svr->cmdBuffer = cmd->parameter; + svr->script = cmd->ptr; break; - case 5: - // get_1442CC - AGB_ASSERT(cmd->flag == FALSE); - AGB_ASSERT(cmd->parameter == NULL); - memcpy(svr->mevent_unk1442cc, svr->recvBuffer, sizeof(struct MEventStruct_Unk1442CC)); + case SVR_COPY_GAME_DATA: + AGB_ASSERT(cmd->parameter == 0); + AGB_ASSERT(cmd->ptr == NULL); + memcpy(svr->linkGameData, svr->recvBuffer, sizeof(*svr->linkGameData)); break; - case 6: - // check_header__pass_false - AGB_ASSERT(cmd->flag == FALSE); - AGB_ASSERT(cmd->parameter == NULL); - svr->param = sub_801B6A0(svr->mevent_unk1442cc, FALSE); + case SVR_CHECK_GAME_DATA_CARD: + AGB_ASSERT(cmd->parameter == 0); + AGB_ASSERT(cmd->ptr == NULL); + svr->param = MysteryGift_ValidateLinkGameData(svr->linkGameData, FALSE); break; - case 30: - // check_header__pass_true - AGB_ASSERT(cmd->flag == FALSE); - AGB_ASSERT(cmd->parameter == NULL); - svr->param = sub_801B6A0(svr->mevent_unk1442cc, TRUE); + case SVR_CHECK_GAME_DATA_NEWS: + AGB_ASSERT(cmd->parameter == 0); + AGB_ASSERT(cmd->ptr == NULL); + svr->param = MysteryGift_ValidateLinkGameData(svr->linkGameData, TRUE); break; - case 4: - // jump_if_eq - if (svr->param == cmd->flag) + case SVR_GOTO_IF_EQ: + if (svr->param == cmd->parameter) { svr->cmdidx = 0; - svr->cmdBuffer = cmd->parameter; + svr->script = cmd->ptr; } break; - case 7: - // check_crc - AGB_ASSERT(cmd->flag == FALSE); - ptr = mevent_first_if_not_null_else_second(cmd->parameter, svr->wonder_card); - svr->param = sub_801B6EC(ptr, svr->mevent_unk1442cc, ptr); + case SVR_CHECK_EXISTING_CARD: + AGB_ASSERT(cmd->parameter == 0); + ptr = MysteryGiftServer_GetSendData(cmd->ptr, svr->card); + svr->param = MysteryGift_CompareCardFlags(ptr, svr->linkGameData, ptr); break; - case 8: - // read_word - AGB_ASSERT(cmd->flag == FALSE); - AGB_ASSERT(cmd->parameter == NULL); + case SVR_READ_RESPONSE: + AGB_ASSERT(cmd->parameter == 0); + AGB_ASSERT(cmd->ptr == NULL); svr->param = *(u32 *)svr->recvBuffer; break; - case 9: - AGB_ASSERT(cmd->flag == FALSE); - ptr = mevent_first_if_not_null_else_second(cmd->parameter, &svr->sendWord); - svr->param = sub_801B708(ptr, svr->mevent_unk1442cc, ptr); + case SVR_CHECK_EXISTING_STAMPS: + AGB_ASSERT(cmd->parameter == 0); + ptr = MysteryGiftServer_GetSendData(cmd->ptr, &svr->stamp); + svr->param = MysteryGift_CheckStamps(ptr, svr->linkGameData, ptr); break; - case 10: - AGB_ASSERT(cmd->parameter == NULL); - svr->param = MEventStruct_Unk1442CC_GetValueNFrom_unk_20(svr->mevent_unk1442cc, cmd->flag); + case SVR_GET_CARD_STAT: + AGB_ASSERT(cmd->ptr == NULL); + svr->param = MysteryGift_GetCardStatFromLinkData(svr->linkGameData, cmd->parameter); break; - case 11: - AGB_ASSERT(cmd->flag == FALSE); - svr->param = MysteryGift_DoesQuestionnaireMatch(svr->mevent_unk1442cc, cmd->parameter); + case SVR_CHECK_QUESTIONNAIRE: + AGB_ASSERT(cmd->parameter == 0); + svr->param = MysteryGift_DoesQuestionnaireMatch(svr->linkGameData, cmd->ptr); break; - case 12: - AGB_ASSERT(cmd->flag == FALSE); - svr->param = mevent_compare_pointers(cmd->parameter, *(void **)svr->recvBuffer); + case SVR_COMPARE: + AGB_ASSERT(cmd->parameter == 0); + svr->param = MysteryGiftServer_Compare(cmd->ptr, *(void **)svr->recvBuffer); break; - case 14: - AGB_ASSERT(cmd->flag == FALSE); - mevent_srv_common_init_send(svr, 0x17, mevent_first_if_not_null_else_second(cmd->parameter, svr->wonder_news), sizeof(struct WonderNews)); + case SVR_LOAD_NEWS: + AGB_ASSERT(cmd->parameter == 0); + MysteryGiftServer_InitSend(svr, MG_LINKID_NEWS, MysteryGiftServer_GetSendData(cmd->ptr, svr->news), sizeof(*svr->news)); break; - case 13: - AGB_ASSERT(cmd->flag == FALSE); - mevent_srv_common_init_send(svr, 0x16, mevent_first_if_not_null_else_second(cmd->parameter, svr->wonder_card), sizeof(struct WonderCard)); + case SVR_LOAD_CARD: + AGB_ASSERT(cmd->parameter == 0); + MysteryGiftServer_InitSend(svr, MG_LINKID_CARD, MysteryGiftServer_GetSendData(cmd->ptr, svr->card), sizeof(*svr->card)); break; - case 16: - AGB_ASSERT(cmd->flag == FALSE); - mevent_srv_common_init_send(svr, 0x18, mevent_first_if_not_null_else_second(cmd->parameter, &svr->sendWord), 4); + case SVR_LOAD_STAMP: + AGB_ASSERT(cmd->parameter == 0); + MysteryGiftServer_InitSend(svr, MG_LINKID_STAMP, MysteryGiftServer_GetSendData(cmd->ptr, &svr->stamp), sizeof(svr->stamp)); break; - case 15: - if (cmd->parameter == NULL) - mevent_srv_common_init_send(svr, 0x19, svr->sendBuffer1, svr->sendBuffer1Size); + case SVR_LOAD_RAM_SCRIPT: + if (cmd->ptr == NULL) + MysteryGiftServer_InitSend(svr, MG_LINKID_RAM_SCRIPT, svr->ramScript, svr->ramScriptSize); else - mevent_srv_common_init_send(svr, 0x19, cmd->parameter, cmd->flag); + MysteryGiftServer_InitSend(svr, MG_LINKID_RAM_SCRIPT, cmd->ptr, cmd->parameter); break; - case 18: - if (cmd->parameter == NULL) - mevent_srv_common_init_send(svr, 0x10, svr->sendBuffer2, svr->sendBuffer2Size); + case SVR_LOAD_CLIENT_SCRIPT: + if (cmd->ptr == NULL) + MysteryGiftServer_InitSend(svr, MG_LINKID_CLIENT_SCRIPT, svr->clientScript, svr->clientScriptSize); else - mevent_srv_common_init_send(svr, 0x10, cmd->parameter, cmd->flag); + MysteryGiftServer_InitSend(svr, MG_LINKID_CLIENT_SCRIPT, cmd->ptr, cmd->parameter); break; - case 19: - AGB_ASSERT(cmd->flag == FALSE); - mevent_srv_common_init_send(svr, 0x1a, cmd->parameter, 188); + case SVR_LOAD_EREADER_TRAINER: + AGB_ASSERT(cmd->parameter == 0); + MysteryGiftServer_InitSend(svr, MG_LINKID_EREADER_TRAINER, cmd->ptr, sizeof(struct BattleTowerEReaderTrainer)); break; - case 20: - mevent_srv_common_init_send(svr, 0x15, cmd->parameter, cmd->flag); + case SVR_LOAD_MSG: + MysteryGiftServer_InitSend(svr, MG_LINKID_DYNAMIC_MSG, cmd->ptr, cmd->parameter); break; - case 17: - mevent_srv_common_init_send(svr, 0x1c, cmd->parameter, cmd->flag); + case SVR_LOAD_UNK_2: + MysteryGiftServer_InitSend(svr, MG_LINKID_UNK_2, cmd->ptr, cmd->parameter); break; - case 22: - AGB_ASSERT(cmd->flag == FALSE); - memcpy(svr->wonder_card, cmd->parameter, 332); + case SVR_COPY_CARD: + AGB_ASSERT(cmd->parameter == 0); + memcpy(svr->card, cmd->ptr, sizeof(*svr->card)); break; - case 23: - AGB_ASSERT(cmd->flag == FALSE); - memcpy(svr->wonder_news, cmd->parameter, 444); + case SVR_COPY_NEWS: + AGB_ASSERT(cmd->parameter == 0); + memcpy(svr->news, cmd->ptr, sizeof(*svr->news)); break; - case 21: - AGB_ASSERT(cmd->flag == FALSE); - svr->sendWord = *(u32 *)cmd->parameter; + case SVR_COPY_STAMP: + AGB_ASSERT(cmd->parameter == 0); + svr->stamp = *(u32 *)cmd->ptr; break; - case 24: - svr->sendBuffer1 = cmd->parameter; - svr->sendBuffer1Size = cmd->flag; + case SVR_SET_RAM_SCRIPT: + svr->ramScript = cmd->ptr; + svr->ramScriptSize = cmd->parameter; break; - case 25: - svr->sendBuffer2 = cmd->parameter; - svr->sendBuffer2Size = cmd->flag; + case SVR_SET_CLIENT_SCRIPT: + svr->clientScript = cmd->ptr; + svr->clientScriptSize = cmd->parameter; break; - case 26: - AGB_ASSERT(cmd->flag == FALSE && cmd->parameter == NULL); - memcpy(svr->wonder_card, GetSavedWonderCard(), 332); - WonderCard_ResetInternalReceivedFlag(svr->wonder_card); + case SVR_COPY_SAVED_CARD: + AGB_ASSERT(cmd->parameter == 0 && cmd->ptr == NULL); + memcpy(svr->card, GetSavedWonderCard(), sizeof(*svr->card)); + DisableWonderCardSending(svr->card); break; - case 27: - AGB_ASSERT(cmd->flag == FALSE && cmd->parameter == NULL); - memcpy(svr->wonder_news, GetSavedWonderNews(), 444); + case SVR_COPY_SAVED_NEWS: + AGB_ASSERT(cmd->parameter == 0 && cmd->ptr == NULL); + memcpy(svr->news, GetSavedWonderNews(), sizeof(*svr->news)); break; - case 28: - AGB_ASSERT(cmd->flag == FALSE && cmd->parameter == NULL); - svr->sendBuffer1 = GetSavedRamScriptIfValid(); + case SVR_COPY_SAVED_RAM_SCRIPT: + AGB_ASSERT(cmd->parameter == 0 && cmd->ptr == NULL); + svr->ramScript = GetSavedRamScriptIfValid(); break; - case 29: - mevent_srv_common_init_send(svr, 0x1b, cmd->parameter, cmd->flag); + case SVR_LOAD_UNK_1: + MysteryGiftServer_InitSend(svr, MG_LINKID_UNK_1, cmd->ptr, cmd->parameter); break; } - return 1; + return SVR_RET_ACTIVE; } -static u32 (*const func_tbl[])(struct mevent_srv_common *) = { - common_mainseq_0, - common_mainseq_1, - common_mainseq_2, - common_mainseq_3, - common_mainseq_4 +static u32 (*const sFuncTable[])(struct MysteryGiftServer *) = { + [FUNC_INIT] = Server_Init, + [FUNC_DONE] = Server_Done, + [FUNC_RECV] = Server_Recv, + [FUNC_SEND] = Server_Send, + [FUNC_RUN] = Server_Run }; -static u32 mevent_srv_exec_common(struct mevent_srv_common * svr) +static u32 MysteryGiftServer_CallFunc(struct MysteryGiftServer * svr) { u32 response; - AGB_ASSERT(svr->mainseqno < ARRAY_COUNT(func_tbl)); - response = func_tbl[svr->mainseqno](svr); - AGB_ASSERT(svr->mainseqno < ARRAY_COUNT(func_tbl)); + AGB_ASSERT(svr->funcId < ARRAY_COUNT(sFuncTable)); + response = sFuncTable[svr->funcId](svr); + AGB_ASSERT(svr->funcId < ARRAY_COUNT(sFuncTable)); return response; } diff --git a/src/mevent_server_helpers.c b/src/mevent_server_helpers.c index 17686e287..83ecc9f50 100644 --- a/src/mevent_server_helpers.c +++ b/src/mevent_server_helpers.c @@ -11,200 +11,211 @@ #include "mevent.h" #include "mevent_server_helpers.h" -static u32 mevent_receive_func(struct MysteryGiftLink *); -static u32 mevent_send_func(struct MysteryGiftLink *); +/* + Handles the link connection functions used by the Mystery Gift client/server. + Note: MysteryGiftLink is shortened to MGL for internal functions. +*/ -u32 MysteryGiftLink_Recv(struct MysteryGiftLink * svr) +struct SendRecvHeader { - return svr->recvFunc(svr); + u16 ident; + u16 crc; + u16 size; +}; + +static u32 MGL_Receive(struct MysteryGiftLink *); +static u32 MGL_Send(struct MysteryGiftLink *); + +u32 MysteryGiftLink_Recv(struct MysteryGiftLink * link) +{ + return link->recvFunc(link); } -u32 MysteryGiftLink_Send(struct MysteryGiftLink * svr) +u32 MysteryGiftLink_Send(struct MysteryGiftLink * link) { - return svr->sendFunc(svr); + return link->sendFunc(link); } -void MysteryGiftLink_Init(struct MysteryGiftLink * svr, u32 sendPlayerNo, u32 recvPlayerNo) +void MysteryGiftLink_Init(struct MysteryGiftLink * link, u32 sendPlayerId, u32 recvPlayerId) { - svr->sendPlayerNo = sendPlayerNo; - svr->recvPlayerNo = recvPlayerNo; - svr->seqno = 0; - svr->sendCRC = 0; - svr->sendSize = 0; - svr->sendCounter = 0; - svr->recvCRC = 0; - svr->recvSize = 0; - svr->recvCounter = 0; - svr->sendBfr = NULL; - svr->recvBfr = NULL; - svr->sendFunc = mevent_send_func; - svr->recvFunc = mevent_receive_func; + link->sendPlayerId = sendPlayerId; + link->recvPlayerId = recvPlayerId; + link->state = 0; + link->sendCRC = 0; + link->sendSize = 0; + link->sendCounter = 0; + link->recvCRC = 0; + link->recvSize = 0; + link->recvCounter = 0; + link->sendBfr = NULL; + link->recvBfr = NULL; + link->sendFunc = MGL_Send; + link->recvFunc = MGL_Receive; } -void MysteryGiftLink_InitSend(struct MysteryGiftLink * svr, u32 ident, const void * src, u32 size) +void MysteryGiftLink_InitSend(struct MysteryGiftLink * link, u32 ident, const void * src, u32 size) { - svr->seqno = 0; - svr->sendIdent = ident; - svr->sendCounter = 0; - svr->sendCRC = 0; + link->state = 0; + link->sendIdent = ident; + link->sendCounter = 0; + link->sendCRC = 0; if (size != 0) - svr->sendSize = size; + link->sendSize = size; else - svr->sendSize = ME_SEND_BUF_SIZE; - svr->sendBfr = src; + link->sendSize = MG_LINK_BUFFER_SIZE; + link->sendBfr = src; } -void MysteryGiftLink_InitRecv(struct MysteryGiftLink * svr, u32 ident, void * dest) +void MysteryGiftLink_InitRecv(struct MysteryGiftLink * link, u32 ident, void * dest) { - svr->seqno = 0; - svr->recvIdent = ident; - svr->recvCounter = 0; - svr->recvCRC = 0; - svr->recvSize = 0; - svr->recvBfr = dest; + link->state = 0; + link->recvIdent = ident; + link->recvCounter = 0; + link->recvCRC = 0; + link->recvSize = 0; + link->recvBfr = dest; } -static void mevent_recv_block(u32 recv_idx, void * dest, size_t size) +static void MGL_ReceiveBlock(u32 playerId, void * dest, size_t size) { - memcpy(dest, gBlockRecvBuffer[recv_idx], size); + memcpy(dest, gBlockRecvBuffer[playerId], size); } -static bool32 mevent_has_received(u32 recv_idx) +static bool32 MGL_HasReceived(u32 playerId) { - if ((GetBlockReceivedStatus() >> recv_idx) & 1) + if ((GetBlockReceivedStatus() >> playerId) & 1) return TRUE; else return FALSE; } -static void mevent_reset_recv(u32 recv_idx) +static void MGL_ResetReceived(u32 playerId) { - ResetBlockReceivedFlag(recv_idx); + ResetBlockReceivedFlag(playerId); } -static bool32 mevent_receive_func(struct MysteryGiftLink * svr) +static bool32 MGL_Receive(struct MysteryGiftLink * link) { - struct send_recv_header header; + struct SendRecvHeader header; - switch (svr->seqno) + switch (link->state) { - case 0: - if (mevent_has_received(svr->recvPlayerNo)) + case 0: + if (MGL_HasReceived(link->recvPlayerId)) + { + MGL_ReceiveBlock(link->recvPlayerId, &header, sizeof(header)); + link->recvSize = header.size; + link->recvCRC = header.crc; + if (link->recvSize > MG_LINK_BUFFER_SIZE) { - mevent_recv_block(svr->recvPlayerNo, &header, sizeof(header)); - svr->recvSize = header.size; - svr->recvCRC = header.crc; - if (svr->recvSize > ME_SEND_BUF_SIZE) - { - LinkRfu_FatalError(); - return FALSE; - } - else if (svr->recvIdent != header.ident) - { - LinkRfu_FatalError(); - return FALSE; - } - else - { - svr->recvCounter = 0; - mevent_reset_recv(svr->recvPlayerNo); - ++svr->seqno; - } + LinkRfu_FatalError(); + return FALSE; } - break; - case 1: - if (mevent_has_received(svr->recvPlayerNo)) - { - size_t blocksiz = svr->recvCounter * 252; - if (svr->recvSize - blocksiz <= 252) - { - mevent_recv_block(svr->recvPlayerNo, svr->recvBfr + blocksiz, svr->recvSize - blocksiz); - ++svr->recvCounter; - ++svr->seqno; - } - else - { - mevent_recv_block(svr->recvPlayerNo, svr->recvBfr + blocksiz, 252); - ++svr->recvCounter; - } - mevent_reset_recv(svr->recvPlayerNo); - } - break; - case 2: - if (CalcCRC16WithTable(svr->recvBfr, svr->recvSize) != svr->recvCRC) + else if (link->recvIdent != header.ident) { LinkRfu_FatalError(); return FALSE; } else { - svr->seqno = 0; - return TRUE; + link->recvCounter = 0; + MGL_ResetReceived(link->recvPlayerId); + link->state++; } - break; - + } + break; + case 1: + if (MGL_HasReceived(link->recvPlayerId)) + { + size_t blocksize = link->recvCounter * 252; + if (link->recvSize - blocksize <= 252) + { + MGL_ReceiveBlock(link->recvPlayerId, link->recvBfr + blocksize, link->recvSize - blocksize); + link->recvCounter++; + link->state++; + } + else + { + MGL_ReceiveBlock(link->recvPlayerId, link->recvBfr + blocksize, 252); + link->recvCounter++; + } + MGL_ResetReceived(link->recvPlayerId); + } + break; + case 2: + if (CalcCRC16WithTable(link->recvBfr, link->recvSize) != link->recvCRC) + { + LinkRfu_FatalError(); + return FALSE; + } + else + { + link->state = 0; + return TRUE; + } + break; } return FALSE; } -static bool32 mevent_send_func(struct MysteryGiftLink * svr) +static bool32 MGL_Send(struct MysteryGiftLink * link) { - struct send_recv_header header; + struct SendRecvHeader header; - switch (svr->seqno) + switch (link->state) { - case 0: - if (IsLinkTaskFinished()) + case 0: + if (IsLinkTaskFinished()) + { + header.ident = link->sendIdent; + header.size = link->sendSize; + header.crc = CalcCRC16WithTable(link->sendBfr, link->sendSize); + link->sendCRC = header.crc; + link->sendCounter = 0; + SendBlock(0, &header, sizeof(header)); + link->state++; + } + break; + case 1: + if (IsLinkTaskFinished()) + { + if (MGL_HasReceived(link->sendPlayerId)) { - header.ident = svr->sendIdent; - header.size = svr->sendSize; - header.crc = CalcCRC16WithTable(svr->sendBfr, svr->sendSize); - svr->sendCRC = header.crc; - svr->sendCounter = 0; - SendBlock(0, &header, sizeof(header)); - ++svr->seqno; - } - break; - case 1: - if (IsLinkTaskFinished()) - { - if (mevent_has_received(svr->sendPlayerNo)) + size_t blocksize; + MGL_ResetReceived(link->sendPlayerId); + blocksize = 252 * link->sendCounter; + if (link->sendSize - blocksize <= 252) { - size_t blocksiz; - mevent_reset_recv(svr->sendPlayerNo); - blocksiz = 252 * svr->sendCounter; - if (svr->sendSize - blocksiz <= 252) - { - SendBlock(0, svr->sendBfr + blocksiz, svr->sendSize - blocksiz); - ++svr->sendCounter; - ++svr->seqno; - } - else - { - SendBlock(0, svr->sendBfr + blocksiz, 252); - ++svr->sendCounter; - } + SendBlock(0, link->sendBfr + blocksize, link->sendSize - blocksize); + link->sendCounter++; + link->state++; + } + else + { + SendBlock(0, link->sendBfr + blocksize, 252); + link->sendCounter++; } } - break; - case 2: - if (IsLinkTaskFinished()) - { - if (CalcCRC16WithTable(svr->sendBfr, svr->sendSize) != svr->sendCRC) - LinkRfu_FatalError(); - else - ++svr->seqno; - } - break; - case 3: - if (mevent_has_received(svr->sendPlayerNo)) - { - mevent_reset_recv(svr->sendPlayerNo); - svr->seqno = 0; - return TRUE; - } - break; + } + break; + case 2: + if (IsLinkTaskFinished()) + { + if (CalcCRC16WithTable(link->sendBfr, link->sendSize) != link->sendCRC) + LinkRfu_FatalError(); + else + link->state++; + } + break; + case 3: + if (MGL_HasReceived(link->sendPlayerId)) + { + MGL_ResetReceived(link->sendPlayerId); + link->state = 0; + return TRUE; + } + break; } return FALSE; diff --git a/src/mystery_gift.c b/src/mystery_gift.c index b3ec493f5..de0874d28 100644 --- a/src/mystery_gift.c +++ b/src/mystery_gift.c @@ -44,18 +44,18 @@ static const u32 gUnkTextboxBorderGfx[] = INCBIN_U32("graphics/interface/unk_tex struct MysteryGiftTaskData { - u16 curPromptWindowId; - u16 unk2; - u16 unk4; - u16 unk6; + u16 var; // Multipurpose + u16 unused1; + u16 unused2; + u16 unused3; u8 state; u8 textState; - u8 unkA; - u8 unkB; + u8 unused4; + u8 unused5; bool8 isWonderNews; bool8 sourceIsFriend; - u8 prevPromptWindowId; - u8 * buffer; + u8 msgId; + u8 * clientMsg; }; static const struct BgTemplate sBGTemplates[] = { @@ -547,7 +547,7 @@ static void ClearTextWindow(void) CopyWindowToVram(1, 1); } -bool32 MG_PrintTextOnWindow1AndWaitButton(u8 *textState, const u8 *str) +bool32 PrintMysteryGiftMenuMessage(u8 *textState, const u8 *str) { switch (*textState) { @@ -700,6 +700,7 @@ s8 DoMysteryGiftYesNo(u8 * textState, u16 * windowId, bool8 yesNoBoxPlacement, c return MENU_NOTHING_CHOSEN; } +// Handle the "Receive/Send/Toss" menu that appears when selecting Wonder Card/News static s32 HandleMysteryGiftListMenu(u8 * textState, u16 * windowId, bool32 cannotToss, bool32 cannotSend) { struct WindowTemplate windowTemplate; @@ -772,7 +773,7 @@ static bool32 HandleLoadWonderCardOrNews(u8 * state, bool32 isWonderNews) { case 0: if (!isWonderNews) - WonderCard_Init(GetSavedWonderCard(), sav1_get_mevent_buffer_2()); + WonderCard_Init(GetSavedWonderCard(), GetSavedWonderCardMetadata()); else WonderNews_Init(GetSavedWonderNews()); (*state)++; @@ -798,9 +799,9 @@ static bool32 HandleLoadWonderCardOrNews(u8 * state, bool32 isWonderNews) static bool32 ClearSavedNewsOrCard(bool32 isWonderNews) { if (!isWonderNews) - ClearSavedWonderCard(); + ClearSavedWonderCardAndRelated(); else - ClearSavedWonderNews(); + ClearSavedWonderNewsAndRelated(); return TRUE; } @@ -843,12 +844,12 @@ static s32 AskDiscardGift(u8 * textState, u16 * windowId, bool32 isWonderNews) static bool32 PrintThrownAway(u8 * textState, bool32 isWonderNews) { if (!isWonderNews) - return MG_PrintTextOnWindow1AndWaitButton(textState, gText_WonderCardThrownAway); + return PrintMysteryGiftMenuMessage(textState, gText_WonderCardThrownAway); else - return MG_PrintTextOnWindow1AndWaitButton(textState, gText_WonderNewsThrownAway); + return PrintMysteryGiftMenuMessage(textState, gText_WonderNewsThrownAway); } -static bool32 mevent_save_game(u8 * state) +static bool32 SaveOnMysteryGiftMenu(u8 * state) { switch (*state) { @@ -865,10 +866,8 @@ static bool32 mevent_save_game(u8 * state) (*state)++; break; case 3: - if (({JOY_NEW(A_BUTTON | B_BUTTON);})) - { + if (JOY_NEW(A_BUTTON | B_BUTTON)) (*state)++; - } break; case 4: *state = 0; @@ -879,70 +878,72 @@ static bool32 mevent_save_game(u8 * state) return FALSE; } -static const u8 * GetStdMessage(bool32 * receivedMsg, bool8 isWonderNews, bool8 sourceIsFriend, u32 msgId) +static const u8 * GetClientResultMessage(bool32 * successMsg, bool8 isWonderNews, bool8 sourceIsFriend, u32 msgId) { const u8 * msg = NULL; - *receivedMsg = FALSE; + *successMsg = FALSE; switch (msgId) { - case 0: - *receivedMsg = FALSE; + case CLI_MSG_NOTHING_SENT: + *successMsg = FALSE; msg = gText_NothingSentOver; break; - case 1: - *receivedMsg = FALSE; + case CLI_MSG_RECORD_UPLOADED: + *successMsg = FALSE; msg = gText_RecordUploadedViaWireless; break; - case 2: - *receivedMsg = TRUE; + case CLI_MSG_CARD_RECEIVED: + *successMsg = TRUE; msg = !sourceIsFriend ? gText_WonderCardReceived : gText_WonderCardReceivedFrom; break; - case 3: - *receivedMsg = TRUE; + case CLI_MSG_NEWS_RECEIVED: + *successMsg = TRUE; msg = !sourceIsFriend ? gText_WonderNewsReceived : gText_WonderNewsReceivedFrom; break; - case 4: - *receivedMsg = TRUE; + case CLI_MSG_STAMP_RECEIVED: + *successMsg = TRUE; msg = gText_NewStampReceived; break; - case 5: - *receivedMsg = FALSE; + case CLI_MSG_HAD_CARD: + *successMsg = FALSE; msg = gText_AlreadyHadCard; break; - case 6: - *receivedMsg = FALSE; + case CLI_MSG_HAD_STAMP: + *successMsg = FALSE; msg = gText_AlreadyHadStamp; break; - case 7: - *receivedMsg = FALSE; + case CLI_MSG_HAD_NEWS: + *successMsg = FALSE; msg = gText_AlreadyHadNews; break; - case 8: - *receivedMsg = FALSE; + case CLI_MSG_NO_ROOM_STAMPS: + *successMsg = FALSE; msg = gText_NoMoreRoomForStamps; break; - case 9: - *receivedMsg = FALSE; + case CLI_MSG_COMM_CANCELED: + *successMsg = FALSE; msg = gText_CommunicationCanceled; break; - case 10: - *receivedMsg = FALSE; + case CLI_MSG_CANT_ACCEPT: + *successMsg = FALSE; msg = !isWonderNews ? gText_CantAcceptCardFromTrainer : gText_CantAcceptNewsFromTrainer; break; - case 11: - *receivedMsg = FALSE; + case CLI_MSG_COMM_ERROR: + *successMsg = FALSE; msg = gText_CommunicationError; break; - case 12: - *receivedMsg = TRUE; + case CLI_MSG_TRAINER_RECEIVED: + *successMsg = TRUE; msg = gText_NewTrainerReceived; break; - case 13: - *receivedMsg = TRUE; + case CLI_MSG_BUFFER_SUCCESS: + *successMsg = TRUE; + // msg is NULL, use buffer break; - case 14: - *receivedMsg = FALSE; + case CLI_MSG_BUFFER_FAILURE: + *successMsg = FALSE; + // msg is NULL, use buffer break; } @@ -976,91 +977,95 @@ static bool32 PrintSuccessMessage(u8 * state, const u8 * msg, u16 * timer) return FALSE; } -static const u8 * mevent_message_stamp_card_etc_send_status(u32 * a0, u8 unused, u32 msgId) +static const u8 * GetServerResultMessage(bool32 * wonderSuccess, bool8 sourceIsFriend, u32 msgId) { const u8 * result = gText_CommunicationError; - *a0 = 0; + *wonderSuccess = FALSE; switch (msgId) { - case 0: + case SVR_MSG_NOTHING_SENT: result = gText_NothingSentOver; break; - case 1: + case SVR_MSG_RECORD_UPLOADED: result = gText_RecordUploadedViaWireless; break; - case 2: + case SVR_MSG_CARD_SENT: result = gText_WonderCardSentTo; - *a0 = 1; + *wonderSuccess = TRUE; break; - case 3: + case SVR_MSG_NEWS_SENT: result = gText_WonderNewsSentTo; - *a0 = 1; + *wonderSuccess = TRUE; break; - case 4: + case SVR_MSG_STAMP_SENT: result = gText_StampSentTo; break; - case 5: + case SVR_MSG_HAS_CARD: result = gText_OtherTrainerHasCard; break; - case 6: + case SVR_MSG_HAS_STAMP: result = gText_OtherTrainerHasStamp; break; - case 7: + case SVR_MSG_HAS_NEWS: result = gText_OtherTrainerHasNews; break; - case 8: + case SVR_MSG_NO_ROOM_STAMPS: result = gText_NoMoreRoomForStamps; break; - case 9: + case SVR_MSG_CLIENT_CANCELED: result = gText_OtherTrainerCanceled; break; - case 10: + case SVR_MSG_CANT_SEND_GIFT_1: result = gText_CantSendGiftToTrainer; break; - case 11: + case SVR_MSG_COMM_ERROR: result = gText_CommunicationError; break; - case 12: + case SVR_MSG_GIFT_SENT_1: result = gText_GiftSentTo; break; - case 13: + case SVR_MSG_GIFT_SENT_2: result = gText_GiftSentTo; break; - case 14: + case SVR_MSG_CANT_SEND_GIFT_2: result = gText_CantSendGiftToTrainer; break; } return result; } -static bool32 PrintMGSendStatus(u8 * state, u16 * arg1, u8 arg2, u32 msgId) +static bool32 PrintServerResultMessage(u8 * state, u16 * timer, bool8 sourceIsFriend, u32 msgId) { - u32 flag; - const u8 * str = mevent_message_stamp_card_etc_send_status(&flag, arg2, msgId); - if (flag) - return PrintSuccessMessage(state, str, arg1); + bool32 wonderSuccess; + const u8 * str = GetServerResultMessage(&wonderSuccess, sourceIsFriend, msgId); + if (wonderSuccess) + return PrintSuccessMessage(state, str, timer); else - return MG_PrintTextOnWindow1AndWaitButton(state, str); + return PrintMysteryGiftMenuMessage(state, str); } +// States for Task_MysteryGift. +// CLIENT states are for when the player is receiving a gift, and use mevent_client.c link functions. +// SERVER states are for when the player is sending a gift, and use mevent_server.c link functions. +// Other states handle the general Mystery Gift menu usage. enum { MG_STATE_TO_MAIN_MENU, MG_STATE_MAIN_MENU, MG_STATE_DONT_HAVE_ANY, - MG_STATE_LINK_PROMPT, - MG_STATE_LINK_PROMPT_INPUT, - MG_STATE_LINK_START, - MG_STATE_LINK_WAIT, - MG_STATE_COMMUNICATING, - MG_STATE_COMMUNICATE, - MG_STATE_9, - MG_STATE_10, - MG_STATE_LINK_ASK_TOSS, - MG_STATE_LINK_ASK_TOSS_UNRECEIVED, - MG_STATE_LINK_COMPLETE_WAIT, - MG_STATE_LINK_COMPLETED, - MG_STATE_LINK_RESULT_MSG, - MG_STATE_LINK_ERROR_1, + MG_STATE_SOURCE_PROMPT, + MG_STATE_SOURCE_PROMPT_INPUT, + MG_STATE_CLIENT_LINK_START, + MG_STATE_CLIENT_LINK_WAIT, + MG_STATE_CLIENT_COMMUNICATING, + MG_STATE_CLIENT_LINK, + MG_STATE_CLIENT_YES_NO, + MG_STATE_CLIENT_MESSAGE, + MG_STATE_CLIENT_ASK_TOSS, + MG_STATE_CLIENT_ASK_TOSS_UNRECEIVED, + MG_STATE_CLIENT_LINK_END, + MG_STATE_CLIENT_COMM_COMPLETED, + MG_STATE_CLIENT_RESULT_MSG, + MG_STATE_CLIENT_ERROR, MG_STATE_SAVE_LOAD_GIFT, MG_STATE_LOAD_GIFT, MG_STATE_UNUSED, @@ -1074,13 +1079,13 @@ enum { MG_STATE_GIFT_INPUT_EXIT, MG_STATE_RECEIVE, MG_STATE_SEND, - MG_STATE_SEND_WAIT, - MG_STATE_SEND_START, - MG_STATE_SENDING, - MG_STATE_SEND_FINISH, - MG_STATE_SEND_WAIT_END, - MG_STATE_SEND_END, - MG_STATE_LINK_ERROR_2, + MG_STATE_SERVER_LINK_WAIT, + MG_STATE_SERVER_LINK_START, + MG_STATE_SERVER_LINK, + MG_STATE_SERVER_LINK_END, + MG_STATE_SERVER_LINK_END_WAIT, + MG_STATE_SERVER_RESULT_MSG, + MG_STATE_SERVER_ERROR, MG_STATE_EXIT, }; @@ -1090,22 +1095,22 @@ static void CreateMysteryGiftTask(void) struct MysteryGiftTaskData * data = (void *)gTasks[taskId].data; data->state = MG_STATE_TO_MAIN_MENU; data->textState = 0; - data->unkA = 0; - data->unkB = 0; + data->unused4 = 0; + data->unused5 = 0; data->isWonderNews = 0; data->sourceIsFriend = 0; - data->curPromptWindowId = 0; - data->unk2 = 0; - data->unk4 = 0; - data->unk6 = 0; - data->prevPromptWindowId = 0; - data->buffer = AllocZeroed(0x40); + data->var = 0; + data->unused1 = 0; + data->unused2 = 0; + data->unused3 = 0; + data->msgId = 0; + data->clientMsg = AllocZeroed(CLIENT_MAX_MSG_SIZE); } static void Task_MysteryGift(u8 taskId) { struct MysteryGiftTaskData *data = (void *)gTasks[taskId].data; - u32 receivedMsg, input; + u32 successMsg, input; const u8 *msg; switch (data->state) @@ -1115,7 +1120,7 @@ static void Task_MysteryGift(u8 taskId) break; case MG_STATE_MAIN_MENU: // Main Mystery Gift menu, player can select Wonder Cards or News (or exit) - switch (MysteryGift_HandleThreeOptionMenu(&data->textState, &data->curPromptWindowId, FALSE)) + switch (MysteryGift_HandleThreeOptionMenu(&data->textState, &data->var, FALSE)) { case 0: // "Wonder Cards" data->isWonderNews = FALSE; @@ -1142,41 +1147,41 @@ static void Task_MysteryGift(u8 taskId) // Start prompt to ask where to read one from if (!data->isWonderNews) { - if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, gText_DontHaveCardNewOneInput)) + if (PrintMysteryGiftMenuMessage(&data->textState, gText_DontHaveCardNewOneInput)) { - data->state = MG_STATE_LINK_PROMPT; + data->state = MG_STATE_SOURCE_PROMPT; PrintMysteryGiftOrEReaderTopMenu(FALSE, TRUE); } } else { - if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, gText_DontHaveNewsNewOneInput)) + if (PrintMysteryGiftMenuMessage(&data->textState, gText_DontHaveNewsNewOneInput)) { - data->state = MG_STATE_LINK_PROMPT; + data->state = MG_STATE_SOURCE_PROMPT; PrintMysteryGiftOrEReaderTopMenu(FALSE, TRUE); } } break; } - case MG_STATE_LINK_PROMPT: + case MG_STATE_SOURCE_PROMPT: if (!data->isWonderNews) AddTextPrinterToWindow1(gText_WhereShouldCardBeAccessed); else AddTextPrinterToWindow1(gText_WhereShouldNewsBeAccessed); - data->state = MG_STATE_LINK_PROMPT_INPUT; + data->state = MG_STATE_SOURCE_PROMPT_INPUT; break; - case MG_STATE_LINK_PROMPT_INPUT: + case MG_STATE_SOURCE_PROMPT_INPUT: // Choose where to access the Wonder Card/News from - switch (MysteryGift_HandleThreeOptionMenu(&data->textState, &data->curPromptWindowId, TRUE)) + switch (MysteryGift_HandleThreeOptionMenu(&data->textState, &data->var, TRUE)) { case 0: // "Wireless Communication" ClearTextWindow(); - data->state = MG_STATE_LINK_START; + data->state = MG_STATE_CLIENT_LINK_START; data->sourceIsFriend = FALSE; break; case 1: // "Friend" ClearTextWindow(); - data->state = MG_STATE_LINK_START; + data->state = MG_STATE_CLIENT_LINK_START; data->sourceIsFriend = TRUE; break; case LIST_CANCEL: @@ -1193,7 +1198,7 @@ static void Task_MysteryGift(u8 taskId) break; } break; - case MG_STATE_LINK_START: + case MG_STATE_CLIENT_LINK_START: *gStringVar1 = EOS; *gStringVar2 = EOS; *gStringVar3 = EOS; @@ -1213,149 +1218,153 @@ static void Task_MysteryGift(u8 taskId) CreateTask_LinkMysteryGiftOverWireless(ACTIVITY_WONDER_NEWS); break; } - data->state = MG_STATE_LINK_WAIT; + data->state = MG_STATE_CLIENT_LINK_WAIT; break; - case MG_STATE_LINK_WAIT: + case MG_STATE_CLIENT_LINK_WAIT: if (gReceivedRemoteLinkPlayers != 0) { ClearScreenInBg0(TRUE); - data->state = MG_STATE_COMMUNICATING; + data->state = MG_STATE_CLIENT_COMMUNICATING; MysteryGiftClient_Create(data->isWonderNews); } else if (gSpecialVar_Result == LINKUP_FAILED) { // Link failed, return to link start menu ClearScreenInBg0(TRUE); - data->state = MG_STATE_LINK_PROMPT; + data->state = MG_STATE_SOURCE_PROMPT; } break; - case MG_STATE_COMMUNICATING: + case MG_STATE_CLIENT_COMMUNICATING: AddTextPrinterToWindow1(gText_Communicating); - data->state = MG_STATE_COMMUNICATE; + data->state = MG_STATE_CLIENT_LINK; break; - case MG_STATE_COMMUNICATE: - switch (MysteryGiftClient_Run(&data->curPromptWindowId)) + case MG_STATE_CLIENT_LINK: + switch (MysteryGiftClient_Run(&data->var)) { case CLI_RET_END: Rfu_SetCloseLinkCallback(); - data->prevPromptWindowId = data->curPromptWindowId; - data->state = MG_STATE_LINK_COMPLETE_WAIT; + data->msgId = data->var; + data->state = MG_STATE_CLIENT_LINK_END; break; - case CLI_RET_5: - memcpy(data->buffer, mevent_client_get_buffer(), 0x40); + case CLI_RET_COPY_MSG: + memcpy(data->clientMsg, MysteryGiftClient_GetMsg(), 0x40); MysteryGiftClient_AdvanceState(); break; - case CLI_RET_3: - data->state = MG_STATE_10; + case CLI_RET_PRINT_MSG: + data->state = MG_STATE_CLIENT_MESSAGE; break; - case CLI_RET_2: - data->state = MG_STATE_9; + case CLI_RET_YES_NO: + data->state = MG_STATE_CLIENT_YES_NO; break; case CLI_RET_ASK_TOSS: - data->state = MG_STATE_LINK_ASK_TOSS; + data->state = MG_STATE_CLIENT_ASK_TOSS; StringCopy(gStringVar1, gLinkPlayers[0].name); break; } break; - case MG_STATE_9: - input = DoMysteryGiftYesNo(&data->textState, &data->curPromptWindowId, FALSE, mevent_client_get_buffer()); + case MG_STATE_CLIENT_YES_NO: + input = DoMysteryGiftYesNo(&data->textState, &data->var, FALSE, MysteryGiftClient_GetMsg()); switch (input) { case 0: // Yes - MysteryGiftClient_SetParam(0); + MysteryGiftClient_SetParam(FALSE); MysteryGiftClient_AdvanceState(); - data->state = MG_STATE_COMMUNICATING; + data->state = MG_STATE_CLIENT_COMMUNICATING; break; case 1: // No case MENU_B_PRESSED: - MysteryGiftClient_SetParam(1); + MysteryGiftClient_SetParam(TRUE); MysteryGiftClient_AdvanceState(); - data->state = MG_STATE_COMMUNICATING; + data->state = MG_STATE_CLIENT_COMMUNICATING; break; } break; - case MG_STATE_10: - if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, mevent_client_get_buffer())) + case MG_STATE_CLIENT_MESSAGE: + if (PrintMysteryGiftMenuMessage(&data->textState, MysteryGiftClient_GetMsg())) { MysteryGiftClient_AdvanceState(); - data->state = MG_STATE_COMMUNICATING; + data->state = MG_STATE_CLIENT_COMMUNICATING; } break; - case MG_STATE_LINK_ASK_TOSS: - input = DoMysteryGiftYesNo(&data->textState, &data->curPromptWindowId, FALSE, gText_ThrowAwayWonderCard); + case MG_STATE_CLIENT_ASK_TOSS: + // Player is receiving a new Wonder Card/News but needs to toss an existing one to make room. + // Ask for confirmation. + input = DoMysteryGiftYesNo(&data->textState, &data->var, FALSE, gText_ThrowAwayWonderCard); switch (input) { case 0: // Yes - if (CheckReceivedGiftFromWonderCard() == TRUE) + if (IsSavedWonderCardGiftNotReceived() == TRUE) { - data->state = MG_STATE_LINK_ASK_TOSS_UNRECEIVED; + data->state = MG_STATE_CLIENT_ASK_TOSS_UNRECEIVED; } else { - MysteryGiftClient_SetParam(0); + MysteryGiftClient_SetParam(FALSE); MysteryGiftClient_AdvanceState(); - data->state = MG_STATE_COMMUNICATING; + data->state = MG_STATE_CLIENT_COMMUNICATING; } break; case 1: // No case MENU_B_PRESSED: - MysteryGiftClient_SetParam(1); + MysteryGiftClient_SetParam(TRUE); MysteryGiftClient_AdvanceState(); - data->state = MG_STATE_COMMUNICATING; + data->state = MG_STATE_CLIENT_COMMUNICATING; break; } break; - case MG_STATE_LINK_ASK_TOSS_UNRECEIVED: - input = DoMysteryGiftYesNo(&data->textState, &data->curPromptWindowId, FALSE, gText_HaventReceivedCardsGift); + case MG_STATE_CLIENT_ASK_TOSS_UNRECEIVED: + // Player has selected to toss a Wonder Card that they haven't received the gift for. + // Ask for confirmation again. + input = DoMysteryGiftYesNo(&data->textState, &data->var, FALSE, gText_HaventReceivedCardsGift); switch (input) { case 0: // Yes - MysteryGiftClient_SetParam(0); + MysteryGiftClient_SetParam(FALSE); MysteryGiftClient_AdvanceState(); - data->state = MG_STATE_COMMUNICATING; + data->state = MG_STATE_CLIENT_COMMUNICATING; break; case 1: // No case MENU_B_PRESSED: - MysteryGiftClient_SetParam(1); + MysteryGiftClient_SetParam(TRUE); MysteryGiftClient_AdvanceState(); - data->state = MG_STATE_COMMUNICATING; + data->state = MG_STATE_CLIENT_COMMUNICATING; break; } break; - case MG_STATE_LINK_COMPLETE_WAIT: + case MG_STATE_CLIENT_LINK_END: if (gReceivedRemoteLinkPlayers == 0) { DestroyWirelessStatusIndicatorSprite(); - data->state = MG_STATE_LINK_COMPLETED; + data->state = MG_STATE_CLIENT_COMM_COMPLETED; } break; - case MG_STATE_LINK_COMPLETED: + case MG_STATE_CLIENT_COMM_COMPLETED: if (PrintStringAndWait2Seconds(&data->textState, gText_CommunicationCompleted)) { if (data->sourceIsFriend == TRUE) StringCopy(gStringVar1, gLinkPlayers[0].name); - data->state = MG_STATE_LINK_RESULT_MSG; + data->state = MG_STATE_CLIENT_RESULT_MSG; } break; - case MG_STATE_LINK_RESULT_MSG: - msg = GetStdMessage(&receivedMsg, data->isWonderNews, data->sourceIsFriend, data->prevPromptWindowId); + case MG_STATE_CLIENT_RESULT_MSG: + msg = GetClientResultMessage(&successMsg, data->isWonderNews, data->sourceIsFriend, data->msgId); if (msg == NULL) - msg = data->buffer; - if (receivedMsg) - input = PrintSuccessMessage(&data->textState, msg, &data->curPromptWindowId); + msg = data->clientMsg; + if (successMsg) + input = PrintSuccessMessage(&data->textState, msg, &data->var); else - input = MG_PrintTextOnWindow1AndWaitButton(&data->textState, msg); + input = PrintMysteryGiftMenuMessage(&data->textState, msg); // input var re-used, here it is TRUE if the message is finished if (input) { - if (data->prevPromptWindowId == 3) + if (data->msgId == CLI_MSG_NEWS_RECEIVED) { if (data->sourceIsFriend == TRUE) - GenerateRandomNews(1); + GenerateRandomWonderNews(1); else - GenerateRandomNews(2); + GenerateRandomWonderNews(2); } - if (!receivedMsg) + if (!successMsg) { // Did not receive card/news, return to main menu data->state = MG_STATE_TO_MAIN_MENU; @@ -1368,7 +1377,7 @@ static void Task_MysteryGift(u8 taskId) } break; case MG_STATE_SAVE_LOAD_GIFT: - if (mevent_save_game(&data->textState)) + if (SaveOnMysteryGiftMenu(&data->textState)) data->state = MG_STATE_LOAD_GIFT; break; case MG_STATE_LOAD_GIFT: @@ -1404,17 +1413,17 @@ static void Task_MysteryGift(u8 taskId) u32 result; if (!data->isWonderNews) { - if (WonderCard_Test_Unk_08_6()) - result = HandleMysteryGiftListMenu(&data->textState, &data->curPromptWindowId, data->isWonderNews, FALSE); + if (IsSendingSavedWonderCardAllowed()) + result = HandleMysteryGiftListMenu(&data->textState, &data->var, data->isWonderNews, FALSE); else - result = HandleMysteryGiftListMenu(&data->textState, &data->curPromptWindowId, data->isWonderNews, TRUE); + result = HandleMysteryGiftListMenu(&data->textState, &data->var, data->isWonderNews, TRUE); } else { - if (WonderNews_Test_Unk_02()) - result = HandleMysteryGiftListMenu(&data->textState, &data->curPromptWindowId, data->isWonderNews, FALSE); + if (IsSendingSavedWonderNewsAllowed()) + result = HandleMysteryGiftListMenu(&data->textState, &data->var, data->isWonderNews, FALSE); else - result = HandleMysteryGiftListMenu(&data->textState, &data->curPromptWindowId, data->isWonderNews, TRUE); + result = HandleMysteryGiftListMenu(&data->textState, &data->var, data->isWonderNews, TRUE); } switch (result) { @@ -1436,11 +1445,11 @@ static void Task_MysteryGift(u8 taskId) break; } case MG_STATE_ASK_TOSS: - // Player is attempting to discard a Wonder Card/News - switch (AskDiscardGift(&data->textState, &data->curPromptWindowId, data->isWonderNews)) + // Player is attempting to discard a saved Wonder Card/News + switch (AskDiscardGift(&data->textState, &data->var, data->isWonderNews)) { case 0: // Yes - if (!data->isWonderNews && CheckReceivedGiftFromWonderCard() == TRUE) + if (!data->isWonderNews && IsSavedWonderCardGiftNotReceived() == TRUE) data->state = MG_STATE_ASK_TOSS_UNRECEIVED; else data->state = MG_STATE_TOSS; @@ -1454,7 +1463,7 @@ static void Task_MysteryGift(u8 taskId) case MG_STATE_ASK_TOSS_UNRECEIVED: // Player has selected to toss a Wonder Card that they haven't received the gift for. // Ask for confirmation again. - switch ((u32)DoMysteryGiftYesNo(&data->textState, &data->curPromptWindowId, TRUE, gText_HaventReceivedGiftOkayToDiscard)) + switch ((u32)DoMysteryGiftYesNo(&data->textState, &data->var, TRUE, gText_HaventReceivedGiftOkayToDiscard)) { case 0: // Yes data->state = MG_STATE_TOSS; @@ -1473,7 +1482,7 @@ static void Task_MysteryGift(u8 taskId) } break; case MG_STATE_TOSS_SAVE: - if (mevent_save_game(&data->textState)) + if (SaveOnMysteryGiftMenu(&data->textState)) data->state = MG_STATE_TOSSED; break; case MG_STATE_TOSSED: @@ -1489,7 +1498,7 @@ static void Task_MysteryGift(u8 taskId) break; case MG_STATE_RECEIVE: if (ExitWonderCardOrNews(data->isWonderNews, 1)) - data->state = MG_STATE_LINK_PROMPT; + data->state = MG_STATE_SOURCE_PROMPT; break; case MG_STATE_SEND: if (ExitWonderCardOrNews(data->isWonderNews, 1)) @@ -1504,14 +1513,14 @@ static void Task_MysteryGift(u8 taskId) break; } data->sourceIsFriend = TRUE; - data->state = MG_STATE_SEND_WAIT; + data->state = MG_STATE_SERVER_LINK_WAIT; } break; - case MG_STATE_SEND_WAIT: + case MG_STATE_SERVER_LINK_WAIT: if (gReceivedRemoteLinkPlayers != 0) { ClearScreenInBg0(1); - data->state = MG_STATE_SEND_START; + data->state = MG_STATE_SERVER_LINK_START; } else if (gSpecialVar_Result == LINKUP_FAILED) { @@ -1519,7 +1528,7 @@ static void Task_MysteryGift(u8 taskId) data->state = MG_STATE_LOAD_GIFT; } break; - case MG_STATE_SEND_START: + case MG_STATE_SERVER_LINK_START: *gStringVar1 = EOS; *gStringVar2 = EOS; *gStringVar3 = EOS; @@ -1527,40 +1536,40 @@ static void Task_MysteryGift(u8 taskId) if (!data->isWonderNews) { AddTextPrinterToWindow1(gText_SendingWonderCard); - mevent_srv_new_wcard(); + MysterGiftServer_CreateForCard(); } else { AddTextPrinterToWindow1(gText_SendingWonderNews); - mevent_srv_init_wnews(); + MysterGiftServer_CreateForNews(); } - data->state = MG_STATE_SENDING; + data->state = MG_STATE_SERVER_LINK; break; - case MG_STATE_SENDING: - if (mevent_srv_common_do_exec(&data->curPromptWindowId) == 3) + case MG_STATE_SERVER_LINK: + if (MysterGiftServer_Run(&data->var) == SVR_RET_END) { - data->prevPromptWindowId = data->curPromptWindowId; - data->state = MG_STATE_SEND_FINISH; + data->msgId = data->var; + data->state = MG_STATE_SERVER_LINK_END; } break; - case MG_STATE_SEND_FINISH: + case MG_STATE_SERVER_LINK_END: Rfu_SetCloseLinkCallback(); StringCopy(gStringVar1, gLinkPlayers[1].name); - data->state = MG_STATE_SEND_WAIT_END; + data->state = MG_STATE_SERVER_LINK_END_WAIT; break; - case MG_STATE_SEND_WAIT_END: + case MG_STATE_SERVER_LINK_END_WAIT: if (gReceivedRemoteLinkPlayers == 0) { DestroyWirelessStatusIndicatorSprite(); - data->state = MG_STATE_SEND_END; + data->state = MG_STATE_SERVER_RESULT_MSG; } break; - case MG_STATE_SEND_END: - if (PrintMGSendStatus(&data->textState, &data->curPromptWindowId, data->sourceIsFriend, data->prevPromptWindowId)) + case MG_STATE_SERVER_RESULT_MSG: + if (PrintServerResultMessage(&data->textState, &data->var, data->sourceIsFriend, data->msgId)) { - if (data->sourceIsFriend == TRUE && data->prevPromptWindowId == 3) + if (data->sourceIsFriend == TRUE && data->msgId == SVR_MSG_NEWS_SENT) { - GenerateRandomNews(3); + GenerateRandomWonderNews(3); data->state = MG_STATE_SAVE_LOAD_GIFT; } else @@ -1570,9 +1579,9 @@ static void Task_MysteryGift(u8 taskId) } } break; - case MG_STATE_LINK_ERROR_1: - case MG_STATE_LINK_ERROR_2: - if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, gText_CommunicationError)) + case MG_STATE_CLIENT_ERROR: + case MG_STATE_SERVER_ERROR: + if (PrintMysteryGiftMenuMessage(&data->textState, gText_CommunicationError)) { data->state = MG_STATE_TO_MAIN_MENU; PrintMysteryGiftOrEReaderTopMenu(FALSE, FALSE); @@ -1580,7 +1589,7 @@ static void Task_MysteryGift(u8 taskId) break; case MG_STATE_EXIT: CloseLink(); - Free(data->buffer); + Free(data->clientMsg); DestroyTask(taskId); SetMainCallback2(MainCB_FreeAllBuffersAndReturnToInitTitleScreen); break; diff --git a/src/new_game.c b/src/new_game.c index 2a950efbc..c4622820c 100644 --- a/src/new_game.c +++ b/src/new_game.c @@ -200,7 +200,7 @@ void NewGameInitData(void) ResetAllApprenticeData(); ClearRankingHallRecords(); InitMatchCallCounters(); - sub_801AFD8(); + ClearMysteryGift(); WipeTrainerNameRecords(); ResetTrainerHillResults(); ResetContestLinkResults(); diff --git a/src/script.c b/src/script.c index 6c2115dee..a3e223768 100644 --- a/src/script.c +++ b/src/script.c @@ -3,6 +3,7 @@ #include "event_data.h" #include "mevent.h" #include "util.h" +#include "constants/maps.h" #include "constants/map_scripts.h" #define RAM_SCRIPT_MAGIC 51 @@ -403,9 +404,9 @@ bool32 ValidateSavedRamScript(void) struct RamScriptData *scriptData = &gSaveBlock1Ptr->ramScript.data; if (scriptData->magic != RAM_SCRIPT_MAGIC) return FALSE; - if (scriptData->mapGroup != 0xFF) + if (scriptData->mapGroup != MAP_GROUP(UNDEFINED)) return FALSE; - if (scriptData->mapNum != 0xFF) + if (scriptData->mapNum != MAP_NUM(UNDEFINED)) return FALSE; if (scriptData->objectId != 0xFF) return FALSE; @@ -421,9 +422,9 @@ u8 *GetSavedRamScriptIfValid(void) return NULL; if (scriptData->magic != RAM_SCRIPT_MAGIC) return NULL; - if (scriptData->mapGroup != 0xFF) + if (scriptData->mapGroup != MAP_GROUP(UNDEFINED)) return NULL; - if (scriptData->mapNum != 0xFF) + if (scriptData->mapNum != MAP_NUM(UNDEFINED)) return NULL; if (scriptData->objectId != 0xFF) return NULL; @@ -442,5 +443,5 @@ void InitRamScript_NoObjectEvent(u8 *script, u16 scriptSize) { if (scriptSize > sizeof(gSaveBlock1Ptr->ramScript.data.script)) scriptSize = sizeof(gSaveBlock1Ptr->ramScript.data.script); - InitRamScript(script, scriptSize, 0xFF, 0xFF, 0xFF); + InitRamScript(script, scriptSize, MAP_GROUP(UNDEFINED), MAP_NUM(UNDEFINED), 0xFF); } diff --git a/src/trade.c b/src/trade.c index 60d999edd..f51a9f6e9 100644 --- a/src/trade.c +++ b/src/trade.c @@ -19,7 +19,7 @@ #include "load_save.h" #include "mail.h" #include "main.h" -#include "mevent2.h" +#include "mevent.h" #include "mystery_gift.h" #include "overworld.h" #include "palette.h" @@ -4655,9 +4655,8 @@ static void CB2_SaveAndEndTrade(void) if (!InUnionRoom()) IncrementGameStat(GAME_STAT_POKEMON_TRADES); if (gWirelessCommType) - { - RecordIdOfWonderCardSenderByEventType(2, gLinkPlayers[GetMultiplayerId() ^ 1].trainerId); - } + TryIncrementMysteryGiftStat(CARD_STAT_NUM_TRADES, gLinkPlayers[GetMultiplayerId() ^ 1].trainerId); + SetContinueGameWarpStatusToDynamicWarp(); sub_8153380(); gMain.state++; diff --git a/src/union_room.c b/src/union_room.c index 37d2434dd..1a7ccc8e3 100644 --- a/src/union_room.c +++ b/src/union_room.c @@ -1539,12 +1539,14 @@ static void Task_ExchangeCards(u8 taskId) { // Note: hasAllFrontierSymbols is a re-used field. // Here it is set by CreateTrainerCardInBuffer. + // If the player has a saved Wonder Card and it is the same Wonder Card + // as their partner then mystery gift stats are enabled. recvBuff = gBlockRecvBuffer[GetMultiplayerId() ^ 1]; - MEventHandleReceivedWonderCard(((struct TrainerCard *)recvBuff)->hasAllFrontierSymbols); + MysteryGift_TryEnableStatsByFlagId(((struct TrainerCard *)recvBuff)->hasAllFrontierSymbols); } else { - ResetReceivedWonderCardFlag(); + MysteryGift_DisableStats(); } ResetBlockReceivedFlags(); @@ -1640,7 +1642,7 @@ static void CreateTrainerCardInBuffer(void *dest, bool32 setWonderCard) static void Task_StartActivity(u8 taskId) { - ResetReceivedWonderCardFlag(); + MysteryGift_DisableStats(); switch (gPlayerCurrActivity) { case ACTIVITY_BATTLE_SINGLE: @@ -1937,7 +1939,7 @@ static void Task_SendMysteryGift(u8 taskId) } break; case 6: - if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, sText_LinkWithFriendDropped)) + if (PrintMysteryGiftMenuMessage(&data->textState, sText_LinkWithFriendDropped)) { data->playerCount = LeaderPrunePlayerList(data->playerList); RedrawListMenu(data->listTaskId); @@ -2034,7 +2036,7 @@ static void Task_SendMysteryGift(u8 taskId) data->state++; break; case 14: - if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, sText_PleaseStartOver)) + if (PrintMysteryGiftMenuMessage(&data->textState, sText_PleaseStartOver)) { DestroyTask(taskId); gSpecialVar_Result = LINKUP_FAILED; @@ -2212,7 +2214,7 @@ static void Task_CardOrNewsWithFriend(u8 taskId) data->state++; break; case 9: - if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, sLinkDroppedTexts[RfuGetStatus()])) + if (PrintMysteryGiftMenuMessage(&data->textState, sLinkDroppedTexts[RfuGetStatus()])) { DestroyWirelessStatusIndicatorSprite(); DestroyTask(taskId); @@ -2380,7 +2382,7 @@ static void Task_CardOrNewsOverWireless(u8 taskId) data->state++; break; case 9: - if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, sText_WirelessLinkDropped)) + if (PrintMysteryGiftMenuMessage(&data->textState, sText_WirelessLinkDropped)) { DestroyWirelessStatusIndicatorSprite(); DestroyTask(taskId); @@ -2389,7 +2391,7 @@ static void Task_CardOrNewsOverWireless(u8 taskId) } break; case 7: - if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, sText_WirelessSearchCanceled)) + if (PrintMysteryGiftMenuMessage(&data->textState, sText_WirelessSearchCanceled)) { DestroyWirelessStatusIndicatorSprite(); DestroyTask(taskId); @@ -2398,7 +2400,7 @@ static void Task_CardOrNewsOverWireless(u8 taskId) } break; case 11: - if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, sNoWonderSharedTexts[data->isWonderNews])) + if (PrintMysteryGiftMenuMessage(&data->textState, sNoWonderSharedTexts[data->isWonderNews])) { DestroyWirelessStatusIndicatorSprite(); DestroyTask(taskId); diff --git a/src/wonder_transfer.c b/src/wonder_transfer.c index 1c456ecb3..f2754fbff 100644 --- a/src/wonder_transfer.c +++ b/src/wonder_transfer.c @@ -51,7 +51,7 @@ struct UnkStruct_203F3C8_02DC struct WonderCardData { /*0000*/ struct WonderCard card; - /*014c*/ struct MEventBuffer_3430 unk_014C; + /*014c*/ struct WonderCardMetadata cardMetadata; /*0170*/ const struct WonderGraphics * gfx; /*0174*/ u8 enterExitState; /*0175*/ u8 unk_0175; @@ -81,7 +81,14 @@ static const u8 sCard_TextColorTable[][3] = { {TEXT_COLOR_TRANSPARENT, TEXT_COLOR_DARK_GRAY, TEXT_COLOR_LIGHT_GRAY}, {TEXT_COLOR_TRANSPARENT, TEXT_COLOR_WHITE, TEXT_COLOR_DARK_GRAY} }; -const u8 ALIGNED(4) sCard_TextYOffsets[3] = {7, 4, 7}; + +static const u8 ALIGNED(4) sCard_TextYOffsets[CARD_TYPE_COUNT] = +{ + [CARD_TYPE_GIFT] = 7, + [CARD_TYPE_STAMP] = 4, + [CARD_TYPE_LINK_STAT] = 7 +}; + static const struct WindowTemplate sCard_WindowTemplates[] = { [CARD_WIN_0] = { .bg = 1, @@ -176,21 +183,21 @@ static const struct WonderGraphics sCardGraphics[NUM_WONDER_BGS] = { {.textPal1 = 1, .textPal2 = 0, .textPal3 = 0, .textPal4 = 7, .tiles = sWonderCardBgGfx8, .map = sWonderCardBgTilemap8, .pal = sWonderCardBgPal8} }; -bool32 WonderCard_Init(struct WonderCard * card, struct MEventBuffer_3430 * r6) +bool32 WonderCard_Init(struct WonderCard * card, struct WonderCardMetadata * metadata) { - if (card == NULL || r6 == NULL) + if (card == NULL || metadata == NULL) return FALSE; sWonderCardData = AllocZeroed(sizeof(*sWonderCardData)); if (sWonderCardData == NULL) return FALSE; sWonderCardData->card = *card; - sWonderCardData->unk_014C = *r6; - if (sWonderCardData->card.bgType >= ARRAY_COUNT(sCardGraphics)) + sWonderCardData->cardMetadata = *metadata; + if (sWonderCardData->card.bgType >= NUM_WONDER_BGS) sWonderCardData->card.bgType = 0; - if (sWonderCardData->card.unk_08_0 >= ARRAY_COUNT(sCard_TextYOffsets)) - sWonderCardData->card.unk_08_0 = 0; - if (sWonderCardData->card.unk_09 > ARRAY_COUNT(sWonderCardData->unk_017D)) - sWonderCardData->card.unk_09 = 0; + if (sWonderCardData->card.type >= CARD_TYPE_COUNT) + sWonderCardData->card.type = 0; + if (sWonderCardData->card.maxStamps > ARRAY_COUNT(sWonderCardData->unk_017D)) + sWonderCardData->card.maxStamps = 0; sWonderCardData->gfx = &sCardGraphics[sWonderCardData->card.bgType]; return TRUE; } @@ -337,20 +344,20 @@ static void BufferCardText(void) } memcpy(sWonderCardData->unk_0288, sWonderCardData->card.unk_FA, WONDER_CARD_TEXT_LENGTH); sWonderCardData->unk_0288[WONDER_CARD_TEXT_LENGTH] = EOS; - switch (sWonderCardData->card.unk_08_0) + switch (sWonderCardData->card.type) { - case 0: + case CARD_TYPE_GIFT: memcpy(sWonderCardData->unk_02B1, sWonderCardData->card.unk_122, WONDER_CARD_TEXT_LENGTH); sWonderCardData->unk_02B1[WONDER_CARD_TEXT_LENGTH] = EOS; break; - case 1: + case CARD_TYPE_STAMP: sWonderCardData->unk_02B1[0] = EOS; break; - case 2: + case CARD_TYPE_LINK_STAT: sWonderCardData->unk_02B1[0] = EOS; - sp0[0] = sWonderCardData->unk_014C.unk_00 < 999 ? sWonderCardData->unk_014C.unk_00 : 999; - sp0[1] = sWonderCardData->unk_014C.unk_02 < 999 ? sWonderCardData->unk_014C.unk_02 : 999; - sp0[2] = sWonderCardData->unk_014C.unk_04 < 999 ? sWonderCardData->unk_014C.unk_04 : 999; + sp0[0] = sWonderCardData->cardMetadata.battlesWon < MAX_WONDER_CARD_STAT ? sWonderCardData->cardMetadata.battlesWon : MAX_WONDER_CARD_STAT; + sp0[1] = sWonderCardData->cardMetadata.battlesLost < MAX_WONDER_CARD_STAT ? sWonderCardData->cardMetadata.battlesLost : MAX_WONDER_CARD_STAT; + sp0[2] = sWonderCardData->cardMetadata.numTrades < MAX_WONDER_CARD_STAT ? sWonderCardData->cardMetadata.numTrades : MAX_WONDER_CARD_STAT; for (i = 0; i < 8; i++) { memset(sWonderCardData->unk_02DC[i].unk_42, EOS, sizeof(sWonderCardData->unk_02DC[i].unk_42)); @@ -410,15 +417,15 @@ static void DrawCardWindow(u8 whichWindow) AddTextPrinterParameterized3(windowId, 3, 0, 16 * sp0C + 2, sCard_TextColorTable[sWonderCardData->gfx->textPal2], 0, sWonderCardData->unk_01E4[sp0C]); break; case CARD_WIN_2: - AddTextPrinterParameterized3(windowId, 3, 0, sCard_TextYOffsets[sWonderCardData->card.unk_08_0], sCard_TextColorTable[sWonderCardData->gfx->textPal3], 0, sWonderCardData->unk_0288); - if (sWonderCardData->card.unk_08_0 != 2) + AddTextPrinterParameterized3(windowId, 3, 0, sCard_TextYOffsets[sWonderCardData->card.type], sCard_TextColorTable[sWonderCardData->gfx->textPal3], 0, sWonderCardData->unk_0288); + if (sWonderCardData->card.type != CARD_TYPE_LINK_STAT) { - AddTextPrinterParameterized3(windowId, 3, 0, 16 + sCard_TextYOffsets[sWonderCardData->card.unk_08_0], sCard_TextColorTable[sWonderCardData->gfx->textPal3], 0, sWonderCardData->unk_02B1); + AddTextPrinterParameterized3(windowId, 3, 0, 16 + sCard_TextYOffsets[sWonderCardData->card.type], sCard_TextColorTable[sWonderCardData->gfx->textPal3], 0, sWonderCardData->unk_02B1); } else { s32 x = 0; - s32 y = sCard_TextYOffsets[sWonderCardData->card.unk_08_0] + 16; + s32 y = sCard_TextYOffsets[sWonderCardData->card.type] + 16; s32 spacing = GetFontAttribute(3, FONTATTR_LETTER_SPACING); for (; sp0C < sWonderCardData->unk_0175; sp0C++) { @@ -438,26 +445,26 @@ static void DrawCardWindow(u8 whichWindow) static void CreateCardSprites(void) { - u8 r7 = 0; + u8 i = 0; sWonderCardData->monIconSpriteId = SPRITE_NONE; - if (sWonderCardData->unk_014C.unk_06 != SPECIES_NONE) + if (sWonderCardData->cardMetadata.iconSpecies != SPECIES_NONE) { - sWonderCardData->monIconSpriteId = CreateMonIconNoPersonality(GetIconSpeciesNoPersonality(sWonderCardData->unk_014C.unk_06), SpriteCallbackDummy, 220, 20, 0, FALSE); + sWonderCardData->monIconSpriteId = CreateMonIconNoPersonality(GetIconSpeciesNoPersonality(sWonderCardData->cardMetadata.iconSpecies), SpriteCallbackDummy, 220, 20, 0, FALSE); gSprites[sWonderCardData->monIconSpriteId].oam.priority = 2; } - if (sWonderCardData->card.unk_09 != 0 && sWonderCardData->card.unk_08_0 == 1) + if (sWonderCardData->card.maxStamps != 0 && sWonderCardData->card.type == CARD_TYPE_STAMP) { LoadCompressedSpriteSheetUsingHeap(&sSpriteSheet_IconShadow); LoadSpritePalette(&sSpritePalettes_IconShadow[sWonderCardData->gfx->textPal4]); - for (; r7 < sWonderCardData->card.unk_09; r7++) + for (; i < sWonderCardData->card.maxStamps; i++) { - sWonderCardData->unk_017D[r7][0] = SPRITE_NONE; - sWonderCardData->unk_017D[r7][1] = SPRITE_NONE; - sWonderCardData->unk_017D[r7][0] = CreateSprite(&sSpriteTemplate_IconShadow, 216 - 32 * r7, 144, 8); - if (sWonderCardData->unk_014C.unk_08[0][r7] != SPECIES_NONE) - sWonderCardData->unk_017D[r7][1] = CreateMonIconNoPersonality(GetIconSpeciesNoPersonality(sWonderCardData->unk_014C.unk_08[0][r7]), + sWonderCardData->unk_017D[i][0] = SPRITE_NONE; + sWonderCardData->unk_017D[i][1] = SPRITE_NONE; + sWonderCardData->unk_017D[i][0] = CreateSprite(&sSpriteTemplate_IconShadow, 216 - 32 * i, 144, 8); + if (sWonderCardData->cardMetadata.stampData[0][i] != SPECIES_NONE) + sWonderCardData->unk_017D[i][1] = CreateMonIconNoPersonality(GetIconSpeciesNoPersonality(sWonderCardData->cardMetadata.stampData[0][i]), SpriteCallbackDummy, - 216 - 32 * r7, + 216 - 32 * i, 136, 0, 0); } } @@ -465,17 +472,17 @@ static void CreateCardSprites(void) static void DestroyCardSprites(void) { - u8 r6 = 0; + u8 i = 0; if (sWonderCardData->monIconSpriteId != SPRITE_NONE) FreeAndDestroyMonIconSprite(&gSprites[sWonderCardData->monIconSpriteId]); - if (sWonderCardData->card.unk_09 != 0 && sWonderCardData->card.unk_08_0 == 1) + if (sWonderCardData->card.maxStamps != 0 && sWonderCardData->card.type == CARD_TYPE_STAMP) { - for (; r6 < sWonderCardData->card.unk_09; r6++) + for (; i < sWonderCardData->card.maxStamps; i++) { - if (sWonderCardData->unk_017D[r6][0] != SPRITE_NONE) - DestroySprite(&gSprites[sWonderCardData->unk_017D[r6][0]]); - if (sWonderCardData->unk_017D[r6][1] != SPRITE_NONE) - FreeAndDestroyMonIconSprite(&gSprites[sWonderCardData->unk_017D[r6][1]]); + if (sWonderCardData->unk_017D[i][0] != SPRITE_NONE) + DestroySprite(&gSprites[sWonderCardData->unk_017D[i][0]]); + if (sWonderCardData->unk_017D[i][1] != SPRITE_NONE) + FreeAndDestroyMonIconSprite(&gSprites[sWonderCardData->unk_017D[i][1]]); } FreeSpriteTilesByTag(TAG_ICON_SHADOW); FreeSpritePaletteByTag(TAG_ICON_SHADOW);