From 3c3101b72ca9e2d1dad163bba0e4360b31103d73 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Sat, 19 Nov 2022 18:39:26 -0500 Subject: [PATCH 1/8] Sync mevent file names --- common_syms/{mevent.txt => mystery_gift.txt} | 0 include/link_rfu.h | 2 +- include/{mevent.h => mystery_gift.h} | 6 ++--- ...{mevent_server.h => mystery_gift_server.h} | 6 ++--- include/strings.h | 2 +- include/{menews_jisan.h => wonder_news.h} | 6 ++--- ld_script.txt | 24 +++++++++---------- src/cable_club.c | 2 +- src/easy_chat.c | 2 +- src/easy_chat_2.c | 2 +- src/field_control_avatar.c | 2 +- src/field_specials.c | 2 +- src/{mevent.c => mystery_gift.c} | 4 ++-- ...{mevent_client.c => mystery_gift_client.c} | 4 ++-- ...t_server_helpers.c => mystery_gift_link.c} | 2 +- src/mystery_gift_menu.c | 6 ++--- ...event_scripts.c => mystery_gift_scripts.c} | 2 +- ...{mevent_server.c => mystery_gift_server.c} | 4 ++-- src/mystery_gift_show_card.c | 2 +- src/mystery_gift_show_news.c | 2 +- src/new_game.c | 2 +- src/script.c | 2 +- src/trade_scene.c | 2 +- src/union_room.c | 2 +- src/union_room_message.c | 2 +- src/{menews_jisan.c => wonder_news.c} | 4 ++-- sym_common.txt | 2 +- sym_ewram.txt | 8 +++---- 28 files changed, 53 insertions(+), 53 deletions(-) rename common_syms/{mevent.txt => mystery_gift.txt} (100%) rename include/{mevent.h => mystery_gift.h} (97%) rename include/{mevent_server.h => mystery_gift_server.h} (97%) rename include/{menews_jisan.h => wonder_news.h} (59%) rename src/{mevent.c => mystery_gift.c} (99%) rename src/{mevent_client.c => mystery_gift_client.c} (99%) rename src/{mevent_server_helpers.c => mystery_gift_link.c} (99%) rename src/{mevent_scripts.c => mystery_gift_scripts.c} (99%) rename src/{mevent_server.c => mystery_gift_server.c} (99%) rename src/{menews_jisan.c => wonder_news.c} (98%) diff --git a/common_syms/mevent.txt b/common_syms/mystery_gift.txt similarity index 100% rename from common_syms/mevent.txt rename to common_syms/mystery_gift.txt diff --git a/include/link_rfu.h b/include/link_rfu.h index e3b60ccb4..65d1cf6dd 100644 --- a/include/link_rfu.h +++ b/include/link_rfu.h @@ -324,7 +324,7 @@ void RfuSetNormalDisconnectMode(void); void SetUnionRoomChatPlayerData(u32 numPlayers); void ClearRecvCommands(void); -#include "mevent_server.h" +#include "mystery_gift_server.h" extern const struct mevent_server_cmd gServerScript_ClientCanceledCard[]; #endif //GUARD_LINK_RFU_H diff --git a/include/mevent.h b/include/mystery_gift.h similarity index 97% rename from include/mevent.h rename to include/mystery_gift.h index 92c664d46..e25598c9a 100644 --- a/include/mevent.h +++ b/include/mystery_gift.h @@ -1,5 +1,5 @@ -#ifndef GUARD_MEVENT_H -#define GUARD_MEVENT_H +#ifndef GUARD_MYSTERY_GIFT_H +#define GUARD_MYSTERY_GIFT_H #include "global.h" @@ -105,4 +105,4 @@ void MysteryGift_DisableStats(void); bool32 MysteryGift_TryEnableStatsByFlagId(u16 flagId); u16 GetWonderCardFlagId(void); -#endif //GUARD_MEVENT_H +#endif // GUARD_MYSTERY_GIFT_H diff --git a/include/mevent_server.h b/include/mystery_gift_server.h similarity index 97% rename from include/mevent_server.h rename to include/mystery_gift_server.h index 9560fe25f..06bac26f3 100644 --- a/include/mevent_server.h +++ b/include/mystery_gift_server.h @@ -1,5 +1,5 @@ -#ifndef GUARD_MEVENT_SERVER_H -#define GUARD_MEVENT_SERVER_H +#ifndef GUARD_MYSTERY_GIFT_SERVER_H +#define GUARD_MYSTERY_GIFT_SERVER_H #include "global.h" @@ -126,4 +126,4 @@ void mevent_srv_init_wnews(void); void mevent_srv_new_wcard(void); u32 mevent_srv_common_do_exec(u16 * a0); -#endif //GUARD_MEVENT_SERVER_H +#endif //GUARD_MYSTERY_GIFT_SERVER_H diff --git a/include/strings.h b/include/strings.h index 0d1fe4afa..8326616b0 100644 --- a/include/strings.h +++ b/include/strings.h @@ -1141,7 +1141,7 @@ extern const u8 gText_PeopleBattling[]; extern const u8 gText_PeopleInUnionRoom[]; extern const u8 gText_PeopleCommunicating[]; -// mevent +// mystery_gift extern const u8 gJPText_ReceiveMysteryGiftWithEReader[]; extern const u8 gJPText_SelectConnectFromEReaderMenu[]; extern const u8 gJPText_SelectConnectWithGBA[]; diff --git a/include/menews_jisan.h b/include/wonder_news.h similarity index 59% rename from include/menews_jisan.h rename to include/wonder_news.h index 8e1c251f9..ec845906e 100644 --- a/include/menews_jisan.h +++ b/include/wonder_news.h @@ -1,5 +1,5 @@ -#ifndef GUARD_MENEWS_JISAN_H -#define GUARD_MENEWS_JISAN_H +#ifndef GUARD_WONDER_NEWS_H +#define GUARD_WONDER_NEWS_H #include "global.h" @@ -7,4 +7,4 @@ void MENewsJisan_SetRandomReward(u32 a0); void MENewsJisanReset(void); void MENewsJisanStepCounter(void); -#endif //GUARD_MENEWS_JISAN_H +#endif //GUARD_WONDER_NEWS_H diff --git a/ld_script.txt b/ld_script.txt index 5c7a3751d..e19fa1ee6 100644 --- a/ld_script.txt +++ b/ld_script.txt @@ -275,13 +275,13 @@ SECTIONS { src/slot_machine.o(.text); src/roamer.o(.text); src/mystery_gift_menu.o(.text); - src/mevent.o(.text); - src/mevent_server_helpers.o(.text); - src/mevent_client.o(.text); - src/mevent_server.o(.text); + src/mystery_gift.o(.text); + src/mystery_gift_link.o(.text); + src/mystery_gift_client.o(.text); + src/mystery_gift_server.o(.text); src/mystery_gift_show_card.o(.text); src/mystery_gift_show_news.o(.text); - src/menews_jisan.o(.text); + src/wonder_news.o(.text); src/seagallop.o(.text); src/pokemon_jump.o(.text); src/berry_crush.o(.text); @@ -568,15 +568,15 @@ SECTIONS { src/slot_machine.o(.rodata); src/roamer.o(.rodata); src/mystery_gift_menu.o(.rodata); - src/mevent.o(.rodata); - src/mevent_server_helpers.o(.rodata); - src/mevent_client.o(.rodata); - src/mevent_server.o(.rodata); + src/mystery_gift.o(.rodata); + src/mystery_gift_link.o(.rodata); + src/mystery_gift_client.o(.rodata); + src/mystery_gift_server.o(.rodata); src/mystery_gift_show_card.o(.rodata); src/mystery_gift_show_news.o(.rodata); - src/mevent_scripts.o(.rodata); - src/menews_jisan.o(.rodata); - src/menews_jisan.o(.rodata.str1.4); + src/mystery_gift_scripts.o(.rodata); + src/wonder_news.o(.rodata); + src/wonder_news.o(.rodata.str1.4); src/seagallop.o(.rodata); src/pokemon_jump.o(.rodata); src/berry_crush.o(.rodata); diff --git a/src/cable_club.c b/src/cable_club.c index b3fbc1f78..730b42d3d 100644 --- a/src/cable_club.c +++ b/src/cable_club.c @@ -10,7 +10,7 @@ #include "link.h" #include "load_save.h" #include "m4a.h" -#include "mevent.h" +#include "mystery_gift.h" #include "new_menu_helpers.h" #include "overworld.h" #include "quest_log.h" diff --git a/src/easy_chat.c b/src/easy_chat.c index 096bda634..443500453 100644 --- a/src/easy_chat.c +++ b/src/easy_chat.c @@ -4,7 +4,7 @@ #include "easy_chat.h" #include "event_data.h" #include "field_message_box.h" -#include "mevent.h" +#include "mystery_gift.h" #include "menu.h" #include "mail.h" #include "pokedex.h" diff --git a/src/easy_chat_2.c b/src/easy_chat_2.c index 5a3c9a7cb..1688e92e0 100644 --- a/src/easy_chat_2.c +++ b/src/easy_chat_2.c @@ -3,7 +3,7 @@ #include "easy_chat.h" #include "event_data.h" #include "menu.h" -#include "mevent.h" +#include "mystery_gift.h" #include "overworld.h" #include "strings.h" #include "task.h" diff --git a/src/field_control_avatar.c b/src/field_control_avatar.c index 615a70e60..c673a0753 100644 --- a/src/field_control_avatar.c +++ b/src/field_control_avatar.c @@ -14,7 +14,7 @@ #include "field_specials.h" #include "item_menu.h" #include "link.h" -#include "menews_jisan.h" +#include "wonder_news.h" #include "metatile_behavior.h" #include "overworld.h" #include "renewable_hidden_items.h" diff --git a/src/field_specials.c b/src/field_specials.c index 84ffd75e3..8ee9bb04c 100644 --- a/src/field_specials.c +++ b/src/field_specials.c @@ -28,7 +28,7 @@ #include "pokedex.h" #include "text_window.h" #include "menu.h" -#include "mevent.h" +#include "mystery_gift.h" #include "naming_screen.h" #include "party_menu.h" #include "dynamic_placeholder_text_util.h" diff --git a/src/mevent.c b/src/mystery_gift.c similarity index 99% rename from src/mevent.c rename to src/mystery_gift.c index 984c792b3..a12238263 100644 --- a/src/mevent.c +++ b/src/mystery_gift.c @@ -12,11 +12,11 @@ #include "event_data.h" #include "battle_tower.h" #include "new_game.h" -#include "menews_jisan.h" +#include "wonder_news.h" #include "cereader_tool.h" #include "mystery_gift_menu.h" #include "help_system.h" -#include "mevent.h" +#include "mystery_gift.h" #include "strings.h" struct MEventTaskData1 diff --git a/src/mevent_client.c b/src/mystery_gift_client.c similarity index 99% rename from src/mevent_client.c rename to src/mystery_gift_client.c index e2d226ed6..289de83f4 100644 --- a/src/mevent_client.c +++ b/src/mystery_gift_client.c @@ -5,8 +5,8 @@ #include "script.h" #include "battle_tower.h" #include "mystery_event_script.h" -#include "mevent.h" -#include "mevent_server.h" +#include "mystery_gift.h" +#include "mystery_gift_server.h" static EWRAM_DATA struct mevent_client * s_mevent_client_ptr = NULL; diff --git a/src/mevent_server_helpers.c b/src/mystery_gift_link.c similarity index 99% rename from src/mevent_server_helpers.c rename to src/mystery_gift_link.c index 33148d539..f90151d6b 100644 --- a/src/mevent_server_helpers.c +++ b/src/mystery_gift_link.c @@ -2,7 +2,7 @@ #include "util.h" #include "link.h" #include "link_rfu.h" -#include "mevent_server.h" +#include "mystery_gift_server.h" static u32 mevent_receive_func(struct mevent_srv_sub *); static u32 mevent_send_func(struct mevent_srv_sub *); diff --git a/src/mystery_gift_menu.c b/src/mystery_gift_menu.c index b07a57ee0..7e65298cd 100644 --- a/src/mystery_gift_menu.c +++ b/src/mystery_gift_menu.c @@ -9,12 +9,12 @@ #include "title_screen.h" #include "list_menu.h" #include "link_rfu.h" -#include "mevent.h" +#include "mystery_gift.h" #include "save.h" #include "link.h" #include "event_data.h" -#include "mevent_server.h" -#include "menews_jisan.h" +#include "mystery_gift_server.h" +#include "wonder_news.h" #include "help_system.h" #include "strings.h" #include "constants/songs.h" diff --git a/src/mevent_scripts.c b/src/mystery_gift_scripts.c similarity index 99% rename from src/mevent_scripts.c rename to src/mystery_gift_scripts.c index 0c2918655..b99c16405 100644 --- a/src/mevent_scripts.c +++ b/src/mystery_gift_scripts.c @@ -1,5 +1,5 @@ #include "global.h" -#include "mevent_server.h" +#include "mystery_gift_server.h" extern const struct mevent_server_cmd gServerScript_ClientCanceledCard[]; diff --git a/src/mevent_server.c b/src/mystery_gift_server.c similarity index 99% rename from src/mevent_server.c rename to src/mystery_gift_server.c index 7d4929195..98211e2ae 100644 --- a/src/mevent_server.c +++ b/src/mystery_gift_server.c @@ -1,8 +1,8 @@ #include "global.h" #include "gflib.h" #include "script.h" -#include "mevent.h" -#include "mevent_server.h" +#include "mystery_gift.h" +#include "mystery_gift_server.h" EWRAM_DATA struct mevent_srv_common * s_mevent_srv_common_ptr = NULL; diff --git a/src/mystery_gift_show_card.c b/src/mystery_gift_show_card.c index c462bda76..16382ce8f 100644 --- a/src/mystery_gift_show_card.c +++ b/src/mystery_gift_show_card.c @@ -5,7 +5,7 @@ #include "new_menu_helpers.h" #include "pokemon_icon.h" #include "mystery_gift_menu.h" -#include "mevent.h" +#include "mystery_gift.h" #include "battle_anim.h" #include "constants/mystery_gift.h" diff --git a/src/mystery_gift_show_news.c b/src/mystery_gift_show_news.c index b97e74c8c..e1112d726 100644 --- a/src/mystery_gift_show_news.c +++ b/src/mystery_gift_show_news.c @@ -2,7 +2,7 @@ #include "gflib.h" #include "menu_indicators.h" #include "new_menu_helpers.h" -#include "mevent.h" +#include "mystery_gift.h" #include "mystery_gift_menu.h" #include "menu.h" #include "link_rfu.h" diff --git a/src/new_game.c b/src/new_game.c index d6400d763..18ff73e29 100644 --- a/src/new_game.c +++ b/src/new_game.c @@ -22,7 +22,7 @@ #include "berry.h" #include "easy_chat.h" #include "union_room_chat.h" -#include "mevent.h" +#include "mystery_gift.h" #include "renewable_hidden_items.h" #include "trainer_tower.h" #include "script.h" diff --git a/src/script.c b/src/script.c index 641c63572..9095ab3ba 100644 --- a/src/script.c +++ b/src/script.c @@ -7,7 +7,7 @@ extern void ResetContextNpcTextColor(void); // field_specials extern u16 CalcCRC16WithTable(u8 *data, int length); // util -extern bool32 ValidateReceivedWonderCard(void); // mevent +extern bool32 ValidateReceivedWonderCard(void); #define RAM_SCRIPT_MAGIC 51 diff --git a/src/trade_scene.c b/src/trade_scene.c index 50f8e4780..8e0e2598d 100644 --- a/src/trade_scene.c +++ b/src/trade_scene.c @@ -6,7 +6,7 @@ #include "trade.h" #include "link.h" #include "link_rfu.h" -#include "mevent.h" +#include "mystery_gift.h" #include "graphics.h" #include "strings.h" #include "menu.h" diff --git a/src/union_room.c b/src/union_room.c index 8b8410e3d..5c21a0ac6 100644 --- a/src/union_room.c +++ b/src/union_room.c @@ -20,7 +20,7 @@ #include "list_menu.h" #include "load_save.h" #include "menu.h" -#include "mevent.h" +#include "mystery_gift.h" #include "mystery_gift_menu.h" #include "new_menu_helpers.h" #include "overworld.h" diff --git a/src/union_room_message.c b/src/union_room_message.c index 21d74736f..d3c3c6e46 100644 --- a/src/union_room_message.c +++ b/src/union_room_message.c @@ -1,6 +1,6 @@ #include "global.h" #include "link_rfu.h" -#include "mevent_server.h" +#include "mystery_gift_server.h" #include "constants/union_room.h" ALIGNED(4) const u8 gText_UR_EmptyString[] = _(""); diff --git a/src/menews_jisan.c b/src/wonder_news.c similarity index 98% rename from src/menews_jisan.c rename to src/wonder_news.c index d8d4af917..20f0ab3e7 100644 --- a/src/menews_jisan.c +++ b/src/wonder_news.c @@ -1,8 +1,8 @@ #include "global.h" -#include "mevent.h" +#include "mystery_gift.h" #include "random.h" #include "event_data.h" -#include "menews_jisan.h" +#include "wonder_news.h" #include "constants/items.h" static u32 GetMENewsJisanRewardItem(struct WonderNewsMetadata *); diff --git a/sym_common.txt b/sym_common.txt index e130c3bf4..51b041064 100644 --- a/sym_common.txt +++ b/sym_common.txt @@ -40,7 +40,7 @@ .include "fame_checker.o" .include "help_system_util.o" .align 4 - .include "mevent.o" + .include "mystery_gift.o" .align 4 .include "battle_controller_pokedude.o" .align 4 diff --git a/sym_ewram.txt b/sym_ewram.txt index f957d320b..cee4e8281 100644 --- a/sym_ewram.txt +++ b/sym_ewram.txt @@ -121,10 +121,10 @@ .include "src/slot_machine.o" .include "src/roamer.o" .include "src/mystery_gift_menu.o" - .include "src/mevent.o" - .include "src/mevent_server_helpers.o" - .include "src/mevent_client.o" - .include "src/mevent_server.o" + .include "src/mystery_gift.o" + .include "src/mystery_gift_link.o" + .include "src/mystery_gift_client.o" + .include "src/mystery_gift_server.o" .include "src/mystery_gift_show_card.o" .include "src/mystery_gift_show_news.o" .include "src/seagallop.o" From 6d6f207eb4a6348ccf63fdddd7c904ea977cf60b Mon Sep 17 00:00:00 2001 From: GriffinR Date: Sat, 19 Nov 2022 18:52:29 -0500 Subject: [PATCH 2/8] Initial mystery gift sync --- data/mystery_event_msg.s | 8 +- data/scripts/cable_club.inc | 2 +- data/specials.inc | 2 +- include/constants/flags.h | 42 +-- include/constants/vars.h | 2 +- include/easy_chat.h | 2 +- include/event_data.h | 4 +- include/global.h | 4 +- include/main.h | 3 +- include/mystery_gift.h | 68 ++-- include/mystery_gift_server.h | 2 +- include/wonder_news.h | 13 +- src/easy_chat.c | 4 +- src/easy_chat_2.c | 2 +- src/event_data.c | 4 +- src/field_control_avatar.c | 2 +- src/field_specials.c | 10 +- src/mystery_gift.c | 588 ++++++++++++++++++---------------- src/mystery_gift_client.c | 12 +- src/mystery_gift_menu.c | 56 +--- src/mystery_gift_server.c | 16 +- src/new_game.c | 2 +- src/script.c | 4 +- src/wonder_news.c | 97 +++--- 24 files changed, 488 insertions(+), 461 deletions(-) diff --git a/data/mystery_event_msg.s b/data/mystery_event_msg.s index 26048ca52..fed033c39 100644 --- a/data/mystery_event_msg.s +++ b/data/mystery_event_msg.s @@ -208,7 +208,7 @@ MysteryEventScript_AuroraTicket:: setvaddress MysteryEventScript_AuroraTicket lock faceplayer - vgoto_if_set FLAG_GOT_AURORA_TICKET, AuroraTicket_Obtained + vgoto_if_set FLAG_RECEIVED_AURORA_TICKET, AuroraTicket_Obtained vgoto_if_set FLAG_FOUGHT_DEOXYS, AuroraTicket_Obtained checkitem ITEM_AURORA_TICKET, 1 vgoto_if_eq VAR_RESULT, TRUE, AuroraTicket_Obtained @@ -219,7 +219,7 @@ MysteryEventScript_AuroraTicket:: vgoto_if_eq VAR_RESULT, FALSE, AuroraTicket_NoBagSpace giveitem ITEM_AURORA_TICKET setflag FLAG_ENABLE_SHIP_BIRTH_ISLAND - setflag FLAG_GOT_AURORA_TICKET + setflag FLAG_RECEIVED_AURORA_TICKET vmessage sText_AuroraTicket2 waitmessage waitbuttonpress @@ -266,7 +266,7 @@ MysteryEventScript_MysticTicket:: setvaddress MysteryEventScript_MysticTicket lock faceplayer - vgoto_if_set FLAG_GOT_MYSTIC_TICKET, MysticTicket_Obtained + vgoto_if_set FLAG_RECEIVED_MYSTIC_TICKET, MysticTicket_Obtained vgoto_if_set FLAG_FOUGHT_LUGIA, MysticTicket_Obtained vgoto_if_set FLAG_FOUGHT_HO_OH, MysticTicket_Obtained checkitem ITEM_MYSTIC_TICKET, 1 @@ -278,7 +278,7 @@ MysteryEventScript_MysticTicket:: vgoto_if_eq VAR_RESULT, FALSE, MysticTicket_NoBagSpace giveitem ITEM_MYSTIC_TICKET setflag FLAG_ENABLE_SHIP_NAVEL_ROCK - setflag FLAG_GOT_MYSTIC_TICKET + setflag FLAG_RECEIVED_MYSTIC_TICKET vmessage sText_MysticTicket1 waitmessage waitbuttonpress diff --git a/data/scripts/cable_club.inc b/data/scripts/cable_club.inc index f725dbaea..e7f53ada2 100644 --- a/data/scripts/cable_club.inc +++ b/data/scripts/cable_club.inc @@ -3,7 +3,7 @@ CableClub_OnTransition:: end CableClub_EventScript_HideOrShowMysteryGiftMan:: - specialvar VAR_RESULT, ValidateReceivedWonderCard + specialvar VAR_RESULT, ValidateSavedWonderCard goto_if_eq VAR_RESULT, FALSE, EventScript_HideMysteryGiftMan clearflag FLAG_HIDE_MG_DELIVERYMEN return diff --git a/data/specials.inc b/data/specials.inc index f815d05d6..5c6e5eb0c 100644 --- a/data/specials.inc +++ b/data/specials.inc @@ -392,7 +392,7 @@ gSpecials:: def_special Script_SetHelpContext def_special BackupHelpContext def_special RestoreHelpContext - def_special ValidateReceivedWonderCard + def_special ValidateSavedWonderCard def_special SetUnlockedPokedexFlags def_special InitUnionRoom def_special BufferUnionRoomPlayerName diff --git a/include/constants/flags.h b/include/constants/flags.h index 5baa6c75c..24e44dd9e 100644 --- a/include/constants/flags.h +++ b/include/constants/flags.h @@ -701,26 +701,28 @@ #define FLAG_0x2A4 0x2A4 #define FLAG_CAN_USE_ROCKET_HIDEOUT_LIFT 0x2A5 #define FLAG_GOT_TEA 0x2A6 -#define FLAG_GOT_AURORA_TICKET 0x2A7 -#define FLAG_GOT_MYSTIC_TICKET 0x2A8 -#define FLAG_0x2A9 0x2A9 -#define FLAG_0x2AA 0x2AA -#define FLAG_0x2AB 0x2AB -#define FLAG_0x2AC 0x2AC -#define FLAG_0x2AD 0x2AD -#define FLAG_0x2AE 0x2AE -#define FLAG_0x2AF 0x2AF -#define FLAG_0x2B0 0x2B0 -#define FLAG_0x2B1 0x2B1 -#define FLAG_0x2B2 0x2B2 -#define FLAG_0x2B3 0x2B3 -#define FLAG_0x2B4 0x2B4 -#define FLAG_0x2B5 0x2B5 -#define FLAG_0x2B6 0x2B6 -#define FLAG_0x2B7 0x2B7 -#define FLAG_0x2B8 0x2B8 -#define FLAG_0x2B9 0x2B9 -#define FLAG_0x2BA 0x2BA +#define FLAG_RECEIVED_AURORA_TICKET 0x2A7 +#define FLAG_RECEIVED_MYSTIC_TICKET 0x2A8 +#define FLAG_RECEIVED_OLD_SEA_MAP 0x2A9 +#define FLAG_WONDER_CARD_UNUSED_1 0x2AA +#define FLAG_WONDER_CARD_UNUSED_2 0x2AB +#define FLAG_WONDER_CARD_UNUSED_3 0x2AC +#define FLAG_WONDER_CARD_UNUSED_4 0x2AD +#define FLAG_WONDER_CARD_UNUSED_5 0x2AE +#define FLAG_WONDER_CARD_UNUSED_6 0x2AF +#define FLAG_WONDER_CARD_UNUSED_7 0x2B0 +#define FLAG_WONDER_CARD_UNUSED_8 0x2B1 +#define FLAG_WONDER_CARD_UNUSED_9 0x2B2 +#define FLAG_WONDER_CARD_UNUSED_10 0x2B3 +#define FLAG_WONDER_CARD_UNUSED_11 0x2B4 +#define FLAG_WONDER_CARD_UNUSED_12 0x2B5 +#define FLAG_WONDER_CARD_UNUSED_13 0x2B6 +#define FLAG_WONDER_CARD_UNUSED_14 0x2B7 +#define FLAG_WONDER_CARD_UNUSED_15 0x2B8 +#define FLAG_WONDER_CARD_UNUSED_16 0x2B9 +#define FLAG_WONDER_CARD_UNUSED_17 0x2BA +#define NUM_WONDER_CARD_FLAGS (1 + FLAG_WONDER_CARD_UNUSED_17 - FLAG_RECEIVED_AURORA_TICKET) + #define FLAG_GOT_POWDER_JAR 0x2BB #define FLAG_FOUGHT_MEWTWO 0x2BC #define FLAG_FOUGHT_MOLTRES 0x2BD diff --git a/include/constants/vars.h b/include/constants/vars.h index 56dafee12..5c7bbf8a3 100644 --- a/include/constants/vars.h +++ b/include/constants/vars.h @@ -84,7 +84,7 @@ // Bits 12-15 are the same for the player's party. // Used by Quest Log. #define VAR_QUEST_LOG_MON_COUNTS 0x4027 -#define VAR_MENEWS_JISAN_STEP_COUNTER 0x4028 +#define VAR_WONDER_NEWS_STEP_COUNTER 0x4028 #define VAR_0x4029 0x4029 #define VAR_0x402A 0x402A #define VAR_0x402B 0x402B diff --git a/include/easy_chat.h b/include/easy_chat.h index 853060f4f..ec5488bca 100644 --- a/include/easy_chat.h +++ b/include/easy_chat.h @@ -36,7 +36,7 @@ struct EasyChatWordsByLetter u8 *CopyEasyChatWord(u8 *dest, u16 word); u8 *ConvertEasyChatWordsToString(u8 *dest, const u16 *src, u16 columns, u16 rows); bool8 EC_DoesEasyChatStringFitOnLine(const u16 *easyChatWords, u8 columns, u8 rows, u16 maxLength); -void EC_ResetMEventProfileMaybe(void); +void InitQuestionnaireWords(void); void InitEasyChatPhrases(void); void EnableRareWord(u8); bool8 InitEasyChatSelection(void); diff --git a/include/event_data.h b/include/event_data.h index 5a6f98c6c..285b4cc83 100644 --- a/include/event_data.h +++ b/include/event_data.h @@ -49,8 +49,8 @@ bool8 FlagGet(u16 id); u16 * GetVarPointer(u16 id); bool32 IsMysteryGiftEnabled(void); void ResetSpecialVars(void); -void ResetMysteryEventFlags(void); -void ResetMysteryEventVars(void); +void ClearMysteryGiftFlags(void); +void ClearMysteryGiftVars(void); bool32 IsNationalPokedexEnabled(void); void EnableNationalPokedex_RSE(void); void ClearTempFieldEventData(void); diff --git a/include/global.h b/include/global.h index 79dedcdc2..417cee4f7 100644 --- a/include/global.h +++ b/include/global.h @@ -627,7 +627,7 @@ struct FameCheckerSaveData struct WonderNewsMetadata { - u8 unk_0_0:2; + u8 newsType:2; u8 unk_0_2:3; u8 unk_0_5:3; u8 berry; @@ -635,7 +635,7 @@ struct WonderNewsMetadata struct WonderNews { - u16 newsId; + u16 id; u8 sendType; // SEND_TYPE_* u8 bgType; u8 titleText[WONDER_NEWS_TEXT_LENGTH]; diff --git a/include/main.h b/include/main.h index a27145c7b..4a5f79a9d 100644 --- a/include/main.h +++ b/include/main.h @@ -69,7 +69,8 @@ void StartTimer1(void); void SeedRngAndSetTrainerId(void); u16 GetGeneratedTrainerIdLower(void); -extern const char RomHeaderGameCode[4]; +#define GAME_CODE_LENGTH 4 +extern const char RomHeaderGameCode[GAME_CODE_LENGTH]; extern const char RomHeaderSoftwareVersion; extern u8 gLinkTransferringData; diff --git a/include/mystery_gift.h b/include/mystery_gift.h index e25598c9a..a8ec84f86 100644 --- a/include/mystery_gift.h +++ b/include/mystery_gift.h @@ -2,6 +2,8 @@ #define GUARD_MYSTERY_GIFT_H #include "global.h" +#include "main.h" +#include "constants/mystery_gift.h" #define CARD_STAT_BATTLES_WON 0 #define CARD_STAT_BATTLES_LOST 1 @@ -17,21 +19,21 @@ enum { NEWS_INPUT_NONE = 0xFF }; -struct MEventClientHeaderStruct +struct MysteryGiftLinkGameData { u32 unk_00; u16 unk_04; u32 unk_08; u16 unk_0C; u32 unk_10; - u16 id; - u16 unk_16[4]; - struct WonderCardMetadata unk_20; - u8 maxDistributionMons; - u8 playerName[7]; - u8 playerTrainerId[4]; - u16 easyChatProfile[6]; - u8 gameCode[4]; + u16 flagId; + u16 questionnaireWords[NUM_QUESTIONNAIRE_WORDS]; + struct WonderCardMetadata cardMetadata; + u8 maxStamps; + u8 playerName[PLAYER_NAME_LENGTH]; + u8 playerTrainerId[TRAINER_ID_LENGTH]; + u16 easyChatProfile[EASY_CHAT_BATTLE_WORDS_COUNT]; + u8 gameCode[GAME_CODE_LENGTH]; u8 version; }; @@ -66,41 +68,41 @@ extern const u16 gCard5Pal[]; struct WonderNews * GetSavedWonderNews(void); struct WonderCard * GetSavedWonderCard(void); -struct WonderCardMetadata * sav1_get_mevent_buffer_2(void); -struct WonderNewsMetadata * GetMENewsJisanStructPtr(void); -bool32 OverwriteSavedWonderNewsWithReceivedNews(const struct WonderNews * src); -bool32 ValidateReceivedWonderNews(void); -bool32 ValidateReceivedWonderCard(void); -bool32 MEvent_HaveAlreadyReceivedWonderNews(const u8 * src); -bool32 OverwriteSavedWonderCardWithReceivedCard(const struct WonderCard * data); -void MEvent_WonderCardResetUnk08_6(struct WonderCard * buffer); -bool32 MEvent_ReceiveDistributionMon(const u16 * data); -void BuildMEventClientHeader(struct MEventClientHeaderStruct * data); -bool32 ValidateMEventClientHeader(const struct MEventClientHeaderStruct * data); -u32 sub_8144418(const u16 * a0, const struct MEventClientHeaderStruct * a1, void *unused); -u32 MEvent_CanPlayerReceiveDistributionMon(const u16 * a0, const struct MEventClientHeaderStruct * a1, void *unused); -bool32 sub_8144474(const struct MEventClientHeaderStruct * a0, const u16 * a1); -u16 sub_81444B0(const struct MEventClientHeaderStruct * a0, u32 command); +struct WonderCardMetadata * GetSavedWonderCardMetadata(void); +struct WonderNewsMetadata * GetSavedWonderNewsMetadata(void); +bool32 SaveWonderNews(const struct WonderNews * news); +bool32 ValidateSavedWonderNews(void); +bool32 ValidateSavedWonderCard(void); +bool32 IsWonderNewsSameAsSaved(const u8 * news); +bool32 SaveWonderCard(const struct WonderCard * card); +void DisableWonderCardSending(struct WonderCard * card); +bool32 MysteryGift_TrySaveStamp(const u16 * stamp); +void MysteryGift_LoadLinkGameData(struct MysteryGiftLinkGameData * data); +bool32 MysteryGift_ValidateLinkGameData(const struct MysteryGiftLinkGameData * data); +u32 MysteryGift_CompareCardFlags(const u16 * flagId, const struct MysteryGiftLinkGameData * data, void *unused); +u32 MysteryGift_CheckStamps(const u16 * stamp, const struct MysteryGiftLinkGameData * data, void *unused); +bool32 MysteryGift_DoesQuestionnaireMatch(const struct MysteryGiftLinkGameData * data, const u16 * words); +u16 MysteryGift_GetCardStatFromLinkData(const struct MysteryGiftLinkGameData * data, u32 stat); bool32 WonderCard_Init(struct WonderCard * card, struct WonderCardMetadata * metadata); bool32 WonderNews_Init(const struct WonderNews * news); s32 WonderCard_Enter(void); s32 WonderNews_Enter(void); -void DestroyWonderCard(void); -void DestroyWonderNews(void); +void ClearSavedWonderCardAndRelated(void); +void ClearSavedWonderNewsAndRelated(void); void WonderCard_Destroy(void); void WonderNews_Destroy(void); s32 WonderCard_Exit(bool32 flag); s32 WonderNews_Exit(bool32 flag); -bool32 CheckReceivedGiftFromWonderCard(void); +bool32 IsSavedWonderCardGiftNotReceived(void); void WonderNews_AddScrollIndicatorArrowPair(void); void WonderNews_RemoveScrollIndicatorArrowPair(void); -bool32 WonderNews_Test_Unk_02(void); -bool32 WonderCard_Test_Unk_08_6(void); +bool32 IsSendingSavedWonderNewsAllowed(void); +bool32 IsSendingSavedWonderCardAllowed(void); u32 WonderNews_GetInput(u16 input); -void InitMEventData(void); -u16 MEvent_GetBattleCardCount(u32 command); -void MysteryGift_TryIncrementStat(u32 eventId, u32 trainerId); -u16 *GetMEventProfileECWordsMaybe(void); +void ClearMysteryGift(void); +u16 MysteryGift_GetCardStat(u32 stat); +void MysteryGift_TryIncrementStat(u32 stat, u32 trainerId); +u16 *GetQuestionnaireWordsPtr(void); void MysteryGift_DisableStats(void); bool32 MysteryGift_TryEnableStatsByFlagId(u16 flagId); u16 GetWonderCardFlagId(void); diff --git a/include/mystery_gift_server.h b/include/mystery_gift_server.h index 06bac26f3..2a9070afb 100644 --- a/include/mystery_gift_server.h +++ b/include/mystery_gift_server.h @@ -102,7 +102,7 @@ struct mevent_srv_common void *recvBuffer; struct WonderCard * card; struct WonderNews * news; - struct MEventClientHeaderStruct * mevent_unk1442cc; + struct MysteryGiftLinkGameData * mevent_unk1442cc; void *sendBuffer1; u32 sendBuffer1Size; void *sendBuffer2; diff --git a/include/wonder_news.h b/include/wonder_news.h index ec845906e..3cbb46055 100644 --- a/include/wonder_news.h +++ b/include/wonder_news.h @@ -3,8 +3,15 @@ #include "global.h" -void MENewsJisan_SetRandomReward(u32 a0); -void MENewsJisanReset(void); -void MENewsJisanStepCounter(void); +enum { + WONDER_NEWS_NONE, + WONDER_NEWS_RECV_FRIEND, + WONDER_NEWS_RECV_WIRELESS, + WONDER_NEWS_SENT, +}; + +void WonderNews_SetReward(u32 newsType); +void WonderNews_Reset(void); +void WonderNews_IncrementStepCounter(void); #endif //GUARD_WONDER_NEWS_H diff --git a/src/easy_chat.c b/src/easy_chat.c index 443500453..563a7bd5c 100644 --- a/src/easy_chat.c +++ b/src/easy_chat.c @@ -472,10 +472,10 @@ void InitEasyChatPhrases(void) #endif } -void EC_ResetMEventProfileMaybe(void) +void InitQuestionnaireWords(void) { s32 i; - u16 *ptr = GetMEventProfileECWordsMaybe(); + u16 *ptr = GetQuestionnaireWordsPtr(); for (i = 0; i < 4; i++) ptr[i] = EC_WORD_UNDEFINED; } diff --git a/src/easy_chat_2.c b/src/easy_chat_2.c index 1688e92e0..6951da8e8 100644 --- a/src/easy_chat_2.c +++ b/src/easy_chat_2.c @@ -271,7 +271,7 @@ void ShowEasyChatScreen(void) words = gSaveBlock1Ptr->easyChatBattleLost; break; case EASY_CHAT_TYPE_QUESTIONNAIRE: - words = GetMEventProfileECWordsMaybe(); + words = GetQuestionnaireWordsPtr(); break; case EASY_CHAT_TYPE_MAIL: words = gSaveBlock1Ptr->mail[gSpecialVar_0x8005].words; diff --git a/src/event_data.c b/src/event_data.c index 5d3bad5d6..13ec93917 100644 --- a/src/event_data.c +++ b/src/event_data.c @@ -129,7 +129,7 @@ bool32 IsMysteryGiftEnabled(void) return FlagGet(FLAG_SYS_MYSTERY_GIFT_ENABLED); } -void ResetMysteryEventFlags(void) +void ClearMysteryGiftFlags(void) { FlagClear(FLAG_MYSTERY_GIFT_DONE); FlagClear(FLAG_MYSTERY_GIFT_1); @@ -149,7 +149,7 @@ void ResetMysteryEventFlags(void) FlagClear(FLAG_MYSTERY_GIFT_15); } -void ResetMysteryEventVars(void) +void ClearMysteryGiftVars(void) { VarSet(VAR_EVENT_PICHU_SLOT, 0); VarSet(VAR_MYSTERY_GIFT_1, 0); diff --git a/src/field_control_avatar.c b/src/field_control_avatar.c index c673a0753..31dd27e17 100644 --- a/src/field_control_avatar.c +++ b/src/field_control_avatar.c @@ -215,7 +215,7 @@ int ProcessPlayerFieldInput(struct FieldInput *input) if (input->tookStep) { IncrementGameStat(GAME_STAT_STEPS); - MENewsJisanStepCounter(); + WonderNews_IncrementStepCounter(); IncrementRenewableHiddenItemStepCounter(); RunMassageCooldownStepCounter(); IncrementResortGorgeousStepCounter(); diff --git a/src/field_specials.c b/src/field_specials.c index 8ee9bb04c..45fc701a9 100644 --- a/src/field_specials.c +++ b/src/field_specials.c @@ -1955,15 +1955,15 @@ u16 BattleCardAction(void) switch (gSpecialVar_Result) { case 0: - return MEvent_GetBattleCardCount(3); + return MysteryGift_GetCardStat(3); case 1: - return MEvent_GetBattleCardCount(4); + return MysteryGift_GetCardStat(4); case 2: - return MEvent_GetBattleCardCount(0); + return MysteryGift_GetCardStat(0); case 3: - return MEvent_GetBattleCardCount(1); + return MysteryGift_GetCardStat(1); case 4: - return MEvent_GetBattleCardCount(2); + return MysteryGift_GetCardStat(2); default: AGB_ASSERT_EX(0, ABSPATH("scr_tool.c"), 3873); return 0; diff --git a/src/mystery_gift.c b/src/mystery_gift.c index a12238263..fa164b924 100644 --- a/src/mystery_gift.c +++ b/src/mystery_gift.c @@ -19,6 +19,8 @@ #include "mystery_gift.h" #include "strings.h" +#define CALC_CRC(data) CalcCRC16WithTable((void *)&(data), sizeof(data)) + struct MEventTaskData1 { u16 stateAdvanceDelay; @@ -36,44 +38,44 @@ struct MEventTaskData1 }; static void Task_EReaderComm(u8 taskId); -static bool32 IsReceivedWonderNewsHeaderValid(const struct WonderNews * src); -static void BlankWonderNews(void); -static void BlankMENewsJisan(void); -static bool32 IsReceivedWonderCardHeaderValid(const struct WonderCard * src); -static void BlankSavedWonderCard(void); -static void BlankMEventBuffer2(void); -static void RecordIdOfWonderCardSender(u32 eventId, u32 trainerId, u32 *idsList, s32 count); -static void BlankBuffer344(void); +static bool32 ValidateWonderNews(const struct WonderNews * src); +static void ClearSavedWonderNews(void); +static void ClearSavedWonderNewsMetadata(void); +static bool32 ValidateWonderCard(const struct WonderCard * src); +static void ClearSavedWonderCard(void); +static void ClearSavedWonderCardMetadata(void); +static void IncrementCardStatForNewTrainer(u32 eventId, u32 trainerId, u32 *idsList, s32 count); +static void ClearSavedTrainerIds(void); extern const u8 gMultiBootProgram_EReader_Start[]; extern const u8 gMultiBootProgram_EReader_End[]; -static const u16 sGiftItemFlagIds[] = { - FLAG_GOT_AURORA_TICKET, - FLAG_GOT_MYSTIC_TICKET, - FLAG_0x2A9, - FLAG_0x2AA, - FLAG_0x2AB, - FLAG_0x2AC, - FLAG_0x2AD, - FLAG_0x2AE, - FLAG_0x2AF, - FLAG_0x2B0, - FLAG_0x2B1, - FLAG_0x2B2, - FLAG_0x2B3, - FLAG_0x2B4, - FLAG_0x2B5, - FLAG_0x2B6, - FLAG_0x2B7, - FLAG_0x2B8, - FLAG_0x2B9, - FLAG_0x2BA +static const u16 sReceivedGiftFlags[] = { + FLAG_RECEIVED_AURORA_TICKET, + FLAG_RECEIVED_MYSTIC_TICKET, + FLAG_RECEIVED_OLD_SEA_MAP, // Not used until Emerald + 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 }; struct MEvent_Str_1 sMEventSendToEReaderManager; -static EWRAM_DATA bool32 sReceivedWonderCardIsValid = FALSE; +static EWRAM_DATA bool32 sStatsEnabled = FALSE; void SendUnknownSerialData_Init(struct MEvent_Str_1 *mgr, size_t size, const void *data) { @@ -475,11 +477,11 @@ static void Task_EReaderComm(u8 taskId) } } -void InitMEventData(void) +void ClearMysteryGift(void) { CpuFill32(0, &gSaveBlock1Ptr->mysteryGift, sizeof(gSaveBlock1Ptr->mysteryGift)); - BlankMENewsJisan(); - EC_ResetMEventProfileMaybe(); + ClearSavedWonderNewsMetadata(); + InitQuestionnaireWords(); } struct WonderNews * GetSavedWonderNews(void) @@ -492,301 +494,310 @@ struct WonderCard * GetSavedWonderCard(void) return &gSaveBlock1Ptr->mysteryGift.card; } -struct WonderCardMetadata * sav1_get_mevent_buffer_2(void) +struct WonderCardMetadata * GetSavedWonderCardMetadata(void) { return &gSaveBlock1Ptr->mysteryGift.cardMetadata; } -struct WonderNewsMetadata * GetMENewsJisanStructPtr(void) +struct WonderNewsMetadata * GetSavedWonderNewsMetadata(void) { return &gSaveBlock1Ptr->mysteryGift.newsMetadata; } -u16 * GetMEventProfileECWordsMaybe(void) +u16 * GetQuestionnaireWordsPtr(void) { return gSaveBlock1Ptr->mysteryGift.questionnaireWords; } -void DestroyWonderNews(void) +// Equivalent to ClearSavedWonderCardAndRelated, but nothing else to clear +void ClearSavedWonderNewsAndRelated(void) { - BlankWonderNews(); + ClearSavedWonderNews(); } -bool32 OverwriteSavedWonderNewsWithReceivedNews(const struct WonderNews * src) +bool32 SaveWonderNews(const struct WonderNews * news) { - if (!IsReceivedWonderNewsHeaderValid(src)) + if (!ValidateWonderNews(news)) return FALSE; - BlankWonderNews(); - gSaveBlock1Ptr->mysteryGift.news = *src; - gSaveBlock1Ptr->mysteryGift.newsCrc = CalcCRC16WithTable((void *)&gSaveBlock1Ptr->mysteryGift.news, sizeof(struct WonderNews)); + + ClearSavedWonderNews(); + gSaveBlock1Ptr->mysteryGift.news = *news; + gSaveBlock1Ptr->mysteryGift.newsCrc = CALC_CRC(gSaveBlock1Ptr->mysteryGift.news); return TRUE; } -bool32 ValidateReceivedWonderNews(void) +bool32 ValidateSavedWonderNews(void) { - if (CalcCRC16WithTable((void *)&gSaveBlock1Ptr->mysteryGift.news, sizeof(struct WonderNews)) != gSaveBlock1Ptr->mysteryGift.newsCrc) + if (CALC_CRC(gSaveBlock1Ptr->mysteryGift.news) != gSaveBlock1Ptr->mysteryGift.newsCrc) return FALSE; - if (!IsReceivedWonderNewsHeaderValid(&gSaveBlock1Ptr->mysteryGift.news)) + if (!ValidateWonderNews(&gSaveBlock1Ptr->mysteryGift.news)) return FALSE; return TRUE; } -static bool32 IsReceivedWonderNewsHeaderValid(const struct WonderNews * data) +static bool32 ValidateWonderNews(const struct WonderNews * news) { - if (data->newsId == 0) + if (news->id == 0) return FALSE; return TRUE; } -bool32 WonderNews_Test_Unk_02(void) +bool32 IsSendingSavedWonderNewsAllowed(void) { - const struct WonderNews * data = &gSaveBlock1Ptr->mysteryGift.news; - if (data->sendType == 0) + const struct WonderNews * news = &gSaveBlock1Ptr->mysteryGift.news; + if (news->sendType == SEND_TYPE_DISALLOWED) return FALSE; return TRUE; } -static void BlankWonderNews(void) +static void ClearSavedWonderNews(void) { CpuFill32(0, GetSavedWonderNews(), sizeof(gSaveBlock1Ptr->mysteryGift.news)); gSaveBlock1Ptr->mysteryGift.newsCrc = 0; } -static void BlankMENewsJisan(void) +static void ClearSavedWonderNewsMetadata(void) { - CpuFill32(0, GetMENewsJisanStructPtr(), sizeof(struct WonderNewsMetadata)); - MENewsJisanReset(); + CpuFill32(0, GetSavedWonderNewsMetadata(), sizeof(gSaveBlock1Ptr->mysteryGift.newsMetadata)); + WonderNews_Reset(); } -bool32 MEvent_HaveAlreadyReceivedWonderNews(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 (!ValidateReceivedWonderNews()) + 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 DestroyWonderCard(void) +void ClearSavedWonderCardAndRelated(void) { - BlankSavedWonderCard(); - BlankMEventBuffer2(); - BlankBuffer344(); + ClearSavedWonderCard(); + ClearSavedWonderCardMetadata(); + ClearSavedTrainerIds(); ClearRamScript(); - ResetMysteryEventFlags(); - ResetMysteryEventVars(); + ClearMysteryGiftFlags(); + ClearMysteryGiftVars(); ClearEReaderTrainer(&gSaveBlock2Ptr->battleTower.ereaderTrainer); } -bool32 OverwriteSavedWonderCardWithReceivedCard(const struct WonderCard * data) +bool32 SaveWonderCard(const struct WonderCard * card) { - struct WonderCardMetadata * r2; - struct WonderCard * r1; - if (!IsReceivedWonderCardHeaderValid(data)) + struct WonderCardMetadata * metadata; + if (!ValidateWonderCard(card)) return FALSE; - DestroyWonderCard(); - memcpy(&gSaveBlock1Ptr->mysteryGift.card, data, sizeof(struct WonderCard)); - gSaveBlock1Ptr->mysteryGift.cardCrc = CalcCRC16WithTable((void *)&gSaveBlock1Ptr->mysteryGift.card, sizeof(struct WonderCard)); - // Annoying hack to match - r2 = &gSaveBlock1Ptr->mysteryGift.cardMetadata; - r1 = &gSaveBlock1Ptr->mysteryGift.card; - r2->iconSpecies = r1->iconSpecies; + + ClearSavedWonderCardAndRelated(); + memcpy(&gSaveBlock1Ptr->mysteryGift.card, card, sizeof(struct WonderCard)); + gSaveBlock1Ptr->mysteryGift.cardCrc = CALC_CRC(gSaveBlock1Ptr->mysteryGift.card); + metadata = &gSaveBlock1Ptr->mysteryGift.cardMetadata; + metadata->iconSpecies = (&gSaveBlock1Ptr->mysteryGift.card)->iconSpecies; return TRUE; } -bool32 ValidateReceivedWonderCard(void) +bool32 ValidateSavedWonderCard(void) { - if (gSaveBlock1Ptr->mysteryGift.cardCrc != CalcCRC16WithTable((void *)&gSaveBlock1Ptr->mysteryGift.card, sizeof(struct WonderCard))) + if (gSaveBlock1Ptr->mysteryGift.cardCrc != CALC_CRC(gSaveBlock1Ptr->mysteryGift.card)) return FALSE; - if (!IsReceivedWonderCardHeaderValid(&gSaveBlock1Ptr->mysteryGift.card)) + if (!ValidateWonderCard(&gSaveBlock1Ptr->mysteryGift.card)) return FALSE; if (!ValidateRamScript()) return FALSE; return TRUE; } -static bool32 IsReceivedWonderCardHeaderValid(const struct WonderCard * data) +static bool32 ValidateWonderCard(const struct WonderCard * card) { - if (data->flagId == 0) + if (card->flagId == 0) return FALSE; - if (data->type > 2) + if (card->type >= CARD_TYPE_COUNT) return FALSE; - if (!(data->sendType == 0 || data->sendType == 1 || data->sendType == 2)) + if (!(card->sendType == SEND_TYPE_DISALLOWED + || card->sendType == SEND_TYPE_ALLOWED + || card->sendType == SEND_TYPE_ALLOWED_ALWAYS)) return FALSE; - if (data->bgType > 7) + if (card->bgType >= NUM_WONDER_BGS) return FALSE; - if (data->maxStamps > 7) + if (card->maxStamps > MAX_STAMP_CARD_STAMPS) return FALSE; return TRUE; } -bool32 WonderCard_Test_Unk_08_6(void) +bool32 IsSendingSavedWonderCardAllowed(void) { - const struct WonderCard * data = &gSaveBlock1Ptr->mysteryGift.card; - if (data->sendType == 0) + const struct WonderCard * card = &gSaveBlock1Ptr->mysteryGift.card; + if (card->sendType == SEND_TYPE_DISALLOWED) return FALSE; return TRUE; } -static void BlankSavedWonderCard(void) +static void ClearSavedWonderCard(void) { - CpuFill32(0, &gSaveBlock1Ptr->mysteryGift.card, sizeof(struct WonderCard)); + CpuFill32(0, &gSaveBlock1Ptr->mysteryGift.card, sizeof(gSaveBlock1Ptr->mysteryGift.card)); gSaveBlock1Ptr->mysteryGift.cardCrc = 0; } -static void BlankMEventBuffer2(void) +static void ClearSavedWonderCardMetadata(void) { - CpuFill32(0, sav1_get_mevent_buffer_2(), 18 * sizeof(u16)); + CpuFill32(0, GetSavedWonderCardMetadata(), sizeof(gSaveBlock1Ptr->mysteryGift.cardMetadata)); gSaveBlock1Ptr->mysteryGift.cardMetadataCrc = 0; } u16 GetWonderCardFlagId(void) { - if (ValidateReceivedWonderCard()) + if (ValidateSavedWonderCard()) return gSaveBlock1Ptr->mysteryGift.card.flagId; return 0; } -void MEvent_WonderCardResetUnk08_6(struct WonderCard * buffer) +void DisableWonderCardSending(struct WonderCard * card) { - if (buffer->sendType == 1) - buffer->sendType = 0; + if (card->sendType == SEND_TYPE_ALLOWED) + card->sendType = SEND_TYPE_DISALLOWED; } -static bool32 IsCardIdInValidRange(u16 a0) +static bool32 IsWonderCardFlagIDInValidRange(u16 flagId) { - if (a0 >= 1000 && a0 < 1020) + if (flagId >= WONDER_CARD_FLAG_OFFSET && flagId < WONDER_CARD_FLAG_OFFSET + NUM_WONDER_CARD_FLAGS) return TRUE; return FALSE; } -bool32 CheckReceivedGiftFromWonderCard(void) +bool32 IsSavedWonderCardGiftNotReceived(void) { u16 value = GetWonderCardFlagId(); - if (!IsCardIdInValidRange(value)) + if (!IsWonderCardFlagIDInValidRange(value)) return FALSE; - if (FlagGet(sGiftItemFlagIds[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 s32 CountReceivedDistributionMons(const struct WonderCardMetadata * data, s32 size) +static s32 GetNumStampsInMetadata(const struct WonderCardMetadata * data, s32 size) { - s32 r3 = 0; + s32 numStamps = 0; s32 i; for (i = 0; i < size; i++) { - if (data->stampData[1][i] && data->stampData[0][i]) - r3++; + if (data->stampData[STAMP_ID][i] && data->stampData[STAMP_SPECIES][i]) + numStamps++; } - return r3; + return numStamps; } -static bool32 HasPlayerAlreadyReceivedDistributedMon(const struct WonderCardMetadata * data1, const u16 * data2, s32 size) +static bool32 IsStampInMetadata(const struct WonderCardMetadata * metadata, const u16 * stamp, s32 maxStamps) { s32 i; - for (i = 0; i < size; i++) + for (i = 0; i < maxStamps; i++) { - if (data1->stampData[1][i] == data2[1]) + if (metadata->stampData[STAMP_ID][i] == stamp[STAMP_ID]) return TRUE; - if (data1->stampData[0][i] == data2[0]) + if (metadata->stampData[STAMP_SPECIES][i] == stamp[STAMP_SPECIES]) return TRUE; } return FALSE; } -static bool32 IsWonderCardSpeciesValid(const u16 * data) +static bool32 ValidateStamp(const u16 * stamp) { - if (data[1] == 0) + if (stamp[STAMP_ID] == 0) return FALSE; - if (data[0] == SPECIES_NONE) + if (stamp[STAMP_SPECIES] == SPECIES_NONE) return FALSE; - if (data[0] >= NUM_SPECIES) + if (stamp[STAMP_SPECIES] >= NUM_SPECIES) return FALSE; return TRUE; } -static s32 ValidateCardAndCountMonsReceived(void) +static s32 GetNumStampsInSavedCard(void) { - struct WonderCard * data; - if (!ValidateReceivedWonderCard()) + struct WonderCard * card; + if (!ValidateSavedWonderCard()) return 0; - data = &gSaveBlock1Ptr->mysteryGift.card; - if (data->type != 1) + card = &gSaveBlock1Ptr->mysteryGift.card; + if (card->type != CARD_TYPE_STAMP) return 0; - return CountReceivedDistributionMons(&gSaveBlock1Ptr->mysteryGift.cardMetadata, data->maxStamps); + return GetNumStampsInMetadata(&gSaveBlock1Ptr->mysteryGift.cardMetadata, card->maxStamps); } -bool32 MEvent_ReceiveDistributionMon(const u16 * data) +bool32 MysteryGift_TrySaveStamp(const u16 * stamp) { - struct WonderCard * buffer = &gSaveBlock1Ptr->mysteryGift.card; - s32 capacity = buffer->maxStamps; + struct WonderCard * card = &gSaveBlock1Ptr->mysteryGift.card; + s32 maxStamps = card->maxStamps; s32 i; - if (!IsWonderCardSpeciesValid(data)) + if (!ValidateStamp(stamp)) return FALSE; - if (HasPlayerAlreadyReceivedDistributedMon(&gSaveBlock1Ptr->mysteryGift.cardMetadata, data, capacity)) + if (IsStampInMetadata(&gSaveBlock1Ptr->mysteryGift.cardMetadata, stamp, maxStamps)) return FALSE; - for (i = 0; i < capacity; i++) + for (i = 0; i < maxStamps; i++) { - if (gSaveBlock1Ptr->mysteryGift.cardMetadata.stampData[1][i] == 0 && gSaveBlock1Ptr->mysteryGift.cardMetadata.stampData[0][i] == 0) + if (gSaveBlock1Ptr->mysteryGift.cardMetadata.stampData[STAMP_ID][i] == 0 + && gSaveBlock1Ptr->mysteryGift.cardMetadata.stampData[STAMP_SPECIES][i] == SPECIES_NONE) { - gSaveBlock1Ptr->mysteryGift.cardMetadata.stampData[1][i] = data[1]; - gSaveBlock1Ptr->mysteryGift.cardMetadata.stampData[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; } } return FALSE; } +#define GAME_DATA_VALID_VAR 0x101 + #if defined(FIRERED) -#define MEVENT_HEADER_VERSION_CODE 1 +#define VERSION_CODE 1 #elif defined(LEAFGREEN) -#define MEVENT_HEADER_VERSION_CODE 2 +#define VERSION_CODE 2 #endif -void BuildMEventClientHeader(struct MEventClientHeaderStruct * data) +void MysteryGift_LoadLinkGameData(struct MysteryGiftLinkGameData * data) { s32 i; - CpuFill32(0, data, sizeof(struct MEventClientHeaderStruct)); + CpuFill32(0, data, sizeof(*data)); // Magic - data->unk_00 = 0x101; + data->unk_00 = GAME_DATA_VALID_VAR; data->unk_04 = 1; data->unk_08 = 1; data->unk_0C = 1; - data->unk_10 = MEVENT_HEADER_VERSION_CODE; + data->unk_10 = VERSION_CODE; // Check whether a card already exists - if (ValidateReceivedWonderCard()) + if (ValidateSavedWonderCard()) { // Populate fields - data->id = GetSavedWonderCard()->flagId; - data->unk_20 = *sav1_get_mevent_buffer_2(); - data->maxDistributionMons = GetSavedWonderCard()->maxStamps; + data->flagId = GetSavedWonderCard()->flagId; + data->cardMetadata = *GetSavedWonderCardMetadata(); + data->maxStamps = GetSavedWonderCard()->maxStamps; } else - data->id = 0; + { + data->flagId = 0; + } - // Get something - for (i = 0; i < 4; i++) - data->unk_16[i] = gSaveBlock1Ptr->mysteryGift.questionnaireWords[i]; + for (i = 0; i < NUM_QUESTIONNAIRE_WORDS; i++) + data->questionnaireWords[i] = gSaveBlock1Ptr->mysteryGift.questionnaireWords[i]; - // Get player ID CopyTrainerId(data->playerTrainerId, gSaveBlock2Ptr->playerTrainerId); StringCopy(data->playerName, gSaveBlock2Ptr->playerName); - for (i = 0; i < 6; i++) + for (i = 0; i < EASY_CHAT_BATTLE_WORDS_COUNT; i++) data->easyChatProfile[i] = gSaveBlock1Ptr->easyChatProfile[i]; - memcpy(data->gameCode, RomHeaderGameCode, 4); + + memcpy(data->gameCode, RomHeaderGameCode, GAME_CODE_LENGTH); data->version = RomHeaderSoftwareVersion; } -bool32 ValidateMEventClientHeader(const struct MEventClientHeaderStruct * data) +bool32 MysteryGift_ValidateLinkGameData(const struct MysteryGiftLinkGameData * data) { - if (data->unk_00 != 0x101) + if (data->unk_00 != GAME_DATA_VALID_VAR) return FALSE; if (!(data->unk_04 & 1)) return FALSE; @@ -799,145 +810,156 @@ bool32 ValidateMEventClientHeader(const struct MEventClientHeaderStruct * data) return TRUE; } -u32 sub_8144418(const u16 * a0, const struct MEventClientHeaderStruct * a1, void *unused) +u32 MysteryGift_CompareCardFlags(const u16 * flagId, const struct MysteryGiftLinkGameData * data, void *unused) { - if (a1->id == 0) + // Has a Wonder Card already? + if (data->flagId == 0) return 0; - if (*a0 == a1->id) + + // Has this Wonder Card already? + if (*flagId == data->flagId) return 1; + + // Player has a different Wonder Card return 2; } -u32 MEvent_CanPlayerReceiveDistributionMon(const u16 * a0, const struct MEventClientHeaderStruct * a1, void *unused) +u32 MysteryGift_CheckStamps(const u16 * stamp, const struct MysteryGiftLinkGameData * data, void *unused) { - s32 numSpaces = a1->maxDistributionMons - CountReceivedDistributionMons(&a1->unk_20, a1->maxDistributionMons); - if (numSpaces == 0) + s32 stampsMissing = data->maxStamps - GetNumStampsInMetadata(&data->cardMetadata, data->maxStamps); + + // Has full stamp card? + if (stampsMissing == 0) return 1; - if (HasPlayerAlreadyReceivedDistributedMon(&a1->unk_20, a0, a1->maxDistributionMons)) + + // Already has stamp? + if (IsStampInMetadata(&data->cardMetadata, stamp, data->maxStamps)) return 3; - if (numSpaces == 1) + + // Only 1 empty stamp left? + if (stampsMissing == 1) return 4; + + // This is a new stamp return 2; } -bool32 sub_8144474(const struct MEventClientHeaderStruct * a0, const u16 * a1) +bool32 MysteryGift_DoesQuestionnaireMatch(const struct MysteryGiftLinkGameData * data, const u16 * words) { s32 i; - for (i = 0; i < 4; i++) + for (i = 0; i < NUM_QUESTIONNAIRE_WORDS; i++) { - if (a0->unk_16[i] != a1[i]) + if (data->questionnaireWords[i] != words[i]) return FALSE; } return TRUE; } -static s32 GetNumReceivedDistributionMons(const struct MEventClientHeaderStruct * a0) +static s32 GetNumStampsInLinkData(const struct MysteryGiftLinkGameData * data) { - return CountReceivedDistributionMons(&a0->unk_20, a0->maxDistributionMons); + return GetNumStampsInMetadata(&data->cardMetadata, data->maxStamps); } -u16 sub_81444B0(const struct MEventClientHeaderStruct * a0, u32 command) +u16 MysteryGift_GetCardStatFromLinkData(const struct MysteryGiftLinkGameData * data, u32 stat) { - switch (command) + switch (stat) { - case 0: - return a0->unk_20.battlesWon; - case 1: - return a0->unk_20.battlesLost; - case 2: - return a0->unk_20.numTrades; - case 3: - return GetNumReceivedDistributionMons(a0); - case 4: - return a0->maxDistributionMons; - default: - AGB_ASSERT_EX(0, ABSPATH("mevent.c"), 825); - return 0; + 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_EX(0, ABSPATH("mevent.c"), 825); + return 0; } } -// Increments an interaction count in the save block -static void IncrementBattleCardCount(u32 command) +static void IncrementCardStat(u32 statType) { - struct WonderCard * data = &gSaveBlock1Ptr->mysteryGift.card; - if (data->type == 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.cardMetadata.battlesWon; - break; - case 1: - dest = &gSaveBlock1Ptr->mysteryGift.cardMetadata.battlesLost; - break; - case 2: - dest = &gSaveBlock1Ptr->mysteryGift.cardMetadata.numTrades; - break; - case 3: - break; - case 4: - break; + case CARD_STAT_BATTLES_WON: + stat = &gSaveBlock1Ptr->mysteryGift.cardMetadata.battlesWon; + break; + case CARD_STAT_BATTLES_LOST: + stat = &gSaveBlock1Ptr->mysteryGift.cardMetadata.battlesLost; + break; + case CARD_STAT_NUM_TRADES: + stat = &gSaveBlock1Ptr->mysteryGift.cardMetadata.numTrades; + break; + case CARD_STAT_NUM_STAMPS: + case CARD_STAT_MAX_STAMPS: + break; } - if (dest == NULL) + if (stat == NULL) { AGB_ASSERT_EX(0, ABSPATH("mevent.c"), 868); } - else if (++(*dest) > 999) + else if (++(*stat) > MAX_WONDER_CARD_STAT) { - *dest = 999; + *stat = MAX_WONDER_CARD_STAT; } } } -u16 MEvent_GetBattleCardCount(u32 command) +u16 MysteryGift_GetCardStat(u32 stat) { - switch (command) + switch (stat) { - case 0: + case CARD_STAT_BATTLES_WON: + { + struct WonderCard * card = &gSaveBlock1Ptr->mysteryGift.card; + if (card->type == CARD_TYPE_LINK_STAT) { - struct WonderCard * data = &gSaveBlock1Ptr->mysteryGift.card; - if (data->type == 2) - { - struct WonderCardMetadata * buffer = &gSaveBlock1Ptr->mysteryGift.cardMetadata; - return buffer->battlesWon; - } - break; + struct WonderCardMetadata * metadata = &gSaveBlock1Ptr->mysteryGift.cardMetadata; + return metadata->battlesWon; } - case 1: + break; + } + case CARD_STAT_BATTLES_LOST: + { + struct WonderCard * card = &gSaveBlock1Ptr->mysteryGift.card; + if (card->type == CARD_TYPE_LINK_STAT) { - struct WonderCard * data = &gSaveBlock1Ptr->mysteryGift.card; - if (data->type == 2) - { - struct WonderCardMetadata * buffer = &gSaveBlock1Ptr->mysteryGift.cardMetadata; - return buffer->battlesLost; - } - break; + struct WonderCardMetadata * metadata = &gSaveBlock1Ptr->mysteryGift.cardMetadata; + return metadata->battlesLost; } - case 2: + break; + } + case CARD_STAT_NUM_TRADES: + { + struct WonderCard * card = &gSaveBlock1Ptr->mysteryGift.card; + if (card->type == CARD_TYPE_LINK_STAT) { - struct WonderCard * data = &gSaveBlock1Ptr->mysteryGift.card; - if (data->type == 2) - { - struct WonderCardMetadata * buffer = &gSaveBlock1Ptr->mysteryGift.cardMetadata; - return buffer->numTrades; - } - break; - } - case 3: - { - struct WonderCard * data = &gSaveBlock1Ptr->mysteryGift.card; - if (data->type == 1) - return ValidateCardAndCountMonsReceived(); - break; - } - case 4: - { - struct WonderCard * data = &gSaveBlock1Ptr->mysteryGift.card; - if (data->type == 1) - return data->maxStamps; - 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_EX(0, ABSPATH("mevent.c"), 913); return 0; @@ -945,85 +967,93 @@ u16 MEvent_GetBattleCardCount(u32 command) void MysteryGift_DisableStats(void) { - sReceivedWonderCardIsValid = FALSE; + sStatsEnabled = FALSE; } bool32 MysteryGift_TryEnableStatsByFlagId(u16 flagId) { - sReceivedWonderCardIsValid = FALSE; + sStatsEnabled = FALSE; if (flagId == 0) return FALSE; - if (!ValidateReceivedWonderCard()) + if (!ValidateSavedWonderCard()) return FALSE; if (gSaveBlock1Ptr->mysteryGift.card.flagId != flagId) return FALSE; - sReceivedWonderCardIsValid = TRUE; + sStatsEnabled = TRUE; return TRUE; } -void MysteryGift_TryIncrementStat(u32 eventId, u32 trainerId) +void MysteryGift_TryIncrementStat(u32 stat, u32 trainerId) { - if (sReceivedWonderCardIsValid) + if (sStatsEnabled) { - switch (eventId) + switch (stat) { - case 2: // trade - RecordIdOfWonderCardSender(2, trainerId, gSaveBlock1Ptr->mysteryGift.trainerIds[1], 5); - break; - case 0: // link win - RecordIdOfWonderCardSender(0, trainerId, gSaveBlock1Ptr->mysteryGift.trainerIds[0], 5); - break; - case 1: // link loss - RecordIdOfWonderCardSender(1, trainerId, gSaveBlock1Ptr->mysteryGift.trainerIds[0], 5); - break; - default: - AGB_ASSERT_EX(0, ABSPATH("mevent.c"), 988); + case CARD_STAT_NUM_TRADES: + IncrementCardStatForNewTrainer(CARD_STAT_NUM_TRADES, + trainerId, + gSaveBlock1Ptr->mysteryGift.trainerIds[1], + ARRAY_COUNT(gSaveBlock1Ptr->mysteryGift.trainerIds[1])); + break; + case CARD_STAT_BATTLES_WON: + IncrementCardStatForNewTrainer(CARD_STAT_BATTLES_WON, + trainerId, + gSaveBlock1Ptr->mysteryGift.trainerIds[0], + ARRAY_COUNT(gSaveBlock1Ptr->mysteryGift.trainerIds[0])); + break; + 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_EX(0, ABSPATH("mevent.c"), 988); + break; } } } -static void BlankBuffer344(void) +static void ClearSavedTrainerIds(void) { CpuFill32(0, gSaveBlock1Ptr->mysteryGift.trainerIds, sizeof(gSaveBlock1Ptr->mysteryGift.trainerIds)); } -// Looks up trainerId in an array idsList with count elements. -// If trainerId is found, rearranges idsList to put it in the front. -// Otherwise, drops the last element of the list and inserts -// trainerId at the front. -// Returns TRUE in the latter case. -static bool32 PlaceTrainerIdAtFrontOfList(u32 trainerId, u32 * idsList, s32 count) +// 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, s32 size) { s32 i; s32 j; - for (i = 0; i < count; i++) + for (i = 0; i < size; i++) { - if (idsList[i] == trainerId) + if (trainerIds[i] == trainerId) break; } - if (i == count) + + if (i == size) { - for (j = count - 1; j > 0; j--) - { - idsList[j] = idsList[j - 1]; - } - idsList[0] = trainerId; + // New trainer, shift array and insert new id at front + for (j = size - 1; j > 0; j--) + trainerIds[j] = trainerIds[j - 1]; + + trainerIds[0] = trainerId; return TRUE; } else { + // Existing trainer, shift back to old slot and move id to front for (j = i; j > 0; j--) - { - idsList[j] = idsList[j - 1]; - } - idsList[0] = trainerId; + trainerIds[j] = trainerIds[j - 1]; + + trainerIds[0] = trainerId; return FALSE; } } -static void RecordIdOfWonderCardSender(u32 eventId, u32 trainerId, u32 * idsList, s32 count) +static void IncrementCardStatForNewTrainer(u32 stat, u32 trainerId, u32 * trainerIds, s32 size) { - if (PlaceTrainerIdAtFrontOfList(trainerId, idsList, count)) - IncrementBattleCardCount(eventId); + if (RecordTrainerId(trainerId, trainerIds, size)) + IncrementCardStat(stat); } diff --git a/src/mystery_gift_client.c b/src/mystery_gift_client.c index 289de83f4..48fc8ffc3 100644 --- a/src/mystery_gift_client.c +++ b/src/mystery_gift_client.c @@ -188,19 +188,19 @@ static u32 client_mainseq_4(struct mevent_client * svr) svr->flag = 0; return 4; case 8: - BuildMEventClientHeader(svr->sendBuffer); - mevent_srv_sub_init_send(&svr->manager, 0x11, svr->sendBuffer, sizeof(struct MEventClientHeaderStruct)); + MysteryGift_LoadLinkGameData(svr->sendBuffer); + mevent_srv_sub_init_send(&svr->manager, 0x11, svr->sendBuffer, sizeof(struct MysteryGiftLinkGameData)); break; case 14: mevent_client_send_word(svr, 0x13, svr->param); break; case 10: - OverwriteSavedWonderCardWithReceivedCard(svr->recvBuffer); + SaveWonderCard(svr->recvBuffer); break; case 9: - if (!MEvent_HaveAlreadyReceivedWonderNews(svr->recvBuffer)) + if (!IsWonderNewsSameAsSaved(svr->recvBuffer)) { - OverwriteSavedWonderNewsWithReceivedNews(svr->recvBuffer); + SaveWonderNews(svr->recvBuffer); mevent_client_send_word(svr, 0x13, 0); } else @@ -212,7 +212,7 @@ static u32 client_mainseq_4(struct mevent_client * svr) svr->flag = 0; break; case 16: - MEvent_ReceiveDistributionMon(svr->recvBuffer); + MysteryGift_TrySaveStamp(svr->recvBuffer); break; case 17: InitRamScript_NoObjectEvent(svr->recvBuffer, 1000); diff --git a/src/mystery_gift_menu.c b/src/mystery_gift_menu.c index 7e65298cd..cb8a5bfe9 100644 --- a/src/mystery_gift_menu.c +++ b/src/mystery_gift_menu.c @@ -784,13 +784,9 @@ s32 HandleMysteryGiftListMenu(u8 * textState, u16 * windowId, bool32 cannotToss, bool32 ValidateCardOrNews(bool32 cardOrNews) { if (cardOrNews == 0) - { - return ValidateReceivedWonderCard(); - } + return ValidateSavedWonderCard(); else - { - return ValidateReceivedWonderNews(); - } + return ValidateSavedWonderNews(); } bool32 HandleLoadWonderCardOrNews(u8 * state, bool32 cardOrNews) @@ -802,7 +798,7 @@ bool32 HandleLoadWonderCardOrNews(u8 * state, bool32 cardOrNews) case 0: if (cardOrNews == 0) { - WonderCard_Init(GetSavedWonderCard(), sav1_get_mevent_buffer_2()); + WonderCard_Init(GetSavedWonderCard(), GetSavedWonderCardMetadata()); } else { @@ -837,13 +833,9 @@ bool32 HandleLoadWonderCardOrNews(u8 * state, bool32 cardOrNews) bool32 DestroyNewsOrCard(bool32 cardOrNews) { if (cardOrNews == 0) - { - DestroyWonderCard(); - } + ClearSavedWonderCardAndRelated(); else - { - DestroyWonderNews(); - } + ClearSavedWonderNewsAndRelated(); return TRUE; } @@ -1128,25 +1120,17 @@ void task00_mystery_gift(u8 taskId) { case 0: data->IsCardOrNews = 0; - if (ValidateReceivedWonderCard() == TRUE) - { + if (ValidateSavedWonderCard() == TRUE) data->state = 18; - } else - { data->state = 2; - } break; case 1: data->IsCardOrNews = 1; - if (ValidateReceivedWonderNews() == TRUE) - { + if (ValidateSavedWonderNews() == TRUE) data->state = 18; - } else - { data->state = 2; - } break; case -2u: data->state = 37; @@ -1307,7 +1291,7 @@ void task00_mystery_gift(u8 taskId) switch (flag) { case 0: - if (CheckReceivedGiftFromWonderCard() == TRUE) + if (IsSavedWonderCardGiftNotReceived() == TRUE) { data->state = 12; } @@ -1382,13 +1366,9 @@ void task00_mystery_gift(u8 taskId) if (data->prevPromptWindowId == 3) { if (data->source == 1) - { - MENewsJisan_SetRandomReward(1); - } + WonderNews_SetReward(1); else - { - MENewsJisan_SetRandomReward(2); - } + WonderNews_SetReward(2); } if (sp0 == 0) { @@ -1452,25 +1432,17 @@ void task00_mystery_gift(u8 taskId) u32 result; if (data->IsCardOrNews == 0) { - if (WonderCard_Test_Unk_08_6()) - { + if (IsSendingSavedWonderCardAllowed()) result = HandleMysteryGiftListMenu(&data->textState, &data->curPromptWindowId, data->IsCardOrNews, FALSE); - } else - { result = HandleMysteryGiftListMenu(&data->textState, &data->curPromptWindowId, data->IsCardOrNews, TRUE); - } } else { - if (WonderNews_Test_Unk_02()) - { + if (IsSendingSavedWonderNewsAllowed()) result = HandleMysteryGiftListMenu(&data->textState, &data->curPromptWindowId, data->IsCardOrNews, FALSE); - } else - { result = HandleMysteryGiftListMenu(&data->textState, &data->curPromptWindowId, data->IsCardOrNews, TRUE); - } } switch (result) { @@ -1497,7 +1469,7 @@ void task00_mystery_gift(u8 taskId) switch (mevent_message_prompt_discard(&data->textState, &data->curPromptWindowId, data->IsCardOrNews)) { case 0: - if (data->IsCardOrNews == 0 && CheckReceivedGiftFromWonderCard() == TRUE) + if (data->IsCardOrNews == 0 && IsSavedWonderCardGiftNotReceived() == TRUE) { data->state = 23; } @@ -1628,7 +1600,7 @@ void task00_mystery_gift(u8 taskId) { if (data->source == 1 && data->prevPromptWindowId == 3) { - MENewsJisan_SetRandomReward(3); + WonderNews_SetReward(3); data->state = 17; } else diff --git a/src/mystery_gift_server.c b/src/mystery_gift_server.c index 98211e2ae..d2f15644a 100644 --- a/src/mystery_gift_server.c +++ b/src/mystery_gift_server.c @@ -48,7 +48,7 @@ static void mevent_srv_init_common(struct mevent_srv_common * svr, const void *c svr->card = AllocZeroed(sizeof(struct WonderCard)); svr->news = AllocZeroed(sizeof(struct WonderNews)); svr->recvBuffer = AllocZeroed(ME_SEND_BUF_SIZE); - svr->mevent_unk1442cc = AllocZeroed(sizeof(struct MEventClientHeaderStruct)); + svr->mevent_unk1442cc = AllocZeroed(sizeof(struct MysteryGiftLinkGameData)); svr->cmdBuffer = cmdBuffer; svr->cmdidx = 0; mevent_srv_sub_init(&svr->manager, sendPlayerNo, recvPlayerNo); @@ -145,12 +145,12 @@ static u32 common_mainseq_4(struct mevent_srv_common * svr) case 5: AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 376); AGB_ASSERT_EX(cmd->parameter == NULL, ABSPATH("mevent_server.c"), 377); - memcpy(svr->mevent_unk1442cc, svr->recvBuffer, sizeof(struct MEventClientHeaderStruct)); + memcpy(svr->mevent_unk1442cc, svr->recvBuffer, sizeof(struct MysteryGiftLinkGameData)); break; case 6: AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 382); AGB_ASSERT_EX(cmd->parameter == NULL, ABSPATH("mevent_server.c"), 383); - svr->param = ValidateMEventClientHeader(svr->mevent_unk1442cc); + svr->param = MysteryGift_ValidateLinkGameData(svr->mevent_unk1442cc); break; case 4: if (svr->param == cmd->flag) @@ -162,7 +162,7 @@ static u32 common_mainseq_4(struct mevent_srv_common * svr) case 7: AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 396); ptr = mevent_first_if_not_null_else_second(cmd->parameter, svr->card); - svr->param = sub_8144418(ptr, svr->mevent_unk1442cc, ptr); + svr->param = MysteryGift_CompareCardFlags(ptr, svr->mevent_unk1442cc, ptr); break; case 8: AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 402); @@ -172,15 +172,15 @@ static u32 common_mainseq_4(struct mevent_srv_common * svr) case 9: AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 408); ptr = mevent_first_if_not_null_else_second(cmd->parameter, &svr->sendWord); - svr->param = MEvent_CanPlayerReceiveDistributionMon(ptr, svr->mevent_unk1442cc, ptr); + svr->param = MysteryGift_CheckStamps(ptr, svr->mevent_unk1442cc, ptr); break; case 10: AGB_ASSERT_EX(cmd->parameter == NULL, ABSPATH("mevent_server.c"), 415); - svr->param = sub_81444B0(svr->mevent_unk1442cc, cmd->flag); + svr->param = MysteryGift_GetCardStatFromLinkData(svr->mevent_unk1442cc, cmd->flag); break; case 11: AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 420); - svr->param = sub_8144474(svr->mevent_unk1442cc, cmd->parameter); + svr->param = MysteryGift_DoesQuestionnaireMatch(svr->mevent_unk1442cc, cmd->parameter); break; case 12: AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 426); @@ -243,7 +243,7 @@ static u32 common_mainseq_4(struct mevent_srv_common * svr) case 26: AGB_ASSERT_EX(cmd->flag == FALSE && cmd->parameter == NULL, ABSPATH("mevent_server.c"), 506); memcpy(svr->card, GetSavedWonderCard(), 332); - MEvent_WonderCardResetUnk08_6(svr->card); + DisableWonderCardSending(svr->card); break; case 27: AGB_ASSERT_EX(cmd->flag == FALSE && cmd->parameter == NULL, ABSPATH("mevent_server.c"), 512); diff --git a/src/new_game.c b/src/new_game.c index 18ff73e29..ab5fa9958 100644 --- a/src/new_game.c +++ b/src/new_game.c @@ -143,7 +143,7 @@ void NewGameInitData(void) ResetTrainerFanClub(); UnionRoomChat_InitializeRegisteredTexts(); ResetMiniGamesResults(); - InitMEventData(); + ClearMysteryGift(); SetAllRenewableItemFlags(); WarpToPlayersRoom(); RunScriptImmediately(EventScript_ResetAllMapFlags); diff --git a/src/script.c b/src/script.c index 9095ab3ba..4d021606d 100644 --- a/src/script.c +++ b/src/script.c @@ -2,12 +2,12 @@ #include "script.h" #include "event_data.h" #include "quest_log.h" +#include "mystery_gift.h" #include "constants/maps.h" #include "constants/map_scripts.h" extern void ResetContextNpcTextColor(void); // field_specials extern u16 CalcCRC16WithTable(u8 *data, int length); // util -extern bool32 ValidateReceivedWonderCard(void); #define RAM_SCRIPT_MAGIC 51 @@ -554,7 +554,7 @@ bool32 ValidateRamScript(void) u8 *GetSavedRamScriptIfValid(void) { struct RamScriptData *scriptData = &gSaveBlock1Ptr->ramScript.data; - if (!ValidateReceivedWonderCard()) + if (!ValidateSavedWonderCard()) return NULL; if (scriptData->magic != RAM_SCRIPT_MAGIC) return NULL; diff --git a/src/wonder_news.c b/src/wonder_news.c index 20f0ab3e7..4e7c4f472 100644 --- a/src/wonder_news.c +++ b/src/wonder_news.c @@ -5,85 +5,100 @@ #include "wonder_news.h" #include "constants/items.h" +/* + Wonder News related functions. + Because this feature is largely unused, the names in here are + mostly nebulous and without a real indication of purpose. +*/ + +enum { + NEWS_VAL_INVALID, + NEWS_VAL_RECV_FRIEND, + NEWS_VAL_RECV_WIRELESS, + NEWS_VAL_NONE, + NEWS_VAL_SENT, + NEWS_VAL_SENT_MAX, + NEWS_VAL_GET_MAX, +}; + static u32 GetMENewsJisanRewardItem(struct WonderNewsMetadata *); static void MENewsJisanIncrementCounterUnk0_5(struct WonderNewsMetadata *); static u32 GetMENewsJisanState(struct WonderNewsMetadata *); static void MENewsJisanIncrementCounterUnk0_2(struct WonderNewsMetadata *); static void MENewsJisanResetCounterUnk0_2(struct WonderNewsMetadata *); -void MENewsJisan_SetRandomReward(u32 a0) +void WonderNews_SetReward(u32 newsType) { - struct WonderNewsMetadata *r5 = GetMENewsJisanStructPtr(); + struct WonderNewsMetadata *data = GetSavedWonderNewsMetadata(); - r5->unk_0_0 = a0; - switch (a0) + data->newsType = newsType; + switch (newsType) { - case 0: + case WONDER_NEWS_NONE: break; - case 1: - case 2: - r5->berry = (Random() % 15) + ITEM_TO_BERRY(ITEM_RAZZ_BERRY); + case WONDER_NEWS_RECV_FRIEND: + case WONDER_NEWS_RECV_WIRELESS: + data->berry = (Random() % 15) + ITEM_TO_BERRY(ITEM_RAZZ_BERRY); break; - case 3: - r5->berry = (Random() % 15) + ITEM_TO_BERRY(ITEM_CHERI_BERRY); + case WONDER_NEWS_SENT: + data->berry = (Random() % 15) + ITEM_TO_BERRY(ITEM_CHERI_BERRY); break; } } -void MENewsJisanReset(void) +void WonderNews_Reset(void) { - struct WonderNewsMetadata *r5 = GetMENewsJisanStructPtr(); + struct WonderNewsMetadata *r5 = GetSavedWonderNewsMetadata(); - r5->unk_0_0 = 0; + r5->newsType = 0; r5->unk_0_2 = 0; r5->unk_0_5 = 0; r5->berry = 0; - VarSet(VAR_MENEWS_JISAN_STEP_COUNTER, 0); + VarSet(VAR_WONDER_NEWS_STEP_COUNTER, 0); } -void MENewsJisanStepCounter(void) +void WonderNews_IncrementStepCounter(void) { - u16 *r4 = GetVarPointer(VAR_MENEWS_JISAN_STEP_COUNTER); - struct WonderNewsMetadata *r2 = GetMENewsJisanStructPtr(); - struct WonderNewsMetadata r0 = *r2; + u16 *stepCounter = GetVarPointer(VAR_WONDER_NEWS_STEP_COUNTER); + struct WonderNewsMetadata *data = GetSavedWonderNewsMetadata(); - if ((u8)r0.unk_0_5 > 4 && ++(*r4) >= 500) + if (data->unk_0_5 > 4 && ++(*stepCounter) >= 500) { - r2->unk_0_5 = 0; - *r4 = 0; + data->unk_0_5 = 0; + *stepCounter = 0; } } u16 GetMENewsJisanItemAndState(void) { - u16 *r6 = &gSpecialVar_Result; - struct WonderNewsMetadata *r4 = GetMENewsJisanStructPtr(); + u16 *result = &gSpecialVar_Result; + struct WonderNewsMetadata *data = GetSavedWonderNewsMetadata(); u16 r5; - if (!IsMysteryGiftEnabled() || !ValidateReceivedWonderNews()) + if (!IsMysteryGiftEnabled() || !ValidateSavedWonderNews()) return 0; - r5 = GetMENewsJisanState(r4); + r5 = GetMENewsJisanState(data); switch (r5) { case 0: break; case 1: - *r6 = GetMENewsJisanRewardItem(r4); + *result = GetMENewsJisanRewardItem(data); break; case 2: - *r6 = GetMENewsJisanRewardItem(r4); + *result = GetMENewsJisanRewardItem(data); break; case 3: break; case 4: - *r6 = GetMENewsJisanRewardItem(r4); - MENewsJisanIncrementCounterUnk0_2(r4); + *result = GetMENewsJisanRewardItem(data); + MENewsJisanIncrementCounterUnk0_2(data); break; case 5: - *r6 = GetMENewsJisanRewardItem(r4); - MENewsJisanResetCounterUnk0_2(r4); + *result = GetMENewsJisanRewardItem(data); + MENewsJisanResetCounterUnk0_2(data); break; case 6: break; @@ -96,7 +111,7 @@ static u32 GetMENewsJisanRewardItem(struct WonderNewsMetadata *a0) { u32 r4; - a0->unk_0_0 = 0; + a0->newsType = 0; r4 = a0->berry + FIRST_BERRY_INDEX - 1; a0->berry = 0; MENewsJisanIncrementCounterUnk0_5(a0); @@ -122,23 +137,21 @@ static void MENewsJisanIncrementCounterUnk0_5(struct WonderNewsMetadata *a0) a0->unk_0_5 = 5; } -static u32 GetMENewsJisanState(struct WonderNewsMetadata *a0) +static u32 GetMENewsJisanState(struct WonderNewsMetadata *data) { - struct WonderNewsMetadata r0; - if ((u8)a0->unk_0_5 == 5) + if (data->unk_0_5 == 5) return 6; - r0 = *a0; - switch (r0.unk_0_0) + switch (data->newsType) { - case 0: + case WONDER_NEWS_NONE: return 3; - case 1: + case WONDER_NEWS_RECV_FRIEND: return 1; - case 2: + case WONDER_NEWS_RECV_WIRELESS: return 2; - case 3: - if ((u8)r0.unk_0_2 < 3) + case WONDER_NEWS_SENT: + if (data->unk_0_2 < 3) return 4; return 5; default: From 12b0c700699763a80addaf7f0341dd140de8e124 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Sat, 19 Nov 2022 21:18:10 -0500 Subject: [PATCH 3/8] Sync mystery_gift_link --- include/mystery_gift_server.h | 37 ++--- src/mystery_gift_client.c | 14 +- src/mystery_gift_link.c | 291 ++++++++++++++++++---------------- src/mystery_gift_server.c | 10 +- 4 files changed, 178 insertions(+), 174 deletions(-) diff --git a/include/mystery_gift_server.h b/include/mystery_gift_server.h index 2a9070afb..7c71ed856 100644 --- a/include/mystery_gift_server.h +++ b/include/mystery_gift_server.h @@ -5,11 +5,11 @@ #define ME_SEND_BUF_SIZE 0x400 -struct mevent_srv_sub +struct MysteryGiftLink { - s32 seqno; - u8 sendPlayerNo; - u8 recvPlayerNo; + s32 state; + u8 sendPlayerId; + u8 recvPlayerId; u16 recvIdent; u16 recvCounter; u16 recvCRC; @@ -18,17 +18,10 @@ struct mevent_srv_sub u16 sendCounter; u16 sendCRC; u16 sendSize; - void *recvBfr; - const void *sendBfr; - u32 (*recvFunc)(struct mevent_srv_sub *); - u32 (*sendFunc)(struct mevent_srv_sub *); -}; - -struct send_recv_header -{ - u16 ident; - u16 crc; - u16 size; + void *recvBuffer; + const void *sendBuffer; + u32 (*recvFunc)(struct MysteryGiftLink *); + u32 (*sendFunc)(struct MysteryGiftLink *); }; struct mevent_client_cmd @@ -63,7 +56,7 @@ struct mevent_client void *recvBuffer; struct mevent_client_cmd * cmdBuffer; void *buffer; - struct mevent_srv_sub manager; + struct MysteryGiftLink manager; }; struct mevent_server_cmd @@ -108,14 +101,14 @@ struct mevent_srv_common void *sendBuffer2; u32 sendBuffer2Size; u32 sendWord; - struct mevent_srv_sub manager; + struct MysteryGiftLink manager; }; -u32 mevent_srv_sub_recv(struct mevent_srv_sub * svr); -u32 mevent_srv_sub_send(struct mevent_srv_sub * svr); -void mevent_srv_sub_init(struct mevent_srv_sub * svr, u32 sendPlayerNo, u32 recvPlayerNo); -void mevent_srv_sub_init_send(struct mevent_srv_sub * svr, u32 ident, const void *src, u32 size); -void mevent_srv_sub_init_recv(struct mevent_srv_sub * svr, u32 ident, void *dest); +u32 MysteryGiftLink_Recv(struct MysteryGiftLink * link); +u32 MysteryGiftLink_Send(struct MysteryGiftLink * link); +void MysteryGiftLink_Init(struct MysteryGiftLink * link, u32 sendPlayerId, u32 recvPlayerId); +void MysteryGiftLink_InitSend(struct MysteryGiftLink * link, u32 ident, const void *src, u32 size); +void MysteryGiftLink_InitRecv(struct MysteryGiftLink * link, u32 ident, void *dest); void mevent_client_do_init(void); u32 mevent_client_do_exec(u16 * a0); diff --git a/src/mystery_gift_client.c b/src/mystery_gift_client.c index 48fc8ffc3..5844f80e2 100644 --- a/src/mystery_gift_client.c +++ b/src/mystery_gift_client.c @@ -62,7 +62,7 @@ static void mevent_client_init(struct mevent_client * svr, u32 sendPlayerNo, u32 svr->recvBuffer = AllocZeroed(ME_SEND_BUF_SIZE); svr->cmdBuffer = AllocZeroed(ME_SEND_BUF_SIZE); svr->buffer = AllocZeroed(0x40); - mevent_srv_sub_init(&svr->manager, sendPlayerNo, recvPlayerNo); + MysteryGiftLink_Init(&svr->manager, sendPlayerNo, recvPlayerNo); } static void mevent_client_free_resources(struct mevent_client * svr) @@ -83,7 +83,7 @@ static void mevent_client_send_word(struct mevent_client * svr, u32 ident, u32 w { CpuFill32(0, svr->sendBuffer, ME_SEND_BUF_SIZE); *(u32 *)svr->sendBuffer = word; - mevent_srv_sub_init_send(&svr->manager, ident, svr->sendBuffer, sizeof(u32)); + MysteryGiftLink_InitSend(&svr->manager, ident, svr->sendBuffer, sizeof(u32)); } static u32 client_mainseq_0(struct mevent_client * svr) @@ -105,7 +105,7 @@ static u32 client_mainseq_1(struct mevent_client * svr) static u32 client_mainseq_2(struct mevent_client * svr) { // do recv - if (mevent_srv_sub_recv(&svr->manager)) + if (MysteryGiftLink_Recv(&svr->manager)) { svr->mainseqno = 4; svr->flag = 0; @@ -116,7 +116,7 @@ static u32 client_mainseq_2(struct mevent_client * svr) static u32 client_mainseq_3(struct mevent_client * svr) { // do send - if (mevent_srv_sub_send(&svr->manager)) + if (MysteryGiftLink_Send(&svr->manager)) { svr->mainseqno = 4; svr->flag = 0; @@ -139,7 +139,7 @@ static u32 client_mainseq_4(struct mevent_client * svr) svr->flag = 0; break; case 2: - mevent_srv_sub_init_recv(&svr->manager, cmd->parameter, svr->recvBuffer); + MysteryGiftLink_InitRecv(&svr->manager, cmd->parameter, svr->recvBuffer); svr->mainseqno = 2; svr->flag = 0; break; @@ -148,7 +148,7 @@ static u32 client_mainseq_4(struct mevent_client * svr) svr->flag = 0; break; case 20: - mevent_srv_sub_init_send(&svr->manager, 0x14, svr->sendBuffer, 0); + MysteryGiftLink_InitSend(&svr->manager, 0x14, svr->sendBuffer, 0); svr->mainseqno = 3; svr->flag = 0; break; @@ -189,7 +189,7 @@ static u32 client_mainseq_4(struct mevent_client * svr) return 4; case 8: MysteryGift_LoadLinkGameData(svr->sendBuffer); - mevent_srv_sub_init_send(&svr->manager, 0x11, svr->sendBuffer, sizeof(struct MysteryGiftLinkGameData)); + MysteryGiftLink_InitSend(&svr->manager, 0x11, svr->sendBuffer, sizeof(struct MysteryGiftLinkGameData)); break; case 14: mevent_client_send_word(svr, 0x13, svr->param); diff --git a/src/mystery_gift_link.c b/src/mystery_gift_link.c index f90151d6b..0ef2eb84a 100644 --- a/src/mystery_gift_link.c +++ b/src/mystery_gift_link.c @@ -4,200 +4,211 @@ #include "link_rfu.h" #include "mystery_gift_server.h" -static u32 mevent_receive_func(struct mevent_srv_sub *); -static u32 mevent_send_func(struct mevent_srv_sub *); +/* + Handles the link connection functions used by the Mystery Gift client/server. + Note: MysteryGiftLink is shortened to MGL for internal functions. +*/ -u32 mevent_srv_sub_recv(struct mevent_srv_sub * 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 mevent_srv_sub_send(struct mevent_srv_sub * svr) +u32 MysteryGiftLink_Send(struct MysteryGiftLink * link) { - return svr->sendFunc(svr); + return link->sendFunc(link); } -void mevent_srv_sub_init(struct mevent_srv_sub * 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->sendBuffer = NULL; + link->recvBuffer = NULL; + link->sendFunc = MGL_Send; + link->recvFunc = MGL_Receive; } -void mevent_srv_sub_init_send(struct mevent_srv_sub * 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 = ME_SEND_BUF_SIZE; + link->sendBuffer = src; } -void mevent_srv_sub_init_recv(struct mevent_srv_sub * 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->recvBuffer = 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 mevent_srv_sub * 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 > ME_SEND_BUF_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->recvBuffer + blocksize, link->recvSize - blocksize); + link->recvCounter++; + link->state++; + } + else + { + MGL_ReceiveBlock(link->recvPlayerId, link->recvBuffer + blocksize, 252); + link->recvCounter++; + } + MGL_ResetReceived(link->recvPlayerId); + } + break; + case 2: + if (CalcCRC16WithTable(link->recvBuffer, link->recvSize) != link->recvCRC) + { + LinkRfu_FatalError(); + return FALSE; + } + else + { + link->state = 0; + return TRUE; + } + break; } return FALSE; } -static bool32 mevent_send_func(struct mevent_srv_sub * 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->sendBuffer, 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->sendBuffer + blocksize, link->sendSize - blocksize); + link->sendCounter++; + link->state++; + } + else + { + SendBlock(0, link->sendBuffer + 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->sendBuffer, 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_server.c b/src/mystery_gift_server.c index d2f15644a..d2f2b2262 100644 --- a/src/mystery_gift_server.c +++ b/src/mystery_gift_server.c @@ -51,7 +51,7 @@ static void mevent_srv_init_common(struct mevent_srv_common * svr, const void *c svr->mevent_unk1442cc = AllocZeroed(sizeof(struct MysteryGiftLinkGameData)); svr->cmdBuffer = cmdBuffer; svr->cmdidx = 0; - mevent_srv_sub_init(&svr->manager, sendPlayerNo, recvPlayerNo); + MysteryGiftLink_Init(&svr->manager, sendPlayerNo, recvPlayerNo); } static void mevent_srv_free_resources(struct mevent_srv_common * svr) @@ -65,7 +65,7 @@ static void mevent_srv_free_resources(struct mevent_srv_common * svr) static void mevent_srv_common_init_send(struct mevent_srv_common * svr, u32 ident, const void *src, u32 size) { AGB_ASSERT_EX(size <= ME_SEND_BUF_SIZE, ABSPATH("mevent_server.c"), 257); - mevent_srv_sub_init_send(&svr->manager, ident, src, size); + MysteryGiftLink_InitSend(&svr->manager, ident, src, size); } static void *mevent_first_if_not_null_else_second(void *a0, void *a1) @@ -102,7 +102,7 @@ static u32 common_mainseq_1(struct mevent_srv_common * svr) static u32 common_mainseq_2(struct mevent_srv_common * svr) { // do recv - if (mevent_srv_sub_recv(&svr->manager)) + if (MysteryGiftLink_Recv(&svr->manager)) svr->mainseqno = 4; return 1; } @@ -110,7 +110,7 @@ static u32 common_mainseq_2(struct mevent_srv_common * svr) static u32 common_mainseq_3(struct mevent_srv_common * svr) { // do send - if (mevent_srv_sub_send(&svr->manager)) + if (MysteryGiftLink_Send(&svr->manager)) svr->mainseqno = 4; return 1; } @@ -134,7 +134,7 @@ static u32 common_mainseq_4(struct mevent_srv_common * svr) break; case 2: AGB_ASSERT_EX(cmd->parameter == NULL, ABSPATH("mevent_server.c"), 364); - mevent_srv_sub_init_recv(&svr->manager, cmd->flag, svr->recvBuffer); + MysteryGiftLink_InitRecv(&svr->manager, cmd->flag, svr->recvBuffer); svr->mainseqno = 2; break; case 3: From 52e1af81b30d956d6b61405d5340d8cb26725eb5 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Mon, 21 Nov 2022 12:37:25 -0500 Subject: [PATCH 4/8] Document pokedex area markers --- include/pokedex.h | 84 +++++++++ include/pokedex_area_markers.h | 18 +- include/wild_encounter.h | 2 + include/wild_pokemon_area.h | 2 +- src/pokedex_area_markers.c | 301 +++++++++++++++++-------------- src/pokedex_screen.c | 12 +- src/wild_encounter.c | 2 +- src/wild_pokemon_area.c | 318 +++++++++++++++++---------------- 8 files changed, 434 insertions(+), 305 deletions(-) diff --git a/include/pokedex.h b/include/pokedex.h index 0e20648f7..8e27bbe56 100644 --- a/include/pokedex.h +++ b/include/pokedex.h @@ -15,6 +15,90 @@ enum FLAG_SET_CAUGHT }; +// IDs for the pokedex area markers +enum { + DEX_AREA_NONE, + DEX_AREA_PALLET_TOWN, + DEX_AREA_VIRIDIAN_CITY, + DEX_AREA_PEWTER_CITY, + DEX_AREA_CERULEAN_CITY, + DEX_AREA_LAVENDER_TOWN, + DEX_AREA_VERMILION_CITY, + DEX_AREA_CELADON_CITY, + DEX_AREA_FUCHSIA_CITY, + DEX_AREA_CINNABAR_ISLAND, + DEX_AREA_INDIGO_PLATEAU, + DEX_AREA_SAFFRON_CITY, + DEX_AREA_ROUTE_1, + DEX_AREA_ROUTE_2, + DEX_AREA_ROUTE_3, + DEX_AREA_ROUTE_4, + DEX_AREA_ROUTE_5, + DEX_AREA_ROUTE_6, + DEX_AREA_ROUTE_7, + DEX_AREA_ROUTE_8, + DEX_AREA_ROUTE_9, + DEX_AREA_ROUTE_10, + DEX_AREA_ROUTE_11, + DEX_AREA_ROUTE_12, + DEX_AREA_ROUTE_13, + DEX_AREA_ROUTE_14, + DEX_AREA_ROUTE_15, + DEX_AREA_ROUTE_16, + DEX_AREA_ROUTE_17, + DEX_AREA_ROUTE_18, + DEX_AREA_ROUTE_19, + DEX_AREA_ROUTE_20, + DEX_AREA_ROUTE_21, + DEX_AREA_ROUTE_22, + DEX_AREA_ROUTE_23, + DEX_AREA_ROUTE_24, + DEX_AREA_ROUTE_25, + DEX_AREA_VIRIDIAN_FOREST, + DEX_AREA_DIGLETTS_CAVE, + DEX_AREA_MT_MOON, + DEX_AREA_CERULEAN_CAVE, + DEX_AREA_ROCK_TUNNEL, + DEX_AREA_POWER_PLANT, + DEX_AREA_POKEMON_TOWER, + DEX_AREA_SAFARI_ZONE, + DEX_AREA_SEAFOAM_ISLANDS, + DEX_AREA_POKEMON_MANSION, + DEX_AREA_VICTORY_ROAD, + DEX_AREA_ONE_ISLAND, + DEX_AREA_TWO_ISLAND, + DEX_AREA_THREE_ISLAND, + DEX_AREA_FOUR_ISLAND, + DEX_AREA_FIVE_ISLAND, + DEX_AREA_SIX_ISLAND, // Not associated with any MAPSEC + DEX_AREA_SEVEN_ISLAND, // Not associated with any MAPSEC + DEX_AREA_KINDLE_ROAD, + DEX_AREA_TREASURE_BEACH, + DEX_AREA_CAPE_BRINK, + DEX_AREA_BOND_BRIDGE, + DEX_AREA_THREE_ISLE_PATH, + DEX_AREA_RESORT_GORGEOUS, + DEX_AREA_WATER_LABYRINTH, + DEX_AREA_FIVE_ISLE_MEADOW, + DEX_AREA_MEMORIAL_PILLAR, + DEX_AREA_OUTCAST_ISLAND, + DEX_AREA_GREEN_PATH, + DEX_AREA_WATER_PATH, + DEX_AREA_RUIN_VALLEY, + DEX_AREA_TRAINER_TOWER, + DEX_AREA_CANYON_ENTRANCE, + DEX_AREA_SEVAULT_CANYON, + DEX_AREA_TANOBY_RUINS, + DEX_AREA_MT_EMBER, + DEX_AREA_BERRY_FOREST, + DEX_AREA_ICEFALL_CAVE, + DEX_AREA_LOST_CAVE, + DEX_AREA_ALTERING_CAVE, + DEX_AREA_PATTERN_BUSH, + DEX_AREA_DOTTED_HOLE, + DEX_AREA_TANOBY_CHAMBER, +}; + struct PokedexEntry { /*0x00*/ u8 categoryName[12]; diff --git a/include/pokedex_area_markers.h b/include/pokedex_area_markers.h index c0b1978cc..48f54389f 100644 --- a/include/pokedex_area_markers.h +++ b/include/pokedex_area_markers.h @@ -1,19 +1,9 @@ #ifndef GUARD_POKEDEX_AREA_MARKERS_H #define GUARD_POKEDEX_AREA_MARKERS_H -struct PAM_TaskData -{ - struct SubspriteTable subsprites; - void *buffer; - u8 unk_0C; - u8 spr_id; - u16 tilesTag; - u16 unk_10; -}; - -void SetAreaSubsprite(s32 i, s32 whichArea, struct Subsprite * subsprites); -void Dtor_PokedexAreaMarkers(u8 taskId); -u8 Ctor_PokedexAreaMarkers(u16 species, u16 tilesTag, u8 palIdx, u8 y); -u8 PokedexAreaMarkers_Any(u8 taskId); +void GetAreaMarkerSubsprite(s32 i, s32 dexArea, struct Subsprite * subsprites); +void DestroyPokedexAreaMarkers(u8 taskId); +u8 CreatePokedexAreaMarkers(u16 species, u16 tilesTag, u8 palIdx, u8 y); +u8 GetNumPokedexAreaMarkers(u8 taskId); #endif //GUARD_POKEDEX_AREA_MARKERS_H diff --git a/include/wild_encounter.h b/include/wild_encounter.h index 8e151d55d..b73010306 100644 --- a/include/wild_encounter.h +++ b/include/wild_encounter.h @@ -8,6 +8,8 @@ #define ROCK_WILD_COUNT 5 #define FISH_WILD_COUNT 10 +#define NUM_ALTERING_CAVE_TABLES 9 + struct WildPokemon { u8 minLevel; diff --git a/include/wild_pokemon_area.h b/include/wild_pokemon_area.h index 354683408..f1d67fd86 100644 --- a/include/wild_pokemon_area.h +++ b/include/wild_pokemon_area.h @@ -1,6 +1,6 @@ #ifndef GUARD_WILD_POKEMON_AREA_H #define GUARD_WILD_POKEMON_AREA_H -s32 BuildPokedexAreaSubspriteBuffer(u16 species, struct Subsprite * subsprites); +s32 GetSpeciesPokedexAreaMarkers(u16 species, struct Subsprite * subsprites); #endif //GUARD_WILD_POKEMON_AREA_H diff --git a/src/pokedex_area_markers.c b/src/pokedex_area_markers.c index 5226133ac..6ca1090c9 100644 --- a/src/pokedex_area_markers.c +++ b/src/pokedex_area_markers.c @@ -4,160 +4,191 @@ #include "task.h" #include "wild_pokemon_area.h" #include "pokedex_area_markers.h" +#include "pokedex.h" + +/* + Controls the red ellipse markers that appear on the pokedex maps to show where a species is found. + All of the markers together are a single sprite, with each individual marker being represented by + a subsprite of the necessary size and shape. + + The data about each area marker is in sAreaMarkers, each specified by a DEX_AREA constant. + A MAPSEC is associated with a DEX_AREA constant by a series of arrays in wild_pokemon_area.c +*/ + +struct PAM_TaskData +{ + struct SubspriteTable subsprites; + void *buffer; + u8 unused; + u8 spriteId; + u16 tilesTag; + u16 paletteTag; // Never read +}; + +enum { + MARKER_CIRCULAR, + MARKER_SMALL_H, + MARKER_SMALL_V, + MARKER_MED_H, + MARKER_MED_V, + MARKER_LARGE_H, + MARKER_LARGE_V, +}; static const u16 sMarkerPal[] = INCBIN_U16("graphics/pokedex/area_markers/marker.gbapal"); static const u32 sMarkerTiles[] = INCBIN_U32("graphics/pokedex/area_markers/marker.4bpp.lz"); -static const struct Subsprite sSubsprite0 = { - .size = ST_OAM_SIZE_0, - .shape = ST_OAM_SQUARE, +static const struct Subsprite sSubsprite_Circular = { + .size = SPRITE_SIZE(8x8), + .shape = SPRITE_SHAPE(8x8), .priority = 1, .tileOffset = 0 }; -static const struct Subsprite sSubsprite1 = { - .size = ST_OAM_SIZE_0, - .shape = ST_OAM_H_RECTANGLE, +static const struct Subsprite sSubsprite_SmallHorizontal = { + .size = SPRITE_SIZE(16x8), + .shape = SPRITE_SHAPE(16x8), .priority = 1, .tileOffset = 1 }; -static const struct Subsprite sSubsprite2 = { - .size = ST_OAM_SIZE_0, - .shape = ST_OAM_V_RECTANGLE, +static const struct Subsprite sSubsprite_SmallVertical = { + .size = SPRITE_SIZE(8x16), + .shape = SPRITE_SHAPE(8x16), .priority = 1, .tileOffset = 3 }; -static const struct Subsprite sSubsprite3 = { - .size = ST_OAM_SIZE_2, - .shape = ST_OAM_H_RECTANGLE, +static const struct Subsprite sSubsprite_MediumHorizontal = { + .size = SPRITE_SIZE(32x16), + .shape = SPRITE_SHAPE(32x16), .priority = 1, .tileOffset = 5 }; -static const struct Subsprite sSubsprite4 = { - .size = ST_OAM_SIZE_2, - .shape = ST_OAM_V_RECTANGLE, +static const struct Subsprite sSubsprite_MediumVertical = { + .size = SPRITE_SIZE(16x32), + .shape = SPRITE_SHAPE(16x32), .priority = 1, .tileOffset = 13 }; -static const struct Subsprite sSubsprite5 = { - .size = ST_OAM_SIZE_2, - .shape = ST_OAM_H_RECTANGLE, +static const struct Subsprite sSubsprite_LargeHorizontal = { + .size = SPRITE_SIZE(32x16), + .shape = SPRITE_SHAPE(32x16), .priority = 1, .tileOffset = 21 }; -static const struct Subsprite sSubsprite6 = { - .size = ST_OAM_SIZE_2, - .shape = ST_OAM_V_RECTANGLE, +static const struct Subsprite sSubsprite_LargeVertical = { + .size = SPRITE_SIZE(16x32), + .shape = SPRITE_SHAPE(16x32), .priority = 1, .tileOffset = 29 }; static const struct Subsprite *const sSubsprites[] = { - &sSubsprite0, - &sSubsprite1, - &sSubsprite2, - &sSubsprite3, - &sSubsprite4, - &sSubsprite5, - &sSubsprite6 + [MARKER_CIRCULAR] = &sSubsprite_Circular, + [MARKER_SMALL_H] = &sSubsprite_SmallHorizontal, + [MARKER_SMALL_V] = &sSubsprite_SmallVertical, + [MARKER_MED_H] = &sSubsprite_MediumHorizontal, + [MARKER_MED_V] = &sSubsprite_MediumVertical, + [MARKER_LARGE_H] = &sSubsprite_LargeHorizontal, + [MARKER_LARGE_V] = &sSubsprite_LargeVertical }; -static const s8 sSubspriteLookupTable[][4] = { - { 0, 0x00, 0x00 }, - { 0, 0x36, 0x2c }, - { 0, 0x36, 0x1c }, - { 0, 0x36, 0x0c }, - { 0, 0x5c, 0x0c }, - { 0, 0x6e, 0x18 }, - { 0, 0x5c, 0x24 }, - { 0, 0x4c, 0x18 }, - { 0, 0x4e, 0x34 }, - { 0, 0x36, 0x3e }, - { 0, 0x2a, 0x02 }, - { 0, 0x5c, 0x18 }, - { 2, 0x36, 0x20 }, - { 2, 0x36, 0x10 }, - { 1, 0x3d, 0x0c }, - { 1, 0x4d, 0x0c }, - { 0, 0x5c, 0x12 }, - { 0, 0x5c, 0x1e }, - { 0, 0x54, 0x18 }, - { 1, 0x62, 0x18 }, - { 1, 0x62, 0x0c }, - { 2, 0x6e, 0x0c }, - { 1, 0x62, 0x24 }, - { 4, 0x6a, 0x19 }, - { 1, 0x64, 0x2e }, - { 2, 0x5e, 0x2d }, - { 1, 0x55, 0x34 }, - { 0, 0x44, 0x18 }, - { 4, 0x3e, 0x1a }, - { 1, 0x40, 0x34 }, - { 0, 0x4e, 0x3c }, - { 3, 0x37, 0x3a }, - { 2, 0x36, 0x32 }, - { 1, 0x28, 0x1c }, - { 4, 0x26, 0x04 }, - { 0, 0x5c, 0x04 }, - { 3, 0x5a, 0xfe }, - { 0, 0x33, 0x14 }, - { 1, 0x3d, 0x12 }, - { 0, 0x48, 0x08 }, - { 0, 0x57, 0x08 }, - { 0, 0x70, 0x0e }, - { 0, 0x71, 0x14 }, - { 0, 0x71, 0x19 }, - { 1, 0x4e, 0x2c }, - { 0, 0x41, 0x3c }, - { 0, 0x34, 0x3e }, - { 0, 0x2d, 0x07 }, - { 0, 0x0a, 0x0a }, - { 0, 0x0c, 0x23 }, - { 0, 0x0e, 0x34 }, - { 0, 0x0c, 0x54 }, - { 0, 0x2d, 0x51 }, - { 0, 0x4c, 0x54 }, - { 0, 0x68, 0x52 }, - { 2, 0x0e, 0x02 }, - { 0, 0x0a, 0x0f }, - { 0, 0x0c, 0x1d }, - { 1, 0x02, 0x34 }, - { 1, 0x0c, 0x38 }, - { 1, 0x2c, 0x4a }, - { 1, 0x24, 0x4e }, - { 2, 0x30, 0x50 }, - { 2, 0x34, 0x56 }, - { 0, 0x48, 0x4a }, - { 1, 0x48, 0x4e }, - { 2, 0x51, 0x50 }, - { 0, 0x4c, 0x5c }, - { 0, 0x68, 0x4b }, - { 0, 0x68, 0x56 }, - { 2, 0x6c, 0x53 }, - { 3, 0x60, 0x5a }, - { 0, 0x0e, 0x01 }, - { 0, 0x05, 0x34 }, - { 0, 0x0d, 0x50 }, - { 0, 0x36, 0x4a }, - { 0, 0x45, 0x49 }, - { 0, 0x4c, 0x4d }, - { 0, 0x49, 0x5f }, - { 3, 0x60, 0x5a } +static const s8 sAreaMarkers[][4] = { + // Marker, x, y + [DEX_AREA_NONE] = {}, + [DEX_AREA_PALLET_TOWN] = { MARKER_CIRCULAR, 54, 44 }, + [DEX_AREA_VIRIDIAN_CITY] = { MARKER_CIRCULAR, 54, 28 }, + [DEX_AREA_PEWTER_CITY] = { MARKER_CIRCULAR, 54, 12 }, + [DEX_AREA_CERULEAN_CITY] = { MARKER_CIRCULAR, 92, 12 }, + [DEX_AREA_LAVENDER_TOWN] = { MARKER_CIRCULAR, 110, 24 }, + [DEX_AREA_VERMILION_CITY] = { MARKER_CIRCULAR, 92, 36 }, + [DEX_AREA_CELADON_CITY] = { MARKER_CIRCULAR, 76, 24 }, + [DEX_AREA_FUCHSIA_CITY] = { MARKER_CIRCULAR, 78, 52 }, + [DEX_AREA_CINNABAR_ISLAND] = { MARKER_CIRCULAR, 54, 62 }, + [DEX_AREA_INDIGO_PLATEAU] = { MARKER_CIRCULAR, 42, 2 }, + [DEX_AREA_SAFFRON_CITY] = { MARKER_CIRCULAR, 92, 24 }, + [DEX_AREA_ROUTE_1] = { MARKER_SMALL_V, 54, 32 }, + [DEX_AREA_ROUTE_2] = { MARKER_SMALL_V, 54, 16 }, + [DEX_AREA_ROUTE_3] = { MARKER_SMALL_H, 61, 12 }, + [DEX_AREA_ROUTE_4] = { MARKER_SMALL_H, 77, 12 }, + [DEX_AREA_ROUTE_5] = { MARKER_CIRCULAR, 92, 18 }, + [DEX_AREA_ROUTE_6] = { MARKER_CIRCULAR, 92, 30 }, + [DEX_AREA_ROUTE_7] = { MARKER_CIRCULAR, 84, 24 }, + [DEX_AREA_ROUTE_8] = { MARKER_SMALL_H, 98, 24 }, + [DEX_AREA_ROUTE_9] = { MARKER_SMALL_H, 98, 12 }, + [DEX_AREA_ROUTE_10] = { MARKER_SMALL_V, 110, 12 }, + [DEX_AREA_ROUTE_11] = { MARKER_SMALL_H, 98, 36 }, + [DEX_AREA_ROUTE_12] = { MARKER_MED_V, 106, 25 }, + [DEX_AREA_ROUTE_13] = { MARKER_SMALL_H, 100, 46 }, + [DEX_AREA_ROUTE_14] = { MARKER_SMALL_V, 94, 45 }, + [DEX_AREA_ROUTE_15] = { MARKER_SMALL_H, 85, 52 }, + [DEX_AREA_ROUTE_16] = { MARKER_CIRCULAR, 68, 24 }, + [DEX_AREA_ROUTE_17] = { MARKER_MED_V, 62, 26 }, + [DEX_AREA_ROUTE_18] = { MARKER_SMALL_H, 64, 52 }, + [DEX_AREA_ROUTE_19] = { MARKER_CIRCULAR, 78, 60 }, + [DEX_AREA_ROUTE_20] = { MARKER_MED_H, 55, 58 }, + [DEX_AREA_ROUTE_21] = { MARKER_SMALL_V, 54, 50 }, + [DEX_AREA_ROUTE_22] = { MARKER_SMALL_H, 40, 28 }, + [DEX_AREA_ROUTE_23] = { MARKER_MED_V, 38, 4 }, + [DEX_AREA_ROUTE_24] = { MARKER_CIRCULAR, 92, 4 }, + [DEX_AREA_ROUTE_25] = { MARKER_MED_H, 90, 254 }, + [DEX_AREA_VIRIDIAN_FOREST] = { MARKER_CIRCULAR, 51, 20 }, + [DEX_AREA_DIGLETTS_CAVE] = { MARKER_SMALL_H, 61, 18 }, + [DEX_AREA_MT_MOON] = { MARKER_CIRCULAR, 72, 8 }, + [DEX_AREA_CERULEAN_CAVE] = { MARKER_CIRCULAR, 87, 8 }, + [DEX_AREA_ROCK_TUNNEL] = { MARKER_CIRCULAR, 112, 14 }, + [DEX_AREA_POWER_PLANT] = { MARKER_CIRCULAR, 113, 20 }, + [DEX_AREA_POKEMON_TOWER] = { MARKER_CIRCULAR, 113, 25 }, + [DEX_AREA_SAFARI_ZONE] = { MARKER_SMALL_H, 78, 44 }, + [DEX_AREA_SEAFOAM_ISLANDS] = { MARKER_CIRCULAR, 65, 60 }, + [DEX_AREA_POKEMON_MANSION] = { MARKER_CIRCULAR, 52, 62 }, + [DEX_AREA_VICTORY_ROAD] = { MARKER_CIRCULAR, 45, 7 }, + [DEX_AREA_ONE_ISLAND] = { MARKER_CIRCULAR, 10, 10 }, + [DEX_AREA_TWO_ISLAND] = { MARKER_CIRCULAR, 12, 35 }, + [DEX_AREA_THREE_ISLAND] = { MARKER_CIRCULAR, 14, 52 }, + [DEX_AREA_FOUR_ISLAND] = { MARKER_CIRCULAR, 12, 84 }, + [DEX_AREA_FIVE_ISLAND] = { MARKER_CIRCULAR, 45, 81 }, + [DEX_AREA_SIX_ISLAND] = { MARKER_CIRCULAR, 76, 84 }, + [DEX_AREA_SEVEN_ISLAND] = { MARKER_CIRCULAR, 104, 82 }, + [DEX_AREA_KINDLE_ROAD] = { MARKER_SMALL_V, 14, 2 }, + [DEX_AREA_TREASURE_BEACH] = { MARKER_CIRCULAR, 10, 15 }, + [DEX_AREA_CAPE_BRINK] = { MARKER_CIRCULAR, 12, 29 }, + [DEX_AREA_BOND_BRIDGE] = { MARKER_SMALL_H, 2, 52 }, + [DEX_AREA_THREE_ISLE_PATH] = { MARKER_SMALL_H, 12, 56 }, + [DEX_AREA_RESORT_GORGEOUS] = { MARKER_SMALL_H, 44, 74 }, + [DEX_AREA_WATER_LABYRINTH] = { MARKER_SMALL_H, 36, 78 }, + [DEX_AREA_FIVE_ISLE_MEADOW] = { MARKER_SMALL_V, 48, 80 }, + [DEX_AREA_MEMORIAL_PILLAR] = { MARKER_SMALL_V, 52, 86 }, + [DEX_AREA_OUTCAST_ISLAND] = { MARKER_CIRCULAR, 72, 74 }, + [DEX_AREA_GREEN_PATH] = { MARKER_SMALL_H, 72, 78 }, + [DEX_AREA_WATER_PATH] = { MARKER_SMALL_V, 81, 80 }, + [DEX_AREA_RUIN_VALLEY] = { MARKER_CIRCULAR, 76, 92 }, + [DEX_AREA_TRAINER_TOWER] = { MARKER_CIRCULAR, 104, 75 }, + [DEX_AREA_CANYON_ENTRANCE] = { MARKER_CIRCULAR, 104, 86 }, + [DEX_AREA_SEVAULT_CANYON] = { MARKER_SMALL_V, 108, 83 }, + [DEX_AREA_TANOBY_RUINS] = { MARKER_MED_H, 96, 90 }, + [DEX_AREA_MT_EMBER] = { MARKER_CIRCULAR, 14, 1 }, + [DEX_AREA_BERRY_FOREST] = { MARKER_CIRCULAR, 5, 52 }, + [DEX_AREA_ICEFALL_CAVE] = { MARKER_CIRCULAR, 13, 80 }, + [DEX_AREA_LOST_CAVE] = { MARKER_CIRCULAR, 54, 74 }, + [DEX_AREA_ALTERING_CAVE] = { MARKER_CIRCULAR, 69, 73 }, + [DEX_AREA_PATTERN_BUSH] = { MARKER_CIRCULAR, 76, 77 }, + [DEX_AREA_DOTTED_HOLE] = { MARKER_CIRCULAR, 73, 95 }, + [DEX_AREA_TANOBY_CHAMBER] = { MARKER_MED_H, 96, 90 }, }; static void Task_ShowAreaMarkers(u8 taskId) { struct PAM_TaskData * data = (void *)gTasks[taskId].data; - gSprites[data->spr_id].invisible = FALSE; + gSprites[data->spriteId].invisible = FALSE; } -u8 Ctor_PokedexAreaMarkers(u16 species, u16 tilesTag, u8 palIdx, u8 y) +u8 CreatePokedexAreaMarkers(u16 species, u16 tilesTag, u8 palIdx, u8 y) { struct SpriteTemplate spriteTemplate; struct CompressedSpriteSheet spriteSheet; @@ -165,34 +196,42 @@ u8 Ctor_PokedexAreaMarkers(u16 species, u16 tilesTag, u8 palIdx, u8 y) struct PAM_TaskData * data; struct Subsprite * subsprites; + // Load gfx spriteSheet.data = sMarkerTiles; spriteSheet.size = 0x4A0; spriteSheet.tag = tilesTag; LoadCompressedSpriteSheet(&spriteSheet); LoadPalette(sMarkerPal, 0x100 + 16 * palIdx, 0x20); + + // Get marker subsprites taskId = CreateTask(Task_ShowAreaMarkers, 0); data = (void *)gTasks[taskId].data; - data->unk_0C = 0; + data->unused = 0; data->tilesTag = tilesTag; - data->unk_10 = 0xFFFF; + data->paletteTag = TAG_NONE; subsprites = Alloc(120 * sizeof(struct Subsprite)); data->buffer = subsprites; data->subsprites.subsprites = subsprites; - data->subsprites.subspriteCount = BuildPokedexAreaSubspriteBuffer(species, subsprites); + data->subsprites.subspriteCount = GetSpeciesPokedexAreaMarkers(species, subsprites); + SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_OBJWIN_ON); SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG1 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_BG0 | BLDCNT_TGT2_BG1 | BLDCNT_TGT2_BG2 | BLDCNT_TGT2_BG3 | BLDCNT_TGT2_BD); SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(12, 8)); SetGpuReg(REG_OFFSET_BLDY, 0); - SetGpuReg(REG_OFFSET_WININ, 0x1F1F); - SetGpuReg(REG_OFFSET_WINOUT, 0x2F3D); + SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ); + SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG0 | WINOUT_WIN01_BG2 | WINOUT_WIN01_BG3 | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR | WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_CLR); + + // Set marker subsprites on full sprite spriteTemplate = gDummySpriteTemplate; spriteTemplate.tileTag = tilesTag; - data->spr_id = CreateSprite(&spriteTemplate, 104, y + 32, 0); - SetSubspriteTables(&gSprites[data->spr_id], &data->subsprites); - gSprites[data->spr_id].oam.objMode = ST_OAM_OBJ_WINDOW; - gSprites[data->spr_id].oam.paletteNum = palIdx; - gSprites[data->spr_id].subspriteTableNum = 0; - gSprites[data->spr_id].invisible = TRUE; + data->spriteId = CreateSprite(&spriteTemplate, 104, y + 32, 0); + SetSubspriteTables(&gSprites[data->spriteId], &data->subsprites); + gSprites[data->spriteId].oam.objMode = ST_OAM_OBJ_WINDOW; + gSprites[data->spriteId].oam.paletteNum = palIdx; + gSprites[data->spriteId].subspriteTableNum = 0; + gSprites[data->spriteId].invisible = TRUE; + + // Show markers HideBg(1); SetBgAttribute(1, BG_ATTR_CHARBASEINDEX, 0); FillBgTilemapBufferRect_Palette0(1, 0x00F, 0, 0, 30, 20); @@ -201,17 +240,17 @@ u8 Ctor_PokedexAreaMarkers(u16 species, u16 tilesTag, u8 palIdx, u8 y) return taskId; } -void Dtor_PokedexAreaMarkers(u8 taskId) +void DestroyPokedexAreaMarkers(u8 taskId) { struct PAM_TaskData * data = (void *)gTasks[taskId].data; FreeSpriteTilesByTag(data->tilesTag); - DestroySprite(&gSprites[data->spr_id]); + DestroySprite(&gSprites[data->spriteId]); Free(data->buffer); SetGpuReg(REG_OFFSET_BLDCNT, 0); SetGpuReg(REG_OFFSET_BLDALPHA, 0); SetGpuReg(REG_OFFSET_BLDY, 0); - SetGpuReg(REG_OFFSET_WININ, 0x1F1F); - SetGpuReg(REG_OFFSET_WINOUT, 0x1F1F); + SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ); + SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ); ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_OBJWIN_ON); HideBg(1); SetBgAttribute(1, BG_ATTR_CHARBASEINDEX, 2); @@ -221,14 +260,14 @@ void Dtor_PokedexAreaMarkers(u8 taskId) DestroyTask(taskId); } -void SetAreaSubsprite(s32 i, s32 whichArea, struct Subsprite * subsprites) +void GetAreaMarkerSubsprite(s32 i, s32 dexArea, struct Subsprite * subsprites) { - subsprites[i] = *sSubsprites[sSubspriteLookupTable[whichArea][0]]; - subsprites[i].x = sSubspriteLookupTable[whichArea][1]; - subsprites[i].y = sSubspriteLookupTable[whichArea][2]; + subsprites[i] = *sSubsprites[sAreaMarkers[dexArea][0]]; + subsprites[i].x = sAreaMarkers[dexArea][1]; + subsprites[i].y = sAreaMarkers[dexArea][2]; } -u8 PokedexAreaMarkers_Any(u8 taskId) +u8 GetNumPokedexAreaMarkers(u8 taskId) { struct PAM_TaskData * data = (void *)gTasks[taskId].data; return data->subsprites.subspriteCount; diff --git a/src/pokedex_screen.c b/src/pokedex_screen.c index 5da6f5b3d..691b3447f 100644 --- a/src/pokedex_screen.c +++ b/src/pokedex_screen.c @@ -21,6 +21,8 @@ #include "pokedex_area_markers.h" #include "field_specials.h" +#define TAG_AREA_MARKERS 2001 + enum TextMode { TEXT_LEFT, TEXT_CENTER, @@ -31,7 +33,8 @@ struct PokedexScreenData { u8 taskId; u8 state; - u8 data[4]; + u8 data[2]; + u8 areaMarkersTaskId; u32 unlockedCategories; u32 modeSelectInput; u16 modeSelectItemsAbove; @@ -3123,9 +3126,10 @@ u8 DexScreen_DrawMonAreaPage(void) } // Create the area markers - sPokedexScreenData->data[2] = Ctor_PokedexAreaMarkers(species, 2001, 3, kantoMapVoff * 8); - if (!(PokedexAreaMarkers_Any(sPokedexScreenData->data[2]))) + sPokedexScreenData->areaMarkersTaskId = CreatePokedexAreaMarkers(species, TAG_AREA_MARKERS, 3, kantoMapVoff * 8); + if (GetNumPokedexAreaMarkers(sPokedexScreenData->areaMarkersTaskId) == 0) { + // No markers, display "Area Unknown" BlitBitmapRectToWindow(sPokedexScreenData->windowIds[0], (void *)sBlitTiles_WideEllipse, 0, 0, 88, 16, 4, 28, 88, 16); { s32 strWidth = GetStringWidth(FONT_0, gText_AreaUnknown, 0); @@ -3149,7 +3153,7 @@ u8 DexScreen_DestroyAreaScreenResources(void) { int i; - Dtor_PokedexAreaMarkers(sPokedexScreenData->data[2]); + DestroyPokedexAreaMarkers(sPokedexScreenData->areaMarkersTaskId); for (i = 0; i < 13; i++) DexScreen_RemoveWindow(&sPokedexScreenData->windowIds[i]); diff --git a/src/wild_encounter.c b/src/wild_encounter.c index 288a6b235..a49b48910 100644 --- a/src/wild_encounter.c +++ b/src/wild_encounter.c @@ -186,7 +186,7 @@ static u16 GetCurrentMapWildMonHeaderId(void) gSaveBlock1Ptr->location.mapNum == MAP_NUM(SIX_ISLAND_ALTERING_CAVE)) { u16 alteringCaveId = VarGet(VAR_ALTERING_CAVE_WILD_SET); - if (alteringCaveId > 8) + if (alteringCaveId >= NUM_ALTERING_CAVE_TABLES) alteringCaveId = 0; i += alteringCaveId; diff --git a/src/wild_pokemon_area.c b/src/wild_pokemon_area.c index c93ae36b6..1fc25e12c 100644 --- a/src/wild_pokemon_area.c +++ b/src/wild_pokemon_area.c @@ -4,16 +4,11 @@ #include "wild_encounter.h" #include "roamer.h" #include "overworld.h" +#include "pokedex.h" #include "pokedex_area_markers.h" #include "constants/region_map_sections.h" #include "constants/maps.h" -struct SeviiDexArea -{ - const u16 (*lut)[2]; - s32 count; -}; - struct RoamerPair { u16 roamer; @@ -21,137 +16,141 @@ struct RoamerPair }; static s32 GetRoamerIndex(u16 species); -static s32 CountRoamerNests(u16 species, struct Subsprite * subsprites); -static bool32 PokemonInAnyEncounterTableInMap(const struct WildPokemonHeader * data, s32 species); -static bool32 PokemonInEncounterTable(const struct WildPokemonInfo * pokemon, s32 species, s32 count); +static s32 GetRoamerPokedexAreaMarkers(u16 species, struct Subsprite * subsprites); +static bool32 IsSpeciesOnMap(const struct WildPokemonHeader * data, s32 species); +static bool32 IsSpeciesInEncounterTable(const struct WildPokemonInfo * pokemon, s32 species, s32 count); static u16 GetMapSecIdFromWildMonHeader(const struct WildPokemonHeader * header); -static bool32 TryGetMapSecPokedexAreaEntry(u16 mapSecId, const u16 (*lut)[2], s32 count, s32 * lutIdx_p, u16 * tableIdx_p); +static bool32 FindDexAreaByMapSec(u16 mapSecId, const u16 (*lut)[2], s32 count, s32 * lutIdx_p, u16 * tableIdx_p); static const u16 sDexAreas_Kanto[][2] = { - { MAPSEC_PALLET_TOWN, 1 }, - { MAPSEC_VIRIDIAN_CITY, 2 }, - { MAPSEC_PEWTER_CITY, 3 }, - { MAPSEC_CERULEAN_CITY, 4 }, - { MAPSEC_LAVENDER_TOWN, 5 }, - { MAPSEC_VERMILION_CITY, 6 }, - { MAPSEC_CELADON_CITY, 7 }, - { MAPSEC_FUCHSIA_CITY, 8 }, - { MAPSEC_CINNABAR_ISLAND, 9 }, - { MAPSEC_INDIGO_PLATEAU, 10 }, - { MAPSEC_SAFFRON_CITY, 11 }, - { MAPSEC_ROUTE_4_POKECENTER, 15 }, - { MAPSEC_ROUTE_10_POKECENTER, 21 }, - { MAPSEC_ROUTE_1, 12 }, - { MAPSEC_ROUTE_2, 13 }, - { MAPSEC_ROUTE_3, 14 }, - { MAPSEC_ROUTE_4, 15 }, - { MAPSEC_ROUTE_5, 16 }, - { MAPSEC_ROUTE_6, 17 }, - { MAPSEC_ROUTE_7, 18 }, - { MAPSEC_ROUTE_8, 19 }, - { MAPSEC_ROUTE_9, 20 }, - { MAPSEC_ROUTE_10, 21 }, - { MAPSEC_ROUTE_11, 22 }, - { MAPSEC_ROUTE_12, 23 }, - { MAPSEC_ROUTE_13, 24 }, - { MAPSEC_ROUTE_14, 25 }, - { MAPSEC_ROUTE_15, 26 }, - { MAPSEC_ROUTE_16, 27 }, - { MAPSEC_ROUTE_17, 28 }, - { MAPSEC_ROUTE_18, 29 }, - { MAPSEC_ROUTE_19, 30 }, - { MAPSEC_ROUTE_20, 31 }, - { MAPSEC_ROUTE_21, 32 }, - { MAPSEC_ROUTE_22, 33 }, - { MAPSEC_ROUTE_23, 34 }, - { MAPSEC_ROUTE_24, 35 }, - { MAPSEC_ROUTE_25, 36 }, - { MAPSEC_VIRIDIAN_FOREST, 37 }, - { MAPSEC_MT_MOON, 39 }, - { MAPSEC_S_S_ANNE, 6 }, - { MAPSEC_UNDERGROUND_PATH, 11 }, - { MAPSEC_UNDERGROUND_PATH_2, 11 }, - { MAPSEC_DIGLETTS_CAVE, 38 }, - { MAPSEC_KANTO_VICTORY_ROAD, 47 }, - { MAPSEC_ROCKET_HIDEOUT, 7 }, - { MAPSEC_SILPH_CO, 11 }, - { MAPSEC_POKEMON_MANSION, 46 }, - { MAPSEC_KANTO_SAFARI_ZONE, 44 }, - { MAPSEC_POKEMON_LEAGUE, 47 }, - { MAPSEC_ROCK_TUNNEL, 41 }, - { MAPSEC_SEAFOAM_ISLANDS, 45 }, - { MAPSEC_POKEMON_TOWER, 43 }, - { MAPSEC_CERULEAN_CAVE, 40 }, - { MAPSEC_POWER_PLANT, 42 } + { MAPSEC_PALLET_TOWN, DEX_AREA_PALLET_TOWN }, + { MAPSEC_VIRIDIAN_CITY, DEX_AREA_VIRIDIAN_CITY }, + { MAPSEC_PEWTER_CITY, DEX_AREA_PEWTER_CITY }, + { MAPSEC_CERULEAN_CITY, DEX_AREA_CERULEAN_CITY }, + { MAPSEC_LAVENDER_TOWN, DEX_AREA_LAVENDER_TOWN }, + { MAPSEC_VERMILION_CITY, DEX_AREA_VERMILION_CITY }, + { MAPSEC_CELADON_CITY, DEX_AREA_CELADON_CITY }, + { MAPSEC_FUCHSIA_CITY, DEX_AREA_FUCHSIA_CITY }, + { MAPSEC_CINNABAR_ISLAND, DEX_AREA_CINNABAR_ISLAND }, + { MAPSEC_INDIGO_PLATEAU, DEX_AREA_INDIGO_PLATEAU }, + { MAPSEC_SAFFRON_CITY, DEX_AREA_SAFFRON_CITY }, + { MAPSEC_ROUTE_4_POKECENTER, DEX_AREA_ROUTE_4 }, + { MAPSEC_ROUTE_10_POKECENTER, DEX_AREA_ROUTE_10 }, + { MAPSEC_ROUTE_1, DEX_AREA_ROUTE_1 }, + { MAPSEC_ROUTE_2, DEX_AREA_ROUTE_2 }, + { MAPSEC_ROUTE_3, DEX_AREA_ROUTE_3 }, + { MAPSEC_ROUTE_4, DEX_AREA_ROUTE_4 }, + { MAPSEC_ROUTE_5, DEX_AREA_ROUTE_5 }, + { MAPSEC_ROUTE_6, DEX_AREA_ROUTE_6 }, + { MAPSEC_ROUTE_7, DEX_AREA_ROUTE_7 }, + { MAPSEC_ROUTE_8, DEX_AREA_ROUTE_8 }, + { MAPSEC_ROUTE_9, DEX_AREA_ROUTE_9 }, + { MAPSEC_ROUTE_10, DEX_AREA_ROUTE_10 }, + { MAPSEC_ROUTE_11, DEX_AREA_ROUTE_11 }, + { MAPSEC_ROUTE_12, DEX_AREA_ROUTE_12 }, + { MAPSEC_ROUTE_13, DEX_AREA_ROUTE_13 }, + { MAPSEC_ROUTE_14, DEX_AREA_ROUTE_14 }, + { MAPSEC_ROUTE_15, DEX_AREA_ROUTE_15 }, + { MAPSEC_ROUTE_16, DEX_AREA_ROUTE_16 }, + { MAPSEC_ROUTE_17, DEX_AREA_ROUTE_17 }, + { MAPSEC_ROUTE_18, DEX_AREA_ROUTE_18 }, + { MAPSEC_ROUTE_19, DEX_AREA_ROUTE_19 }, + { MAPSEC_ROUTE_20, DEX_AREA_ROUTE_20 }, + { MAPSEC_ROUTE_21, DEX_AREA_ROUTE_21 }, + { MAPSEC_ROUTE_22, DEX_AREA_ROUTE_22 }, + { MAPSEC_ROUTE_23, DEX_AREA_ROUTE_23 }, + { MAPSEC_ROUTE_24, DEX_AREA_ROUTE_24 }, + { MAPSEC_ROUTE_25, DEX_AREA_ROUTE_25 }, + { MAPSEC_VIRIDIAN_FOREST, DEX_AREA_VIRIDIAN_FOREST }, + { MAPSEC_MT_MOON, DEX_AREA_MT_MOON }, + { MAPSEC_S_S_ANNE, DEX_AREA_VERMILION_CITY }, + { MAPSEC_UNDERGROUND_PATH, DEX_AREA_SAFFRON_CITY }, + { MAPSEC_UNDERGROUND_PATH_2, DEX_AREA_SAFFRON_CITY }, + { MAPSEC_DIGLETTS_CAVE, DEX_AREA_DIGLETTS_CAVE }, + { MAPSEC_KANTO_VICTORY_ROAD, DEX_AREA_VICTORY_ROAD }, + { MAPSEC_ROCKET_HIDEOUT, DEX_AREA_CELADON_CITY }, + { MAPSEC_SILPH_CO, DEX_AREA_SAFFRON_CITY }, + { MAPSEC_POKEMON_MANSION, DEX_AREA_POKEMON_MANSION }, + { MAPSEC_KANTO_SAFARI_ZONE, DEX_AREA_SAFARI_ZONE }, + { MAPSEC_POKEMON_LEAGUE, DEX_AREA_VICTORY_ROAD }, + { MAPSEC_ROCK_TUNNEL, DEX_AREA_ROCK_TUNNEL }, + { MAPSEC_SEAFOAM_ISLANDS, DEX_AREA_SEAFOAM_ISLANDS }, + { MAPSEC_POKEMON_TOWER, DEX_AREA_POKEMON_TOWER }, + { MAPSEC_CERULEAN_CAVE, DEX_AREA_CERULEAN_CAVE }, + { MAPSEC_POWER_PLANT, DEX_AREA_POWER_PLANT } }; static const u16 sDexAreas_Sevii1[][2] = { - { MAPSEC_KINDLE_ROAD, 55 }, - { MAPSEC_TREASURE_BEACH, 56 }, - { MAPSEC_ONE_ISLAND, 48 }, - { MAPSEC_MT_EMBER, 72 } + { MAPSEC_KINDLE_ROAD, DEX_AREA_KINDLE_ROAD }, + { MAPSEC_TREASURE_BEACH, DEX_AREA_TREASURE_BEACH }, + { MAPSEC_ONE_ISLAND, DEX_AREA_ONE_ISLAND }, + { MAPSEC_MT_EMBER, DEX_AREA_MT_EMBER } }; static const u16 sDexAreas_Sevii2[][2] = { - { MAPSEC_CAPE_BRINK, 57 }, - { MAPSEC_TWO_ISLAND, 49 } + { MAPSEC_CAPE_BRINK, DEX_AREA_CAPE_BRINK }, + { MAPSEC_TWO_ISLAND, DEX_AREA_TWO_ISLAND } }; static const u16 sDexAreas_Sevii3[][2] = { - { MAPSEC_BOND_BRIDGE, 58 }, - { MAPSEC_THREE_ISLE_PORT, 59 }, - { MAPSEC_THREE_ISLAND, 50 }, - { MAPSEC_BERRY_FOREST, 73 }, - { MAPSEC_THREE_ISLE_PATH, 59 } + { MAPSEC_BOND_BRIDGE, DEX_AREA_BOND_BRIDGE }, + { MAPSEC_THREE_ISLE_PORT, DEX_AREA_THREE_ISLE_PATH }, + { MAPSEC_THREE_ISLAND, DEX_AREA_THREE_ISLAND }, + { MAPSEC_BERRY_FOREST, DEX_AREA_BERRY_FOREST }, + { MAPSEC_THREE_ISLE_PATH, DEX_AREA_THREE_ISLE_PATH } }; static const u16 sDexAreas_Sevii4[][2] = { - { MAPSEC_FOUR_ISLAND, 51 }, - { MAPSEC_ICEFALL_CAVE, 74 } + { MAPSEC_FOUR_ISLAND, DEX_AREA_FOUR_ISLAND }, + { MAPSEC_ICEFALL_CAVE, DEX_AREA_ICEFALL_CAVE } }; static const u16 sDexAreas_Sevii5[][2] = { - { MAPSEC_RESORT_GORGEOUS, 60 }, - { MAPSEC_WATER_LABYRINTH, 61 }, - { MAPSEC_FIVE_ISLE_MEADOW, 62 }, - { MAPSEC_MEMORIAL_PILLAR, 63 }, - { MAPSEC_FIVE_ISLAND, 52 }, - { MAPSEC_ROCKET_WAREHOUSE, 62 }, - { MAPSEC_LOST_CAVE, 75 } + { MAPSEC_RESORT_GORGEOUS, DEX_AREA_RESORT_GORGEOUS }, + { MAPSEC_WATER_LABYRINTH, DEX_AREA_WATER_LABYRINTH }, + { MAPSEC_FIVE_ISLE_MEADOW, DEX_AREA_FIVE_ISLE_MEADOW }, + { MAPSEC_MEMORIAL_PILLAR, DEX_AREA_MEMORIAL_PILLAR }, + { MAPSEC_FIVE_ISLAND, DEX_AREA_FIVE_ISLAND }, + { MAPSEC_ROCKET_WAREHOUSE, DEX_AREA_FIVE_ISLE_MEADOW }, + { MAPSEC_LOST_CAVE, DEX_AREA_LOST_CAVE } }; static const u16 sDexAreas_Sevii6[][2] = { - { MAPSEC_OUTCAST_ISLAND, 64 }, - { MAPSEC_GREEN_PATH, 65 }, - { MAPSEC_WATER_PATH, 66 }, - { MAPSEC_RUIN_VALLEY, 67 }, - { MAPSEC_DOTTED_HOLE, 78 }, - { MAPSEC_PATTERN_BUSH, 77 }, - { MAPSEC_ALTERING_CAVE, 76 } + { MAPSEC_OUTCAST_ISLAND, DEX_AREA_OUTCAST_ISLAND }, + { MAPSEC_GREEN_PATH, DEX_AREA_GREEN_PATH }, + { MAPSEC_WATER_PATH, DEX_AREA_WATER_PATH }, + { MAPSEC_RUIN_VALLEY, DEX_AREA_RUIN_VALLEY }, + { MAPSEC_DOTTED_HOLE, DEX_AREA_DOTTED_HOLE }, + { MAPSEC_PATTERN_BUSH, DEX_AREA_PATTERN_BUSH }, + { MAPSEC_ALTERING_CAVE, DEX_AREA_ALTERING_CAVE } }; static const u16 sDexAreas_Sevii7[][2] = { - { MAPSEC_TRAINER_TOWER, 68 }, - { MAPSEC_CANYON_ENTRANCE, 69 }, - { MAPSEC_SEVAULT_CANYON, 70 }, - { MAPSEC_TANOBY_RUINS, 71 }, - { MAPSEC_MONEAN_CHAMBER, 79 }, - { MAPSEC_LIPTOO_CHAMBER, 79 }, - { MAPSEC_WEEPTH_CHAMBER, 79 }, - { MAPSEC_DILFORD_CHAMBER, 79 }, - { MAPSEC_SCUFIB_CHAMBER, 79 }, - { MAPSEC_RIXY_CHAMBER, 79 }, - { MAPSEC_VIAPOIS_CHAMBER, 79 } + { MAPSEC_TRAINER_TOWER, DEX_AREA_TRAINER_TOWER }, + { MAPSEC_CANYON_ENTRANCE, DEX_AREA_CANYON_ENTRANCE }, + { MAPSEC_SEVAULT_CANYON, DEX_AREA_SEVAULT_CANYON }, + { MAPSEC_TANOBY_RUINS, DEX_AREA_TANOBY_RUINS }, + { MAPSEC_MONEAN_CHAMBER, DEX_AREA_TANOBY_CHAMBER }, + { MAPSEC_LIPTOO_CHAMBER, DEX_AREA_TANOBY_CHAMBER }, + { MAPSEC_WEEPTH_CHAMBER, DEX_AREA_TANOBY_CHAMBER }, + { MAPSEC_DILFORD_CHAMBER, DEX_AREA_TANOBY_CHAMBER }, + { MAPSEC_SCUFIB_CHAMBER, DEX_AREA_TANOBY_CHAMBER }, + { MAPSEC_RIXY_CHAMBER, DEX_AREA_TANOBY_CHAMBER }, + { MAPSEC_VIAPOIS_CHAMBER, DEX_AREA_TANOBY_CHAMBER } }; -static const struct SeviiDexArea sSeviiDexAreas[] = { - { sDexAreas_Sevii1, 4 }, - { sDexAreas_Sevii2, 2 }, - { sDexAreas_Sevii3, 5 }, - { sDexAreas_Sevii4, 2 }, - { sDexAreas_Sevii5, 7 }, - { sDexAreas_Sevii6, 7 }, - { sDexAreas_Sevii7, 11 } +static const struct +{ + const u16 (*table)[2]; + s32 count; +} sSeviiDexAreas[] = { + { sDexAreas_Sevii1, ARRAY_COUNT(sDexAreas_Sevii1) }, + { sDexAreas_Sevii2, ARRAY_COUNT(sDexAreas_Sevii2) }, + { sDexAreas_Sevii3, ARRAY_COUNT(sDexAreas_Sevii3) }, + { sDexAreas_Sevii4, ARRAY_COUNT(sDexAreas_Sevii4) }, + { sDexAreas_Sevii5, ARRAY_COUNT(sDexAreas_Sevii5) }, + { sDexAreas_Sevii6, ARRAY_COUNT(sDexAreas_Sevii6) }, + { sDexAreas_Sevii7, ARRAY_COUNT(sDexAreas_Sevii7) } }; static const struct RoamerPair sRoamerPairs[] = { @@ -160,27 +159,27 @@ static const struct RoamerPair sRoamerPairs[] = { { SPECIES_RAIKOU, SPECIES_SQUIRTLE } }; -s32 BuildPokedexAreaSubspriteBuffer(u16 species, struct Subsprite * subsprites) +// Scans for the given species and populates 'subsprites' with the area markers. +// Returns the number of areas where the species was found. +s32 GetSpeciesPokedexAreaMarkers(u16 species, struct Subsprite * subsprites) { s32 areaCount; s32 j; s32 mapSecId; - u16 dexAreaSubspriteIdx; - s32 dexAreaEntryLUTidx; + u16 dexArea; + s32 tableIndex; s32 seviiAreas; s32 alteringCaveCount; s32 alteringCaveNum; s32 i; - if (GetRoamerIndex(species) >= SPECIES_NONE) - { - return CountRoamerNests(species, subsprites); - } + if (GetRoamerIndex(species) >= 0) + return GetRoamerPokedexAreaMarkers(species, subsprites); seviiAreas = GetUnlockedSeviiAreas(); alteringCaveCount = 0; alteringCaveNum = VarGet(VAR_ALTERING_CAVE_WILD_SET); - if (alteringCaveNum > 8) + if (alteringCaveNum >= NUM_ALTERING_CAVE_TABLES) alteringCaveNum = 0; for (i = 0, areaCount = 0; gWildMonHeaders[i].mapGroup != MAP_GROUP(UNDEFINED); i++) { @@ -191,27 +190,27 @@ s32 BuildPokedexAreaSubspriteBuffer(u16 species, struct Subsprite * subsprites) if (alteringCaveNum != alteringCaveCount - 1) continue; } - if (PokemonInAnyEncounterTableInMap(&gWildMonHeaders[i], species)) + if (IsSpeciesOnMap(&gWildMonHeaders[i], species)) { - dexAreaEntryLUTidx = 0; - while (TryGetMapSecPokedexAreaEntry(mapSecId, sDexAreas_Kanto, 55, &dexAreaEntryLUTidx, &dexAreaSubspriteIdx)) + // Search for all dex areas associated with this MAPSEC. + // In the vanilla game each MAPSEC only has at most one DEX_AREA. + tableIndex = 0; + while (FindDexAreaByMapSec(mapSecId, sDexAreas_Kanto, ARRAY_COUNT(sDexAreas_Kanto), &tableIndex, &dexArea)) { - if (dexAreaSubspriteIdx != 0) - { - SetAreaSubsprite(areaCount++, dexAreaSubspriteIdx, subsprites); - } + if (dexArea != DEX_AREA_NONE) + GetAreaMarkerSubsprite(areaCount++, dexArea, subsprites); } - for (j = 0; j < NELEMS(sSeviiDexAreas); j++) + + for (j = 0; j < ARRAY_COUNT(sSeviiDexAreas); j++) { if ((seviiAreas >> j) & 1) { - dexAreaEntryLUTidx = 0; - while (TryGetMapSecPokedexAreaEntry(mapSecId, sSeviiDexAreas[j].lut, sSeviiDexAreas[j].count, &dexAreaEntryLUTidx, &dexAreaSubspriteIdx)) + // Search for all dex areas associated with this MAPSEC in this unlocked Sevii Island + tableIndex = 0; + while (FindDexAreaByMapSec(mapSecId, sSeviiDexAreas[j].table, sSeviiDexAreas[j].count, &tableIndex, &dexArea)) { - if (dexAreaSubspriteIdx != 0) - { - SetAreaSubsprite(areaCount++, dexAreaSubspriteIdx, subsprites); - } + if (dexArea != DEX_AREA_NONE) + GetAreaMarkerSubsprite(areaCount++, dexArea, subsprites); } } } @@ -224,7 +223,7 @@ s32 BuildPokedexAreaSubspriteBuffer(u16 species, struct Subsprite * subsprites) static s32 GetRoamerIndex(u16 species) { s32 i; - for (i = 0; i < NELEMS(sRoamerPairs); i++) + for (i = 0; i < ARRAY_COUNT(sRoamerPairs); i++) { if (sRoamerPairs[i].roamer == species) return i; @@ -233,46 +232,54 @@ static s32 GetRoamerIndex(u16 species) return -1; } -static s32 CountRoamerNests(u16 species, struct Subsprite * subsprites) +static s32 GetRoamerPokedexAreaMarkers(u16 species, struct Subsprite * subsprites) { - u16 roamerLocation; + u16 mapSecId; s32 roamerIdx; - u16 dexAreaSubspriteIdx; - s32 dexAreaEntryLUTidx; + u16 dexArea; + s32 tableIndex; + // Make sure that this is a roamer species, and that it corresponds to the player's starter. roamerIdx = GetRoamerIndex(species); if (roamerIdx < 0) return 0; if (sRoamerPairs[roamerIdx].starter != GetStarterSpecies()) return 0; - roamerLocation = GetRoamerLocationMapSectionId(); - dexAreaEntryLUTidx = 0; - if (TryGetMapSecPokedexAreaEntry(roamerLocation, sDexAreas_Kanto, 55, &dexAreaEntryLUTidx, &dexAreaSubspriteIdx)) + + mapSecId = GetRoamerLocationMapSectionId(); + tableIndex = 0; + if (FindDexAreaByMapSec(mapSecId, sDexAreas_Kanto, ARRAY_COUNT(sDexAreas_Kanto), &tableIndex, &dexArea)) { - if (dexAreaSubspriteIdx != 0) + if (dexArea != DEX_AREA_NONE) { - SetAreaSubsprite(0, dexAreaSubspriteIdx, subsprites); + GetAreaMarkerSubsprite(0, dexArea, subsprites); return 1; } } return 0; } -static bool32 PokemonInAnyEncounterTableInMap(const struct WildPokemonHeader * data, s32 species) +static bool32 IsSpeciesOnMap(const struct WildPokemonHeader * data, s32 species) { - if (PokemonInEncounterTable(data->landMonsInfo, species, 12)) + if (IsSpeciesInEncounterTable(data->landMonsInfo, species, LAND_WILD_COUNT)) return TRUE; - if (PokemonInEncounterTable(data->waterMonsInfo, species, 5)) + if (IsSpeciesInEncounterTable(data->waterMonsInfo, species, WATER_WILD_COUNT)) return TRUE; - if (PokemonInEncounterTable(data->fishingMonsInfo, species, 12)) // 10 +// When searching the fishing encounters, this incorrectly uses the size of the land encounters. +// As a result it's reading out of bounds of the fishing encounters tables. +#ifdef BUGFIX + if (IsSpeciesInEncounterTable(data->fishingMonsInfo, species, FISH_WILD_COUNT)) +#else + if (IsSpeciesInEncounterTable(data->fishingMonsInfo, species, LAND_WILD_COUNT)) +#endif return TRUE; - if (PokemonInEncounterTable(data->rockSmashMonsInfo, species, 5)) + if (IsSpeciesInEncounterTable(data->rockSmashMonsInfo, species, ROCK_WILD_COUNT)) return TRUE; return FALSE; } -static bool32 PokemonInEncounterTable(const struct WildPokemonInfo * info, s32 species, s32 count) +static bool32 IsSpeciesInEncounterTable(const struct WildPokemonInfo * info, s32 species, s32 count) { s32 i; if (info != NULL) @@ -291,15 +298,18 @@ static u16 GetMapSecIdFromWildMonHeader(const struct WildPokemonHeader * header) return Overworld_GetMapHeaderByGroupAndId(header->mapGroup, header->mapNum)->regionMapSectionId; } -static bool32 TryGetMapSecPokedexAreaEntry(u16 mapSecId, const u16 (*lut)[2], s32 count, s32 * lutIdx_p, u16 * tableIdx_p) +// Search a MAPSEC -> DEX_AREA table for the given mapsec. +// Assigns the DEX_AREA (if found) to 'dexArea', and the first unread table index to 'index'. +// Returns TRUE if DEX_AREA was found, FALSE otherwise. +static bool32 FindDexAreaByMapSec(u16 mapSecId, const u16 (*table)[2], s32 count, s32 * index, u16 * dexArea) { s32 i; - for (i = *lutIdx_p; i < count; i++) + for (i = *index; i < count; i++) { - if (lut[i][0] == mapSecId) + if (table[i][0] == mapSecId) { - *tableIdx_p = lut[i][1]; - *lutIdx_p = i + 1; + *dexArea = table[i][1]; + *index = i + 1; return TRUE; } } From b79736aec895730facb18c9779b968bb2f19ca96 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Mon, 21 Nov 2022 13:44:14 -0500 Subject: [PATCH 5/8] Fix Route 25 marker coords --- src/pokedex_area_markers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pokedex_area_markers.c b/src/pokedex_area_markers.c index 6ca1090c9..b98943b06 100644 --- a/src/pokedex_area_markers.c +++ b/src/pokedex_area_markers.c @@ -136,7 +136,7 @@ static const s8 sAreaMarkers[][4] = { [DEX_AREA_ROUTE_22] = { MARKER_SMALL_H, 40, 28 }, [DEX_AREA_ROUTE_23] = { MARKER_MED_V, 38, 4 }, [DEX_AREA_ROUTE_24] = { MARKER_CIRCULAR, 92, 4 }, - [DEX_AREA_ROUTE_25] = { MARKER_MED_H, 90, 254 }, + [DEX_AREA_ROUTE_25] = { MARKER_MED_H, 90, -2 }, [DEX_AREA_VIRIDIAN_FOREST] = { MARKER_CIRCULAR, 51, 20 }, [DEX_AREA_DIGLETTS_CAVE] = { MARKER_SMALL_H, 61, 18 }, [DEX_AREA_MT_MOON] = { MARKER_CIRCULAR, 72, 8 }, From af6837c093c7fbd9eeda74e64fa1e6b24e4a8c2d Mon Sep 17 00:00:00 2001 From: GriffinR Date: Sat, 19 Nov 2022 21:49:50 -0500 Subject: [PATCH 6/8] Sync mystery gift server, client, scripts --- include/link_rfu.h | 2 +- include/mystery_gift.h | 4 +- include/mystery_gift_client.h | 91 ++++++++ include/mystery_gift_link.h | 50 +++++ include/mystery_gift_server.h | 170 +++++++------- src/mystery_gift.c | 4 +- src/mystery_gift_client.c | 359 +++++++++++++++--------------- src/mystery_gift_menu.c | 57 ++--- src/mystery_gift_scripts.c | 280 +++++++++++------------ src/mystery_gift_server.c | 406 +++++++++++++++++----------------- src/union_room_message.c | 25 ++- 11 files changed, 800 insertions(+), 648 deletions(-) create mode 100644 include/mystery_gift_client.h create mode 100644 include/mystery_gift_link.h diff --git a/include/link_rfu.h b/include/link_rfu.h index 65d1cf6dd..9610a9682 100644 --- a/include/link_rfu.h +++ b/include/link_rfu.h @@ -325,6 +325,6 @@ void SetUnionRoomChatPlayerData(u32 numPlayers); void ClearRecvCommands(void); #include "mystery_gift_server.h" -extern const struct mevent_server_cmd gServerScript_ClientCanceledCard[]; +extern const struct MysteryGiftServerCmd gServerScript_ClientCanceledCard[]; #endif //GUARD_LINK_RFU_H diff --git a/include/mystery_gift.h b/include/mystery_gift.h index a8ec84f86..a59b60ec8 100644 --- a/include/mystery_gift.h +++ b/include/mystery_gift.h @@ -79,8 +79,8 @@ void DisableWonderCardSending(struct WonderCard * card); bool32 MysteryGift_TrySaveStamp(const u16 * stamp); void MysteryGift_LoadLinkGameData(struct MysteryGiftLinkGameData * data); bool32 MysteryGift_ValidateLinkGameData(const struct MysteryGiftLinkGameData * data); -u32 MysteryGift_CompareCardFlags(const u16 * flagId, const struct MysteryGiftLinkGameData * data, void *unused); -u32 MysteryGift_CheckStamps(const u16 * stamp, const struct MysteryGiftLinkGameData * data, void *unused); +u32 MysteryGift_CompareCardFlags(const u16 * flagId, const struct MysteryGiftLinkGameData * data, const void *unused); +u32 MysteryGift_CheckStamps(const u16 * stamp, 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); bool32 WonderCard_Init(struct WonderCard * card, struct WonderCardMetadata * metadata); diff --git a/include/mystery_gift_client.h b/include/mystery_gift_client.h new file mode 100644 index 000000000..c7817d161 --- /dev/null +++ b/include/mystery_gift_client.h @@ -0,0 +1,91 @@ +#ifndef GUARD_MYSTERY_GIFT_CLIENT_H +#define GUARD_MYSTERY_GIFT_CLIENT_H + +#include "mystery_gift_link.h" + +// Return values for client functions called by MysteryGiftClient_Run +enum { + CLI_RET_INIT, + CLI_RET_ACTIVE, + CLI_RET_YES_NO, + CLI_RET_PRINT_MSG, + CLI_RET_ASK_TOSS, + CLI_RET_COPY_MSG, + CLI_RET_END, +}; + +// IDs for client script instructions +enum { + CLI_NONE, + CLI_RETURN, + CLI_RECV, + CLI_SEND_LOADED, + CLI_COPY_RECV, + CLI_YES_NO, + CLI_COPY_RECV_IF_N, + CLI_COPY_RECV_IF, + CLI_LOAD_GAME_DATA, + CLI_SAVE_NEWS, + CLI_SAVE_CARD, + CLI_PRINT_MSG, + CLI_COPY_MSG, + CLI_ASK_TOSS, + CLI_LOAD_TOSS_RESPONSE, + CLI_RUN_MEVENT_SCRIPT, + CLI_SAVE_STAMP, + CLI_SAVE_RAM_SCRIPT, + CLI_RECV_EREADER_TRAINER, + CLI_SEND_STAT, + 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; + u32 parameter; +}; + +struct MysteryGiftClient +{ + u32 unused; + u32 param; + u32 funcId; + u32 funcState; + u32 cmdidx; + void *sendBuffer; + void *recvBuffer; + struct MysteryGiftClientCmd * script; + void *msg; + struct MysteryGiftLink link; +}; + +void MysteryGiftClient_Create(void); +u32 MysteryGiftClient_Run(u16 * endVal); +void MysteryGiftClient_AdvanceState(void); +void * MysteryGiftClient_GetMsg(void); +void MysteryGiftClient_SetParam(u32 value); + +#endif //GUARD_MYSTERY_GIFT_CLIENT_H diff --git a/include/mystery_gift_link.h b/include/mystery_gift_link.h new file mode 100644 index 000000000..8f36d9108 --- /dev/null +++ b/include/mystery_gift_link.h @@ -0,0 +1,50 @@ +#ifndef GUARD_MYSTERY_GIFT_LINK_H +#define GUARD_MYSTERY_GIFT_LINK_H + +#define MG_LINK_BUFFER_SIZE 0x400 +#define ME_SEND_BUF_SIZE MG_LINK_BUFFER_SIZE + +// 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 state; + u8 sendPlayerId; + u8 recvPlayerId; + u16 recvIdent; + u16 recvCounter; + u16 recvCRC; + u16 recvSize; + u16 sendIdent; + u16 sendCounter; + u16 sendCRC; + u16 sendSize; + void * recvBuffer; + const void * sendBuffer; + u32 (*recvFunc)(struct MysteryGiftLink *); + u32 (*sendFunc)(struct MysteryGiftLink *); +}; + +void MysteryGiftLink_Init(struct MysteryGiftLink * link, u32 sendPlayerId, u32 recvPlayerId); +void MysteryGiftLink_InitSend(struct MysteryGiftLink * link, u32 ident, const void * src, u32 size); +bool32 MysteryGiftLink_Recv(struct MysteryGiftLink * link); +bool32 MysteryGiftLink_Send(struct MysteryGiftLink * link); +void MysteryGiftLink_InitRecv(struct MysteryGiftLink * link, u32 ident, void * dest); + +#endif //GUARD_MYSTERY_GIFT_LINK_H diff --git a/include/mystery_gift_server.h b/include/mystery_gift_server.h index 7c71ed856..64bb9e9bf 100644 --- a/include/mystery_gift_server.h +++ b/include/mystery_gift_server.h @@ -2,121 +2,103 @@ #define GUARD_MYSTERY_GIFT_SERVER_H #include "global.h" +#include "mystery_gift_link.h" -#define ME_SEND_BUF_SIZE 0x400 - -struct MysteryGiftLink -{ - s32 state; - u8 sendPlayerId; - u8 recvPlayerId; - u16 recvIdent; - u16 recvCounter; - u16 recvCRC; - u16 recvSize; - u16 sendIdent; - u16 sendCounter; - u16 sendCRC; - u16 sendSize; - void *recvBuffer; - const void *sendBuffer; - u32 (*recvFunc)(struct MysteryGiftLink *); - u32 (*sendFunc)(struct MysteryGiftLink *); +// 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 }; -struct mevent_client_cmd -{ - u32 instr; - u32 parameter; +// 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, // In Emerald, this was separated into SVR_CHECK_GAME_DATA_CARD and SVR_CHECK_GAME_DATA_NEWS + 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, }; -// Client commands -#define CLI_RETURN(x) {.instr = 1, .parameter = x} -#define CLI_RECEIVE(x) {.instr = 2, .parameter = x} -#define CLI_WAITSND {.instr = 3, .parameter = 0} -#define CLI_JUMPBUF {.instr = 4, .parameter = 0} -#define CLI_SNDHEAD {.instr = 8, .parameter = 0} -#define CLI_VLDNEWS {.instr = 9, .parameter = 0} -#define CLI_RECVSAV {.instr = 10, .parameter = 0} -#define CLI_RECVBUF {.instr = 12, .parameter = 0} -#define CLI_REQWORD {.instr = 13, .parameter = 0} -#define CLI_SNDWORD {.instr = 14, .parameter = 0} -#define CLI_RECVMON {.instr = 16, .parameter = 0} -#define CLI_RECVRAM {.instr = 17, .parameter = 0} -#define CLI_SENDALL {.instr = 20, .parameter = 0} +// 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) .flag = sizeof(pointer), .parameter = pointer -struct mevent_client -{ - u32 unk_00; - u32 param; - u32 mainseqno; - u32 flag; - u32 cmdidx; - void *sendBuffer; - void *recvBuffer; - struct mevent_client_cmd * cmdBuffer; - void *buffer; - struct MysteryGiftLink manager; +// 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 mevent_server_cmd +struct MysteryGiftServerCmd { u32 instr; bool32 flag; - void *parameter; + const void *parameter; }; -// Server commands -#define SRV_RETURN(x) {.instr = 0, .flag = x} -#define SRV_WAITSND {.instr = 1} -#define SRV_RECV(x) {.instr = 2, .flag = x} -#define SRV_BRANCH(y) {.instr = 3, .parameter = (void *)y} -#define SRV_BRANCHIF(x, y) {.instr = 4, .flag = x, .parameter = (void *)y} -#define SRV_READ_1442CC {.instr = 5} -#define SRV_VALID_1442CC {.instr = 6} -#define SRV_CHECK_1442CC_14 {.instr = 7} -#define SRV_READWORD {.instr = 8} -#define SRV_SEND_CARD {.instr = 13} -#define SRV_SEND_NEWS {.instr = 14} -#define SRV_BUFFER_SEND {.instr = 15} -#define SRV_SEND(x, y) {.instr = 18, .flag = x, .parameter = (void *)y} -#define SRV_SENDSTR(x, y) {.instr = 20, .flag = x, .parameter = (void *)y} -#define SRV_BUFFER_CARD {.instr = 26} -#define SRV_BUFFER_NEWS {.instr = 27} -#define SRV_RAM_SCRIPT_IF_VALID {.instr = 28} - -struct mevent_srv_common +struct MysteryGiftServer { - u32 unk_00; + u32 unused; u32 param; - u32 mainseqno; + u32 funcId; u32 cmdidx; - const struct mevent_server_cmd * cmdBuffer; + const struct MysteryGiftServerCmd * script; void *recvBuffer; struct WonderCard * card; struct WonderNews * news; - struct MysteryGiftLinkGameData * mevent_unk1442cc; - void *sendBuffer1; - u32 sendBuffer1Size; - void *sendBuffer2; - u32 sendBuffer2Size; - u32 sendWord; + struct MysteryGiftLinkGameData * linkGameData; + const void *ramScript; + u32 ramScriptSize; + const void *clientScript; + u32 clientScriptSize; + u32 stamp; struct MysteryGiftLink manager; }; -u32 MysteryGiftLink_Recv(struct MysteryGiftLink * link); -u32 MysteryGiftLink_Send(struct MysteryGiftLink * link); -void MysteryGiftLink_Init(struct MysteryGiftLink * link, u32 sendPlayerId, u32 recvPlayerId); -void MysteryGiftLink_InitSend(struct MysteryGiftLink * link, u32 ident, const void *src, u32 size); -void MysteryGiftLink_InitRecv(struct MysteryGiftLink * link, u32 ident, void *dest); - -void mevent_client_do_init(void); -u32 mevent_client_do_exec(u16 * a0); -void mevent_client_inc_flag(void); -void *mevent_client_get_buffer(void); -void mevent_client_set_param(u32 a0); -void mevent_srv_init_wnews(void); -void mevent_srv_new_wcard(void); -u32 mevent_srv_common_do_exec(u16 * a0); +void MysterGiftServer_CreateForNews(void); +void MysterGiftServer_CreateForCard(void); +u32 MysterGiftServer_Run(u16 * endVal); #endif //GUARD_MYSTERY_GIFT_SERVER_H diff --git a/src/mystery_gift.c b/src/mystery_gift.c index fa164b924..8db1ee5e0 100644 --- a/src/mystery_gift.c +++ b/src/mystery_gift.c @@ -810,7 +810,7 @@ bool32 MysteryGift_ValidateLinkGameData(const struct MysteryGiftLinkGameData * d return TRUE; } -u32 MysteryGift_CompareCardFlags(const u16 * flagId, const struct MysteryGiftLinkGameData * data, void *unused) +u32 MysteryGift_CompareCardFlags(const u16 * flagId, const struct MysteryGiftLinkGameData * data, const void *unused) { // Has a Wonder Card already? if (data->flagId == 0) @@ -824,7 +824,7 @@ u32 MysteryGift_CompareCardFlags(const u16 * flagId, const struct MysteryGiftLin return 2; } -u32 MysteryGift_CheckStamps(const u16 * stamp, const struct MysteryGiftLinkGameData * data, void *unused) +u32 MysteryGift_CheckStamps(const u16 * stamp, const struct MysteryGiftLinkGameData * data, const void *unused) { s32 stampsMissing = data->maxStamps - GetNumStampsInMetadata(&data->cardMetadata, data->maxStamps); diff --git a/src/mystery_gift_client.c b/src/mystery_gift_client.c index 5844f80e2..dc1830b60 100644 --- a/src/mystery_gift_client.c +++ b/src/mystery_gift_client.c @@ -6,285 +6,296 @@ #include "battle_tower.h" #include "mystery_event_script.h" #include "mystery_gift.h" +#include "mystery_gift_client.h" #include "mystery_gift_server.h" -static EWRAM_DATA struct mevent_client * s_mevent_client_ptr = NULL; +enum { + FUNC_INIT, + FUNC_DONE, + FUNC_RECV, + FUNC_SEND, + FUNC_RUN, + FUNC_WAIT, + FUNC_RUN_MEVENT, + FUNC_RUN_BUFFER, +}; -static void mevent_client_init(struct mevent_client *, u32, u32); -static u32 mevent_client_exec(struct mevent_client *); -static void mevent_client_free_resources(struct mevent_client *); +static EWRAM_DATA struct MysteryGiftClient * sClient = NULL; -extern const struct mevent_client_cmd gMEventClientScript_InitialListen[]; +static void MysteryGiftClient_Init(struct MysteryGiftClient *, u32, u32); +static u32 MysteryGiftClient_CallFunc(struct MysteryGiftClient *); +static void MysteryGiftClient_Free(struct MysteryGiftClient *); -void mevent_client_do_init(void) +extern const struct MysteryGiftClientCmd gMysteryGiftClientScript_Init[]; + +void MysteryGiftClient_Create(void) { - s_mevent_client_ptr = AllocZeroed(sizeof(struct mevent_client)); - mevent_client_init(s_mevent_client_ptr, 1, 0); + sClient = AllocZeroed(sizeof(*sClient)); + MysteryGiftClient_Init(sClient, 1, 0); } -u32 mevent_client_do_exec(u16 * a0) +u32 MysteryGiftClient_Run(u16 * endVal) { u32 result; - if (s_mevent_client_ptr == NULL) - return 6; - result = mevent_client_exec(s_mevent_client_ptr); - if (result == 6) + if (sClient == NULL) + return CLI_RET_END; + result = MysteryGiftClient_CallFunc(sClient); + if (result == CLI_RET_END) { - *a0 = s_mevent_client_ptr->param; - mevent_client_free_resources(s_mevent_client_ptr); - Free(s_mevent_client_ptr); - s_mevent_client_ptr = NULL; + *endVal = sClient->param; + MysteryGiftClient_Free(sClient); + FREE_AND_SET_NULL(sClient); } return result; } -void mevent_client_inc_flag(void) +void MysteryGiftClient_AdvanceState(void) { - s_mevent_client_ptr->flag++; + sClient->funcState++; } -void *mevent_client_get_buffer(void) +void *MysteryGiftClient_GetMsg(void) { - return s_mevent_client_ptr->buffer; + return sClient->msg; } -void mevent_client_set_param(u32 a0) +void MysteryGiftClient_SetParam(u32 val) { - s_mevent_client_ptr->param = a0; + sClient->param = val; } -static void mevent_client_init(struct mevent_client * svr, u32 sendPlayerNo, u32 recvPlayerNo) +static void MysteryGiftClient_Init(struct MysteryGiftClient * client, u32 sendPlayerId, u32 recvPlayerId) { - svr->unk_00 = 0; - svr->mainseqno = 0; - svr->flag = 0; - svr->sendBuffer = AllocZeroed(ME_SEND_BUF_SIZE); - svr->recvBuffer = AllocZeroed(ME_SEND_BUF_SIZE); - svr->cmdBuffer = AllocZeroed(ME_SEND_BUF_SIZE); - svr->buffer = AllocZeroed(0x40); - MysteryGiftLink_Init(&svr->manager, sendPlayerNo, recvPlayerNo); + client->unused = 0; + client->funcId = FUNC_INIT; + client->funcState = 0; + 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 mevent_client_free_resources(struct mevent_client * svr) +static void MysteryGiftClient_Free(struct MysteryGiftClient * client) { - Free(svr->sendBuffer); - Free(svr->recvBuffer); - Free(svr->cmdBuffer); - Free(svr->buffer); + Free(client->sendBuffer); + Free(client->recvBuffer); + Free(client->script); + Free(client->msg); } -static void mevent_client_jmp_buffer(struct mevent_client * svr) +static void MysteryGiftClient_CopyRecvScript(struct MysteryGiftClient * client) { - memcpy(svr->cmdBuffer, svr->recvBuffer, ME_SEND_BUF_SIZE); - svr->cmdidx = 0; + memcpy(client->script, client->recvBuffer, MG_LINK_BUFFER_SIZE); + client->cmdidx = 0; } -static void mevent_client_send_word(struct mevent_client * svr, u32 ident, u32 word) +static void MysteryGiftClient_InitSendWord(struct MysteryGiftClient * client, u32 ident, u32 word) { - CpuFill32(0, svr->sendBuffer, ME_SEND_BUF_SIZE); - *(u32 *)svr->sendBuffer = word; - MysteryGiftLink_InitSend(&svr->manager, ident, svr->sendBuffer, sizeof(u32)); + CpuFill32(0, client->sendBuffer, MG_LINK_BUFFER_SIZE); + *(u32 *)client->sendBuffer = word; + MysteryGiftLink_InitSend(&client->link, ident, client->sendBuffer, sizeof(word)); } -static u32 client_mainseq_0(struct mevent_client * svr) +static u32 Client_Init(struct MysteryGiftClient * client) { // init - memcpy(svr->cmdBuffer, gMEventClientScript_InitialListen, ME_SEND_BUF_SIZE); - svr->cmdidx = 0; - svr->mainseqno = 4; - svr->flag = 0; - return 0; + memcpy(client->script, gMysteryGiftClientScript_Init, MG_LINK_BUFFER_SIZE); + client->cmdidx = 0; + client->funcId = FUNC_RUN; + client->funcState = 0; + return CLI_RET_INIT; } -static u32 client_mainseq_1(struct mevent_client * svr) +static u32 Client_Done(struct MysteryGiftClient * client) { - // done - return 6; + return CLI_RET_END; } -static u32 client_mainseq_2(struct mevent_client * svr) +static u32 Client_Recv(struct MysteryGiftClient * client) { - // do recv - if (MysteryGiftLink_Recv(&svr->manager)) + if (MysteryGiftLink_Recv(&client->link)) { - svr->mainseqno = 4; - svr->flag = 0; + client->funcId = FUNC_RUN; + client->funcState = 0; } - return 1; + return CLI_RET_ACTIVE; } -static u32 client_mainseq_3(struct mevent_client * svr) +static u32 Client_Send(struct MysteryGiftClient * client) { - // do send - if (MysteryGiftLink_Send(&svr->manager)) + if (MysteryGiftLink_Send(&client->link)) { - svr->mainseqno = 4; - svr->flag = 0; + client->funcId = FUNC_RUN; + client->funcState = 0; } - return 1; + return CLI_RET_ACTIVE; } -static u32 client_mainseq_4(struct mevent_client * svr) +static u32 Client_Run(struct MysteryGiftClient * client) { // process command - struct mevent_client_cmd * cmd = &svr->cmdBuffer[svr->cmdidx]; - ++svr->cmdidx; + struct MysteryGiftClientCmd * cmd = &client->script[client->cmdidx]; + client->cmdidx++; switch (cmd->instr) { - case 0: + case CLI_NONE: break; - case 1: - svr->param = cmd->parameter; - svr->mainseqno = 1; - svr->flag = 0; + case CLI_RETURN: + client->param = cmd->parameter; // Set for endVal in MysteryGiftClient_Run + client->funcId = FUNC_DONE; + client->funcState = 0; break; - case 2: - MysteryGiftLink_InitRecv(&svr->manager, cmd->parameter, svr->recvBuffer); - svr->mainseqno = 2; - svr->flag = 0; + case CLI_RECV: + MysteryGiftLink_InitRecv(&client->link, cmd->parameter, client->recvBuffer); + client->funcId = FUNC_RECV; + client->funcState = 0; break; - case 3: - svr->mainseqno = 3; - svr->flag = 0; + case CLI_SEND_LOADED: + // Send without a MysteryGiftLink_InitSend + // Sends whatever has been loaded already + client->funcId = FUNC_SEND; + client->funcState = 0; break; - case 20: - MysteryGiftLink_InitSend(&svr->manager, 0x14, svr->sendBuffer, 0); - svr->mainseqno = 3; - svr->flag = 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 19: - mevent_client_send_word(svr, 0x12, GetGameStat(cmd->parameter)); - svr->mainseqno = 3; - svr->flag = 0; + case CLI_SEND_STAT: + MysteryGiftClient_InitSendWord(client, MG_LINKID_GAME_STAT, GetGameStat(cmd->parameter)); + client->funcId = FUNC_SEND; + client->funcState = 0; break; - case 6: - if (svr->param == 0) - mevent_client_jmp_buffer(svr); + case CLI_COPY_RECV_IF_N: + if (client->param == FALSE) + MysteryGiftClient_CopyRecvScript(client); break; - case 7: - if (svr->param == 1) - mevent_client_jmp_buffer(svr); + case CLI_COPY_RECV_IF: + if (client->param == TRUE) + MysteryGiftClient_CopyRecvScript(client); break; - case 4: - mevent_client_jmp_buffer(svr); + case CLI_COPY_RECV: + MysteryGiftClient_CopyRecvScript(client); break; - case 5: - memcpy(svr->buffer, svr->recvBuffer, 0x40); - svr->mainseqno = 5; - svr->flag = 0; - return 2; - case 11: - memcpy(svr->buffer, svr->recvBuffer, 0x40); - svr->mainseqno = 5; - svr->flag = 0; - return 3; - case 12: - memcpy(svr->buffer, svr->recvBuffer, 0x40); - svr->mainseqno = 5; - svr->flag = 0; - return 5; - case 13: - svr->mainseqno = 5; - svr->flag = 0; - return 4; - case 8: - MysteryGift_LoadLinkGameData(svr->sendBuffer); - MysteryGiftLink_InitSend(&svr->manager, 0x11, svr->sendBuffer, sizeof(struct MysteryGiftLinkGameData)); + case CLI_YES_NO: + memcpy(client->msg, client->recvBuffer, CLIENT_MAX_MSG_SIZE); + client->funcId = FUNC_WAIT; + client->funcState = 0; + 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_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_COPY_MSG; + case CLI_ASK_TOSS: + client->funcId = FUNC_WAIT; + client->funcState = 0; + return CLI_RET_ASK_TOSS; + case CLI_LOAD_GAME_DATA: + MysteryGift_LoadLinkGameData(client->sendBuffer); + MysteryGiftLink_InitSend(&client->link, MG_LINKID_GAME_DATA, client->sendBuffer, sizeof(struct MysteryGiftLinkGameData)); break; - case 14: - mevent_client_send_word(svr, 0x13, svr->param); + case CLI_LOAD_TOSS_RESPONSE: + // param here is set by MG_STATE_CLIENT_ASK_TOSS or MG_STATE_CLIENT_ASK_TOSS_UNRECEIVED + MysteryGiftClient_InitSendWord(client, MG_LINKID_RESPONSE, client->param); break; - case 10: - SaveWonderCard(svr->recvBuffer); + case CLI_SAVE_CARD: + SaveWonderCard(client->recvBuffer); break; - case 9: - if (!IsWonderNewsSameAsSaved(svr->recvBuffer)) + case CLI_SAVE_NEWS: + if (!IsWonderNewsSameAsSaved(client->recvBuffer)) { - SaveWonderNews(svr->recvBuffer); - mevent_client_send_word(svr, 0x13, 0); + SaveWonderNews(client->recvBuffer); + MysteryGiftClient_InitSendWord(client, MG_LINKID_RESPONSE, FALSE); } else - // Other trainer already has news - mevent_client_send_word(svr, 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 15: - svr->mainseqno = 6; - svr->flag = 0; + case CLI_RUN_MEVENT_SCRIPT: + client->funcId = FUNC_RUN_MEVENT; + client->funcState = 0; break; - case 16: - MysteryGift_TrySaveStamp(svr->recvBuffer); + case CLI_SAVE_STAMP: + MysteryGift_TrySaveStamp(client->recvBuffer); break; - case 17: - InitRamScript_NoObjectEvent(svr->recvBuffer, 1000); + case CLI_SAVE_RAM_SCRIPT: + InitRamScript_NoObjectEvent(client->recvBuffer, sizeof(struct RamScriptData)); break; - case 18: - memcpy(&gSaveBlock2Ptr->battleTower.ereaderTrainer, svr->recvBuffer, sizeof(struct BattleTowerEReaderTrainer)); + case CLI_RECV_EREADER_TRAINER: + memcpy(&gSaveBlock2Ptr->battleTower.ereaderTrainer, client->recvBuffer, sizeof(gSaveBlock2Ptr->battleTower.ereaderTrainer)); ValidateEReaderTrainer(); break; - case 21: - memcpy(gDecompressionBuffer, svr->recvBuffer, ME_SEND_BUF_SIZE); - svr->mainseqno = 7; - svr->flag = 0; + case CLI_RUN_BUFFER_SCRIPT: + memcpy(gDecompressionBuffer, client->recvBuffer, MG_LINK_BUFFER_SIZE); + client->funcId = FUNC_RUN_BUFFER; + client->funcState = 0; break; } - return 1; + return CLI_RET_ACTIVE; } -static u32 client_mainseq_5(struct mevent_client * svr) +static u32 Client_Wait(struct MysteryGiftClient * client) { - // wait flag - if (svr->flag) + if (client->funcState) { - svr->mainseqno = 4; - svr->flag = 0; + client->funcId = FUNC_RUN; + client->funcState = 0; } - return 1; + return CLI_RET_ACTIVE; } -static u32 client_mainseq_6(struct mevent_client * svr) +static u32 Client_RunMysteryEventScript(struct MysteryGiftClient * client) { - // Run mevent buffer script - switch (svr->flag) + switch (client->funcState) { case 0: - MEventScript_InitContext(svr->recvBuffer); - ++svr->flag; + MEventScript_InitContext(client->recvBuffer); + client->funcState++; break; case 1: - if (!MEventScript_Run(&svr->param)) + if (!MEventScript_Run(&client->param)) { - svr->mainseqno = 4; - svr->flag = 0; + client->funcId = FUNC_RUN; + client->funcState = 0; } break; } - return 1; + return CLI_RET_ACTIVE; } -static u32 client_mainseq_7(struct mevent_client * svr) +static u32 Client_RunBufferScript(struct MysteryGiftClient * client) { - // exec arbitrary code u32 (*func)(u32 *, struct SaveBlock2 *, struct SaveBlock1 *) = (void *)gDecompressionBuffer; - if (func(&svr->param, gSaveBlock2Ptr, gSaveBlock1Ptr) == 1) + if (func(&client->param, gSaveBlock2Ptr, gSaveBlock1Ptr) == 1) { - svr->mainseqno = 4; - svr->flag = 0; + client->funcId = FUNC_RUN; + client->funcState = 0; } - return 1; + return CLI_RET_ACTIVE; } -static u32 mevent_client_exec(struct mevent_client * svr) +static u32 MysteryGiftClient_CallFunc(struct MysteryGiftClient * client) { - u32 (*funcs[])(struct mevent_client *) = { - client_mainseq_0, - client_mainseq_1, - client_mainseq_2, - client_mainseq_3, - client_mainseq_4, - client_mainseq_5, - client_mainseq_6, - client_mainseq_7 + u32 (*funcs[])(struct MysteryGiftClient *) = { + [FUNC_INIT] = Client_Init, + [FUNC_DONE] = Client_Done, + [FUNC_RECV] = Client_Recv, + [FUNC_SEND] = Client_Send, + [FUNC_RUN] = Client_Run, + [FUNC_WAIT] = Client_Wait, + [FUNC_RUN_MEVENT] = Client_RunMysteryEventScript, + [FUNC_RUN_BUFFER] = Client_RunBufferScript }; - return funcs[svr->mainseqno](svr); + return funcs[client->funcId](client); } diff --git a/src/mystery_gift_menu.c b/src/mystery_gift_menu.c index cb8a5bfe9..a06b93ba3 100644 --- a/src/mystery_gift_menu.c +++ b/src/mystery_gift_menu.c @@ -14,6 +14,7 @@ #include "link.h" #include "event_data.h" #include "mystery_gift_server.h" +#include "mystery_gift_client.h" #include "wonder_news.h" #include "help_system.h" #include "strings.h" @@ -1222,7 +1223,7 @@ void task00_mystery_gift(u8 taskId) { ClearScreenInBg0(TRUE); data->state = 7; - mevent_client_do_init(); + MysteryGiftClient_Create(); } else if (gSpecialVar_Result == 5) { @@ -1235,7 +1236,7 @@ void task00_mystery_gift(u8 taskId) data->state = 8; break; case 8: - switch (mevent_client_do_exec(&data->curPromptWindowId)) + switch (MysteryGiftClient_Run(&data->curPromptWindowId)) { case 6: // done Rfu_SetCloseLinkCallback(); @@ -1243,8 +1244,8 @@ void task00_mystery_gift(u8 taskId) data->state = 13; break; case 5: - memcpy(data->buffer, mevent_client_get_buffer(), 0x40); - mevent_client_inc_flag(); + memcpy(data->buffer, MysteryGiftClient_GetMsg(), 0x40); + MysteryGiftClient_AdvanceState(); break; case 3: data->state = 10; @@ -1259,30 +1260,30 @@ void task00_mystery_gift(u8 taskId) } break; case 9: - flag = DoMysteryGiftYesNo(&data->textState, &data->curPromptWindowId, FALSE, mevent_client_get_buffer()); + flag = DoMysteryGiftYesNo(&data->textState, &data->curPromptWindowId, FALSE, MysteryGiftClient_GetMsg()); switch (flag) { case 0: - mevent_client_set_param(0); - mevent_client_inc_flag(); + MysteryGiftClient_SetParam(0); + MysteryGiftClient_AdvanceState(); data->state = 7; break; case 1: - mevent_client_set_param(1); - mevent_client_inc_flag(); + MysteryGiftClient_SetParam(1); + MysteryGiftClient_AdvanceState(); data->state = 7; break; case -1u: - mevent_client_set_param(1); - mevent_client_inc_flag(); + MysteryGiftClient_SetParam(1); + MysteryGiftClient_AdvanceState(); data->state = 7; break; } break; case 10: - if (PrintMysteryGiftMenuMessage(&data->textState, mevent_client_get_buffer())) + if (PrintMysteryGiftMenuMessage(&data->textState, MysteryGiftClient_GetMsg())) { - mevent_client_inc_flag(); + MysteryGiftClient_AdvanceState(); data->state = 7; } break; @@ -1297,19 +1298,19 @@ void task00_mystery_gift(u8 taskId) } else { - mevent_client_set_param(0); - mevent_client_inc_flag(); + MysteryGiftClient_SetParam(0); + MysteryGiftClient_AdvanceState(); data->state = 7; } break; case 1: - mevent_client_set_param(1); - mevent_client_inc_flag(); + MysteryGiftClient_SetParam(1); + MysteryGiftClient_AdvanceState(); data->state = 7; break; case -1u: - mevent_client_set_param(1); - mevent_client_inc_flag(); + MysteryGiftClient_SetParam(1); + MysteryGiftClient_AdvanceState(); data->state = 7; break; } @@ -1319,18 +1320,18 @@ void task00_mystery_gift(u8 taskId) switch (flag) { case 0: - mevent_client_set_param(0); - mevent_client_inc_flag(); + MysteryGiftClient_SetParam(0); + MysteryGiftClient_AdvanceState(); data->state = 7; break; case 1: - mevent_client_set_param(1); - mevent_client_inc_flag(); + MysteryGiftClient_SetParam(1); + MysteryGiftClient_AdvanceState(); data->state = 7; break; case -1u: - mevent_client_set_param(1); - mevent_client_inc_flag(); + MysteryGiftClient_SetParam(1); + MysteryGiftClient_AdvanceState(); data->state = 7; break; } @@ -1567,17 +1568,17 @@ void task00_mystery_gift(u8 taskId) if (data->IsCardOrNews == 0) { AddTextPrinterToWindow1(gText_SendingWonderCard); - mevent_srv_new_wcard(); + MysterGiftServer_CreateForCard(); } else { AddTextPrinterToWindow1(gText_SendingWonderNews); - mevent_srv_init_wnews(); + MysterGiftServer_CreateForNews(); } data->state = 32; break; case 32: - if (mevent_srv_common_do_exec(&data->curPromptWindowId) == 3) + if (MysterGiftServer_Run(&data->curPromptWindowId) == 3) { data->prevPromptWindowId = data->curPromptWindowId; data->state = 33; diff --git a/src/mystery_gift_scripts.c b/src/mystery_gift_scripts.c index b99c16405..0af0f2346 100644 --- a/src/mystery_gift_scripts.c +++ b/src/mystery_gift_scripts.c @@ -1,192 +1,198 @@ #include "global.h" #include "mystery_gift_server.h" +#include "mystery_gift_client.h" +#include "constants/mystery_gift.h" -extern const struct mevent_server_cmd gServerScript_ClientCanceledCard[]; +extern const struct MysteryGiftServerCmd gServerScript_ClientCanceledCard[]; // Unreferenced -const u8 gUnknown_84687A0[] = _("You have collected all STAMPs!\nWant to input a CARD as a prize?"); +static const u8 sText_CollectedAllStamps[] = _("You have collected all STAMPs!\nWant to input a CARD as a prize?"); -/* CLIENT SCRIPTS */ +//================== +// Client scripts +//================== -const struct mevent_client_cmd gMEventClientScript_InitialListen[] = { // 84687E0 - CLI_RECEIVE(0x10), - CLI_JUMPBUF +const struct MysteryGiftClientCmd gMysteryGiftClientScript_Init[] = { + {CLI_RECV, MG_LINKID_CLIENT_SCRIPT}, + {CLI_COPY_RECV} }; -const struct mevent_client_cmd gMEventClientScript_Send1442CC[] = { - CLI_SNDHEAD, - CLI_WAITSND, - CLI_RECEIVE(0x10), - CLI_JUMPBUF +static const struct MysteryGiftClientCmd sClientScript_SendGameData[] = { + {CLI_LOAD_GAME_DATA}, + {CLI_SEND_LOADED}, + {CLI_RECV, MG_LINKID_CLIENT_SCRIPT}, + {CLI_COPY_RECV} }; -const struct mevent_client_cmd gMEventClientScript_UnableToRecv[] = { // can't accept card or news - CLI_SENDALL, - CLI_RETURN(0x0a) +static const struct MysteryGiftClientCmd sClientScript_CantAccept[] = { + {CLI_SEND_READY_END}, + {CLI_RETURN, CLI_MSG_CANT_ACCEPT} }; -const struct mevent_client_cmd gMEventClientScript_CommError[] = { // comm error - CLI_SENDALL, - CLI_RETURN(0x0b) +static const struct MysteryGiftClientCmd sClientScript_CommError[] = { + {CLI_SEND_READY_END}, + {CLI_RETURN, CLI_MSG_COMM_ERROR} }; -const struct mevent_client_cmd gMEventClientScript_NothingSentOver[] = { // nothing sent - CLI_SENDALL, - CLI_RETURN(0x00) +static const struct MysteryGiftClientCmd sClientScript_NothingSent[] = { + {CLI_SEND_READY_END}, + {CLI_RETURN, CLI_MSG_NOTHING_SENT} }; -const struct mevent_client_cmd gMEventClientScript_ReceiveCardAndReturnSuccess[] = { // card success - CLI_RECEIVE(0x16), - CLI_RECVSAV, - CLI_RECEIVE(0x19), - CLI_RECVRAM, - CLI_SENDALL, - CLI_RETURN(0x02) +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 mevent_client_cmd gMEventClientScript_ReceiveNewsAndValidate[] = { - CLI_RECEIVE(0x17), - CLI_VLDNEWS, - CLI_WAITSND, - CLI_RECEIVE(0x10), - CLI_JUMPBUF +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 mevent_client_cmd gMEventClientScript_AlreadyHadNews[] = { // already had news - CLI_SENDALL, - CLI_RETURN(0x07) +static const struct MysteryGiftClientCmd sClientScript_HadNews[] = { + {CLI_SEND_READY_END}, + {CLI_RETURN, CLI_MSG_HAD_NEWS} }; -const struct mevent_client_cmd gMEventClientScript_RecvNewsSuccess[] = { // news success - CLI_SENDALL, - CLI_RETURN(0x03) +static const struct MysteryGiftClientCmd sClientScript_NewsReceived[] = { + {CLI_SEND_READY_END}, + {CLI_RETURN, CLI_MSG_NEWS_RECEIVED} }; -const struct mevent_client_cmd gMEventClientScript_AskWouldLikeToTossCard[] = { - CLI_REQWORD, - CLI_SNDWORD, - CLI_WAITSND, - CLI_RECEIVE(0x10), - CLI_JUMPBUF +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 mevent_client_cmd gMEventClientScript_OtherTrainerCanceled[] = { // comm canceled - CLI_SENDALL, - CLI_RETURN(0x09) +static const struct MysteryGiftClientCmd sClientScript_Canceled[] = { + {CLI_SEND_READY_END}, + {CLI_RETURN, CLI_MSG_COMM_CANCELED} }; -const struct mevent_client_cmd gMEventClientScript_AlreadyHadCard[] = { // already had card - CLI_SENDALL, - CLI_RETURN(0x05) +static const struct MysteryGiftClientCmd sClientScript_HadCard[] = { + {CLI_SEND_READY_END}, + {CLI_RETURN, CLI_MSG_HAD_CARD} }; -const struct mevent_client_cmd gMEventClientScript_SuccessFromBuffer[] = { // success from buffer - CLI_RECEIVE(0x15), - CLI_RECVBUF, - CLI_SENDALL, - CLI_RETURN(0x0d) +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} }; -/* SERVER SCRIPTS */ +//================== +// Server scripts +//================== -const struct mevent_server_cmd gMEventSrvScript_UnableToSend[] = { - SRV_SEND(0x10, gMEventClientScript_UnableToRecv), - SRV_WAITSND, - SRV_RECV(0x14), - SRV_RETURN(0x0a) +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_server_cmd gUnknown_8468950[] = { - SRV_SEND(0x10, gMEventClientScript_CommError), - SRV_WAITSND, - SRV_RECV(0x14), - SRV_RETURN(0x0b) +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_server_cmd gUnknown_8468980[] = { - SRV_SEND(0x10, gMEventClientScript_OtherTrainerCanceled), - SRV_WAITSND, - SRV_RECV(0x14), - SRV_RETURN(0x09) +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_server_cmd gMEventSrvScript_OtherTrnHasNews[] = { - SRV_SEND(0x10, gMEventClientScript_AlreadyHadNews), - SRV_WAITSND, - SRV_RECV(0x14), - SRV_RETURN(0x07) +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_server_cmd gMEventSrvScript_SentNewsSuccess[] = { - SRV_SEND(0x28, gMEventClientScript_ReceiveNewsAndValidate), - SRV_WAITSND, - SRV_SEND_NEWS, - SRV_WAITSND, - SRV_RECV(0x13), - SRV_READWORD, - SRV_BRANCHIF(0x01, gMEventSrvScript_OtherTrnHasNews), - SRV_SEND(0x10, gMEventClientScript_RecvNewsSuccess), - SRV_WAITSND, - SRV_RECV(0x14), - SRV_RETURN(0x03) +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_server_cmd gMEventSrvScript_SendCardSuccess[] = { - SRV_SEND(0x30, gMEventClientScript_ReceiveCardAndReturnSuccess), - SRV_WAITSND, - SRV_SEND_CARD, - SRV_WAITSND, - SRV_BUFFER_SEND, - SRV_WAITSND, - SRV_RECV(0x14), - SRV_RETURN(0x02) +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_server_cmd gMEventSrvScript_AskClientToOverwriteCard[] = { - SRV_SEND(0x28, gMEventClientScript_AskWouldLikeToTossCard), - SRV_WAITSND, - SRV_RECV(0x13), - SRV_READWORD, - SRV_BRANCHIF(0x00, gMEventSrvScript_SendCardSuccess), - SRV_BRANCH(gServerScript_ClientCanceledCard) +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, .parameter = gServerScript_ClientCanceledCard} // Kept old card, cancel new one }; -const struct mevent_server_cmd gMEventSrvScript_OtherTrnHasCard[] = { - SRV_SEND(0x10, gMEventClientScript_AlreadyHadCard), - SRV_WAITSND, - SRV_RECV(0x14), - SRV_RETURN(0x05) +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} }; -const struct mevent_server_cmd gUnknown_8468B3C[] = { - SRV_SEND(0x10, gMEventClientScript_NothingSentOver), - SRV_WAITSND, - SRV_RECV(0x14), - SRV_RETURN(0x00) +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 mevent_server_cmd gMEventSrvScript_SendNews[] = { - SRV_BUFFER_NEWS, - SRV_SEND(0x20, gMEventClientScript_Send1442CC), - SRV_WAITSND, - SRV_RECV(0x11), - SRV_READ_1442CC, - SRV_VALID_1442CC, - SRV_BRANCHIF(0x00, gMEventSrvScript_UnableToSend), - SRV_BRANCH(gMEventSrvScript_SentNewsSuccess) +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}, + {SVR_GOTO_IF_EQ, FALSE, sServerScript_CantSend}, + {SVR_GOTO, .parameter = sServerScript_SendNews}, }; -const struct mevent_server_cmd gMEventSrvScript_SendCard[] = { - SRV_BUFFER_CARD, - SRV_RAM_SCRIPT_IF_VALID, - SRV_SEND(0x20, gMEventClientScript_Send1442CC), - SRV_WAITSND, - SRV_RECV(0x11), - SRV_READ_1442CC, - SRV_VALID_1442CC, - SRV_BRANCHIF(0x00, gMEventSrvScript_UnableToSend), - SRV_CHECK_1442CC_14, - SRV_BRANCHIF(0x02, gMEventSrvScript_AskClientToOverwriteCard), - SRV_BRANCHIF(0x00, gMEventSrvScript_SendCardSuccess), - SRV_BRANCH(gMEventSrvScript_OtherTrnHasCard) +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}, + {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, .parameter = sServerScript_HasCard} // HAS_SAME_CARD }; diff --git a/src/mystery_gift_server.c b/src/mystery_gift_server.c index d2f2b2262..9c6868b6e 100644 --- a/src/mystery_gift_server.c +++ b/src/mystery_gift_server.c @@ -4,276 +4,286 @@ #include "mystery_gift.h" #include "mystery_gift_server.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 *); +static EWRAM_DATA struct MysteryGiftServer * sServer = NULL; -extern const struct mevent_server_cmd gMEventSrvScript_SendNews[]; -extern const struct mevent_server_cmd gMEventSrvScript_SendCard[]; +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, gMEventSrvScript_SendNews, 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, gMEventSrvScript_SendCard, 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_AND_SET_NULL(sServer); } 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->card = AllocZeroed(sizeof(struct WonderCard)); - svr->news = AllocZeroed(sizeof(struct WonderNews)); + svr->unused = 0; + svr->funcId = FUNC_INIT; + svr->card = AllocZeroed(sizeof(*svr->card)); + svr->news = AllocZeroed(sizeof(*svr->news)); svr->recvBuffer = AllocZeroed(ME_SEND_BUF_SIZE); - svr->mevent_unk1442cc = AllocZeroed(sizeof(struct MysteryGiftLinkGameData)); - svr->cmdBuffer = cmdBuffer; + svr->linkGameData = AllocZeroed(sizeof(*svr->linkGameData)); + svr->script = script; svr->cmdidx = 0; - MysteryGiftLink_Init(&svr->manager, sendPlayerNo, recvPlayerNo); + MysteryGiftLink_Init(&svr->manager, sendPlayerId, recvPlayerId); } -static void mevent_srv_free_resources(struct mevent_srv_common * svr) +static void MysteryGiftServer_Free(struct MysteryGiftServer * svr) { Free(svr->card); Free(svr->news); Free(svr->recvBuffer); - Free(svr->mevent_unk1442cc); + Free(svr->linkGameData); } -static 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_EX(size <= ME_SEND_BUF_SIZE, ABSPATH("mevent_server.c"), 257); + AGB_ASSERT_EX(size <= ME_SEND_BUF_SIZE, ABSPATH("mevent_server.c"), 257); MysteryGiftLink_InitSend(&svr->manager, ident, src, size); } -static void *mevent_first_if_not_null_else_second(void *a0, 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(void *a0, 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; + 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; + 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_server_cmd * cmd = &svr->cmdBuffer[svr->cmdidx]; - void *ptr; + const struct MysteryGiftServerCmd * cmd = &svr->script[svr->cmdidx]; + const void *ptr; svr->cmdidx++; switch (cmd->instr) { - case 0: - AGB_ASSERT_EX(cmd->parameter == NULL, ABSPATH("mevent_server.c"), 354); - svr->mainseqno = 1; - svr->param = cmd->flag; - break; - case 1: - svr->mainseqno = 3; - break; - case 2: - AGB_ASSERT_EX(cmd->parameter == NULL, ABSPATH("mevent_server.c"), 364); - MysteryGiftLink_InitRecv(&svr->manager, cmd->flag, svr->recvBuffer); - svr->mainseqno = 2; - break; - case 3: - AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 370); + case SVR_RETURN: + AGB_ASSERT_EX(cmd->parameter == NULL, ABSPATH("mevent_server.c"), 354); + svr->funcId = FUNC_DONE; + svr->param = cmd->flag; // Set for endVal in MysteryGiftServer_Run + break; + case SVR_SEND: + svr->funcId = FUNC_SEND; + break; + case SVR_RECV: + AGB_ASSERT_EX(cmd->parameter == NULL, ABSPATH("mevent_server.c"), 364); + MysteryGiftLink_InitRecv(&svr->manager, cmd->flag, svr->recvBuffer); + svr->funcId = FUNC_RECV; + break; + case SVR_GOTO: + AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 370); + svr->cmdidx = 0; + svr->script = cmd->parameter; + break; + case SVR_COPY_GAME_DATA: + AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 376); + AGB_ASSERT_EX(cmd->parameter == NULL, ABSPATH("mevent_server.c"), 377); + memcpy(svr->linkGameData, svr->recvBuffer, sizeof(*svr->linkGameData)); + break; + case SVR_CHECK_GAME_DATA: + AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 382); + AGB_ASSERT_EX(cmd->parameter == NULL, ABSPATH("mevent_server.c"), 383); + svr->param = MysteryGift_ValidateLinkGameData(svr->linkGameData); + break; + case SVR_GOTO_IF_EQ: + if (svr->param == cmd->flag) + { svr->cmdidx = 0; - svr->cmdBuffer = cmd->parameter; - break; - case 5: - AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 376); - AGB_ASSERT_EX(cmd->parameter == NULL, ABSPATH("mevent_server.c"), 377); - memcpy(svr->mevent_unk1442cc, svr->recvBuffer, sizeof(struct MysteryGiftLinkGameData)); - break; - case 6: - AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 382); - AGB_ASSERT_EX(cmd->parameter == NULL, ABSPATH("mevent_server.c"), 383); - svr->param = MysteryGift_ValidateLinkGameData(svr->mevent_unk1442cc); - break; - case 4: - if (svr->param == cmd->flag) - { - svr->cmdidx = 0; - svr->cmdBuffer = cmd->parameter; - } - break; - case 7: - AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 396); - ptr = mevent_first_if_not_null_else_second(cmd->parameter, svr->card); - svr->param = MysteryGift_CompareCardFlags(ptr, svr->mevent_unk1442cc, ptr); - break; - case 8: - AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 402); - AGB_ASSERT_EX(cmd->parameter == NULL, ABSPATH("mevent_server.c"), 403); - svr->param = *(u32 *)svr->recvBuffer; - break; - case 9: - AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 408); - ptr = mevent_first_if_not_null_else_second(cmd->parameter, &svr->sendWord); - svr->param = MysteryGift_CheckStamps(ptr, svr->mevent_unk1442cc, ptr); - break; - case 10: - AGB_ASSERT_EX(cmd->parameter == NULL, ABSPATH("mevent_server.c"), 415); - svr->param = MysteryGift_GetCardStatFromLinkData(svr->mevent_unk1442cc, cmd->flag); - break; - case 11: - AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 420); - svr->param = MysteryGift_DoesQuestionnaireMatch(svr->mevent_unk1442cc, cmd->parameter); - break; - case 12: - AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 426); - svr->param = mevent_compare_pointers(cmd->parameter, *(void **)svr->recvBuffer); - break; - case 14: - AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 432); - mevent_srv_common_init_send(svr, 0x17, mevent_first_if_not_null_else_second(cmd->parameter, svr->news), sizeof(struct WonderNews)); - break; - case 13: - AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 438); - mevent_srv_common_init_send(svr, 0x16, mevent_first_if_not_null_else_second(cmd->parameter, svr->card), sizeof(struct WonderCard)); - break; - case 16: - AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 444); - mevent_srv_common_init_send(svr, 0x18, mevent_first_if_not_null_else_second(cmd->parameter, &svr->sendWord), 4); - break; - case 15: - if (cmd->parameter == NULL) - mevent_srv_common_init_send(svr, 0x19, svr->sendBuffer1, svr->sendBuffer1Size); - else - mevent_srv_common_init_send(svr, 0x19, cmd->parameter, cmd->flag); - break; - case 18: - if (cmd->parameter == NULL) - mevent_srv_common_init_send(svr, 0x10, svr->sendBuffer2, svr->sendBuffer2Size); - else - mevent_srv_common_init_send(svr, 0x10, cmd->parameter, cmd->flag); - break; - case 19: - AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 466); - mevent_srv_common_init_send(svr, 0x1a, cmd->parameter, 188); - break; - case 20: - mevent_srv_common_init_send(svr, 0x15, cmd->parameter, cmd->flag); - break; - case 17: - mevent_srv_common_init_send(svr, 0x1c, cmd->parameter, cmd->flag); - break; - case 22: - AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 481); - memcpy(svr->card, cmd->parameter, 332); - break; - case 23: - AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 486); - memcpy(svr->news, cmd->parameter, 444); - break; - case 21: - AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 491); - svr->sendWord = *(u32 *)cmd->parameter; - break; - case 24: - svr->sendBuffer1 = cmd->parameter; - svr->sendBuffer1Size = cmd->flag; - break; - case 25: - svr->sendBuffer2 = cmd->parameter; - svr->sendBuffer2Size = cmd->flag; - break; - case 26: - AGB_ASSERT_EX(cmd->flag == FALSE && cmd->parameter == NULL, ABSPATH("mevent_server.c"), 506); - memcpy(svr->card, GetSavedWonderCard(), 332); - DisableWonderCardSending(svr->card); - break; - case 27: - AGB_ASSERT_EX(cmd->flag == FALSE && cmd->parameter == NULL, ABSPATH("mevent_server.c"), 512); - memcpy(svr->news, GetSavedWonderNews(), 444); - break; - case 28: - AGB_ASSERT_EX(cmd->flag == FALSE && cmd->parameter == NULL, ABSPATH("mevent_server.c"), 517); - svr->sendBuffer1 = GetSavedRamScriptIfValid(); - break; - case 29: - mevent_srv_common_init_send(svr, 0x1b, cmd->parameter, cmd->flag); - break; + svr->script = cmd->parameter; + } + break; + case SVR_CHECK_EXISTING_CARD: + AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 396); + ptr = MysteryGiftServer_GetSendData(cmd->parameter, svr->card); + svr->param = MysteryGift_CompareCardFlags(ptr, svr->linkGameData, ptr); + break; + case SVR_READ_RESPONSE: + AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 402); + AGB_ASSERT_EX(cmd->parameter == NULL, ABSPATH("mevent_server.c"), 403); + svr->param = *(u32 *)svr->recvBuffer; + break; + case SVR_CHECK_EXISTING_STAMPS: + AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 408); + ptr = MysteryGiftServer_GetSendData(cmd->parameter, &svr->stamp); + svr->param = MysteryGift_CheckStamps(ptr, svr->linkGameData, ptr); + break; + case SVR_GET_CARD_STAT: + AGB_ASSERT_EX(cmd->parameter == NULL, ABSPATH("mevent_server.c"), 415); + svr->param = MysteryGift_GetCardStatFromLinkData(svr->linkGameData, cmd->flag); + break; + case SVR_CHECK_QUESTIONNAIRE: + AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 420); + svr->param = MysteryGift_DoesQuestionnaireMatch(svr->linkGameData, cmd->parameter); + break; + case SVR_COMPARE: + AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 426); + svr->param = MysteryGiftServer_Compare(cmd->parameter, *(void **)svr->recvBuffer); + break; + case SVR_LOAD_NEWS: + AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 432); + MysteryGiftServer_InitSend(svr, MG_LINKID_NEWS, MysteryGiftServer_GetSendData(cmd->parameter, svr->news), sizeof(struct WonderNews)); + break; + case SVR_LOAD_CARD: + AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 438); + MysteryGiftServer_InitSend(svr, MG_LINKID_CARD, MysteryGiftServer_GetSendData(cmd->parameter, svr->card), sizeof(struct WonderCard)); + break; + case SVR_LOAD_STAMP: + AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 444); + MysteryGiftServer_InitSend(svr, MG_LINKID_STAMP, MysteryGiftServer_GetSendData(cmd->parameter, &svr->stamp), sizeof(svr->stamp)); + break; + case SVR_LOAD_RAM_SCRIPT: + if (cmd->parameter == NULL) + MysteryGiftServer_InitSend(svr, MG_LINKID_RAM_SCRIPT, svr->ramScript, svr->ramScriptSize); + else + MysteryGiftServer_InitSend(svr, MG_LINKID_RAM_SCRIPT, cmd->parameter, cmd->flag); + break; + case SVR_LOAD_CLIENT_SCRIPT: + if (cmd->parameter == NULL) + MysteryGiftServer_InitSend(svr, MG_LINKID_CLIENT_SCRIPT, svr->clientScript, svr->clientScriptSize); + else + MysteryGiftServer_InitSend(svr, MG_LINKID_CLIENT_SCRIPT, cmd->parameter, cmd->flag); + break; + case SVR_LOAD_EREADER_TRAINER: + AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 466); + MysteryGiftServer_InitSend(svr, MG_LINKID_EREADER_TRAINER, cmd->parameter, 188); + break; + case SVR_LOAD_MSG: + MysteryGiftServer_InitSend(svr, MG_LINKID_DYNAMIC_MSG, cmd->parameter, cmd->flag); + break; + case SVR_LOAD_UNK_2: + MysteryGiftServer_InitSend(svr, MG_LINKID_UNK_2, cmd->parameter, cmd->flag); + break; + case SVR_COPY_CARD: + AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 481); + memcpy(svr->card, cmd->parameter, sizeof(*svr->card)); + break; + case SVR_COPY_NEWS: + AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 486); + memcpy(svr->news, cmd->parameter, sizeof(*svr->news)); + break; + case SVR_COPY_STAMP: + AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 491); + svr->stamp = *(u32 *)cmd->parameter; + break; + case SVR_SET_RAM_SCRIPT: + svr->ramScript = cmd->parameter; + svr->ramScriptSize = cmd->flag; + break; + case SVR_SET_CLIENT_SCRIPT: + svr->clientScript = cmd->parameter; + svr->clientScriptSize = cmd->flag; + break; + case SVR_COPY_SAVED_CARD: + AGB_ASSERT_EX(cmd->flag == FALSE && cmd->parameter == NULL, ABSPATH("mevent_server.c"), 506); + memcpy(svr->card, GetSavedWonderCard(), sizeof(*svr->card)); + DisableWonderCardSending(svr->card); + break; + case SVR_COPY_SAVED_NEWS: + AGB_ASSERT_EX(cmd->flag == FALSE && cmd->parameter == NULL, ABSPATH("mevent_server.c"), 512); + memcpy(svr->news, GetSavedWonderNews(), sizeof(*svr->news)); + break; + case SVR_COPY_SAVED_RAM_SCRIPT: + AGB_ASSERT_EX(cmd->flag == FALSE && cmd->parameter == NULL, ABSPATH("mevent_server.c"), 517); + svr->ramScript = GetSavedRamScriptIfValid(); + break; + case SVR_LOAD_UNK_1: + MysteryGiftServer_InitSend(svr, MG_LINKID_UNK_1, cmd->parameter, cmd->flag); + 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) { +// Original GF names +#define mainseqno funcId +#define func_tbl sFuncTable u32 response; AGB_ASSERT_EX(svr->mainseqno < NELEMS(func_tbl), ABSPATH("mevent_server.c"), 546); - response = func_tbl[svr->mainseqno](svr); + response = sFuncTable[svr->funcId](svr); AGB_ASSERT_EX(svr->mainseqno < NELEMS(func_tbl), ABSPATH("mevent_server.c"), 548); return response; +#undef mainseqno +#undef func_tbl } diff --git a/src/union_room_message.c b/src/union_room_message.c index d3c3c6e46..a1368e9fa 100644 --- a/src/union_room_message.c +++ b/src/union_room_message.c @@ -1,6 +1,7 @@ #include "global.h" #include "link_rfu.h" #include "mystery_gift_server.h" +#include "mystery_gift_client.h" #include "constants/union_room.h" ALIGNED(4) const u8 gText_UR_EmptyString[] = _(""); @@ -558,18 +559,18 @@ const u8 *const gTexts_UR_GladToMeetYou[GENDER_COUNT] = { ALIGNED(4) const u8 gText_UR_FinishedCheckingPlayersTrainerCard[] = _("Finished checking {SPECIAL_F7 0x01}'s\nTRAINER CARD.{PAUSE 60}"); ALIGNED(4) static const u8 sText_CanceledReadingCard[] = _("Canceled reading the Card."); -static const struct mevent_client_cmd sClientScript_DynamicError[] = { - CLI_RECEIVE(0x15), - CLI_RECVBUF, - CLI_SENDALL, - CLI_RETURN(0x0e) +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} }; -const struct mevent_server_cmd gServerScript_ClientCanceledCard[] = { - SRV_SEND(0x20, sClientScript_DynamicError), - SRV_WAITSND, - SRV_SENDSTR(0x1b, sText_CanceledReadingCard), - SRV_WAITSND, - SRV_RECV(0x14), - SRV_RETURN(0x09) +const struct MysteryGiftServerCmd gServerScript_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} }; From 76c3b014d8c18e1f09176b17fbe08f6db4f037c6 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Mon, 21 Nov 2022 22:10:41 -0500 Subject: [PATCH 7/8] Sync mystery gift menu, ereader screen --- common_syms/ereader_screen.txt | 1 + common_syms/mystery_gift.txt | 1 - include/ereader_helpers.h | 9 +- include/link.h | 18 +- include/link_rfu.h | 2 - include/mystery_gift.h | 12 - include/mystery_gift_menu.h | 4 +- ld_script.txt | 2 + src/ereader_screen.c | 520 ++++++++++++++++ src/main_menu.c | 2 +- src/mystery_gift.c | 425 ------------- src/mystery_gift_menu.c | 1069 ++++++++++++++++---------------- sym_common.txt | 2 +- 13 files changed, 1068 insertions(+), 999 deletions(-) create mode 100644 common_syms/ereader_screen.txt delete mode 100644 common_syms/mystery_gift.txt create mode 100644 src/ereader_screen.c diff --git a/common_syms/ereader_screen.txt b/common_syms/ereader_screen.txt new file mode 100644 index 000000000..2189eedbc --- /dev/null +++ b/common_syms/ereader_screen.txt @@ -0,0 +1 @@ +gEReaderData diff --git a/common_syms/mystery_gift.txt b/common_syms/mystery_gift.txt deleted file mode 100644 index af4db66e6..000000000 --- a/common_syms/mystery_gift.txt +++ /dev/null @@ -1 +0,0 @@ -sMEventSendToEReaderManager diff --git a/include/ereader_helpers.h b/include/ereader_helpers.h index d6f3d13bb..244d6e2ef 100644 --- a/include/ereader_helpers.h +++ b/include/ereader_helpers.h @@ -14,17 +14,20 @@ enum { #define EREADER_XFER_EXE 1 #define EREADER_XFER_CHK 2 #define EREADER_XFER_SHIFT 0 -#define EREADER_XFER_MASK 3 +#define EREADER_XFER_MASK ((EREADER_XFER_EXE | EREADER_XFER_CHK) << EREADER_XFER_SHIFT) #define EREADER_CANCEL_TIMEOUT 1 #define EREADER_CANCEL_KEY 2 -#define EREADER_CANCEL_MASK 0xC #define EREADER_CANCEL_SHIFT 2 +#define EREADER_CANCEL_TIMEOUT_MASK (EREADER_CANCEL_TIMEOUT << EREADER_CANCEL_SHIFT) +#define EREADER_CANCEL_KEY_MASK (EREADER_CANCEL_KEY << EREADER_CANCEL_SHIFT) +#define EREADER_CANCEL_MASK ((EREADER_CANCEL_TIMEOUT | EREADER_CANCEL_KEY) << EREADER_CANCEL_SHIFT) #define EREADER_CHECKSUM_OK 1 #define EREADER_CHECKSUM_ERR 2 -#define EREADER_CHECKSUM_MASK 0x30 #define EREADER_CHECKSUM_SHIFT 4 +#define EREADER_CHECKSUM_OK_MASK (EREADER_CHECKSUM_OK << EREADER_CHECKSUM_SHIFT) +#define EREADER_CHECKSUM_MASK ((EREADER_CHECKSUM_OK | EREADER_CHECKSUM_ERR) << EREADER_CHECKSUM_SHIFT) void EReaderHelper_SerialCallback(void); void EReaderHelper_Timer3Callback(void); diff --git a/include/link.h b/include/link.h index 6de96da5e..7e5e5ecb0 100644 --- a/include/link.h +++ b/include/link.h @@ -85,12 +85,12 @@ #define LINKCMD_PARTNER_CANCEL_TRADE 0xEECC #define LINKCMD_NONE 0xEFFF -#define LINKTYPE_TRADE 0x1111 // trade -#define LINKTYPE_0x1122 0x1122 // trade +#define LINKTYPE_TRADE 0x1111 +#define LINKTYPE_TRADE_CONNECTING 0x1122 #define LINKTYPE_TRADE_SETUP 0x1133 -#define LINKTYPE_0x1144 0x1144 // trade +#define LINKTYPE_TRADE_DISCONNECTED 0x1144 #define LINKTYPE_BATTLE 0x2211 -#define LINKTYPE_0x2222 0x2222 // unused battle? +#define LINKTYPE_UNUSED_BATTLE 0x2222 // Unused, inferred from gap #define LINKTYPE_SINGLE_BATTLE 0x2233 #define LINKTYPE_DOUBLE_BATTLE 0x2244 #define LINKTYPE_MULTI_BATTLE 0x2255 @@ -100,7 +100,12 @@ #define LINKTYPE_RECORD_MIX_BEFORE 0x3311 #define LINKTYPE_RECORD_MIX_AFTER 0x3322 #define LINKTYPE_BERRY_BLENDER_SETUP 0x4411 +#define LINKTYPE_BERRY_BLENDER 0x4422 +#define LINKTYPE_MYSTERY_EVENT 0x5501 +#define LINKTYPE_EREADER_FRLG 0x5502 +#define LINKTYPE_EREADER_EM 0x5503 #define LINKTYPE_CONTEST_GMODE 0x6601 +#define LINKTYPE_CONTEST_EMODE 0x6602 enum { BLOCK_REQ_SIZE_NONE, // Identical to 200 @@ -110,8 +115,9 @@ enum { BLOCK_REQ_SIZE_40, }; -#define MASTER_HANDSHAKE 0x8FFF -#define SLAVE_HANDSHAKE 0xB9A0 +#define MASTER_HANDSHAKE 0x8FFF +#define SLAVE_HANDSHAKE 0xB9A0 +#define EREADER_HANDSHAKE 0xCCD0 #define IsSendCmdComplete() (gSendCmd[0] == 0) diff --git a/include/link_rfu.h b/include/link_rfu.h index 9610a9682..dbc14ea03 100644 --- a/include/link_rfu.h +++ b/include/link_rfu.h @@ -233,8 +233,6 @@ extern struct RfuGameData gHostRfuGameData; extern u8 gHostRfuUsername[]; extern struct RfuManager gRfu; -void AddTextPrinterToWindow1(const u8 *str); -bool32 PrintMysteryGiftMenuMessage(u8 * cmdPtr, const u8 * src); void LinkRfu_FatalError(void); void MG_DrawCheckerboardPattern(void); void Rfu_SetCloseLinkCallback(void); diff --git a/include/mystery_gift.h b/include/mystery_gift.h index a59b60ec8..c6f4210e2 100644 --- a/include/mystery_gift.h +++ b/include/mystery_gift.h @@ -37,18 +37,6 @@ struct MysteryGiftLinkGameData u8 version; }; -struct MEvent_Str_1 -{ - u16 status; - size_t size; - const void *data; -}; - -struct MEvent_Str_2 -{ - u8 fill_00[0x40]; -}; - struct WonderGraphics { u8 titleTextPal:4; diff --git a/include/mystery_gift_menu.h b/include/mystery_gift_menu.h index 82a47fb5f..84c647c5b 100644 --- a/include/mystery_gift_menu.h +++ b/include/mystery_gift_menu.h @@ -3,9 +3,11 @@ extern bool8 gGiftIsFromEReader; +bool32 PrintMysteryGiftMenuMessage(u8 * cmdPtr, const u8 * src); +void AddTextPrinterToWindow1(const u8 *str); void MainCB_FreeAllBuffersAndReturnToInitTitleScreen(void); void PrintMysteryGiftOrEReaderTopMenu(bool8, bool32); -void c2_mystery_gift(void); +void CB2_InitMysteryGift(void); void CB2_MysteryGiftEReader(void); s8 DoMysteryGiftYesNo(u8 * textState, u16 * windowId, bool8 yesNoBoxPlacement, const u8 * str); void MG_DrawTextBorder(u8 windowId); diff --git a/ld_script.txt b/ld_script.txt index e19fa1ee6..54c794e52 100644 --- a/ld_script.txt +++ b/ld_script.txt @@ -275,6 +275,7 @@ SECTIONS { src/slot_machine.o(.text); src/roamer.o(.text); src/mystery_gift_menu.o(.text); + src/ereader_screen.o(.text); src/mystery_gift.o(.text); src/mystery_gift_link.o(.text); src/mystery_gift_client.o(.text); @@ -568,6 +569,7 @@ SECTIONS { src/slot_machine.o(.rodata); src/roamer.o(.rodata); src/mystery_gift_menu.o(.rodata); + src/ereader_screen.o(.rodata); src/mystery_gift.o(.rodata); src/mystery_gift_link.o(.rodata); src/mystery_gift_client.o(.rodata); diff --git a/src/ereader_screen.c b/src/ereader_screen.c new file mode 100644 index 000000000..060150cbf --- /dev/null +++ b/src/ereader_screen.c @@ -0,0 +1,520 @@ +#include "global.h" +#include "malloc.h" +#include "decompress.h" +#include "ereader_helpers.h" +#include "link.h" +#include "main.h" +#include "mystery_gift_menu.h" +#include "mystery_gift_client.h" +#include "save.h" +#include "sound.h" +#include "sprite.h" +#include "task.h" +#include "strings.h" +#include "util.h" +#include "cereader_tool.h" +#include "help_system.h" +#include "constants/songs.h" + +struct EReaderTaskData +{ + u16 timer; + u16 unused1; + u16 unused2; + u16 unused3; + u8 state; + u8 textState; + u8 unused4; + u8 unused5; + u8 unused6; + u8 unused7; + u8 status; + u8 *unusedBuffer; +}; + +struct EReaderData +{ + u16 status; + size_t size; + const void *data; +}; + +static void Task_EReader(u8); + +struct EReaderData gEReaderData; + +extern const u8 gMultiBootProgram_EReader_Start[]; +extern const u8 gMultiBootProgram_EReader_End[]; + +static void EReader_Load(struct EReaderData *eReader, size_t size, const void *data) +{ + vu16 imeBak = REG_IME; + REG_IME = 0; + gIntrTable[1] = EReaderHelper_SerialCallback; + gIntrTable[2] = EReaderHelper_Timer3Callback; + EReaderHelper_SaveRegsState(); + EReaderHelper_ClearsSendRecvMgr(); + REG_IE |= INTR_FLAG_VCOUNT; + REG_IME = imeBak; + eReader->status = 0; + eReader->size = size; + eReader->data = data; +} + +static void EReader_Reset(struct EReaderData *eReader) +{ + vu16 imeBak = REG_IME; + REG_IME = 0; + EReaderHelper_ClearsSendRecvMgr(); + EReaderHelper_RestoreRegsState(); + RestoreSerialTimer3IntrHandlers(); + REG_IME = imeBak; +} + +// Return values for EReader_Transfer +enum { + TRANSFER_ACTIVE, + TRANSFER_SUCCESS, + TRANSFER_CANCELED, + TRANSFER_TIMEOUT, +}; + +static u8 EReader_Transfer(struct EReaderData *eReader) +{ + u8 transferStatus = TRANSFER_ACTIVE; + eReader->status = EReaderHandleTransfer(TRUE, eReader->size, eReader->data, NULL); + + if ((eReader->status & EREADER_XFER_MASK) == 0 && eReader->status & EREADER_CHECKSUM_OK_MASK) + transferStatus = TRANSFER_SUCCESS; + + if (eReader->status & EREADER_CANCEL_KEY_MASK) + transferStatus = TRANSFER_CANCELED; + + if (eReader->status & EREADER_CANCEL_TIMEOUT_MASK) + transferStatus = TRANSFER_TIMEOUT; + + gShouldAdvanceLinkState = 0; + return transferStatus; +} + +static void OpenEReaderLink(void) +{ + memset(gDecompressionBuffer, 0, 0x2000); + gLinkType = LINKTYPE_EREADER_FRLG; + OpenLink(); + SetSuppressLinkErrorMessage(TRUE); +} + +static bool32 ValidateEReaderConnection(void) +{ + vu16 imeBak = REG_IME; + u16 handshakes[MAX_LINK_PLAYERS]; + + REG_IME = 0; + *(u64 *)handshakes = *(u64 *)gLink.tempRecvBuffer; + REG_IME = imeBak; + + // Validate that we are player 1, the EReader is player 2, + // and that players 3 and 4 are empty. + if (handshakes[0] == SLAVE_HANDSHAKE + && handshakes[1] == EREADER_HANDSHAKE + && handshakes[2] == 0xFFFF + && handshakes[3] == 0xFFFF) + return TRUE; + return FALSE; +} + +static bool32 IsEReaderConnectionSane(void) +{ + if (IsLinkMaster() && GetLinkPlayerCount_2() == 2) + return TRUE; + return FALSE; +} + +// States for TryReceiveCard +enum { + RECV_STATE_INIT, + RECV_STATE_WAIT_START, + RECV_STATE_START, + RECV_STATE_EXCHANGE, + RECV_STATE_START_DISCONNECT, + RECV_STATE_WAIT_DISCONNECT, +}; + +// Return values for TryReceiveCard +enum { + RECV_ACTIVE, + RECV_CANCELED, + RECV_SUCCESS, + RECV_ERROR, + RECV_DISCONNECTED, + RECV_TIMEOUT, +}; + +static u32 TryReceiveCard(u8 * state, u16 * timer) +{ + if ((*state == RECV_STATE_EXCHANGE + || *state == RECV_STATE_START_DISCONNECT + || *state == RECV_STATE_WAIT_DISCONNECT) + && HasLinkErrorOccurred()) + { + // Return error status if an error occurs + // during the link exchange. + *state = 0; + return RECV_ERROR; + } + + switch (*state) + { + case RECV_STATE_INIT: + if (IsLinkMaster() && GetLinkPlayerCount_2() > 1) + { + *state = RECV_STATE_WAIT_START; + } + else if (JOY_NEW(B_BUTTON)) + { + *state = 0; + return RECV_CANCELED; + } + break; + case RECV_STATE_WAIT_START: + if (++(*timer) > 5) + { + *timer = 0; + *state = RECV_STATE_START; + } + break; + case RECV_STATE_START: + if (GetLinkPlayerCount_2() == 2) + { + PlaySE(SE_DING_DONG); + CheckShouldAdvanceLinkState(); + *timer = 0; + *state = RECV_STATE_EXCHANGE; + } + else if (JOY_NEW(B_BUTTON)) + { + *state = 0; + return RECV_CANCELED; + } + break; + case RECV_STATE_EXCHANGE: + if (++(*timer) > 30) + { + *state = 0; + return RECV_TIMEOUT; + } + + if (IsLinkConnectionEstablished()) + { + if (gReceivedRemoteLinkPlayers) + { + if (IsLinkPlayerDataExchangeComplete()) + { + *state = 0; + return RECV_SUCCESS; + } + else + *state = RECV_STATE_START_DISCONNECT; + } + else + *state = RECV_STATE_EXCHANGE; + } + break; + case RECV_STATE_START_DISCONNECT: + SetCloseLinkCallbackAndType(0); + *state = RECV_STATE_WAIT_DISCONNECT; + break; + case RECV_STATE_WAIT_DISCONNECT: + if (!gReceivedRemoteLinkPlayers) + { + *state = 0; + return RECV_DISCONNECTED; + } + break; + } + return RECV_ACTIVE; +} + +void CreateEReaderTask(void) +{ + u8 taskId = CreateTask(Task_EReader, 0); + struct EReaderTaskData *data = (struct EReaderTaskData *)gTasks[taskId].data; + data->state = 0; + data->textState = 0; + data->unused4 = 0; + data->unused5 = 0; + data->unused6 = 0; + data->unused7 = 0; + data->timer = 0; + data->unused1 = 0; + data->unused2 = 0; + data->unused3 = 0; + data->status = 0; + data->unusedBuffer = AllocZeroed(CLIENT_MAX_MSG_SIZE); +} + +static void ResetTimer(u16 *timer) +{ + *timer = 0; +} + +static bool32 UpdateTimer(u16 * timer, u16 time) +{ + if (++(*timer) > time) + { + // Timer has finished + *timer = 0; + return TRUE; + } + return FALSE; +} + +// States for Task_EReader +enum { + ER_STATE_START, + ER_STATE_INIT_LINK, + ER_STATE_INIT_LINK_WAIT, + ER_STATE_INIT_LINK_CHECK, + ER_STATE_MSG_SELECT_CONNECT, + ER_STATE_MSG_SELECT_CONNECT_WAIT, + ER_STATE_TRY_LINK, + ER_STATE_INCORRECT_LINK, + ER_STATE_CONNECTING, + ER_STATE_TRANSFER, + ER_STATE_TRANSFER_END, + ER_STATE_TRANSFER_SUCCESS, + ER_STATE_LOAD_CARD_START, + ER_STATE_LOAD_CARD, + ER_STATE_WAIT_RECV_CARD, + ER_STATE_VALIDATE_CARD, + ER_STATE_WAIT_DISCONNECT, + ER_STATE_SAVE, + ER_STATE_SUCCESS_MSG, + ER_STATE_SUCCESS_END, + ER_STATE_LINK_ERROR, + ER_STATE_LINK_ERROR_TRY_AGAIN, + ER_STATE_SAVE_FAILED, + ER_STATE_CANCELED_CARD_READ, + ER_STATE_UNUSED_1, + ER_STATE_UNUSED_2, + ER_STATE_END, +}; + +static void Task_EReader(u8 taskId) +{ + struct EReaderTaskData *data = (struct EReaderTaskData *)gTasks[taskId].data; + switch (data->state) + { + case ER_STATE_START: + if (PrintMysteryGiftMenuMessage(&data->textState, gJPText_ReceiveMysteryGiftWithEReader)) + data->state = ER_STATE_INIT_LINK; + break; + case ER_STATE_INIT_LINK: + OpenEReaderLink(); + ResetTimer(&data->timer); + data->state = ER_STATE_INIT_LINK_WAIT; + break; + case ER_STATE_INIT_LINK_WAIT: + if (UpdateTimer(&data->timer, 10)) + data->state = ER_STATE_INIT_LINK_CHECK; + break; + case ER_STATE_INIT_LINK_CHECK: + if (!IsEReaderConnectionSane()) + { + CloseLink(); + data->state = ER_STATE_MSG_SELECT_CONNECT; + } + else + data->state = ER_STATE_LOAD_CARD; + break; + case ER_STATE_MSG_SELECT_CONNECT: + if (PrintMysteryGiftMenuMessage(&data->textState, gJPText_SelectConnectFromEReaderMenu)) + { + AddTextPrinterToWindow1(gJPText_SelectConnectWithGBA); + ResetTimer(&data->timer); + data->state = ER_STATE_MSG_SELECT_CONNECT_WAIT; + } + break; + case ER_STATE_MSG_SELECT_CONNECT_WAIT: + if (UpdateTimer(&data->timer, 90)) + { + OpenEReaderLink(); + data->state = ER_STATE_TRY_LINK; + } + else if (JOY_NEW(B_BUTTON)) + { + ResetTimer(&data->timer); + PlaySE(SE_SELECT); + data->state = ER_STATE_CANCELED_CARD_READ; + } + break; + case ER_STATE_TRY_LINK: + if (JOY_NEW(B_BUTTON)) + { + // Canceled + PlaySE(SE_SELECT); + CloseLink(); + ResetTimer(&data->timer); + data->state = ER_STATE_CANCELED_CARD_READ; + } + else if (GetLinkPlayerCount_2() > 1) + { + ResetTimer(&data->timer); + CloseLink(); + data->state = ER_STATE_INCORRECT_LINK; + } + else if (ValidateEReaderConnection()) + { + // Successful connection + PlaySE(SE_SELECT); + CloseLink(); + ResetTimer(&data->timer); + data->state = ER_STATE_CONNECTING; + } + else if (UpdateTimer(&data->timer, 10)) + { + // Retry connection + CloseLink(); + OpenEReaderLink(); + ResetTimer(&data->timer); + } + break; + case ER_STATE_INCORRECT_LINK: + if (PrintMysteryGiftMenuMessage(&data->textState, gJPText_LinkIsIncorrect)) + data->state = ER_STATE_MSG_SELECT_CONNECT; + break; + case ER_STATE_CONNECTING: + AddTextPrinterToWindow1(gJPText_Connecting); + EReader_Load(&gEReaderData, gMultiBootProgram_EReader_End - gMultiBootProgram_EReader_Start, gMultiBootProgram_EReader_Start); + data->state = ER_STATE_TRANSFER; + break; + case ER_STATE_TRANSFER: + data->status = EReader_Transfer(&gEReaderData); + if (data->status != TRANSFER_ACTIVE) + data->state = ER_STATE_TRANSFER_END; + break; + case ER_STATE_TRANSFER_END: + EReader_Reset(&gEReaderData); + if (data->status == TRANSFER_TIMEOUT) + { + data->state = ER_STATE_LINK_ERROR; + } + else if (data->status == TRANSFER_SUCCESS) + { + ResetTimer(&data->timer); + AddTextPrinterToWindow1(gJPText_PleaseWaitAMoment); + data->state = ER_STATE_TRANSFER_SUCCESS; + } + else // TRANSFER_CANCELED + { + data->state = ER_STATE_START; + } + break; + case ER_STATE_TRANSFER_SUCCESS: + if (UpdateTimer(&data->timer, 840)) + data->state = ER_STATE_LOAD_CARD_START; + break; + case ER_STATE_LOAD_CARD_START: + OpenEReaderLink(); + AddTextPrinterToWindow1(gJPText_AllowEReaderToLoadCard); + data->state = ER_STATE_LOAD_CARD; + break; + case ER_STATE_LOAD_CARD: + switch (TryReceiveCard(&data->textState, &data->timer)) + { + case RECV_ACTIVE: + // Running + break; + case RECV_SUCCESS: + AddTextPrinterToWindow1(gJPText_Connecting); + data->state = ER_STATE_WAIT_RECV_CARD; + break; + case RECV_CANCELED: + PlaySE(SE_SELECT); + CloseLink(); + data->state = ER_STATE_CANCELED_CARD_READ; + break; + case RECV_TIMEOUT: + CloseLink(); + data->state = ER_STATE_LINK_ERROR_TRY_AGAIN; + break; + case RECV_ERROR: + case RECV_DISCONNECTED: + CloseLink(); + data->state = ER_STATE_LINK_ERROR; + break; + } + break; + case ER_STATE_WAIT_RECV_CARD: + if (HasLinkErrorOccurred()) + { + CloseLink(); + data->state = ER_STATE_LINK_ERROR; + } + else if (GetBlockReceivedStatus()) + { + ResetBlockReceivedFlags(); + data->state = ER_STATE_VALIDATE_CARD; + } + break; + case ER_STATE_VALIDATE_CARD: + data->status = ValidateTrainerTowerData((struct EReaderTrainerTowerSet *)gDecompressionBuffer); + SetCloseLinkCallbackAndType(data->status); + data->state = ER_STATE_WAIT_DISCONNECT; + break; + case ER_STATE_WAIT_DISCONNECT: + if (!gReceivedRemoteLinkPlayers) + { + if (data->status == TRUE) // Was data valid? + data->state = ER_STATE_SAVE; + else + data->state = ER_STATE_LINK_ERROR; + } + break; + case ER_STATE_SAVE: + if (CEReaderTool_SaveTrainerTower((struct EReaderTrainerTowerSet *)gDecompressionBuffer)) + { + AddTextPrinterToWindow1(gJPText_ConnectionComplete); + ResetTimer(&data->timer); + data->state = ER_STATE_SUCCESS_MSG; + } + else + data->state = ER_STATE_SAVE_FAILED; + break; + case ER_STATE_SUCCESS_MSG: + if (UpdateTimer(&data->timer, 120)) + { + AddTextPrinterToWindow1(gJPText_NewTrainerHasComeToSevii); + PlayFanfare(MUS_OBTAIN_ITEM); + data->state = ER_STATE_SUCCESS_END; + } + break; + case ER_STATE_SUCCESS_END: + if (IsFanfareTaskInactive() && JOY_NEW(A_BUTTON | B_BUTTON)) + data->state = ER_STATE_END; + break; + case ER_STATE_CANCELED_CARD_READ: + if (PrintMysteryGiftMenuMessage(&data->textState, gJPText_CardReadingHasBeenHalted)) + data->state = ER_STATE_END; + break; + case ER_STATE_LINK_ERROR: + if (PrintMysteryGiftMenuMessage(&data->textState, gJPText_ConnectionErrorCheckLink)) + data->state = ER_STATE_START; + break; + case ER_STATE_LINK_ERROR_TRY_AGAIN: + if (PrintMysteryGiftMenuMessage(&data->textState, gJPText_ConnectionErrorTryAgain)) + data->state = ER_STATE_START; + break; + case ER_STATE_SAVE_FAILED: + if (PrintMysteryGiftMenuMessage(&data->textState, gJPText_WriteErrorUnableToSaveData)) + data->state = ER_STATE_START; + break; + case ER_STATE_END: + HelpSystem_Enable(); + Free(data->unusedBuffer); + DestroyTask(taskId); + SetMainCallback2(MainCB_FreeAllBuffersAndReturnToInitTitleScreen); + break; + } +} diff --git a/src/main_menu.c b/src/main_menu.c index 011bc2308..94fcb7ac6 100644 --- a/src/main_menu.c +++ b/src/main_menu.c @@ -481,7 +481,7 @@ static void Task_ExecuteMainMenuSelection(u8 taskId) TrySetUpQuestLogScenes_ElseContinueFromSave(taskId); break; case MAIN_MENU_MYSTERYGIFT: - SetMainCallback2(c2_mystery_gift); + SetMainCallback2(CB2_InitMysteryGift); HelpSystem_Disable(); FreeAllWindowBuffers(); DestroyTask(taskId); diff --git a/src/mystery_gift.c b/src/mystery_gift.c index 8db1ee5e0..b02d949f2 100644 --- a/src/mystery_gift.c +++ b/src/mystery_gift.c @@ -3,17 +3,14 @@ #include "constants/songs.h" #include "easy_chat.h" #include "task.h" -#include "decompress.h" #include "link.h" #include "link_rfu.h" -#include "ereader_helpers.h" #include "util.h" #include "script.h" #include "event_data.h" #include "battle_tower.h" #include "new_game.h" #include "wonder_news.h" -#include "cereader_tool.h" #include "mystery_gift_menu.h" #include "help_system.h" #include "mystery_gift.h" @@ -21,23 +18,6 @@ #define CALC_CRC(data) CalcCRC16WithTable((void *)&(data), sizeof(data)) -struct MEventTaskData1 -{ - u16 stateAdvanceDelay; - u16 t02; - u16 t04; - u16 t06; - u8 state; - u8 textOrReceiveState; - u8 t0A; - u8 t0B; - u8 t0C; - u8 t0D; - u8 initialSendResult; - struct MEvent_Str_2 *t10; -}; - -static void Task_EReaderComm(u8 taskId); static bool32 ValidateWonderNews(const struct WonderNews * src); static void ClearSavedWonderNews(void); static void ClearSavedWonderNewsMetadata(void); @@ -47,9 +27,6 @@ static void ClearSavedWonderCardMetadata(void); static void IncrementCardStatForNewTrainer(u32 eventId, u32 trainerId, u32 *idsList, s32 count); static void ClearSavedTrainerIds(void); -extern const u8 gMultiBootProgram_EReader_Start[]; -extern const u8 gMultiBootProgram_EReader_End[]; - static const u16 sReceivedGiftFlags[] = { FLAG_RECEIVED_AURORA_TICKET, FLAG_RECEIVED_MYSTIC_TICKET, @@ -73,410 +50,8 @@ static const u16 sReceivedGiftFlags[] = { FLAG_WONDER_CARD_UNUSED_17 }; -struct MEvent_Str_1 sMEventSendToEReaderManager; - static EWRAM_DATA bool32 sStatsEnabled = FALSE; -void SendUnknownSerialData_Init(struct MEvent_Str_1 *mgr, size_t size, const void *data) -{ - vu16 imeBak = REG_IME; - REG_IME = 0; - gIntrTable[1] = EReaderHelper_SerialCallback; - gIntrTable[2] = EReaderHelper_Timer3Callback; - EReaderHelper_SaveRegsState(); - EReaderHelper_ClearsSendRecvMgr(); - REG_IE |= INTR_FLAG_VCOUNT; - REG_IME = imeBak; - mgr->status = 0; - mgr->size = size; - mgr->data = data; -} - -void SendUnknownSerialData_Teardown(struct MEvent_Str_1 *unused) -{ - vu16 imeBak = REG_IME; - REG_IME = 0; - EReaderHelper_ClearsSendRecvMgr(); - EReaderHelper_RestoreRegsState(); - RestoreSerialTimer3IntrHandlers(); - REG_IME = imeBak; -} - -u8 SendUnknownSerialData_Run(struct MEvent_Str_1 *mgr) -{ - u8 resp = 0; - mgr->status = EReaderHandleTransfer(1, mgr->size, mgr->data, 0); - if ((mgr->status & 0x13) == 0x10) // checksum OK and xfer off - resp = 1; - if (mgr->status & 8) // cancelled by player - resp = 2; - if (mgr->status & 4) // timed out - resp = 3; - gShouldAdvanceLinkState = 0; - return resp; -} - -static void ResetTTDataBuffer(void) -{ - memset(gDecompressionBuffer, 0, 0x2000); - gLinkType = 0x5502; - OpenLink(); - SetSuppressLinkErrorMessage(TRUE); -} - -bool32 sub_81436EC(void) -{ - vu16 imeBak = REG_IME; - u16 data[4]; - REG_IME = 0; - *(u64 *)data = *(u64 *)gLink.tempRecvBuffer; - REG_IME = imeBak; - if ( data[0] == 0xB9A0 - && data[1] == 0xCCD0 - && data[2] == 0xFFFF - && data[3] == 0xFFFF - ) - return TRUE; - return FALSE; -} - -static bool32 IsEReaderConnectionSane(void) -{ - if (IsLinkMaster() && GetLinkPlayerCount_2() == 2) - return TRUE; - return FALSE; -} - -static u32 EReaderReceive(u8 * state_p, u16 * receiveDelay) -{ - if ((*state_p == 3 || *state_p == 4 || *state_p == 5) && HasLinkErrorOccurred()) - { - *state_p = 0; - return 3; - } - switch (*state_p) - { - case 0: - if (IsLinkMaster() && GetLinkPlayerCount_2() > 1) - { - *state_p = 1; - ; - } - else if (JOY_NEW(B_BUTTON)) - { - *state_p = 0; - return 1; - } - break; - case 1: - if (++(*receiveDelay) > 5) - { - *receiveDelay = 0; - *state_p = 2; - } - break; - case 2: - if (GetLinkPlayerCount_2() == 2) - { - PlaySE(SE_DING_DONG); - CheckShouldAdvanceLinkState(); - *receiveDelay = 0; - *state_p = 3; - } - else if (JOY_NEW(B_BUTTON)) - { - *state_p = 0; - return 1; - } - break; - case 3: - if (++(*receiveDelay) > 30) - { - *state_p = 0; - return 5; - } - else if (IsLinkConnectionEstablished()) - { - if (gReceivedRemoteLinkPlayers) - { - if (IsLinkPlayerDataExchangeComplete()) - { - *state_p = 0; - return 2; - } - else - *state_p = 4; - } - else - *state_p = 3; - } - break; - case 4: - SetCloseLinkCallbackAndType(0); - *state_p = 5; - break; - case 5: - if (!gReceivedRemoteLinkPlayers) - { - *state_p = 0; - return 4; - } - break; - } - return 0; -} - -void task_add_00_ereader(void) -{ - u8 taskId = CreateTask(Task_EReaderComm, 0); - struct MEventTaskData1 *data = (struct MEventTaskData1 *)gTasks[taskId].data; - data->state = 0; - data->textOrReceiveState = 0; - data->t0A = 0; - data->t0B = 0; - data->t0C = 0; - data->t0D = 0; - data->stateAdvanceDelay = 0; - data->t02 = 0; - data->t04 = 0; - data->t06 = 0; - data->initialSendResult = 0; - data->t10 = AllocZeroed(sizeof(struct MEvent_Str_2)); -} - -static void ResetDelayTimer(u16 *a0) -{ - *a0 = 0; -} - -static bool32 AdvanceDelayTimerCheckTimeout(u16 * a0, u16 a1) -{ - if (++(*a0) > a1) - { - *a0 = 0; - return TRUE; - } - return FALSE; -} - -static void Task_EReaderComm(u8 taskId) -{ - struct MEventTaskData1 *data = (struct MEventTaskData1 *)gTasks[taskId].data; - switch (data->state) - { - case 0: - if (PrintMysteryGiftMenuMessage(&data->textOrReceiveState, gJPText_ReceiveMysteryGiftWithEReader)) - data->state = 1; - break; - case 1: - ResetTTDataBuffer(); - ResetDelayTimer(&data->stateAdvanceDelay); - data->state = 2; - break; - case 2: - if (AdvanceDelayTimerCheckTimeout(&data->stateAdvanceDelay, 10)) - data->state = 3; - break; - case 3: - if (!IsEReaderConnectionSane()) - { - CloseLink(); - data->state = 4; - } - else - data->state = 13; - break; - case 4: - if (PrintMysteryGiftMenuMessage(&data->textOrReceiveState, gJPText_SelectConnectFromEReaderMenu)) - { - AddTextPrinterToWindow1(gJPText_SelectConnectWithGBA); - ResetDelayTimer(&data->stateAdvanceDelay); - data->state = 5; - } - break; - case 5: - if (AdvanceDelayTimerCheckTimeout(&data->stateAdvanceDelay, 90)) - { - ResetTTDataBuffer(); - data->state = 6; - } - else if (JOY_NEW(B_BUTTON)) - { - ResetDelayTimer(&data->stateAdvanceDelay); - PlaySE(SE_SELECT); - data->state = 23; - } - break; - case 6: - if (JOY_NEW(B_BUTTON)) - { - PlaySE(SE_SELECT); - CloseLink(); - ResetDelayTimer(&data->stateAdvanceDelay); - data->state = 23; - } - else if (GetLinkPlayerCount_2() > 1) - { - ResetDelayTimer(&data->stateAdvanceDelay); - CloseLink(); - data->state = 7; - } - else if (sub_81436EC()) - { - PlaySE(SE_SELECT); - CloseLink(); - ResetDelayTimer(&data->stateAdvanceDelay); - data->state = 8; - } - else if (AdvanceDelayTimerCheckTimeout(&data->stateAdvanceDelay, 10)) - { - CloseLink(); - ResetTTDataBuffer(); - ResetDelayTimer(&data->stateAdvanceDelay); - } - break; - case 7: - if (PrintMysteryGiftMenuMessage(&data->textOrReceiveState, gJPText_LinkIsIncorrect)) - data->state = 4; - break; - case 8: - AddTextPrinterToWindow1(gJPText_Connecting); - SendUnknownSerialData_Init(&sMEventSendToEReaderManager, gMultiBootProgram_EReader_End - gMultiBootProgram_EReader_Start, gMultiBootProgram_EReader_Start); - data->state = 9; - break; - case 9: - data->initialSendResult = SendUnknownSerialData_Run(&sMEventSendToEReaderManager); - if (data->initialSendResult != 0) - data->state = 10; - break; - case 10: - SendUnknownSerialData_Teardown(&sMEventSendToEReaderManager); - if (data->initialSendResult == 3) - // Error - data->state = 20; - else if (data->initialSendResult == 1) - { - // OK - ResetDelayTimer(&data->stateAdvanceDelay); - AddTextPrinterToWindow1(gJPText_PleaseWaitAMoment); - data->state = 11; - } - else - // Try again - data->state = 0; - break; - case 11: - if (AdvanceDelayTimerCheckTimeout(&data->stateAdvanceDelay, 840)) - data->state = 12; - break; - case 12: - ResetTTDataBuffer(); - AddTextPrinterToWindow1(gJPText_AllowEReaderToLoadCard); - data->state = 13; - break; - case 13: - switch (EReaderReceive(&data->textOrReceiveState, &data->stateAdvanceDelay)) - { - case 0: - // Running - break; - case 2: - // Done - AddTextPrinterToWindow1(gJPText_Connecting); - data->state = 14; - break; - case 1: - // Cancelled - PlaySE(SE_SELECT); - CloseLink(); - data->state = 23; - break; - case 5: - // Error Try Again - CloseLink(); - data->state = 21; - break; - case 3: - case 4: - // Error CheckLink - CloseLink(); - data->state = 20; - break; - } - break; - case 14: - if (HasLinkErrorOccurred()) - { - CloseLink(); - data->state = 20; - } - else if (GetBlockReceivedStatus()) - { - ResetBlockReceivedFlags(); - data->state = 15; - } - break; - case 15: - data->initialSendResult = ValidateTrainerTowerData((struct EReaderTrainerTowerSet *)gDecompressionBuffer); - SetCloseLinkCallbackAndType(data->initialSendResult); - data->state = 16; - break; - case 16: - if (!gReceivedRemoteLinkPlayers) - { - if (data->initialSendResult == 1) - data->state = 17; - else - data->state = 20; - } - break; - case 17: - if (CEReaderTool_SaveTrainerTower((struct EReaderTrainerTowerSet *)gDecompressionBuffer)) - { - AddTextPrinterToWindow1(gJPText_ConnectionComplete); - ResetDelayTimer(&data->stateAdvanceDelay); - data->state = 18; - } - else - data->state = 22; - break; - case 18: - if (AdvanceDelayTimerCheckTimeout(&data->stateAdvanceDelay, 120)) - { - AddTextPrinterToWindow1(gJPText_NewTrainerHasComeToSevii); - PlayFanfare(MUS_OBTAIN_ITEM); - data->state = 19; - } - break; - case 19: - if (IsFanfareTaskInactive() && JOY_NEW(A_BUTTON | B_BUTTON)) - data->state = 26; - break; - case 23: - if (PrintMysteryGiftMenuMessage(&data->textOrReceiveState, gJPText_CardReadingHasBeenHalted)) - data->state = 26; - break; - case 20: - if (PrintMysteryGiftMenuMessage(&data->textOrReceiveState, gJPText_ConnectionErrorCheckLink)) - data->state = 0; - break; - case 21: - if (PrintMysteryGiftMenuMessage(&data->textOrReceiveState, gJPText_ConnectionErrorTryAgain)) - data->state = 0; - break; - case 22: - if (PrintMysteryGiftMenuMessage(&data->textOrReceiveState, gJPText_WriteErrorUnableToSaveData)) - data->state = 0; - break; - case 26: - HelpSystem_Enable(); - Free(data->t10); - DestroyTask(taskId); - SetMainCallback2(MainCB_FreeAllBuffersAndReturnToInitTitleScreen); - break; - } -} - void ClearMysteryGift(void) { CpuFill32(0, &gSaveBlock1Ptr->mysteryGift, sizeof(gSaveBlock1Ptr->mysteryGift)); diff --git a/src/mystery_gift_menu.c b/src/mystery_gift_menu.c index a06b93ba3..09c1b9378 100644 --- a/src/mystery_gift_menu.c +++ b/src/mystery_gift_menu.c @@ -18,36 +18,38 @@ #include "wonder_news.h" #include "help_system.h" #include "strings.h" +#include "decompress.h" +#include "constants/cable_club.h" #include "constants/songs.h" #include "constants/union_room.h" EWRAM_DATA u8 sDownArrowCounterAndYCoordIdx[8] = {}; EWRAM_DATA bool8 gGiftIsFromEReader = FALSE; -void task_add_00_mystery_gift(void); -void task00_mystery_gift(u8 taskId); -void task_add_00_ereader(void); +static void CreateMysteryGiftTask(void); +static void Task_MysteryGift(u8 taskId); +extern void CreateEReaderTask(void); -const u16 gUnkTextboxBorderPal[] = INCBIN_U16("graphics/interface/unk_textbox_border.gbapal"); -const u32 gUnkTextboxBorderGfx[] = INCBIN_U32("graphics/interface/unk_textbox_border.4bpp.lz"); +static const u16 sTextboxBorder_Pal[] = INCBIN_U16("graphics/interface/unk_textbox_border.gbapal"); +static const u32 sTextboxBorder_Gfx[] = INCBIN_U32("graphics/interface/unk_textbox_border.4bpp.lz"); 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 IsCardOrNews; - u8 source; - u8 prevPromptWindowId; - u8 * buffer; + u8 unused4; + u8 unused5; + bool8 isWonderNews; + bool8 sourceIsFriend; + u8 msgId; + u8 * clientMsg; }; -const struct BgTemplate sBGTemplates[] = { +static const struct BgTemplate sBGTemplates[] = { { .bg = 0, .charBaseIndex = 2, @@ -83,7 +85,7 @@ const struct BgTemplate sBGTemplates[] = { } }; -const struct WindowTemplate sMainWindows[] = { +static const struct WindowTemplate sMainWindows[] = { { .bg = 0x00, .tilemapLeft = 0x00, @@ -108,12 +110,11 @@ const struct WindowTemplate sMainWindows[] = { .height = 0x05, .paletteNum = 0x0d, .baseBlock = 0x004f - }, { - 0xFF - } + }, + DUMMY_WIN_TEMPLATE }; -const struct WindowTemplate sWindowTemplate_PromptYesOrNo_Width28 = { +static const struct WindowTemplate sWindowTemplate_YesNoMsg_Wide = { .bg = 0x00, .tilemapLeft = 0x01, .tilemapTop = 0x0f, @@ -123,7 +124,7 @@ const struct WindowTemplate sWindowTemplate_PromptYesOrNo_Width28 = { .baseBlock = 0x00e5 }; -const struct WindowTemplate sWindowTemplate_PromptYesOrNo_Width20 = { +static const struct WindowTemplate sWindowTemplate_YesNoMsg = { .bg = 0x00, .tilemapLeft = 0x01, .tilemapTop = 0x0f, @@ -133,7 +134,7 @@ const struct WindowTemplate sWindowTemplate_PromptYesOrNo_Width20 = { .baseBlock = 0x00e5 }; -const struct WindowTemplate sMysteryGiftMenuWindowTemplate = { +static const struct WindowTemplate sWindowTemplate_GiftSelect = { .bg = 0x00, .tilemapLeft = 0x01, .tilemapTop = 0x0f, @@ -143,7 +144,7 @@ const struct WindowTemplate sMysteryGiftMenuWindowTemplate = { .baseBlock = 0x00e5 }; -const struct WindowTemplate sWindowTemplate_ThreeOptions = { +static const struct WindowTemplate sWindowTemplate_ThreeOptions = { .bg = 0x00, .tilemapLeft = 0x08, .tilemapTop = 0x05, @@ -153,7 +154,7 @@ const struct WindowTemplate sWindowTemplate_ThreeOptions = { .baseBlock = 0x0155 }; -const struct WindowTemplate sWindowTemplate_YesNoBox = { +static const struct WindowTemplate sWindowTemplate_YesNoBox = { .bg = 0x00, .tilemapLeft = 0x17, .tilemapTop = 0x0f, @@ -163,7 +164,7 @@ const struct WindowTemplate sWindowTemplate_YesNoBox = { .baseBlock = 0x0155 }; -const struct WindowTemplate sWindowTemplate_7by8 = { +static const struct WindowTemplate sWindowTemplate_GiftSelect_3Options = { .bg = 0x00, .tilemapLeft = 0x16, .tilemapTop = 0x0c, @@ -173,7 +174,7 @@ const struct WindowTemplate sWindowTemplate_7by8 = { .baseBlock = 0x0155 }; -const struct WindowTemplate sWindowTemplate_7by6 = { +static const struct WindowTemplate sWindowTemplate_GiftSelect_2Options = { .bg = 0x00, .tilemapLeft = 0x16, .tilemapTop = 0x0e, @@ -183,7 +184,7 @@ const struct WindowTemplate sWindowTemplate_7by6 = { .baseBlock = 0x0155 }; -const struct WindowTemplate sWindowTemplate_7by4 = { +static const struct WindowTemplate sWindowTemplate_GiftSelect_1Option = { .bg = 0x00, .tilemapLeft = 0x16, .tilemapTop = 0x0f, @@ -193,19 +194,19 @@ const struct WindowTemplate sWindowTemplate_7by4 = { .baseBlock = 0x0155 }; -const struct ListMenuItem sListMenuItems_CardsOrNews[] = { +static const struct ListMenuItem sListMenuItems_CardsOrNews[] = { { gText_WonderCards, 0 }, { gText_WonderNews, 1 }, - { gText_Exit3, -2 } + { gText_Exit3, LIST_CANCEL } }; -const struct ListMenuItem sListMenuItems_WirelessOrFriend[] = { +static const struct ListMenuItem sListMenuItems_WirelessOrFriend[] = { { gText_WirelessCommunication, 0 }, { gText_Friend2, 1 }, - { gFameCheckerText_Cancel, -2 } + { gFameCheckerText_Cancel, LIST_CANCEL } }; -const struct ListMenuTemplate sListMenuTemplate_ThreeOptions = { +static const struct ListMenuTemplate sListMenuTemplate_ThreeOptions = { .items = NULL, .moveCursorFunc = ListMenuDefaultCursorMoveFunc, .itemPrintFunc = NULL, @@ -226,31 +227,31 @@ const struct ListMenuTemplate sListMenuTemplate_ThreeOptions = { .cursorKind = 0 }; -const struct ListMenuItem sListMenuItems_ReceiveSendToss[] = { +static const struct ListMenuItem sListMenuItems_ReceiveSendToss[] = { { gText_Receive, 0 }, { gText_Send, 1 }, { gText_Toss, 2 }, - { gFameCheckerText_Cancel, -2 } + { gFameCheckerText_Cancel, LIST_CANCEL } }; -const struct ListMenuItem sListMenuItems_ReceiveToss[] = { +static const struct ListMenuItem sListMenuItems_ReceiveToss[] = { { gText_Receive, 0 }, { gText_Toss, 2 }, - { gFameCheckerText_Cancel, -2 } + { gFameCheckerText_Cancel, LIST_CANCEL } }; -const struct ListMenuItem sListMenuItems_ReceiveSend[] = { +static const struct ListMenuItem sListMenuItems_ReceiveSend[] = { { gText_Receive, 0 }, { gText_Send, 1 }, - { gFameCheckerText_Cancel, -2 } + { gFameCheckerText_Cancel, LIST_CANCEL } }; -const struct ListMenuItem sListMenuItems_Receive[] = { +static const struct ListMenuItem sListMenuItems_Receive[] = { { gText_Receive, 0 }, - { gFameCheckerText_Cancel, -2 } + { gFameCheckerText_Cancel, LIST_CANCEL } }; -const struct ListMenuTemplate sListMenu_ReceiveSendToss = { +static const struct ListMenuTemplate sListMenu_ReceiveSendToss = { .items = sListMenuItems_ReceiveSendToss, .moveCursorFunc = ListMenuDefaultCursorMoveFunc, .itemPrintFunc = NULL, @@ -271,7 +272,7 @@ const struct ListMenuTemplate sListMenu_ReceiveSendToss = { .cursorKind = 0 }; -const struct ListMenuTemplate sListMenu_ReceiveToss = { +static const struct ListMenuTemplate sListMenu_ReceiveToss = { .items = sListMenuItems_ReceiveToss, .moveCursorFunc = ListMenuDefaultCursorMoveFunc, .itemPrintFunc = NULL, @@ -292,7 +293,7 @@ const struct ListMenuTemplate sListMenu_ReceiveToss = { .cursorKind = 0 }; -const struct ListMenuTemplate sListMenu_ReceiveSend = { +static const struct ListMenuTemplate sListMenu_ReceiveSend = { .items = sListMenuItems_ReceiveSend, .moveCursorFunc = ListMenuDefaultCursorMoveFunc, .itemPrintFunc = NULL, @@ -313,7 +314,7 @@ const struct ListMenuTemplate sListMenu_ReceiveSend = { .cursorKind = 0 }; -const struct ListMenuTemplate sListMenu_Receive = { +static const struct ListMenuTemplate sListMenu_Receive = { .items = sListMenuItems_Receive, .moveCursorFunc = ListMenuDefaultCursorMoveFunc, .itemPrintFunc = NULL, @@ -341,14 +342,14 @@ static const u8 *const sUnusedMenuTexts[] = { gText_ReturnToTitle }; -ALIGNED(4) const u8 sMG_Ereader_TextColor_1[3] = { 0, 1, 2 }; -ALIGNED(4) const u8 sMG_Ereader_TextColor_1_Copy[3] = { 0, 1, 2 }; -ALIGNED(4) const u8 sMG_Ereader_TextColor_2[3] = { 1, 2, 3 }; +ALIGNED(4) static const u8 sTextColors_TopMenu[3] = { 0, 1, 2 }; +ALIGNED(4) static const u8 sTextColors_TopMenu_Copy[3] = { 0, 1, 2 }; +ALIGNED(4) static const u8 sMG_Ereader_TextColor_2[3] = { 1, 2, 3 }; static const u8 sText_Test[] = _("テスト"); static const u8 sText_EonTicket[] = _("むげんのチケット"); -void vblankcb_mystery_gift_e_reader_run(void) +static void VBlankCB_MysteryGiftEReader(void) { ProcessSpriteCopyRequests(); LoadOam(); @@ -363,7 +364,7 @@ void CB2_MysteryGiftEReader(void) BuildOamBuffer(); } -bool32 HandleMysteryGiftOrEReaderSetup(s32 mg_or_ereader) +bool32 HandleMysteryGiftOrEReaderSetup(s32 isEReader) { switch (gMain.state) { @@ -376,24 +377,24 @@ bool32 HandleMysteryGiftOrEReaderSetup(s32 mg_or_ereader) ScanlineEffect_Stop(); ResetBgsAndClearDma3BusyFlags(1); - InitBgsFromTemplates(0, sBGTemplates, NELEMS(sBGTemplates)); - ChangeBgX(0, 0, 0); - ChangeBgY(0, 0, 0); - ChangeBgX(1, 0, 0); - ChangeBgY(1, 0, 0); - ChangeBgX(2, 0, 0); - ChangeBgY(2, 0, 0); - ChangeBgX(3, 0, 0); - ChangeBgY(3, 0, 0); + InitBgsFromTemplates(0, sBGTemplates, ARRAY_COUNT(sBGTemplates)); + ChangeBgX(0, 0, BG_COORD_SET); + ChangeBgY(0, 0, BG_COORD_SET); + ChangeBgX(1, 0, BG_COORD_SET); + ChangeBgY(1, 0, BG_COORD_SET); + ChangeBgX(2, 0, BG_COORD_SET); + ChangeBgY(2, 0, BG_COORD_SET); + ChangeBgX(3, 0, BG_COORD_SET); + ChangeBgY(3, 0, BG_COORD_SET); - SetBgTilemapBuffer(3, Alloc(0x800)); - SetBgTilemapBuffer(2, Alloc(0x800)); - SetBgTilemapBuffer(1, Alloc(0x800)); - SetBgTilemapBuffer(0, Alloc(0x800)); + SetBgTilemapBuffer(3, Alloc(BG_SCREEN_SIZE)); + SetBgTilemapBuffer(2, Alloc(BG_SCREEN_SIZE)); + SetBgTilemapBuffer(1, Alloc(BG_SCREEN_SIZE)); + SetBgTilemapBuffer(0, Alloc(BG_SCREEN_SIZE)); LoadUserWindowGfx2(0, 10, 0xE0); LoadStdWindowGfxOnBg(0, 1, 0xF0); - DecompressAndLoadBgGfxUsingHeap(3, gUnkTextboxBorderGfx, 0x100, 0, 0); + DecompressAndLoadBgGfxUsingHeap(3, sTextboxBorder_Gfx, 0x100, 0, 0); InitWindows(sMainWindows); DeactivateAllTextPrinters(); ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON | DISPCNT_WIN1_ON); @@ -403,13 +404,13 @@ bool32 HandleMysteryGiftOrEReaderSetup(s32 mg_or_ereader) gMain.state++; break; case 1: - LoadPalette(gUnkTextboxBorderPal, 0, 0x20); + LoadPalette(sTextboxBorder_Pal, 0, 0x20); LoadPalette(GetTextWindowPalette(2), 0xd0, 0x20); FillBgTilemapBufferRect(0, 0x000, 0, 0, 32, 32, 0x11); FillBgTilemapBufferRect(1, 0x000, 0, 0, 32, 32, 0x11); FillBgTilemapBufferRect(2, 0x000, 0, 0, 32, 32, 0x11); MG_DrawCheckerboardPattern(); - PrintMysteryGiftOrEReaderTopMenu(mg_or_ereader, 0); + PrintMysteryGiftOrEReaderTopMenu(isEReader, FALSE); gMain.state++; break; case 2: @@ -423,7 +424,7 @@ bool32 HandleMysteryGiftOrEReaderSetup(s32 mg_or_ereader) ShowBg(0); ShowBg(3); PlayBGM(MUS_MYSTERY_GIFT); - SetVBlankCallback(vblankcb_mystery_gift_e_reader_run); + SetVBlankCallback(VBlankCB_MysteryGiftEReader); EnableInterrupts(INTR_FLAG_VBLANK | INTR_FLAG_VCOUNT | INTR_FLAG_TIMER3 | INTR_FLAG_SERIAL); return TRUE; } @@ -431,23 +432,23 @@ bool32 HandleMysteryGiftOrEReaderSetup(s32 mg_or_ereader) return FALSE; } -void c2_mystery_gift(void) +void CB2_InitMysteryGift(void) { - if (HandleMysteryGiftOrEReaderSetup(0)) + if (HandleMysteryGiftOrEReaderSetup(FALSE)) { SetMainCallback2(CB2_MysteryGiftEReader); gGiftIsFromEReader = FALSE; - task_add_00_mystery_gift(); + CreateMysteryGiftTask(); } } -void c2_ereader(void) +void CB2_InitEReader(void) { - if (HandleMysteryGiftOrEReaderSetup(1)) + if (HandleMysteryGiftOrEReaderSetup(TRUE)) { SetMainCallback2(CB2_MysteryGiftEReader); gGiftIsFromEReader = TRUE; - task_add_00_ereader(); + CreateEReaderTask(); } } @@ -462,22 +463,22 @@ void MainCB_FreeAllBuffersAndReturnToInitTitleScreen(void) SetMainCallback2(CB2_InitTitleScreen); } -void PrintMysteryGiftOrEReaderTopMenu(bool8 mg_or_ereader, bool32 usePickOkCancel) +void PrintMysteryGiftOrEReaderTopMenu(bool8 isEReader, bool32 useCancel) { - const u8 * src; + const u8 * options; s32 width; FillWindowPixelBuffer(0, 0x00); - if (!mg_or_ereader) + if (!isEReader) { - src = usePickOkCancel == TRUE ? gText_PickOKExit : gText_PickOKCancel; - AddTextPrinterParameterized4(0, FONT_2, 2, 2, 0, 0, sMG_Ereader_TextColor_1, 0, gText_MysteryGift2); - width = 222 - GetStringWidth(FONT_0, src, 0); - AddTextPrinterParameterized4(0, FONT_0, width, 2, 0, 0, sMG_Ereader_TextColor_1, 0, src); + options = useCancel == TRUE ? gText_PickOKExit : gText_PickOKCancel; + AddTextPrinterParameterized4(0, FONT_2, 2, 2, 0, 0, sTextColors_TopMenu, 0, gText_MysteryGift2); + width = 222 - GetStringWidth(FONT_0, options, 0); + AddTextPrinterParameterized4(0, FONT_0, width, 2, 0, 0, sTextColors_TopMenu, 0, options); } else { - AddTextPrinterParameterized4(0, FONT_2, 2, 2, 0, 0, sMG_Ereader_TextColor_1, 0, gJPText_MysteryGift); - AddTextPrinterParameterized4(0, FONT_0, 0x78, 2, 0, 0, sMG_Ereader_TextColor_1, 0, gJPText_DecideStop); + AddTextPrinterParameterized4(0, FONT_2, 2, 2, 0, 0, sTextColors_TopMenu, 0, gJPText_MysteryGift); + AddTextPrinterParameterized4(0, FONT_0, 120, 2, 0, 0, sTextColors_TopMenu, 0, gJPText_DecideStop); } CopyWindowToVram(0, COPYWIN_GFX); PutWindowTilemap(0); @@ -499,13 +500,9 @@ void MG_DrawCheckerboardPattern(void) for (j = 0; j < 32; j++) { if ((i & 1) != (j & 1)) - { FillBgTilemapBufferRect(3, 1, j, i + 2, 1, 1, 0x11); - } else - { FillBgTilemapBufferRect(3, 2, j, i + 2, 1, 1, 0x11); - } } } } @@ -534,13 +531,16 @@ void AddTextPrinterToWindow1(const u8 *str) CopyWindowToVram(1, COPYWIN_FULL); } -void ClearTextWindow(void) +static void ClearTextWindow(void) { rbox_fill_rectangle(1); ClearWindowTilemap(1); CopyWindowToVram(1, COPYWIN_MAP); } +#define DOWN_ARROW_X 208 +#define DOWN_ARROW_Y 20 + bool32 PrintMysteryGiftMenuMessage(u8 *textState, const u8 *str) { switch (*textState) @@ -549,7 +549,7 @@ bool32 PrintMysteryGiftMenuMessage(u8 *textState, const u8 *str) AddTextPrinterToWindow1(str); goto inc; case 1: - DrawDownArrow(1, 0xD0, 0x14, 1, FALSE, &sDownArrowCounterAndYCoordIdx[0], &sDownArrowCounterAndYCoordIdx[1]); + DrawDownArrow(1, DOWN_ARROW_X, DOWN_ARROW_Y, 1, FALSE, &sDownArrowCounterAndYCoordIdx[0], &sDownArrowCounterAndYCoordIdx[1]); if (JOY_NEW(A_BUTTON | B_BUTTON)) { inc: @@ -557,7 +557,7 @@ bool32 PrintMysteryGiftMenuMessage(u8 *textState, const u8 *str) } break; case 2: - DrawDownArrow(1, 0xD0, 0x14, 1, TRUE, &sDownArrowCounterAndYCoordIdx[0], &sDownArrowCounterAndYCoordIdx[1]); + DrawDownArrow(1, DOWN_ARROW_X, DOWN_ARROW_Y, 1, TRUE, &sDownArrowCounterAndYCoordIdx[0], &sDownArrowCounterAndYCoordIdx[1]); *textState = 0; ClearTextWindow(); return TRUE; @@ -568,26 +568,25 @@ bool32 PrintMysteryGiftMenuMessage(u8 *textState, const u8 *str) return FALSE; } -void HideDownArrow(void) +static void HideDownArrow(void) { - DrawDownArrow(1, 0xD0, 0x14, 1, FALSE, &sDownArrowCounterAndYCoordIdx[0], &sDownArrowCounterAndYCoordIdx[1]); + DrawDownArrow(1, DOWN_ARROW_X, DOWN_ARROW_Y, 1, FALSE, &sDownArrowCounterAndYCoordIdx[0], &sDownArrowCounterAndYCoordIdx[1]); } -void ShowDownArrow(void) +static void ShowDownArrow(void) { - DrawDownArrow(1, 0xD0, 0x14, 1, TRUE, &sDownArrowCounterAndYCoordIdx[0], &sDownArrowCounterAndYCoordIdx[1]); + DrawDownArrow(1, DOWN_ARROW_X, DOWN_ARROW_Y, 1, TRUE, &sDownArrowCounterAndYCoordIdx[0], &sDownArrowCounterAndYCoordIdx[1]); } -bool32 unref_HideDownArrowAndWaitButton(u8 * textState) +// Unused +static bool32 HideDownArrowAndWaitButton(u8 * textState) { switch (*textState) { case 0: HideDownArrow(); if (JOY_NEW(A_BUTTON | B_BUTTON)) - { (*textState)++; - } break; case 1: ShowDownArrow(); @@ -597,12 +596,11 @@ bool32 unref_HideDownArrowAndWaitButton(u8 * textState) return FALSE; } -bool32 PrintStringAndWait2Seconds(u8 * counter, const u8 * str) +static bool32 PrintStringAndWait2Seconds(u8 * counter, const u8 * str) { if (*counter == 0) - { AddTextPrinterToWindow1(str); - } + if (++(*counter) > 120) { *counter = 0; @@ -615,7 +613,7 @@ bool32 PrintStringAndWait2Seconds(u8 * counter, const u8 * str) } } -u32 MysteryGift_HandleThreeOptionMenu(u8 * unused0, u16 * unused1, u8 whichMenu) +static u32 MysteryGift_HandleThreeOptionMenu(u8 * unused0, u16 * unused1, u8 whichMenu) { struct ListMenuTemplate listMenuTemplate = sListMenuTemplate_ThreeOptions; struct WindowTemplate windowTemplate = sWindowTemplate_ThreeOptions; @@ -625,13 +623,10 @@ u32 MysteryGift_HandleThreeOptionMenu(u8 * unused0, u16 * unused1, u8 whichMenu) u32 i; if (whichMenu == 0) - { listMenuTemplate.items = sListMenuItems_CardsOrNews; - } else - { listMenuTemplate.items = sListMenuItems_WirelessOrFriend; - } + width = 0; for (i = 0; i < listMenuTemplate.totalItems; i++) { @@ -643,7 +638,7 @@ u32 MysteryGift_HandleThreeOptionMenu(u8 * unused0, u16 * unused1, u8 whichMenu) windowTemplate.width = finalWidth; windowTemplate.tilemapLeft = (30 - finalWidth) / 2; response = DoMysteryGiftListMenu(&windowTemplate, &listMenuTemplate, 1, 0x00A, 0xE0); - if (response != -1) + if (response != LIST_NOTHING_CHOSEN) { ClearWindowTilemap(2); CopyWindowToVram(2, COPYWIN_MAP); @@ -659,15 +654,12 @@ s8 DoMysteryGiftYesNo(u8 * textState, u16 * windowId, bool8 yesNoBoxPlacement, c switch (*textState) { case 0: + // Print question message StringExpandPlaceholders(gStringVar4, str); if (yesNoBoxPlacement == 0) - { - *windowId = AddWindow(&sWindowTemplate_PromptYesOrNo_Width28); - } + *windowId = AddWindow(&sWindowTemplate_YesNoMsg_Wide); else - { - *windowId = AddWindow(&sWindowTemplate_PromptYesOrNo_Width20); - } + *windowId = AddWindow(&sWindowTemplate_YesNoMsg); FillWindowPixelBuffer(*windowId, 0x11); AddTextPrinterParameterized4(*windowId, FONT_2, 0, 2, 0, 2, sMG_Ereader_TextColor_2, 0, gStringVar4); DrawTextBorderOuter(*windowId, 0x001, 0x0F); @@ -676,21 +668,19 @@ s8 DoMysteryGiftYesNo(u8 * textState, u16 * windowId, bool8 yesNoBoxPlacement, c (*textState)++; break; case 1: + // Create Yes/No windowTemplate = sWindowTemplate_YesNoBox; if (yesNoBoxPlacement == 0) - { windowTemplate.tilemapTop = 9; - } else - { windowTemplate.tilemapTop = 15; - } CreateYesNoMenu(&windowTemplate, FONT_2, 0, 2, 10, 14, 0); (*textState)++; break; case 2: + // Handle Yes/No input input = Menu_ProcessInputNoWrapClearOnChoose(); - if (input == -1 || input == 0 || input == 1) + if (input == MENU_B_PRESSED || input == 0 || input == 1) { *textState = 0; rbox_fill_rectangle(*windowId); @@ -706,13 +696,14 @@ s8 DoMysteryGiftYesNo(u8 * textState, u16 * windowId, bool8 yesNoBoxPlacement, c ClearWindowTilemap(*windowId); CopyWindowToVram(*windowId, COPYWIN_MAP); RemoveWindow(*windowId); - return -1; + return MENU_B_PRESSED; } - return -2; + return MENU_NOTHING_CHOSEN; } -s32 HandleMysteryGiftListMenu(u8 * textState, u16 * windowId, bool32 cannotToss, bool32 cannotSend) +// 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; s32 input; @@ -720,15 +711,12 @@ s32 HandleMysteryGiftListMenu(u8 * textState, u16 * windowId, bool32 cannotToss, switch (*textState) { case 0: - if (cannotToss == 0) - { + // Print menu message + if (!cannotToss) StringExpandPlaceholders(gStringVar4, gText_WhatToDoWithCards); - } else - { StringExpandPlaceholders(gStringVar4, gText_WhatToDoWithNews); - } - *windowId = AddWindow(&sMysteryGiftMenuWindowTemplate); + *windowId = AddWindow(&sWindowTemplate_GiftSelect); FillWindowPixelBuffer(*windowId, 0x11); AddTextPrinterParameterized4(*windowId, FONT_2, 0, 2, 0, 2, sMG_Ereader_TextColor_2, 0, gStringVar4); DrawTextBorderOuter(*windowId, 0x001, 0x0F); @@ -740,27 +728,19 @@ s32 HandleMysteryGiftListMenu(u8 * textState, u16 * windowId, bool32 cannotToss, windowTemplate = sWindowTemplate_YesNoBox; if (cannotSend) { - if (cannotToss == 0) - { - input = DoMysteryGiftListMenu(&sWindowTemplate_7by6, &sListMenu_ReceiveToss, 1, 0x00A, 0xE0); - } + if (!cannotToss) + input = DoMysteryGiftListMenu(&sWindowTemplate_GiftSelect_2Options, &sListMenu_ReceiveToss, 1, 0x00A, 0xE0); else - { - input = DoMysteryGiftListMenu(&sWindowTemplate_7by4, &sListMenu_Receive, 1, 0x00A, 0xE0); - } + input = DoMysteryGiftListMenu(&sWindowTemplate_GiftSelect_1Option, &sListMenu_Receive, 1, 0x00A, 0xE0); } else { - if (cannotToss == 0) - { - input = DoMysteryGiftListMenu(&sWindowTemplate_7by8, &sListMenu_ReceiveSendToss, 1, 0x00A, 0xE0); - } + if (!cannotToss) + input = DoMysteryGiftListMenu(&sWindowTemplate_GiftSelect_3Options, &sListMenu_ReceiveSendToss, 1, 0x00A, 0xE0); else - { - input = DoMysteryGiftListMenu(&sWindowTemplate_7by6, &sListMenu_ReceiveSend, 1, 0x00A, 0xE0); - } + input = DoMysteryGiftListMenu(&sWindowTemplate_GiftSelect_2Options, &sListMenu_ReceiveSend, 1, 0x00A, 0xE0); } - if (input != -1) + if (input != LIST_NOTHING_CHOSEN) { *textState = 0; rbox_fill_rectangle(*windowId); @@ -776,54 +756,42 @@ s32 HandleMysteryGiftListMenu(u8 * textState, u16 * windowId, bool32 cannotToss, ClearWindowTilemap(*windowId); CopyWindowToVram(*windowId, COPYWIN_MAP); RemoveWindow(*windowId); - return -2; + return LIST_CANCEL; } - return -1; + return LIST_NOTHING_CHOSEN; } -bool32 ValidateCardOrNews(bool32 cardOrNews) +static bool32 ValidateCardOrNews(bool32 isWonderNews) { - if (cardOrNews == 0) + if (!isWonderNews) return ValidateSavedWonderCard(); else return ValidateSavedWonderNews(); } -bool32 HandleLoadWonderCardOrNews(u8 * state, bool32 cardOrNews) +static bool32 HandleLoadWonderCardOrNews(u8 * state, bool32 isWonderNews) { - s32 v0; - switch (*state) { case 0: - if (cardOrNews == 0) - { + if (!isWonderNews) WonderCard_Init(GetSavedWonderCard(), GetSavedWonderCardMetadata()); - } else - { WonderNews_Init(GetSavedWonderNews()); - } (*state)++; break; case 1: - if (cardOrNews == 0) + if (!isWonderNews) { - v0 = WonderCard_Enter(); - check: - if (v0 != 0) - { - goto done; - } - break; + if (!WonderCard_Enter()) + return FALSE; } else { - v0 = WonderNews_Enter(); - goto check; + if (!WonderNews_Enter()) + return FALSE; } - done: *state = 0; return TRUE; } @@ -831,20 +799,20 @@ bool32 HandleLoadWonderCardOrNews(u8 * state, bool32 cardOrNews) return FALSE; } -bool32 DestroyNewsOrCard(bool32 cardOrNews) +static bool32 ClearSavedNewsOrCard(bool32 isWonderNews) { - if (cardOrNews == 0) + if (!isWonderNews) ClearSavedWonderCardAndRelated(); else ClearSavedWonderNewsAndRelated(); return TRUE; } -bool32 TearDownCardOrNews_ReturnToTopMenu(bool32 cardOrNews, bool32 arg1) +static bool32 ExitWonderCardOrNews(bool32 isWonderNews, bool32 useCancel) { - if (cardOrNews == 0) + if (!isWonderNews) { - if (WonderCard_Exit(arg1) != 0) + if (WonderCard_Exit(useCancel)) { WonderCard_Destroy(); return TRUE; @@ -856,7 +824,7 @@ bool32 TearDownCardOrNews_ReturnToTopMenu(bool32 cardOrNews, bool32 arg1) } else { - if (WonderNews_Exit(arg1) != 0) + if (WonderNews_Exit(useCancel)) { WonderNews_Destroy(); return TRUE; @@ -868,23 +836,23 @@ bool32 TearDownCardOrNews_ReturnToTopMenu(bool32 cardOrNews, bool32 arg1) } } -s32 mevent_message_prompt_discard(u8 * textState, u16 * windowId, bool32 cardOrNews) +static s32 AskDiscardGift(u8 * textState, u16 * windowId, bool32 isWonderNews) { - if (cardOrNews == 0) + if (!isWonderNews) return DoMysteryGiftYesNo(textState, windowId, TRUE, gText_IfThrowAwayCardEventWontHappen); else return DoMysteryGiftYesNo(textState, windowId, TRUE, gText_OkayToDiscardNews); } -bool32 mevent_message_was_thrown_away(u8 * textState, bool32 cardOrNews) +static bool32 PrintThrownAway(u8 * textState, bool32 isWonderNews) { - if (cardOrNews == 0) + if (!isWonderNews) return PrintMysteryGiftMenuMessage(textState, gText_WonderCardThrownAway); else return PrintMysteryGiftMenuMessage(textState, gText_WonderNewsThrownAway); } -bool32 mevent_save_game(u8 * state) +static bool32 SaveOnMysteryGiftMenu(u8 * state) { switch (*state) { @@ -902,9 +870,7 @@ bool32 mevent_save_game(u8 * state) break; case 3: if (JOY_NEW(A_BUTTON | B_BUTTON)) - { (*state)++; - } break; case 4: *state = 0; @@ -915,94 +881,92 @@ bool32 mevent_save_game(u8 * state) return FALSE; } -const u8 * mevent_message(u32 * flag_p, u8 cardOrNews, u8 cardOrNewsSource, u32 msgId) +static const u8 * GetClientResultMessage(bool32 * successMsg, bool8 isWonderNews, bool8 sourceIsFriend, u32 msgId) { const u8 * msg = NULL; - *flag_p = 0; + *successMsg = FALSE; switch (msgId) { - case 0: - *flag_p = 0; + case CLI_MSG_NOTHING_SENT: + *successMsg = FALSE; msg = gText_NothingSentOver; break; - case 1: - *flag_p = 0; + case CLI_MSG_RECORD_UPLOADED: + *successMsg = FALSE; msg = gText_RecordUploadedViaWireless; break; - case 2: - *flag_p = 1; - msg = cardOrNewsSource == 0 ? gText_WonderCardReceived : gText_WonderCardReceivedFrom; + case CLI_MSG_CARD_RECEIVED: + *successMsg = TRUE; + msg = !sourceIsFriend ? gText_WonderCardReceived : gText_WonderCardReceivedFrom; break; - case 3: - *flag_p = 1; - msg = cardOrNewsSource == 0 ? gText_WonderNewsReceived : gText_WonderNewsReceivedFrom; + case CLI_MSG_NEWS_RECEIVED: + *successMsg = TRUE; + msg = !sourceIsFriend ? gText_WonderNewsReceived : gText_WonderNewsReceivedFrom; break; - case 4: - *flag_p = 1; + case CLI_MSG_STAMP_RECEIVED: + *successMsg = TRUE; msg = gText_NewStampReceived; break; - case 5: - *flag_p = 0; + case CLI_MSG_HAD_CARD: + *successMsg = FALSE; msg = gText_AlreadyHadCard; break; - case 6: - *flag_p = 0; + case CLI_MSG_HAD_STAMP: + *successMsg = FALSE; msg = gText_AlreadyHadStamp; break; - case 7: - *flag_p = 0; + case CLI_MSG_HAD_NEWS: + *successMsg = FALSE; msg = gText_AlreadyHadNews; break; - case 8: - *flag_p = 0; + case CLI_MSG_NO_ROOM_STAMPS: + *successMsg = FALSE; msg = gText_NoMoreRoomForStamps; break; - case 9: - *flag_p = 0; + case CLI_MSG_COMM_CANCELED: + *successMsg = FALSE; msg = gText_CommunicationCanceled; break; - case 10: - *flag_p = 0; - msg = cardOrNews == 0 ? gText_CantAcceptCardFromTrainer : gText_CantAcceptNewsFromTrainer; + case CLI_MSG_CANT_ACCEPT: + *successMsg = FALSE; + msg = !isWonderNews ? gText_CantAcceptCardFromTrainer : gText_CantAcceptNewsFromTrainer; break; - case 11: - *flag_p = 0; + case CLI_MSG_COMM_ERROR: + *successMsg = FALSE; msg = gText_CommunicationError; break; - case 12: - *flag_p = 1; + case CLI_MSG_TRAINER_RECEIVED: + *successMsg = TRUE; msg = gText_NewTrainerReceived; break; - case 13: - *flag_p = 1; + case CLI_MSG_BUFFER_SUCCESS: + *successMsg = TRUE; + // msg is NULL, use buffer break; - case 14: - *flag_p = 0; + case CLI_MSG_BUFFER_FAILURE: + *successMsg = FALSE; + // msg is NULL, use buffer break; } return msg; } -bool32 PrintMGSuccessMessage(u8 * state, const u8 * arg1, u16 * arg2) +static bool32 PrintSuccessMessage(u8 * state, const u8 * msg, u16 * timer) { switch (*state) { case 0: - if (arg1 != NULL) - { - AddTextPrinterToWindow1(arg1); - } + if (msg != NULL) + AddTextPrinterToWindow1(msg); PlayFanfare(MUS_OBTAIN_ITEM); - *arg2 = 0; + *timer = 0; (*state)++; break; case 1: - if (++(*arg2) > 0xF0) - { + if (++(*timer) > 240) (*state)++; - } break; case 2: if (IsFanfareTaskInactive()) @@ -1016,556 +980,566 @@ bool32 PrintMGSuccessMessage(u8 * state, const u8 * arg1, u16 * arg2) return FALSE; } -const u8 * mevent_message_stamp_card_etc_send_status(u32 * a0, u8 unused, u32 msgId) +static const u8 * GetServerResultMessage(bool32 * wonderSuccess, u8 unused, 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 PrintMGSuccessMessage(state, str, arg1); - } + bool32 wonderSuccess; + const u8 * str = GetServerResultMessage(&wonderSuccess, sourceIsFriend, msgId); + if (wonderSuccess) + return PrintSuccessMessage(state, str, timer); else - { return PrintMysteryGiftMenuMessage(state, str); - } } -void task_add_00_mystery_gift(void) +// States for Task_MysteryGift. +// CLIENT states are for when the player is receiving a gift, and use mystery_gift_client.c link functions. +// SERVER states are for when the player is sending a gift, and use mystery_gift_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_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, + MG_STATE_HANDLE_GIFT_INPUT, + MG_STATE_HANDLE_GIFT_SELECT, + MG_STATE_ASK_TOSS, + MG_STATE_ASK_TOSS_UNRECEIVED, + MG_STATE_TOSS, + MG_STATE_TOSS_SAVE, + MG_STATE_TOSSED, + MG_STATE_GIFT_INPUT_EXIT, + MG_STATE_RECEIVE, + MG_STATE_SEND, + 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, +}; + +static void CreateMysteryGiftTask(void) { - u8 taskId = CreateTask(task00_mystery_gift, 0); + u8 taskId = CreateTask(Task_MysteryGift, 0); struct MysteryGiftTaskData * data = (void *)gTasks[taskId].data; - data->state = 0; + data->state = MG_STATE_TO_MAIN_MENU; data->textState = 0; - data->unkA = 0; - data->unkB = 0; - data->IsCardOrNews = 0; - data->source = 0; - data->curPromptWindowId = 0; - data->unk2 = 0; - data->unk4 = 0; - data->unk6 = 0; - data->prevPromptWindowId = 0; - data->buffer = AllocZeroed(0x40); + data->unused4 = 0; + data->unused5 = 0; + data->isWonderNews = FALSE; + data->sourceIsFriend = FALSE; + data->var = 0; + data->unused1 = 0; + data->unused2 = 0; + data->unused3 = 0; + data->msgId = 0; + data->clientMsg = AllocZeroed(CLIENT_MAX_MSG_SIZE); } -void task00_mystery_gift(u8 taskId) +static void Task_MysteryGift(u8 taskId) { struct MysteryGiftTaskData * data = (void *)gTasks[taskId].data; - u32 sp0, flag; - const u8 * r1; + bool32 successMsg, input; + const u8 * msg; switch (data->state) { - case 0: - data->state = 1; + case MG_STATE_TO_MAIN_MENU: + data->state = MG_STATE_MAIN_MENU; break; - case 1: - switch (MysteryGift_HandleThreeOptionMenu(&data->textState, &data->curPromptWindowId, FALSE)) + case MG_STATE_MAIN_MENU: + // Main Mystery Gift menu, player can select Wonder Cards or News (or exit) + switch (MysteryGift_HandleThreeOptionMenu(&data->textState, &data->var, FALSE)) { - case 0: - data->IsCardOrNews = 0; + case 0: // "Wonder Cards" + data->isWonderNews = FALSE; if (ValidateSavedWonderCard() == TRUE) - data->state = 18; + data->state = MG_STATE_LOAD_GIFT; else - data->state = 2; + data->state = MG_STATE_DONT_HAVE_ANY; break; - case 1: - data->IsCardOrNews = 1; + case 1: // "Wonder News" + data->isWonderNews = TRUE; if (ValidateSavedWonderNews() == TRUE) - data->state = 18; + data->state = MG_STATE_LOAD_GIFT; else - data->state = 2; + data->state = MG_STATE_DONT_HAVE_ANY; break; - case -2u: - data->state = 37; + case LIST_CANCEL: + data->state = MG_STATE_EXIT; break; } break; - case 2: + case MG_STATE_DONT_HAVE_ANY: { - if (data->IsCardOrNews == 0) + // Player doesn't have any Wonder Card/News + // Start prompt to ask where to read one from + if (!data->isWonderNews) { if (PrintMysteryGiftMenuMessage(&data->textState, gText_DontHaveCardNewOneInput)) { - data->state = 3; - PrintMysteryGiftOrEReaderTopMenu(0, 1); + data->state = MG_STATE_SOURCE_PROMPT; + PrintMysteryGiftOrEReaderTopMenu(FALSE, TRUE); } } else { if (PrintMysteryGiftMenuMessage(&data->textState, gText_DontHaveNewsNewOneInput)) { - data->state = 3; - PrintMysteryGiftOrEReaderTopMenu(0, 1); + data->state = MG_STATE_SOURCE_PROMPT; + PrintMysteryGiftOrEReaderTopMenu(FALSE, TRUE); } } break; } - case 3: - if (data->IsCardOrNews == 0) - { + case MG_STATE_SOURCE_PROMPT: + if (!data->isWonderNews) AddTextPrinterToWindow1(gText_WhereShouldCardBeAccessed); - } else - { AddTextPrinterToWindow1(gText_WhereShouldNewsBeAccessed); - } - data->state = 4; + data->state = MG_STATE_SOURCE_PROMPT_INPUT; break; - case 4: - switch (MysteryGift_HandleThreeOptionMenu(&data->textState, &data->curPromptWindowId, TRUE)) + case MG_STATE_SOURCE_PROMPT_INPUT: + // Choose where to access the Wonder Card/News from + switch (MysteryGift_HandleThreeOptionMenu(&data->textState, &data->var, TRUE)) { - case 0: + case 0: // "Wireless Communication" ClearTextWindow(); - data->state = 5; - data->source = 0; + data->state = MG_STATE_CLIENT_LINK_START; + data->sourceIsFriend = FALSE; break; - case 1: + case 1: // "Friend" ClearTextWindow(); - data->state = 5; - data->source = 1; + data->state = MG_STATE_CLIENT_LINK_START; + data->sourceIsFriend = TRUE; break; - case -2u: + case LIST_CANCEL: ClearTextWindow(); - if (ValidateCardOrNews(data->IsCardOrNews)) + if (ValidateCardOrNews(data->isWonderNews)) { - data->state = 18; + data->state = MG_STATE_LOAD_GIFT; } else { - data->state = 0; - PrintMysteryGiftOrEReaderTopMenu(0, 0); + data->state = MG_STATE_TO_MAIN_MENU; + PrintMysteryGiftOrEReaderTopMenu(FALSE, FALSE); } break; } break; - case 5: + case MG_STATE_CLIENT_LINK_START: *gStringVar1 = EOS; *gStringVar2 = EOS; *gStringVar3 = EOS; - switch (data->IsCardOrNews) + switch (data->isWonderNews) { - case 0: - if (data->source == 1) + case FALSE: + if (data->sourceIsFriend == TRUE) CreateTask_LinkMysteryGiftWithFriend(ACTIVITY_WONDER_CARD); - else if (data->source == 0) + else if (data->sourceIsFriend == FALSE) CreateTask_LinkMysteryGiftOverWireless(ACTIVITY_WONDER_CARD); break; - case 1: - if (data->source == 1) + case TRUE: + if (data->sourceIsFriend == TRUE) CreateTask_LinkMysteryGiftWithFriend(ACTIVITY_WONDER_NEWS); - else if (data->source == 0) + else if (data->sourceIsFriend == FALSE) CreateTask_LinkMysteryGiftOverWireless(ACTIVITY_WONDER_NEWS); break; } - data->state = 6; + data->state = MG_STATE_CLIENT_LINK_WAIT; break; - case 6: + case MG_STATE_CLIENT_LINK_WAIT: if (gReceivedRemoteLinkPlayers) { ClearScreenInBg0(TRUE); - data->state = 7; + data->state = MG_STATE_CLIENT_COMMUNICATING; MysteryGiftClient_Create(); } - else if (gSpecialVar_Result == 5) + else if (gSpecialVar_Result == LINKUP_FAILED) { + // Link failed, return to link start menu ClearScreenInBg0(TRUE); - data->state = 3; + data->state = MG_STATE_SOURCE_PROMPT; } break; - case 7: + case MG_STATE_CLIENT_COMMUNICATING: AddTextPrinterToWindow1(gText_Communicating); - data->state = 8; + data->state = MG_STATE_CLIENT_LINK; break; - case 8: - switch (MysteryGiftClient_Run(&data->curPromptWindowId)) + case MG_STATE_CLIENT_LINK: + switch (MysteryGiftClient_Run(&data->var)) { - case 6: // done + case CLI_RET_END: Rfu_SetCloseLinkCallback(); - data->prevPromptWindowId = data->curPromptWindowId; - data->state = 13; + data->msgId = data->var; + data->state = MG_STATE_CLIENT_LINK_END; break; - case 5: - memcpy(data->buffer, MysteryGiftClient_GetMsg(), 0x40); + case CLI_RET_COPY_MSG: + memcpy(data->clientMsg, MysteryGiftClient_GetMsg(), CLIENT_MAX_MSG_SIZE); MysteryGiftClient_AdvanceState(); break; - case 3: - data->state = 10; + case CLI_RET_PRINT_MSG: + data->state = MG_STATE_CLIENT_MESSAGE; break; - case 2: - data->state = 9; + case CLI_RET_YES_NO: + data->state = MG_STATE_CLIENT_YES_NO; break; - case 4: - data->state = 11; + case CLI_RET_ASK_TOSS: + data->state = MG_STATE_CLIENT_ASK_TOSS; StringCopy(gStringVar1, gLinkPlayers[0].name); break; } break; - case 9: - flag = DoMysteryGiftYesNo(&data->textState, &data->curPromptWindowId, FALSE, MysteryGiftClient_GetMsg()); - switch (flag) + case MG_STATE_CLIENT_YES_NO: + input = DoMysteryGiftYesNo(&data->textState, &data->var, FALSE, MysteryGiftClient_GetMsg()); + switch (input) { - case 0: - MysteryGiftClient_SetParam(0); + case 0: // Yes + MysteryGiftClient_SetParam(FALSE); MysteryGiftClient_AdvanceState(); - data->state = 7; + data->state = MG_STATE_CLIENT_COMMUNICATING; break; - case 1: - MysteryGiftClient_SetParam(1); + case 1: // No + case MENU_B_PRESSED: + MysteryGiftClient_SetParam(TRUE); MysteryGiftClient_AdvanceState(); - data->state = 7; - break; - case -1u: - MysteryGiftClient_SetParam(1); - MysteryGiftClient_AdvanceState(); - data->state = 7; + data->state = MG_STATE_CLIENT_COMMUNICATING; break; } break; - case 10: + case MG_STATE_CLIENT_MESSAGE: if (PrintMysteryGiftMenuMessage(&data->textState, MysteryGiftClient_GetMsg())) { MysteryGiftClient_AdvanceState(); - data->state = 7; + data->state = MG_STATE_CLIENT_COMMUNICATING; } break; - case 11: - flag = DoMysteryGiftYesNo(&data->textState, &data->curPromptWindowId, FALSE, gText_ThrowAwayWonderCard); - switch (flag) + 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: + case 0: // Yes if (IsSavedWonderCardGiftNotReceived() == TRUE) { - data->state = 12; + data->state = MG_STATE_CLIENT_ASK_TOSS_UNRECEIVED; } else { - MysteryGiftClient_SetParam(0); + MysteryGiftClient_SetParam(FALSE); MysteryGiftClient_AdvanceState(); - data->state = 7; + data->state = MG_STATE_CLIENT_COMMUNICATING; } break; - case 1: - MysteryGiftClient_SetParam(1); + case 1: // No + case MENU_B_PRESSED: + MysteryGiftClient_SetParam(TRUE); MysteryGiftClient_AdvanceState(); - data->state = 7; - break; - case -1u: - MysteryGiftClient_SetParam(1); - MysteryGiftClient_AdvanceState(); - data->state = 7; + data->state = MG_STATE_CLIENT_COMMUNICATING; break; } break; - case 12: - flag = DoMysteryGiftYesNo(&data->textState, &data->curPromptWindowId, FALSE, gText_HaventReceivedCardsGift); - switch (flag) + 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: - MysteryGiftClient_SetParam(0); + case 0: // Yes + MysteryGiftClient_SetParam(FALSE); MysteryGiftClient_AdvanceState(); - data->state = 7; + data->state = MG_STATE_CLIENT_COMMUNICATING; break; - case 1: - MysteryGiftClient_SetParam(1); + case 1: // No + case MENU_B_PRESSED: + MysteryGiftClient_SetParam(TRUE); MysteryGiftClient_AdvanceState(); - data->state = 7; - break; - case -1u: - MysteryGiftClient_SetParam(1); - MysteryGiftClient_AdvanceState(); - data->state = 7; + data->state = MG_STATE_CLIENT_COMMUNICATING; break; } break; - case 13: + case MG_STATE_CLIENT_LINK_END: if (IsLinkRfuTaskFinished()) { DestroyWirelessStatusIndicatorSprite(); - data->state = 14; + data->state = MG_STATE_CLIENT_COMM_COMPLETED; } break; - case 14: + case MG_STATE_CLIENT_COMM_COMPLETED: if (PrintStringAndWait2Seconds(&data->textState, gText_CommunicationCompleted)) { - if (data->source == 1) - { + if (data->sourceIsFriend == TRUE) StringCopy(gStringVar1, gLinkPlayers[0].name); - } - data->state = 15; + data->state = MG_STATE_CLIENT_RESULT_MSG; } break; - case 15: - r1 = mevent_message(&sp0, data->IsCardOrNews, data->source, data->prevPromptWindowId); - if (r1 == NULL) - r1 = data->buffer; - if (sp0) - flag = PrintMGSuccessMessage(&data->textState, r1, &data->curPromptWindowId); + case MG_STATE_CLIENT_RESULT_MSG: + msg = GetClientResultMessage(&successMsg, data->isWonderNews, data->sourceIsFriend, data->msgId); + if (msg == NULL) + msg = data->clientMsg; + if (successMsg) + input = PrintSuccessMessage(&data->textState, msg, &data->var); else - flag = PrintMysteryGiftMenuMessage(&data->textState, r1); + input = PrintMysteryGiftMenuMessage(&data->textState, msg); - if (flag) + // 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->source == 1) - WonderNews_SetReward(1); + if (data->sourceIsFriend == TRUE) + WonderNews_SetReward(WONDER_NEWS_RECV_FRIEND); else - WonderNews_SetReward(2); + WonderNews_SetReward(WONDER_NEWS_RECV_WIRELESS); } - if (sp0 == 0) + if (!successMsg) { - data->state = 0; - PrintMysteryGiftOrEReaderTopMenu(0, 0); + // Did not receive card/news, return to main menu + data->state = MG_STATE_TO_MAIN_MENU; + PrintMysteryGiftOrEReaderTopMenu(FALSE, FALSE); } else { - data->state = 17; + data->state = MG_STATE_SAVE_LOAD_GIFT; } } break; - case 16: - if (PrintMysteryGiftMenuMessage(&data->textState, gText_CommunicationError)) + case MG_STATE_SAVE_LOAD_GIFT: + if (SaveOnMysteryGiftMenu(&data->textState)) { - data->state = 0; - PrintMysteryGiftOrEReaderTopMenu(0, 0); + data->state = MG_STATE_TO_MAIN_MENU; + PrintMysteryGiftOrEReaderTopMenu(FALSE, FALSE); } break; - case 17: - if (mevent_save_game(&data->textState)) - { - data->state = 0; - PrintMysteryGiftOrEReaderTopMenu(0, 0); - } + case MG_STATE_LOAD_GIFT: + if (HandleLoadWonderCardOrNews(&data->textState, data->isWonderNews)) + data->state = MG_STATE_HANDLE_GIFT_INPUT; break; - case 18: - if (HandleLoadWonderCardOrNews(&data->textState, data->IsCardOrNews)) - { - data->state = 20; - } - break; - case 20: - if (data->IsCardOrNews == 0) + case MG_STATE_HANDLE_GIFT_INPUT: + if (!data->isWonderNews) { + // Handle Wonder Card input if (JOY_NEW(A_BUTTON)) - { - data->state = 21; - } + data->state = MG_STATE_HANDLE_GIFT_SELECT; if (JOY_NEW(B_BUTTON)) - { - data->state = 27; - } + data->state = MG_STATE_GIFT_INPUT_EXIT; } else { switch (WonderNews_GetInput(gMain.newKeys)) { - case 0: + case NEWS_INPUT_A: WonderNews_RemoveScrollIndicatorArrowPair(); - data->state = 21; + data->state = MG_STATE_HANDLE_GIFT_SELECT; break; - case 1: - data->state = 27; + case NEWS_INPUT_B: + data->state = MG_STATE_GIFT_INPUT_EXIT; break; } } break; - case 21: + case MG_STATE_HANDLE_GIFT_SELECT: { + // A Wonder Card/News has been selected, handle its menu u32 result; - if (data->IsCardOrNews == 0) + if (!data->isWonderNews) { if (IsSendingSavedWonderCardAllowed()) - result = HandleMysteryGiftListMenu(&data->textState, &data->curPromptWindowId, data->IsCardOrNews, FALSE); + result = HandleMysteryGiftListMenu(&data->textState, &data->var, data->isWonderNews, FALSE); else - result = HandleMysteryGiftListMenu(&data->textState, &data->curPromptWindowId, data->IsCardOrNews, TRUE); + result = HandleMysteryGiftListMenu(&data->textState, &data->var, data->isWonderNews, TRUE); } else { if (IsSendingSavedWonderNewsAllowed()) - result = HandleMysteryGiftListMenu(&data->textState, &data->curPromptWindowId, data->IsCardOrNews, FALSE); + result = HandleMysteryGiftListMenu(&data->textState, &data->var, data->isWonderNews, FALSE); else - result = HandleMysteryGiftListMenu(&data->textState, &data->curPromptWindowId, data->IsCardOrNews, TRUE); + result = HandleMysteryGiftListMenu(&data->textState, &data->var, data->isWonderNews, TRUE); } switch (result) { - case 0: - data->state = 28; + case 0: // Receive + data->state = MG_STATE_RECEIVE; break; - case 1: - data->state = 29; + case 1: // Send + data->state = MG_STATE_SEND; break; - case 2: - data->state = 22; + case 2: // Toss + data->state = MG_STATE_ASK_TOSS; break; - case -2u: - if (data->IsCardOrNews == 1) - { + case LIST_CANCEL: + if (data->isWonderNews == TRUE) WonderNews_AddScrollIndicatorArrowPair(); - } - data->state = 20; + data->state = MG_STATE_HANDLE_GIFT_INPUT; break; } break; } - case 22: - switch (mevent_message_prompt_discard(&data->textState, &data->curPromptWindowId, data->IsCardOrNews)) + case MG_STATE_ASK_TOSS: + // Player is attempting to discard a saved Wonder Card/News + switch (AskDiscardGift(&data->textState, &data->var, data->isWonderNews)) { - case 0: - if (data->IsCardOrNews == 0 && IsSavedWonderCardGiftNotReceived() == TRUE) - { - data->state = 23; - } + case 0: // Yes + if (!data->isWonderNews && IsSavedWonderCardGiftNotReceived() == TRUE) + data->state = MG_STATE_ASK_TOSS_UNRECEIVED; else + data->state = MG_STATE_TOSS; + break; + case 1: // No + case MENU_B_PRESSED: + data->state = MG_STATE_HANDLE_GIFT_SELECT; + break; + } + break; + 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->var, TRUE, gText_HaventReceivedGiftOkayToDiscard)) + { + case 0: // Yes + data->state = MG_STATE_TOSS; + break; + case 1: // No + case MENU_B_PRESSED: + data->state = MG_STATE_HANDLE_GIFT_SELECT; + break; + } + break; + case MG_STATE_TOSS: + if (ExitWonderCardOrNews(data->isWonderNews, TRUE)) + { + ClearSavedNewsOrCard(data->isWonderNews); + data->state = MG_STATE_TOSS_SAVE; + } + break; + case MG_STATE_TOSS_SAVE: + if (SaveOnMysteryGiftMenu(&data->textState)) + data->state = MG_STATE_TOSSED; + break; + case MG_STATE_TOSSED: + if (PrintThrownAway(&data->textState, data->isWonderNews)) + { + data->state = MG_STATE_TO_MAIN_MENU; + PrintMysteryGiftOrEReaderTopMenu(FALSE, FALSE); + } + break; + case MG_STATE_GIFT_INPUT_EXIT: + if (ExitWonderCardOrNews(data->isWonderNews, FALSE)) + data->state = MG_STATE_TO_MAIN_MENU; + break; + case MG_STATE_RECEIVE: + if (ExitWonderCardOrNews(data->isWonderNews, TRUE)) + data->state = MG_STATE_SOURCE_PROMPT; + break; + case MG_STATE_SEND: + if (ExitWonderCardOrNews(data->isWonderNews, TRUE)) + { + switch (data->isWonderNews) { - data->state = 24; - } - break; - case 1: - data->state = 21; - break; - case -1: - data->state = 21; - break; - } - break; - case 23: - switch ((u32)DoMysteryGiftYesNo(&data->textState, &data->curPromptWindowId, TRUE, gText_HaventReceivedGiftOkayToDiscard)) - { - case 0: - data->state = 24; - break; - case 1: - data->state = 21; - break; - case -1u: - data->state = 21; - break; - } - break; - case 24: - if (TearDownCardOrNews_ReturnToTopMenu(data->IsCardOrNews, 1)) - { - DestroyNewsOrCard(data->IsCardOrNews); - data->state = 25; - } - break; - case 25: - if (mevent_save_game(&data->textState)) - { - data->state = 26; - } - break; - case 26: - if (mevent_message_was_thrown_away(&data->textState, data->IsCardOrNews)) - { - data->state = 0; - PrintMysteryGiftOrEReaderTopMenu(0, 0); - } - break; - case 27: - if (TearDownCardOrNews_ReturnToTopMenu(data->IsCardOrNews, 0)) - { - data->state = 0; - } - break; - case 28: - if (TearDownCardOrNews_ReturnToTopMenu(data->IsCardOrNews, 1)) - { - data->state = 3; - } - break; - case 29: - if (TearDownCardOrNews_ReturnToTopMenu(data->IsCardOrNews, 1)) - { - switch (data->IsCardOrNews) - { - case 0: + case FALSE: CreateTask_SendMysteryGift(ACTIVITY_WONDER_CARD); break; - case 1: + case TRUE: CreateTask_SendMysteryGift(ACTIVITY_WONDER_NEWS); break; } - data->source = 1; - data->state = 30; + data->sourceIsFriend = TRUE; + data->state = MG_STATE_SERVER_LINK_WAIT; } break; - case 30: + case MG_STATE_SERVER_LINK_WAIT: if (gReceivedRemoteLinkPlayers) { - ClearScreenInBg0(1); - data->state = 31; + ClearScreenInBg0(TRUE); + data->state = MG_STATE_SERVER_LINK_START; } - else if (gSpecialVar_Result == 5) + else if (gSpecialVar_Result == LINKUP_FAILED) { - ClearScreenInBg0(1); - data->state = 18; + ClearScreenInBg0(TRUE); + data->state = MG_STATE_LOAD_GIFT; } break; - case 31: + case MG_STATE_SERVER_LINK_START: *gStringVar1 = EOS; *gStringVar2 = EOS; *gStringVar3 = EOS; - if (data->IsCardOrNews == 0) + if (!data->isWonderNews) { AddTextPrinterToWindow1(gText_SendingWonderCard); MysterGiftServer_CreateForCard(); @@ -1575,53 +1549,54 @@ void task00_mystery_gift(u8 taskId) AddTextPrinterToWindow1(gText_SendingWonderNews); MysterGiftServer_CreateForNews(); } - data->state = 32; + data->state = MG_STATE_SERVER_LINK; break; - case 32: - if (MysterGiftServer_Run(&data->curPromptWindowId) == 3) + case MG_STATE_SERVER_LINK: + if (MysterGiftServer_Run(&data->var) == SVR_RET_END) { - data->prevPromptWindowId = data->curPromptWindowId; - data->state = 33; + data->msgId = data->var; + data->state = MG_STATE_SERVER_LINK_END; } break; - case 33: + case MG_STATE_SERVER_LINK_END: Rfu_SetCloseLinkCallback(); StringCopy(gStringVar1, gLinkPlayers[1].name); - data->state = 34; + data->state = MG_STATE_SERVER_LINK_END_WAIT; break; - case 34: + case MG_STATE_SERVER_LINK_END_WAIT: if (IsLinkRfuTaskFinished()) { DestroyWirelessStatusIndicatorSprite(); - data->state = 35; + data->state = MG_STATE_SERVER_RESULT_MSG; } break; - case 35: - if (PrintMGSendStatus(&data->textState, &data->curPromptWindowId, data->source, data->prevPromptWindowId)) + case MG_STATE_SERVER_RESULT_MSG: + if (PrintServerResultMessage(&data->textState, &data->var, data->sourceIsFriend, data->msgId)) { - if (data->source == 1 && data->prevPromptWindowId == 3) + if (data->sourceIsFriend == TRUE && data->msgId == SVR_MSG_NEWS_SENT) { - WonderNews_SetReward(3); - data->state = 17; + WonderNews_SetReward(WONDER_NEWS_SENT); + data->state = MG_STATE_SAVE_LOAD_GIFT; } else { - data->state = 0; - PrintMysteryGiftOrEReaderTopMenu(0, 0); + data->state = MG_STATE_TO_MAIN_MENU; + PrintMysteryGiftOrEReaderTopMenu(FALSE, FALSE); } } break; - case 36: + case MG_STATE_CLIENT_ERROR: + case MG_STATE_SERVER_ERROR: if (PrintMysteryGiftMenuMessage(&data->textState, gText_CommunicationError)) { - data->state = 0; - PrintMysteryGiftOrEReaderTopMenu(0, 0); + data->state = MG_STATE_TO_MAIN_MENU; + PrintMysteryGiftOrEReaderTopMenu(FALSE, FALSE); } break; - case 37: + case MG_STATE_EXIT: CloseLink(); HelpSystem_Enable(); - Free(data->buffer); + Free(data->clientMsg); DestroyTask(taskId); SetMainCallback2(MainCB_FreeAllBuffersAndReturnToInitTitleScreen); break; diff --git a/sym_common.txt b/sym_common.txt index 51b041064..1e57985da 100644 --- a/sym_common.txt +++ b/sym_common.txt @@ -40,7 +40,7 @@ .include "fame_checker.o" .include "help_system_util.o" .align 4 - .include "mystery_gift.o" + .include "ereader_screen.o" .align 4 .include "battle_controller_pokedude.o" .align 4 From a19cb44458e774f4d7f98849dcaf12fd5876e818 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Mon, 21 Nov 2022 23:52:11 -0500 Subject: [PATCH 8/8] Clean up mystery gift sync, document wonder news --- data/event_scripts.s | 1 + data/maps/CeruleanCity_House4/scripts.inc | 48 +++--- data/mystery_event_msg.s | 6 +- data/specials.inc | 4 +- ...er.png => mystery_gift_textbox_border.png} | Bin include/constants/mystery_gift.h | 8 + include/global.h | 4 +- include/mystery_gift_link.h | 1 - include/mystery_gift_server.h | 6 +- src/easy_chat.c | 2 +- src/field_specials.c | 22 +-- src/mystery_gift_client.c | 1 - src/mystery_gift_link.c | 6 +- src/mystery_gift_menu.c | 6 +- src/mystery_gift_scripts.c | 8 +- src/mystery_gift_server.c | 135 +++++++++-------- src/wonder_news.c | 143 +++++++++--------- 17 files changed, 212 insertions(+), 189 deletions(-) rename graphics/interface/{unk_textbox_border.png => mystery_gift_textbox_border.png} (100%) diff --git a/data/event_scripts.s b/data/event_scripts.s index 5e349996d..d6aa4d512 100644 --- a/data/event_scripts.s +++ b/data/event_scripts.s @@ -36,6 +36,7 @@ #include "constants/easy_chat.h" #include "constants/trainer_card.h" #include "constants/help_system.h" +#include "constants/mystery_gift.h" .include "asm/macros.inc" .include "asm/macros/event.inc" .set FALSE, 0 diff --git a/data/maps/CeruleanCity_House4/scripts.inc b/data/maps/CeruleanCity_House4/scripts.inc index e812d3b73..42ddde3f2 100644 --- a/data/maps/CeruleanCity_House4/scripts.inc +++ b/data/maps/CeruleanCity_House4/scripts.inc @@ -1,5 +1,8 @@ .set LOCALID_WONDER_NEWS_BERRY_MAN, 1 +.set REWARD_TYPE, VAR_0x8004 +.set REWARD_ITEM, VAR_0x8008 + CeruleanCity_House4_MapScripts:: .byte 0 @@ -7,62 +10,69 @@ CeruleanCity_House4_EventScript_WonderNewsBerryMan:: goto_if_questlog EventScript_ReleaseEnd special QuestLog_CutRecording lock - specialvar VAR_0x8004, GetMENewsJisanItemAndState - copyvar VAR_0x8008, VAR_RESULT - goto_if_eq VAR_0x8004, 0, CeruleanCity_House4_EventScript_NoNews - goto_if_eq VAR_0x8004, 1, CeruleanCity_House4_EventScript_News1 - goto_if_eq VAR_0x8004, 2, CeruleanCity_House4_EventScript_News2 - goto_if_eq VAR_0x8004, 3, CeruleanCity_House4_EventScript_NewsNotSpread - goto_if_eq VAR_0x8004, 4, CeruleanCity_House4_EventScript_NewsSpread1 - goto_if_eq VAR_0x8004, 5, CeruleanCity_House4_EventScript_NewsSpread2 - goto_if_eq VAR_0x8004, 6, CeruleanCity_House4_EventScript_NewsDone + specialvar REWARD_TYPE, WonderNews_GetRewardInfo + copyvar REWARD_ITEM, VAR_RESULT + goto_if_eq REWARD_TYPE, NEWS_REWARD_NONE, CeruleanCity_House4_EventScript_NoNews + goto_if_eq REWARD_TYPE, NEWS_REWARD_RECV_SMALL, CeruleanCity_House4_EventScript_Reward_RecvSmall + goto_if_eq REWARD_TYPE, NEWS_REWARD_RECV_BIG, CeruleanCity_House4_EventScript_Reward_RecvBig + goto_if_eq REWARD_TYPE, NEWS_REWARD_WAITING, CeruleanCity_House4_EventScript_Waiting + goto_if_eq REWARD_TYPE, NEWS_REWARD_SENT_SMALL, CeruleanCity_House4_EventScript_Reward_SentSmall + goto_if_eq REWARD_TYPE, NEWS_REWARD_SENT_BIG, CeruleanCity_House4_EventScript_Reward_SentBig + goto_if_eq REWARD_TYPE, NEWS_REWARD_AT_MAX, CeruleanCity_House4_EventScript_AtMax end +@ Mystery Gift is not enabled, or the player has no saved Wonder News CeruleanCity_House4_EventScript_NoNews:: msgbox CeruleanCity_House4_Text_NothingEntertaining release end -CeruleanCity_House4_EventScript_News1:: +@ Small reward for receiving Wonder News from friend +CeruleanCity_House4_EventScript_Reward_RecvSmall:: call CeruleanCity_House4_EventScript_MovementReactionToNews msgbox CeruleanCity_House4_Text_NewNewsInformativeHaveThis - giveitem VAR_0x8008 + giveitem REWARD_ITEM goto_if_eq VAR_RESULT, FALSE, CeruleanCity_House4_EventScript_NoRoomForBerries release end -CeruleanCity_House4_EventScript_News2:: +@ Big reward for receiving Wonder News from non-friend source +CeruleanCity_House4_EventScript_Reward_RecvBig:: call CeruleanCity_House4_EventScript_MovementReactionToNews msgbox CeruleanCity_House4_Text_IncredibleNewsHaveBerries - giveitem VAR_0x8008, 4 + giveitem REWARD_ITEM, 4 goto_if_eq VAR_RESULT, FALSE, CeruleanCity_House4_EventScript_NoRoomForBerries release end -CeruleanCity_House4_EventScript_NewsNotSpread:: +@ Player has not recently sent Wonder News +CeruleanCity_House4_EventScript_Waiting:: applymovement LOCALID_WONDER_NEWS_BERRY_MAN, Common_Movement_FacePlayer waitmovement 0 msgbox CeruleanCity_House4_Text_WishCouldShareNewsWithOthers release end -CeruleanCity_House4_EventScript_NewsSpread1:: +@ Small reward for sending Wonder News every 1-3 times +CeruleanCity_House4_EventScript_Reward_SentSmall:: call CeruleanCity_House4_EventScript_MovementReactionToNews msgbox CeruleanCity_House4_Text_ThanksForSpreadingNewsTakeThis - giveitem VAR_0x8008 + giveitem REWARD_ITEM goto_if_eq VAR_RESULT, FALSE, CeruleanCity_House4_EventScript_NoRoomForBerries release end -CeruleanCity_House4_EventScript_NewsSpread2:: +@ Big reward for sending Wonder News every 4th time +CeruleanCity_House4_EventScript_Reward_SentBig:: call CeruleanCity_House4_EventScript_MovementReactionToNews msgbox CeruleanCity_House4_Text_MagnificentNewsSpreadHaveBerries - giveitem VAR_0x8008, 4 + giveitem REWARD_ITEM, 4 goto_if_eq VAR_RESULT, FALSE, CeruleanCity_House4_EventScript_NoRoomForBerries release end -CeruleanCity_House4_EventScript_NewsDone:: +@ Player has hit reward limit and must wait to receive new rewards +CeruleanCity_House4_EventScript_AtMax:: applymovement LOCALID_WONDER_NEWS_BERRY_MAN, Common_Movement_FacePlayer waitmovement 0 msgbox CeruleanCity_House4_Text_EnjoyingMyselfWithAllSortsOfNews diff --git a/data/mystery_event_msg.s b/data/mystery_event_msg.s index fed033c39..d4fe7faf2 100644 --- a/data/mystery_event_msg.s +++ b/data/mystery_event_msg.s @@ -17,9 +17,9 @@ MysteryEventScript_StampCard:: setvaddress MysteryEventScript_StampCard setorcopyvar VAR_RESULT, 1 - specialvar VAR_0x8008, BattleCardAction + specialvar VAR_0x8008, GetMysteryGiftCardStat setorcopyvar VAR_RESULT, 0 - specialvar VAR_0x8009, BattleCardAction + specialvar VAR_0x8009, GetMysteryGiftCardStat subvar VAR_0x8008, VAR_0x8009 buffernumberstring STR_VAR_1, VAR_0x8008 lock @@ -162,7 +162,7 @@ MysteryEventScript_BattleCard:: setvaddress MysteryEventScript_BattleCard vgoto_if_set FLAG_MYSTERY_GIFT_DONE, MysteryEventScript_BattleCardInfo setorcopyvar VAR_RESULT, 2 - specialvar VAR_0x8008, BattleCardAction + specialvar VAR_0x8008, GetMysteryGiftCardStat vgoto_if_ne VAR_0x8008, 3, MysteryEventScript_BattleCardInfo lock faceplayer diff --git a/data/specials.inc b/data/specials.inc index 5c6e5eb0c..be6e3d575 100644 --- a/data/specials.inc +++ b/data/specials.inc @@ -398,10 +398,10 @@ gSpecials:: def_special BufferUnionRoomPlayerName def_special QuestLog_StartRecordingInputsAfterDeferredEvent def_special GetMartClerkObjectId - def_special BattleCardAction + def_special GetMysteryGiftCardStat def_special GetQuestLogState def_special QuestLog_CutRecording - def_special GetMENewsJisanItemAndState + def_special WonderNews_GetRewardInfo def_special GetPCBoxToSendMon def_special OpenMuseumFossilPic def_special CloseMuseumFossilPic diff --git a/graphics/interface/unk_textbox_border.png b/graphics/interface/mystery_gift_textbox_border.png similarity index 100% rename from graphics/interface/unk_textbox_border.png rename to graphics/interface/mystery_gift_textbox_border.png diff --git a/include/constants/mystery_gift.h b/include/constants/mystery_gift.h index 8ff71c3aa..13eb7f103 100644 --- a/include/constants/mystery_gift.h +++ b/include/constants/mystery_gift.h @@ -44,4 +44,12 @@ #define WONDER_CARD_FLAG_OFFSET 1000 +#define NEWS_REWARD_NONE 0 +#define NEWS_REWARD_RECV_SMALL 1 +#define NEWS_REWARD_RECV_BIG 2 +#define NEWS_REWARD_WAITING 3 +#define NEWS_REWARD_SENT_SMALL 4 +#define NEWS_REWARD_SENT_BIG 5 +#define NEWS_REWARD_AT_MAX 6 + #endif //GUARD_CONSTANTS_MYSTERY_GIFT_H diff --git a/include/global.h b/include/global.h index 417cee4f7..3c643f184 100644 --- a/include/global.h +++ b/include/global.h @@ -628,8 +628,8 @@ struct FameCheckerSaveData struct WonderNewsMetadata { u8 newsType:2; - u8 unk_0_2:3; - u8 unk_0_5:3; + u8 sentRewardCounter:3; + u8 rewardCounter:3; u8 berry; }; diff --git a/include/mystery_gift_link.h b/include/mystery_gift_link.h index 8f36d9108..32100db5f 100644 --- a/include/mystery_gift_link.h +++ b/include/mystery_gift_link.h @@ -2,7 +2,6 @@ #define GUARD_MYSTERY_GIFT_LINK_H #define MG_LINK_BUFFER_SIZE 0x400 -#define ME_SEND_BUF_SIZE MG_LINK_BUFFER_SIZE // Send/receive ids for the Client/Server to make sure // they're sending/receiving the same thing diff --git a/include/mystery_gift_server.h b/include/mystery_gift_server.h index 64bb9e9bf..9832cb05a 100644 --- a/include/mystery_gift_server.h +++ b/include/mystery_gift_server.h @@ -49,7 +49,7 @@ enum { // 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) .flag = sizeof(pointer), .parameter = pointer +#define PTR_ARG(pointer) .param = sizeof(pointer), .ptr = pointer // IDs for server messages when ending a script. // Given as the parameter to SVR_RETURN, and resolved to text in GetServerResultMessage @@ -74,8 +74,8 @@ enum { struct MysteryGiftServerCmd { u32 instr; - bool32 flag; - const void *parameter; + bool32 param; + const void *ptr; }; struct MysteryGiftServer diff --git a/src/easy_chat.c b/src/easy_chat.c index 563a7bd5c..4a08a1afb 100644 --- a/src/easy_chat.c +++ b/src/easy_chat.c @@ -476,7 +476,7 @@ void InitQuestionnaireWords(void) { s32 i; u16 *ptr = GetQuestionnaireWordsPtr(); - for (i = 0; i < 4; i++) + for (i = 0; i < NUM_QUESTIONNAIRE_WORDS; i++) ptr[i] = EC_WORD_UNDEFINED; } diff --git a/src/field_specials.c b/src/field_specials.c index 45fc701a9..331a32b15 100644 --- a/src/field_specials.c +++ b/src/field_specials.c @@ -1950,20 +1950,20 @@ void QuestLog_TryRecordDepartedLocation(void) } } -u16 BattleCardAction(void) +u16 GetMysteryGiftCardStat(void) { switch (gSpecialVar_Result) { - case 0: - return MysteryGift_GetCardStat(3); - case 1: - return MysteryGift_GetCardStat(4); - case 2: - return MysteryGift_GetCardStat(0); - case 3: - return MysteryGift_GetCardStat(1); - case 4: - return MysteryGift_GetCardStat(2); + case GET_NUM_STAMPS: + return MysteryGift_GetCardStat(CARD_STAT_NUM_STAMPS); + case GET_MAX_STAMPS: + return MysteryGift_GetCardStat(CARD_STAT_MAX_STAMPS); + case GET_CARD_BATTLES_WON: + return MysteryGift_GetCardStat(CARD_STAT_BATTLES_WON); + case GET_CARD_BATTLES_LOST: + return MysteryGift_GetCardStat(CARD_STAT_BATTLES_LOST); + case GET_CARD_NUM_TRADES: + return MysteryGift_GetCardStat(CARD_STAT_NUM_TRADES); default: AGB_ASSERT_EX(0, ABSPATH("scr_tool.c"), 3873); return 0; diff --git a/src/mystery_gift_client.c b/src/mystery_gift_client.c index dc1830b60..ab25ceb43 100644 --- a/src/mystery_gift_client.c +++ b/src/mystery_gift_client.c @@ -99,7 +99,6 @@ static void MysteryGiftClient_InitSendWord(struct MysteryGiftClient * client, u3 static u32 Client_Init(struct MysteryGiftClient * client) { - // init memcpy(client->script, gMysteryGiftClientScript_Init, MG_LINK_BUFFER_SIZE); client->cmdidx = 0; client->funcId = FUNC_RUN; diff --git a/src/mystery_gift_link.c b/src/mystery_gift_link.c index 0ef2eb84a..f066574e9 100644 --- a/src/mystery_gift_link.c +++ b/src/mystery_gift_link.c @@ -55,7 +55,7 @@ void MysteryGiftLink_InitSend(struct MysteryGiftLink * link, u32 ident, const vo if (size != 0) link->sendSize = size; else - link->sendSize = ME_SEND_BUF_SIZE; + link->sendSize = MG_LINK_BUFFER_SIZE; link->sendBuffer = src; } @@ -99,7 +99,7 @@ static bool32 MGL_Receive(struct MysteryGiftLink * link) MGL_ReceiveBlock(link->recvPlayerId, &header, sizeof(header)); link->recvSize = header.size; link->recvCRC = header.crc; - if (link->recvSize > ME_SEND_BUF_SIZE) + if (link->recvSize > MG_LINK_BUFFER_SIZE) { LinkRfu_FatalError(); return FALSE; @@ -167,7 +167,7 @@ static bool32 MGL_Send(struct MysteryGiftLink * link) link->sendCRC = header.crc; link->sendCounter = 0; SendBlock(0, &header, sizeof(header)); - ++link->state; + link->state++; } break; case 1: diff --git a/src/mystery_gift_menu.c b/src/mystery_gift_menu.c index 09c1b9378..7a711aacf 100644 --- a/src/mystery_gift_menu.c +++ b/src/mystery_gift_menu.c @@ -30,8 +30,8 @@ static void CreateMysteryGiftTask(void); static void Task_MysteryGift(u8 taskId); extern void CreateEReaderTask(void); -static const u16 sTextboxBorder_Pal[] = INCBIN_U16("graphics/interface/unk_textbox_border.gbapal"); -static const u32 sTextboxBorder_Gfx[] = INCBIN_U32("graphics/interface/unk_textbox_border.4bpp.lz"); +static const u16 sTextboxBorder_Pal[] = INCBIN_U16("graphics/interface/mystery_gift_textbox_border.gbapal"); +static const u32 sTextboxBorder_Gfx[] = INCBIN_U32("graphics/interface/mystery_gift_textbox_border.4bpp.lz"); struct MysteryGiftTaskData { @@ -344,7 +344,7 @@ static const u8 *const sUnusedMenuTexts[] = { ALIGNED(4) static const u8 sTextColors_TopMenu[3] = { 0, 1, 2 }; ALIGNED(4) static const u8 sTextColors_TopMenu_Copy[3] = { 0, 1, 2 }; -ALIGNED(4) static const u8 sMG_Ereader_TextColor_2[3] = { 1, 2, 3 }; +ALIGNED(4) static const u8 sMG_Ereader_TextColor_2[3] = { 1, 2, 3 }; static const u8 sText_Test[] = _("テスト"); static const u8 sText_EonTicket[] = _("むげんのチケット"); diff --git a/src/mystery_gift_scripts.c b/src/mystery_gift_scripts.c index 0af0f2346..ef781c5af 100644 --- a/src/mystery_gift_scripts.c +++ b/src/mystery_gift_scripts.c @@ -153,8 +153,8 @@ static const struct MysteryGiftServerCmd sServerScript_TossPrompt[] = { {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, .parameter = gServerScript_ClientCanceledCard} // Kept old card, cancel new one + {SVR_GOTO_IF_EQ, FALSE, sServerScript_SendCard}, // Tossed old card, send new one + {SVR_GOTO, .ptr = gServerScript_ClientCanceledCard} // Kept old card, cancel new one }; static const struct MysteryGiftServerCmd sServerScript_HasCard[] = { @@ -179,7 +179,7 @@ const struct MysteryGiftServerCmd gMysteryGiftServerScript_SendWonderNews[] = { {SVR_COPY_GAME_DATA}, {SVR_CHECK_GAME_DATA}, {SVR_GOTO_IF_EQ, FALSE, sServerScript_CantSend}, - {SVR_GOTO, .parameter = sServerScript_SendNews}, + {SVR_GOTO, .ptr = sServerScript_SendNews}, }; const struct MysteryGiftServerCmd gMysteryGiftServerScript_SendWonderCard[] = { @@ -194,5 +194,5 @@ const struct MysteryGiftServerCmd gMysteryGiftServerScript_SendWonderCard[] = { {SVR_CHECK_EXISTING_CARD}, {SVR_GOTO_IF_EQ, HAS_DIFF_CARD, sServerScript_TossPrompt}, {SVR_GOTO_IF_EQ, HAS_NO_CARD, sServerScript_SendCard}, - {SVR_GOTO, .parameter = sServerScript_HasCard} // HAS_SAME_CARD + {SVR_GOTO, .ptr = sServerScript_HasCard} // HAS_SAME_CARD }; diff --git a/src/mystery_gift_server.c b/src/mystery_gift_server.c index 9c6868b6e..f3b2af2f5 100644 --- a/src/mystery_gift_server.c +++ b/src/mystery_gift_server.c @@ -4,6 +4,24 @@ #include "mystery_gift.h" #include "mystery_gift_server.h" +// Assert statements use the original GF names, which are defined below. +// Note that their name "flag" is especially misleading, +// as it's not a boolean (for example it can contain a size argument). +// 'parameter' is shortened to param explicitly to avoid a collision with +// the original name for a different field. +#define mainseqno funcId +#define func_tbl sFuncTable +#define parameter ptr +#define flag param +#define ME_SEND_BUF_SIZE MG_LINK_BUFFER_SIZE +#define FILE ABSPATH("mevent_server.c") + +#define ASSERT_PTR_EMPTY(lineNum) AGB_ASSERT_EX(cmd->parameter == NULL, FILE, (lineNum)); +#define ASSERT_PARAM_EMPTY(lineNum) AGB_ASSERT_EX(cmd->flag == FALSE, FILE, (lineNum)); +#define ASSERT_PTR_PARAM_EMPTY(lineNum) AGB_ASSERT_EX(cmd->flag == FALSE && cmd->parameter == NULL, FILE, (lineNum)); +#define ASSERT_VALID_FUNC(lineNum) AGB_ASSERT_EX(svr->mainseqno < NELEMS(func_tbl), FILE, (lineNum)); +#define ASSERT_SIZE_OK(lineNum) AGB_ASSERT_EX(size <= ME_SEND_BUF_SIZE, FILE, (lineNum)); + enum { FUNC_INIT, FUNC_DONE, @@ -54,7 +72,7 @@ static void MysteryGiftServer_Init(struct MysteryGiftServer * svr, const void *s svr->funcId = FUNC_INIT; svr->card = AllocZeroed(sizeof(*svr->card)); svr->news = AllocZeroed(sizeof(*svr->news)); - svr->recvBuffer = AllocZeroed(ME_SEND_BUF_SIZE); + svr->recvBuffer = AllocZeroed(MG_LINK_BUFFER_SIZE); svr->linkGameData = AllocZeroed(sizeof(*svr->linkGameData)); svr->script = script; svr->cmdidx = 0; @@ -71,7 +89,7 @@ static void MysteryGiftServer_Free(struct MysteryGiftServer * svr) static void MysteryGiftServer_InitSend(struct MysteryGiftServer * svr, u32 ident, const void *src, u32 size) { - AGB_ASSERT_EX(size <= ME_SEND_BUF_SIZE, ABSPATH("mevent_server.c"), 257); + ASSERT_SIZE_OK(257); MysteryGiftLink_InitSend(&svr->manager, ident, src, size); } @@ -130,136 +148,136 @@ static u32 Server_Run(struct MysteryGiftServer * svr) switch (cmd->instr) { case SVR_RETURN: - AGB_ASSERT_EX(cmd->parameter == NULL, ABSPATH("mevent_server.c"), 354); + ASSERT_PTR_EMPTY(354); svr->funcId = FUNC_DONE; - svr->param = cmd->flag; // Set for endVal in MysteryGiftServer_Run + svr->param = cmd->param; // Set for endVal in MysteryGiftServer_Run break; case SVR_SEND: svr->funcId = FUNC_SEND; break; case SVR_RECV: - AGB_ASSERT_EX(cmd->parameter == NULL, ABSPATH("mevent_server.c"), 364); - MysteryGiftLink_InitRecv(&svr->manager, cmd->flag, svr->recvBuffer); + ASSERT_PTR_EMPTY(364); + MysteryGiftLink_InitRecv(&svr->manager, cmd->param, svr->recvBuffer); svr->funcId = FUNC_RECV; break; case SVR_GOTO: - AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 370); + ASSERT_PARAM_EMPTY(370); svr->cmdidx = 0; - svr->script = cmd->parameter; + svr->script = cmd->ptr; break; case SVR_COPY_GAME_DATA: - AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 376); - AGB_ASSERT_EX(cmd->parameter == NULL, ABSPATH("mevent_server.c"), 377); + ASSERT_PARAM_EMPTY(376); + ASSERT_PTR_EMPTY(377); memcpy(svr->linkGameData, svr->recvBuffer, sizeof(*svr->linkGameData)); break; case SVR_CHECK_GAME_DATA: - AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 382); - AGB_ASSERT_EX(cmd->parameter == NULL, ABSPATH("mevent_server.c"), 383); + ASSERT_PARAM_EMPTY(382); + ASSERT_PTR_EMPTY(383); svr->param = MysteryGift_ValidateLinkGameData(svr->linkGameData); break; case SVR_GOTO_IF_EQ: - if (svr->param == cmd->flag) + if (svr->param == cmd->param) { svr->cmdidx = 0; - svr->script = cmd->parameter; + svr->script = cmd->ptr; } break; case SVR_CHECK_EXISTING_CARD: - AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 396); - ptr = MysteryGiftServer_GetSendData(cmd->parameter, svr->card); + ASSERT_PARAM_EMPTY(396); + ptr = MysteryGiftServer_GetSendData(cmd->ptr, svr->card); svr->param = MysteryGift_CompareCardFlags(ptr, svr->linkGameData, ptr); break; case SVR_READ_RESPONSE: - AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 402); - AGB_ASSERT_EX(cmd->parameter == NULL, ABSPATH("mevent_server.c"), 403); + ASSERT_PARAM_EMPTY(402); + ASSERT_PTR_EMPTY(403); svr->param = *(u32 *)svr->recvBuffer; break; case SVR_CHECK_EXISTING_STAMPS: - AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 408); - ptr = MysteryGiftServer_GetSendData(cmd->parameter, &svr->stamp); + ASSERT_PARAM_EMPTY(408); + ptr = MysteryGiftServer_GetSendData(cmd->ptr, &svr->stamp); svr->param = MysteryGift_CheckStamps(ptr, svr->linkGameData, ptr); break; case SVR_GET_CARD_STAT: - AGB_ASSERT_EX(cmd->parameter == NULL, ABSPATH("mevent_server.c"), 415); - svr->param = MysteryGift_GetCardStatFromLinkData(svr->linkGameData, cmd->flag); + ASSERT_PTR_EMPTY(415); + svr->param = MysteryGift_GetCardStatFromLinkData(svr->linkGameData, cmd->param); break; case SVR_CHECK_QUESTIONNAIRE: - AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 420); - svr->param = MysteryGift_DoesQuestionnaireMatch(svr->linkGameData, cmd->parameter); + ASSERT_PARAM_EMPTY(420); + svr->param = MysteryGift_DoesQuestionnaireMatch(svr->linkGameData, cmd->ptr); break; case SVR_COMPARE: - AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 426); - svr->param = MysteryGiftServer_Compare(cmd->parameter, *(void **)svr->recvBuffer); + ASSERT_PARAM_EMPTY(426); + svr->param = MysteryGiftServer_Compare(cmd->ptr, *(void **)svr->recvBuffer); break; case SVR_LOAD_NEWS: - AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 432); - MysteryGiftServer_InitSend(svr, MG_LINKID_NEWS, MysteryGiftServer_GetSendData(cmd->parameter, svr->news), sizeof(struct WonderNews)); + ASSERT_PARAM_EMPTY(432); + MysteryGiftServer_InitSend(svr, MG_LINKID_NEWS, MysteryGiftServer_GetSendData(cmd->ptr, svr->news), sizeof(struct WonderNews)); break; case SVR_LOAD_CARD: - AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 438); - MysteryGiftServer_InitSend(svr, MG_LINKID_CARD, MysteryGiftServer_GetSendData(cmd->parameter, svr->card), sizeof(struct WonderCard)); + ASSERT_PARAM_EMPTY(438); + MysteryGiftServer_InitSend(svr, MG_LINKID_CARD, MysteryGiftServer_GetSendData(cmd->ptr, svr->card), sizeof(struct WonderCard)); break; case SVR_LOAD_STAMP: - AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 444); - MysteryGiftServer_InitSend(svr, MG_LINKID_STAMP, MysteryGiftServer_GetSendData(cmd->parameter, &svr->stamp), sizeof(svr->stamp)); + ASSERT_PARAM_EMPTY(444); + MysteryGiftServer_InitSend(svr, MG_LINKID_STAMP, MysteryGiftServer_GetSendData(cmd->ptr, &svr->stamp), sizeof(svr->stamp)); break; case SVR_LOAD_RAM_SCRIPT: - if (cmd->parameter == NULL) + if (cmd->ptr == NULL) MysteryGiftServer_InitSend(svr, MG_LINKID_RAM_SCRIPT, svr->ramScript, svr->ramScriptSize); else - MysteryGiftServer_InitSend(svr, MG_LINKID_RAM_SCRIPT, cmd->parameter, cmd->flag); + MysteryGiftServer_InitSend(svr, MG_LINKID_RAM_SCRIPT, cmd->ptr, cmd->param); break; case SVR_LOAD_CLIENT_SCRIPT: - if (cmd->parameter == NULL) + if (cmd->ptr == NULL) MysteryGiftServer_InitSend(svr, MG_LINKID_CLIENT_SCRIPT, svr->clientScript, svr->clientScriptSize); else - MysteryGiftServer_InitSend(svr, MG_LINKID_CLIENT_SCRIPT, cmd->parameter, cmd->flag); + MysteryGiftServer_InitSend(svr, MG_LINKID_CLIENT_SCRIPT, cmd->ptr, cmd->param); break; case SVR_LOAD_EREADER_TRAINER: - AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 466); - MysteryGiftServer_InitSend(svr, MG_LINKID_EREADER_TRAINER, cmd->parameter, 188); + ASSERT_PARAM_EMPTY(466); + MysteryGiftServer_InitSend(svr, MG_LINKID_EREADER_TRAINER, cmd->ptr, sizeof(struct BattleTowerEReaderTrainer)); break; case SVR_LOAD_MSG: - MysteryGiftServer_InitSend(svr, MG_LINKID_DYNAMIC_MSG, cmd->parameter, cmd->flag); + MysteryGiftServer_InitSend(svr, MG_LINKID_DYNAMIC_MSG, cmd->ptr, cmd->param); break; case SVR_LOAD_UNK_2: - MysteryGiftServer_InitSend(svr, MG_LINKID_UNK_2, cmd->parameter, cmd->flag); + MysteryGiftServer_InitSend(svr, MG_LINKID_UNK_2, cmd->ptr, cmd->param); break; case SVR_COPY_CARD: - AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 481); - memcpy(svr->card, cmd->parameter, sizeof(*svr->card)); + ASSERT_PARAM_EMPTY(481); + memcpy(svr->card, cmd->ptr, sizeof(*svr->card)); break; case SVR_COPY_NEWS: - AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 486); - memcpy(svr->news, cmd->parameter, sizeof(*svr->news)); + ASSERT_PARAM_EMPTY(486); + memcpy(svr->news, cmd->ptr, sizeof(*svr->news)); break; case SVR_COPY_STAMP: - AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 491); - svr->stamp = *(u32 *)cmd->parameter; + ASSERT_PARAM_EMPTY(491); + svr->stamp = *(u32 *)cmd->ptr; break; case SVR_SET_RAM_SCRIPT: - svr->ramScript = cmd->parameter; - svr->ramScriptSize = cmd->flag; + svr->ramScript = cmd->ptr; + svr->ramScriptSize = cmd->param; break; case SVR_SET_CLIENT_SCRIPT: - svr->clientScript = cmd->parameter; - svr->clientScriptSize = cmd->flag; + svr->clientScript = cmd->ptr; + svr->clientScriptSize = cmd->param; break; case SVR_COPY_SAVED_CARD: - AGB_ASSERT_EX(cmd->flag == FALSE && cmd->parameter == NULL, ABSPATH("mevent_server.c"), 506); + ASSERT_PTR_PARAM_EMPTY(506); memcpy(svr->card, GetSavedWonderCard(), sizeof(*svr->card)); DisableWonderCardSending(svr->card); break; case SVR_COPY_SAVED_NEWS: - AGB_ASSERT_EX(cmd->flag == FALSE && cmd->parameter == NULL, ABSPATH("mevent_server.c"), 512); + ASSERT_PTR_PARAM_EMPTY(512); memcpy(svr->news, GetSavedWonderNews(), sizeof(*svr->news)); break; case SVR_COPY_SAVED_RAM_SCRIPT: - AGB_ASSERT_EX(cmd->flag == FALSE && cmd->parameter == NULL, ABSPATH("mevent_server.c"), 517); + ASSERT_PTR_PARAM_EMPTY(517); svr->ramScript = GetSavedRamScriptIfValid(); break; case SVR_LOAD_UNK_1: - MysteryGiftServer_InitSend(svr, MG_LINKID_UNK_1, cmd->parameter, cmd->flag); + MysteryGiftServer_InitSend(svr, MG_LINKID_UNK_1, cmd->ptr, cmd->param); break; } @@ -276,14 +294,9 @@ static u32 (*const sFuncTable[])(struct MysteryGiftServer *) = { static u32 MysteryGiftServer_CallFunc(struct MysteryGiftServer * svr) { -// Original GF names -#define mainseqno funcId -#define func_tbl sFuncTable u32 response; - AGB_ASSERT_EX(svr->mainseqno < NELEMS(func_tbl), ABSPATH("mevent_server.c"), 546); + ASSERT_VALID_FUNC(546) response = sFuncTable[svr->funcId](svr); - AGB_ASSERT_EX(svr->mainseqno < NELEMS(func_tbl), ABSPATH("mevent_server.c"), 548); + ASSERT_VALID_FUNC(548) return response; -#undef mainseqno -#undef func_tbl } diff --git a/src/wonder_news.c b/src/wonder_news.c index 4e7c4f472..03dd4c73f 100644 --- a/src/wonder_news.c +++ b/src/wonder_news.c @@ -5,27 +5,18 @@ #include "wonder_news.h" #include "constants/items.h" -/* - Wonder News related functions. - Because this feature is largely unused, the names in here are - mostly nebulous and without a real indication of purpose. -*/ +// Every 4th reward for sending Wonder News to a link partner is a "big" reward. +#define MAX_SENT_REWARD 4 -enum { - NEWS_VAL_INVALID, - NEWS_VAL_RECV_FRIEND, - NEWS_VAL_RECV_WIRELESS, - NEWS_VAL_NONE, - NEWS_VAL_SENT, - NEWS_VAL_SENT_MAX, - NEWS_VAL_GET_MAX, -}; +// Only up to 5 rewards can be received in a short period. After this the player +// must take 500 steps before any more rewards can be received. +#define MAX_REWARD 5 -static u32 GetMENewsJisanRewardItem(struct WonderNewsMetadata *); -static void MENewsJisanIncrementCounterUnk0_5(struct WonderNewsMetadata *); -static u32 GetMENewsJisanState(struct WonderNewsMetadata *); -static void MENewsJisanIncrementCounterUnk0_2(struct WonderNewsMetadata *); -static void MENewsJisanResetCounterUnk0_2(struct WonderNewsMetadata *); +static u32 GetRewardItem(struct WonderNewsMetadata *); +static u32 GetRewardType(struct WonderNewsMetadata *); +static void IncrementRewardCounter(struct WonderNewsMetadata *); +static void IncrementSentRewardCounter(struct WonderNewsMetadata *); +static void ResetSentRewardCounter(struct WonderNewsMetadata *); void WonderNews_SetReward(u32 newsType) { @@ -38,9 +29,11 @@ void WonderNews_SetReward(u32 newsType) break; case WONDER_NEWS_RECV_FRIEND: case WONDER_NEWS_RECV_WIRELESS: + // Random berry between ITEM_RAZZ_BERRY and ITEM_NOMEL_BERRY data->berry = (Random() % 15) + ITEM_TO_BERRY(ITEM_RAZZ_BERRY); break; case WONDER_NEWS_SENT: + // Random berry between ITEM_CHERI_BERRY and ITEM_IAPAPA_BERRY data->berry = (Random() % 15) + ITEM_TO_BERRY(ITEM_CHERI_BERRY); break; } @@ -48,12 +41,12 @@ void WonderNews_SetReward(u32 newsType) void WonderNews_Reset(void) { - struct WonderNewsMetadata *r5 = GetSavedWonderNewsMetadata(); + struct WonderNewsMetadata *data = GetSavedWonderNewsMetadata(); - r5->newsType = 0; - r5->unk_0_2 = 0; - r5->unk_0_5 = 0; - r5->berry = 0; + data->newsType = WONDER_NEWS_NONE; + data->sentRewardCounter = 0; + data->rewardCounter = 0; + data->berry = 0; VarSet(VAR_WONDER_NEWS_STEP_COUNTER, 0); } @@ -62,100 +55,100 @@ void WonderNews_IncrementStepCounter(void) u16 *stepCounter = GetVarPointer(VAR_WONDER_NEWS_STEP_COUNTER); struct WonderNewsMetadata *data = GetSavedWonderNewsMetadata(); - if (data->unk_0_5 > 4 && ++(*stepCounter) >= 500) + // If the player has reached the reward limit, start counting steps. + // When they reach 500 steps reset the reward counter to allow them to + // receive rewards again. + if (data->rewardCounter >= MAX_REWARD && ++(*stepCounter) >= 500) { - data->unk_0_5 = 0; + data->rewardCounter = 0; *stepCounter = 0; } } -u16 GetMENewsJisanItemAndState(void) +u16 WonderNews_GetRewardInfo(void) { u16 *result = &gSpecialVar_Result; struct WonderNewsMetadata *data = GetSavedWonderNewsMetadata(); - u16 r5; + u16 rewardType; if (!IsMysteryGiftEnabled() || !ValidateSavedWonderNews()) - return 0; + return NEWS_REWARD_NONE; - r5 = GetMENewsJisanState(data); + rewardType = GetRewardType(data); - switch (r5) + switch (rewardType) { - case 0: + case NEWS_REWARD_RECV_SMALL: + case NEWS_REWARD_RECV_BIG: + *result = GetRewardItem(data); break; - case 1: - *result = GetMENewsJisanRewardItem(data); + case NEWS_REWARD_SENT_SMALL: + *result = GetRewardItem(data); + IncrementSentRewardCounter(data); break; - case 2: - *result = GetMENewsJisanRewardItem(data); + case NEWS_REWARD_SENT_BIG: + *result = GetRewardItem(data); + ResetSentRewardCounter(data); break; - case 3: - break; - case 4: - *result = GetMENewsJisanRewardItem(data); - MENewsJisanIncrementCounterUnk0_2(data); - break; - case 5: - *result = GetMENewsJisanRewardItem(data); - MENewsJisanResetCounterUnk0_2(data); - break; - case 6: + case NEWS_REWARD_NONE: + case NEWS_REWARD_WAITING: + case NEWS_REWARD_AT_MAX: break; } - return r5; + return rewardType; } -static u32 GetMENewsJisanRewardItem(struct WonderNewsMetadata *a0) +static u32 GetRewardItem(struct WonderNewsMetadata *data) { - u32 r4; + u32 itemId; - a0->newsType = 0; - r4 = a0->berry + FIRST_BERRY_INDEX - 1; - a0->berry = 0; - MENewsJisanIncrementCounterUnk0_5(a0); - return r4; + data->newsType = WONDER_NEWS_NONE; + itemId = data->berry + FIRST_BERRY_INDEX - 1; + data->berry = 0; + IncrementRewardCounter(data); + return itemId; } -static void MENewsJisanResetCounterUnk0_2(struct WonderNewsMetadata *a0) +static void ResetSentRewardCounter(struct WonderNewsMetadata *data) { - a0->unk_0_2 = 0; + data->sentRewardCounter = 0; } -static void MENewsJisanIncrementCounterUnk0_2(struct WonderNewsMetadata *a0) +// Track number of times a reward was received (or attmepted to receive) for sending Wonder News to a link partner. +static void IncrementSentRewardCounter(struct WonderNewsMetadata *data) { - a0->unk_0_2++; - if ((u8)a0->unk_0_2 > 4) - a0->unk_0_2 = 4; + data->sentRewardCounter++; + if (data->sentRewardCounter > MAX_SENT_REWARD) + data->sentRewardCounter = MAX_SENT_REWARD; } -static void MENewsJisanIncrementCounterUnk0_5(struct WonderNewsMetadata *a0) +static void IncrementRewardCounter(struct WonderNewsMetadata *data) { - a0->unk_0_5++; - if ((u8)a0->unk_0_5 > 5) - a0->unk_0_5 = 5; + data->rewardCounter++; + if (data->rewardCounter > MAX_REWARD) + data->rewardCounter = MAX_REWARD; } -static u32 GetMENewsJisanState(struct WonderNewsMetadata *data) +static u32 GetRewardType(struct WonderNewsMetadata *data) { - if (data->unk_0_5 == 5) - return 6; + if (data->rewardCounter == MAX_REWARD) + return NEWS_REWARD_AT_MAX; switch (data->newsType) { case WONDER_NEWS_NONE: - return 3; + return NEWS_REWARD_WAITING; case WONDER_NEWS_RECV_FRIEND: - return 1; + return NEWS_REWARD_RECV_SMALL; case WONDER_NEWS_RECV_WIRELESS: - return 2; + return NEWS_REWARD_RECV_BIG; case WONDER_NEWS_SENT: - if (data->unk_0_2 < 3) - return 4; - return 5; + if (data->sentRewardCounter < MAX_SENT_REWARD - 1) + return NEWS_REWARD_SENT_SMALL; + return NEWS_REWARD_SENT_BIG; default: AGB_ASSERT_EX(0, ABSPATH("menews_jisan.c"), 383); - return 0; + return NEWS_REWARD_NONE; } }