summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/battle_script_commands.c2
-rw-r--r--src/battle_setup.c6
-rw-r--r--src/cable_club.c12
-rw-r--r--src/crt0.s2
-rw-r--r--src/easy_chat.c2
-rwxr-xr-xsrc/ereader_screen.c32
-rw-r--r--src/event_data.c60
-rw-r--r--src/field_control_avatar.c6
-rwxr-xr-xsrc/field_effect_helpers.c10
-rw-r--r--src/field_specials.c121
-rw-r--r--src/hall_of_fame.c2
-rw-r--r--src/international_string_util.c49
-rwxr-xr-xsrc/item_use.c2
-rw-r--r--src/link_rfu_2.c4
-rw-r--r--src/main_menu.c12
-rw-r--r--src/mauville_old_man.c963
-rw-r--r--src/metatile_behavior.c107
-rwxr-xr-xsrc/mevent2.c630
-rw-r--r--src/mevent_801BAAC.c826
-rw-r--r--src/mevent_client.c291
-rw-r--r--src/mevent_news.c148
-rw-r--r--src/mevent_scripts.c191
-rw-r--r--src/mevent_server.c295
-rw-r--r--src/mevent_server_helpers.c211
-rw-r--r--src/mystery_event_msg.c22
-rw-r--r--src/mystery_event_script.c26
-rwxr-xr-x[-rw-r--r--]src/mystery_gift.c1966
-rw-r--r--src/mystery_gift_client.c303
-rw-r--r--src/mystery_gift_link.c222
-rw-r--r--src/mystery_gift_menu.c1618
-rw-r--r--src/mystery_gift_scripts.c217
-rw-r--r--src/mystery_gift_server.c291
-rw-r--r--src/mystery_gift_view.c936
-rw-r--r--src/new_game.c4
-rw-r--r--src/player_pc.c2
-rw-r--r--src/pokedex.c228
-rw-r--r--src/pokemon_icon.c44
-rw-r--r--src/pokemon_storage_system.c4
-rw-r--r--src/pokenav_conditions_1.c2
-rw-r--r--src/pokenav_conditions_3.c4
-rwxr-xr-xsrc/pokenav_match_call_1.c6
-rw-r--r--src/pokenav_ribbons_1.c4
-rw-r--r--src/rotating_tile_puzzle.c10
-rw-r--r--src/save_location.c54
-rw-r--r--src/scrcmd.c2
-rw-r--r--src/script.c15
-rw-r--r--src/starter_choose.c2
-rw-r--r--src/trade.c7
-rw-r--r--src/trader.c12
-rwxr-xr-xsrc/trainer_card.c34
-rw-r--r--src/trainer_pokemon_sprites.c96
-rw-r--r--src/tv.c2
-rw-r--r--src/union_room.c50
-rwxr-xr-xsrc/union_room_chat.c149
-rw-r--r--src/wild_encounter.c2
-rw-r--r--src/wonder_news.c160
56 files changed, 5331 insertions, 5147 deletions
diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c
index 84854ebb8..92d4b9707 100644
--- a/src/battle_script_commands.c
+++ b/src/battle_script_commands.c
@@ -6062,7 +6062,7 @@ static void DrawLevelUpBannerText(void)
var = (u32)(txtPtr);
txtPtr = ConvertIntToDecimalStringN(txtPtr, monLevel, STR_CONV_MODE_LEFT_ALIGN, 3);
var = (u32)(txtPtr) - var;
- txtPtr = StringFill(txtPtr, CHAR_GENDERLESS, 4 - var);
+ txtPtr = StringFill(txtPtr, CHAR_SPACER, 4 - var);
if (monGender != MON_GENDERLESS)
{
diff --git a/src/battle_setup.c b/src/battle_setup.c
index 172bfc5be..2a716e08c 100644
--- a/src/battle_setup.c
+++ b/src/battle_setup.c
@@ -674,9 +674,11 @@ u8 BattleSetup_GetTerrainId(void)
return BATTLE_TERRAIN_MOUNTAIN;
if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING))
{
- if (MetatileBehavior_GetBridgeType(tileBehavior))
+ // Is BRIDGE_TYPE_POND_*?
+ if (MetatileBehavior_GetBridgeType(tileBehavior) != BRIDGE_TYPE_OCEAN)
return BATTLE_TERRAIN_POND;
- if (MetatileBehavior_IsBridge(tileBehavior) == TRUE)
+
+ if (MetatileBehavior_IsBridgeOverWater(tileBehavior) == TRUE)
return BATTLE_TERRAIN_WATER;
}
if (gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(ROUTE113) && gSaveBlock1Ptr->location.mapNum == MAP_NUM(ROUTE113))
diff --git a/src/cable_club.c b/src/cable_club.c
index 8db583989..3083ed9c0 100644
--- a/src/cable_club.c
+++ b/src/cable_club.c
@@ -18,7 +18,7 @@
#include "overworld.h"
#include "palette.h"
#include "union_room.h"
-#include "mevent2.h"
+#include "mystery_gift.h"
#include "script.h"
#include "script_pokemon_util.h"
#include "sound.h"
@@ -372,7 +372,7 @@ static void Task_LinkupExchangeDataWithLeader(u8 taskId)
gLocalLinkPlayerId = GetMultiplayerId();
SaveLinkPlayers(gFieldLinkPlayerCount);
card = (struct TrainerCard *)gBlockSendBuffer;
- TrainerCard_GenerateCardForPlayer(card);
+ TrainerCard_GenerateCardForLinkPlayer(card);
card->monSpecies[0] = GetMonData(&gPlayerParty[gSelectedOrderFromParty[0] - 1], MON_DATA_SPECIES, NULL);
card->monSpecies[1] = GetMonData(&gPlayerParty[gSelectedOrderFromParty[1] - 1], MON_DATA_SPECIES, NULL);
gTasks[taskId].func = Task_LinkupAwaitTrainerCardData;
@@ -420,7 +420,7 @@ static void Task_LinkupCheckStatusAfterConfirm(u8 taskId)
gLocalLinkPlayerId = GetMultiplayerId();
SaveLinkPlayers(gFieldLinkPlayerCount);
card = (struct TrainerCard *)gBlockSendBuffer;
- TrainerCard_GenerateCardForPlayer(card);
+ TrainerCard_GenerateCardForLinkPlayer(card);
card->monSpecies[0] = GetMonData(&gPlayerParty[gSelectedOrderFromParty[0] - 1], MON_DATA_SPECIES, NULL);
card->monSpecies[1] = GetMonData(&gPlayerParty[gSelectedOrderFromParty[1] - 1], MON_DATA_SPECIES, NULL);
gTasks[taskId].func = Task_LinkupAwaitTrainerCardData;
@@ -518,7 +518,7 @@ static void Task_LinkupAwaitTrainerCardData(u8 taskId)
for (index = 0; index < GetLinkPlayerCount(); index++)
{
- CopyTrainerCardData(&gTrainerCards[index], gBlockRecvBuffer[index], gLinkPlayers[index].version);
+ CopyTrainerCardData(&gTrainerCards[index], (struct TrainerCard *)gBlockRecvBuffer[index], gLinkPlayers[index].version);
}
SetSuppressLinkErrorMessage(FALSE);
@@ -1004,10 +1004,10 @@ void CB2_ReturnFromCableClubBattle(void)
switch (gBattleOutcome)
{
case B_OUTCOME_WON:
- RecordIdOfWonderCardSenderByEventType(0, gLinkPlayers[GetMultiplayerId() ^ 1].trainerId);
+ MysteryGift_TryIncrementStat(CARD_STAT_BATTLES_WON, gLinkPlayers[GetMultiplayerId() ^ 1].trainerId);
break;
case B_OUTCOME_LOST:
- RecordIdOfWonderCardSenderByEventType(1, gLinkPlayers[GetMultiplayerId() ^ 1].trainerId);
+ MysteryGift_TryIncrementStat(CARD_STAT_BATTLES_LOST, gLinkPlayers[GetMultiplayerId() ^ 1].trainerId);
break;
}
}
diff --git a/src/crt0.s b/src/crt0.s
index 835522589..672fc94f2 100644
--- a/src/crt0.s
+++ b/src/crt0.s
@@ -94,7 +94,7 @@ GPIOPortReadEnable: @ 80000C8
.byte 0x1e, 0x1e, 0x10, 0x40
- .4byte 0x0000322e @ offsetof(struct SaveBlock1, ? part-way into unk_322C)
+ .4byte 0x0000322e @ offsetof(struct SaveBlock1, ? part-way into mysteryGift)
.4byte 0x00000498 @ offsetof(struct SaveBlock1, pcItems)
.4byte 0x000031a8 @ offsetof(struct SaveBlock1, giftRibbons)
.4byte 0x000031f8 @ offsetof(struct SaveBlock1, enigmaBerry)
diff --git a/src/easy_chat.c b/src/easy_chat.c
index 79300bd52..b18d09b83 100644
--- a/src/easy_chat.c
+++ b/src/easy_chat.c
@@ -15,7 +15,7 @@
#include "graphics.h"
#include "international_string_util.h"
#include "main.h"
-#include "mevent.h"
+#include "mystery_gift.h"
#include "menu.h"
#include "overworld.h"
#include "palette.h"
diff --git a/src/ereader_screen.c b/src/ereader_screen.c
index f5edbc628..73a1b870e 100755
--- a/src/ereader_screen.c
+++ b/src/ereader_screen.c
@@ -4,7 +4,7 @@
#include "ereader_helpers.h"
#include "link.h"
#include "main.h"
-#include "mystery_gift.h"
+#include "mystery_gift_menu.h"
#include "save.h"
#include "sound.h"
#include "sprite.h"
@@ -13,7 +13,7 @@
#include "util.h"
#include "constants/songs.h"
-struct Unk81D5014
+struct EReaderTaskData
{
u16 unk0;
u16 unk2;
@@ -36,7 +36,7 @@ struct Unk03006370
u32 *unk8;
};
-static void sub_81D5084(u8);
+static void Task_EReader(u8);
struct Unk03006370 gUnknown_03006370;
@@ -209,11 +209,11 @@ static u32 sub_81D4EE4(u8 *arg0, u16 *arg1)
return 0;
}
-void task_add_00_ereader(void)
+void CreateEReaderTask(void)
{
- struct Unk81D5014 *data;
- u8 taskId = CreateTask(sub_81D5084, 0);
- data = (struct Unk81D5014 *)gTasks[taskId].data;
+ struct EReaderTaskData *data;
+ u8 taskId = CreateTask(Task_EReader, 0);
+ data = (struct EReaderTaskData *)gTasks[taskId].data;
data->unk8 = 0;
data->unk9 = 0;
data->unkA = 0;
@@ -244,13 +244,13 @@ static bool32 sub_81D5064(u16 *arg0, u16 arg1)
return FALSE;
}
-static void sub_81D5084(u8 taskId)
+static void Task_EReader(u8 taskId)
{
- struct Unk81D5014 *data = (struct Unk81D5014 *)gTasks[taskId].data;
+ struct EReaderTaskData *data = (struct EReaderTaskData *)gTasks[taskId].data;
switch (data->unk8)
{
case 0:
- if (MG_PrintTextOnWindow1AndWaitButton(&data->unk9, gJPText_ReceiveMysteryGiftWithEReader))
+ if (PrintMysteryGiftMenuMessage(&data->unk9, gJPText_ReceiveMysteryGiftWithEReader))
data->unk8 = 1;
break;
case 1:
@@ -274,7 +274,7 @@ static void sub_81D5084(u8 taskId)
}
break;
case 4:
- if (MG_PrintTextOnWindow1AndWaitButton(&data->unk9, gJPText_SelectConnectFromEReaderMenu))
+ if (PrintMysteryGiftMenuMessage(&data->unk9, gJPText_SelectConnectFromEReaderMenu))
{
AddTextPrinterToWindow1(gJPText_SelectConnectWithGBA);
sub_81D505C(&data->unk0);
@@ -323,7 +323,7 @@ static void sub_81D5084(u8 taskId)
}
break;
case 7:
- if (MG_PrintTextOnWindow1AndWaitButton(&data->unk9, gJPText_LinkIsIncorrect))
+ if (PrintMysteryGiftMenuMessage(&data->unk9, gJPText_LinkIsIncorrect))
data->unk8 = 4;
break;
case 8:
@@ -439,19 +439,19 @@ static void sub_81D5084(u8 taskId)
data->unk8 = 26;
break;
case 23:
- if (MG_PrintTextOnWindow1AndWaitButton(&data->unk9, gJPText_CardReadingHasBeenHalted))
+ if (PrintMysteryGiftMenuMessage(&data->unk9, gJPText_CardReadingHasBeenHalted))
data->unk8 = 26;
break;
case 20:
- if (MG_PrintTextOnWindow1AndWaitButton(&data->unk9, gJPText_ConnectionErrorCheckLink))
+ if (PrintMysteryGiftMenuMessage(&data->unk9, gJPText_ConnectionErrorCheckLink))
data->unk8 = 0;
break;
case 21:
- if (MG_PrintTextOnWindow1AndWaitButton(&data->unk9, gJPText_ConnectionErrorTryAgain))
+ if (PrintMysteryGiftMenuMessage(&data->unk9, gJPText_ConnectionErrorTryAgain))
data->unk8 = 0;
break;
case 22:
- if (MG_PrintTextOnWindow1AndWaitButton(&data->unk9, gJPText_WriteErrorUnableToSaveData))
+ if (PrintMysteryGiftMenuMessage(&data->unk9, gJPText_WriteErrorUnableToSaveData))
data->unk8 = 0;
break;
case 26:
diff --git a/src/event_data.c b/src/event_data.c
index 2bde09012..e2af6c3d0 100644
--- a/src/event_data.c
+++ b/src/event_data.c
@@ -114,36 +114,36 @@ bool32 IsMysteryGiftEnabled(void)
return FlagGet(FLAG_SYS_MYSTERY_GIFT_ENABLE);
}
-void ClearMysteryEventFlags(void)
-{
- FlagClear(FLAG_MYSTERY_EVENT_DONE);
- FlagClear(FLAG_MYSTERY_EVENT_1);
- FlagClear(FLAG_MYSTERY_EVENT_2);
- FlagClear(FLAG_MYSTERY_EVENT_3);
- FlagClear(FLAG_MYSTERY_EVENT_4);
- FlagClear(FLAG_MYSTERY_EVENT_5);
- FlagClear(FLAG_MYSTERY_EVENT_6);
- FlagClear(FLAG_MYSTERY_EVENT_7);
- FlagClear(FLAG_MYSTERY_EVENT_8);
- FlagClear(FLAG_MYSTERY_EVENT_9);
- FlagClear(FLAG_MYSTERY_EVENT_10);
- FlagClear(FLAG_MYSTERY_EVENT_11);
- FlagClear(FLAG_MYSTERY_EVENT_12);
- FlagClear(FLAG_MYSTERY_EVENT_13);
- FlagClear(FLAG_MYSTERY_EVENT_14);
- FlagClear(FLAG_MYSTERY_EVENT_15);
-}
-
-void ClearMysteryEventVars(void)
-{
- VarSet(VAR_EVENT_PICHU_SLOT, 0);
- VarSet(VAR_NEVER_READ_0x40DE, 0);
- VarSet(VAR_NEVER_READ_0x40DF, 0);
- VarSet(VAR_NEVER_READ_0x40E0, 0);
- VarSet(VAR_NEVER_READ_0x40E1, 0);
- VarSet(VAR_NEVER_READ_0x40E2, 0);
- VarSet(VAR_NEVER_READ_0x40E3, 0);
- VarSet(VAR_NEVER_READ_0x40E4, 0);
+void ClearMysteryGiftFlags(void)
+{
+ FlagClear(FLAG_MYSTERY_GIFT_DONE);
+ FlagClear(FLAG_MYSTERY_GIFT_1);
+ FlagClear(FLAG_MYSTERY_GIFT_2);
+ FlagClear(FLAG_MYSTERY_GIFT_3);
+ FlagClear(FLAG_MYSTERY_GIFT_4);
+ FlagClear(FLAG_MYSTERY_GIFT_5);
+ FlagClear(FLAG_MYSTERY_GIFT_6);
+ FlagClear(FLAG_MYSTERY_GIFT_7);
+ FlagClear(FLAG_MYSTERY_GIFT_8);
+ FlagClear(FLAG_MYSTERY_GIFT_9);
+ FlagClear(FLAG_MYSTERY_GIFT_10);
+ FlagClear(FLAG_MYSTERY_GIFT_11);
+ FlagClear(FLAG_MYSTERY_GIFT_12);
+ FlagClear(FLAG_MYSTERY_GIFT_13);
+ FlagClear(FLAG_MYSTERY_GIFT_14);
+ FlagClear(FLAG_MYSTERY_GIFT_15);
+}
+
+void ClearMysteryGiftVars(void)
+{
+ VarSet(VAR_GIFT_PICHU_SLOT, 0);
+ VarSet(VAR_GIFT_UNUSED_1, 0);
+ VarSet(VAR_GIFT_UNUSED_2, 0);
+ VarSet(VAR_GIFT_UNUSED_3, 0);
+ VarSet(VAR_GIFT_UNUSED_4, 0);
+ VarSet(VAR_GIFT_UNUSED_5, 0);
+ VarSet(VAR_GIFT_UNUSED_6, 0);
+ VarSet(VAR_GIFT_UNUSED_7, 0);
}
void DisableResetRTC(void)
diff --git a/src/field_control_avatar.c b/src/field_control_avatar.c
index 10f8d49bb..e58fb783b 100644
--- a/src/field_control_avatar.c
+++ b/src/field_control_avatar.c
@@ -729,9 +729,9 @@ static bool8 TryStartWarpEventScript(struct MapPosition *position, u16 metatileB
DoTeleportTileWarp();
return TRUE;
}
- if (MetatileBehavior_IsWarpOrBridge(metatileBehavior) == TRUE)
+ if (MetatileBehavior_IsBridgeOverOcean(metatileBehavior) == TRUE)
{
- // Maybe unused? This MB is used by log bridges, but there's never a warp event on them
+ // Maybe unused? This MB is used by log bridges, but there's never a warp event on them.
DoSpinExitWarp();
return TRUE;
}
@@ -762,7 +762,7 @@ static bool8 IsWarpMetatileBehavior(u16 metatileBehavior)
&& MetatileBehavior_IsAquaHideoutWarp(metatileBehavior) != TRUE
&& MetatileBehavior_IsMtPyreHole(metatileBehavior) != TRUE
&& MetatileBehavior_IsMossdeepGymWarp(metatileBehavior) != TRUE
- && MetatileBehavior_IsWarpOrBridge(metatileBehavior) != TRUE)
+ && MetatileBehavior_IsBridgeOverOcean(metatileBehavior) != TRUE)
return FALSE;
return TRUE;
}
diff --git a/src/field_effect_helpers.c b/src/field_effect_helpers.c
index 0a0e465a8..0acb15863 100755
--- a/src/field_effect_helpers.c
+++ b/src/field_effect_helpers.c
@@ -71,9 +71,15 @@ static s16 GetReflectionVerticalOffset(struct ObjectEvent *objectEvent)
static void LoadObjectReflectionPalette(struct ObjectEvent *objectEvent, struct Sprite *reflectionSprite)
{
u8 bridgeType;
- u16 bridgeReflectionVerticalOffsets[] = { 12, 28, 44 };
+ u16 bridgeReflectionVerticalOffsets[] = {
+ [BRIDGE_TYPE_POND_LOW - 1] = 12,
+ [BRIDGE_TYPE_POND_MED - 1] = 28,
+ [BRIDGE_TYPE_POND_HIGH - 1] = 44
+ };
reflectionSprite->sReflectionVerticalOffset = 0;
- if (!GetObjectEventGraphicsInfo(objectEvent->graphicsId)->disableReflectionPaletteLoad && ((bridgeType = MetatileBehavior_GetBridgeType(objectEvent->previousMetatileBehavior)) || (bridgeType = MetatileBehavior_GetBridgeType(objectEvent->currentMetatileBehavior))))
+ if (!GetObjectEventGraphicsInfo(objectEvent->graphicsId)->disableReflectionPaletteLoad
+ && ((bridgeType = MetatileBehavior_GetBridgeType(objectEvent->previousMetatileBehavior))
+ || (bridgeType = MetatileBehavior_GetBridgeType(objectEvent->currentMetatileBehavior))))
{
reflectionSprite->sReflectionVerticalOffset = bridgeReflectionVerticalOffsets[bridgeType - 1];
LoadObjectHighBridgeReflectionPalette(objectEvent, reflectionSprite->oam.paletteNum);
diff --git a/src/field_specials.c b/src/field_specials.c
index 3285ea9a4..22fd6872b 100644
--- a/src/field_specials.c
+++ b/src/field_specials.c
@@ -22,7 +22,7 @@
#include "link.h"
#include "list_menu.h"
#include "main.h"
-#include "mevent.h"
+#include "mystery_gift.h"
#include "match_call.h"
#include "menu.h"
#include "overworld.h"
@@ -56,7 +56,7 @@
#include "constants/heal_locations.h"
#include "constants/map_types.h"
#include "constants/maps.h"
-#include "constants/mevent.h"
+#include "constants/mystery_gift.h"
#include "constants/script_menu.h"
#include "constants/slot_machine.h"
#include "constants/songs.h"
@@ -116,8 +116,8 @@ static void HideFrontierExchangeCornerItemIcon(u16 menu, u16 unused);
static void ShowBattleFrontierTutorMoveDescription(u8 menu, u16 selection);
static void CloseScrollableMultichoice(u8 taskId);
static void ScrollableMultichoice_RemoveScrollArrows(u8 taskId);
-static void sub_813A600(u8 taskId);
-static void sub_813A664(u8 taskId);
+static void Task_ScrollableMultichoice_WaitReturnToList(u8 taskId);
+static void Task_ScrollableMultichoice_ReturnToList(u8 taskId);
static void ShowFrontierExchangeCornerItemIcon(u16 item);
static void Task_DeoxysRockInteraction(u8 taskId);
static void ChangeDeoxysRockLevel(u8 a0);
@@ -1655,20 +1655,20 @@ void BufferLottoTicketNumber(void)
}
}
-u16 GetMysteryEventCardVal(void)
+u16 GetMysteryGiftCardStat(void)
{
switch (gSpecialVar_Result)
{
case GET_NUM_STAMPS:
- return mevent_081445C0(GET_NUM_STAMPS_INTERNAL);
+ return MysteryGift_GetCardStat(CARD_STAT_NUM_STAMPS);
case GET_MAX_STAMPS:
- return mevent_081445C0(GET_MAX_STAMPS_INTERNAL);
+ return MysteryGift_GetCardStat(CARD_STAT_MAX_STAMPS);
case GET_CARD_BATTLES_WON:
- return mevent_081445C0(GET_CARD_BATTLES_WON_INTERNAL);
- case 3: // Never occurs
- return mevent_081445C0(1);
- case 4: // Never occurs
- return mevent_081445C0(2);
+ return MysteryGift_GetCardStat(CARD_STAT_BATTLES_WON);
+ case GET_CARD_BATTLES_LOST: // Never occurs
+ return MysteryGift_GetCardStat(CARD_STAT_BATTLES_LOST);
+ case GET_CARD_NUM_TRADES: // Never occurs
+ return MysteryGift_GetCardStat(CARD_STAT_NUM_TRADES);
default:
return 0;
}
@@ -2702,10 +2702,10 @@ static void ScrollableMultichoice_ProcessInput(u8 taskId)
{
CloseScrollableMultichoice(taskId);
}
- else
+ else // Handle selection while keeping the menu open
{
ScrollableMultichoice_RemoveScrollArrows(taskId);
- task->func = sub_813A600;
+ task->func = Task_ScrollableMultichoice_WaitReturnToList;
EnableBothScriptContexts();
}
break;
@@ -2729,36 +2729,32 @@ static void CloseScrollableMultichoice(u8 taskId)
EnableBothScriptContexts();
}
-// Functionally unused; tKeepOpenAfterSelect is only != 0 in unused functions
-static void sub_813A600(u8 taskId)
+// Never run, tKeepOpenAfterSelect is FALSE for all scrollable multichoices.
+static void Task_ScrollableMultichoice_WaitReturnToList(u8 taskId)
{
switch (gTasks[taskId].tKeepOpenAfterSelect)
{
- case 1:
- default:
- break;
- case 2:
- gTasks[taskId].tKeepOpenAfterSelect = 1;
- gTasks[taskId].func = sub_813A664;
- break;
+ case 1:
+ default:
+ break;
+ case 2:
+ gTasks[taskId].tKeepOpenAfterSelect = 1;
+ gTasks[taskId].func = Task_ScrollableMultichoice_ReturnToList;
+ break;
}
}
// Never called
-void sub_813A630(void)
+void ScrollableMultichoice_TryReturnToList(void)
{
- u8 taskId = FindTaskIdByFunc(sub_813A600);
+ u8 taskId = FindTaskIdByFunc(Task_ScrollableMultichoice_WaitReturnToList);
if (taskId == TASK_NONE)
- {
EnableBothScriptContexts();
- }
else
- {
- gTasks[taskId].tKeepOpenAfterSelect++;
- }
+ gTasks[taskId].tKeepOpenAfterSelect++; // Return to list
}
-static void sub_813A664(u8 taskId)
+static void Task_ScrollableMultichoice_ReturnToList(u8 taskId)
{
ScriptContext2_Enable();
ScrollableMultichoice_UpdateScrollArrows(taskId);
@@ -2807,23 +2803,7 @@ static void ScrollableMultichoice_RemoveScrollArrows(u8 taskId)
// Removed for Emerald (replaced by ShowScrollableMultichoice)
void ShowGlassWorkshopMenu(void)
{
- /*
- u8 i;
- ScriptContext2_Enable();
- Menu_DrawStdWindowFrame(0, 0, 10, 11);
- InitMenu(0, 1, 1, 5, 0, 9);
- gUnknown_0203925C = 0;
- ClearVerticalScrollIndicatorPalettes();
- LoadScrollIndicatorPalette();
- sub_810F2B4();
- for (i = 0; i < 5; i++)
- {
- Menu_PrintText(gUnknown_083F83C0[i], 1, 2 * i + 1);
- }
- gUnknown_0203925B = 0;
- gUnknown_0203925A = ARRAY_COUNT(gUnknown_083F83C0);
- CreateTask(sub_810F118, 8);
- */
+
}
void SetBattleTowerLinkPlayerGfx(void)
@@ -3252,11 +3232,11 @@ void CloseBattleFrontierTutorWindow(void)
}
// Never called
-void sub_813ADD4(void)
+void ScrollableMultichoice_RedrawPersistentMenu(void)
{
u16 scrollOffset, selectedRow;
u8 i;
- u8 taskId = FindTaskIdByFunc(sub_813A600);
+ u8 taskId = FindTaskIdByFunc(Task_ScrollableMultichoice_WaitReturnToList);
if (taskId != TASK_NONE)
{
struct Task *task = &gTasks[taskId];
@@ -3264,9 +3244,7 @@ void sub_813ADD4(void)
SetStandardWindowBorderStyle(task->tWindowId, 0);
for (i = 0; i < MAX_SCROLL_MULTI_ON_SCREEN; i++)
- {
AddTextPrinterParameterized5(task->tWindowId, 1, sScrollableMultichoiceOptions[gSpecialVar_0x8004][scrollOffset + i], 10, i * 16, TEXT_SPEED_FF, NULL, 0, 0);
- }
AddTextPrinterParameterized(task->tWindowId, 1, gText_SelectorArrow, 0, selectedRow * 16, TEXT_SPEED_FF, NULL);
PutWindowTilemap(task->tWindowId);
@@ -3313,9 +3291,10 @@ void GetBattleFrontierTutorMoveIndex(void)
}
// Never called
-void sub_813AF48(void)
+// Close a scrollable multichoice that stays open after selection
+void ScrollableMultichoice_ClosePersistentMenu(void)
{
- u8 taskId = FindTaskIdByFunc(sub_813A600);
+ u8 taskId = FindTaskIdByFunc(Task_ScrollableMultichoice_WaitReturnToList);
if (taskId != TASK_NONE)
{
struct Task *task = &gTasks[taskId];
@@ -3931,13 +3910,18 @@ static void Task_LoopWingFlapSE(u8 taskId)
#undef playCount
#undef delay
+#define CURTAIN_HEIGHT 4
+#define CURTAIN_WIDTH 3
+#define tFrameTimer data
+#define tCurrentFrame data[3]
+
void CloseBattlePikeCurtain(void)
{
u8 taskId = CreateTask(Task_CloseBattlePikeCurtain, 8);
- gTasks[taskId].data[0] = 4;
- gTasks[taskId].data[1] = 4;
- gTasks[taskId].data[2] = 4;
- gTasks[taskId].data[3] = 0;
+ gTasks[taskId].tFrameTimer[0] = 4;
+ gTasks[taskId].tFrameTimer[1] = 4;
+ gTasks[taskId].tFrameTimer[2] = 4;
+ gTasks[taskId].tCurrentFrame = 0;
}
static void Task_CloseBattlePikeCurtain(u8 taskId)
@@ -3945,19 +3929,21 @@ static void Task_CloseBattlePikeCurtain(u8 taskId)
u8 x, y;
s16 *data = gTasks[taskId].data;
- data[data[3]]--;
- if (data[data[3]] == 0)
+ tFrameTimer[tCurrentFrame]--;
+ if (tFrameTimer[tCurrentFrame] == 0)
{
- for (y = 0; y < 4; y++)
+ for (y = 0; y < CURTAIN_HEIGHT; y++)
{
- for (x = 0; x < 3; x++)
+ for (x = 0; x < CURTAIN_WIDTH; x++)
{
- MapGridSetMetatileIdAt(gSaveBlock1Ptr->pos.x + x + 6, gSaveBlock1Ptr->pos.y + y + 4, x + 513 + y * 8 + data[3] * 32);
+ MapGridSetMetatileIdAt(gSaveBlock1Ptr->pos.x + x + MAP_OFFSET - 1,
+ gSaveBlock1Ptr->pos.y + y + MAP_OFFSET - 3,
+ (x + METATILE_BattlePike_CurtainFrames_Start) + (y * METATILE_ROW_WIDTH) + (tCurrentFrame * CURTAIN_HEIGHT * METATILE_ROW_WIDTH));
}
}
DrawWholeMapView();
- data[3]++;
- if (data[3] == 3)
+ tCurrentFrame++;
+ if (tCurrentFrame == 3)
{
DestroyTask(taskId);
EnableBothScriptContexts();
@@ -3965,6 +3951,11 @@ static void Task_CloseBattlePikeCurtain(u8 taskId)
}
}
+#undef CURTAIN_HEIGHT
+#undef CURTAIN_WIDTH
+#undef tFrameTimer
+#undef tCurrentFrame
+
void GetBattlePyramidHint(void)
{
gSpecialVar_Result = gSpecialVar_0x8004 / 7;
diff --git a/src/hall_of_fame.c b/src/hall_of_fame.c
index ca9a40b6e..3cbe8df6e 100644
--- a/src/hall_of_fame.c
+++ b/src/hall_of_fame.c
@@ -586,7 +586,7 @@ static void Task_Hof_DisplayMon(u8 taskId)
if (currMon->species == SPECIES_EGG)
destY += 10;
- spriteId = CreatePicSprite2(currMon->species, currMon->tid, currMon->personality, 1, startX, startY, currMonId, TAG_NONE);
+ spriteId = CreateMonPicSprite_Affine(currMon->species, currMon->tid, currMon->personality, MON_PIC_AFFINE_FRONT, startX, startY, currMonId, TAG_NONE);
gSprites[spriteId].tDestinationX = destX;
gSprites[spriteId].tDestinationY = destY;
gSprites[spriteId].data[0] = 0;
diff --git a/src/international_string_util.c b/src/international_string_util.c
index eb2ec16e7..b2ee9743e 100644
--- a/src/international_string_util.c
+++ b/src/international_string_util.c
@@ -34,32 +34,32 @@ int GetStringWidthDifference(int fontId, const u8 *str, int totalWidth, int lett
return 0;
}
-int GetMaxWidthInMenuTable(const struct MenuAction *str, int numActions)
+int GetMaxWidthInMenuTable(const struct MenuAction *actions, int numActions)
{
- int i, var;
+ int i, maxWidth;
- for (var = 0, i = 0; i < numActions; i++)
+ for (maxWidth = 0, i = 0; i < numActions; i++)
{
- int stringWidth = GetStringWidth(1, str[i].text, 0);
- if (stringWidth > var)
- var = stringWidth;
+ int stringWidth = GetStringWidth(1, actions[i].text, 0);
+ if (stringWidth > maxWidth)
+ maxWidth = stringWidth;
}
- return ConvertPixelWidthToTileWidth(var);
+ return ConvertPixelWidthToTileWidth(maxWidth);
}
-int sub_81DB3D8(const struct MenuAction *str, const u8* arg1, int arg2)
+int GetMaxWidthInSubsetOfMenuTable(const struct MenuAction *actions, const u8* actionIds, int numActions)
{
- int i, var;
+ int i, maxWidth;
- for (var = 0, i = 0; i < arg2; i++)
+ for (maxWidth = 0, i = 0; i < numActions; i++)
{
- int stringWidth = GetStringWidth(1, str[arg1[i]].text, 0);
- if (stringWidth > var)
- var = stringWidth;
+ int stringWidth = GetStringWidth(1, actions[actionIds[i]].text, 0);
+ if (stringWidth > maxWidth)
+ maxWidth = stringWidth;
}
- return ConvertPixelWidthToTileWidth(var);
+ return ConvertPixelWidthToTileWidth(maxWidth);
}
int Intl_GetListMenuWidth(const struct ListMenuTemplate *listMenu)
@@ -93,32 +93,29 @@ void CopyMonCategoryText(int dexNum, u8 *dest)
StringCopy(str + 1, gText_Pokemon);
}
-u8 *sub_81DB494(u8 *str, int fontId, const u8 *str2, int totalStringWidth)
+u8 *GetStringClearToWidth(u8 *dest, int fontId, const u8 *str, int totalStringWidth)
{
u8 *buffer;
int width;
int clearWidth;
- if (str2)
+ if (str)
{
- buffer = StringCopy(str, str2);
- width = GetStringWidth(fontId, str2, 0);
+ buffer = StringCopy(dest, str);
+ width = GetStringWidth(fontId, str, 0);
}
else
{
- buffer = str;
+ buffer = dest;
width = 0;
}
clearWidth = totalStringWidth - width;
if (clearWidth > 0)
{
- *buffer = EXT_CTRL_CODE_BEGIN;
- buffer++;
- *buffer = EXT_CTRL_CODE_CLEAR;
- buffer++;
- *buffer = clearWidth;
- buffer++;
+ *(buffer++) = EXT_CTRL_CODE_BEGIN;
+ *(buffer++) = EXT_CTRL_CODE_CLEAR;
+ *(buffer++) = clearWidth;
*buffer = EOS;
}
@@ -209,7 +206,7 @@ void TVShowConvertInternationalString(u8 *dest, const u8 *src, int language)
ConvertInternationalString(dest, language);
}
-int sub_81DB604(u8 *str)
+int GetNicknameLanguage(u8 *str)
{
if (str[0] == EXT_CTRL_CODE_BEGIN && str[1] == EXT_CTRL_CODE_JPN)
return LANGUAGE_JAPANESE;
diff --git a/src/item_use.c b/src/item_use.c
index 4525cd7f9..833e80b97 100755
--- a/src/item_use.c
+++ b/src/item_use.c
@@ -249,7 +249,7 @@ static bool32 CanFish(void)
{
if (MetatileBehavior_IsSurfableWaterOrUnderwater(tileBehavior) && !MapGridIsImpassableAt(x, y))
return TRUE;
- if (MetatileBehavior_8089510(tileBehavior) == TRUE)
+ if (MetatileBehavior_IsBridgeOverWaterNoEdge(tileBehavior) == TRUE)
return TRUE;
}
diff --git a/src/link_rfu_2.c b/src/link_rfu_2.c
index f2caef949..87e9f8e9d 100644
--- a/src/link_rfu_2.c
+++ b/src/link_rfu_2.c
@@ -16,7 +16,7 @@
#include "task.h"
#include "text.h"
#include "save.h"
-#include "mystery_gift.h"
+#include "mystery_gift_menu.h"
enum {
RFUSTATE_INIT,
@@ -1981,7 +1981,7 @@ static void RfuCheckErrorStatus(void)
{
if (gRfu.errorState == RFU_ERROR_STATE_OCCURRED && lman.childClockSlave_flag == 0)
{
- if (gMain.callback2 == c2_mystery_gift_e_reader_run || lman.init_param->mboot_flag)
+ if (gMain.callback2 == CB2_MysteryGiftEReader || lman.init_param->mboot_flag)
gWirelessCommType = 2;
SetMainCallback2(CB2_LinkError);
gMain.savedCallback = CB2_LinkError;
diff --git a/src/main_menu.c b/src/main_menu.c
index f6dff3d44..b2879968c 100644
--- a/src/main_menu.c
+++ b/src/main_menu.c
@@ -35,7 +35,7 @@
#include "text_window.h"
#include "title_screen.h"
#include "window.h"
-#include "mystery_gift.h"
+#include "mystery_gift_menu.h"
/*
* Main menu state machine
@@ -90,7 +90,7 @@
* - If the user selected New Game, advance to Task_NewGameBirchSpeech_Init.
* - If the user selected Continue, advance to CB2_ContinueSavedGame.
* - If the user selected the Options menu, advance to CB2_InitOptionMenu.
- * - If the user selected Mystery Gift, advance to CB2_MysteryGift. However,
+ * - If the user selected Mystery Gift, advance to CB2_InitMysteryGift. However,
* if the wireless adapter was removed, instead advance to
* Task_DisplayMainMenuInvalidActionError.
* - Code to start a Mystery Event is present here, but is unreachable in this
@@ -1070,7 +1070,7 @@ static void Task_HandleMainMenuAPressed(u8 taskId)
DestroyTask(taskId);
break;
case ACTION_MYSTERY_GIFT:
- SetMainCallback2(c2_mystery_gift);
+ SetMainCallback2(CB2_InitMysteryGift);
DestroyTask(taskId);
break;
case ACTION_MYSTERY_EVENTS:
@@ -1078,7 +1078,7 @@ static void Task_HandleMainMenuAPressed(u8 taskId)
DestroyTask(taskId);
break;
case ACTION_EREADER:
- SetMainCallback2(c2_ereader);
+ SetMainCallback2(CB2_InitEReader);
DestroyTask(taskId);
break;
case ACTION_INVALID:
@@ -1871,9 +1871,9 @@ static void SpriteCB_MovePlayerDownWhileShrinking(struct Sprite *sprite)
sprite->data[0] = y;
}
-static u8 NewGameBirchSpeech_CreateLotadSprite(u8 a, u8 b)
+static u8 NewGameBirchSpeech_CreateLotadSprite(u8 x, u8 y)
{
- return CreatePicSprite2(SPECIES_LOTAD, SHINY_ODDS, 0, 1, a, b, 14, -1);
+ return CreateMonPicSprite_Affine(SPECIES_LOTAD, SHINY_ODDS, 0, MON_PIC_AFFINE_FRONT, x, y, 14, TAG_NONE);
}
static void AddBirchSpeechObjects(u8 taskId)
diff --git a/src/mauville_old_man.c b/src/mauville_old_man.c
index d3c41236c..2fd0e6730 100644
--- a/src/mauville_old_man.c
+++ b/src/mauville_old_man.c
@@ -21,12 +21,9 @@
#include "field_message_box.h"
#include "script_menu.h"
#include "trader.h"
+#include "m4a.h"
#include "constants/mauville_old_man.h"
-#define CHAR_SONG_WORD_SEPARATOR 0x37
-
-extern struct MusicPlayerInfo gMPlayInfo_SE2;
-
static void InitGiddyTaleList(void);
static void StartBardSong(bool8 useTemporaryLyrics);
static void Task_BardSong(u8 taskId);
@@ -51,25 +48,28 @@ static const u16 sDefaultBardSongLyrics[BARD_SONG_LENGTH] = {
};
static const u8 * const sGiddyAdjectives[] = {
- gText_SoPretty,
- gText_SoDarling,
- gText_SoRelaxed,
- gText_SoSunny,
- gText_SoDesirable,
- gText_SoExciting,
- gText_SoAmusing,
- gText_SoMagical
+ GiddyText_SoPretty,
+ GiddyText_SoDarling,
+ GiddyText_SoRelaxed,
+ GiddyText_SoSunny,
+ GiddyText_SoDesirable,
+ GiddyText_SoExciting,
+ GiddyText_SoAmusing,
+ GiddyText_SoMagical
};
-static const u8 * const sGiddyQuestions[] = {
- gMauvilleManText_ISoWantToGoOnAVacation,
- gMauvilleManText_IBoughtCrayonsWith120Colors,
- gMauvilleManText_WouldntItBeNiceIfWeCouldFloat,
- gMauvilleManText_WhenYouWriteOnASandyBeach,
- gMauvilleManText_WhatsTheBottomOfTheSeaLike,
- gMauvilleManText_WhenYouSeeTheSettingSunDoesIt,
- gMauvilleManText_LyingBackInTheGreenGrass,
- gMauvilleManText_SecretBasesAreSoWonderful
+// Non-random lines Giddy can say. Not all are strictly
+// questions, but most are, and the player will receive
+// a Yes/No prompt afterwards regardless.
+static const u8 * const sGiddyQuestions[GIDDY_MAX_QUESTIONS] = {
+ GiddyText_ISoWantToGoOnAVacation,
+ GiddyText_IBoughtCrayonsWith120Colors,
+ GiddyText_WouldntItBeNiceIfWeCouldFloat,
+ GiddyText_WhenYouWriteOnASandyBeach,
+ GiddyText_WhatsTheBottomOfTheSeaLike,
+ GiddyText_WhenYouSeeTheSettingSunDoesIt,
+ GiddyText_LyingBackInTheGreenGrass,
+ GiddyText_SecretBasesAreSoWonderful
};
static void SetupBard(void)
@@ -120,46 +120,41 @@ void SetMauvilleOldMan(void)
// Determine man based on the last digit of the player's trainer ID.
switch ((trainerId % 10) / 2)
{
- case MAUVILLE_MAN_BARD:
- SetupBard();
- break;
- case MAUVILLE_MAN_HIPSTER:
- SetupHipster();
- break;
- case MAUVILLE_MAN_TRADER:
- SetupTrader();
- break;
- case MAUVILLE_MAN_STORYTELLER:
- SetupStoryteller();
- break;
- case MAUVILLE_MAN_GIDDY:
- SetupGiddy();
- break;
+ case MAUVILLE_MAN_BARD:
+ SetupBard();
+ break;
+ case MAUVILLE_MAN_HIPSTER:
+ SetupHipster();
+ break;
+ case MAUVILLE_MAN_TRADER:
+ SetupTrader();
+ break;
+ case MAUVILLE_MAN_STORYTELLER:
+ SetupStoryteller();
+ break;
+ case MAUVILLE_MAN_GIDDY:
+ SetupGiddy();
+ break;
}
- ScrSpecial_SetMauvilleOldManObjEventGfx();
+ SetMauvilleOldManObjEventGfx();
}
u8 GetCurrentMauvilleOldMan(void)
{
- struct MauvilleManCommon *common = &gSaveBlock1Ptr->oldMan.common;
-
- return common->id;
+ return gSaveBlock1Ptr->oldMan.common.id;
}
-void ScrSpecial_GetCurrentMauvilleMan(void)
+void Script_GetCurrentMauvilleMan(void)
{
gSpecialVar_Result = GetCurrentMauvilleOldMan();
}
-void ScrSpecial_HasBardSongBeenChanged(void)
+void HasBardSongBeenChanged(void)
{
- u16 *scriptResult = &gSpecialVar_Result; // why??
- struct MauvilleManBard *bard = &gSaveBlock1Ptr->oldMan.bard;
-
- *scriptResult = bard->hasChangedSong;
+ gSpecialVar_Result = (&gSaveBlock1Ptr->oldMan.bard)->hasChangedSong;
}
-void ScrSpecial_SaveBardSongLyrics(void)
+void SaveBardSongLyrics(void)
{
u16 i;
struct MauvilleManBard *bard = &gSaveBlock1Ptr->oldMan.bard;
@@ -191,7 +186,7 @@ static void PrepareSongText(void)
while (wordEnd != str)
{
if (*str == CHAR_SPACE)
- *str = CHAR_SONG_WORD_SEPARATOR;
+ *str = CHAR_BARD_WORD_DELIMIT;
str++;
}
@@ -202,7 +197,7 @@ static void PrepareSongText(void)
while (wordEnd != str)
{
if (*str == CHAR_SPACE)
- *str = CHAR_SONG_WORD_SEPARATOR;
+ *str = CHAR_BARD_WORD_DELIMIT;
str++;
}
@@ -213,7 +208,7 @@ static void PrepareSongText(void)
while (wordEnd != str)
{
if (*str == CHAR_SPACE)
- *str = CHAR_SONG_WORD_SEPARATOR;
+ *str = CHAR_BARD_WORD_DELIMIT;
str++;
}
@@ -225,28 +220,23 @@ static void PrepareSongText(void)
}
}
-void ScrSpecial_PlayBardSong(void)
+void PlayBardSong(void)
{
StartBardSong(gSpecialVar_0x8004);
ScriptContext1_Stop();
}
-void ScrSpecial_GetHipsterSpokenFlag(void)
+void GetHipsterSpokenFlag(void)
{
- u16 *scriptResult = &gSpecialVar_Result; // again??
- struct MauvilleManHipster *hipster = &gSaveBlock1Ptr->oldMan.hipster;
-
- *scriptResult = hipster->alreadySpoken;
+ gSpecialVar_Result = (&gSaveBlock1Ptr->oldMan.hipster)->alreadySpoken;
}
-void ScrSpecial_SetHipsterSpokenFlag(void)
+void SetHipsterSpokenFlag(void)
{
- struct MauvilleManHipster *hipster = &gSaveBlock1Ptr->oldMan.hipster;
-
- hipster->alreadySpoken = TRUE;
+ (&gSaveBlock1Ptr->oldMan.hipster)->alreadySpoken = TRUE;
}
-void ScrSpecial_HipsterTeachWord(void)
+void HipsterTryTeachWord(void)
{
u16 phrase = GetNewHipsterPhraseToTeach();
@@ -261,11 +251,11 @@ void ScrSpecial_HipsterTeachWord(void)
}
}
-void ScrSpecial_GiddyShouldTellAnotherTale(void)
+void GiddyShouldTellAnotherTale(void)
{
struct MauvilleManGiddy *giddy = &gSaveBlock1Ptr->oldMan.giddy;
- if (giddy->taleCounter == 10)
+ if (giddy->taleCounter == GIDDY_MAX_TALES)
{
gSpecialVar_Result = FALSE;
giddy->taleCounter = 0;
@@ -276,31 +266,35 @@ void ScrSpecial_GiddyShouldTellAnotherTale(void)
}
}
-void ScrSpecial_GenerateGiddyLine(void)
+void GenerateGiddyLine(void)
{
struct MauvilleManGiddy *giddy = &gSaveBlock1Ptr->oldMan.giddy;
if (giddy->taleCounter == 0)
InitGiddyTaleList();
+ // A line from Giddy is either a line following this format:
+ // "{random word} is so {adjective}! Don't you agree?",
+ // or one of the texts in sGiddyQuestions.
if (giddy->randomWords[giddy->taleCounter] != EC_EMPTY_WORD)
{
u8 *stringPtr;
u32 adjective = Random();
+ adjective %= ARRAY_COUNT(sGiddyAdjectives);
- adjective %= 8;
stringPtr = CopyEasyChatWord(gStringVar4, giddy->randomWords[giddy->taleCounter]);
- stringPtr = StringCopy(stringPtr, gOtherText_Is);
+ stringPtr = StringCopy(stringPtr, GiddyText_Is);
stringPtr = StringCopy(stringPtr, sGiddyAdjectives[adjective]);
- StringCopy(stringPtr, gOtherText_DontYouAgree);
+ StringCopy(stringPtr, GiddyText_DontYouAgree);
}
else
{
StringCopy(gStringVar4, sGiddyQuestions[giddy->questionList[giddy->questionNum++]]);
}
+ // 10% chance for Giddy to stop telling tales.
if (!(Random() % 10))
- giddy->taleCounter = 10;
+ giddy->taleCounter = GIDDY_MAX_TALES;
else
giddy->taleCounter++;
@@ -310,7 +304,7 @@ void ScrSpecial_GenerateGiddyLine(void)
static void InitGiddyTaleList(void)
{
struct MauvilleManGiddy *giddy = &gSaveBlock1Ptr->oldMan.giddy;
- u16 arr[][2] = {
+ u16 wordGroupsAndCount[][2] = {
{EC_GROUP_POKEMON, 0},
{EC_GROUP_LIFESTYLE, 0},
{EC_GROUP_HOBBIES, 0},
@@ -319,62 +313,64 @@ static void InitGiddyTaleList(void)
{EC_GROUP_POKEMON_NATIONAL, 0}
};
u16 i;
- u16 r10;
- u16 r7;
- u16 r1;
+ u16 totalWords;
+ u16 temp;
+ u16 var; // re-used
- for (i = 0; i < 8; i++)
+ // Shuffle question list
+ for (i = 0; i < GIDDY_MAX_QUESTIONS; i++)
giddy->questionList[i] = i;
-
- for (i = 0; i < 8; i++)
+ for (i = 0; i < GIDDY_MAX_QUESTIONS; i++)
{
- r1 = Random() % (i + 1);
- r7 = giddy->questionList[i];
- giddy->questionList[i] = giddy->questionList[r1];
- giddy->questionList[r1] = r7;
+ var = Random() % (i + 1);
+ SWAP(giddy->questionList[i], giddy->questionList[var], temp);
}
- r10 = 0;
- for (i = 0; i < 6; i++)
+ // Count total number of words in above word groups
+ totalWords = 0;
+ for (i = 0; i < ARRAY_COUNT(wordGroupsAndCount); i++)
{
- arr[i][1] = EasyChat_GetNumWordsInGroup(arr[i][0]);
- r10 += arr[i][1];
+ wordGroupsAndCount[i][1] = EasyChat_GetNumWordsInGroup(wordGroupsAndCount[i][0]);
+ totalWords += wordGroupsAndCount[i][1];
}
giddy->questionNum = 0;
- r7 = 0;
- for (i = 0; i < 10; i++)
+ temp = 0;
+ for (i = 0; i < GIDDY_MAX_TALES; i++)
{
- r1 = Random() % 10;
- if (r1 < 3 && r7 < 8)
+ var = Random() % 10;
+ if (var < 3 && temp < GIDDY_MAX_QUESTIONS)
{
+ // 30% chance for word to be empty (in which case Giddy
+ // will say one of his non-random questions), unless
+ // the limit for questions has been reached already.
giddy->randomWords[i] = EC_EMPTY_WORD;
- r7++;
+ temp++;
}
else
{
- s16 r2 = Random() % r10;
- for (r1 = 0; i < 6; r1++)
- if ((r2 -= arr[r1][1]) <= 0)
+ // Pick a random word id, then advance through the word
+ // groups until the group where that id landed.
+ s16 randWord = Random() % totalWords;
+ for (var = 0; i < ARRAY_COUNT(wordGroupsAndCount); var++)
+ if ((randWord -= wordGroupsAndCount[var][1]) <= 0)
break;
- if (r1 == 6)
- r1 = 0;
- giddy->randomWords[i] = GetRandomEasyChatWordFromUnlockedGroup(arr[r1][0]);
+ if (var == ARRAY_COUNT(wordGroupsAndCount))
+ var = 0;
+
+ // Save the randomly selected word
+ giddy->randomWords[i] = GetRandomEasyChatWordFromUnlockedGroup(wordGroupsAndCount[var][0]);
}
}
}
static void ResetBardFlag(void)
{
- struct MauvilleManBard *bard = &gSaveBlock1Ptr->oldMan.bard;
-
- bard->hasChangedSong = FALSE;
+ (&gSaveBlock1Ptr->oldMan.bard)->hasChangedSong = FALSE;
}
static void ResetHipsterFlag(void)
{
- struct MauvilleManHipster *hipster = &gSaveBlock1Ptr->oldMan.hipster;
-
- hipster->alreadySpoken = FALSE;
+ (&gSaveBlock1Ptr->oldMan.hipster)->alreadySpoken = FALSE;
}
static void ResetTraderFlag(void)
@@ -391,28 +387,41 @@ void ResetMauvilleOldManFlag(void)
{
switch (GetCurrentMauvilleOldMan())
{
- case MAUVILLE_MAN_BARD:
- ResetBardFlag();
- break;
- case MAUVILLE_MAN_HIPSTER:
- ResetHipsterFlag();
- break;
- case MAUVILLE_MAN_STORYTELLER:
- ResetStorytellerFlag();
- break;
- case MAUVILLE_MAN_TRADER:
- ResetTraderFlag();
- break;
- case MAUVILLE_MAN_GIDDY:
- break;
+ case MAUVILLE_MAN_BARD:
+ ResetBardFlag();
+ break;
+ case MAUVILLE_MAN_HIPSTER:
+ ResetHipsterFlag();
+ break;
+ case MAUVILLE_MAN_STORYTELLER:
+ ResetStorytellerFlag();
+ break;
+ case MAUVILLE_MAN_TRADER:
+ ResetTraderFlag();
+ break;
+ case MAUVILLE_MAN_GIDDY:
+ break;
}
- ScrSpecial_SetMauvilleOldManObjEventGfx();
+ SetMauvilleOldManObjEventGfx();
}
+// States and task data for Task_BardSong.
+// The function BardSing receives this task as an
+// argument and reads its state as well.
+enum {
+ BARD_STATE_INIT,
+ BARD_STATE_WAIT_BGM,
+ BARD_STATE_GET_WORD,
+ BARD_STATE_HANDLE_WORD,
+ BARD_STATE_WAIT_WORD,
+ BARD_STATE_PAUSE,
+};
-#define tState data[0]
-#define tCharIndex data[3]
-#define tCurrWord data[4]
+#define tState data[0]
+#define tWordState data[1]
+#define tDelay data[2]
+#define tCharIndex data[3]
+#define tCurrWord data[4]
#define tUseTemporaryLyrics data[5]
#define MACRO1(a) (((a) & 3) + (((a) / 8) & 1))
@@ -430,15 +439,15 @@ static void EnableTextPrinters(void)
gDisableTextPrinters = FALSE;
}
-static void BardSong_DisableTextPrinters(struct TextPrinterTemplate * printer, u16 a1)
+static void DisableTextPrinters(struct TextPrinterTemplate * printer, u16 a1)
{
gDisableTextPrinters = TRUE;
}
-static void sub_8120708(const u8 * src)
+static void DrawSongTextWindow(const u8 * str)
{
DrawDialogueFrame(0, 0);
- AddTextPrinterParameterized(0, 1, src, 0, 1, 1, BardSong_DisableTextPrinters);
+ AddTextPrinterParameterized(0, 1, str, 0, 1, 1, DisableTextPrinters);
gDisableTextPrinters = TRUE;
CopyWindowToVram(0, 3);
}
@@ -447,233 +456,244 @@ static void BardSing(struct Task *task, struct BardSong *song)
{
switch (task->tState)
{
- case 0: // Initialize song
- {
- struct MauvilleManBard *bard = &gSaveBlock1Ptr->oldMan.bard;
- u16 *lyrics;
- s32 i;
+ case BARD_STATE_INIT:
+ {
+ struct MauvilleManBard *bard = &gSaveBlock1Ptr->oldMan.bard;
+ u16 *lyrics;
+ s32 i;
- // Copy lyrics
- if (gSpecialVar_0x8004 == 0)
- lyrics = bard->songLyrics;
- else
- lyrics = bard->temporaryLyrics;
- for (i = 0; i < BARD_SONG_LENGTH; i++)
- song->lyrics[i] = lyrics[i];
- song->currWord = 0;
+ // Copy lyrics
+ if (gSpecialVar_0x8004 == 0)
+ lyrics = bard->songLyrics;
+ else
+ lyrics = bard->temporaryLyrics;
+ for (i = 0; i < BARD_SONG_LENGTH; i++)
+ song->lyrics[i] = lyrics[i];
+ song->currWord = 0;
+ }
+ break;
+ case BARD_STATE_WAIT_BGM:
+ break;
+ case BARD_STATE_GET_WORD:
+ {
+ u16 word = song->lyrics[song->currWord];
+ song->sound = GetWordSounds(word);
+ GetWordPhonemes(song, MACRO1(word));
+ song->currWord++;
+ if (song->sound->var00 != 0xFF)
+ song->state = 0;
+ else
+ {
+ song->state = 3;
+ song->phonemeTimer = 2;
}
+ break;
+ }
+ case BARD_STATE_HANDLE_WORD:
+ case BARD_STATE_WAIT_WORD:
+ {
+ const struct BardSound *sound = &song->sound[song->currPhoneme];
+
+ switch (song->state)
+ {
+ case 0:
+ song->phonemeTimer = song->phonemes[song->currPhoneme].length;
+ if (sound->var00 <= 50)
+ {
+ u8 num = sound->var00 / 3;
+ m4aSongNumStart(PH_TRAP_HELD + 3 * num);
+ }
+ song->state = 2;
+ song->phonemeTimer--;
break;
- case 1: // Wait for BGM to end
+ case 2:
+ song->state = 1;
+ if (sound->var00 <= 50)
+ {
+ song->volume = 0x100 + sound->volume * 16;
+ m4aMPlayVolumeControl(&gMPlayInfo_SE2, TRACKS_ALL, song->volume);
+ song->pitch = 0x200 + song->phonemes[song->currPhoneme].pitch;
+ m4aMPlayPitchControl(&gMPlayInfo_SE2, TRACKS_ALL, song->pitch);
+ }
break;
- case 2: // Initialize word
- {
- u16 word = song->lyrics[song->currWord];
- song->sound = GetWordSounds(word);
- GetWordPhonemes(song, MACRO1(word));
- song->currWord++;
- if (song->sound->var00 != 0xFF)
- song->state = 0;
+ case 1:
+ if (song->voiceInflection > 10)
+ song->volume -= 2;
+ if (song->voiceInflection & 1)
+ song->pitch += 64;
else
+ song->pitch -= 64;
+ m4aMPlayVolumeControl(&gMPlayInfo_SE2, TRACKS_ALL, song->volume);
+ m4aMPlayPitchControl(&gMPlayInfo_SE2, TRACKS_ALL, song->pitch);
+ song->voiceInflection++;
+ song->phonemeTimer--;
+ if (song->phonemeTimer == 0)
{
- song->state = 3;
- song->phonemeTimer = 2;
+ song->currPhoneme++;
+ if (song->currPhoneme != 6 && song->sound[song->currPhoneme].var00 != 0xFF)
+ song->state = 0;
+ else
+ {
+ song->state = 3;
+ song->phonemeTimer = 2;
+ }
}
break;
- }
case 3:
- case 4:
- {
- const struct BardSound *sound = &song->sound[song->currPhoneme];
-
- switch (song->state)
+ song->phonemeTimer--;
+ if (song->phonemeTimer == 0)
{
- case 0:
- song->phonemeTimer = song->phonemes[song->currPhoneme].length;
- if (sound->var00 <= 50)
- {
- u8 num = sound->var00 / 3;
- m4aSongNumStart(PH_TRAP_HELD + 3 * num);
- }
- song->state = 2;
- song->phonemeTimer--;
- break;
- case 2:
- song->state = 1;
- if (sound->var00 <= 50)
- {
- song->volume = 0x100 + sound->volume * 16;
- m4aMPlayVolumeControl(&gMPlayInfo_SE2, TRACKS_ALL, song->volume);
- song->pitch = 0x200 + song->phonemes[song->currPhoneme].pitch;
- m4aMPlayPitchControl(&gMPlayInfo_SE2, TRACKS_ALL, song->pitch);
- }
- break;
- case 1:
- if (song->voiceInflection > 10)
- song->volume -= 2;
- if (song->voiceInflection & 1)
- song->pitch += 64;
- else
- song->pitch -= 64;
- m4aMPlayVolumeControl(&gMPlayInfo_SE2, TRACKS_ALL, song->volume);
- m4aMPlayPitchControl(&gMPlayInfo_SE2, TRACKS_ALL, song->pitch);
- song->voiceInflection++;
- song->phonemeTimer--;
- if (song->phonemeTimer == 0)
- {
- song->currPhoneme++;
- if (song->currPhoneme != 6 && song->sound[song->currPhoneme].var00 != 0xFF)
- song->state = 0;
- else
- {
- song->state = 3;
- song->phonemeTimer = 2;
- }
- }
- break;
- case 3:
- song->phonemeTimer--;
- if (song->phonemeTimer == 0)
- {
- m4aMPlayStop(&gMPlayInfo_SE2);
- song->state = 4;
- }
- break;
+ m4aMPlayStop(&gMPlayInfo_SE2);
+ song->state = 4;
}
- }
- break;
- case 5:
break;
+ }
+ }
+ break;
+ case BARD_STATE_PAUSE:
+ break;
}
}
static void Task_BardSong(u8 taskId)
{
- struct Task *task = &gTasks[taskId]; // r5
+ struct Task *task = &gTasks[taskId];
BardSing(task, &gBardSong);
+
switch (task->tState)
{
- case 0: // Initialize song
- PrepareSongText();
- sub_8120708(gStringVar4);
- task->data[1] = 0;
- task->data[2] = 0;
- task->tCharIndex = 0;
- task->tCurrWord = 0;
- FadeOutBGMTemporarily(4);
- task->tState = 1;
- break;
- case 1: // Wait for BGM to end
- if (IsBGMPausedOrStopped())
- task->tState = 2;
- break;
- case 2: // Initialize word
+ case BARD_STATE_INIT:
+ PrepareSongText();
+ DrawSongTextWindow(gStringVar4);
+ task->tWordState = 0;
+ task->tDelay = 0;
+ task->tCharIndex = 0;
+ task->tCurrWord = 0;
+ FadeOutBGMTemporarily(4);
+ task->tState = BARD_STATE_WAIT_BGM;
+ break;
+ case BARD_STATE_WAIT_BGM:
+ if (IsBGMPausedOrStopped())
+ task->tState = BARD_STATE_GET_WORD;
+ break;
+ case BARD_STATE_GET_WORD:
+ {
+ struct MauvilleManBard *bard = &gSaveBlock1Ptr->oldMan.bard;
+ u8 *str = &gStringVar4[task->tCharIndex];
+ u16 wordLen = 0;
+
+ // Read letters until delimiter
+ while (*str != CHAR_SPACE
+ && *str != CHAR_NEWLINE
+ && *str != EXT_CTRL_CODE_BEGIN
+ && *str != EOS)
{
- struct MauvilleManBard *bard = &gSaveBlock1Ptr->oldMan.bard;
- u8 *str = gStringVar4 + task->tCharIndex;
- u16 wordLen = 0;
-
- while (*str != CHAR_SPACE
- && *str != CHAR_NEWLINE
- && *str != EXT_CTRL_CODE_BEGIN
- && *str != EOS)
- {
- str++;
- wordLen++;
- }
- if (!task->tUseTemporaryLyrics)
- sUnknownBardRelated = MACRO2(bard->songLyrics[task->tCurrWord]);
- else
- sUnknownBardRelated = MACRO2(bard->temporaryLyrics[task->tCurrWord]);
+ str++;
+ wordLen++;
+ }
- gBardSong.length /= wordLen;
- if (gBardSong.length <= 0)
- gBardSong.length = 1;
- task->tCurrWord++;
+ if (!task->tUseTemporaryLyrics)
+ sUnknownBardRelated = MACRO2(bard->songLyrics[task->tCurrWord]);
+ else
+ sUnknownBardRelated = MACRO2(bard->temporaryLyrics[task->tCurrWord]);
- if (task->data[2] == 0)
- {
- task->tState = 3;
- task->data[1] = 0;
- }
- else
- {
- task->tState = 5;
- task->data[1] = 0;
- }
- }
- break;
- case 5:
- if (task->data[2] == 0)
- task->tState = 3;
- else
- task->data[2]--;
- break;
- case 3:
- if (gStringVar4[task->tCharIndex] == EOS)
- {
- FadeInBGM(6);
- m4aMPlayFadeOutTemporarily(&gMPlayInfo_SE2, 2);
- EnableBothScriptContexts();
- DestroyTask(taskId);
- }
- else if (gStringVar4[task->tCharIndex] == CHAR_SPACE)
- {
+ gBardSong.length /= wordLen;
+ if (gBardSong.length <= 0)
+ gBardSong.length = 1;
+ task->tCurrWord++;
- EnableTextPrinters();
- task->tCharIndex++;
- task->tState = 2;
- task->data[2] = 0;
- }
- else if (gStringVar4[task->tCharIndex] == CHAR_NEWLINE)
- {
- task->tCharIndex++;
- task->tState = 2;
- task->data[2] = 0;
- }
- else if (gStringVar4[task->tCharIndex] == EXT_CTRL_CODE_BEGIN)
- {
- task->tCharIndex += 2; // skip over control codes
- task->tState = 2;
- task->data[2] = 8;
- }
- else if (gStringVar4[task->tCharIndex] == CHAR_SONG_WORD_SEPARATOR)
+ if (task->tDelay == 0)
+ {
+ task->tState = BARD_STATE_HANDLE_WORD;
+ task->tWordState = 0;
+ }
+ else
+ {
+ task->tState = BARD_STATE_PAUSE;
+ task->tWordState = 0;
+ }
+ }
+ break;
+ case BARD_STATE_PAUSE:
+ // Wait before singing next word
+ if (task->tDelay == 0)
+ task->tState = BARD_STATE_HANDLE_WORD;
+ else
+ task->tDelay--;
+ break;
+ case BARD_STATE_HANDLE_WORD:
+ if (gStringVar4[task->tCharIndex] == EOS)
+ {
+ // End song
+ FadeInBGM(6);
+ m4aMPlayFadeOutTemporarily(&gMPlayInfo_SE2, 2);
+ EnableBothScriptContexts();
+ DestroyTask(taskId);
+ }
+ else if (gStringVar4[task->tCharIndex] == CHAR_SPACE)
+ {
+ // Handle space
+ EnableTextPrinters();
+ task->tCharIndex++;
+ task->tState = BARD_STATE_GET_WORD;
+ task->tDelay = 0;
+ }
+ else if (gStringVar4[task->tCharIndex] == CHAR_NEWLINE)
+ {
+ // Handle newline
+ task->tCharIndex++;
+ task->tState = BARD_STATE_GET_WORD;
+ task->tDelay = 0;
+ }
+ else if (gStringVar4[task->tCharIndex] == EXT_CTRL_CODE_BEGIN)
+ {
+ // Handle ctrl code
+ task->tCharIndex += 2; // skip over control codes
+ task->tState = BARD_STATE_GET_WORD;
+ task->tDelay = 8;
+ }
+ else if (gStringVar4[task->tCharIndex] == CHAR_BARD_WORD_DELIMIT)
+ {
+ // Handle word boundary
+ gStringVar4[task->tCharIndex] = CHAR_SPACE; // Replace with a real space
+ EnableTextPrinters();
+ task->tCharIndex++;
+ task->tDelay = 0;
+ }
+ else
+ {
+ // Handle regular word
+ switch (task->tWordState)
{
- gStringVar4[task->tCharIndex] = CHAR_SPACE; // restore it back to a space
+ case 0:
EnableTextPrinters();
+ task->tWordState++;
+ break;
+ case 1:
+ task->tWordState++;
+ break;
+ case 2:
task->tCharIndex++;
- task->data[2] = 0;
- }
- else
- {
- switch (task->data[1])
- {
- case 0:
- EnableTextPrinters();
- task->data[1]++;
- break;
- case 1:
- task->data[1]++;
- break;
- case 2:
- task->tCharIndex++;
- task->data[1] = 0;
- task->data[2] = gBardSong.length;
- task->tState = 4;
- break;
- }
+ task->tWordState = 0;
+ task->tDelay = gBardSong.length;
+ task->tState = BARD_STATE_WAIT_WORD;
+ break;
}
- break;
- case 4:
- task->data[2]--;
- if (task->data[2] == 0)
- task->tState = 3;
- break;
+ }
+ break;
+ case BARD_STATE_WAIT_WORD:
+ // Wait for word to finish being sung.
+ // BardSing will continue to play it.
+ task->tDelay--;
+ if (task->tDelay == 0)
+ task->tState = BARD_STATE_HANDLE_WORD;
+ break;
}
RunTextPrintersAndIsPrinter0Active();
}
-void ScrSpecial_SetMauvilleOldManObjEventGfx(void)
+void SetMauvilleOldManObjEventGfx(void)
{
VarSet(VAR_OBJ_GFX_ID_0, OBJ_EVENT_GFX_BARD);
}
@@ -720,76 +740,69 @@ void SanitizeMauvilleOldManForRuby(union OldMan * oldMan)
}
}
-void sub_8120C0C(union OldMan * oldMan, u32 r8, u32 r7, u32 r3)
+// Unused
+static void SetMauvilleOldManLanguage(union OldMan * oldMan, u32 language1, u32 language2, u32 language3)
{
s32 i;
switch (oldMan->common.id)
{
- case MAUVILLE_MAN_TRADER:
- {
- struct MauvilleOldManTrader * trader = &oldMan->trader;
-
- for (i = 0; i < NUM_TRADER_ITEMS; i++)
- {
- if (IsStringJapanese(trader->playerNames[i]))
- {
- trader->language[i] = r8;
- }
- else
- {
- trader->language[i] = r7;
- }
- }
- }
- break;
- case MAUVILLE_MAN_STORYTELLER:
- {
- struct MauvilleManStoryteller * storyteller = &oldMan->storyteller;
+ case MAUVILLE_MAN_TRADER:
+ {
+ struct MauvilleOldManTrader * trader = &oldMan->trader;
- for (i = 0; i < NUM_STORYTELLER_TALES; i++)
- {
- if (IsStringJapanese(storyteller->trainerNames[i]))
- {
- storyteller->language[i] = r8;
- }
- else
- {
- storyteller->language[i] = r7;
- }
- }
- }
- break;
- case MAUVILLE_MAN_BARD:
+ for (i = 0; i < NUM_TRADER_ITEMS; i++)
{
- struct MauvilleManBard * bard = &oldMan->bard;
-
- if (r3 == LANGUAGE_JAPANESE)
- bard->language = r8;
+ if (IsStringJapanese(trader->playerNames[i]))
+ trader->language[i] = language1;
else
- bard->language = r7;
+ trader->language[i] = language2;
}
- break;
- case MAUVILLE_MAN_HIPSTER:
- {
- struct MauvilleManHipster * hipster = &oldMan->hipster;
+ }
+ break;
+ case MAUVILLE_MAN_STORYTELLER:
+ {
+ struct MauvilleManStoryteller * storyteller = &oldMan->storyteller;
- if (r3 == LANGUAGE_JAPANESE)
- hipster->language = r8;
- else
- hipster->language = r7;
- }
- break;
- case MAUVILLE_MAN_GIDDY:
+ for (i = 0; i < NUM_STORYTELLER_TALES; i++)
{
- struct MauvilleManGiddy * giddy = &oldMan->giddy;
-
- if (r3 == LANGUAGE_JAPANESE)
- giddy->language = r8;
+ if (IsStringJapanese(storyteller->trainerNames[i]))
+ storyteller->language[i] = language1;
else
- giddy->language = r7;
+ storyteller->language[i] = language2;
}
- break;
+ }
+ break;
+ case MAUVILLE_MAN_BARD:
+ {
+ struct MauvilleManBard * bard = &oldMan->bard;
+
+ if (language3 == LANGUAGE_JAPANESE)
+ bard->language = language1;
+ else
+ bard->language = language2;
+ }
+ break;
+ case MAUVILLE_MAN_HIPSTER:
+ {
+ struct MauvilleManHipster * hipster = &oldMan->hipster;
+
+ if (language3 == LANGUAGE_JAPANESE)
+ hipster->language = language1;
+ else
+ hipster->language = language2;
+ }
+ break;
+ case MAUVILLE_MAN_GIDDY:
+ {
+ struct MauvilleManGiddy * giddy = &oldMan->giddy;
+
+ if (language3 == LANGUAGE_JAPANESE)
+ giddy->language = language1;
+ else
+ giddy->language = language2;
+ }
+ break;
}
}
@@ -822,83 +835,83 @@ void SanitizeReceivedRubyOldMan(union OldMan * oldMan, u32 version, u32 language
switch (oldMan->common.id)
{
- case MAUVILLE_MAN_TRADER:
- {
- struct MauvilleOldManTrader * trader = &oldMan->trader;
- s32 i;
+ case MAUVILLE_MAN_TRADER:
+ {
+ struct MauvilleOldManTrader * trader = &oldMan->trader;
+ s32 i;
- if (isRuby)
- {
- for (i = 0; i < NUM_TRADER_ITEMS; i++)
- {
- u8 * str = trader->playerNames[i];
- if (str[0] == EXT_CTRL_CODE_BEGIN && str[1] == EXT_CTRL_CODE_JPN)
- {
- StripExtCtrlCodes(str);
- trader->language[i] = LANGUAGE_JAPANESE;
- }
- else
- trader->language[i] = language;
- }
- }
- else
+ if (isRuby)
+ {
+ for (i = 0; i < NUM_TRADER_ITEMS; i++)
{
- for (i = 0; i < NUM_TRADER_ITEMS; i++)
+ u8 * str = trader->playerNames[i];
+ if (str[0] == EXT_CTRL_CODE_BEGIN && str[1] == EXT_CTRL_CODE_JPN)
{
- if (trader->language[i] == LANGUAGE_JAPANESE)
- {
- StripExtCtrlCodes(trader->playerNames[i]);
- }
+ StripExtCtrlCodes(str);
+ trader->language[i] = LANGUAGE_JAPANESE;
}
+ else
+ trader->language[i] = language;
}
}
- break;
- case MAUVILLE_MAN_STORYTELLER:
+ else
{
-
- struct MauvilleManStoryteller * storyteller = &oldMan->storyteller;
- s32 i;
-
- if (isRuby)
+ for (i = 0; i < NUM_TRADER_ITEMS; i++)
{
- for (i = 0; i < NUM_STORYTELLER_TALES; i++)
+ if (trader->language[i] == LANGUAGE_JAPANESE)
{
- if (storyteller->gameStatIDs[i] != 0)
- storyteller->language[i] = language;
+ StripExtCtrlCodes(trader->playerNames[i]);
}
}
}
- break;
- case MAUVILLE_MAN_BARD:
- {
- struct MauvilleManBard * bard = &oldMan->bard;
+ }
+ break;
+ case MAUVILLE_MAN_STORYTELLER:
+ {
- if (isRuby)
+ struct MauvilleManStoryteller * storyteller = &oldMan->storyteller;
+ s32 i;
+
+ if (isRuby)
+ {
+ for (i = 0; i < NUM_STORYTELLER_TALES; i++)
{
- bard->language = language;
+ if (storyteller->gameStatIDs[i] != 0)
+ storyteller->language[i] = language;
}
}
- break;
- case MAUVILLE_MAN_HIPSTER:
- {
- struct MauvilleManHipster * hipster = &oldMan->hipster;
+ }
+ break;
+ case MAUVILLE_MAN_BARD:
+ {
+ struct MauvilleManBard * bard = &oldMan->bard;
- if (isRuby)
- {
- hipster->language = language;
- }
+ if (isRuby)
+ {
+ bard->language = language;
}
- break;
- case MAUVILLE_MAN_GIDDY:
+ }
+ break;
+ case MAUVILLE_MAN_HIPSTER:
+ {
+ struct MauvilleManHipster * hipster = &oldMan->hipster;
+
+ if (isRuby)
{
- struct MauvilleManGiddy * giddy = &oldMan->giddy;
+ hipster->language = language;
+ }
+ }
+ break;
+ case MAUVILLE_MAN_GIDDY:
+ {
+ struct MauvilleManGiddy * giddy = &oldMan->giddy;
- if (isRuby)
- {
- giddy->language = language;
- }
+ if (isRuby)
+ {
+ giddy->language = language;
}
- break;
+ }
+ break;
}
}
@@ -1131,6 +1144,9 @@ static const struct Story sStorytellerStories[] = {
}
};
+static const s32 sNumStories = ARRAY_COUNT(sStorytellerStories);
+static const u32 sUnused = 8;
+
static void StorytellerSetup(void)
{
s32 i;
@@ -1164,12 +1180,12 @@ static const struct Story *GetStoryByStat(u32 stat)
{
s32 i;
- for (i = 0; i < (int)ARRAY_COUNT(sStorytellerStories); i++)
+ for (i = 0; i < sNumStories; i++)
{
if (sStorytellerStories[i].stat == stat)
return &sStorytellerStories[i];
}
- return &sStorytellerStories[ARRAY_COUNT(sStorytellerStories) - 1];
+ return &sStorytellerStories[sNumStories - 1];
}
static const u8 *GetStoryTitleByStat(u32 stat)
@@ -1260,34 +1276,21 @@ static void ScrambleStatList(u8 * arr, s32 count)
{
u32 a = Random() % count;
u32 b = Random() % count;
- u8 temp = arr[a];
- arr[a] = arr[b];
- arr[b] = temp;
+ u8 temp;
+ SWAP(arr[a], arr[b], temp);
}
}
-struct UnknownStruct_0859F288
-{
- s32 length;
- u32 unused2;
-};
-
-static const struct UnknownStruct_0859F288 sStorytellerStuff = {
- ARRAY_COUNT(sStorytellerStories),
- sizeof(sStorytellerStuff)
-};
-
static bool8 StorytellerInitializeRandomStat(void)
{
- u8 arr[sStorytellerStuff.length];
- s32 i;
- s32 j;
+ u8 storyIds[sNumStories];
+ s32 i, j;
- ScrambleStatList(arr, ARRAY_COUNT(sStorytellerStories));
- for (i = 0; i < (s32)ARRAY_COUNT(sStorytellerStories); i++)
+ ScrambleStatList(storyIds, sNumStories);
+ for (i = 0; i < sNumStories; i++)
{
- u8 stat = sStorytellerStories[arr[i]].stat;
- u8 minVal = sStorytellerStories[arr[i]].minVal;
+ u8 stat = sStorytellerStories[storyIds[i]].stat;
+ u8 minVal = sStorytellerStories[storyIds[i]].minVal;
for (j = 0; j < NUM_STORYTELLER_TALES; j++)
{
@@ -1354,63 +1357,63 @@ static void Task_StoryListMenu(u8 taskId)
switch (task->data[0])
{
- case 0:
- PrintStoryList();
- task->data[0]++;
- break;
- case 1:
- selection = Menu_ProcessInput();
- if (selection == MENU_NOTHING_CHOSEN)
- break;
- if (selection == MENU_B_PRESSED || selection == GetFreeStorySlot())
- {
- gSpecialVar_Result = 0;
- }
- else
- {
- gSpecialVar_Result = 1;
- sSelectedStory = selection;
- }
- ClearToTransparentAndRemoveWindow(sStorytellerWindowId);
- DestroyTask(taskId);
- EnableBothScriptContexts();
+ case 0:
+ PrintStoryList();
+ task->data[0]++;
+ break;
+ case 1:
+ selection = Menu_ProcessInput();
+ if (selection == MENU_NOTHING_CHOSEN)
break;
+ if (selection == MENU_B_PRESSED || selection == GetFreeStorySlot())
+ {
+ gSpecialVar_Result = 0;
+ }
+ else
+ {
+ gSpecialVar_Result = 1;
+ sSelectedStory = selection;
+ }
+ ClearToTransparentAndRemoveWindow(sStorytellerWindowId);
+ DestroyTask(taskId);
+ EnableBothScriptContexts();
+ break;
}
}
// Sets gSpecialVar_Result to TRUE if player selected a story
-void ScrSpecial_StorytellerStoryListMenu(void)
+void StorytellerStoryListMenu(void)
{
CreateTask(Task_StoryListMenu, 80);
}
-void ScrSpecial_StorytellerDisplayStory(void)
+void Script_StorytellerDisplayStory(void)
{
StorytellerDisplayStory(sSelectedStory);
}
-u8 ScrSpecial_StorytellerGetFreeStorySlot(void)
+u8 StorytellerGetFreeStorySlot(void)
{
sStorytellerPtr = &gSaveBlock1Ptr->oldMan.storyteller;
return GetFreeStorySlot();
}
// Returns TRUE if stat has increased
-bool8 ScrSpecial_StorytellerUpdateStat(void)
+bool8 StorytellerUpdateStat(void)
{
- u8 r4;
+ u8 stat;
sStorytellerPtr = &gSaveBlock1Ptr->oldMan.storyteller;
- r4 = sStorytellerPtr->gameStatIDs[sSelectedStory];
+ stat = sStorytellerPtr->gameStatIDs[sSelectedStory];
if (HasTrainerStatIncreased(sSelectedStory) == TRUE)
{
- StorytellerRecordNewStat(sSelectedStory, r4);
+ StorytellerRecordNewStat(sSelectedStory, stat);
return TRUE;
}
return FALSE;
}
-bool8 ScrSpecial_HasStorytellerAlreadyRecorded(void)
+bool8 HasStorytellerAlreadyRecorded(void)
{
sStorytellerPtr = &gSaveBlock1Ptr->oldMan.storyteller;
@@ -1420,7 +1423,7 @@ bool8 ScrSpecial_HasStorytellerAlreadyRecorded(void)
return TRUE;
}
-bool8 ScrSpecial_StorytellerInitializeRandomStat(void)
+bool8 Script_StorytellerInitializeRandomStat(void)
{
sStorytellerPtr = &gSaveBlock1Ptr->oldMan.storyteller;
return StorytellerInitializeRandomStat();
diff --git a/src/metatile_behavior.c b/src/metatile_behavior.c
index 5c8b8ec51..3829523df 100644
--- a/src/metatile_behavior.c
+++ b/src/metatile_behavior.c
@@ -122,22 +122,22 @@ static const u8 sTileBitAttributes[] =
[MB_WATER_SOUTH_ARROW_WARP] = TILE_ATTRIBUTES(TRUE, TRUE, FALSE),
[MB_DEEP_SOUTH_WARP] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
[MB_UNUSED_6F] = TILE_ATTRIBUTES(TRUE, TRUE, FALSE),
- [MB_WARP_OR_BRIDGE] = TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
- [MB_UNUSED_71] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
- [MB_ROUTE120_NORTH_BRIDGE_1] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
- [MB_ROUTE120_NORTH_BRIDGE_2] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ [MB_BRIDGE_OVER_OCEAN] = TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ [MB_BRIDGE_OVER_POND_LOW] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ [MB_BRIDGE_OVER_POND_MED] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ [MB_BRIDGE_OVER_POND_HIGH] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
[MB_PACIFIDLOG_VERTICAL_LOG_1] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
[MB_PACIFIDLOG_VERTICAL_LOG_2] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
[MB_PACIFIDLOG_HORIZONTAL_LOG_1] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
[MB_PACIFIDLOG_HORIZONTAL_LOG_2] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
[MB_FORTREE_BRIDGE] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
[MB_UNUSED_79] = TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
- [MB_ROUTE120_SOUTH_BRIDGE_1] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
- [MB_ROUTE120_SOUTH_BRIDGE_2] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
- [MB_ROUTE120_NORTH_BRIDGE_3] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
- [MB_ROUTE120_NORTH_BRIDGE_4] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
- [MB_UNUSED_7E] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
- [MB_ROUTE110_BRIDGE] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ [MB_BRIDGE_OVER_POND_MED_EDGE_1] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ [MB_BRIDGE_OVER_POND_MED_EDGE_2] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ [MB_BRIDGE_OVER_POND_HIGH_EDGE_1] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ [MB_BRIDGE_OVER_POND_HIGH_EDGE_2] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ [MB_UNUSED_BRIDGE_1] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ [MB_UNUSED_BRIDGE_2] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
[MB_COUNTER] = TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
[MB_UNUSED_81] = TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
[MB_UNUSED_82] = TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
@@ -833,7 +833,9 @@ bool8 MetatileBehavior_IsPlayerRoomPCOn(u8 metatileBehavior)
bool8 MetatileBehavior_HasRipples(u8 metatileBehavior)
{
- if (metatileBehavior == MB_POND_WATER || metatileBehavior == MB_PUDDLE || metatileBehavior == MB_SOOTOPOLIS_DEEP_WATER)
+ if (metatileBehavior == MB_POND_WATER
+ || metatileBehavior == MB_PUDDLE
+ || metatileBehavior == MB_SOOTOPOLIS_DEEP_WATER)
return TRUE;
else
return FALSE;
@@ -888,10 +890,19 @@ bool8 MetatileBehavior_IsFootprints(u8 metatileBehavior)
return FALSE;
}
-bool8 MetatileBehavior_IsBridge(u8 metatileBehavior)
+// For the sections of log bridges that span water / water's edge.
+// Note that the rest of the metatiles for these bridges use MB_NORMAL.
+// This is used to allow encounters on the water below the bridge.
+bool8 MetatileBehavior_IsBridgeOverWater(u8 metatileBehavior)
{
- if ((metatileBehavior == MB_WARP_OR_BRIDGE || metatileBehavior == MB_UNUSED_71 || metatileBehavior == MB_ROUTE120_NORTH_BRIDGE_1 || metatileBehavior == MB_ROUTE120_NORTH_BRIDGE_2)
- || (metatileBehavior == MB_ROUTE120_NORTH_BRIDGE_3 || metatileBehavior == MB_ROUTE120_NORTH_BRIDGE_4 || metatileBehavior == MB_UNUSED_7E || metatileBehavior == MB_ROUTE110_BRIDGE))
+ if ((metatileBehavior == MB_BRIDGE_OVER_OCEAN
+ || metatileBehavior == MB_BRIDGE_OVER_POND_LOW
+ || metatileBehavior == MB_BRIDGE_OVER_POND_MED
+ || metatileBehavior == MB_BRIDGE_OVER_POND_HIGH)
+ || (metatileBehavior == MB_BRIDGE_OVER_POND_HIGH_EDGE_1
+ || metatileBehavior == MB_BRIDGE_OVER_POND_HIGH_EDGE_2
+ || metatileBehavior == MB_UNUSED_BRIDGE_1
+ || metatileBehavior == MB_UNUSED_BRIDGE_2))
return TRUE;
else
return FALSE;
@@ -899,34 +910,39 @@ bool8 MetatileBehavior_IsBridge(u8 metatileBehavior)
u8 MetatileBehavior_GetBridgeType(u8 metatileBehavior)
{
- u8 result = metatileBehavior - MB_WARP_OR_BRIDGE;
- if (result < 4)
- return result;
+ // MB_BRIDGE_OVER_OCEAN --> BRIDGE_TYPE_OCEAN (Routes 110/119)
+ // MB_BRIDGE_OVER_POND_LOW --> BRIDGE_TYPE_POND_LOW (Unused)
+ // MB_BRIDGE_OVER_POND_MED --> BRIDGE_TYPE_POND_MED (Route 120, south)
+ // MB_BRIDGE_OVER_POND_HIGH --> BRIDGE_TYPE_POND_HIGH (Route 120, north)
+ if (metatileBehavior >= MB_BRIDGE_OVER_OCEAN
+ && metatileBehavior <= MB_BRIDGE_OVER_POND_HIGH)
+ return metatileBehavior - MB_BRIDGE_OVER_OCEAN;
- result = metatileBehavior - MB_ROUTE120_SOUTH_BRIDGE_1;
- if (result < 2)
- return 2;
+ if (metatileBehavior >= MB_BRIDGE_OVER_POND_MED_EDGE_1
+ && metatileBehavior <= MB_BRIDGE_OVER_POND_MED_EDGE_2)
+ return BRIDGE_TYPE_POND_MED;
- result = metatileBehavior - MB_ROUTE120_NORTH_BRIDGE_3;
- if (result < 2)
- return 3;
+ if (metatileBehavior >= MB_BRIDGE_OVER_POND_HIGH_EDGE_1
+ && metatileBehavior <= MB_BRIDGE_OVER_POND_HIGH_EDGE_2)
+ return BRIDGE_TYPE_POND_HIGH;
- return 0;
+ return BRIDGE_TYPE_OCEAN;
}
-u8 MetatileBehavior_8089510(u8 metatileBehavior)
+// Used to allow fishing below the bridge metatiles.
+bool8 MetatileBehavior_IsBridgeOverWaterNoEdge(u8 metatileBehavior)
{
- u8 result = metatileBehavior - MB_WARP_OR_BRIDGE;
-
- if (result < 4)
- return 1;
+ if (metatileBehavior >= MB_BRIDGE_OVER_OCEAN
+ && metatileBehavior <= MB_BRIDGE_OVER_POND_HIGH)
+ return TRUE;
else
- return 0;
+ return FALSE;
}
bool8 MetatileBehavior_IsLandWildEncounter(u8 metatileBehavior)
{
- if (MetatileBehavior_IsSurfableWaterOrUnderwater(metatileBehavior) == FALSE && MetatileBehavior_IsEncounterTile(metatileBehavior) == TRUE)
+ if (MetatileBehavior_IsSurfableWaterOrUnderwater(metatileBehavior) == FALSE
+ && MetatileBehavior_IsEncounterTile(metatileBehavior) == TRUE)
return TRUE;
else
return FALSE;
@@ -934,7 +950,8 @@ bool8 MetatileBehavior_IsLandWildEncounter(u8 metatileBehavior)
bool8 MetatileBehavior_IsWaterWildEncounter(u8 metatileBehavior)
{
- if (MetatileBehavior_IsSurfableWaterOrUnderwater(metatileBehavior) == TRUE && MetatileBehavior_IsEncounterTile(metatileBehavior) == TRUE)
+ if (MetatileBehavior_IsSurfableWaterOrUnderwater(metatileBehavior) == TRUE
+ && MetatileBehavior_IsEncounterTile(metatileBehavior) == TRUE)
return TRUE;
else
return FALSE;
@@ -1148,8 +1165,10 @@ bool8 MetatileBehavior_IsPacifidlogHorizontalLog2(u8 metatileBehavior)
bool8 MetatileBehavior_IsPacifidlogLog(u8 metatileBehavior)
{
- if (metatileBehavior == MB_PACIFIDLOG_VERTICAL_LOG_1 || metatileBehavior == MB_PACIFIDLOG_VERTICAL_LOG_2
- || metatileBehavior == MB_PACIFIDLOG_HORIZONTAL_LOG_1 || metatileBehavior == MB_PACIFIDLOG_HORIZONTAL_LOG_2)
+ if (metatileBehavior == MB_PACIFIDLOG_VERTICAL_LOG_1
+ || metatileBehavior == MB_PACIFIDLOG_VERTICAL_LOG_2
+ || metatileBehavior == MB_PACIFIDLOG_HORIZONTAL_LOG_1
+ || metatileBehavior == MB_PACIFIDLOG_HORIZONTAL_LOG_2)
return TRUE;
else
return FALSE;
@@ -1243,9 +1262,13 @@ bool8 MetatileBehavior_IsAquaHideoutWarp(u8 metatileBehavior)
return FALSE;
}
-bool8 MetatileBehavior_IsWarpOrBridge(u8 metatileBehavior)
+// Very odd, used to initiate a teleport-style warp.
+// No warp events seem to be on a metatile of this kind, and it's
+// used by log bridges over ocean-style water, which wouldn't make
+// sense to have a warp like this.
+bool8 MetatileBehavior_IsBridgeOverOcean(u8 metatileBehavior)
{
- if (metatileBehavior == MB_WARP_OR_BRIDGE)
+ if (metatileBehavior == MB_BRIDGE_OVER_OCEAN)
return TRUE;
else
return FALSE;
@@ -1262,9 +1285,15 @@ bool8 MetatileBehavior_IsMossdeepGymWarp(u8 metatileBehavior)
bool8 MetatileBehavior_IsSurfableFishableWater(u8 metatileBehavior)
{
- if (metatileBehavior == MB_POND_WATER || metatileBehavior == MB_OCEAN_WATER || metatileBehavior == MB_SEMI_DEEP_WATER || metatileBehavior == MB_DEEP_WATER
- || metatileBehavior == MB_SOOTOPOLIS_DEEP_WATER || (metatileBehavior == MB_EASTWARD_CURRENT || metatileBehavior == MB_WESTWARD_CURRENT
- || metatileBehavior == MB_NORTHWARD_CURRENT || metatileBehavior == MB_SOUTHWARD_CURRENT))
+ if (metatileBehavior == MB_POND_WATER
+ || metatileBehavior == MB_OCEAN_WATER
+ || metatileBehavior == MB_SEMI_DEEP_WATER
+ || metatileBehavior == MB_DEEP_WATER
+ || metatileBehavior == MB_SOOTOPOLIS_DEEP_WATER
+ || (metatileBehavior == MB_EASTWARD_CURRENT
+ || metatileBehavior == MB_WESTWARD_CURRENT
+ || metatileBehavior == MB_NORTHWARD_CURRENT
+ || metatileBehavior == MB_SOUTHWARD_CURRENT))
return TRUE;
else
return FALSE;
diff --git a/src/mevent2.c b/src/mevent2.c
deleted file mode 100755
index d2c020858..000000000
--- a/src/mevent2.c
+++ /dev/null
@@ -1,630 +0,0 @@
-#include "global.h"
-#include "util.h"
-#include "main.h"
-#include "event_data.h"
-#include "easy_chat.h"
-#include "script.h"
-#include "battle_tower.h"
-#include "mevent_news.h"
-#include "string_util.h"
-#include "new_game.h"
-#include "mevent.h"
-#include "constants/mevent.h"
-
-static EWRAM_DATA bool32 gUnknown_02022C70 = FALSE;
-
-static void sub_801B180(void);
-static void s_DestroyWonderNews(void);
-static bool32 sub_801B114(const struct WonderNews *data);
-static bool32 sub_801B2CC(const struct WonderCard *data);
-static void sub_801B330(void);
-static void sub_801B368(void);
-static void sub_801B9F8(void);
-static void sub_801BA8C(u32 a0, u32 a1, u32 *a2, int a3);
-
-void sub_801AFD8(void)
-{
- CpuFill32(0, &gSaveBlock1Ptr->unk_322C, sizeof(gSaveBlock1Ptr->unk_322C));
- sub_801B180();
- InitQuestionnaireWords();
-}
-
-struct WonderNews *GetSavedWonderNews(void)
-{
- return &gSaveBlock1Ptr->unk_322C.wonderNews.data;
-}
-
-struct WonderCard *GetSavedWonderCard(void)
-{
- return &gSaveBlock1Ptr->unk_322C.wonderCard.data;
-}
-
-struct MEventBuffer_3430_Sub *sav1_get_mevent_buffer_2(void)
-{
- return &gSaveBlock1Ptr->unk_322C.buffer_310.data;
-}
-
-struct MysteryEventStruct *sub_801B044(void)
-{
- return &gSaveBlock1Ptr->unk_322C.unk_340;
-}
-
-u16 *GetQuestionnaireWordsPtr(void)
-{
- return gSaveBlock1Ptr->unk_322C.questionnaireWords;
-}
-
-void DestroyWonderNews(void)
-{
- s_DestroyWonderNews();
-}
-
-bool32 sub_801B078(const struct WonderNews *src)
-{
- if (!sub_801B114(src))
- return FALSE;
-
- s_DestroyWonderNews();
- gSaveBlock1Ptr->unk_322C.wonderNews.data = *src;
- gSaveBlock1Ptr->unk_322C.wonderNews.crc = CalcCRC16WithTable((void *)&gSaveBlock1Ptr->unk_322C.wonderNews.data, sizeof(struct WonderNews));
- return TRUE;
-}
-
-bool32 ValidateReceivedWonderNews(void)
-{
- if (CalcCRC16WithTable((void *)&gSaveBlock1Ptr->unk_322C.wonderNews.data, sizeof(struct WonderNews)) != gSaveBlock1Ptr->unk_322C.wonderNews.crc)
- return FALSE;
- if (!sub_801B114(&gSaveBlock1Ptr->unk_322C.wonderNews.data))
- return FALSE;
-
- return TRUE;
-}
-
-static bool32 sub_801B114(const struct WonderNews *data)
-{
- if (data->unk_00 == 0)
- return FALSE;
-
- return TRUE;
-}
-
-bool32 WonderNews_Test_Unk_02(void)
-{
- const struct WonderNews *data = &gSaveBlock1Ptr->unk_322C.wonderNews.data;
- if (data->unk_02 == 0)
- return FALSE;
-
- return TRUE;
-}
-
-static void s_DestroyWonderNews(void)
-{
- CpuFill32(0, GetSavedWonderNews(), sizeof(gSaveBlock1Ptr->unk_322C.wonderNews.data));
- gSaveBlock1Ptr->unk_322C.wonderNews.crc = 0;
-}
-
-static void sub_801B180(void)
-{
- CpuFill32(0, sub_801B044(), sizeof(struct MysteryEventStruct));
- sub_801DBC0();
-}
-
-bool32 sub_801B1A4(const u8 *src)
-{
- const u8 *r5 = (const u8 *)&gSaveBlock1Ptr->unk_322C.wonderNews.data;
- u32 i;
- if (!ValidateReceivedWonderNews())
- return FALSE;
-
- for (i = 0; i < sizeof(struct WonderNews); i++)
- {
- if (r5[i] != src[i])
- return FALSE;
- }
-
- return TRUE;
-}
-
-void DestroyWonderCard(void)
-{
- sub_801B330();
- sub_801B368();
- sub_801B9F8();
- ClearRamScript();
- ClearMysteryEventFlags();
- ClearMysteryEventVars();
- ClearEReaderTrainer(&gSaveBlock2Ptr->frontier.ereaderTrainer);
-}
-
-bool32 sub_801B21C(const struct WonderCard *data)
-{
- struct MEventBuffer_3430_Sub *r2;
- struct WonderCard *r1;
- if (!sub_801B2CC(data))
- return FALSE;
-
- DestroyWonderCard();
- memcpy(&gSaveBlock1Ptr->unk_322C.wonderCard.data, data, sizeof(struct WonderCard));
- gSaveBlock1Ptr->unk_322C.wonderCard.crc = CalcCRC16WithTable((void *)&gSaveBlock1Ptr->unk_322C.wonderCard.data, sizeof(struct WonderCard));
- r2 = &gSaveBlock1Ptr->unk_322C.buffer_310.data;
- r1 = &gSaveBlock1Ptr->unk_322C.wonderCard.data;
- r2->unk_06 = r1->unk_02;
- return TRUE;
-}
-
-bool32 ValidateReceivedWonderCard(void)
-{
- if (gSaveBlock1Ptr->unk_322C.wonderCard.crc != CalcCRC16WithTable((void *)&gSaveBlock1Ptr->unk_322C.wonderCard.data, sizeof(struct WonderCard)))
- return FALSE;
- if (!sub_801B2CC(&gSaveBlock1Ptr->unk_322C.wonderCard.data))
- return FALSE;
- if (!ValidateSavedRamScript())
- return FALSE;
-
- return TRUE;
-}
-
-static bool32 sub_801B2CC(const struct WonderCard *data)
-{
- if (data->unk_00 == 0)
- return FALSE;
- if (data->unk_08_0 > 2)
- return FALSE;
- if (!(data->unk_08_6 == 0 || data->unk_08_6 == 1 || data->unk_08_6 == 2))
- return FALSE;
- if (data->unk_08_2 > 7)
- return FALSE;
- if (data->unk_09 > 7)
- return FALSE;
-
- return TRUE;
-}
-
-bool32 WonderCard_Test_Unk_08_6(void)
-{
- const struct WonderCard *data = &gSaveBlock1Ptr->unk_322C.wonderCard.data;
- if (data->unk_08_6 == 0)
- return FALSE;
-
- return TRUE;
-}
-
-static void sub_801B330(void)
-{
- CpuFill32(0, &gSaveBlock1Ptr->unk_322C.wonderCard.data, sizeof(struct WonderCard));
- gSaveBlock1Ptr->unk_322C.wonderCard.crc = 0;
-}
-
-static void sub_801B368(void)
-{
- CpuFill32(0, sav1_get_mevent_buffer_2(), 18 *sizeof(u16));
- gSaveBlock1Ptr->unk_322C.buffer_310.crc = 0;
-}
-
-u16 GetWonderCardFlagID(void)
-{
- if (ValidateReceivedWonderCard())
- return gSaveBlock1Ptr->unk_322C.wonderCard.data.unk_00;
-
- return 0;
-}
-
-void WonderCard_ResetInternalReceivedFlag(struct WonderCard *buffer)
-{
- if (buffer->unk_08_6 == 1)
- buffer->unk_08_6 = 0;
-}
-
-static bool32 IsWonderCardFlagIDInValidRange(u16 a0)
-{
- if (a0 >= 1000 && a0 < 1020)
- return TRUE;
-
- return FALSE;
-}
-
-static const u16 sMysteryGiftFlags[] =
-{
- FLAG_RECEIVED_AURORA_TICKET,
- FLAG_RECEIVED_MYSTIC_TICKET,
- FLAG_RECEIVED_OLD_SEA_MAP,
- FLAG_UNUSED_MYSTERY_GIFT_0x13D,
- FLAG_UNUSED_MYSTERY_GIFT_0x13E,
- FLAG_UNUSED_MYSTERY_GIFT_0x13F,
- FLAG_UNUSED_MYSTERY_GIFT_0x140,
- FLAG_UNUSED_MYSTERY_GIFT_0x141,
- FLAG_UNUSED_MYSTERY_GIFT_0x142,
- FLAG_UNUSED_MYSTERY_GIFT_0x143,
- FLAG_UNUSED_MYSTERY_GIFT_0x144,
- FLAG_UNUSED_MYSTERY_GIFT_0x145,
- FLAG_UNUSED_MYSTERY_GIFT_0x146,
- FLAG_UNUSED_MYSTERY_GIFT_0x147,
- FLAG_UNUSED_MYSTERY_GIFT_0x148,
- FLAG_UNUSED_MYSTERY_GIFT_0x149,
- FLAG_UNUSED_MYSTERY_GIFT_0x14A,
- FLAG_UNUSED_MYSTERY_GIFT_0x14B,
- FLAG_UNUSED_MYSTERY_GIFT_0x14C,
- FLAG_UNUSED_MYSTERY_GIFT_0x14D,
-};
-
-bool32 CheckReceivedGiftFromWonderCard(void)
-{
- u16 value = GetWonderCardFlagID();
- if (!IsWonderCardFlagIDInValidRange(value))
- return FALSE;
-
- if (FlagGet(sMysteryGiftFlags[value - 1000]) == TRUE)
- return FALSE;
-
- return TRUE;
-}
-
-static int sub_801B438(const struct MEventBuffer_3430_Sub *data, int size)
-{
- int r3 = 0;
- int i;
- for (i = 0; i < size; i++)
- {
- if (data->unk_08[1][i] && data->unk_08[0][i])
- r3++;
- }
-
- return r3;
-}
-
-static bool32 sub_801B460(const struct MEventBuffer_3430_Sub *data1, const u16 *data2, int size)
-{
- int i;
- for (i = 0; i < size; i++)
- {
- if (data1->unk_08[1][i] == data2[1])
- return TRUE;
- if (data1->unk_08[0][i] == data2[0])
- return TRUE;
- }
-
- return FALSE;
-}
-
-static bool32 sub_801B4A4(const u16 *data)
-{
- if (data[1] == 0)
- return FALSE;
- if (data[0] == 0)
- return FALSE;
- if (data[0] >= NUM_SPECIES)
- return FALSE;
- return TRUE;
-}
-
-static int sub_801B4CC(void)
-{
- struct WonderCard *data;
- if (!ValidateReceivedWonderCard())
- return 0;
-
- data = &gSaveBlock1Ptr->unk_322C.wonderCard.data;
- if (data->unk_08_0 != 1)
- return 0;
-
- return sub_801B438(&gSaveBlock1Ptr->unk_322C.buffer_310.data, data->unk_09);
-}
-
-bool32 sub_801B508(const u16 *data)
-{
- struct WonderCard *buffer = &gSaveBlock1Ptr->unk_322C.wonderCard.data;
- int size = buffer->unk_09;
- int i;
- if (!sub_801B4A4(data))
- return FALSE;
-
- if (sub_801B460(&gSaveBlock1Ptr->unk_322C.buffer_310.data, data, size))
- return FALSE;
-
- for (i = 0; i < size; i++)
- {
- if (gSaveBlock1Ptr->unk_322C.buffer_310.data.unk_08[1][i] == 0 && gSaveBlock1Ptr->unk_322C.buffer_310.data.unk_08[0][i] == 0)
- {
- gSaveBlock1Ptr->unk_322C.buffer_310.data.unk_08[1][i] = data[1];
- gSaveBlock1Ptr->unk_322C.buffer_310.data.unk_08[0][i] = data[0];
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-void sub_801B580(struct MEventStruct_Unk1442CC *data, bool32 a1)
-{
- int i;
- CpuFill32(0, data, sizeof(struct MEventStruct_Unk1442CC));
- data->unk_00 = 0x101;
- data->unk_04 = 1;
- data->unk_08 = 1;
-
- if (a1)
- {
- data->unk_0C = 5;
- data->unk_10 = 0x0201;
- }
- else
- {
- data->unk_0C = 4;
- data->unk_10 = 0x0200;
- }
-
- if (ValidateReceivedWonderCard())
- {
- data->unk_14 = GetSavedWonderCard()->unk_00;
- data->unk_20 = *sav1_get_mevent_buffer_2();
- data->unk_44 = GetSavedWonderCard()->unk_09;
- }
- else
- {
- data->unk_14 = 0;
- }
-
- for (i = 0; i < NUM_QUESTIONNAIRE_WORDS; i++)
- data->unk_16[i] = gSaveBlock1Ptr->unk_322C.questionnaireWords[i];
-
- CopyTrainerId(data->unk_4C, gSaveBlock2Ptr->playerTrainerId);
- StringCopy(data->unk_45, gSaveBlock2Ptr->playerName);
- for (i = 0; i < 6; i++)
- data->unk_50[i] = gSaveBlock1Ptr->easyChatProfile[i];
-
- memcpy(data->unk_5C, RomHeaderGameCode, 4);
- data->unk_60 = RomHeaderSoftwareVersion;
-}
-
-bool32 sub_801B6A0(const struct MEventStruct_Unk1442CC *data, bool32 a1)
-{
- if (data->unk_00 != 0x101)
- return FALSE;
-
- if (!(data->unk_04 & 1))
- return FALSE;
-
- if (!(data->unk_08 & 1))
- return FALSE;
-
- if (!a1)
- {
- if (!(data->unk_0C & 4))
- return FALSE;
-
- if (!(data->unk_10 & 0x380))
- return FALSE;
- }
-
- return TRUE;
-}
-
-u32 sub_801B6EC(const u16 *a0, const struct MEventStruct_Unk1442CC *a1, const void *unused)
-{
- if (a1->unk_14 == 0)
- return 0;
-
- if (*a0 == a1->unk_14)
- return 1;
-
- return 2;
-}
-
-u32 sub_801B708(const u16 *a0, const struct MEventStruct_Unk1442CC *a1, const void *unused)
-{
- int r4 = a1->unk_44 - sub_801B438(&a1->unk_20, a1->unk_44);
- if (r4 == 0)
- return 1;
- if (sub_801B460(&a1->unk_20, a0, a1->unk_44))
- return 3;
- if (r4 == 1)
- return 4;
- return 2;
-}
-
-bool32 MEventStruct_Unk1442CC_CompareField_unk_16(const struct MEventStruct_Unk1442CC *a0, const u16 *a1)
-{
- int i;
- for (i = 0; i < NUM_QUESTIONNAIRE_WORDS; i++)
- {
- if (a0->unk_16[i] != a1[i])
- return FALSE;
- }
-
- return TRUE;
-}
-
-static int sub_801B770(const struct MEventStruct_Unk1442CC *a0)
-{
- return sub_801B438(&a0->unk_20, a0->unk_44);
-}
-
-u16 MEventStruct_Unk1442CC_GetValueNFrom_unk_20(const struct MEventStruct_Unk1442CC *a0, u32 command)
-{
- switch (command)
- {
- case 0:
- return a0->unk_20.unk_00;
- case 1:
- return a0->unk_20.unk_02;
- case 2:
- return a0->unk_20.unk_04;
- case 3:
- return sub_801B770(a0);
- case 4:
- return a0->unk_44;
- default:
- AGB_ASSERT(0);
- return 0;
- }
-}
-
-static void sub_801B7D8(u32 command)
-{
- struct WonderCard *data = &gSaveBlock1Ptr->unk_322C.wonderCard.data;
- if (data->unk_08_0 == 2)
- {
- u16 *dest = NULL;
- switch (command)
- {
- case 0:
- dest = &gSaveBlock1Ptr->unk_322C.buffer_310.data.unk_00;
- break;
- case 1:
- dest = &gSaveBlock1Ptr->unk_322C.buffer_310.data.unk_02;
- break;
- case 2:
- dest = &gSaveBlock1Ptr->unk_322C.buffer_310.data.unk_04;
- break;
- case 3:
- break;
- case 4:
- break;
- }
-
- if (dest == NULL)
- {
- AGB_ASSERT(0);
- }
- else if (++(*dest) > 999)
- {
- *dest = 999;
- }
- }
-}
-
-u16 mevent_081445C0(u32 command)
-{
- switch (command)
- {
- case GET_CARD_BATTLES_WON_INTERNAL:
- {
- struct WonderCard *data = &gSaveBlock1Ptr->unk_322C.wonderCard.data;
- if (data->unk_08_0 == 2)
- {
- struct MEventBuffer_3430_Sub *buffer = &gSaveBlock1Ptr->unk_322C.buffer_310.data;
- return buffer->unk_00;
- }
- break;
- }
- case 1: // Never occurs
- {
- struct WonderCard *data = &gSaveBlock1Ptr->unk_322C.wonderCard.data;
- if (data->unk_08_0 == 2)
- {
- struct MEventBuffer_3430_Sub *buffer = &gSaveBlock1Ptr->unk_322C.buffer_310.data;
- return buffer->unk_02;
- }
- break;
- }
- case 2: // Never occurs
- {
- struct WonderCard *data = &gSaveBlock1Ptr->unk_322C.wonderCard.data;
- if (data->unk_08_0 == 2)
- {
- struct MEventBuffer_3430_Sub *buffer = &gSaveBlock1Ptr->unk_322C.buffer_310.data;
- return buffer->unk_04;
- }
- break;
- }
- case GET_NUM_STAMPS_INTERNAL:
- {
- struct WonderCard *data = &gSaveBlock1Ptr->unk_322C.wonderCard.data;
- if (data->unk_08_0 == 1)
- return sub_801B4CC();
- break;
- }
- case GET_MAX_STAMPS_INTERNAL:
- {
- struct WonderCard *data = &gSaveBlock1Ptr->unk_322C.wonderCard.data;
- if (data->unk_08_0 == 1)
- return data->unk_09;
- break;
- }
- }
-
- AGB_ASSERT(0);
- return 0;
-}
-
-void ResetReceivedWonderCardFlag(void)
-{
- gUnknown_02022C70 = FALSE;
-}
-
-bool32 MEventHandleReceivedWonderCard(u16 a0)
-{
- gUnknown_02022C70 = FALSE;
- if (a0 == 0)
- return FALSE;
-
- if (!ValidateReceivedWonderCard())
- return FALSE;
-
- if (gSaveBlock1Ptr->unk_322C.wonderCard.data.unk_00 != a0)
- return FALSE;
-
- gUnknown_02022C70 = TRUE;
- return TRUE;
-}
-
-void RecordIdOfWonderCardSenderByEventType(u32 a0, u32 a1)
-{
- if (gUnknown_02022C70)
- {
- switch (a0)
- {
- case 2:
- sub_801BA8C(2, a1, gSaveBlock1Ptr->unk_322C.unk_344[1], 5);
- break;
- case 0:
- sub_801BA8C(0, a1, gSaveBlock1Ptr->unk_322C.unk_344[0], 5);
- break;
- case 1:
- sub_801BA8C(1, a1, gSaveBlock1Ptr->unk_322C.unk_344[0], 5);
- break;
- default:
- AGB_ASSERT(0);
- }
- }
-}
-
-static void sub_801B9F8(void)
-{
- CpuFill32(0, gSaveBlock1Ptr->unk_322C.unk_344, sizeof(gSaveBlock1Ptr->unk_322C.unk_344));
-}
-
-static bool32 sub_801BA24(u32 a0, u32 *a1, int size)
-{
- int i;
- int j;
-
- for (i = 0; i < size; i++)
- {
- if (a1[i] == a0)
- break;
- }
-
- if (i == size)
- {
- for (j = size - 1; j > 0; j--)
- a1[j] = a1[j - 1];
-
- a1[0] = a0;
- return TRUE;
- }
- else
- {
- for (j = i; j > 0; j--)
- a1[j] = a1[j - 1];
-
- a1[0] = a0;
- return FALSE;
- }
-}
-
-static void sub_801BA8C(u32 a0, u32 a1, u32 *a2, int a3)
-{
- if (sub_801BA24(a1, a2, a3))
- sub_801B7D8(a0);
-}
diff --git a/src/mevent_801BAAC.c b/src/mevent_801BAAC.c
deleted file mode 100644
index a3e6ee0b6..000000000
--- a/src/mevent_801BAAC.c
+++ /dev/null
@@ -1,826 +0,0 @@
-#include "global.h"
-#include "bg.h"
-#include "gpu_regs.h"
-#include "palette.h"
-#include "decompress.h"
-#include "malloc.h"
-#include "menu.h"
-#include "pokemon_icon.h"
-#include "union_room.h"
-#include "list_menu.h"
-#include "text_window.h"
-#include "string_util.h"
-#include "link_rfu.h"
-#include "mevent.h"
-#include "mystery_gift.h"
-#include "constants/rgb.h"
-
-struct UnkStruct_8467FB8
-{
- u8 textPal1:4;
- u8 textPal2:4;
- u8 textPal3:4;
- u8 textPal4:4;
- const u32 * tiles;
- const u32 * map;
- const u16 * pal;
-};
-
-struct UnkStruct_203F3C8_02DC
-{
- u8 unk_00;
- u8 unk_01[41];
- u8 unk_42[4];
-};
-
-struct UnkStruct_203F3C8
-{
- /*0000*/ struct WonderCard unk_0000;
- /*014c*/ struct MEventBuffer_3430_Sub unk_014C;
- /*0170*/ const struct UnkStruct_8467FB8 * unk_0170;
- /*0174*/ u8 unk_0174;
- /*0175*/ u8 unk_0175;
- /*0176*/ u16 unk_0176[3];
- /*017C*/ u8 unk_017C;
- /*017D*/ u8 unk_017D[7][2];
- /*018B*/ u8 unk_018B[41];
- /*01B4*/ u8 unk_01B4[41];
- /*01DD*/ u8 unk_01DD[7];
- /*01E4*/ u8 unk_01E4[4][41];
- /*0288*/ u8 unk_0288[41];
- /*02B1*/ u8 unk_02B1[41];
- /*02DC*/ struct UnkStruct_203F3C8_02DC unk_02DC[8];
- /*045C*/ u8 buffer_045C[0x1000];
-};
-
-EWRAM_DATA struct UnkStruct_203F3C8 * sWonderCardData = NULL;
-
-void sub_801BEF8(void);
-void sub_801C178(u8 whichWindow);
-void sub_801C4C0(void);
-void sub_801C61C(void);
-
-extern const struct OamData gOamData_AffineOff_ObjNormal_32x16;
-
-const u8 sTextColorTable[][3] = {
- {TEXT_COLOR_TRANSPARENT, TEXT_COLOR_DARK_GRAY, TEXT_COLOR_LIGHT_GRAY},
- {TEXT_COLOR_TRANSPARENT, TEXT_COLOR_WHITE, TEXT_COLOR_DARK_GRAY}
-};
-const u8 ALIGNED(4) gUnknown_082F0E18[3] = {7, 4, 7};
-const struct WindowTemplate gUnknown_082F0E1C[] = {
- {
- .bg = 1,
- .tilemapLeft = 1,
- .tilemapTop = 1,
- .width = 25,
- .height = 4,
- .paletteNum = 2,
- .baseBlock = 0x029c
- }, {
- .bg = 1,
- .tilemapLeft = 1,
- .tilemapTop = 6,
- .width = 28,
- .height = 8,
- .paletteNum = 2,
- .baseBlock = 0x01bc
- }, {
- .bg = 1,
- .tilemapLeft = 1,
- .tilemapTop = 14,
- .width = 28,
- .height = 5,
- .paletteNum = 2,
- .baseBlock = 0x0130
- }
-};
-
-const u16 gWonderCardBgPal1[] = INCBIN_U16("graphics/wonder_transfers/wonder_card_1.gbapal");
-const u16 gWonderCardBgPal2[] = INCBIN_U16("graphics/wonder_transfers/wonder_card_2.gbapal");
-const u16 gWonderCardBgPal3[] = INCBIN_U16("graphics/wonder_transfers/wonder_card_3.gbapal");
-const u16 gWonderCardBgPal4[] = INCBIN_U16("graphics/wonder_transfers/wonder_card_4.gbapal");
-const u16 gWonderCardBgPal5[] = INCBIN_U16("graphics/wonder_transfers/wonder_card_5.gbapal");
-const u16 gWonderCardBgPal6[] = INCBIN_U16("graphics/wonder_transfers/wonder_card_6.gbapal");
-const u16 gWonderCardBgPal7[] = INCBIN_U16("graphics/wonder_transfers/wonder_card_7.gbapal");
-const u16 gWonderCardBgPal8[] = INCBIN_U16("graphics/wonder_transfers/wonder_card_8.gbapal");
-const u32 gWonderCardBgGfx1[] = INCBIN_U32("graphics/wonder_transfers/wonder_card_1.4bpp.lz");
-const u32 gWonderCardBgTilemap1[] = INCBIN_U32("graphics/wonder_transfers/wonder_card_1.bin.lz");
-const u32 gWonderCardBgGfx2[] = INCBIN_U32("graphics/wonder_transfers/wonder_card_2.4bpp.lz");
-const u32 gWonderCardBgTilemap2[] = INCBIN_U32("graphics/wonder_transfers/wonder_card_2.bin.lz");
-const u32 gWonderCardBgGfx3[] = INCBIN_U32("graphics/wonder_transfers/wonder_card_3.4bpp.lz");
-const u32 gWonderCardBgTilemap3[] = INCBIN_U32("graphics/wonder_transfers/wonder_card_3.bin.lz");
-const u32 gWonderCardBgGfx7[] = INCBIN_U32("graphics/wonder_transfers/wonder_card_7.4bpp.lz");
-const u32 gWonderCardBgTilemap7[] = INCBIN_U32("graphics/wonder_transfers/wonder_card_7.bin.lz");
-const u32 gWonderCardBgGfx8[] = INCBIN_U32("graphics/wonder_transfers/wonder_card_8.4bpp.lz");
-const u32 gWonderCardBgTilemap8[] = INCBIN_U32("graphics/wonder_transfers/wonder_card_8.bin.lz");
-const u16 gWonderCardShadowPal1[] = INCBIN_U16("graphics/wonder_transfers/wonder_card_shadow_1.gbapal");
-const u16 gWonderCardShadowPal2[] = INCBIN_U16("graphics/wonder_transfers/wonder_card_shadow_2.gbapal");
-const u16 gWonderCardShadowPal3[] = INCBIN_U16("graphics/wonder_transfers/wonder_card_shadow_3.gbapal");
-const u16 gWonderCardShadowPal4[] = INCBIN_U16("graphics/wonder_transfers/wonder_card_shadow_4.gbapal");
-const u16 gWonderCardShadowPal5[] = INCBIN_U16("graphics/wonder_transfers/wonder_card_shadow_5.gbapal");
-const u16 gWonderCardShadowPal6[] = INCBIN_U16("graphics/wonder_transfers/wonder_card_shadow_6.gbapal");
-const u16 gWonderCardShadowPal7[] = INCBIN_U16("graphics/wonder_transfers/wonder_card_shadow_7.gbapal");
-const u16 gWonderCardShadowPal8[] = INCBIN_U16("graphics/wonder_transfers/wonder_card_shadow_8.gbapal");
-const u32 gWonderCardShadowGfx[] = INCBIN_U32("graphics/wonder_transfers/wonder_card_shadow.4bpp.lz");
-
-const struct CompressedSpriteSheet gUnknown_082F1D00 = {
- gWonderCardShadowGfx, 0x100, 0x8000
-};
-const struct SpritePalette gUnknown_082F1D08[] = {
- {gWonderCardShadowPal1, 0x8000},
- {gWonderCardShadowPal2, 0x8000},
- {gWonderCardShadowPal3, 0x8000},
- {gWonderCardShadowPal4, 0x8000},
- {gWonderCardShadowPal5, 0x8000},
- {gWonderCardShadowPal6, 0x8000},
- {gWonderCardShadowPal7, 0x8000},
- {gWonderCardShadowPal8, 0x8000}
-};
-const struct SpriteTemplate gUnknown_082F1D48 = {
- 0x8000, 0x8000, &gOamData_AffineOff_ObjNormal_32x16, gDummySpriteAnimTable, NULL, gDummySpriteAffineAnimTable, SpriteCallbackDummy
-};
-const struct UnkStruct_8467FB8 gUnknown_082F1D60[8] = {
- {1, 0, 0, 0, gWonderCardBgGfx1, gWonderCardBgTilemap1, gWonderCardBgPal1},
- {1, 0, 0, 1, gWonderCardBgGfx2, gWonderCardBgTilemap2, gWonderCardBgPal2},
- {1, 0, 0, 2, gWonderCardBgGfx3, gWonderCardBgTilemap3, gWonderCardBgPal3},
- {1, 0, 0, 3, gWonderCardBgGfx3, gWonderCardBgTilemap3, gWonderCardBgPal4},
- {1, 0, 0, 4, gWonderCardBgGfx3, gWonderCardBgTilemap3, gWonderCardBgPal5},
- {1, 0, 0, 5, gWonderCardBgGfx3, gWonderCardBgTilemap3, gWonderCardBgPal6},
- {1, 0, 0, 6, gWonderCardBgGfx7, gWonderCardBgTilemap7, gWonderCardBgPal7},
- {1, 0, 0, 7, gWonderCardBgGfx8, gWonderCardBgTilemap8, gWonderCardBgPal8}
-};
-
-bool32 InitWonderCardResources(struct WonderCard * r5, struct MEventBuffer_3430_Sub * r6)
-{
- if (r5 == NULL || r6 == NULL)
- return FALSE;
- sWonderCardData = AllocZeroed(sizeof(struct UnkStruct_203F3C8));
- if (sWonderCardData == NULL)
- return FALSE;
- sWonderCardData->unk_0000 = *r5;
- sWonderCardData->unk_014C = *r6;
- if (sWonderCardData->unk_0000.unk_08_2 >= ARRAY_COUNT(gUnknown_082F1D60))
- sWonderCardData->unk_0000.unk_08_2 = 0;
- if (sWonderCardData->unk_0000.unk_08_0 >= ARRAY_COUNT(gUnknown_082F0E18))
- sWonderCardData->unk_0000.unk_08_0 = 0;
- if (sWonderCardData->unk_0000.unk_09 > ARRAY_COUNT(sWonderCardData->unk_017D))
- sWonderCardData->unk_0000.unk_09 = 0;
- sWonderCardData->unk_0170 = &gUnknown_082F1D60[sWonderCardData->unk_0000.unk_08_2];
- return TRUE;
-}
-
-void DestroyWonderCardResources(void)
-{
- if (sWonderCardData != NULL)
- {
- *sWonderCardData = (struct UnkStruct_203F3C8){};
- Free(sWonderCardData);
- sWonderCardData = NULL;
- }
-}
-
-s32 FadeToWonderCardMenu(void)
-{
- if (sWonderCardData == NULL)
- return -1;
- switch(sWonderCardData->unk_0174)
- {
- case 0:
- BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK);
- break;
- case 1:
- if (UpdatePaletteFade())
- return 0;
- break;
- case 2:
- FillBgTilemapBufferRect_Palette0(0, 0x000, 0, 0, 30, 20);
- FillBgTilemapBufferRect_Palette0(1, 0x000, 0, 0, 30, 20);
- FillBgTilemapBufferRect_Palette0(2, 0x000, 0, 0, 30, 20);
- CopyBgTilemapBufferToVram(0);
- CopyBgTilemapBufferToVram(1);
- CopyBgTilemapBufferToVram(2);
- DecompressAndCopyTileDataToVram(2, sWonderCardData->unk_0170->tiles, 0, 0x008, 0);
- sWonderCardData->unk_0176[0] = AddWindow(&gUnknown_082F0E1C[0]);
- sWonderCardData->unk_0176[1] = AddWindow(&gUnknown_082F0E1C[1]);
- sWonderCardData->unk_0176[2] = AddWindow(&gUnknown_082F0E1C[2]);
- break;
- case 3:
- if (FreeTempTileDataBuffersIfPossible())
- return 0;
- LoadPalette(GetTextWindowPalette(1), 0x20, 0x20);
- gPaletteFade.bufferTransferDisabled = TRUE;
- LoadPalette(sWonderCardData->unk_0170->pal, 0x10, 0x20);
- LZ77UnCompWram(sWonderCardData->unk_0170->map, sWonderCardData->buffer_045C);
- CopyRectToBgTilemapBufferRect(2, sWonderCardData->buffer_045C, 0, 0, 30, 20, 0, 0, 30, 20, 1, 0x008, 0);
- CopyBgTilemapBufferToVram(2);
- break;
- case 4:
- sub_801BEF8();
- break;
- case 5:
- sub_801C178(0);
- sub_801C178(1);
- sub_801C178(2);
- CopyBgTilemapBufferToVram(1);
- break;
- case 6:
- LoadMonIconPalettes();
- break;
- case 7:
- ShowBg(1);
- ShowBg(2);
- gPaletteFade.bufferTransferDisabled = FALSE;
- sub_801C4C0();
- BeginNormalPaletteFade(PALETTES_ALL, 0, 16, 0, RGB_BLACK);
- UpdatePaletteFade();
- break;
- default:
- if (UpdatePaletteFade())
- return 0;
- sWonderCardData->unk_0174 = 0;
- return 1;
- }
- ++sWonderCardData->unk_0174;
- return 0;
-}
-
-s32 FadeOutFromWonderCard(bool32 flag)
-{
- if (sWonderCardData == NULL)
- return -1;
- switch (sWonderCardData->unk_0174)
- {
- case 0:
- BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK);
- break;
- case 1:
- if (UpdatePaletteFade())
- return 0;
- break;
- case 2:
- FillBgTilemapBufferRect_Palette0(0, 0x000, 0, 0, 30, 20);
- FillBgTilemapBufferRect_Palette0(1, 0x000, 0, 0, 30, 20);
- FillBgTilemapBufferRect_Palette0(2, 0x000, 0, 0, 30, 20);
- CopyBgTilemapBufferToVram(0);
- CopyBgTilemapBufferToVram(1);
- CopyBgTilemapBufferToVram(2);
- break;
- case 3:
- HideBg(1);
- HideBg(2);
- RemoveWindow(sWonderCardData->unk_0176[2]);
- RemoveWindow(sWonderCardData->unk_0176[1]);
- RemoveWindow(sWonderCardData->unk_0176[0]);
- break;
- case 4:
- sub_801C61C();
- FreeMonIconPalettes();
- break;
- case 5:
- PrintMysteryGiftOrEReaderTopMenu(gGiftIsFromEReader, flag);
- CopyBgTilemapBufferToVram(0);
- BeginNormalPaletteFade(PALETTES_ALL, 0, 16, 0, RGB_BLACK);
- break;
- default:
- if (UpdatePaletteFade())
- return 0;
- sWonderCardData->unk_0174 = 0;
- return 1;
- }
- ++sWonderCardData->unk_0174;
- return 0;
-}
-
-void sub_801BEF8(void)
-{
- u16 i = 0;
- u16 r6;
- u16 sp0[3] = {0, 0, 0};
-
- memcpy(sWonderCardData->unk_018B, sWonderCardData->unk_0000.unk_0A, 40);
- sWonderCardData->unk_018B[40] = EOS;
- memcpy(sWonderCardData->unk_01B4, sWonderCardData->unk_0000.unk_32, 40);
- sWonderCardData->unk_01B4[40] = EOS;
- if (sWonderCardData->unk_0000.unk_04 > 999999)
- sWonderCardData->unk_0000.unk_04 = 999999;
- ConvertIntToDecimalStringN(sWonderCardData->unk_01DD, sWonderCardData->unk_0000.unk_04, STR_CONV_MODE_LEFT_ALIGN, 6);
- for (i = 0; i < 4; i++)
- {
- memcpy(sWonderCardData->unk_01E4[i], sWonderCardData->unk_0000.unk_5A[i], 40);
- sWonderCardData->unk_01E4[i][40] = EOS;
- }
- memcpy(sWonderCardData->unk_0288, sWonderCardData->unk_0000.unk_FA, 40);
- sWonderCardData->unk_0288[40] = EOS;
- switch (sWonderCardData->unk_0000.unk_08_0)
- {
- case 0:
- memcpy(sWonderCardData->unk_02B1, sWonderCardData->unk_0000.unk_122, 40);
- sWonderCardData->unk_02B1[40] = EOS;
- break;
- case 1:
- sWonderCardData->unk_02B1[00] = EOS;
- break;
- case 2:
- sWonderCardData->unk_02B1[00] = EOS;
- sp0[0] = sWonderCardData->unk_014C.unk_00 < 999 ? sWonderCardData->unk_014C.unk_00 : 999;
- sp0[1] = sWonderCardData->unk_014C.unk_02 < 999 ? sWonderCardData->unk_014C.unk_02 : 999;
- sp0[2] = sWonderCardData->unk_014C.unk_04 < 999 ? sWonderCardData->unk_014C.unk_04 : 999;
- for (i = 0; i < 8; i++)
- {
- memset(sWonderCardData->unk_02DC[i].unk_42, EOS, 4);
- memset(sWonderCardData->unk_02DC[i].unk_01, EOS, 41);
- }
- for (i = 0, r6 = 0; i < 40; i++)
- {
- if (sWonderCardData->unk_0000.unk_122[i] != 0xF7)
- {
- sWonderCardData->unk_02DC[sWonderCardData->unk_0175].unk_01[r6] = sWonderCardData->unk_0000.unk_122[i];
- r6++;
- }
- else
- {
- u8 r3 = sWonderCardData->unk_0000.unk_122[i + 1];
- if (r3 > 2)
- {
- i += 2;
- }
- else
- {
- ConvertIntToDecimalStringN(sWonderCardData->unk_02DC[sWonderCardData->unk_0175].unk_42, sp0[r3], STR_CONV_MODE_LEADING_ZEROS, 3);
- sWonderCardData->unk_02DC[sWonderCardData->unk_0175].unk_00 = sWonderCardData->unk_0000.unk_122[i + 2];
- sWonderCardData->unk_0175++;
- if (sWonderCardData->unk_0175 > 7)
- break;
- r6 = 0;
- i += 2;
- }
- }
- }
- }
-}
-
-void sub_801C178(u8 whichWindow)
-{
- s8 sp0C = 0;
- s32 windowId = sWonderCardData->unk_0176[whichWindow];
- PutWindowTilemap(windowId);
- FillWindowPixelBuffer(windowId, 0);
- switch (whichWindow)
- {
- case 0:
- {
- s32 x;
- AddTextPrinterParameterized3(windowId, 3, 0, 1, sTextColorTable[sWonderCardData->unk_0170->textPal1], 0, sWonderCardData->unk_018B);
- x = 160 - GetStringWidth(3, sWonderCardData->unk_01B4, GetFontAttribute(3, 2));
- if (x < 0)
- x = 0;
- AddTextPrinterParameterized3(windowId, 3, x, 17, sTextColorTable[sWonderCardData->unk_0170->textPal1], 0, sWonderCardData->unk_01B4);
- if (sWonderCardData->unk_0000.unk_04 != 0)
- {
- AddTextPrinterParameterized3(windowId, 1, 166, 17, sTextColorTable[sWonderCardData->unk_0170->textPal1], 0, sWonderCardData->unk_01DD);
- }
- break;
- }
- case 1:
- for (; sp0C < 4; sp0C++)
- {
- AddTextPrinterParameterized3(windowId, 3, 0, 16 * sp0C + 2, sTextColorTable[sWonderCardData->unk_0170->textPal2], 0, sWonderCardData->unk_01E4[sp0C]);
- }
- break;
- case 2:
- AddTextPrinterParameterized3(windowId, 3, 0, gUnknown_082F0E18[sWonderCardData->unk_0000.unk_08_0], sTextColorTable[sWonderCardData->unk_0170->textPal3], 0, sWonderCardData->unk_0288);
- if (sWonderCardData->unk_0000.unk_08_0 != 2)
- {
- AddTextPrinterParameterized3(windowId, 3, 0, 16 + gUnknown_082F0E18[sWonderCardData->unk_0000.unk_08_0], sTextColorTable[sWonderCardData->unk_0170->textPal3], 0, sWonderCardData->unk_02B1);
- }
- else
- {
- s32 x = 0;
- s32 y = gUnknown_082F0E18[sWonderCardData->unk_0000.unk_08_0] + 16;
- s32 spacing = GetFontAttribute(3, 2);
- for (; sp0C < sWonderCardData->unk_0175; sp0C++)
- {
- AddTextPrinterParameterized3(windowId, 3, x, y, sTextColorTable[sWonderCardData->unk_0170->textPal3], 0, sWonderCardData->unk_02DC[sp0C].unk_01);
- if (sWonderCardData->unk_02DC[sp0C].unk_42[0] != EOS)
- {
- x += GetStringWidth(3, sWonderCardData->unk_02DC[sp0C].unk_01, spacing);
- AddTextPrinterParameterized3(windowId, 3, x, y, sTextColorTable[sWonderCardData->unk_0170->textPal3], 0, sWonderCardData->unk_02DC[sp0C].unk_42);
- x += GetStringWidth(3, sWonderCardData->unk_02DC[sp0C].unk_42, spacing) + sWonderCardData->unk_02DC[sp0C].unk_00;
- }
- }
- }
- break;
- }
- CopyWindowToVram(windowId, 3);
-}
-
-void sub_801C4C0(void)
-{
- u8 r7 = 0;
- sWonderCardData->unk_017C = 0xFF;
- if (sWonderCardData->unk_014C.unk_06 != SPECIES_NONE)
- {
- sWonderCardData->unk_017C = CreateMonIconNoPersonality(GetIconSpeciesNoPersonality(sWonderCardData->unk_014C.unk_06), SpriteCallbackDummy, 0xDC, 0x14, 0, FALSE);
- gSprites[sWonderCardData->unk_017C].oam.priority = 2;
- }
- if (sWonderCardData->unk_0000.unk_09 != 0 && sWonderCardData->unk_0000.unk_08_0 == 1)
- {
- LoadCompressedSpriteSheetUsingHeap(&gUnknown_082F1D00);
- LoadSpritePalette(&gUnknown_082F1D08[sWonderCardData->unk_0170->textPal4]);
- for (; r7 < sWonderCardData->unk_0000.unk_09; r7++)
- {
- sWonderCardData->unk_017D[r7][0] = 0xFF;
- sWonderCardData->unk_017D[r7][1] = 0xFF;
- sWonderCardData->unk_017D[r7][0] = CreateSprite(&gUnknown_082F1D48, 0xd8 - 32 * r7, 0x90, 8);
- if (sWonderCardData->unk_014C.unk_08[0][r7] != 0)
- {
- sWonderCardData->unk_017D[r7][1] = CreateMonIconNoPersonality(GetIconSpeciesNoPersonality(sWonderCardData->unk_014C.unk_08[0][r7]), SpriteCallbackDummy, 0xd8 - 32 * r7, 0x88, 0, 0);
- }
- }
- }
-}
-
-void sub_801C61C(void)
-{
- u8 r6 = 0;
- if (sWonderCardData->unk_017C != 0xFF)
- FreeAndDestroyMonIconSprite(&gSprites[sWonderCardData->unk_017C]);
- if (sWonderCardData->unk_0000.unk_09 != 0 && sWonderCardData->unk_0000.unk_08_0 == 1)
- {
- for (; r6 < sWonderCardData->unk_0000.unk_09; r6++)
- {
- if (sWonderCardData->unk_017D[r6][0] != 0xFF)
- {
- DestroySprite(&gSprites[sWonderCardData->unk_017D[r6][0]]);
- }
- if (sWonderCardData->unk_017D[r6][1] != 0xFF)
- {
- FreeAndDestroyMonIconSprite(&gSprites[sWonderCardData->unk_017D[r6][1]]);
- }
- }
- FreeSpriteTilesByTag(0x8000);
- FreeSpritePaletteByTag(0x8000);
- }
-}
-
-struct UnkStruct_203F3CC
-{
- /*0000*/ struct WonderNews unk_0000;
- /*01bc*/ const struct UnkStruct_8467FB8 * unk_01BC;
- /*01c0*/ u8 unk_01C0_0:1;
- u8 unk_01C0_1:7;
- /*01c1*/ u8 unk_01C1;
- /*01c2*/ u8 unk_01C2_0:1;
- u8 unk_01C2_1:7;
- /*01c3*/ u8 unk_01C3_0:1;
- u8 unk_01C3_1:7;
- /*01c4*/ u16 unk_01C4;
- /*01c6*/ u16 unk_01C6;
- /*01c8*/ u16 unk_01C8[2];
- /*01cc*/ u8 filler_01CC[2];
- /*01ce*/ u8 unk_01CE[41];
- /*01f7*/ u8 unk_01F7[10][41];
- /*0394*/ struct ScrollArrowsTemplate unk_0394;
- /*03a4*/ u8 buffer_03A4[0x1000];
-};
-
-EWRAM_DATA struct UnkStruct_203F3CC * sWonderNewsData = NULL;
-
-void sub_801CDCC(void);
-void sub_801CE7C(void);
-void sub_801CFA4(void);
-
-const u8 gUnknown_082F1DE0[][3] = {
- {0, 2, 3},
- {0, 1, 2}
-};
-const struct WindowTemplate gUnknown_082F1DE8[] = {
- {
- .bg = 0,
- .tilemapLeft = 1,
- .tilemapTop = 0,
- .width = 28,
- .height = 3,
- .paletteNum = 2,
- .baseBlock = 0x2AC
- }, {
- .bg = 2,
- .tilemapLeft = 1,
- .tilemapTop = 3,
- .width = 28,
- .height = 20,
- .paletteNum = 2,
- .baseBlock = 0x07C
- }
-};
-const struct ScrollArrowsTemplate gUnknown_082F1DF8 = {
- 0x02, 0xe8, 0x18, 0x03, 0xe8, 0x98,
- 0x0000, 0x0002, 0x1000, 0x1000, 0x0
-};
-const u16 gWonderNewsPal1[] = INCBIN_U16("graphics/wonder_transfers/wonder_news_1.gbapal");
-const u16 gWonderNewsPal7[] = INCBIN_U16("graphics/wonder_transfers/wonder_news_7.gbapal");
-const u16 gWonderNewsPal8[] = INCBIN_U16("graphics/wonder_transfers/wonder_news_8.gbapal");
-const u32 gWonderNewsGfx1[] = INCBIN_U32("graphics/wonder_transfers/wonder_news_1.4bpp.lz");
-const u32 gWonderNewsTilemap1[] = INCBIN_U32("graphics/wonder_transfers/wonder_news_1.bin.lz");
-const u32 gWonderNewsGfx2[] = INCBIN_U32("graphics/wonder_transfers/wonder_news_2.4bpp.lz");
-const u32 gWonderNewsTilemap2[] = INCBIN_U32("graphics/wonder_transfers/wonder_news_2.bin.lz");
-const u32 gWonderNewsGfx3[] = INCBIN_U32("graphics/wonder_transfers/wonder_news_3.4bpp.lz");
-const u32 gWonderNewsTilemap3[] = INCBIN_U32("graphics/wonder_transfers/wonder_news_3.bin.lz");
-const u32 gWonderNewsGfx7[] = INCBIN_U32("graphics/wonder_transfers/wonder_news_7.4bpp.lz");
-const u32 gWonderNewsTilemap7[] = INCBIN_U32("graphics/wonder_transfers/wonder_news_7.bin.lz");
-const u32 gWonderNewsGfx8[] = INCBIN_U32("graphics/wonder_transfers/wonder_news_8.4bpp.lz");
-const u32 gWonderNewsTilemap8[] = INCBIN_U32("graphics/wonder_transfers/wonder_news_8.bin.lz");
-
-const struct UnkStruct_8467FB8 gUnknown_082F24C8[] = {
- {1, 0, 0, 0, gWonderNewsGfx1, gWonderNewsTilemap1, gWonderNewsPal1},
- {1, 0, 0, 0, gWonderNewsGfx2, gWonderNewsTilemap2, gWonderCardBgPal2},
- {1, 0, 0, 0, gWonderNewsGfx3, gWonderNewsTilemap3, gWonderCardBgPal3},
- {1, 0, 0, 0, gWonderNewsGfx3, gWonderNewsTilemap3, gWonderCardBgPal4},
- {1, 0, 0, 0, gWonderNewsGfx3, gWonderNewsTilemap3, gWonderCardBgPal5},
- {1, 0, 0, 0, gWonderNewsGfx3, gWonderNewsTilemap3, gWonderCardBgPal6},
- {1, 0, 0, 0, gWonderNewsGfx7, gWonderNewsTilemap7, gWonderNewsPal7},
- {1, 0, 0, 0, gWonderNewsGfx8, gWonderNewsTilemap8, gWonderNewsPal8}
-};
-
-bool32 InitWonderNewsResources(const struct WonderNews * a0)
-{
- if (a0 == NULL)
- return FALSE;
- sWonderNewsData = AllocZeroed(sizeof(struct UnkStruct_203F3CC));
- if (sWonderNewsData == NULL)
- return FALSE;
- sWonderNewsData->unk_0000 = *a0;
- if (sWonderNewsData->unk_0000.unk_03 >= ARRAY_COUNT(gUnknown_082F24C8))
- sWonderNewsData->unk_0000.unk_03 = 0;
- sWonderNewsData->unk_01BC = &gUnknown_082F24C8[sWonderNewsData->unk_0000.unk_03];
- sWonderNewsData->unk_01C1 = 0xFF;
- return TRUE;
-}
-
-void DestroyWonderNewsResources(void)
-{
- if (sWonderNewsData != NULL)
- {
- *sWonderNewsData = (struct UnkStruct_203F3CC){};
- Free(sWonderNewsData);
- sWonderNewsData = NULL;
- }
-}
-
-s32 FadeToWonderNewsMenu(void)
-{
- if (sWonderNewsData == NULL)
- return -1;
-
- switch (sWonderNewsData->unk_01C0_1)
- {
- case 0:
- BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK);
- break;
- case 1:
- if (UpdatePaletteFade())
- return 0;
- ChangeBgY(0, 0, 0);
- ChangeBgY(1, 0, 0);
- ChangeBgY(2, 0, 0);
- ChangeBgY(3, 0, 0);
- SetGpuReg(REG_OFFSET_WIN0H, WIN_RANGE(0, DISPLAY_WIDTH));
- SetGpuReg(REG_OFFSET_WIN0V, WIN_RANGE(26, 152));
- SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ);
- SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG0 | WINOUT_WIN01_BG1 | WINOUT_WIN01_BG3 | WINOUT_WIN01_OBJ);
- SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON);
- break;
- case 2:
- FillBgTilemapBufferRect_Palette0(0, 0x000, 0, 0, 30, 20);
- FillBgTilemapBufferRect_Palette0(1, 0x000, 0, 0, 30, 20);
- FillBgTilemapBufferRect_Palette0(2, 0x000, 0, 0, 30, 20);
- FillBgTilemapBufferRect_Palette0(3, 0x000, 0, 0, 30, 20);
- CopyBgTilemapBufferToVram(0);
- CopyBgTilemapBufferToVram(1);
- CopyBgTilemapBufferToVram(2);
- CopyBgTilemapBufferToVram(3);
- DecompressAndCopyTileDataToVram(3, sWonderNewsData->unk_01BC->tiles, 0, 8, 0);
- sWonderNewsData->unk_01C8[0] = AddWindow(&gUnknown_082F1DE8[0]);
- sWonderNewsData->unk_01C8[1] = AddWindow(&gUnknown_082F1DE8[1]);
- break;
- case 3:
- if (FreeTempTileDataBuffersIfPossible())
- return 0;
- LoadPalette(GetTextWindowPalette(1), 0x20, 0x20);
- gPaletteFade.bufferTransferDisabled = TRUE;
- LoadPalette(sWonderNewsData->unk_01BC->pal, 0x10, 0x20);
- LZ77UnCompWram(sWonderNewsData->unk_01BC->map, sWonderNewsData->buffer_03A4);
- CopyRectToBgTilemapBufferRect(1, sWonderNewsData->buffer_03A4, 0, 0, 30, 3, 0, 0, 30, 3, 1, 8, 0);
- CopyRectToBgTilemapBufferRect(3, sWonderNewsData->buffer_03A4, 0, 3, 30, 23, 0, 3, 30, 23, 1, 8, 0);
- CopyBgTilemapBufferToVram(1);
- CopyBgTilemapBufferToVram(3);
- break;
- case 4:
- sub_801CDCC();
- break;
- case 5:
- sub_801CE7C();
- CopyBgTilemapBufferToVram(0);
- CopyBgTilemapBufferToVram(2);
- break;
- case 6:
- ShowBg(1);
- ShowBg(2);
- ShowBg(3);
- gPaletteFade.bufferTransferDisabled = FALSE;
- sWonderNewsData->unk_01C1 = AddScrollIndicatorArrowPair(&sWonderNewsData->unk_0394, &sWonderNewsData->unk_01C6);
- BeginNormalPaletteFade(PALETTES_ALL, 0, 16, 0, RGB_BLACK);
- UpdatePaletteFade();
- break;
- default:
- if (UpdatePaletteFade())
- return 0;
- sWonderNewsData->unk_01C0_1 = 0;
- return 1;
- }
-
- ++sWonderNewsData->unk_01C0_1;
- return 0;
-}
-
-s32 FadeOutFromWonderNews(bool32 flag)
-{
- if (sWonderNewsData == NULL)
- return -1;
- switch (sWonderNewsData->unk_01C0_1)
- {
- case 0:
- BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK);
- break;
- case 1:
- if (UpdatePaletteFade())
- return 0;
- ChangeBgY(2, 0, 0);
- SetGpuReg(REG_OFFSET_WIN0H, 0);
- SetGpuReg(REG_OFFSET_WIN0V, 0);
- SetGpuReg(REG_OFFSET_WININ, 0);
- SetGpuReg(REG_OFFSET_WINOUT, 0);
- ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON);
- break;
- case 2:
- FillBgTilemapBufferRect_Palette0(0, 0x000, 0, 0, 30, 20);
- FillBgTilemapBufferRect_Palette0(1, 0x000, 0, 0, 30, 20);
- FillBgTilemapBufferRect_Palette0(2, 0x000, 0, 0, 30, 24);
- FillBgTilemapBufferRect_Palette0(3, 0x000, 0, 0, 30, 24);
- CopyBgTilemapBufferToVram(0);
- CopyBgTilemapBufferToVram(1);
- CopyBgTilemapBufferToVram(2);
- CopyBgTilemapBufferToVram(3);
- break;
- case 3:
- HideBg(1);
- HideBg(2);
- RemoveWindow(sWonderNewsData->unk_01C8[1]);
- RemoveWindow(sWonderNewsData->unk_01C8[0]);
- break;
- case 4:
- ChangeBgY(2, 0, 0);
- ChangeBgY(3, 0, 0);
- if (sWonderNewsData->unk_01C1 != 0xFF)
- {
- RemoveScrollIndicatorArrowPair(sWonderNewsData->unk_01C1);
- sWonderNewsData->unk_01C1 = 0xFF;
- }
- break;
- case 5:
- PrintMysteryGiftOrEReaderTopMenu(gGiftIsFromEReader, flag);
- MG_DrawCheckerboardPattern(3);
- CopyBgTilemapBufferToVram(0);
- CopyBgTilemapBufferToVram(3);
- BeginNormalPaletteFade(PALETTES_ALL, 0, 16, 0, RGB_BLACK);
- break;
- default:
- if (UpdatePaletteFade())
- return 0;
- sWonderNewsData->unk_01C0_1 = 0;
- return 1;
- }
- ++sWonderNewsData->unk_01C0_1;
- return 0;
-}
-
-void MENews_RemoveScrollIndicatorArrowPair(void)
-{
- if (!sWonderNewsData->unk_01C0_0 && sWonderNewsData->unk_01C1 != 0xFF)
- {
- RemoveScrollIndicatorArrowPair(sWonderNewsData->unk_01C1);
- sWonderNewsData->unk_01C1 = 0xFF;
- sWonderNewsData->unk_01C0_0 = TRUE;
- }
-}
-
-
-void MENews_AddScrollIndicatorArrowPair(void)
-{
- if (sWonderNewsData->unk_01C0_0)
- {
- sWonderNewsData->unk_01C1 = AddScrollIndicatorArrowPair(&sWonderNewsData->unk_0394, &sWonderNewsData->unk_01C6);
- sWonderNewsData->unk_01C0_0 = FALSE;
- }
-}
-
-u32 MENews_GetInput(u16 input)
-{
- if (sWonderNewsData->unk_01C2_0)
- {
- sub_801CFA4();
- return 0xFF;
- }
- switch (input)
- {
- case A_BUTTON:
- return 0;
- case B_BUTTON:
- return 1;
- case DPAD_UP:
- if (sWonderNewsData->unk_01C6 == 0)
- return 0xFF;
- if (sWonderNewsData->unk_01C0_0)
- return 0xFF;
- sWonderNewsData->unk_01C3_0 = FALSE;
- break;
- case DPAD_DOWN:
- if (sWonderNewsData->unk_01C6 == sWonderNewsData->unk_01C4)
- return 0xFF;
- if (sWonderNewsData->unk_01C0_0)
- return 0xFF;
- sWonderNewsData->unk_01C3_0 = TRUE;
- break;
- default:
- return 0xFF;
- }
- sWonderNewsData->unk_01C2_0 = TRUE;
- sWonderNewsData->unk_01C2_1 = 2;
- sWonderNewsData->unk_01C3_1 = 0;
- if (sWonderNewsData->unk_01C3_0 == FALSE)
- return 2;
- else
- return 3;
-}
-
-void sub_801CDCC(void)
-{
- u8 i = 0;
- memcpy(sWonderNewsData->unk_01CE, sWonderNewsData->unk_0000.unk_04, 40);
- sWonderNewsData->unk_01CE[40] = EOS;
- for (; i < 10; ++i)
- {
- memcpy(sWonderNewsData->unk_01F7[i], sWonderNewsData->unk_0000.unk_2C[i], 40);
- sWonderNewsData->unk_01F7[i][40] = EOS;
- if (i > 7 && sWonderNewsData->unk_01F7[i][0] != EOS)
- ++sWonderNewsData->unk_01C4;
- }
- sWonderNewsData->unk_0394 = gUnknown_082F1DF8;
- sWonderNewsData->unk_0394.fullyDownThreshold = sWonderNewsData->unk_01C4;
-}
-
-void sub_801CE7C(void)
-{
- u8 i = 0;
- s32 x;
- PutWindowTilemap(sWonderNewsData->unk_01C8[0]);
- PutWindowTilemap(sWonderNewsData->unk_01C8[1]);
- FillWindowPixelBuffer(sWonderNewsData->unk_01C8[0], 0);
- FillWindowPixelBuffer(sWonderNewsData->unk_01C8[1], 0);
- x = (0xe0 - GetStringWidth(3, sWonderNewsData->unk_01CE, GetFontAttribute(3, 2))) / 2;
- if (x < 0)
- x = 0;
- AddTextPrinterParameterized3(sWonderNewsData->unk_01C8[0], 3, x, 6, gUnknown_082F1DE0[sWonderNewsData->unk_01BC->textPal1], 0, sWonderNewsData->unk_01CE);
- for (; i < 10; ++i)
- {
- AddTextPrinterParameterized3(sWonderNewsData->unk_01C8[1], 3, 0, 16 * i + 2, gUnknown_082F1DE0[sWonderNewsData->unk_01BC->textPal2], 0, sWonderNewsData->unk_01F7[i]);
- }
- CopyWindowToVram(sWonderNewsData->unk_01C8[0], 3);
- CopyWindowToVram(sWonderNewsData->unk_01C8[1], 3);
-}
-
-void sub_801CFA4(void)
-{
- u16 r4 = sWonderNewsData->unk_01C2_1;
- r4 <<= 8;
- if (sWonderNewsData->unk_01C3_0)
- {
- ChangeBgY(2, r4, 1);
- ChangeBgY(3, r4, 1);
- }
- else
- {
- ChangeBgY(2, r4, 2);
- ChangeBgY(3, r4, 2);
- }
- sWonderNewsData->unk_01C3_1 += sWonderNewsData->unk_01C2_1;
- if (sWonderNewsData->unk_01C3_1 > 15)
- {
- if (sWonderNewsData->unk_01C3_0)
- ++sWonderNewsData->unk_01C6;
- else
- --sWonderNewsData->unk_01C6;
- sWonderNewsData->unk_01C2_0 = FALSE;
- sWonderNewsData->unk_01C3_1 = 0;
- }
-}
diff --git a/src/mevent_client.c b/src/mevent_client.c
deleted file mode 100644
index 9a62bf18e..000000000
--- a/src/mevent_client.c
+++ /dev/null
@@ -1,291 +0,0 @@
-#include "global.h"
-#include "malloc.h"
-#include "decompress.h"
-#include "overworld.h"
-#include "script.h"
-#include "battle_tower.h"
-#include "mevent.h"
-#include "mystery_event_script.h"
-#include "mevent_client.h"
-
-EWRAM_DATA struct mevent_client * s_mevent_client_ptr = NULL;
-
-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 *);
-
-extern const struct mevent_client_cmd gUnknown_082F2598[];
-
-void mevent_client_do_init(u32 arg)
-{
- s_mevent_client_ptr = AllocZeroed(sizeof(struct mevent_client));
- mevent_client_init(s_mevent_client_ptr, 1, 0);
- s_mevent_client_ptr->unk_4C = arg;
-}
-
-u32 mevent_client_do_exec(u16 * a0)
-{
- u32 result;
- if (s_mevent_client_ptr == NULL)
- return 6;
- result = mevent_client_exec(s_mevent_client_ptr);
- if (result == 6)
- {
- *a0 = s_mevent_client_ptr->param;
- mevent_client_free_resources(s_mevent_client_ptr);
- Free(s_mevent_client_ptr);
- s_mevent_client_ptr = NULL;
- }
- return result;
-}
-
-void mevent_client_inc_flag(void)
-{
- s_mevent_client_ptr->flag++;
-}
-
-void * mevent_client_get_buffer(void)
-{
- return s_mevent_client_ptr->buffer;
-}
-
-void mevent_client_set_param(u32 a0)
-{
- s_mevent_client_ptr->param = a0;
-}
-
-static void mevent_client_init(struct mevent_client * svr, u32 sendPlayerNo, u32 recvPlayerNo)
-{
- 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);
- mevent_srv_sub_init(&svr->manager, sendPlayerNo, recvPlayerNo);
-}
-
-static void mevent_client_free_resources(struct mevent_client * svr)
-{
- Free(svr->sendBuffer);
- Free(svr->recvBuffer);
- Free(svr->cmdBuffer);
- Free(svr->buffer);
-}
-
-static void mevent_client_jmp_buffer(struct mevent_client * svr)
-{
- memcpy(svr->cmdBuffer, svr->recvBuffer, ME_SEND_BUF_SIZE);
- svr->cmdidx = 0;
-}
-
-static void mevent_client_send_word(struct mevent_client * svr, u32 ident, u32 word)
-{
- CpuFill32(0, svr->sendBuffer, ME_SEND_BUF_SIZE);
- *(u32 *)svr->sendBuffer = word;
- mevent_srv_sub_init_send(&svr->manager, ident, svr->sendBuffer, sizeof(u32));
-}
-
-static u32 mainseq_0(struct mevent_client * svr)
-{
- // init
- memcpy(svr->cmdBuffer, gUnknown_082F2598, ME_SEND_BUF_SIZE);
- svr->cmdidx = 0;
- svr->mainseqno = 4;
- svr->flag = 0;
- return 0;
-}
-
-static u32 mainseq_1(struct mevent_client * svr)
-{
- // done
- return 6;
-}
-
-
-static u32 mainseq_2(struct mevent_client * svr)
-{
- // do recv
- if (mevent_srv_sub_recv(&svr->manager))
- {
- svr->mainseqno = 4;
- svr->flag = 0;
- }
- return 1;
-}
-
-static u32 mainseq_3(struct mevent_client * svr)
-{
- // do send
- if (mevent_srv_sub_send(&svr->manager))
- {
- svr->mainseqno = 4;
- svr->flag = 0;
- }
- return 1;
-}
-
-static u32 mainseq_4(struct mevent_client * svr)
-{
- // process command
- struct mevent_client_cmd * cmd = &svr->cmdBuffer[svr->cmdidx];
- ++svr->cmdidx;
- switch (cmd->instr)
- {
- case 0:
- break;
- case 1:
- svr->param = cmd->parameter;
- svr->mainseqno = 1;
- svr->flag = 0;
- break;
- case 2:
- mevent_srv_sub_init_recv(&svr->manager, cmd->parameter, svr->recvBuffer);
- svr->mainseqno = 2;
- svr->flag = 0;
- break;
- case 3:
- svr->mainseqno = 3;
- svr->flag = 0;
- break;
- case 20:
- mevent_srv_sub_init_send(&svr->manager, 0x14, svr->sendBuffer, 0);
- svr->mainseqno = 3;
- svr->flag = 0;
- break;
- case 19:
- mevent_client_send_word(svr, 0x12, GetGameStat(cmd->parameter));
- svr->mainseqno = 3;
- svr->flag = 0;
- break;
- case 6:
- if (svr->param == 0)
- mevent_client_jmp_buffer(svr);
- break;
- case 7:
- if (svr->param == 1)
- mevent_client_jmp_buffer(svr);
- break;
- case 4:
- mevent_client_jmp_buffer(svr);
- 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:
- sub_801B580(svr->sendBuffer, svr->unk_4C);
- mevent_srv_sub_init_send(&svr->manager, 0x11, svr->sendBuffer, sizeof(struct MEventStruct_Unk1442CC));
- break;
- case 14:
- mevent_client_send_word(svr, 0x13, svr->param);
- break;
- case 10:
- sub_801B21C(svr->recvBuffer);
- break;
- case 9:
- if (!sub_801B1A4(svr->recvBuffer))
- {
- sub_801B078(svr->recvBuffer);
- mevent_client_send_word(svr, 0x13, 0);
- }
- else
- mevent_client_send_word(svr, 0x13, 1);
- break;
- case 15:
- svr->mainseqno = 6;
- svr->flag = 0;
- break;
- case 16:
- sub_801B508(svr->recvBuffer);
- break;
- case 17:
- InitRamScript_NoObjectEvent(svr->recvBuffer, 1000);
- break;
- case 18:
- memcpy(&gSaveBlock2Ptr->frontier.ereaderTrainer, svr->recvBuffer, 0xbc);
- ValidateEReaderTrainer();
- break;
- case 21:
- memcpy(gDecompressionBuffer, svr->recvBuffer, ME_SEND_BUF_SIZE);
- svr->mainseqno = 7;
- svr->flag = 0;
- break;
- }
-
- return 1;
-}
-
-static u32 mainseq_5(struct mevent_client * svr)
-{
- // wait flag
- if (svr->flag)
- {
- svr->mainseqno = 4;
- svr->flag = 0;
- }
- return 1;
-}
-
-static u32 mainseq_6(struct mevent_client * svr)
-{
- // ???
- switch (svr->flag)
- {
- case 0:
- sub_8153870(svr->recvBuffer);
- ++svr->flag;
- break;
- case 1:
- if (!sub_8153884(&svr->param))
- {
- svr->mainseqno = 4;
- svr->flag = 0;
- }
- break;
- }
- return 1;
-}
-
-static u32 mainseq_7(struct mevent_client * svr)
-{
- // exec arbitrary code
- u32 (*func)(u32 *, struct SaveBlock2 *, struct SaveBlock1 *) = (void *)gDecompressionBuffer;
- if (func(&svr->param, gSaveBlock2Ptr, gSaveBlock1Ptr) == 1)
- {
- svr->mainseqno = 4;
- svr->flag = 0;
- }
- return 1;
-}
-
-static u32 mevent_client_exec(struct mevent_client * svr)
-{
- u32 (*funcs[])(struct mevent_client *) = {
- mainseq_0,
- mainseq_1,
- mainseq_2,
- mainseq_3,
- mainseq_4,
- mainseq_5,
- mainseq_6,
- mainseq_7
- };
- return funcs[svr->mainseqno](svr);
-}
diff --git a/src/mevent_news.c b/src/mevent_news.c
deleted file mode 100644
index 9e78cf406..000000000
--- a/src/mevent_news.c
+++ /dev/null
@@ -1,148 +0,0 @@
-#include "global.h"
-#include "mevent.h"
-#include "random.h"
-#include "event_data.h"
-#include "mevent_news.h"
-
-static u32 sub_801DCAC(struct MysteryEventStruct *);
-static void sub_801DD10(struct MysteryEventStruct *);
-static u32 sub_801DD44(struct MysteryEventStruct *);
-static void sub_801DCD8(struct MysteryEventStruct *);
-static void sub_801DCCC(struct MysteryEventStruct *);
-
-void GenerateRandomNews(u32 a0)
-{
- struct MysteryEventStruct *r5 = sub_801B044();
-
- r5->unk_0_0 = a0;
- switch (a0)
- {
- case 0:
- break;
- case 1:
- case 2:
- r5->unk_1 = (Random() % 15) + 16;
- break;
- case 3:
- r5->unk_1 = (Random() % 15) + 1;
- break;
- }
-}
-
-void sub_801DBC0(void)
-{
- struct MysteryEventStruct *r5 = sub_801B044();
-
- r5->unk_0_0 = 0;
- r5->unk_0_2 = 0;
- r5->unk_0_5 = 0;
- r5->unk_1 = 0;
- VarSet(VAR_0x402E, 0);
-}
-
-void sub_801DBDC(void)
-{
- u16 *r4 = GetVarPointer(VAR_0x402E);
- struct MysteryEventStruct *r2 = sub_801B044();
- struct MysteryEventStruct r0 = *r2;
-
- if ((u8)r0.unk_0_5 > 4 && ++(*r4) > 0x1f3)
- {
- r2->unk_0_5 = 0;
- *r4 = 0;
- }
-}
-
-// Unused
-u16 sub_801DC20(void)
-{
- u16 *r6 = &gSpecialVar_Result;
- struct MysteryEventStruct *r4 = sub_801B044();
- u16 r5;
-
- if (!IsMysteryEventEnabled() || !ValidateReceivedWonderNews())
- return 0;
-
- r5 = sub_801DD44(r4);
-
- switch (r5)
- {
- case 0:
- break;
- case 1:
- *r6 = sub_801DCAC(r4);
- break;
- case 2:
- *r6 = sub_801DCAC(r4);
- break;
- case 3:
- break;
- case 4:
- *r6 = sub_801DCAC(r4);
- sub_801DCD8(r4);
- break;
- case 5:
- *r6 = sub_801DCAC(r4);
- sub_801DCCC(r4);
- break;
- case 6:
- break;
- }
-
- return r5;
-}
-
-static u32 sub_801DCAC(struct MysteryEventStruct *a0)
-{
- u32 r4;
-
- a0->unk_0_0 = 0;
- r4 = a0->unk_1 + 0x84;
- a0->unk_1 = 0;
- sub_801DD10(a0);
- return r4;
-}
-
-static void sub_801DCCC(struct MysteryEventStruct *a0)
-{
- a0->unk_0_2 = 0;
-}
-
-static void sub_801DCD8(struct MysteryEventStruct *a0)
-{
- a0->unk_0_2++;
- if ((u8)a0->unk_0_2 > 4)
- a0->unk_0_2 = 4;
-}
-
-static void sub_801DD10(struct MysteryEventStruct *a0)
-{
- a0->unk_0_5++;
- if ((u8)a0->unk_0_5 > 5)
- a0->unk_0_5 = 5;
-}
-
-static u32 sub_801DD44(struct MysteryEventStruct *a0)
-{
- struct MysteryEventStruct r0;
- if ((u8)a0->unk_0_5 == 5)
- return 6;
-
- r0 = *a0;
- switch (r0.unk_0_0)
- {
- case 0:
- return 3;
- case 1:
- return 1;
- case 2:
- return 2;
- case 3:
- if ((u8)r0.unk_0_2 < 3)
- return 4;
- return 5;
- default:
- AGB_ASSERT(0);
- return 0;
- }
-}
diff --git a/src/mevent_scripts.c b/src/mevent_scripts.c
deleted file mode 100644
index 41a5ddd51..000000000
--- a/src/mevent_scripts.c
+++ /dev/null
@@ -1,191 +0,0 @@
-#include "global.h"
-#include "mevent_client.h"
-#include "mevent_server.h"
-
-const u8 gText_CanceledReadingCard[] = _("Canceled reading\nthe Card.");
-
-
-const struct mevent_client_cmd gUnknown_082F2598[] = {
- {.instr = 2, .parameter = 16},
- {.instr = 4, .parameter = 0}
-};
-
-const struct mevent_client_cmd gUnknown_082F25A8[] = {
- {.instr = 8, .parameter = 0},
- {.instr = 3, .parameter = 0},
- {.instr = 2, .parameter = 16},
- {.instr = 4, .parameter = 0}
-};
-
-const struct mevent_client_cmd gUnknown_082F25C8[] = {
- {.instr = 20, .parameter = 0},
- {.instr = 1, .parameter = 10}
-};
-
-const struct mevent_client_cmd gUnknown_082F25D8[] = {
- {.instr = 20, .parameter = 0},
- {.instr = 1, .parameter = 11}
-};
-
-const struct mevent_client_cmd gUnknown_082F25E8[] = {
- {.instr = 20, .parameter = 0},
- {.instr = 1, .parameter = 0}
-};
-
-const struct mevent_client_cmd gUnknown_082F25F8[] = {
- {.instr = 2, .parameter = 22},
- {.instr = 10, .parameter = 0},
- {.instr = 2, .parameter = 25},
- {.instr = 17, .parameter = 0},
- {.instr = 20, .parameter = 0},
- {.instr = 1, .parameter = 2}
-};
-
-const struct mevent_client_cmd gUnknown_082F2628[] = {
- {.instr = 2, .parameter = 23},
- {.instr = 9, .parameter = 0},
- {.instr = 3, .parameter = 0},
- {.instr = 2, .parameter = 16},
- {.instr = 4, .parameter = 0}
-};
-
-const struct mevent_client_cmd gUnknown_082F2650[] = {
- {.instr = 20, .parameter = 0},
- {.instr = 1, .parameter = 7}
-};
-
-const struct mevent_client_cmd gUnknown_082F2660[] = {
- {.instr = 20, .parameter = 0},
- {.instr = 1, .parameter = 3}
-};
-
-const struct mevent_client_cmd gUnknown_082F2670[] = {
- {.instr = 13, .parameter = 0},
- {.instr = 14, .parameter = 0},
- {.instr = 3, .parameter = 0},
- {.instr = 2, .parameter = 16},
- {.instr = 4, .parameter = 0}
-};
-
-const struct mevent_client_cmd gUnknown_082F2698[] = {
- {.instr = 20, .parameter = 0},
- {.instr = 1, .parameter = 9}
-};
-
-const struct mevent_client_cmd gUnknown_082F26A8[] = {
- {.instr = 20, .parameter = 0},
- {.instr = 1, .parameter = 5}
-};
-
-const struct mevent_client_cmd gUnknown_082F26B8[] = {
- {.instr = 2, .parameter = 21},
- {.instr = 12, .parameter = 0},
- {.instr = 20, .parameter = 0},
- {.instr = 1, .parameter = 14},
- {.instr = 2, .parameter = 21},
- {.instr = 12, .parameter = 0},
- {.instr = 20, .parameter = 0},
- {.instr = 1, .parameter = 13}
-};
-
-const struct mevent_cmd gUnknown_082F26F8[] = {
- {.instr = 18, .flag = 0x10, .parameter = gUnknown_082F25C8},
- {.instr = 1, .flag = 0x00, .parameter = NULL},
- {.instr = 2, .flag = 0x14, .parameter = NULL},
- {.instr = 0, .flag = 0x0a, .parameter = NULL},
- {.instr = 18, .flag = 0x10, .parameter = gUnknown_082F25D8},
- {.instr = 1, .flag = 0x00, .parameter = NULL},
- {.instr = 2, .flag = 0x14, .parameter = NULL},
- {.instr = 0, .flag = 0x0b, .parameter = NULL},
- {.instr = 18, .flag = 0x10, .parameter = gUnknown_082F2698},
- {.instr = 1, .flag = 0x00, .parameter = NULL},
- {.instr = 2, .flag = 0x14, .parameter = NULL},
- {.instr = 0, .flag = 0x09, .parameter = NULL}
-};
-
-const struct mevent_cmd gUnknown_082F2788[] = {
- {.instr = 18, .flag = 0x20, .parameter = gUnknown_082F26B8},
- {.instr = 1, .flag = 0x00, .parameter = NULL},
- {.instr = 20, .flag = 0x1b, .parameter = gText_CanceledReadingCard},
- {.instr = 1, .flag = 0x00, .parameter = NULL},
- {.instr = 2, .flag = 0x14, .parameter = NULL},
- {.instr = 0, .flag = 0x09, .parameter = NULL}
-};
-
-const struct mevent_cmd gUnknown_082F27D0[] = {
- {.instr = 18, .flag = 0x10, .parameter = gUnknown_082F2650},
- {.instr = 1, .flag = 0x00, .parameter = NULL},
- {.instr = 2, .flag = 0x14, .parameter = NULL},
- {.instr = 0, .flag = 0x07, .parameter = NULL}
-};
-
-const struct mevent_cmd gUnknown_082F2800[] = {
- {.instr = 18, .flag = 0x28, .parameter = gUnknown_082F2628},
- {.instr = 1, .flag = 0x00, .parameter = NULL},
- {.instr = 14, .flag = 0x00, .parameter = NULL},
- {.instr = 1, .flag = 0x00, .parameter = NULL},
- {.instr = 2, .flag = 0x13, .parameter = NULL},
- {.instr = 8, .flag = 0x00, .parameter = NULL},
- {.instr = 4, .flag = 0x01, .parameter = gUnknown_082F27D0},
- {.instr = 18, .flag = 0x10, .parameter = gUnknown_082F2660},
- {.instr = 1, .flag = 0x00, .parameter = NULL},
- {.instr = 2, .flag = 0x14, .parameter = NULL},
- {.instr = 0, .flag = 0x03, .parameter = NULL}
-};
-
-const struct mevent_cmd gUnknown_082F2884[] = {
- {.instr = 18, .flag = 0x30, .parameter = gUnknown_082F25F8},
- {.instr = 1, .flag = 0x00, .parameter = NULL},
- {.instr = 13, .flag = 0x00, .parameter = NULL},
- {.instr = 1, .flag = 0x00, .parameter = NULL},
- {.instr = 15, .flag = 0x00, .parameter = NULL},
- {.instr = 1, .flag = 0x00, .parameter = NULL},
- {.instr = 2, .flag = 0x14, .parameter = NULL},
- {.instr = 0, .flag = 0x02, .parameter = NULL}
-};
-
-const struct mevent_cmd gUnknown_082F28E4[] = {
- {.instr = 18, .flag = 0x28, .parameter = gUnknown_082F2670},
- {.instr = 1, .flag = 0x00, .parameter = NULL},
- {.instr = 2, .flag = 0x13, .parameter = NULL},
- {.instr = 8, .flag = 0x00, .parameter = NULL},
- {.instr = 4, .flag = 0x00, .parameter = gUnknown_082F2884},
- {.instr = 3, .flag = 0x00, .parameter = gUnknown_082F2788}
-};
-
-const struct mevent_cmd gUnknown_082F292C[] = {
- {.instr = 18, .flag = 0x10, .parameter = gUnknown_082F26A8},
- {.instr = 1, .flag = 0x00, .parameter = NULL},
- {.instr = 2, .flag = 0x14, .parameter = NULL},
- {.instr = 0, .flag = 0x05, .parameter = NULL},
- {.instr = 18, .flag = 0x10, .parameter = gUnknown_082F25E8},
- {.instr = 1, .flag = 0x00, .parameter = NULL},
- {.instr = 2, .flag = 0x14, .parameter = NULL},
- {.instr = 0, .flag = 0x00, .parameter = NULL}
-};
-
-const struct mevent_cmd s_mevent_wonder_news[] = {
- {.instr = 27, .flag = 0x00, .parameter = NULL},
- {.instr = 18, .flag = 0x20, .parameter = gUnknown_082F25A8},
- {.instr = 1, .flag = 0x00, .parameter = NULL},
- {.instr = 2, .flag = 0x11, .parameter = NULL},
- {.instr = 5, .flag = 0x00, .parameter = NULL},
- {.instr = 30, .flag = 0x00, .parameter = NULL},
- {.instr = 4, .flag = 0x00, .parameter = gUnknown_082F26F8},
- {.instr = 3, .flag = 0x00, .parameter = gUnknown_082F2800}
-};
-
-const struct mevent_cmd s_mevent_wonder_card[] = {
- {.instr = 26, .flag = 0x00, .parameter = NULL},
- {.instr = 28, .flag = 0x00, .parameter = NULL},
- {.instr = 18, .flag = 0x20, .parameter = gUnknown_082F25A8},
- {.instr = 1, .flag = 0x00, .parameter = NULL},
- {.instr = 2, .flag = 0x11, .parameter = NULL},
- {.instr = 5, .flag = 0x00, .parameter = NULL},
- {.instr = 6, .flag = 0x00, .parameter = NULL},
- {.instr = 4, .flag = 0x00, .parameter = gUnknown_082F26F8},
- {.instr = 7, .flag = 0x00, .parameter = NULL},
- {.instr = 4, .flag = 0x02, .parameter = gUnknown_082F28E4},
- {.instr = 4, .flag = 0x00, .parameter = gUnknown_082F2884},
- {.instr = 3, .flag = 0x00, .parameter = gUnknown_082F292C}
-};
diff --git a/src/mevent_server.c b/src/mevent_server.c
deleted file mode 100644
index 2e7b3d89a..000000000
--- a/src/mevent_server.c
+++ /dev/null
@@ -1,295 +0,0 @@
-#include "global.h"
-#include "malloc.h"
-#include "script.h"
-#include "mevent.h"
-#include "mevent_server.h"
-#include "mevent_server_helpers.h"
-
-EWRAM_DATA struct mevent_srv_common * s_mevent_srv_common_ptr = NULL;
-
-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 *);
-
-extern const struct mevent_cmd s_mevent_wonder_news[];
-extern const struct mevent_cmd s_mevent_wonder_card[];
-
-void mevent_srv_init_wnews(void)
-{
- s_mevent_srv_common_ptr = AllocZeroed(sizeof(struct mevent_srv_common));
- mevent_srv_init_common(s_mevent_srv_common_ptr, s_mevent_wonder_news, 0, 1);
-}
-
-void mevent_srv_new_wcard(void)
-{
- s_mevent_srv_common_ptr = AllocZeroed(sizeof(struct mevent_srv_common));
- mevent_srv_init_common(s_mevent_srv_common_ptr, s_mevent_wonder_card, 0, 1);
-}
-
-u32 mevent_srv_common_do_exec(u16 * a0)
-{
- u32 result;
- if (s_mevent_srv_common_ptr == NULL)
- return 3;
- result = mevent_srv_exec_common(s_mevent_srv_common_ptr);
- if (result == 3)
- {
- *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;
- }
- return result;
-}
-
-static void mevent_srv_init_common(struct mevent_srv_common * svr, const void * cmdBuffer, u32 sendPlayerNo, u32 recvPlayerNo)
-{
- svr->unk_00 = 0;
- svr->mainseqno = 0;
- svr->wonder_card = AllocZeroed(sizeof(struct WonderCard));
- svr->wonder_news = AllocZeroed(sizeof(struct WonderNews));
- svr->recvBuffer = AllocZeroed(ME_SEND_BUF_SIZE);
- svr->mevent_unk1442cc = AllocZeroed(sizeof(struct MEventStruct_Unk1442CC));
- svr->cmdBuffer = cmdBuffer;
- svr->cmdidx = 0;
- mevent_srv_sub_init(&svr->manager, sendPlayerNo, recvPlayerNo);
-}
-
-static void mevent_srv_free_resources(struct mevent_srv_common * svr)
-{
- Free(svr->wonder_card);
- Free(svr->wonder_news);
- Free(svr->recvBuffer);
- Free(svr->mevent_unk1442cc);
-}
-
-void mevent_srv_common_init_send(struct mevent_srv_common * svr, u32 ident, const void * src, u32 size)
-{
- AGB_ASSERT(size <= ME_SEND_BUF_SIZE);
- mevent_srv_sub_init_send(&svr->manager, ident, src, size);
-}
-
-static const void * mevent_first_if_not_null_else_second(const void * a0, const void * a1)
-{
- if (a0 != NULL)
- return a0;
- else
- return a1;
-}
-
-static u32 mevent_compare_pointers(const void * a0, const void * a1)
-{
- if (a1 < a0)
- return 0;
- else if (a1 == a0)
- return 1;
- else
- return 2;
-}
-
-static u32 common_mainseq_0(struct mevent_srv_common * svr)
-{
- // start
- svr->mainseqno = 4;
- return 0;
-}
-
-static u32 common_mainseq_1(struct mevent_srv_common * svr)
-{
- // done
- return 3;
-}
-
-static u32 common_mainseq_2(struct mevent_srv_common * svr)
-{
- // do recv
- if (mevent_srv_sub_recv(&svr->manager))
- svr->mainseqno = 4;
- return 1;
-}
-
-static u32 common_mainseq_3(struct mevent_srv_common * svr)
-{
- // do send
- if (mevent_srv_sub_send(&svr->manager))
- svr->mainseqno = 4;
- return 1;
-}
-
-static u32 common_mainseq_4(struct mevent_srv_common * svr)
-{
- // process command
- const struct mevent_cmd * cmd = &svr->cmdBuffer[svr->cmdidx];
- const void * ptr;
- svr->cmdidx++;
-
- switch (cmd->instr)
- {
- case 0:
- // end
- AGB_ASSERT(cmd->parameter == NULL);
- svr->mainseqno = 1;
- svr->param = cmd->flag;
- break;
- case 1:
- // wait_send
- svr->mainseqno = 3;
- break;
- case 2:
- // receive
- AGB_ASSERT(cmd->parameter == NULL);
- mevent_srv_sub_init_recv(&svr->manager, cmd->flag, svr->recvBuffer);
- svr->mainseqno = 2;
- break;
- case 3:
- // jump
- AGB_ASSERT(cmd->flag == FALSE);
- svr->cmdidx = 0;
- svr->cmdBuffer = cmd->parameter;
- break;
- case 5:
- // get_1442CC
- AGB_ASSERT(cmd->flag == FALSE);
- AGB_ASSERT(cmd->parameter == NULL);
- memcpy(svr->mevent_unk1442cc, svr->recvBuffer, sizeof(struct MEventStruct_Unk1442CC));
- break;
- case 6:
- // check_header__pass_false
- AGB_ASSERT(cmd->flag == FALSE);
- AGB_ASSERT(cmd->parameter == NULL);
- svr->param = sub_801B6A0(svr->mevent_unk1442cc, FALSE);
- break;
- case 30:
- // check_header__pass_true
- AGB_ASSERT(cmd->flag == FALSE);
- AGB_ASSERT(cmd->parameter == NULL);
- svr->param = sub_801B6A0(svr->mevent_unk1442cc, TRUE);
- break;
- case 4:
- // jump_if_eq
- if (svr->param == cmd->flag)
- {
- svr->cmdidx = 0;
- svr->cmdBuffer = cmd->parameter;
- }
- break;
- case 7:
- // check_crc
- AGB_ASSERT(cmd->flag == FALSE);
- ptr = mevent_first_if_not_null_else_second(cmd->parameter, svr->wonder_card);
- svr->param = sub_801B6EC(ptr, svr->mevent_unk1442cc, ptr);
- break;
- case 8:
- // read_word
- AGB_ASSERT(cmd->flag == FALSE);
- AGB_ASSERT(cmd->parameter == NULL);
- svr->param = *(u32 *)svr->recvBuffer;
- break;
- case 9:
- AGB_ASSERT(cmd->flag == FALSE);
- ptr = mevent_first_if_not_null_else_second(cmd->parameter, &svr->sendWord);
- svr->param = sub_801B708(ptr, svr->mevent_unk1442cc, ptr);
- break;
- case 10:
- AGB_ASSERT(cmd->parameter == NULL);
- svr->param = MEventStruct_Unk1442CC_GetValueNFrom_unk_20(svr->mevent_unk1442cc, cmd->flag);
- break;
- case 11:
- AGB_ASSERT(cmd->flag == FALSE);
- svr->param = MEventStruct_Unk1442CC_CompareField_unk_16(svr->mevent_unk1442cc, cmd->parameter);
- break;
- case 12:
- AGB_ASSERT(cmd->flag == FALSE);
- svr->param = mevent_compare_pointers(cmd->parameter, *(void **)svr->recvBuffer);
- break;
- case 14:
- AGB_ASSERT(cmd->flag == FALSE);
- mevent_srv_common_init_send(svr, 0x17, mevent_first_if_not_null_else_second(cmd->parameter, svr->wonder_news), sizeof(struct WonderNews));
- break;
- case 13:
- AGB_ASSERT(cmd->flag == FALSE);
- mevent_srv_common_init_send(svr, 0x16, mevent_first_if_not_null_else_second(cmd->parameter, svr->wonder_card), sizeof(struct WonderCard));
- break;
- case 16:
- AGB_ASSERT(cmd->flag == FALSE);
- mevent_srv_common_init_send(svr, 0x18, mevent_first_if_not_null_else_second(cmd->parameter, &svr->sendWord), 4);
- 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(cmd->flag == FALSE);
- 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(cmd->flag == FALSE);
- memcpy(svr->wonder_card, cmd->parameter, 332);
- break;
- case 23:
- AGB_ASSERT(cmd->flag == FALSE);
- memcpy(svr->wonder_news, cmd->parameter, 444);
- break;
- case 21:
- AGB_ASSERT(cmd->flag == FALSE);
- 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(cmd->flag == FALSE && cmd->parameter == NULL);
- memcpy(svr->wonder_card, GetSavedWonderCard(), 332);
- WonderCard_ResetInternalReceivedFlag(svr->wonder_card);
- break;
- case 27:
- AGB_ASSERT(cmd->flag == FALSE && cmd->parameter == NULL);
- memcpy(svr->wonder_news, GetSavedWonderNews(), 444);
- break;
- case 28:
- AGB_ASSERT(cmd->flag == FALSE && cmd->parameter == NULL);
- svr->sendBuffer1 = GetSavedRamScriptIfValid();
- break;
- case 29:
- mevent_srv_common_init_send(svr, 0x1b, cmd->parameter, cmd->flag);
- break;
- }
-
- return 1;
-}
-
-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 mevent_srv_exec_common(struct mevent_srv_common * svr)
-{
- u32 response;
- AGB_ASSERT(svr->mainseqno < ARRAY_COUNT(func_tbl));
- response = func_tbl[svr->mainseqno](svr);
- AGB_ASSERT(svr->mainseqno < ARRAY_COUNT(func_tbl));
- return response;
-}
diff --git a/src/mevent_server_helpers.c b/src/mevent_server_helpers.c
deleted file mode 100644
index 616f394f7..000000000
--- a/src/mevent_server_helpers.c
+++ /dev/null
@@ -1,211 +0,0 @@
-#include "global.h"
-#include "malloc.h"
-#include "decompress.h"
-#include "util.h"
-#include "link.h"
-#include "link_rfu.h"
-#include "overworld.h"
-#include "script.h"
-#include "battle_tower.h"
-#include "mystery_event_script.h"
-#include "mevent.h"
-#include "mevent_server_helpers.h"
-
-static u32 mevent_receive_func(struct mevent_srv_sub *);
-static u32 mevent_send_func(struct mevent_srv_sub *);
-
-u32 mevent_srv_sub_recv(struct mevent_srv_sub * svr)
-{
- return svr->recvFunc(svr);
-}
-
-u32 mevent_srv_sub_send(struct mevent_srv_sub * svr)
-{
- return svr->sendFunc(svr);
-}
-
-void mevent_srv_sub_init(struct mevent_srv_sub * svr, u32 sendPlayerNo, u32 recvPlayerNo)
-{
- 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;
-}
-
-void mevent_srv_sub_init_send(struct mevent_srv_sub * svr, u32 ident, const void * src, u32 size)
-{
- svr->seqno = 0;
- svr->sendIdent = ident;
- svr->sendCounter = 0;
- svr->sendCRC = 0;
- if (size != 0)
- svr->sendSize = size;
- else
- svr->sendSize = ME_SEND_BUF_SIZE;
- svr->sendBfr = src;
-}
-
-void mevent_srv_sub_init_recv(struct mevent_srv_sub * svr, u32 ident, void * dest)
-{
- svr->seqno = 0;
- svr->recvIdent = ident;
- svr->recvCounter = 0;
- svr->recvCRC = 0;
- svr->recvSize = 0;
- svr->recvBfr = dest;
-}
-
-static void mevent_recv_block(u32 recv_idx, void * dest, size_t size)
-{
- memcpy(dest, gBlockRecvBuffer[recv_idx], size);
-}
-
-static bool32 mevent_has_received(u32 recv_idx)
-{
- if ((GetBlockReceivedStatus() >> recv_idx) & 1)
- return TRUE;
- else
- return FALSE;
-}
-
-static void mevent_reset_recv(u32 recv_idx)
-{
- ResetBlockReceivedFlag(recv_idx);
-}
-
-static bool32 mevent_receive_func(struct mevent_srv_sub * svr)
-{
- struct send_recv_header header;
-
- switch (svr->seqno)
- {
- case 0:
- if (mevent_has_received(svr->recvPlayerNo))
- {
- 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;
- }
- }
- 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)
- {
- LinkRfu_FatalError();
- return FALSE;
- }
- else
- {
- svr->seqno = 0;
- return TRUE;
- }
- break;
-
- }
-
- return FALSE;
-}
-
-static bool32 mevent_send_func(struct mevent_srv_sub * svr)
-{
- struct send_recv_header header;
-
- switch (svr->seqno)
- {
- case 0:
- if (IsLinkTaskFinished())
- {
- 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 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;
- }
- }
- }
- 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;
- }
-
- return FALSE;
-}
diff --git a/src/mystery_event_msg.c b/src/mystery_event_msg.c
index e0e70a218..51141bb77 100644
--- a/src/mystery_event_msg.c
+++ b/src/mystery_event_msg.c
@@ -1,13 +1,13 @@
#include "global.h"
-const u8 gText_MysteryGiftBerry[] = _("Obtained a {STR_VAR_2} BERRY!\nDad has it at PETALBURG GYM.");
-const u8 gText_MysteryGiftBerryTransform[] = _("The {STR_VAR_1} BERRY transformed into\none {STR_VAR_2} BERRY.");
-const u8 gText_MysteryGiftBerryObtained[] = _("The {STR_VAR_1} BERRY has already been\nobtained.");
-const u8 gText_MysteryGiftSpecialRibbon[] = _("A special RIBBON was awarded to\nyour party POKéMON.");
-const u8 gText_MysteryGiftNationalDex[] = _("The POKéDEX has been upgraded\nwith the NATIONAL MODE.");
-const u8 gText_MysteryGiftRareWord[] = _("A rare word has been added.");
-const u8 gText_MysteryGiftSentOver[] = _("{STR_VAR_1} was sent over!");
-const u8 gText_MysteryGiftFullParty[] = _("Your party is full.\n{STR_VAR_1} could not be sent over.");
-const u8 gText_MysteryGiftNewTrainer[] = _("A new TRAINER has arrived in\nHOENN.");
-const u8 gText_MysteryGiftNewAdversaryInBattleTower[] = _("A new adversary has arrived in the\nBATTLE TOWER.");
-const u8 gText_MysteryGiftCantBeUsed[] = _("This data can't be used in\nthis version.");
+const u8 gText_MysteryEventBerry[] = _("Obtained a {STR_VAR_2} BERRY!\nDad has it at PETALBURG GYM.");
+const u8 gText_MysteryEventBerryTransform[] = _("The {STR_VAR_1} BERRY transformed into\none {STR_VAR_2} BERRY.");
+const u8 gText_MysteryEventBerryObtained[] = _("The {STR_VAR_1} BERRY has already been\nobtained.");
+const u8 gText_MysteryEventSpecialRibbon[] = _("A special RIBBON was awarded to\nyour party POKéMON.");
+const u8 gText_MysteryEventNationalDex[] = _("The POKéDEX has been upgraded\nwith the NATIONAL MODE.");
+const u8 gText_MysteryEventRareWord[] = _("A rare word has been added.");
+const u8 gText_MysteryEventSentOver[] = _("{STR_VAR_1} was sent over!");
+const u8 gText_MysteryEventFullParty[] = _("Your party is full.\n{STR_VAR_1} could not be sent over.");
+const u8 gText_MysteryEventNewTrainer[] = _("A new TRAINER has arrived in\nHOENN.");
+const u8 gText_MysteryEventNewAdversaryInBattleTower[] = _("A new adversary has arrived in the\nBATTLE TOWER.");
+const u8 gText_MysteryEventCantBeUsed[] = _("This data can't be used in\nthis version.");
diff --git a/src/mystery_event_script.c b/src/mystery_event_script.c
index f590bcde6..18a1a0d07 100644
--- a/src/mystery_event_script.c
+++ b/src/mystery_event_script.c
@@ -43,7 +43,7 @@ static bool32 CheckCompatibility(u16 a1, u32 a2, u16 a3, u32 a4)
static void SetIncompatible(void)
{
- StringExpandPlaceholders(gStringVar4, gText_MysteryGiftCantBeUsed);
+ StringExpandPlaceholders(gStringVar4, gText_MysteryEventCantBeUsed);
SetMysteryEventScriptStatus(3);
}
@@ -65,15 +65,15 @@ static bool32 RunMysteryEventScriptCommand(struct ScriptContext *ctx)
return FALSE;
}
-void sub_8153870(u8 *script)
+void InitMysteryEventScriptContext(u8 *script)
{
InitMysteryEventScript(&sMysteryEventScriptContext, script);
}
-bool32 sub_8153884(u32 *a0)
+bool32 RunMysteryEventScriptContextCommand(u32 *script)
{
bool32 ret = RunMysteryEventScriptCommand(&sMysteryEventScriptContext);
- *a0 = sMysteryEventScriptContext.data[2];
+ *script = sMysteryEventScriptContext.data[2];
return ret;
}
@@ -229,17 +229,17 @@ bool8 MEScrCmd_setenigmaberry(struct ScriptContext *ctx)
if (!haveBerry)
{
str = gStringVar4;
- message = gText_MysteryGiftBerry;
+ message = gText_MysteryEventBerry;
}
else if (StringCompare(gStringVar1, gStringVar2))
{
str = gStringVar4;
- message = gText_MysteryGiftBerryTransform;
+ message = gText_MysteryEventBerryTransform;
}
else
{
str = gStringVar4;
- message = gText_MysteryGiftBerryObtained;
+ message = gText_MysteryEventBerryObtained;
}
StringExpandPlaceholders(str, message);
@@ -259,7 +259,7 @@ bool8 MEScrCmd_giveribbon(struct ScriptContext *ctx)
u8 index = ScriptReadByte(ctx);
u8 ribbonId = ScriptReadByte(ctx);
GiveGiftRibbonToParty(index, ribbonId);
- StringExpandPlaceholders(gStringVar4, gText_MysteryGiftSpecialRibbon);
+ StringExpandPlaceholders(gStringVar4, gText_MysteryEventSpecialRibbon);
ctx->data[2] = 2;
return FALSE;
}
@@ -278,7 +278,7 @@ bool8 MEScrCmd_initramscript(struct ScriptContext *ctx)
bool8 MEScrCmd_givenationaldex(struct ScriptContext *ctx)
{
EnableNationalPokedex();
- StringExpandPlaceholders(gStringVar4, gText_MysteryGiftNationalDex);
+ StringExpandPlaceholders(gStringVar4, gText_MysteryEventNationalDex);
ctx->data[2] = 2;
return FALSE;
}
@@ -286,7 +286,7 @@ bool8 MEScrCmd_givenationaldex(struct ScriptContext *ctx)
bool8 MEScrCmd_addrareword(struct ScriptContext *ctx)
{
UnlockAdditionalPhrase(ScriptReadByte(ctx));
- StringExpandPlaceholders(gStringVar4, gText_MysteryGiftRareWord);
+ StringExpandPlaceholders(gStringVar4, gText_MysteryEventRareWord);
ctx->data[2] = 2;
return FALSE;
}
@@ -320,7 +320,7 @@ bool8 MEScrCmd_givepokemon(struct ScriptContext *ctx)
if (gPlayerPartyCount == PARTY_SIZE)
{
- StringExpandPlaceholders(gStringVar4, gText_MysteryGiftFullParty);
+ StringExpandPlaceholders(gStringVar4, gText_MysteryEventFullParty);
ctx->data[2] = 3;
}
else
@@ -340,7 +340,7 @@ bool8 MEScrCmd_givepokemon(struct ScriptContext *ctx)
GiveMailToMon(&gPlayerParty[PARTY_SIZE - 1], &mail);
CompactPartySlots();
CalculatePlayerPartyCount();
- StringExpandPlaceholders(gStringVar4, gText_MysteryGiftSentOver);
+ StringExpandPlaceholders(gStringVar4, gText_MysteryEventSentOver);
ctx->data[2] = 2;
}
@@ -352,7 +352,7 @@ bool8 MEScrCmd_addtrainer(struct ScriptContext *ctx)
u32 data = ScriptReadWord(ctx) - ctx->data[1] + ctx->data[0];
memcpy(&gSaveBlock2Ptr->frontier.ereaderTrainer, (void *)data, sizeof(gSaveBlock2Ptr->frontier.ereaderTrainer));
ValidateEReaderTrainer();
- StringExpandPlaceholders(gStringVar4, gText_MysteryGiftNewTrainer);
+ StringExpandPlaceholders(gStringVar4, gText_MysteryEventNewTrainer);
ctx->data[2] = 2;
return FALSE;
}
diff --git a/src/mystery_gift.c b/src/mystery_gift.c
index 6ae6a9534..1df6533d9 100644..100755
--- a/src/mystery_gift.c
+++ b/src/mystery_gift.c
@@ -1,1672 +1,662 @@
#include "global.h"
+#include "util.h"
#include "main.h"
-#include "text.h"
-#include "task.h"
-#include "malloc.h"
-#include "gpu_regs.h"
-#include "scanline_effect.h"
-#include "text_window.h"
-#include "bg.h"
-#include "window.h"
-#include "strings.h"
-#include "text_window.h"
-#include "menu.h"
-#include "palette.h"
-#include "constants/songs.h"
-#include "sound.h"
-#include "mystery_gift.h"
-#include "union_room.h"
-#include "title_screen.h"
-#include "ereader_screen.h"
-#include "international_string_util.h"
-#include "list_menu.h"
-#include "string_util.h"
-#include "mevent.h"
-#include "mevent_801BAAC.h"
-#include "save.h"
-#include "link.h"
-#include "mevent_client.h"
#include "event_data.h"
-#include "link_rfu.h"
-#include "mevent_news.h"
-#include "mevent_server.h"
-#include "constants/cable_club.h"
+#include "easy_chat.h"
+#include "script.h"
+#include "battle_tower.h"
+#include "wonder_news.h"
+#include "string_util.h"
+#include "new_game.h"
+#include "mystery_gift.h"
+#include "constants/mystery_gift.h"
-void bgid_upload_textbox_1(u8 bgId);
-void task_add_00_mystery_gift(void);
-void task00_mystery_gift(u8 taskId);
+static EWRAM_DATA bool32 sStatsEnabled = FALSE;
-EWRAM_DATA u8 sDownArrowCounterAndYCoordIdx[8] = {};
-EWRAM_DATA bool8 gGiftIsFromEReader = FALSE;
+static void ClearSavedWonderNewsMetadata(void);
+static void ClearSavedWonderNews(void);
+static void ClearSavedWonderCard(void);
+static bool32 ValidateWonderNews(const struct WonderNews *);
+static bool32 ValidateWonderCard(const struct WonderCard *);
+static void ClearSavedWonderCardMetadata(void);
+static void ClearSavedTrainerIds(void);
+static void IncrementCardStatForNewTrainer(u32, u32, u32 *, int);
-static const u16 gUnkTextboxBorderPal[] = INCBIN_U16("graphics/interface/unk_textbox_border.gbapal");
-static const u32 gUnkTextboxBorderGfx[] = INCBIN_U32("graphics/interface/unk_textbox_border.4bpp.lz");
+#define CALC_CRC(data) CalcCRC16WithTable((void *)&(data), sizeof(data))
-struct MysteryGiftTaskData
+void ClearMysteryGift(void)
{
- u16 curPromptWindowId;
- u16 unk2;
- u16 unk4;
- u16 unk6;
- u8 state;
- u8 textState;
- u8 unkA;
- u8 unkB;
- u8 IsCardOrNews;
- u8 source;
- u8 prevPromptWindowId;
- u8 * buffer;
-};
-
-static const struct BgTemplate sBGTemplates[] = {
- {
- .bg = 0,
- .charBaseIndex = 2,
- .mapBaseIndex = 15,
- .screenSize = 0,
- .paletteMode = 0,
- .priority = 0,
- .baseTile = 0x000
- }, {
- .bg = 1,
- .charBaseIndex = 0,
- .mapBaseIndex = 14,
- .screenSize = 0,
- .paletteMode = 0,
- .priority = 1,
- .baseTile = 0x000
- }, {
- .bg = 2,
- .charBaseIndex = 0,
- .mapBaseIndex = 13,
- .screenSize = 0,
- .paletteMode = 0,
- .priority = 2,
- .baseTile = 0x000
- }, {
- .bg = 3,
- .charBaseIndex = 0,
- .mapBaseIndex = 12,
- .screenSize = 0,
- .paletteMode = 0,
- .priority = 3,
- .baseTile = 0x000
- }
-};
-
-static const struct WindowTemplate sMainWindows[] = {
- {
- .bg = 0x00,
- .tilemapLeft = 0x00,
- .tilemapTop = 0x00,
- .width = 0x1e,
- .height = 0x02,
- .paletteNum = 0x0c,
- .baseBlock = 0x0013
- }, {
- .bg = 0x00,
- .tilemapLeft = 0x01,
- .tilemapTop = 0x0f,
- .width = 0x1c,
- .height = 0x04,
- .paletteNum = 0x0c,
- .baseBlock = 0x004f
- }, {
- .bg = 0x00,
- .tilemapLeft = 0x00,
- .tilemapTop = 0x0f,
- .width = 0x1e,
- .height = 0x05,
- .paletteNum = 0x0d,
- .baseBlock = 0x004f
- }, {
- 0xFF
- }
-};
-
-static const struct WindowTemplate sWindowTemplate_PromptYesOrNo_Width28 = {
- .bg = 0x00,
- .tilemapLeft = 0x01,
- .tilemapTop = 0x0f,
- .width = 0x1c,
- .height = 0x04,
- .paletteNum = 0x0c,
- .baseBlock = 0x00e5
-};
-
-static const struct WindowTemplate sWindowTemplate_PromptYesOrNo_Width20 = {
- .bg = 0x00,
- .tilemapLeft = 0x01,
- .tilemapTop = 0x0f,
- .width = 0x14,
- .height = 0x04,
- .paletteNum = 0x0c,
- .baseBlock = 0x00e5
-};
-
-static const struct WindowTemplate sMysteryGiftMenuWindowTemplate = {
- .bg = 0x00,
- .tilemapLeft = 0x01,
- .tilemapTop = 0x0f,
- .width = 0x13,
- .height = 0x04,
- .paletteNum = 0x0c,
- .baseBlock = 0x00e5
-};
-
-static const struct WindowTemplate sWindowTemplate_ThreeOptions = {
- .bg = 0x00,
- .tilemapLeft = 0x08,
- .tilemapTop = 0x06,
- .width = 0x0e,
- .height = 0x06,
- .paletteNum = 0x0c,
- .baseBlock = 0x0155
-};
-
-static const struct WindowTemplate sWindowTemplate_YesNoBox = {
- .bg = 0x00,
- .tilemapLeft = 0x17,
- .tilemapTop = 0x0f,
- .width = 0x06,
- .height = 0x04,
- .paletteNum = 0x0c,
- .baseBlock = 0x0155
-};
-
-static const struct WindowTemplate sWindowTemplate_7by8 = {
- .bg = 0x00,
- .tilemapLeft = 0x16,
- .tilemapTop = 0x0b,
- .width = 0x07,
- .height = 0x08,
- .paletteNum = 0x0c,
- .baseBlock = 0x0155
-};
-
-static const struct WindowTemplate sWindowTemplate_7by6 = {
- .bg = 0x00,
- .tilemapLeft = 0x16,
- .tilemapTop = 0x0d,
- .width = 0x07,
- .height = 0x06,
- .paletteNum = 0x0c,
- .baseBlock = 0x0155
-};
+ CpuFill32(0, &gSaveBlock1Ptr->mysteryGift, sizeof(gSaveBlock1Ptr->mysteryGift));
+ ClearSavedWonderNewsMetadata(); // Clear is redundant, InitSavedWonderNews would be sufficient
+ InitQuestionnaireWords();
+}
-static const struct WindowTemplate sWindowTemplate_7by4 = {
- .bg = 0x00,
- .tilemapLeft = 0x16,
- .tilemapTop = 0x0f,
- .width = 0x07,
- .height = 0x04,
- .paletteNum = 0x0c,
- .baseBlock = 0x0155
-};
+struct WonderNews *GetSavedWonderNews(void)
+{
+ return &gSaveBlock1Ptr->mysteryGift.news;
+}
-static const struct ListMenuItem sListMenuItems_CardsOrNews[] = {
- { gText_WonderCards, 0 },
- { gText_WonderNews, 1 },
- { gText_Exit3, -2 }
-};
+struct WonderCard *GetSavedWonderCard(void)
+{
+ return &gSaveBlock1Ptr->mysteryGift.card;
+}
-static const struct ListMenuItem sListMenuItems_WirelessOrFriend[] = {
- { gText_WirelessCommunication, 0 },
- { gText_Friend2, 1 },
- { gText_Cancel2, -2 }
-};
+struct WonderCardMetadata *GetSavedWonderCardMetadata(void)
+{
+ return &gSaveBlock1Ptr->mysteryGift.cardMetadata;
+}
-static const struct ListMenuTemplate sListMenuTemplate_ThreeOptions = {
- .items = NULL,
- .moveCursorFunc = ListMenuDefaultCursorMoveFunc,
- .itemPrintFunc = NULL,
- .totalItems = 3,
- .maxShowed = 3,
- .windowId = 0,
- .header_X = 0,
- .item_X = 8,
- .cursor_X = 0,
- .upText_Y = 1,
- .cursorPal = 2,
- .fillValue = 1,
- .cursorShadowPal = 3,
- .lettersSpacing = 0,
- .itemVerticalPadding = 0,
- .scrollMultiple = 0,
- .fontId = 1,
- .cursorKind = 0
-};
+struct WonderNewsMetadata *GetSavedWonderNewsMetadata(void)
+{
+ return &gSaveBlock1Ptr->mysteryGift.newsMetadata;
+}
-static const struct ListMenuItem sListMenuItems_ReceiveSendToss[] = {
- { gText_Receive, 0 },
- { gText_Send, 1 },
- { gText_Toss, 2 },
- { gText_Cancel2, -2 }
-};
+u16 *GetQuestionnaireWordsPtr(void)
+{
+ return gSaveBlock1Ptr->mysteryGift.questionnaireWords;
+}
-static const struct ListMenuItem sListMenuItems_ReceiveToss[] = {
- { gText_Receive, 0 },
- { gText_Toss, 2 },
- { gText_Cancel2, -2 }
-};
+// Equivalent to ClearSavedWonderCardAndRelated, but nothing else to clear
+void ClearSavedWonderNewsAndRelated(void)
+{
+ ClearSavedWonderNews();
+}
-static const struct ListMenuItem sListMenuItems_ReceiveSend[] = {
- { gText_Receive, 0 },
- { gText_Send, 1 },
- { gText_Cancel2, -2 }
-};
+bool32 SaveWonderNews(const struct WonderNews *news)
+{
+ if (!ValidateWonderNews(news))
+ return FALSE;
-static const struct ListMenuItem sListMenuItems_Receive[] = {
- { gText_Receive, 0 },
- { gText_Cancel2, -2 }
-};
+ ClearSavedWonderNews();
+ gSaveBlock1Ptr->mysteryGift.news = *news;
+ gSaveBlock1Ptr->mysteryGift.newsCrc = CALC_CRC(gSaveBlock1Ptr->mysteryGift.news);
+ return TRUE;
+}
-static const struct ListMenuTemplate sListMenu_ReceiveSendToss = {
- .items = sListMenuItems_ReceiveSendToss,
- .moveCursorFunc = ListMenuDefaultCursorMoveFunc,
- .itemPrintFunc = NULL,
- .totalItems = 4,
- .maxShowed = 4,
- .windowId = 0,
- .header_X = 0,
- .item_X = 8,
- .cursor_X = 0,
- .upText_Y = 1,
- .cursorPal = 2,
- .fillValue = 1,
- .cursorShadowPal = 3,
- .lettersSpacing = 0,
- .itemVerticalPadding = 0,
- .scrollMultiple = 0,
- .fontId = 1,
- .cursorKind = 0
-};
+bool32 ValidateSavedWonderNews(void)
+{
+ if (CALC_CRC(gSaveBlock1Ptr->mysteryGift.news) != gSaveBlock1Ptr->mysteryGift.newsCrc)
+ return FALSE;
+ if (!ValidateWonderNews(&gSaveBlock1Ptr->mysteryGift.news))
+ return FALSE;
-static const struct ListMenuTemplate sListMenu_ReceiveToss = {
- .items = sListMenuItems_ReceiveToss,
- .moveCursorFunc = ListMenuDefaultCursorMoveFunc,
- .itemPrintFunc = NULL,
- .totalItems = 3,
- .maxShowed = 3,
- .windowId = 0,
- .header_X = 0,
- .item_X = 8,
- .cursor_X = 0,
- .upText_Y = 1,
- .cursorPal = 2,
- .fillValue = 1,
- .cursorShadowPal = 3,
- .lettersSpacing = 0,
- .itemVerticalPadding = 0,
- .scrollMultiple = 0,
- .fontId = 1,
- .cursorKind = 0
-};
+ return TRUE;
+}
-static const struct ListMenuTemplate sListMenu_ReceiveSend = {
- .items = sListMenuItems_ReceiveSend,
- .moveCursorFunc = ListMenuDefaultCursorMoveFunc,
- .itemPrintFunc = NULL,
- .totalItems = 3,
- .maxShowed = 3,
- .windowId = 0,
- .header_X = 0,
- .item_X = 8,
- .cursor_X = 0,
- .upText_Y = 1,
- .cursorPal = 2,
- .fillValue = 1,
- .cursorShadowPal = 3,
- .lettersSpacing = 0,
- .itemVerticalPadding = 0,
- .scrollMultiple = 0,
- .fontId = 1,
- .cursorKind = 0
-};
+static bool32 ValidateWonderNews(const struct WonderNews *news)
+{
+ if (news->id == 0)
+ return FALSE;
-static const struct ListMenuTemplate sListMenu_Receive = {
- .items = sListMenuItems_Receive,
- .moveCursorFunc = ListMenuDefaultCursorMoveFunc,
- .itemPrintFunc = NULL,
- .totalItems = 2,
- .maxShowed = 2,
- .windowId = 0,
- .header_X = 0,
- .item_X = 8,
- .cursor_X = 0,
- .upText_Y = 1,
- .cursorPal = 2,
- .fillValue = 1,
- .cursorShadowPal = 3,
- .lettersSpacing = 0,
- .itemVerticalPadding = 0,
- .scrollMultiple = 0,
- .fontId = 1,
- .cursorKind = 0
-};
+ return TRUE;
+}
-static const u8 *const Unref_082F0710[] = {
- gText_VarietyOfEventsImportedWireless,
- gText_WonderCardsInPossession,
- gText_ReadNewsThatArrived,
- gText_ReturnToTitle
-};
+bool32 IsSendingSavedWonderNewsAllowed(void)
+{
+ const struct WonderNews *news = &gSaveBlock1Ptr->mysteryGift.news;
+ if (news->sendType == SEND_TYPE_DISALLOWED)
+ return FALSE;
-ALIGNED(2) const u8 sMG_Ereader_TextColor_1[] = { 0, 1, 2 };
-ALIGNED(2) const u8 sMG_Ereader_TextColor_1_Copy[] = { 0, 1, 2 };
-ALIGNED(2) const u8 sMG_Ereader_TextColor_2[] = { 1, 2, 3 };
+ return TRUE;
+}
-void vblankcb_mystery_gift_e_reader_run(void)
+static void ClearSavedWonderNews(void)
{
- ProcessSpriteCopyRequests();
- LoadOam();
- TransferPlttBuffer();
+ CpuFill32(0, GetSavedWonderNews(), sizeof(gSaveBlock1Ptr->mysteryGift.news));
+ gSaveBlock1Ptr->mysteryGift.newsCrc = 0;
}
-void c2_mystery_gift_e_reader_run(void)
+static void ClearSavedWonderNewsMetadata(void)
{
- RunTasks();
- RunTextPrinters();
- AnimateSprites();
- BuildOamBuffer();
+ CpuFill32(0, GetSavedWonderNewsMetadata(), sizeof(gSaveBlock1Ptr->mysteryGift.newsMetadata));
+ InitSavedWonderNews();
}
-bool32 HandleMysteryGiftOrEReaderSetup(s32 mg_or_ereader)
+bool32 IsWonderNewsSameAsSaved(const u8 *news)
{
- switch (gMain.state)
+ const u8 *savedNews = (const u8 *)&gSaveBlock1Ptr->mysteryGift.news;
+ u32 i;
+ if (!ValidateSavedWonderNews())
+ return FALSE;
+
+ for (i = 0; i < sizeof(gSaveBlock1Ptr->mysteryGift.news); i++)
{
- case 0:
- SetVBlankCallback(NULL);
- ResetPaletteFade();
- ResetSpriteData();
- FreeAllSpritePalettes();
- ResetTasks();
- ScanlineEffect_Stop();
- ResetBgsAndClearDma3BusyFlags(0);
-
- InitBgsFromTemplates(0, sBGTemplates, ARRAY_COUNT(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);
-
- SetBgTilemapBuffer(3, Alloc(BG_SCREEN_SIZE));
- SetBgTilemapBuffer(2, Alloc(BG_SCREEN_SIZE));
- SetBgTilemapBuffer(1, Alloc(BG_SCREEN_SIZE));
- SetBgTilemapBuffer(0, Alloc(BG_SCREEN_SIZE));
-
- bgid_upload_textbox_1(3);
- InitWindows(sMainWindows);
- DeactivateAllTextPrinters();
- ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON | DISPCNT_WIN1_ON);
- SetGpuReg(REG_OFFSET_BLDCNT, 0);
- SetGpuReg(REG_OFFSET_BLDALPHA, 0);
- SetGpuReg(REG_OFFSET_BLDY, 0);
- gMain.state++;
- break;
- case 1:
- LoadPalette(gUnkTextboxBorderPal, 0, 0x20);
- LoadPalette(GetTextWindowPalette(2), 0xd0, 0x20);
- Menu_LoadStdPalAt(0xC0);
- LoadUserWindowBorderGfx(0, 0xA, 0xE0);
- LoadUserWindowBorderGfx_(0, 0x1, 0xF0);
- 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(3);
- PrintMysteryGiftOrEReaderTopMenu(mg_or_ereader, 0);
- gMain.state++;
- break;
- case 2:
- CopyBgTilemapBufferToVram(3);
- CopyBgTilemapBufferToVram(2);
- CopyBgTilemapBufferToVram(1);
- CopyBgTilemapBufferToVram(0);
- gMain.state++;
- break;
- case 3:
- ShowBg(0);
- ShowBg(3);
- PlayBGM(MUS_RG_MYSTERY_GIFT);
- SetVBlankCallback(vblankcb_mystery_gift_e_reader_run);
- EnableInterrupts(INTR_FLAG_VBLANK | INTR_FLAG_VCOUNT | INTR_FLAG_TIMER3 | INTR_FLAG_SERIAL);
- return TRUE;
+ if (savedNews[i] != news[i])
+ return FALSE;
}
- return FALSE;
+ return TRUE;
}
-void c2_mystery_gift(void)
+void ClearSavedWonderCardAndRelated(void)
{
- if (HandleMysteryGiftOrEReaderSetup(0))
- {
- SetMainCallback2(c2_mystery_gift_e_reader_run);
- gGiftIsFromEReader = FALSE;
- task_add_00_mystery_gift();
- }
- RunTasks();
+ ClearSavedWonderCard();
+ ClearSavedWonderCardMetadata();
+ ClearSavedTrainerIds();
+ ClearRamScript();
+ ClearMysteryGiftFlags();
+ ClearMysteryGiftVars();
+ ClearEReaderTrainer(&gSaveBlock2Ptr->frontier.ereaderTrainer);
}
-void c2_ereader(void)
+bool32 SaveWonderCard(const struct WonderCard *card)
{
- if (HandleMysteryGiftOrEReaderSetup(1))
- {
- SetMainCallback2(c2_mystery_gift_e_reader_run);
- gGiftIsFromEReader = TRUE;
- task_add_00_ereader();
- }
-}
+ struct WonderCardMetadata *metadata;
+ if (!ValidateWonderCard(card))
+ return FALSE;
-void MainCB_FreeAllBuffersAndReturnToInitTitleScreen(void)
-{
- gGiftIsFromEReader = FALSE;
- FreeAllWindowBuffers();
- Free(GetBgTilemapBuffer(0));
- Free(GetBgTilemapBuffer(1));
- Free(GetBgTilemapBuffer(2));
- Free(GetBgTilemapBuffer(3));
- SetMainCallback2(CB2_InitTitleScreen);
+ 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;
}
-void PrintMysteryGiftOrEReaderTopMenu(bool8 mg_or_ereader, bool32 usePickOkCancel)
+bool32 ValidateSavedWonderCard(void)
{
- const u8 * header;
- const u8 * options;
- FillWindowPixelBuffer(0, 0);
- if (mg_or_ereader == 0)
- {
- header = gText_MysteryGift;
- options = !usePickOkCancel ? gText_PickOKExit : gText_PickOKCancel;
- }
- else
- {
- header = gJPText_MysteryGift;
- options = gJPText_DecideStop;
- }
+ if (gSaveBlock1Ptr->mysteryGift.cardCrc != CALC_CRC(gSaveBlock1Ptr->mysteryGift.card))
+ return FALSE;
+ if (!ValidateWonderCard(&gSaveBlock1Ptr->mysteryGift.card))
+ return FALSE;
+ if (!ValidateSavedRamScript())
+ return FALSE;
- AddTextPrinterParameterized4(0, 1, 4, 1, 0, 0, sMG_Ereader_TextColor_1, -1, header);
- AddTextPrinterParameterized4(0, 0, GetStringRightAlignXOffset(0, options, 0xDE), 1, 0, 0, sMG_Ereader_TextColor_1, -1, options);
- CopyWindowToVram(0, 2);
- PutWindowTilemap(0);
+ return TRUE;
}
-void MG_DrawTextBorder(u8 windowId)
+static bool32 ValidateWonderCard(const struct WonderCard *card)
{
- DrawTextBorderOuter(windowId, 0x01, 0xF);
+ if (card->flagId == 0)
+ return FALSE;
+ if (card->type >= CARD_TYPE_COUNT)
+ return FALSE;
+ if (!(card->sendType == SEND_TYPE_DISALLOWED
+ || card->sendType == SEND_TYPE_ALLOWED
+ || card->sendType == SEND_TYPE_ALLOWED_ALWAYS))
+ return FALSE;
+ if (card->bgType >= NUM_WONDER_BGS)
+ return FALSE;
+ if (card->maxStamps > MAX_STAMP_CARD_STAMPS)
+ return FALSE;
+
+ return TRUE;
}
-void MG_DrawCheckerboardPattern(u32 bg)
+bool32 IsSendingSavedWonderCardAllowed(void)
{
- s32 i = 0, j;
+ const struct WonderCard *card = &gSaveBlock1Ptr->mysteryGift.card;
+ if (card->sendType == SEND_TYPE_DISALLOWED)
+ return FALSE;
- FillBgTilemapBufferRect(bg, 0x003, 0, 0, 32, 2, 0x11);
+ return TRUE;
+}
- for (i = 0; i < 18; i++)
- {
- for (j = 0; j < 32; j++)
- {
- if ((i & 1) != (j & 1))
- FillBgTilemapBufferRect(bg, 1, j, i + 2, 1, 1, 0x11);
- else
- FillBgTilemapBufferRect(bg, 2, j, i + 2, 1, 1, 0x11);
- }
- }
+static void ClearSavedWonderCard(void)
+{
+ CpuFill32(0, &gSaveBlock1Ptr->mysteryGift.card, sizeof(gSaveBlock1Ptr->mysteryGift.card));
+ gSaveBlock1Ptr->mysteryGift.cardCrc = 0;
}
-void ClearScreenInBg0(bool32 ignoreTopTwoRows)
+static void ClearSavedWonderCardMetadata(void)
{
- switch (ignoreTopTwoRows)
- {
- case 0:
- FillBgTilemapBufferRect(0, 0, 0, 0, 32, 32, 0x11);
- break;
- case 1:
- FillBgTilemapBufferRect(0, 0, 0, 2, 32, 30, 0x11);
- break;
- }
- CopyBgTilemapBufferToVram(0);
+ CpuFill32(0, GetSavedWonderCardMetadata(), sizeof(gSaveBlock1Ptr->mysteryGift.cardMetadata));
+ gSaveBlock1Ptr->mysteryGift.cardMetadataCrc = 0;
}
-void AddTextPrinterToWindow1(const u8 *str)
+u16 GetWonderCardFlagID(void)
{
- StringExpandPlaceholders(gStringVar4, str);
- FillWindowPixelBuffer(1, 0x11);
- AddTextPrinterParameterized4(1, 1, 0, 1, 0, 0, sMG_Ereader_TextColor_2, 0, gStringVar4);
- DrawTextBorderOuter(1, 0x001, 0xF);
- PutWindowTilemap(1);
- CopyWindowToVram(1, 3);
+ if (ValidateSavedWonderCard())
+ return gSaveBlock1Ptr->mysteryGift.card.flagId;
+
+ return 0;
}
-static void ClearTextWindow(void)
+void DisableWonderCardSending(struct WonderCard *card)
{
- rbox_fill_rectangle(1);
- ClearWindowTilemap(1);
- CopyWindowToVram(1, 1);
+ if (card->sendType == SEND_TYPE_ALLOWED)
+ card->sendType = SEND_TYPE_DISALLOWED;
}
-bool32 MG_PrintTextOnWindow1AndWaitButton(u8 *textState, const u8 *str)
+static bool32 IsWonderCardFlagIDInValidRange(u16 flagId)
{
- switch (*textState)
- {
- case 0:
- AddTextPrinterToWindow1(str);
- (*textState)++;
- break;
- case 1:
- DrawDownArrow(1, 0xD0, 0x14, 1, FALSE, &sDownArrowCounterAndYCoordIdx[0], &sDownArrowCounterAndYCoordIdx[1]);
- if (({JOY_NEW(A_BUTTON | B_BUTTON);}))
- (*textState)++;
- break;
- case 2:
- DrawDownArrow(1, 0xD0, 0x14, 1, TRUE, &sDownArrowCounterAndYCoordIdx[0], &sDownArrowCounterAndYCoordIdx[1]);
- *textState = 0;
- ClearTextWindow();
+ if (flagId >= WONDER_CARD_FLAG_OFFSET && flagId < WONDER_CARD_FLAG_OFFSET + NUM_WONDER_CARD_FLAGS)
return TRUE;
- case 0xFF:
- *textState = 2;
- return FALSE;
- }
+
return FALSE;
}
-static void HideDownArrow(void)
+static const u16 sReceivedGiftFlags[] =
+{
+ FLAG_RECEIVED_AURORA_TICKET,
+ FLAG_RECEIVED_MYSTIC_TICKET,
+ FLAG_RECEIVED_OLD_SEA_MAP,
+ FLAG_WONDER_CARD_UNUSED_1,
+ FLAG_WONDER_CARD_UNUSED_2,
+ FLAG_WONDER_CARD_UNUSED_3,
+ FLAG_WONDER_CARD_UNUSED_4,
+ FLAG_WONDER_CARD_UNUSED_5,
+ FLAG_WONDER_CARD_UNUSED_6,
+ FLAG_WONDER_CARD_UNUSED_7,
+ FLAG_WONDER_CARD_UNUSED_8,
+ FLAG_WONDER_CARD_UNUSED_9,
+ FLAG_WONDER_CARD_UNUSED_10,
+ FLAG_WONDER_CARD_UNUSED_11,
+ FLAG_WONDER_CARD_UNUSED_12,
+ FLAG_WONDER_CARD_UNUSED_13,
+ FLAG_WONDER_CARD_UNUSED_14,
+ FLAG_WONDER_CARD_UNUSED_15,
+ FLAG_WONDER_CARD_UNUSED_16,
+ FLAG_WONDER_CARD_UNUSED_17,
+};
+
+bool32 IsSavedWonderCardGiftNotReceived(void)
{
- DrawDownArrow(1, 0xD0, 0x14, 1, FALSE, &sDownArrowCounterAndYCoordIdx[0], &sDownArrowCounterAndYCoordIdx[1]);
+ u16 value = GetWonderCardFlagID();
+ if (!IsWonderCardFlagIDInValidRange(value))
+ return FALSE;
+
+ // 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 void ShowDownArrow(void)
+static int GetNumStampsInMetadata(const struct WonderCardMetadata *data, int size)
{
- DrawDownArrow(1, 0xD0, 0x14, 1, TRUE, &sDownArrowCounterAndYCoordIdx[0], &sDownArrowCounterAndYCoordIdx[1]);
+ int numStamps = 0;
+ int i;
+ for (i = 0; i < size; i++)
+ {
+ if (data->stampData[STAMP_ID][i] && data->stampData[STAMP_SPECIES][i] != SPECIES_NONE)
+ numStamps++;
+ }
+
+ return numStamps;
}
-bool32 unref_HideDownArrowAndWaitButton(u8 * textState)
+static bool32 IsStampInMetadata(const struct WonderCardMetadata *metadata, const u16 *stamp, int maxStamps)
{
- switch (*textState)
+ int i;
+ for (i = 0; i < maxStamps; i++)
{
- case 0:
- HideDownArrow();
- if (JOY_NEW(A_BUTTON | B_BUTTON))
- (*textState)++;
- break;
- case 1:
- ShowDownArrow();
- *textState = 0;
- return TRUE;
+ if (metadata->stampData[STAMP_ID][i] == stamp[STAMP_ID])
+ return TRUE;
+ if (metadata->stampData[STAMP_SPECIES][i] == stamp[STAMP_SPECIES])
+ return TRUE;
}
+
return FALSE;
}
-static bool32 PrintStringAndWait2Seconds(u8 * counter, const u8 * str)
+static bool32 ValidateStamp(const u16 *stamp)
{
- if (*counter == 0)
- AddTextPrinterToWindow1(str);
-
- if (++(*counter) > 120)
- {
- *counter = 0;
- ClearTextWindow();
- return TRUE;
- }
- else
- {
+ if (stamp[STAMP_ID] == 0)
return FALSE;
- }
+ if (stamp[STAMP_SPECIES] == SPECIES_NONE)
+ return FALSE;
+ if (stamp[STAMP_SPECIES] >= NUM_SPECIES)
+ return FALSE;
+ return TRUE;
}
-static u32 MysteryGift_HandleThreeOptionMenu(u8 * unused0, u16 * unused1, u8 whichMenu)
+static int GetNumStampsInSavedCard(void)
{
- struct ListMenuTemplate listMenuTemplate = sListMenuTemplate_ThreeOptions;
- struct WindowTemplate windowTemplate = sWindowTemplate_ThreeOptions;
- s32 width;
- s32 response;
+ struct WonderCard *card;
+ if (!ValidateSavedWonderCard())
+ return 0;
- if (whichMenu == 0)
- listMenuTemplate.items = sListMenuItems_CardsOrNews;
- else
- listMenuTemplate.items = sListMenuItems_WirelessOrFriend;
-
- width = Intl_GetListMenuWidth(&listMenuTemplate);
- if (width & 1)
- width++;
-
- windowTemplate.width = width;
- if (width < 30)
- windowTemplate.tilemapLeft = (30 - width) / 2;
- else
- windowTemplate.tilemapLeft = 0;
+ card = &gSaveBlock1Ptr->mysteryGift.card;
+ if (card->type != CARD_TYPE_STAMP)
+ return 0;
- response = DoMysteryGiftListMenu(&windowTemplate, &listMenuTemplate, 1, 0x00A, 0xE0);
- if (response != -1)
- {
- ClearWindowTilemap(2);
- CopyWindowToVram(2, 1);
- }
- return response;
+ return GetNumStampsInMetadata(&gSaveBlock1Ptr->mysteryGift.cardMetadata, card->maxStamps);
}
-s8 mevent_message_print_and_prompt_yes_no(u8 * textState, u16 * windowId, bool8 yesNoBoxPlacement, const u8 * str)
+bool32 MysteryGift_TrySaveStamp(const u16 *stamp)
{
- struct WindowTemplate windowTemplate;
- s8 input;
+ struct WonderCard *card = &gSaveBlock1Ptr->mysteryGift.card;
+ int maxStamps = card->maxStamps;
+ int i;
+ if (!ValidateStamp(stamp))
+ return FALSE;
+
+ if (IsStampInMetadata(&gSaveBlock1Ptr->mysteryGift.cardMetadata, stamp, maxStamps))
+ return FALSE;
- switch (*textState)
+ for (i = 0; i < maxStamps; i++)
{
- case 0:
- StringExpandPlaceholders(gStringVar4, str);
- if (yesNoBoxPlacement == 0)
- *windowId = AddWindow(&sWindowTemplate_PromptYesOrNo_Width28);
- else
- *windowId = AddWindow(&sWindowTemplate_PromptYesOrNo_Width20);
- FillWindowPixelBuffer(*windowId, 0x11);
- AddTextPrinterParameterized4(*windowId, 1, 0, 1, 0, 0, sMG_Ereader_TextColor_2, 0, gStringVar4);
- DrawTextBorderOuter(*windowId, 0x001, 0x0F);
- CopyWindowToVram(*windowId, 2);
- PutWindowTilemap(*windowId);
- (*textState)++;
- break;
- case 1:
- windowTemplate = sWindowTemplate_YesNoBox;
- if (yesNoBoxPlacement == 0)
- windowTemplate.tilemapTop = 9;
- else
- windowTemplate.tilemapTop = 15;
- CreateYesNoMenu(&windowTemplate, 10, 14, 0);
- (*textState)++;
- break;
- case 2:
- input = Menu_ProcessInputNoWrapClearOnChoose();
- if (input == MENU_B_PRESSED || input == 0 || input == 1)
+ if (gSaveBlock1Ptr->mysteryGift.cardMetadata.stampData[STAMP_ID][i] == 0
+ && gSaveBlock1Ptr->mysteryGift.cardMetadata.stampData[STAMP_SPECIES][i] == SPECIES_NONE)
{
- *textState = 0;
- rbox_fill_rectangle(*windowId);
- ClearWindowTilemap(*windowId);
- CopyWindowToVram(*windowId, 1);
- RemoveWindow(*windowId);
- return input;
+ gSaveBlock1Ptr->mysteryGift.cardMetadata.stampData[STAMP_ID][i] = stamp[STAMP_ID];
+ gSaveBlock1Ptr->mysteryGift.cardMetadata.stampData[STAMP_SPECIES][i] = stamp[STAMP_SPECIES];
+ return TRUE;
}
- break;
- case (u8)MENU_B_PRESSED:
- *textState = 0;
- rbox_fill_rectangle(*windowId);
- ClearWindowTilemap(*windowId);
- CopyWindowToVram(*windowId, 1);
- RemoveWindow(*windowId);
- return MENU_B_PRESSED;
}
- return MENU_NOTHING_CHOSEN;
+ return FALSE;
}
-static s32 HandleMysteryGiftListMenu(u8 * textState, u16 * windowId, bool32 cannotToss, bool32 cannotSend)
+#define GAME_DATA_VALID_VAR 0x101
+#define GAME_DATA_VALID_GIFT_TYPE_1 (1 << 2)
+#define GAME_DATA_VALID_GIFT_TYPE_2 (1 << 9)
+
+void MysteryGift_LoadLinkGameData(struct MysteryGiftLinkGameData *data, bool32 isWonderNews)
{
- struct WindowTemplate windowTemplate;
- s32 input;
+ int i;
+ CpuFill32(0, data, sizeof(*data));
+ data->validationVar = GAME_DATA_VALID_VAR;
+ data->validationFlag1 = 1;
+ data->validationFlag2 = 1;
- switch (*textState)
+ if (isWonderNews)
{
- case 0:
- if (cannotToss == 0)
- {
- StringExpandPlaceholders(gStringVar4, gText_WhatToDoWithCards);
- }
- else
- {
- StringExpandPlaceholders(gStringVar4, gText_WhatToDoWithNews);
- }
- *windowId = AddWindow(&sMysteryGiftMenuWindowTemplate);
- FillWindowPixelBuffer(*windowId, 0x11);
- AddTextPrinterParameterized4(*windowId, 1, 0, 1, 0, 0, sMG_Ereader_TextColor_2, 0, gStringVar4);
- DrawTextBorderOuter(*windowId, 0x001, 0x0F);
- CopyWindowToVram(*windowId, 2);
- PutWindowTilemap(*windowId);
- (*textState)++;
- break;
- case 1:
- windowTemplate = sWindowTemplate_YesNoBox;
- if (cannotSend)
- {
- if (cannotToss == 0)
- {
- input = DoMysteryGiftListMenu(&sWindowTemplate_7by6, &sListMenu_ReceiveToss, 1, 0x00A, 0xE0);
- }
- else
- {
- input = DoMysteryGiftListMenu(&sWindowTemplate_7by4, &sListMenu_Receive, 1, 0x00A, 0xE0);
- }
- }
- else
- {
- if (cannotToss == 0)
- {
- input = DoMysteryGiftListMenu(&sWindowTemplate_7by8, &sListMenu_ReceiveSendToss, 1, 0x00A, 0xE0);
- }
- else
- {
- input = DoMysteryGiftListMenu(&sWindowTemplate_7by6, &sListMenu_ReceiveSend, 1, 0x00A, 0xE0);
- }
- }
- if (input != -1)
- {
- *textState = 0;
- rbox_fill_rectangle(*windowId);
- ClearWindowTilemap(*windowId);
- CopyWindowToVram(*windowId, 1);
- RemoveWindow(*windowId);
- return input;
- }
- break;
- case 0xFF:
- *textState = 0;
- rbox_fill_rectangle(*windowId);
- ClearWindowTilemap(*windowId);
- CopyWindowToVram(*windowId, 1);
- RemoveWindow(*windowId);
- return -2;
+ // Despite setting these for News, they are
+ // only ever checked for Cards
+ data->validationGiftType1 = GAME_DATA_VALID_GIFT_TYPE_1 | 1;
+ data->validationGiftType2 = GAME_DATA_VALID_GIFT_TYPE_2 | 1;
+ }
+ else // Wonder Card
+ {
+ data->validationGiftType1 = GAME_DATA_VALID_GIFT_TYPE_1;
+ data->validationGiftType2 = GAME_DATA_VALID_GIFT_TYPE_2;
}
- return -1;
-}
-
-static bool32 ValidateCardOrNews(bool32 cardOrNews)
-{
- if (cardOrNews == 0)
+ if (ValidateSavedWonderCard())
{
- return ValidateReceivedWonderCard();
+ data->flagId = GetSavedWonderCard()->flagId;
+ data->cardMetadata = *GetSavedWonderCardMetadata();
+ data->maxStamps = GetSavedWonderCard()->maxStamps;
}
else
{
- return ValidateReceivedWonderNews();
+ data->flagId = 0;
}
+
+ for (i = 0; i < NUM_QUESTIONNAIRE_WORDS; i++)
+ data->questionnaireWords[i] = gSaveBlock1Ptr->mysteryGift.questionnaireWords[i];
+
+ CopyTrainerId(data->playerTrainerId, gSaveBlock2Ptr->playerTrainerId);
+ StringCopy(data->playerName, gSaveBlock2Ptr->playerName);
+ for (i = 0; i < EASY_CHAT_BATTLE_WORDS_COUNT; i++)
+ data->easyChatProfile[i] = gSaveBlock1Ptr->easyChatProfile[i];
+
+ memcpy(data->romHeaderGameCode, RomHeaderGameCode, GAME_CODE_LENGTH);
+ data->romHeaderSoftwareVersion = RomHeaderSoftwareVersion;
}
-static bool32 HandleLoadWonderCardOrNews(u8 * state, bool32 cardOrNews)
+bool32 MysteryGift_ValidateLinkGameData(const struct MysteryGiftLinkGameData *data, bool32 isWonderNews)
{
- switch (*state)
+ if (data->validationVar != GAME_DATA_VALID_VAR)
+ return FALSE;
+
+ if (!(data->validationFlag1 & 1))
+ return FALSE;
+
+ if (!(data->validationFlag2 & 1))
+ return FALSE;
+
+ if (!isWonderNews)
{
- case 0:
- if (cardOrNews == 0)
- {
- InitWonderCardResources(GetSavedWonderCard(), sav1_get_mevent_buffer_2());
- }
- else
- {
- InitWonderNewsResources(GetSavedWonderNews());
- }
- (*state)++;
- break;
- case 1:
- if (cardOrNews == 0)
- {
- if (!FadeToWonderCardMenu())
- {
- return FALSE;
- }
- }
- else
- {
- if (!FadeToWonderNewsMenu())
- {
- return FALSE;
- }
- }
- *state = 0;
- return TRUE;
+ if (!(data->validationGiftType1 & GAME_DATA_VALID_GIFT_TYPE_1))
+ return FALSE;
+
+ if (!(data->validationGiftType2 & (GAME_DATA_VALID_GIFT_TYPE_2 | 0x180)))
+ return FALSE;
}
- return FALSE;
+ return TRUE;
}
-static bool32 DestroyNewsOrCard(bool32 cardOrNews)
+u32 MysteryGift_CompareCardFlags(const u16 *flagId, const struct MysteryGiftLinkGameData *data, const void *unused)
{
- if (cardOrNews == 0)
- {
- DestroyWonderCard();
- }
- else
- {
- DestroyWonderNews();
- }
- return TRUE;
+ // Has a Wonder Card already?
+ if (data->flagId == 0)
+ return HAS_NO_CARD;
+
+ // Has this Wonder Card already?
+ if (*flagId == data->flagId)
+ return HAS_SAME_CARD;
+
+ // Player has a different Wonder Card
+ return HAS_DIFF_CARD;
}
-static bool32 TearDownCardOrNews_ReturnToTopMenu(bool32 cardOrNews, bool32 arg1)
+// This is referenced by the Mystery Gift server, but the instruction it's referenced in is never used,
+// so the return values here are never checked by anything.
+u32 MysteryGift_CheckStamps(const u16 *stamp, const struct MysteryGiftLinkGameData *data, const void *unused)
{
- if (cardOrNews == 0)
- {
- if (FadeOutFromWonderCard(arg1) != 0)
- {
- DestroyWonderCardResources();
- return TRUE;
- }
- else
- {
- return FALSE;
- }
- }
- else
+ int stampsMissing = data->maxStamps - GetNumStampsInMetadata(&data->cardMetadata, data->maxStamps);
+
+ // Has full stamp card?
+ if (stampsMissing == 0)
+ return 1;
+
+ // Already has stamp?
+ if (IsStampInMetadata(&data->cardMetadata, stamp, data->maxStamps))
+ return 3;
+
+ // Only 1 empty stamp left?
+ if (stampsMissing == 1)
+ return 4;
+
+ // This is a new stamp
+ return 2;
+}
+
+bool32 MysteryGift_DoesQuestionnaireMatch(const struct MysteryGiftLinkGameData *data, const u16 *words)
+{
+ int i;
+ for (i = 0; i < NUM_QUESTIONNAIRE_WORDS; i++)
{
- if (FadeOutFromWonderNews(arg1) != 0)
- {
- DestroyWonderNewsResources();
- return TRUE;
- }
- else
- {
+ if (data->questionnaireWords[i] != words[i])
return FALSE;
- }
}
+
+ return TRUE;
}
-static s32 mevent_message_prompt_discard(u8 * textState, u16 * windowId, bool32 cardOrNews)
+static int GetNumStampsInLinkData(const struct MysteryGiftLinkGameData *data)
{
- if (cardOrNews == 0)
- {
- return mevent_message_print_and_prompt_yes_no(textState, windowId, TRUE, gText_IfThrowAwayCardEventWontHappen);
- }
- else
- {
- return mevent_message_print_and_prompt_yes_no(textState, windowId, TRUE, gText_OkayToDiscardNews);
- }
+ return GetNumStampsInMetadata(&data->cardMetadata, data->maxStamps);
}
-static bool32 mevent_message_was_thrown_away(u8 * textState, bool32 cardOrNews)
+u16 MysteryGift_GetCardStatFromLinkData(const struct MysteryGiftLinkGameData *data, u32 stat)
{
- if (cardOrNews == 0)
- {
- return MG_PrintTextOnWindow1AndWaitButton(textState, gText_WonderCardThrownAway);
- }
- else
+ switch (stat)
{
- return MG_PrintTextOnWindow1AndWaitButton(textState, gText_WonderNewsThrownAway);
+ case CARD_STAT_BATTLES_WON:
+ return data->cardMetadata.battlesWon;
+ case CARD_STAT_BATTLES_LOST:
+ return data->cardMetadata.battlesLost;
+ case CARD_STAT_NUM_TRADES:
+ return data->cardMetadata.numTrades;
+ case CARD_STAT_NUM_STAMPS:
+ return GetNumStampsInLinkData(data);
+ case CARD_STAT_MAX_STAMPS:
+ return data->maxStamps;
+ default:
+ AGB_ASSERT(0);
+ return 0;
}
}
-static bool32 mevent_save_game(u8 * state)
+static void IncrementCardStat(u32 statType)
{
- switch (*state)
+ struct WonderCard *card = &gSaveBlock1Ptr->mysteryGift.card;
+ if (card->type == CARD_TYPE_LINK_STAT)
{
- case 0:
- AddTextPrinterToWindow1(gText_DataWillBeSaved);
- (*state)++;
- break;
- case 1:
- TrySavingData(SAVE_NORMAL);
- (*state)++;
- break;
- case 2:
- AddTextPrinterToWindow1(gText_SaveCompletedPressA);
- (*state)++;
- break;
- case 3:
- if (({JOY_NEW(A_BUTTON | B_BUTTON);}))
+ u16 *stat = NULL;
+ switch (statType)
{
- (*state)++;
+ 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: // Unused
+ case CARD_STAT_MAX_STAMPS: // Unused
+ break;
}
- break;
- case 4:
- *state = 0;
- ClearTextWindow();
- return TRUE;
- }
-
- return FALSE;
-}
-
-static const u8 * mevent_message(u32 * a0, u8 a1, u8 cardOrNews, u32 msgId)
-{
- const u8 * msg = NULL;
- *a0 = 0;
- switch (msgId)
- {
- case 0:
- *a0 = 0;
- msg = gText_NothingSentOver;
- break;
- case 1:
- *a0 = 0;
- msg = gText_RecordUploadedViaWireless;
- break;
- case 2:
- *a0 = 1;
- msg = cardOrNews == 0 ? gText_WonderCardReceived : gText_WonderCardReceivedFrom;
- break;
- case 3:
- *a0 = 1;
- msg = cardOrNews == 0 ? gText_WonderNewsReceived : gText_WonderNewsReceivedFrom;
- break;
- case 4:
- *a0 = 1;
- msg = gText_NewStampReceived;
- break;
- case 5:
- *a0 = 0;
- msg = gText_AlreadyHadCard;
- break;
- case 6:
- *a0 = 0;
- msg = gText_AlreadyHadStamp;
- break;
- case 7:
- *a0 = 0;
- msg = gText_AlreadyHadNews;
- break;
- case 8:
- *a0 = 0;
- msg = gText_NoMoreRoomForStamps;
- break;
- case 9:
- *a0 = 0;
- msg = gText_CommunicationCanceled;
- break;
- case 10:
- *a0 = 0;
- msg = a1 == 0 ? gText_CantAcceptCardFromTrainer : gText_CantAcceptNewsFromTrainer;
- break;
- case 11:
- *a0 = 0;
- msg = gText_CommunicationError;
- break;
- case 12:
- *a0 = 1;
- msg = gText_NewTrainerReceived;
- break;
- case 13:
- *a0 = 1;
- break;
- case 14:
- *a0 = 0;
- break;
+ if (stat == NULL)
+ AGB_ASSERT(0);
+ else if (++(*stat) > MAX_WONDER_CARD_STAT)
+ *stat = MAX_WONDER_CARD_STAT;
}
-
- return msg;
}
-static bool32 PrintMGSuccessMessage(u8 * state, const u8 * arg1, u16 * arg2)
+u16 MysteryGift_GetCardStat(u32 stat)
{
- switch (*state)
+ switch (stat)
{
- case 0:
- if (arg1 != NULL)
+ case CARD_STAT_BATTLES_WON:
+ {
+ struct WonderCard *card = &gSaveBlock1Ptr->mysteryGift.card;
+ if (card->type == CARD_TYPE_LINK_STAT)
{
- AddTextPrinterToWindow1(arg1);
+ struct WonderCardMetadata *metadata = &gSaveBlock1Ptr->mysteryGift.cardMetadata;
+ return metadata->battlesWon;
}
- PlayFanfare(MUS_OBTAIN_ITEM);
- *arg2 = 0;
- (*state)++;
break;
- case 1:
- if (++(*arg2) > 0xF0)
+ }
+ case CARD_STAT_BATTLES_LOST:
+ {
+ struct WonderCard *card = &gSaveBlock1Ptr->mysteryGift.card;
+ if (card->type == CARD_TYPE_LINK_STAT)
{
- (*state)++;
+ struct WonderCardMetadata *metadata = &gSaveBlock1Ptr->mysteryGift.cardMetadata;
+ return metadata->battlesLost;
}
break;
- case 2:
- if (IsFanfareTaskInactive())
+ }
+ case CARD_STAT_NUM_TRADES:
+ {
+ struct WonderCard *card = &gSaveBlock1Ptr->mysteryGift.card;
+ if (card->type == CARD_TYPE_LINK_STAT)
{
- *state = 0;
- ClearTextWindow();
- return TRUE;
+ struct WonderCardMetadata *metadata = &gSaveBlock1Ptr->mysteryGift.cardMetadata;
+ return metadata->numTrades;
}
break;
}
- return FALSE;
-}
-
-static const u8 * mevent_message_stamp_card_etc_send_status(u32 * a0, u8 unused, u32 msgId)
-{
- const u8 * result = gText_CommunicationError;
- *a0 = 0;
- switch (msgId)
+ case CARD_STAT_NUM_STAMPS:
{
- case 0:
- result = gText_NothingSentOver;
- break;
- case 1:
- result = gText_RecordUploadedViaWireless;
- break;
- case 2:
- result = gText_WonderCardSentTo;
- *a0 = 1;
- break;
- case 3:
- result = gText_WonderNewsSentTo;
- *a0 = 1;
- break;
- case 4:
- result = gText_StampSentTo;
- break;
- case 5:
- result = gText_OtherTrainerHasCard;
- break;
- case 6:
- result = gText_OtherTrainerHasStamp;
- break;
- case 7:
- result = gText_OtherTrainerHasNews;
- break;
- case 8:
- result = gText_NoMoreRoomForStamps;
- break;
- case 9:
- result = gText_OtherTrainerCanceled;
- break;
- case 10:
- result = gText_CantSendGiftToTrainer;
- break;
- case 11:
- result = gText_CommunicationError;
- break;
- case 12:
- result = gText_GiftSentTo;
- break;
- case 13:
- result = gText_GiftSentTo;
- break;
- case 14:
- result = gText_CantSendGiftToTrainer;
+ struct WonderCard *card = &gSaveBlock1Ptr->mysteryGift.card;
+ if (card->type == CARD_TYPE_STAMP)
+ return GetNumStampsInSavedCard();
break;
}
- return result;
-}
-
-static bool32 PrintMGSendStatus(u8 * state, u16 * arg1, u8 arg2, u32 msgId)
-{
- u32 flag;
- const u8 * str = mevent_message_stamp_card_etc_send_status(&flag, arg2, msgId);
- if (flag)
+ case CARD_STAT_MAX_STAMPS:
{
- return PrintMGSuccessMessage(state, str, arg1);
+ struct WonderCard *card = &gSaveBlock1Ptr->mysteryGift.card;
+ if (card->type == CARD_TYPE_STAMP)
+ return card->maxStamps;
+ break;
}
- else
- {
- return MG_PrintTextOnWindow1AndWaitButton(state, str);
}
+
+ AGB_ASSERT(0);
+ return 0;
}
-void task_add_00_mystery_gift(void)
+void MysteryGift_DisableStats(void)
{
- u8 taskId = CreateTask(task00_mystery_gift, 0);
- struct MysteryGiftTaskData * data = (void *)gTasks[taskId].data;
- data->state = 0;
- 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);
+ sStatsEnabled = FALSE;
}
-void task00_mystery_gift(u8 taskId)
+bool32 MysteryGift_TryEnableStatsByFlagId(u16 flagId)
{
- struct MysteryGiftTaskData *data = (void *)gTasks[taskId].data;
- u32 sp0, flag;
- const u8 *r1;
+ sStatsEnabled = FALSE;
+ if (flagId == 0)
+ return FALSE;
+
+ if (!ValidateSavedWonderCard())
+ return FALSE;
+
+ if (gSaveBlock1Ptr->mysteryGift.card.flagId != flagId)
+ return FALSE;
- switch (data->state)
+ sStatsEnabled = TRUE;
+ return TRUE;
+}
+
+void MysteryGift_TryIncrementStat(u32 stat, u32 trainerId)
+{
+ if (sStatsEnabled)
{
- case 0:
- data->state = 1;
- break;
- case 1:
- switch (MysteryGift_HandleThreeOptionMenu(&data->textState, &data->curPromptWindowId, FALSE))
+ switch (stat)
{
- case 0:
- data->IsCardOrNews = 0;
- if (ValidateReceivedWonderCard() == TRUE)
- {
- data->state = 18;
- }
- else
- {
- data->state = 2;
- }
- break;
- case 1:
- data->IsCardOrNews = 1;
- if (ValidateReceivedWonderNews() == TRUE)
- {
- data->state = 18;
- }
- else
- {
- data->state = 2;
- }
- break;
- case -2u:
- data->state = 37;
+ case CARD_STAT_NUM_TRADES:
+ IncrementCardStatForNewTrainer(CARD_STAT_NUM_TRADES,
+ trainerId,
+ gSaveBlock1Ptr->mysteryGift.trainerIds[1],
+ ARRAY_COUNT(gSaveBlock1Ptr->mysteryGift.trainerIds[1]));
break;
- }
- break;
- case 2:
- {
- if (data->IsCardOrNews == 0)
- {
- if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, gText_DontHaveCardNewOneInput))
- {
- data->state = 3;
- PrintMysteryGiftOrEReaderTopMenu(0, 1);
- }
- }
- else
- {
- if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, gText_DontHaveNewsNewOneInput))
- {
- data->state = 3;
- PrintMysteryGiftOrEReaderTopMenu(0, 1);
- }
- }
- break;
- }
- case 3:
- if (data->IsCardOrNews == 0)
- {
- AddTextPrinterToWindow1(gText_WhereShouldCardBeAccessed);
- }
- else
- {
- AddTextPrinterToWindow1(gText_WhereShouldNewsBeAccessed);
- }
- data->state = 4;
- break;
- case 4:
- switch (MysteryGift_HandleThreeOptionMenu(&data->textState, &data->curPromptWindowId, TRUE))
- {
- case 0:
- ClearTextWindow();
- data->state = 5;
- data->source = 0;
+ case CARD_STAT_BATTLES_WON:
+ IncrementCardStatForNewTrainer(CARD_STAT_BATTLES_WON,
+ trainerId,
+ gSaveBlock1Ptr->mysteryGift.trainerIds[0],
+ ARRAY_COUNT(gSaveBlock1Ptr->mysteryGift.trainerIds[0]));
break;
- case 1:
- ClearTextWindow();
- data->state = 5;
- data->source = 1;
+ case CARD_STAT_BATTLES_LOST:
+ IncrementCardStatForNewTrainer(CARD_STAT_BATTLES_LOST,
+ trainerId,
+ gSaveBlock1Ptr->mysteryGift.trainerIds[0],
+ ARRAY_COUNT(gSaveBlock1Ptr->mysteryGift.trainerIds[0]));
break;
- case -2u:
- ClearTextWindow();
- if (ValidateCardOrNews(data->IsCardOrNews))
- {
- data->state = 18;
- }
- else
- {
- data->state = 0;
- PrintMysteryGiftOrEReaderTopMenu(0, 0);
- }
+ default:
+ AGB_ASSERT(0);
break;
}
- break;
- case 5:
- *gStringVar1 = EOS;
- *gStringVar2 = EOS;
- *gStringVar3 = EOS;
+ }
+}
- switch (data->IsCardOrNews)
- {
- case 0:
- if (data->source == 1)
- {
- MEvent_CreateTask_CardOrNewsWithFriend(ACTIVITY_WONDER_CARD);
- }
- else if (data->source == 0)
- {
- MEvent_CreateTask_CardOrNewsOverWireless(ACTIVITY_WONDER_CARD);
- }
- break;
- case 1:
- if (data->source == 1)
- {
- MEvent_CreateTask_CardOrNewsWithFriend(ACTIVITY_WONDER_NEWS);
- }
- else if (data->source == 0)
- {
- MEvent_CreateTask_CardOrNewsOverWireless(ACTIVITY_WONDER_NEWS);
- }
- break;
- }
- data->state = 6;
- break;
- case 6:
- if (gReceivedRemoteLinkPlayers != 0)
- {
- ClearScreenInBg0(TRUE);
- data->state = 7;
- mevent_client_do_init(data->IsCardOrNews);
- }
- else if (gSpecialVar_Result == LINKUP_FAILED)
- {
- ClearScreenInBg0(TRUE);
- data->state = 3;
- }
- break;
- case 7:
- AddTextPrinterToWindow1(gText_Communicating);
- data->state = 8;
- break;
- case 8:
- switch (mevent_client_do_exec(&data->curPromptWindowId))
- {
- case 6:
- Rfu_SetCloseLinkCallback();
- data->prevPromptWindowId = data->curPromptWindowId;
- data->state = 13;
- break;
- case 5:
- memcpy(data->buffer, mevent_client_get_buffer(), 0x40);
- mevent_client_inc_flag();
- break;
- case 3:
- data->state = 10;
- break;
- case 2:
- data->state = 9;
- break;
- case 4:
- data->state = 11;
- StringCopy(gStringVar1, gLinkPlayers[0].name);
- break;
- }
- break;
- case 9:
- flag = mevent_message_print_and_prompt_yes_no(&data->textState, &data->curPromptWindowId, FALSE, mevent_client_get_buffer());
- switch (flag)
- {
- case 0:
- mevent_client_set_param(0);
- mevent_client_inc_flag();
- data->state = 7;
- break;
- case 1:
- mevent_client_set_param(1);
- mevent_client_inc_flag();
- data->state = 7;
- break;
- case -1u:
- mevent_client_set_param(1);
- mevent_client_inc_flag();
- data->state = 7;
- break;
- }
- break;
- case 10:
- if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, mevent_client_get_buffer()))
- {
- mevent_client_inc_flag();
- data->state = 7;
- }
- break;
- case 11:
- flag = mevent_message_print_and_prompt_yes_no(&data->textState, &data->curPromptWindowId, FALSE, gText_ThrowAwayWonderCard);
- switch (flag)
- {
- case 0:
- if (CheckReceivedGiftFromWonderCard() == TRUE)
- {
- data->state = 12;
- }
- else
- {
- mevent_client_set_param(0);
- mevent_client_inc_flag();
- data->state = 7;
- }
- break;
- case 1:
- mevent_client_set_param(1);
- mevent_client_inc_flag();
- data->state = 7;
- break;
- case -1u:
- mevent_client_set_param(1);
- mevent_client_inc_flag();
- data->state = 7;
- break;
- }
- break;
- case 12:
- flag = mevent_message_print_and_prompt_yes_no(&data->textState, &data->curPromptWindowId, FALSE, gText_HaventReceivedCardsGift);
- switch (flag)
- {
- case 0:
- mevent_client_set_param(0);
- mevent_client_inc_flag();
- data->state = 7;
- break;
- case 1:
- mevent_client_set_param(1);
- mevent_client_inc_flag();
- data->state = 7;
- break;
- case -1u:
- mevent_client_set_param(1);
- mevent_client_inc_flag();
- data->state = 7;
- break;
- }
- break;
- case 13:
- if (gReceivedRemoteLinkPlayers == 0)
- {
- DestroyWirelessStatusIndicatorSprite();
- data->state = 14;
- }
- break;
- case 14:
- if (PrintStringAndWait2Seconds(&data->textState, gText_CommunicationCompleted))
- {
- if (data->source == 1)
- {
- StringCopy(gStringVar1, gLinkPlayers[0].name);
- }
- data->state = 15;
- }
- 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);
- }
- else
- {
- flag = MG_PrintTextOnWindow1AndWaitButton(&data->textState, r1);
- }
- if (flag)
- {
- if (data->prevPromptWindowId == 3)
- {
- if (data->source == 1)
- {
- GenerateRandomNews(1);
- }
- else
- {
- GenerateRandomNews(2);
- }
- }
- if (!sp0)
- {
- data->state = 0;
- PrintMysteryGiftOrEReaderTopMenu(0, 0);
- }
- else
- {
- data->state = 17;
- }
- }
- break;
- case 16:
- if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, gText_CommunicationError))
- {
- data->state = 0;
- PrintMysteryGiftOrEReaderTopMenu(0, 0);
- }
- break;
- case 17:
- if (mevent_save_game(&data->textState))
- {
- data->state = 18;
- }
- break;
- case 18:
- if (HandleLoadWonderCardOrNews(&data->textState, data->IsCardOrNews))
- {
- data->state = 20;
- }
- break;
- case 20:
- if (data->IsCardOrNews == 0)
- {
- if (({JOY_NEW(A_BUTTON);}))
- {
- data->state = 21;
- }
- if (({JOY_NEW(B_BUTTON);}))
- {
- data->state = 27;
- }
- }
- else
- {
- switch (MENews_GetInput(gMain.newKeys))
- {
- case 0:
- MENews_RemoveScrollIndicatorArrowPair();
- data->state = 21;
- break;
- case 1:
- data->state = 27;
- break;
- }
- }
- break;
- case 21:
+static void ClearSavedTrainerIds(void)
+{
+ CpuFill32(0, gSaveBlock1Ptr->mysteryGift.trainerIds, sizeof(gSaveBlock1Ptr->mysteryGift.trainerIds));
+}
+
+// Returns TRUE if it's a new trainer id, FALSE if an existing one.
+// In either case the given trainerId is saved in element 0
+static bool32 RecordTrainerId(u32 trainerId, u32 *trainerIds, int size)
+{
+ int i, j;
+
+ for (i = 0; i < size; i++)
{
- u32 result;
- if (data->IsCardOrNews == 0)
- {
- if (WonderCard_Test_Unk_08_6())
- {
- 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())
- {
- result = HandleMysteryGiftListMenu(&data->textState, &data->curPromptWindowId, data->IsCardOrNews, FALSE);
- }
- else
- {
- result = HandleMysteryGiftListMenu(&data->textState, &data->curPromptWindowId, data->IsCardOrNews, TRUE);
- }
- }
- switch (result)
- {
- case 0:
- data->state = 28;
- break;
- case 1:
- data->state = 29;
+ if (trainerIds[i] == trainerId)
break;
- case 2:
- data->state = 22;
- break;
- case -2u:
- if (data->IsCardOrNews == 1)
- {
- MENews_AddScrollIndicatorArrowPair();
- }
- data->state = 20;
- break;
- }
- break;
}
- case 22:
- switch (mevent_message_prompt_discard(&data->textState, &data->curPromptWindowId, data->IsCardOrNews))
- {
- case 0:
- if (data->IsCardOrNews == 0 && CheckReceivedGiftFromWonderCard() == TRUE)
- {
- data->state = 23;
- }
- else
- {
- data->state = 24;
- }
- break;
- case 1:
- data->state = 21;
- break;
- case -1:
- data->state = 21;
- break;
- }
- break;
- case 23:
- switch ((u32)mevent_message_print_and_prompt_yes_no(&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:
- MEvent_CreateTask_Leader(ACTIVITY_WONDER_CARD);
- break;
- case 1:
- MEvent_CreateTask_Leader(ACTIVITY_WONDER_NEWS);
- break;
- }
- data->source = 1;
- data->state = 30;
- }
- break;
- case 30:
- if (gReceivedRemoteLinkPlayers != 0)
- {
- ClearScreenInBg0(1);
- data->state = 31;
- }
- else if (gSpecialVar_Result == LINKUP_FAILED)
- {
- ClearScreenInBg0(1);
- data->state = 18;
- }
- break;
- case 31:
- *gStringVar1 = EOS;
- *gStringVar2 = EOS;
- *gStringVar3 = EOS;
- if (data->IsCardOrNews == 0)
- {
- AddTextPrinterToWindow1(gText_SendingWonderCard);
- mevent_srv_new_wcard();
- }
- else
- {
- AddTextPrinterToWindow1(gText_SendingWonderNews);
- mevent_srv_init_wnews();
- }
- data->state = 32;
- break;
- case 32:
- if (mevent_srv_common_do_exec(&data->curPromptWindowId) == 3)
- {
- data->prevPromptWindowId = data->curPromptWindowId;
- data->state = 33;
- }
- break;
- case 33:
- Rfu_SetCloseLinkCallback();
- StringCopy(gStringVar1, gLinkPlayers[1].name);
- data->state = 34;
- break;
- case 34:
- if (gReceivedRemoteLinkPlayers == 0)
- {
- DestroyWirelessStatusIndicatorSprite();
- data->state = 35;
- }
- break;
- case 35:
- if (PrintMGSendStatus(&data->textState, &data->curPromptWindowId, data->source, data->prevPromptWindowId))
- {
- if (data->source == 1 && data->prevPromptWindowId == 3)
- {
- GenerateRandomNews(3);
- data->state = 17;
- }
- else
- {
- data->state = 0;
- PrintMysteryGiftOrEReaderTopMenu(0, 0);
- }
- }
- break;
- case 36:
- if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, gText_CommunicationError))
- {
- data->state = 0;
- PrintMysteryGiftOrEReaderTopMenu(0, 0);
- }
- break;
- case 37:
- CloseLink();
- Free(data->buffer);
- DestroyTask(taskId);
- SetMainCallback2(MainCB_FreeAllBuffersAndReturnToInitTitleScreen);
- break;
+ if (i == size)
+ {
+ // 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--)
+ trainerIds[j] = trainerIds[j - 1];
-u16 GetMysteryGiftBaseBlock(void)
-{
- return 0x1A9;
+ trainerIds[0] = trainerId;
+ return FALSE;
+ }
}
-void bgid_upload_textbox_1(u8 bgId)
+static void IncrementCardStatForNewTrainer(u32 stat, u32 trainerId, u32 *trainerIds, int size)
{
- DecompressAndLoadBgGfxUsingHeap(bgId, gUnkTextboxBorderGfx, 0x100, 0, 0);
+ if (RecordTrainerId(trainerId, trainerIds, size))
+ IncrementCardStat(stat);
}
diff --git a/src/mystery_gift_client.c b/src/mystery_gift_client.c
new file mode 100644
index 000000000..adf3ce8a6
--- /dev/null
+++ b/src/mystery_gift_client.c
@@ -0,0 +1,303 @@
+#include "global.h"
+#include "malloc.h"
+#include "decompress.h"
+#include "overworld.h"
+#include "script.h"
+#include "battle_tower.h"
+#include "mystery_gift.h"
+#include "mystery_event_script.h"
+#include "mystery_gift_client.h"
+
+enum {
+ FUNC_INIT,
+ FUNC_DONE,
+ FUNC_RECV,
+ FUNC_SEND,
+ FUNC_RUN,
+ FUNC_WAIT,
+ FUNC_RUN_MEVENT,
+ FUNC_RUN_BUFFER,
+};
+
+EWRAM_DATA static struct MysteryGiftClient * sClient = NULL;
+
+static void MysteryGiftClient_Init(struct MysteryGiftClient *, u32, u32);
+static u32 MysteryGiftClient_CallFunc(struct MysteryGiftClient *);
+static void MysteryGiftClient_Free(struct MysteryGiftClient *);
+
+extern const struct MysteryGiftClientCmd gMysteryGiftClientScript_Init[];
+
+void MysteryGiftClient_Create(bool32 isWonderNews)
+{
+ sClient = AllocZeroed(sizeof(*sClient));
+ MysteryGiftClient_Init(sClient, 1, 0);
+ sClient->isWonderNews = isWonderNews;
+}
+
+u32 MysteryGiftClient_Run(u16 * endVal)
+{
+ u32 result;
+ if (sClient == NULL)
+ return CLI_RET_END;
+ result = MysteryGiftClient_CallFunc(sClient);
+ if (result == CLI_RET_END)
+ {
+ *endVal = sClient->param;
+ MysteryGiftClient_Free(sClient);
+ Free(sClient);
+ sClient = NULL;
+ }
+ return result;
+}
+
+void MysteryGiftClient_AdvanceState(void)
+{
+ sClient->funcState++;
+}
+
+void * MysteryGiftClient_GetMsg(void)
+{
+ return sClient->msg;
+}
+
+void MysteryGiftClient_SetParam(u32 val)
+{
+ sClient->param = val;
+}
+
+static void MysteryGiftClient_Init(struct MysteryGiftClient * client, u32 sendPlayerId, u32 recvPlayerId)
+{
+ 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 MysteryGiftClient_Free(struct MysteryGiftClient * client)
+{
+ Free(client->sendBuffer);
+ Free(client->recvBuffer);
+ Free(client->script);
+ Free(client->msg);
+}
+
+static void MysteryGiftClient_CopyRecvScript(struct MysteryGiftClient * client)
+{
+ memcpy(client->script, client->recvBuffer, MG_LINK_BUFFER_SIZE);
+ client->cmdidx = 0;
+}
+
+static void MysteryGiftClient_InitSendWord(struct MysteryGiftClient * client, u32 ident, u32 word)
+{
+ CpuFill32(0, client->sendBuffer, MG_LINK_BUFFER_SIZE);
+ *(u32 *)client->sendBuffer = word;
+ MysteryGiftLink_InitSend(&client->link, ident, client->sendBuffer, sizeof(word));
+}
+
+static u32 Client_Init(struct MysteryGiftClient * client)
+{
+ 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_Done(struct MysteryGiftClient * client)
+{
+ return CLI_RET_END;
+}
+
+
+static u32 Client_Recv(struct MysteryGiftClient * client)
+{
+ if (MysteryGiftLink_Recv(&client->link))
+ {
+ client->funcId = FUNC_RUN;
+ client->funcState = 0;
+ }
+ return CLI_RET_ACTIVE;
+}
+
+static u32 Client_Send(struct MysteryGiftClient * client)
+{
+ if (MysteryGiftLink_Send(&client->link))
+ {
+ client->funcId = FUNC_RUN;
+ client->funcState = 0;
+ }
+ return CLI_RET_ACTIVE;
+}
+
+static u32 Client_Run(struct MysteryGiftClient * client)
+{
+ // process command
+ struct MysteryGiftClientCmd * cmd = &client->script[client->cmdidx];
+ client->cmdidx++;
+ switch (cmd->instr)
+ {
+ case CLI_NONE:
+ break;
+ case CLI_RETURN:
+ client->param = cmd->parameter; // Set for endVal in MysteryGiftClient_Run
+ client->funcId = FUNC_DONE;
+ client->funcState = 0;
+ break;
+ case CLI_RECV:
+ MysteryGiftLink_InitRecv(&client->link, cmd->parameter, client->recvBuffer);
+ client->funcId = FUNC_RECV;
+ client->funcState = 0;
+ break;
+ case CLI_SEND_LOADED:
+ // Send without a MysteryGiftLink_InitSend
+ // Sends whatever has been loaded already
+ client->funcId = FUNC_SEND;
+ client->funcState = 0;
+ break;
+ case CLI_SEND_READY_END:
+ MysteryGiftLink_InitSend(&client->link, MG_LINKID_READY_END, client->sendBuffer, 0);
+ client->funcId = FUNC_SEND;
+ client->funcState = 0;
+ break;
+ case CLI_SEND_STAT:
+ MysteryGiftClient_InitSendWord(client, MG_LINKID_GAME_STAT, GetGameStat(cmd->parameter));
+ client->funcId = FUNC_SEND;
+ client->funcState = 0;
+ break;
+ case CLI_COPY_RECV_IF_N:
+ if (client->param == FALSE)
+ MysteryGiftClient_CopyRecvScript(client);
+ break;
+ case CLI_COPY_RECV_IF:
+ if (client->param == TRUE)
+ MysteryGiftClient_CopyRecvScript(client);
+ break;
+ case CLI_COPY_RECV:
+ MysteryGiftClient_CopyRecvScript(client);
+ break;
+ 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, client->isWonderNews);
+ MysteryGiftLink_InitSend(&client->link, MG_LINKID_GAME_DATA, client->sendBuffer, sizeof(struct MysteryGiftLinkGameData));
+ break;
+ case CLI_LOAD_TOSS_RESPONSE:
+ // param here is set by MG_STATE_LINK_ASK_TOSS or MG_STATE_LINK_ASK_TOSS_UNRECEIVED
+ MysteryGiftClient_InitSendWord(client, MG_LINKID_RESPONSE, client->param);
+ break;
+ case CLI_SAVE_CARD:
+ SaveWonderCard(client->recvBuffer);
+ break;
+ case CLI_SAVE_NEWS:
+ if (!IsWonderNewsSameAsSaved(client->recvBuffer))
+ {
+ SaveWonderNews(client->recvBuffer);
+ MysteryGiftClient_InitSendWord(client, MG_LINKID_RESPONSE, FALSE);
+ }
+ else
+ {
+ // Wonder News has already been saved (or is invalid).
+ // Prepare a signal to indicate it was not saved.
+ MysteryGiftClient_InitSendWord(client, MG_LINKID_RESPONSE, TRUE);
+ }
+ break;
+ case CLI_RUN_MEVENT_SCRIPT:
+ client->funcId = FUNC_RUN_MEVENT;
+ client->funcState = 0;
+ break;
+ case CLI_SAVE_STAMP:
+ MysteryGift_TrySaveStamp(client->recvBuffer);
+ break;
+ case CLI_SAVE_RAM_SCRIPT:
+ InitRamScript_NoObjectEvent(client->recvBuffer, 1000);
+ break;
+ case CLI_RECV_EREADER_TRAINER:
+ memcpy(&gSaveBlock2Ptr->frontier.ereaderTrainer, client->recvBuffer, sizeof(gSaveBlock2Ptr->frontier.ereaderTrainer));
+ ValidateEReaderTrainer();
+ break;
+ case CLI_RUN_BUFFER_SCRIPT:
+ memcpy(gDecompressionBuffer, client->recvBuffer, MG_LINK_BUFFER_SIZE);
+ client->funcId = FUNC_RUN_BUFFER;
+ client->funcState = 0;
+ break;
+ }
+
+ return CLI_RET_ACTIVE;
+}
+
+static u32 Client_Wait(struct MysteryGiftClient * client)
+{
+ if (client->funcState)
+ {
+ client->funcId = FUNC_RUN;
+ client->funcState = 0;
+ }
+ return CLI_RET_ACTIVE;
+}
+
+static u32 Client_RunMysteryEventScript(struct MysteryGiftClient * client)
+{
+ switch (client->funcState)
+ {
+ case 0:
+ InitMysteryEventScriptContext(client->recvBuffer);
+ client->funcState++;
+ break;
+ case 1:
+ if (!RunMysteryEventScriptContextCommand(&client->param))
+ {
+ client->funcId = FUNC_RUN;
+ client->funcState = 0;
+ }
+ break;
+ }
+ return CLI_RET_ACTIVE;
+}
+
+static u32 Client_RunBufferScript(struct MysteryGiftClient * client)
+{
+ // exec arbitrary code
+ u32 (*func)(u32 *, struct SaveBlock2 *, struct SaveBlock1 *) = (void *)gDecompressionBuffer;
+ if (func(&client->param, gSaveBlock2Ptr, gSaveBlock1Ptr) == 1)
+ {
+ client->funcId = FUNC_RUN;
+ client->funcState = 0;
+ }
+ return CLI_RET_ACTIVE;
+}
+
+static u32 MysteryGiftClient_CallFunc(struct MysteryGiftClient * client)
+{
+ 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[client->funcId](client);
+}
diff --git a/src/mystery_gift_link.c b/src/mystery_gift_link.c
new file mode 100644
index 000000000..55f4b7852
--- /dev/null
+++ b/src/mystery_gift_link.c
@@ -0,0 +1,222 @@
+#include "global.h"
+#include "malloc.h"
+#include "decompress.h"
+#include "util.h"
+#include "link.h"
+#include "link_rfu.h"
+#include "overworld.h"
+#include "script.h"
+#include "battle_tower.h"
+#include "mystery_event_script.h"
+#include "mystery_gift.h"
+#include "mystery_gift_link.h"
+
+/*
+ Handles the link connection functions used by the Mystery Gift client/server.
+ Note: MysteryGiftLink is shortened to MGL for internal functions.
+*/
+
+struct SendRecvHeader
+{
+ u16 ident;
+ u16 crc;
+ u16 size;
+};
+
+static u32 MGL_Receive(struct MysteryGiftLink *);
+static u32 MGL_Send(struct MysteryGiftLink *);
+
+u32 MysteryGiftLink_Recv(struct MysteryGiftLink * link)
+{
+ return link->recvFunc(link);
+}
+
+u32 MysteryGiftLink_Send(struct MysteryGiftLink * link)
+{
+ return link->sendFunc(link);
+}
+
+void MysteryGiftLink_Init(struct MysteryGiftLink * link, u32 sendPlayerId, u32 recvPlayerId)
+{
+ 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 MysteryGiftLink_InitSend(struct MysteryGiftLink * link, u32 ident, const void * src, u32 size)
+{
+ link->state = 0;
+ link->sendIdent = ident;
+ link->sendCounter = 0;
+ link->sendCRC = 0;
+ if (size != 0)
+ link->sendSize = size;
+ else
+ link->sendSize = MG_LINK_BUFFER_SIZE;
+ link->sendBuffer = src;
+}
+
+void MysteryGiftLink_InitRecv(struct MysteryGiftLink * link, u32 ident, void * dest)
+{
+ link->state = 0;
+ link->recvIdent = ident;
+ link->recvCounter = 0;
+ link->recvCRC = 0;
+ link->recvSize = 0;
+ link->recvBuffer = dest;
+}
+
+static void MGL_ReceiveBlock(u32 playerId, void * dest, size_t size)
+{
+ memcpy(dest, gBlockRecvBuffer[playerId], size);
+}
+
+static bool32 MGL_HasReceived(u32 playerId)
+{
+ if ((GetBlockReceivedStatus() >> playerId) & 1)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static void MGL_ResetReceived(u32 playerId)
+{
+ ResetBlockReceivedFlag(playerId);
+}
+
+static bool32 MGL_Receive(struct MysteryGiftLink * link)
+{
+ struct SendRecvHeader header;
+
+ switch (link->state)
+ {
+ case 0:
+ if (MGL_HasReceived(link->recvPlayerId))
+ {
+ MGL_ReceiveBlock(link->recvPlayerId, &header, sizeof(header));
+ link->recvSize = header.size;
+ link->recvCRC = header.crc;
+ if (link->recvSize > MG_LINK_BUFFER_SIZE)
+ {
+ LinkRfu_FatalError();
+ return FALSE;
+ }
+ else if (link->recvIdent != header.ident)
+ {
+ LinkRfu_FatalError();
+ return FALSE;
+ }
+ else
+ {
+ link->recvCounter = 0;
+ MGL_ResetReceived(link->recvPlayerId);
+ link->state++;
+ }
+ }
+ 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 MGL_Send(struct MysteryGiftLink * link)
+{
+ struct SendRecvHeader header;
+
+ switch (link->state)
+ {
+ 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))
+ {
+ size_t blocksize;
+ MGL_ResetReceived(link->sendPlayerId);
+ blocksize = 252 * link->sendCounter;
+ if (link->sendSize - blocksize <= 252)
+ {
+ 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(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_menu.c b/src/mystery_gift_menu.c
new file mode 100644
index 000000000..e1236adfd
--- /dev/null
+++ b/src/mystery_gift_menu.c
@@ -0,0 +1,1618 @@
+#include "global.h"
+#include "main.h"
+#include "text.h"
+#include "task.h"
+#include "malloc.h"
+#include "gpu_regs.h"
+#include "scanline_effect.h"
+#include "text_window.h"
+#include "bg.h"
+#include "window.h"
+#include "strings.h"
+#include "text_window.h"
+#include "menu.h"
+#include "palette.h"
+#include "constants/songs.h"
+#include "sound.h"
+#include "mystery_gift_menu.h"
+#include "union_room.h"
+#include "title_screen.h"
+#include "ereader_screen.h"
+#include "international_string_util.h"
+#include "list_menu.h"
+#include "string_util.h"
+#include "mystery_gift.h"
+#include "mystery_gift_view.h"
+#include "save.h"
+#include "link.h"
+#include "mystery_gift_client.h"
+#include "mystery_gift_server.h"
+#include "event_data.h"
+#include "link_rfu.h"
+#include "wonder_news.h"
+#include "constants/cable_club.h"
+
+#define LIST_MENU_TILE_NUM 10
+#define LIST_MENU_PAL_NUM 224
+
+static void LoadMysteryGiftTextboxBorder(u8 bgId);
+static void CreateMysteryGiftTask(void);
+static void Task_MysteryGift(u8 taskId);
+
+EWRAM_DATA static u8 sDownArrowCounterAndYCoordIdx[8] = {};
+EWRAM_DATA bool8 gGiftIsFromEReader = FALSE;
+
+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
+{
+ u16 var; // Multipurpose
+ u16 unused1;
+ u16 unused2;
+ u16 unused3;
+ u8 state;
+ u8 textState;
+ u8 unused4;
+ u8 unused5;
+ bool8 isWonderNews;
+ bool8 sourceIsFriend;
+ u8 msgId;
+ u8 * clientMsg;
+};
+
+static const struct BgTemplate sBGTemplates[] = {
+ {
+ .bg = 0,
+ .charBaseIndex = 2,
+ .mapBaseIndex = 15,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 0,
+ .baseTile = 0x000
+ }, {
+ .bg = 1,
+ .charBaseIndex = 0,
+ .mapBaseIndex = 14,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 1,
+ .baseTile = 0x000
+ }, {
+ .bg = 2,
+ .charBaseIndex = 0,
+ .mapBaseIndex = 13,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 2,
+ .baseTile = 0x000
+ }, {
+ .bg = 3,
+ .charBaseIndex = 0,
+ .mapBaseIndex = 12,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 3,
+ .baseTile = 0x000
+ }
+};
+
+static const struct WindowTemplate sMainWindows[] = {
+ {
+ .bg = 0,
+ .tilemapLeft = 0,
+ .tilemapTop = 0,
+ .width = 30,
+ .height = 2,
+ .paletteNum = 12,
+ .baseBlock = 0x0013
+ }, {
+ .bg = 0,
+ .tilemapLeft = 1,
+ .tilemapTop = 15,
+ .width = 28,
+ .height = 4,
+ .paletteNum = 12,
+ .baseBlock = 0x004f
+ }, {
+ .bg = 0,
+ .tilemapLeft = 0,
+ .tilemapTop = 15,
+ .width = 30,
+ .height = 5,
+ .paletteNum = 13,
+ .baseBlock = 0x004f
+ },
+ DUMMY_WIN_TEMPLATE
+};
+
+static const struct WindowTemplate sWindowTemplate_YesNoMsg_Wide = {
+ .bg = 0,
+ .tilemapLeft = 1,
+ .tilemapTop = 15,
+ .width = 28,
+ .height = 4,
+ .paletteNum = 12,
+ .baseBlock = 0x00e5
+};
+
+static const struct WindowTemplate sWindowTemplate_YesNoMsg = {
+ .bg = 0,
+ .tilemapLeft = 1,
+ .tilemapTop = 15,
+ .width = 20,
+ .height = 4,
+ .paletteNum = 12,
+ .baseBlock = 0x00e5
+};
+
+static const struct WindowTemplate sWindowTemplate_GiftSelect = {
+ .bg = 0,
+ .tilemapLeft = 1,
+ .tilemapTop = 15,
+ .width = 19,
+ .height = 4,
+ .paletteNum = 12,
+ .baseBlock = 0x00e5
+};
+
+static const struct WindowTemplate sWindowTemplate_ThreeOptions = {
+ .bg = 0,
+ .tilemapLeft = 8,
+ .tilemapTop = 6,
+ .width = 14,
+ .height = 6,
+ .paletteNum = 12,
+ .baseBlock = 0x0155
+};
+
+static const struct WindowTemplate sWindowTemplate_YesNoBox = {
+ .bg = 0,
+ .tilemapLeft = 23,
+ .tilemapTop = 15,
+ .width = 6,
+ .height = 4,
+ .paletteNum = 12,
+ .baseBlock = 0x0155
+};
+
+static const struct WindowTemplate sWindowTemplate_GiftSelect_3Options = {
+ .bg = 0,
+ .tilemapLeft = 22,
+ .tilemapTop = 11,
+ .width = 7,
+ .height = 8,
+ .paletteNum = 12,
+ .baseBlock = 0x0155
+};
+
+static const struct WindowTemplate sWindowTemplate_GiftSelect_2Options = {
+ .bg = 0,
+ .tilemapLeft = 22,
+ .tilemapTop = 13,
+ .width = 7,
+ .height = 6,
+ .paletteNum = 12,
+ .baseBlock = 0x0155
+};
+
+static const struct WindowTemplate sWindowTemplate_GiftSelect_1Option = {
+ .bg = 0,
+ .tilemapLeft = 22,
+ .tilemapTop = 15,
+ .width = 7,
+ .height = 4,
+ .paletteNum = 12,
+ .baseBlock = 0x0155
+};
+
+static const struct ListMenuItem sListMenuItems_CardsOrNews[] = {
+ { gText_WonderCards, 0 },
+ { gText_WonderNews, 1 },
+ { gText_Exit3, LIST_CANCEL }
+};
+
+static const struct ListMenuItem sListMenuItems_WirelessOrFriend[] = {
+ { gText_WirelessCommunication, 0 },
+ { gText_Friend2, 1 },
+ { gText_Cancel2, LIST_CANCEL }
+};
+
+static const struct ListMenuTemplate sListMenuTemplate_ThreeOptions = {
+ .items = NULL,
+ .moveCursorFunc = ListMenuDefaultCursorMoveFunc,
+ .itemPrintFunc = NULL,
+ .totalItems = 3,
+ .maxShowed = 3,
+ .windowId = 0,
+ .header_X = 0,
+ .item_X = 8,
+ .cursor_X = 0,
+ .upText_Y = 1,
+ .cursorPal = 2,
+ .fillValue = 1,
+ .cursorShadowPal = 3,
+ .lettersSpacing = 0,
+ .itemVerticalPadding = 0,
+ .scrollMultiple = 0,
+ .fontId = 1,
+ .cursorKind = 0
+};
+
+static const struct ListMenuItem sListMenuItems_ReceiveSendToss[] = {
+ { gText_Receive, 0 },
+ { gText_Send, 1 },
+ { gText_Toss, 2 },
+ { gText_Cancel2, LIST_CANCEL }
+};
+
+static const struct ListMenuItem sListMenuItems_ReceiveToss[] = {
+ { gText_Receive, 0 },
+ { gText_Toss, 2 },
+ { gText_Cancel2, LIST_CANCEL }
+};
+
+static const struct ListMenuItem sListMenuItems_ReceiveSend[] = {
+ { gText_Receive, 0 },
+ { gText_Send, 1 },
+ { gText_Cancel2, LIST_CANCEL }
+};
+
+static const struct ListMenuItem sListMenuItems_Receive[] = {
+ { gText_Receive, 0 },
+ { gText_Cancel2, LIST_CANCEL }
+};
+
+static const struct ListMenuTemplate sListMenu_ReceiveSendToss = {
+ .items = sListMenuItems_ReceiveSendToss,
+ .moveCursorFunc = ListMenuDefaultCursorMoveFunc,
+ .itemPrintFunc = NULL,
+ .totalItems = 4,
+ .maxShowed = 4,
+ .windowId = 0,
+ .header_X = 0,
+ .item_X = 8,
+ .cursor_X = 0,
+ .upText_Y = 1,
+ .cursorPal = 2,
+ .fillValue = 1,
+ .cursorShadowPal = 3,
+ .lettersSpacing = 0,
+ .itemVerticalPadding = 0,
+ .scrollMultiple = 0,
+ .fontId = 1,
+ .cursorKind = 0
+};
+
+static const struct ListMenuTemplate sListMenu_ReceiveToss = {
+ .items = sListMenuItems_ReceiveToss,
+ .moveCursorFunc = ListMenuDefaultCursorMoveFunc,
+ .itemPrintFunc = NULL,
+ .totalItems = 3,
+ .maxShowed = 3,
+ .windowId = 0,
+ .header_X = 0,
+ .item_X = 8,
+ .cursor_X = 0,
+ .upText_Y = 1,
+ .cursorPal = 2,
+ .fillValue = 1,
+ .cursorShadowPal = 3,
+ .lettersSpacing = 0,
+ .itemVerticalPadding = 0,
+ .scrollMultiple = 0,
+ .fontId = 1,
+ .cursorKind = 0
+};
+
+static const struct ListMenuTemplate sListMenu_ReceiveSend = {
+ .items = sListMenuItems_ReceiveSend,
+ .moveCursorFunc = ListMenuDefaultCursorMoveFunc,
+ .itemPrintFunc = NULL,
+ .totalItems = 3,
+ .maxShowed = 3,
+ .windowId = 0,
+ .header_X = 0,
+ .item_X = 8,
+ .cursor_X = 0,
+ .upText_Y = 1,
+ .cursorPal = 2,
+ .fillValue = 1,
+ .cursorShadowPal = 3,
+ .lettersSpacing = 0,
+ .itemVerticalPadding = 0,
+ .scrollMultiple = 0,
+ .fontId = 1,
+ .cursorKind = 0
+};
+
+static const struct ListMenuTemplate sListMenu_Receive = {
+ .items = sListMenuItems_Receive,
+ .moveCursorFunc = ListMenuDefaultCursorMoveFunc,
+ .itemPrintFunc = NULL,
+ .totalItems = 2,
+ .maxShowed = 2,
+ .windowId = 0,
+ .header_X = 0,
+ .item_X = 8,
+ .cursor_X = 0,
+ .upText_Y = 1,
+ .cursorPal = 2,
+ .fillValue = 1,
+ .cursorShadowPal = 3,
+ .lettersSpacing = 0,
+ .itemVerticalPadding = 0,
+ .scrollMultiple = 0,
+ .fontId = 1,
+ .cursorKind = 0
+};
+
+static const u8 *const Unref_082F0710[] = {
+ gText_VarietyOfEventsImportedWireless,
+ gText_WonderCardsInPossession,
+ gText_ReadNewsThatArrived,
+ gText_ReturnToTitle
+};
+
+ALIGNED(2) static const u8 sTextColors_TopMenu[] = { TEXT_COLOR_TRANSPARENT, TEXT_COLOR_WHITE, TEXT_COLOR_DARK_GRAY };
+ALIGNED(2) static const u8 sTextColors_TopMenu_Copy[] = { TEXT_COLOR_TRANSPARENT, TEXT_COLOR_WHITE, TEXT_COLOR_DARK_GRAY };
+ALIGNED(2) static const u8 sMG_Ereader_TextColor_2[] = { TEXT_COLOR_WHITE, TEXT_COLOR_DARK_GRAY, TEXT_COLOR_LIGHT_GRAY };
+
+static void VBlankCB_MysteryGiftEReader(void)
+{
+ ProcessSpriteCopyRequests();
+ LoadOam();
+ TransferPlttBuffer();
+}
+
+void CB2_MysteryGiftEReader(void)
+{
+ RunTasks();
+ RunTextPrinters();
+ AnimateSprites();
+ BuildOamBuffer();
+}
+
+static bool32 HandleMysteryGiftOrEReaderSetup(s32 isEReader)
+{
+ switch (gMain.state)
+ {
+ case 0:
+ SetVBlankCallback(NULL);
+ ResetPaletteFade();
+ ResetSpriteData();
+ FreeAllSpritePalettes();
+ ResetTasks();
+ ScanlineEffect_Stop();
+ ResetBgsAndClearDma3BusyFlags(0);
+
+ InitBgsFromTemplates(0, sBGTemplates, ARRAY_COUNT(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);
+
+ SetBgTilemapBuffer(3, Alloc(BG_SCREEN_SIZE));
+ SetBgTilemapBuffer(2, Alloc(BG_SCREEN_SIZE));
+ SetBgTilemapBuffer(1, Alloc(BG_SCREEN_SIZE));
+ SetBgTilemapBuffer(0, Alloc(BG_SCREEN_SIZE));
+
+ LoadMysteryGiftTextboxBorder(3);
+ InitWindows(sMainWindows);
+ DeactivateAllTextPrinters();
+ ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON | DISPCNT_WIN1_ON);
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ SetGpuReg(REG_OFFSET_BLDY, 0);
+ gMain.state++;
+ break;
+ case 1:
+ LoadPalette(sTextboxBorder_Pal, 0, 0x20);
+ LoadPalette(GetTextWindowPalette(2), 0xd0, 0x20);
+ Menu_LoadStdPalAt(0xC0);
+ LoadUserWindowBorderGfx(0, 0xA, 0xE0);
+ LoadUserWindowBorderGfx_(0, 0x1, 0xF0);
+ 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(3);
+ PrintMysteryGiftOrEReaderTopMenu(isEReader, FALSE);
+ gMain.state++;
+ break;
+ case 2:
+ CopyBgTilemapBufferToVram(3);
+ CopyBgTilemapBufferToVram(2);
+ CopyBgTilemapBufferToVram(1);
+ CopyBgTilemapBufferToVram(0);
+ gMain.state++;
+ break;
+ case 3:
+ ShowBg(0);
+ ShowBg(3);
+ PlayBGM(MUS_RG_MYSTERY_GIFT);
+ SetVBlankCallback(VBlankCB_MysteryGiftEReader);
+ EnableInterrupts(INTR_FLAG_VBLANK | INTR_FLAG_VCOUNT | INTR_FLAG_TIMER3 | INTR_FLAG_SERIAL);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void CB2_InitMysteryGift(void)
+{
+ if (HandleMysteryGiftOrEReaderSetup(FALSE))
+ {
+ SetMainCallback2(CB2_MysteryGiftEReader);
+ gGiftIsFromEReader = FALSE;
+ CreateMysteryGiftTask();
+ }
+ RunTasks();
+}
+
+void CB2_InitEReader(void)
+{
+ if (HandleMysteryGiftOrEReaderSetup(TRUE))
+ {
+ SetMainCallback2(CB2_MysteryGiftEReader);
+ gGiftIsFromEReader = TRUE;
+ CreateEReaderTask();
+ }
+}
+
+void MainCB_FreeAllBuffersAndReturnToInitTitleScreen(void)
+{
+ gGiftIsFromEReader = FALSE;
+ FreeAllWindowBuffers();
+ Free(GetBgTilemapBuffer(0));
+ Free(GetBgTilemapBuffer(1));
+ Free(GetBgTilemapBuffer(2));
+ Free(GetBgTilemapBuffer(3));
+ SetMainCallback2(CB2_InitTitleScreen);
+}
+
+void PrintMysteryGiftOrEReaderTopMenu(bool8 isEReader, bool32 useCancel)
+{
+ const u8 * header;
+ const u8 * options;
+ FillWindowPixelBuffer(0, 0);
+ if (!isEReader)
+ {
+ header = gText_MysteryGift;
+ options = !useCancel ? gText_PickOKExit : gText_PickOKCancel;
+ }
+ else
+ {
+ header = gJPText_MysteryGift;
+ options = gJPText_DecideStop;
+ }
+
+ AddTextPrinterParameterized4(0, 1, 4, 1, 0, 0, sTextColors_TopMenu, TEXT_SPEED_FF, header);
+ AddTextPrinterParameterized4(0, 0, GetStringRightAlignXOffset(0, options, 0xDE), 1, 0, 0, sTextColors_TopMenu, TEXT_SPEED_FF, options);
+ CopyWindowToVram(0, 2);
+ PutWindowTilemap(0);
+}
+
+void MG_DrawTextBorder(u8 windowId)
+{
+ DrawTextBorderOuter(windowId, 0x01, 0xF);
+}
+
+void MG_DrawCheckerboardPattern(u32 bg)
+{
+ s32 i = 0, j;
+
+ FillBgTilemapBufferRect(bg, 0x003, 0, 0, 32, 2, 0x11);
+
+ for (i = 0; i < 18; i++)
+ {
+ for (j = 0; j < 32; j++)
+ {
+ if ((i & 1) != (j & 1))
+ FillBgTilemapBufferRect(bg, 1, j, i + 2, 1, 1, 0x11);
+ else
+ FillBgTilemapBufferRect(bg, 2, j, i + 2, 1, 1, 0x11);
+ }
+ }
+}
+
+static void ClearScreenInBg0(bool32 ignoreTopTwoRows)
+{
+ switch (ignoreTopTwoRows)
+ {
+ case 0:
+ FillBgTilemapBufferRect(0, 0, 0, 0, 32, 32, 0x11);
+ break;
+ case 1:
+ FillBgTilemapBufferRect(0, 0, 0, 2, 32, 30, 0x11);
+ break;
+ }
+ CopyBgTilemapBufferToVram(0);
+}
+
+void AddTextPrinterToWindow1(const u8 *str)
+{
+ StringExpandPlaceholders(gStringVar4, str);
+ FillWindowPixelBuffer(1, 0x11);
+ AddTextPrinterParameterized4(1, 1, 0, 1, 0, 0, sMG_Ereader_TextColor_2, 0, gStringVar4);
+ DrawTextBorderOuter(1, 0x001, 0xF);
+ PutWindowTilemap(1);
+ CopyWindowToVram(1, 3);
+}
+
+static void ClearTextWindow(void)
+{
+ rbox_fill_rectangle(1);
+ ClearWindowTilemap(1);
+ CopyWindowToVram(1, 1);
+}
+
+#define DOWN_ARROW_X 208
+#define DOWN_ARROW_Y 20
+
+bool32 PrintMysteryGiftMenuMessage(u8 *textState, const u8 *str)
+{
+ switch (*textState)
+ {
+ case 0:
+ AddTextPrinterToWindow1(str);
+ (*textState)++;
+ break;
+ case 1:
+ DrawDownArrow(1, DOWN_ARROW_X, DOWN_ARROW_Y, 1, FALSE, &sDownArrowCounterAndYCoordIdx[0], &sDownArrowCounterAndYCoordIdx[1]);
+ if (({JOY_NEW(A_BUTTON | B_BUTTON);}))
+ (*textState)++;
+ break;
+ case 2:
+ DrawDownArrow(1, DOWN_ARROW_X, DOWN_ARROW_Y, 1, TRUE, &sDownArrowCounterAndYCoordIdx[0], &sDownArrowCounterAndYCoordIdx[1]);
+ *textState = 0;
+ ClearTextWindow();
+ return TRUE;
+ case 0xFF:
+ *textState = 2;
+ return FALSE;
+ }
+ return FALSE;
+}
+
+static void HideDownArrow(void)
+{
+ DrawDownArrow(1, DOWN_ARROW_X, DOWN_ARROW_Y, 1, FALSE, &sDownArrowCounterAndYCoordIdx[0], &sDownArrowCounterAndYCoordIdx[1]);
+}
+
+static void ShowDownArrow(void)
+{
+ DrawDownArrow(1, DOWN_ARROW_X, DOWN_ARROW_Y, 1, TRUE, &sDownArrowCounterAndYCoordIdx[0], &sDownArrowCounterAndYCoordIdx[1]);
+}
+
+// Unused
+static bool32 HideDownArrowAndWaitButton(u8 * textState)
+{
+ switch (*textState)
+ {
+ case 0:
+ HideDownArrow();
+ if (JOY_NEW(A_BUTTON | B_BUTTON))
+ (*textState)++;
+ break;
+ case 1:
+ ShowDownArrow();
+ *textState = 0;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static bool32 PrintStringAndWait2Seconds(u8 * counter, const u8 * str)
+{
+ if (*counter == 0)
+ AddTextPrinterToWindow1(str);
+
+ if (++(*counter) > 120)
+ {
+ *counter = 0;
+ ClearTextWindow();
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+static u32 MysteryGift_HandleThreeOptionMenu(u8 * unused0, u16 * unused1, u8 whichMenu)
+{
+ struct ListMenuTemplate listMenuTemplate = sListMenuTemplate_ThreeOptions;
+ struct WindowTemplate windowTemplate = sWindowTemplate_ThreeOptions;
+ s32 width;
+ s32 response;
+
+ if (whichMenu == 0)
+ listMenuTemplate.items = sListMenuItems_CardsOrNews;
+ else
+ listMenuTemplate.items = sListMenuItems_WirelessOrFriend;
+
+ width = Intl_GetListMenuWidth(&listMenuTemplate);
+ if (width & 1)
+ width++;
+
+ windowTemplate.width = width;
+ if (width < 30)
+ windowTemplate.tilemapLeft = (30 - width) / 2;
+ else
+ windowTemplate.tilemapLeft = 0;
+
+ response = DoMysteryGiftListMenu(&windowTemplate, &listMenuTemplate, 1, LIST_MENU_TILE_NUM, LIST_MENU_PAL_NUM);
+ if (response != LIST_NOTHING_CHOSEN)
+ {
+ ClearWindowTilemap(2);
+ CopyWindowToVram(2, 1);
+ }
+ return response;
+}
+
+s8 DoMysteryGiftYesNo(u8 * textState, u16 * windowId, bool8 yesNoBoxPlacement, const u8 * str)
+{
+ struct WindowTemplate windowTemplate;
+ s8 input;
+
+ switch (*textState)
+ {
+ case 0:
+ // Print question message
+ StringExpandPlaceholders(gStringVar4, str);
+ if (yesNoBoxPlacement == 0)
+ *windowId = AddWindow(&sWindowTemplate_YesNoMsg_Wide);
+ else
+ *windowId = AddWindow(&sWindowTemplate_YesNoMsg);
+ FillWindowPixelBuffer(*windowId, 0x11);
+ AddTextPrinterParameterized4(*windowId, 1, 0, 1, 0, 0, sMG_Ereader_TextColor_2, 0, gStringVar4);
+ DrawTextBorderOuter(*windowId, 0x001, 0x0F);
+ CopyWindowToVram(*windowId, 2);
+ PutWindowTilemap(*windowId);
+ (*textState)++;
+ break;
+ case 1:
+ // Create Yes/No
+ windowTemplate = sWindowTemplate_YesNoBox;
+ if (yesNoBoxPlacement == 0)
+ windowTemplate.tilemapTop = 9;
+ else
+ windowTemplate.tilemapTop = 15;
+ CreateYesNoMenu(&windowTemplate, 10, 14, 0);
+ (*textState)++;
+ break;
+ case 2:
+ // Handle Yes/No input
+ input = Menu_ProcessInputNoWrapClearOnChoose();
+ if (input == MENU_B_PRESSED || input == 0 || input == 1)
+ {
+ *textState = 0;
+ rbox_fill_rectangle(*windowId);
+ ClearWindowTilemap(*windowId);
+ CopyWindowToVram(*windowId, 1);
+ RemoveWindow(*windowId);
+ return input;
+ }
+ break;
+ case 0xFF:
+ *textState = 0;
+ rbox_fill_rectangle(*windowId);
+ ClearWindowTilemap(*windowId);
+ CopyWindowToVram(*windowId, 1);
+ RemoveWindow(*windowId);
+ return MENU_B_PRESSED;
+ }
+
+ return MENU_NOTHING_CHOSEN;
+}
+
+// Handle the "Receive/Send/Toss" menu that appears when selecting Wonder Card/News
+static s32 HandleGiftSelectMenu(u8 * textState, u16 * windowId, bool32 cannotToss, bool32 cannotSend)
+{
+ struct WindowTemplate windowTemplate;
+ s32 input;
+
+ switch (*textState)
+ {
+ case 0:
+ // Print menu message
+ if (!cannotToss)
+ StringExpandPlaceholders(gStringVar4, gText_WhatToDoWithCards);
+ else
+ StringExpandPlaceholders(gStringVar4, gText_WhatToDoWithNews);
+ *windowId = AddWindow(&sWindowTemplate_GiftSelect);
+ FillWindowPixelBuffer(*windowId, 0x11);
+ AddTextPrinterParameterized4(*windowId, 1, 0, 1, 0, 0, sMG_Ereader_TextColor_2, 0, gStringVar4);
+ DrawTextBorderOuter(*windowId, 0x001, 0x0F);
+ CopyWindowToVram(*windowId, 2);
+ PutWindowTilemap(*windowId);
+ (*textState)++;
+ break;
+ case 1:
+ windowTemplate = sWindowTemplate_YesNoBox;
+ if (cannotSend)
+ {
+ if (!cannotToss)
+ input = DoMysteryGiftListMenu(&sWindowTemplate_GiftSelect_2Options, &sListMenu_ReceiveToss, 1, LIST_MENU_TILE_NUM, LIST_MENU_PAL_NUM);
+ else
+ input = DoMysteryGiftListMenu(&sWindowTemplate_GiftSelect_1Option, &sListMenu_Receive, 1, LIST_MENU_TILE_NUM, LIST_MENU_PAL_NUM);
+ }
+ else
+ {
+ if (!cannotToss)
+ input = DoMysteryGiftListMenu(&sWindowTemplate_GiftSelect_3Options, &sListMenu_ReceiveSendToss, 1, LIST_MENU_TILE_NUM, LIST_MENU_PAL_NUM);
+ else
+ input = DoMysteryGiftListMenu(&sWindowTemplate_GiftSelect_2Options, &sListMenu_ReceiveSend, 1, LIST_MENU_TILE_NUM, LIST_MENU_PAL_NUM);
+ }
+ if (input != LIST_NOTHING_CHOSEN)
+ {
+ *textState = 0;
+ rbox_fill_rectangle(*windowId);
+ ClearWindowTilemap(*windowId);
+ CopyWindowToVram(*windowId, 1);
+ RemoveWindow(*windowId);
+ return input;
+ }
+ break;
+ case 0xFF:
+ *textState = 0;
+ rbox_fill_rectangle(*windowId);
+ ClearWindowTilemap(*windowId);
+ CopyWindowToVram(*windowId, 1);
+ RemoveWindow(*windowId);
+ return LIST_CANCEL;
+ }
+
+ return LIST_NOTHING_CHOSEN;
+}
+
+static bool32 ValidateCardOrNews(bool32 isWonderNews)
+{
+ if (!isWonderNews)
+ return ValidateSavedWonderCard();
+ else
+ return ValidateSavedWonderNews();
+}
+
+static bool32 HandleLoadWonderCardOrNews(u8 * state, bool32 isWonderNews)
+{
+ switch (*state)
+ {
+ case 0:
+ if (!isWonderNews)
+ WonderCard_Init(GetSavedWonderCard(), GetSavedWonderCardMetadata());
+ else
+ WonderNews_Init(GetSavedWonderNews());
+ (*state)++;
+ break;
+ case 1:
+ if (!isWonderNews)
+ {
+ if (!WonderCard_Enter())
+ return FALSE;
+ }
+ else
+ {
+ if (!WonderNews_Enter())
+ return FALSE;
+ }
+ *state = 0;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static bool32 ClearSavedNewsOrCard(bool32 isWonderNews)
+{
+ if (!isWonderNews)
+ ClearSavedWonderCardAndRelated();
+ else
+ ClearSavedWonderNewsAndRelated();
+ return TRUE;
+}
+
+static bool32 ExitWonderCardOrNews(bool32 isWonderNews, bool32 useCancel)
+{
+ if (!isWonderNews)
+ {
+ if (WonderCard_Exit(useCancel))
+ {
+ WonderCard_Destroy();
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+ }
+ else
+ {
+ if (WonderNews_Exit(useCancel))
+ {
+ WonderNews_Destroy();
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+ }
+}
+
+static s32 AskDiscardGift(u8 * textState, u16 * windowId, bool32 isWonderNews)
+{
+ if (!isWonderNews)
+ return DoMysteryGiftYesNo(textState, windowId, TRUE, gText_IfThrowAwayCardEventWontHappen);
+ else
+ return DoMysteryGiftYesNo(textState, windowId, TRUE, gText_OkayToDiscardNews);
+}
+
+static bool32 PrintThrownAway(u8 * textState, bool32 isWonderNews)
+{
+ if (!isWonderNews)
+ return PrintMysteryGiftMenuMessage(textState, gText_WonderCardThrownAway);
+ else
+ return PrintMysteryGiftMenuMessage(textState, gText_WonderNewsThrownAway);
+}
+
+static bool32 SaveOnMysteryGiftMenu(u8 * state)
+{
+ switch (*state)
+ {
+ case 0:
+ AddTextPrinterToWindow1(gText_DataWillBeSaved);
+ (*state)++;
+ break;
+ case 1:
+ TrySavingData(SAVE_NORMAL);
+ (*state)++;
+ break;
+ case 2:
+ AddTextPrinterToWindow1(gText_SaveCompletedPressA);
+ (*state)++;
+ break;
+ case 3:
+ if (JOY_NEW(A_BUTTON | B_BUTTON))
+ (*state)++;
+ break;
+ case 4:
+ *state = 0;
+ ClearTextWindow();
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static const u8 * GetClientResultMessage(bool32 * successMsg, bool8 isWonderNews, bool8 sourceIsFriend, u32 msgId)
+{
+ const u8 * msg = NULL;
+ *successMsg = FALSE;
+
+ switch (msgId)
+ {
+ case CLI_MSG_NOTHING_SENT:
+ *successMsg = FALSE;
+ msg = gText_NothingSentOver;
+ break;
+ case CLI_MSG_RECORD_UPLOADED:
+ *successMsg = FALSE;
+ msg = gText_RecordUploadedViaWireless;
+ break;
+ case CLI_MSG_CARD_RECEIVED:
+ *successMsg = TRUE;
+ msg = !sourceIsFriend ? gText_WonderCardReceived : gText_WonderCardReceivedFrom;
+ break;
+ case CLI_MSG_NEWS_RECEIVED:
+ *successMsg = TRUE;
+ msg = !sourceIsFriend ? gText_WonderNewsReceived : gText_WonderNewsReceivedFrom;
+ break;
+ case CLI_MSG_STAMP_RECEIVED:
+ *successMsg = TRUE;
+ msg = gText_NewStampReceived;
+ break;
+ case CLI_MSG_HAD_CARD:
+ *successMsg = FALSE;
+ msg = gText_AlreadyHadCard;
+ break;
+ case CLI_MSG_HAD_STAMP:
+ *successMsg = FALSE;
+ msg = gText_AlreadyHadStamp;
+ break;
+ case CLI_MSG_HAD_NEWS:
+ *successMsg = FALSE;
+ msg = gText_AlreadyHadNews;
+ break;
+ case CLI_MSG_NO_ROOM_STAMPS:
+ *successMsg = FALSE;
+ msg = gText_NoMoreRoomForStamps;
+ break;
+ case CLI_MSG_COMM_CANCELED:
+ *successMsg = FALSE;
+ msg = gText_CommunicationCanceled;
+ break;
+ case CLI_MSG_CANT_ACCEPT:
+ *successMsg = FALSE;
+ msg = !isWonderNews ? gText_CantAcceptCardFromTrainer : gText_CantAcceptNewsFromTrainer;
+ break;
+ case CLI_MSG_COMM_ERROR:
+ *successMsg = FALSE;
+ msg = gText_CommunicationError;
+ break;
+ case CLI_MSG_TRAINER_RECEIVED:
+ *successMsg = TRUE;
+ msg = gText_NewTrainerReceived;
+ break;
+ case CLI_MSG_BUFFER_SUCCESS:
+ *successMsg = TRUE;
+ // msg is NULL, use buffer
+ break;
+ case CLI_MSG_BUFFER_FAILURE:
+ *successMsg = FALSE;
+ // msg is NULL, use buffer
+ break;
+ }
+
+ return msg;
+}
+
+static bool32 PrintSuccessMessage(u8 * state, const u8 * msg, u16 * timer)
+{
+ switch (*state)
+ {
+ case 0:
+ if (msg != NULL)
+ AddTextPrinterToWindow1(msg);
+ PlayFanfare(MUS_OBTAIN_ITEM);
+ *timer = 0;
+ (*state)++;
+ break;
+ case 1:
+ if (++(*timer) > 240)
+ (*state)++;
+ break;
+ case 2:
+ if (IsFanfareTaskInactive())
+ {
+ *state = 0;
+ ClearTextWindow();
+ return TRUE;
+ }
+ break;
+ }
+ return FALSE;
+}
+
+static const u8 * GetServerResultMessage(bool32 * wonderSuccess, bool8 sourceIsFriend, u32 msgId)
+{
+ const u8 * result = gText_CommunicationError;
+ *wonderSuccess = FALSE;
+ switch (msgId)
+ {
+ case SVR_MSG_NOTHING_SENT:
+ result = gText_NothingSentOver;
+ break;
+ case SVR_MSG_RECORD_UPLOADED:
+ result = gText_RecordUploadedViaWireless;
+ break;
+ case SVR_MSG_CARD_SENT:
+ result = gText_WonderCardSentTo;
+ *wonderSuccess = TRUE;
+ break;
+ case SVR_MSG_NEWS_SENT:
+ result = gText_WonderNewsSentTo;
+ *wonderSuccess = TRUE;
+ break;
+ case SVR_MSG_STAMP_SENT:
+ result = gText_StampSentTo;
+ break;
+ case SVR_MSG_HAS_CARD:
+ result = gText_OtherTrainerHasCard;
+ break;
+ case SVR_MSG_HAS_STAMP:
+ result = gText_OtherTrainerHasStamp;
+ break;
+ case SVR_MSG_HAS_NEWS:
+ result = gText_OtherTrainerHasNews;
+ break;
+ case SVR_MSG_NO_ROOM_STAMPS:
+ result = gText_NoMoreRoomForStamps;
+ break;
+ case SVR_MSG_CLIENT_CANCELED:
+ result = gText_OtherTrainerCanceled;
+ break;
+ case SVR_MSG_CANT_SEND_GIFT_1:
+ result = gText_CantSendGiftToTrainer;
+ break;
+ case SVR_MSG_COMM_ERROR:
+ result = gText_CommunicationError;
+ break;
+ case SVR_MSG_GIFT_SENT_1:
+ result = gText_GiftSentTo;
+ break;
+ case SVR_MSG_GIFT_SENT_2:
+ result = gText_GiftSentTo;
+ break;
+ case SVR_MSG_CANT_SEND_GIFT_2:
+ result = gText_CantSendGiftToTrainer;
+ break;
+ }
+ return result;
+}
+
+static bool32 PrintServerResultMessage(u8 * state, u16 * timer, bool8 sourceIsFriend, u32 msgId)
+{
+ bool32 wonderSuccess;
+ const u8 * str = GetServerResultMessage(&wonderSuccess, sourceIsFriend, msgId);
+ if (wonderSuccess)
+ return PrintSuccessMessage(state, str, timer);
+ else
+ return PrintMysteryGiftMenuMessage(state, str);
+}
+
+// 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(Task_MysteryGift, 0);
+ struct MysteryGiftTaskData * data = (void *)gTasks[taskId].data;
+ data->state = MG_STATE_TO_MAIN_MENU;
+ data->textState = 0;
+ data->unused4 = 0;
+ data->unused5 = 0;
+ data->isWonderNews = 0;
+ data->sourceIsFriend = 0;
+ data->var = 0;
+ data->unused1 = 0;
+ data->unused2 = 0;
+ data->unused3 = 0;
+ data->msgId = 0;
+ data->clientMsg = AllocZeroed(CLIENT_MAX_MSG_SIZE);
+}
+
+static void Task_MysteryGift(u8 taskId)
+{
+ struct MysteryGiftTaskData *data = (void *)gTasks[taskId].data;
+ u32 successMsg, input;
+ const u8 *msg;
+
+ switch (data->state)
+ {
+ case MG_STATE_TO_MAIN_MENU:
+ data->state = MG_STATE_MAIN_MENU;
+ break;
+ case MG_STATE_MAIN_MENU:
+ // Main Mystery Gift menu, player can select Wonder Cards or News (or exit)
+ switch (MysteryGift_HandleThreeOptionMenu(&data->textState, &data->var, FALSE))
+ {
+ case 0: // "Wonder Cards"
+ data->isWonderNews = FALSE;
+ if (ValidateSavedWonderCard() == TRUE)
+ data->state = MG_STATE_LOAD_GIFT;
+ else
+ data->state = MG_STATE_DONT_HAVE_ANY;
+ break;
+ case 1: // "Wonder News"
+ data->isWonderNews = TRUE;
+ if (ValidateSavedWonderNews() == TRUE)
+ data->state = MG_STATE_LOAD_GIFT;
+ else
+ data->state = MG_STATE_DONT_HAVE_ANY;
+ break;
+ case LIST_CANCEL:
+ data->state = MG_STATE_EXIT;
+ break;
+ }
+ break;
+ case MG_STATE_DONT_HAVE_ANY:
+ {
+ // 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 = MG_STATE_SOURCE_PROMPT;
+ PrintMysteryGiftOrEReaderTopMenu(FALSE, TRUE);
+ }
+ }
+ else
+ {
+ if (PrintMysteryGiftMenuMessage(&data->textState, gText_DontHaveNewsNewOneInput))
+ {
+ data->state = MG_STATE_SOURCE_PROMPT;
+ PrintMysteryGiftOrEReaderTopMenu(FALSE, TRUE);
+ }
+ }
+ break;
+ }
+ case MG_STATE_SOURCE_PROMPT:
+ if (!data->isWonderNews)
+ AddTextPrinterToWindow1(gText_WhereShouldCardBeAccessed);
+ else
+ AddTextPrinterToWindow1(gText_WhereShouldNewsBeAccessed);
+ data->state = MG_STATE_SOURCE_PROMPT_INPUT;
+ break;
+ 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: // "Wireless Communication"
+ ClearTextWindow();
+ data->state = MG_STATE_CLIENT_LINK_START;
+ data->sourceIsFriend = FALSE;
+ break;
+ case 1: // "Friend"
+ ClearTextWindow();
+ data->state = MG_STATE_CLIENT_LINK_START;
+ data->sourceIsFriend = TRUE;
+ break;
+ case LIST_CANCEL:
+ ClearTextWindow();
+ if (ValidateCardOrNews(data->isWonderNews))
+ {
+ data->state = MG_STATE_LOAD_GIFT;
+ }
+ else
+ {
+ data->state = MG_STATE_TO_MAIN_MENU;
+ PrintMysteryGiftOrEReaderTopMenu(FALSE, FALSE);
+ }
+ break;
+ }
+ break;
+ case MG_STATE_CLIENT_LINK_START:
+ *gStringVar1 = EOS;
+ *gStringVar2 = EOS;
+ *gStringVar3 = EOS;
+
+ switch (data->isWonderNews)
+ {
+ case FALSE:
+ if (data->sourceIsFriend == TRUE)
+ CreateTask_LinkMysteryGiftWithFriend(ACTIVITY_WONDER_CARD);
+ else if (data->sourceIsFriend == FALSE)
+ CreateTask_LinkMysteryGiftOverWireless(ACTIVITY_WONDER_CARD);
+ break;
+ case TRUE:
+ if (data->sourceIsFriend == TRUE)
+ CreateTask_LinkMysteryGiftWithFriend(ACTIVITY_WONDER_NEWS);
+ else if (data->sourceIsFriend == FALSE)
+ CreateTask_LinkMysteryGiftOverWireless(ACTIVITY_WONDER_NEWS);
+ break;
+ }
+ data->state = MG_STATE_CLIENT_LINK_WAIT;
+ break;
+ case MG_STATE_CLIENT_LINK_WAIT:
+ if (gReceivedRemoteLinkPlayers != 0)
+ {
+ ClearScreenInBg0(TRUE);
+ data->state = MG_STATE_CLIENT_COMMUNICATING;
+ MysteryGiftClient_Create(data->isWonderNews);
+ }
+ else if (gSpecialVar_Result == LINKUP_FAILED)
+ {
+ // Link failed, return to link start menu
+ ClearScreenInBg0(TRUE);
+ data->state = MG_STATE_SOURCE_PROMPT;
+ }
+ break;
+ case MG_STATE_CLIENT_COMMUNICATING:
+ AddTextPrinterToWindow1(gText_Communicating);
+ data->state = MG_STATE_CLIENT_LINK;
+ break;
+ case MG_STATE_CLIENT_LINK:
+ switch (MysteryGiftClient_Run(&data->var))
+ {
+ case CLI_RET_END:
+ Rfu_SetCloseLinkCallback();
+ data->msgId = data->var;
+ data->state = MG_STATE_CLIENT_LINK_END;
+ break;
+ case CLI_RET_COPY_MSG:
+ memcpy(data->clientMsg, MysteryGiftClient_GetMsg(), 0x40);
+ MysteryGiftClient_AdvanceState();
+ break;
+ case CLI_RET_PRINT_MSG:
+ data->state = MG_STATE_CLIENT_MESSAGE;
+ break;
+ case CLI_RET_YES_NO:
+ data->state = MG_STATE_CLIENT_YES_NO;
+ break;
+ case CLI_RET_ASK_TOSS:
+ data->state = MG_STATE_CLIENT_ASK_TOSS;
+ StringCopy(gStringVar1, gLinkPlayers[0].name);
+ break;
+ }
+ break;
+ case MG_STATE_CLIENT_YES_NO:
+ input = DoMysteryGiftYesNo(&data->textState, &data->var, FALSE, MysteryGiftClient_GetMsg());
+ switch (input)
+ {
+ case 0: // Yes
+ MysteryGiftClient_SetParam(FALSE);
+ MysteryGiftClient_AdvanceState();
+ data->state = MG_STATE_CLIENT_COMMUNICATING;
+ break;
+ case 1: // No
+ case MENU_B_PRESSED:
+ MysteryGiftClient_SetParam(TRUE);
+ MysteryGiftClient_AdvanceState();
+ data->state = MG_STATE_CLIENT_COMMUNICATING;
+ break;
+ }
+ break;
+ case MG_STATE_CLIENT_MESSAGE:
+ if (PrintMysteryGiftMenuMessage(&data->textState, MysteryGiftClient_GetMsg()))
+ {
+ MysteryGiftClient_AdvanceState();
+ data->state = MG_STATE_CLIENT_COMMUNICATING;
+ }
+ break;
+ case MG_STATE_CLIENT_ASK_TOSS:
+ // Player is receiving a new Wonder Card/News but needs to toss an existing one to make room.
+ // Ask for confirmation.
+ input = DoMysteryGiftYesNo(&data->textState, &data->var, FALSE, gText_ThrowAwayWonderCard);
+ switch (input)
+ {
+ case 0: // Yes
+ if (IsSavedWonderCardGiftNotReceived() == TRUE)
+ {
+ data->state = MG_STATE_CLIENT_ASK_TOSS_UNRECEIVED;
+ }
+ else
+ {
+ MysteryGiftClient_SetParam(FALSE);
+ MysteryGiftClient_AdvanceState();
+ data->state = MG_STATE_CLIENT_COMMUNICATING;
+ }
+ break;
+ case 1: // No
+ case MENU_B_PRESSED:
+ MysteryGiftClient_SetParam(TRUE);
+ MysteryGiftClient_AdvanceState();
+ data->state = MG_STATE_CLIENT_COMMUNICATING;
+ break;
+ }
+ break;
+ case MG_STATE_CLIENT_ASK_TOSS_UNRECEIVED:
+ // Player has selected to toss a Wonder Card that they haven't received the gift for.
+ // Ask for confirmation again.
+ input = DoMysteryGiftYesNo(&data->textState, &data->var, FALSE, gText_HaventReceivedCardsGift);
+ switch (input)
+ {
+ case 0: // Yes
+ MysteryGiftClient_SetParam(FALSE);
+ MysteryGiftClient_AdvanceState();
+ data->state = MG_STATE_CLIENT_COMMUNICATING;
+ break;
+ case 1: // No
+ case MENU_B_PRESSED:
+ MysteryGiftClient_SetParam(TRUE);
+ MysteryGiftClient_AdvanceState();
+ data->state = MG_STATE_CLIENT_COMMUNICATING;
+ break;
+ }
+ break;
+ case MG_STATE_CLIENT_LINK_END:
+ if (gReceivedRemoteLinkPlayers == 0)
+ {
+ DestroyWirelessStatusIndicatorSprite();
+ data->state = MG_STATE_CLIENT_COMM_COMPLETED;
+ }
+ break;
+ case MG_STATE_CLIENT_COMM_COMPLETED:
+ if (PrintStringAndWait2Seconds(&data->textState, gText_CommunicationCompleted))
+ {
+ if (data->sourceIsFriend == TRUE)
+ StringCopy(gStringVar1, gLinkPlayers[0].name);
+ data->state = MG_STATE_CLIENT_RESULT_MSG;
+ }
+ break;
+ 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
+ input = PrintMysteryGiftMenuMessage(&data->textState, msg);
+ // input var re-used, here it is TRUE if the message is finished
+ if (input)
+ {
+ if (data->msgId == CLI_MSG_NEWS_RECEIVED)
+ {
+ if (data->sourceIsFriend == TRUE)
+ GenerateRandomWonderNews(WONDER_NEWS_RECV_FRIEND);
+ else
+ GenerateRandomWonderNews(WONDER_NEWS_RECV_WIRELESS);
+ }
+ if (!successMsg)
+ {
+ // Did not receive card/news, return to main menu
+ data->state = MG_STATE_TO_MAIN_MENU;
+ PrintMysteryGiftOrEReaderTopMenu(FALSE, FALSE);
+ }
+ else
+ {
+ data->state = MG_STATE_SAVE_LOAD_GIFT;
+ }
+ }
+ break;
+ case MG_STATE_SAVE_LOAD_GIFT:
+ if (SaveOnMysteryGiftMenu(&data->textState))
+ data->state = MG_STATE_LOAD_GIFT;
+ break;
+ case MG_STATE_LOAD_GIFT:
+ if (HandleLoadWonderCardOrNews(&data->textState, data->isWonderNews))
+ data->state = MG_STATE_HANDLE_GIFT_INPUT;
+ break;
+ case MG_STATE_HANDLE_GIFT_INPUT:
+ if (!data->isWonderNews)
+ {
+ // Handle Wonder Card input
+ if (JOY_NEW(A_BUTTON))
+ data->state = MG_STATE_HANDLE_GIFT_SELECT;
+ if (JOY_NEW(B_BUTTON))
+ data->state = MG_STATE_GIFT_INPUT_EXIT;
+ }
+ else
+ {
+ switch (WonderNews_GetInput(gMain.newKeys))
+ {
+ case NEWS_INPUT_A:
+ WonderNews_RemoveScrollIndicatorArrowPair();
+ data->state = MG_STATE_HANDLE_GIFT_SELECT;
+ break;
+ case NEWS_INPUT_B:
+ data->state = MG_STATE_GIFT_INPUT_EXIT;
+ break;
+ }
+ }
+ break;
+ case MG_STATE_HANDLE_GIFT_SELECT:
+ {
+ // A Wonder Card/News has been selected, handle its menu
+ u32 result;
+ if (!data->isWonderNews)
+ {
+ if (IsSendingSavedWonderCardAllowed())
+ result = HandleGiftSelectMenu(&data->textState, &data->var, data->isWonderNews, FALSE);
+ else
+ result = HandleGiftSelectMenu(&data->textState, &data->var, data->isWonderNews, TRUE);
+ }
+ else
+ {
+ if (IsSendingSavedWonderNewsAllowed())
+ result = HandleGiftSelectMenu(&data->textState, &data->var, data->isWonderNews, FALSE);
+ else
+ result = HandleGiftSelectMenu(&data->textState, &data->var, data->isWonderNews, TRUE);
+ }
+ switch (result)
+ {
+ case 0: // Receive
+ data->state = MG_STATE_RECEIVE;
+ break;
+ case 1: // Send
+ data->state = MG_STATE_SEND;
+ break;
+ case 2: // Toss
+ data->state = MG_STATE_ASK_TOSS;
+ break;
+ case LIST_CANCEL:
+ if (data->isWonderNews == TRUE)
+ WonderNews_AddScrollIndicatorArrowPair();
+ data->state = MG_STATE_HANDLE_GIFT_INPUT;
+ break;
+ }
+ break;
+ }
+ 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: // 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)
+ {
+ case FALSE:
+ CreateTask_SendMysteryGift(ACTIVITY_WONDER_CARD);
+ break;
+ case TRUE:
+ CreateTask_SendMysteryGift(ACTIVITY_WONDER_NEWS);
+ break;
+ }
+ data->sourceIsFriend = TRUE;
+ data->state = MG_STATE_SERVER_LINK_WAIT;
+ }
+ break;
+ case MG_STATE_SERVER_LINK_WAIT:
+ if (gReceivedRemoteLinkPlayers != 0)
+ {
+ ClearScreenInBg0(TRUE);
+ data->state = MG_STATE_SERVER_LINK_START;
+ }
+ else if (gSpecialVar_Result == LINKUP_FAILED)
+ {
+ ClearScreenInBg0(TRUE);
+ data->state = MG_STATE_LOAD_GIFT;
+ }
+ break;
+ case MG_STATE_SERVER_LINK_START:
+ *gStringVar1 = EOS;
+ *gStringVar2 = EOS;
+ *gStringVar3 = EOS;
+
+ if (!data->isWonderNews)
+ {
+ AddTextPrinterToWindow1(gText_SendingWonderCard);
+ MysterGiftServer_CreateForCard();
+ }
+ else
+ {
+ AddTextPrinterToWindow1(gText_SendingWonderNews);
+ MysterGiftServer_CreateForNews();
+ }
+ data->state = MG_STATE_SERVER_LINK;
+ break;
+ case MG_STATE_SERVER_LINK:
+ if (MysterGiftServer_Run(&data->var) == SVR_RET_END)
+ {
+ data->msgId = data->var;
+ data->state = MG_STATE_SERVER_LINK_END;
+ }
+ break;
+ case MG_STATE_SERVER_LINK_END:
+ Rfu_SetCloseLinkCallback();
+ StringCopy(gStringVar1, gLinkPlayers[1].name);
+ data->state = MG_STATE_SERVER_LINK_END_WAIT;
+ break;
+ case MG_STATE_SERVER_LINK_END_WAIT:
+ if (gReceivedRemoteLinkPlayers == 0)
+ {
+ DestroyWirelessStatusIndicatorSprite();
+ data->state = MG_STATE_SERVER_RESULT_MSG;
+ }
+ break;
+ case MG_STATE_SERVER_RESULT_MSG:
+ if (PrintServerResultMessage(&data->textState, &data->var, data->sourceIsFriend, data->msgId))
+ {
+ if (data->sourceIsFriend == TRUE && data->msgId == SVR_MSG_NEWS_SENT)
+ {
+ GenerateRandomWonderNews(WONDER_NEWS_SENT);
+ data->state = MG_STATE_SAVE_LOAD_GIFT;
+ }
+ else
+ {
+ data->state = MG_STATE_TO_MAIN_MENU;
+ PrintMysteryGiftOrEReaderTopMenu(FALSE, FALSE);
+ }
+ }
+ break;
+ case MG_STATE_CLIENT_ERROR:
+ case MG_STATE_SERVER_ERROR:
+ if (PrintMysteryGiftMenuMessage(&data->textState, gText_CommunicationError))
+ {
+ data->state = MG_STATE_TO_MAIN_MENU;
+ PrintMysteryGiftOrEReaderTopMenu(FALSE, FALSE);
+ }
+ break;
+ case MG_STATE_EXIT:
+ CloseLink();
+ Free(data->clientMsg);
+ DestroyTask(taskId);
+ SetMainCallback2(MainCB_FreeAllBuffersAndReturnToInitTitleScreen);
+ break;
+ }
+}
+
+u16 GetMysteryGiftBaseBlock(void)
+{
+ return 0x1A9;
+}
+
+static void LoadMysteryGiftTextboxBorder(u8 bgId)
+{
+ DecompressAndLoadBgGfxUsingHeap(bgId, sTextboxBorder_Gfx, 0x100, 0, 0);
+}
diff --git a/src/mystery_gift_scripts.c b/src/mystery_gift_scripts.c
new file mode 100644
index 000000000..fcd7f568d
--- /dev/null
+++ b/src/mystery_gift_scripts.c
@@ -0,0 +1,217 @@
+#include "global.h"
+#include "mystery_gift_client.h"
+#include "mystery_gift_server.h"
+#include "mystery_gift.h"
+
+static const u8 sText_CanceledReadingCard[] = _("Canceled reading\nthe Card.");
+
+
+//==================
+// Client scripts
+//==================
+
+const struct MysteryGiftClientCmd gMysteryGiftClientScript_Init[] = {
+ {CLI_RECV, MG_LINKID_CLIENT_SCRIPT},
+ {CLI_COPY_RECV}
+};
+
+static const struct MysteryGiftClientCmd sClientScript_SendGameData[] = {
+ {CLI_LOAD_GAME_DATA},
+ {CLI_SEND_LOADED},
+ {CLI_RECV, MG_LINKID_CLIENT_SCRIPT},
+ {CLI_COPY_RECV}
+};
+
+static const struct MysteryGiftClientCmd sClientScript_CantAccept[] = {
+ {CLI_SEND_READY_END},
+ {CLI_RETURN, CLI_MSG_CANT_ACCEPT}
+};
+
+static const struct MysteryGiftClientCmd sClientScript_CommError[] = {
+ {CLI_SEND_READY_END},
+ {CLI_RETURN, CLI_MSG_COMM_ERROR}
+};
+
+static const struct MysteryGiftClientCmd sClientScript_NothingSent[] = {
+ {CLI_SEND_READY_END},
+ {CLI_RETURN, CLI_MSG_NOTHING_SENT}
+};
+
+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}
+};
+
+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}
+};
+
+static const struct MysteryGiftClientCmd sClientScript_HadNews[] = {
+ {CLI_SEND_READY_END},
+ {CLI_RETURN, CLI_MSG_HAD_NEWS}
+};
+
+static const struct MysteryGiftClientCmd sClientScript_NewsReceived[] = {
+ {CLI_SEND_READY_END},
+ {CLI_RETURN, CLI_MSG_NEWS_RECEIVED}
+};
+
+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}
+};
+
+static const struct MysteryGiftClientCmd sClientScript_Canceled[] = {
+ {CLI_SEND_READY_END},
+ {CLI_RETURN, CLI_MSG_COMM_CANCELED}
+};
+
+static const struct MysteryGiftClientCmd sClientScript_HadCard[] = {
+ {CLI_SEND_READY_END},
+ {CLI_RETURN, CLI_MSG_HAD_CARD}
+};
+
+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}
+};
+
+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
+//==================
+
+// Create arguments for SVR_LOAD_CLIENT_SCRIPT or SVR_LOAD_MSG
+// (a script/text size and pointer to send to the client)
+#define PTR_ARG(pointer) .parameter = sizeof(pointer), .ptr = pointer
+
+static const struct MysteryGiftServerCmd sServerScript_CantSend[] = {
+ {SVR_LOAD_CLIENT_SCRIPT, PTR_ARG(sClientScript_CantAccept)},
+ {SVR_SEND},
+ {SVR_RECV, MG_LINKID_READY_END},
+ {SVR_RETURN, SVR_MSG_CANT_SEND_GIFT_1}
+};
+
+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}
+};
+
+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}
+};
+
+static const struct MysteryGiftServerCmd sServerScript_ClientCanceledCard[] = {
+ {SVR_LOAD_CLIENT_SCRIPT, PTR_ARG(sClientScript_DynamicError)},
+ {SVR_SEND},
+ {SVR_LOAD_MSG, PTR_ARG(sText_CanceledReadingCard)},
+ {SVR_SEND},
+ {SVR_RECV, MG_LINKID_READY_END},
+ {SVR_RETURN, SVR_MSG_CLIENT_CANCELED}
+};
+
+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}
+};
+
+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}
+};
+
+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}
+};
+
+static const struct MysteryGiftServerCmd sServerScript_TossPrompt[] = {
+ {SVR_LOAD_CLIENT_SCRIPT, PTR_ARG(sClientScript_AskToss)},
+ {SVR_SEND},
+ {SVR_RECV, MG_LINKID_RESPONSE},
+ {SVR_READ_RESPONSE},
+ {SVR_GOTO_IF_EQ, FALSE, sServerScript_SendCard}, // Tossed old card, send new one
+ {SVR_GOTO, .ptr = sServerScript_ClientCanceledCard} // Kept old card, cancel new one
+};
+
+static const struct MysteryGiftServerCmd sServerScript_HasCard[] = {
+ {SVR_LOAD_CLIENT_SCRIPT, PTR_ARG(sClientScript_HadCard)},
+ {SVR_SEND},
+ {SVR_RECV, MG_LINKID_READY_END},
+ {SVR_RETURN, SVR_MSG_HAS_CARD}
+};
+
+static const struct MysteryGiftServerCmd sServerScript_NothingSent[] = {
+ {SVR_LOAD_CLIENT_SCRIPT, PTR_ARG(sClientScript_NothingSent)},
+ {SVR_SEND},
+ {SVR_RECV, MG_LINKID_READY_END},
+ {SVR_RETURN, SVR_MSG_NOTHING_SENT}
+};
+
+const struct MysteryGiftServerCmd gMysteryGiftServerScript_SendWonderNews[] = {
+ {SVR_COPY_SAVED_NEWS},
+ {SVR_LOAD_CLIENT_SCRIPT, PTR_ARG(sClientScript_SendGameData)},
+ {SVR_SEND},
+ {SVR_RECV, MG_LINKID_GAME_DATA},
+ {SVR_COPY_GAME_DATA},
+ {SVR_CHECK_GAME_DATA_NEWS},
+ {SVR_GOTO_IF_EQ, FALSE, sServerScript_CantSend},
+ {SVR_GOTO, .ptr = sServerScript_SendNews}
+};
+
+const struct MysteryGiftServerCmd gMysteryGiftServerScript_SendWonderCard[] = {
+ {SVR_COPY_SAVED_CARD},
+ {SVR_COPY_SAVED_RAM_SCRIPT},
+ {SVR_LOAD_CLIENT_SCRIPT, PTR_ARG(sClientScript_SendGameData)},
+ {SVR_SEND},
+ {SVR_RECV, MG_LINKID_GAME_DATA},
+ {SVR_COPY_GAME_DATA},
+ {SVR_CHECK_GAME_DATA_CARD},
+ {SVR_GOTO_IF_EQ, FALSE, sServerScript_CantSend},
+ {SVR_CHECK_EXISTING_CARD},
+ {SVR_GOTO_IF_EQ, HAS_DIFF_CARD, sServerScript_TossPrompt},
+ {SVR_GOTO_IF_EQ, HAS_NO_CARD, sServerScript_SendCard},
+ {SVR_GOTO, .ptr = sServerScript_HasCard} // HAS_SAME_CARD
+};
diff --git a/src/mystery_gift_server.c b/src/mystery_gift_server.c
new file mode 100644
index 000000000..0e0acb642
--- /dev/null
+++ b/src/mystery_gift_server.c
@@ -0,0 +1,291 @@
+#include "global.h"
+#include "malloc.h"
+#include "script.h"
+#include "mystery_gift.h"
+#include "mystery_gift_server.h"
+#include "mystery_gift_link.h"
+
+enum {
+ FUNC_INIT,
+ FUNC_DONE,
+ FUNC_RECV,
+ FUNC_SEND,
+ FUNC_RUN,
+};
+
+EWRAM_DATA static struct MysteryGiftServer * sServer = NULL;
+
+static void MysteryGiftServer_Init(struct MysteryGiftServer *, const void *, u32, u32);
+static void MysteryGiftServer_Free(struct MysteryGiftServer *);
+static u32 MysteryGiftServer_CallFunc(struct MysteryGiftServer *);
+
+extern const struct MysteryGiftServerCmd gMysteryGiftServerScript_SendWonderNews[];
+extern const struct MysteryGiftServerCmd gMysteryGiftServerScript_SendWonderCard[];
+
+void MysterGiftServer_CreateForNews(void)
+{
+ sServer = AllocZeroed(sizeof(*sServer));
+ MysteryGiftServer_Init(sServer, gMysteryGiftServerScript_SendWonderNews, 0, 1);
+}
+
+void MysterGiftServer_CreateForCard(void)
+{
+ sServer = AllocZeroed(sizeof(*sServer));
+ MysteryGiftServer_Init(sServer, gMysteryGiftServerScript_SendWonderCard, 0, 1);
+}
+
+u32 MysterGiftServer_Run(u16 * endVal)
+{
+ u32 result;
+ if (sServer == NULL)
+ return SVR_RET_END;
+ result = MysteryGiftServer_CallFunc(sServer);
+ if (result == SVR_RET_END)
+ {
+ *endVal = sServer->param;
+ MysteryGiftServer_Free(sServer);
+ Free(sServer);
+ sServer = NULL;
+ }
+ return result;
+}
+
+static void MysteryGiftServer_Init(struct MysteryGiftServer * svr, const void * script, u32 sendPlayerId, u32 recvPlayerId)
+{
+ svr->unused = 0;
+ svr->funcId = FUNC_INIT;
+ svr->card = AllocZeroed(sizeof(*svr->card));
+ svr->news = AllocZeroed(sizeof(*svr->news));
+ svr->recvBuffer = AllocZeroed(MG_LINK_BUFFER_SIZE);
+ svr->linkGameData = AllocZeroed(sizeof(*svr->linkGameData));
+ svr->script = script;
+ svr->cmdidx = 0;
+ MysteryGiftLink_Init(&svr->link, sendPlayerId, recvPlayerId);
+}
+
+static void MysteryGiftServer_Free(struct MysteryGiftServer * svr)
+{
+ Free(svr->card);
+ Free(svr->news);
+ Free(svr->recvBuffer);
+ Free(svr->linkGameData);
+}
+
+static void MysteryGiftServer_InitSend(struct MysteryGiftServer * svr, u32 ident, const void * src, u32 size)
+{
+ AGB_ASSERT(size <= MG_LINK_BUFFER_SIZE);
+ MysteryGiftLink_InitSend(&svr->link, ident, src, size);
+}
+
+// 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 (dynamicData != NULL)
+ return dynamicData;
+ else
+ return defaultData;
+}
+
+static u32 MysteryGiftServer_Compare(const void * a, const void * b)
+{
+ if (b < a)
+ return 0;
+ else if (b == a)
+ return 1;
+ else
+ return 2;
+}
+
+static u32 Server_Init(struct MysteryGiftServer * svr)
+{
+ svr->funcId = FUNC_RUN;
+ return SVR_RET_INIT;
+}
+
+static u32 Server_Done(struct MysteryGiftServer * svr)
+{
+ return SVR_RET_END;
+}
+
+static u32 Server_Recv(struct MysteryGiftServer * svr)
+{
+ if (MysteryGiftLink_Recv(&svr->link))
+ svr->funcId = FUNC_RUN;
+ return SVR_RET_ACTIVE;
+}
+
+static u32 Server_Send(struct MysteryGiftServer * svr)
+{
+ if (MysteryGiftLink_Send(&svr->link))
+ svr->funcId = FUNC_RUN;
+ return SVR_RET_ACTIVE;
+}
+
+static u32 Server_Run(struct MysteryGiftServer * svr)
+{
+ // process command
+ const struct MysteryGiftServerCmd * cmd = &svr->script[svr->cmdidx];
+ const void * ptr;
+ svr->cmdidx++;
+
+ switch (cmd->instr)
+ {
+ case SVR_RETURN:
+ AGB_ASSERT(cmd->ptr == NULL);
+ svr->funcId = FUNC_DONE;
+ svr->param = cmd->parameter; // Set for endVal in MysteryGiftServer_Run
+ break;
+ case SVR_SEND:
+ svr->funcId = FUNC_SEND;
+ break;
+ case SVR_RECV:
+ AGB_ASSERT(cmd->ptr == NULL);
+ MysteryGiftLink_InitRecv(&svr->link, cmd->parameter, svr->recvBuffer);
+ svr->funcId = FUNC_RECV;
+ break;
+ case SVR_GOTO:
+ AGB_ASSERT(cmd->parameter == 0);
+ svr->cmdidx = 0;
+ svr->script = cmd->ptr;
+ break;
+ case SVR_COPY_GAME_DATA:
+ AGB_ASSERT(cmd->parameter == 0);
+ AGB_ASSERT(cmd->ptr == NULL);
+ memcpy(svr->linkGameData, svr->recvBuffer, sizeof(*svr->linkGameData));
+ break;
+ case SVR_CHECK_GAME_DATA_CARD:
+ AGB_ASSERT(cmd->parameter == 0);
+ AGB_ASSERT(cmd->ptr == NULL);
+ svr->param = MysteryGift_ValidateLinkGameData(svr->linkGameData, FALSE);
+ break;
+ case SVR_CHECK_GAME_DATA_NEWS:
+ AGB_ASSERT(cmd->parameter == 0);
+ AGB_ASSERT(cmd->ptr == NULL);
+ svr->param = MysteryGift_ValidateLinkGameData(svr->linkGameData, TRUE);
+ break;
+ case SVR_GOTO_IF_EQ:
+ if (svr->param == cmd->parameter)
+ {
+ svr->cmdidx = 0;
+ svr->script = cmd->ptr;
+ }
+ break;
+ case SVR_CHECK_EXISTING_CARD:
+ AGB_ASSERT(cmd->parameter == 0);
+ ptr = MysteryGiftServer_GetSendData(cmd->ptr, svr->card);
+ svr->param = MysteryGift_CompareCardFlags(ptr, svr->linkGameData, ptr);
+ break;
+ case SVR_READ_RESPONSE:
+ AGB_ASSERT(cmd->parameter == 0);
+ AGB_ASSERT(cmd->ptr == NULL);
+ svr->param = *(u32 *)svr->recvBuffer;
+ break;
+ case SVR_CHECK_EXISTING_STAMPS:
+ AGB_ASSERT(cmd->parameter == 0);
+ ptr = MysteryGiftServer_GetSendData(cmd->ptr, &svr->stamp);
+ svr->param = MysteryGift_CheckStamps(ptr, svr->linkGameData, ptr);
+ break;
+ case SVR_GET_CARD_STAT:
+ AGB_ASSERT(cmd->ptr == NULL);
+ svr->param = MysteryGift_GetCardStatFromLinkData(svr->linkGameData, cmd->parameter);
+ break;
+ case SVR_CHECK_QUESTIONNAIRE:
+ AGB_ASSERT(cmd->parameter == 0);
+ svr->param = MysteryGift_DoesQuestionnaireMatch(svr->linkGameData, cmd->ptr);
+ break;
+ case SVR_COMPARE:
+ AGB_ASSERT(cmd->parameter == 0);
+ svr->param = MysteryGiftServer_Compare(cmd->ptr, *(void **)svr->recvBuffer);
+ break;
+ case SVR_LOAD_NEWS:
+ AGB_ASSERT(cmd->parameter == 0);
+ MysteryGiftServer_InitSend(svr, MG_LINKID_NEWS, MysteryGiftServer_GetSendData(cmd->ptr, svr->news), sizeof(*svr->news));
+ break;
+ case SVR_LOAD_CARD:
+ AGB_ASSERT(cmd->parameter == 0);
+ MysteryGiftServer_InitSend(svr, MG_LINKID_CARD, MysteryGiftServer_GetSendData(cmd->ptr, svr->card), sizeof(*svr->card));
+ break;
+ case SVR_LOAD_STAMP:
+ AGB_ASSERT(cmd->parameter == 0);
+ MysteryGiftServer_InitSend(svr, MG_LINKID_STAMP, MysteryGiftServer_GetSendData(cmd->ptr, &svr->stamp), sizeof(svr->stamp));
+ break;
+ case SVR_LOAD_RAM_SCRIPT:
+ if (cmd->ptr == NULL)
+ MysteryGiftServer_InitSend(svr, MG_LINKID_RAM_SCRIPT, svr->ramScript, svr->ramScriptSize);
+ else
+ MysteryGiftServer_InitSend(svr, MG_LINKID_RAM_SCRIPT, cmd->ptr, cmd->parameter);
+ break;
+ case SVR_LOAD_CLIENT_SCRIPT:
+ if (cmd->ptr == NULL)
+ MysteryGiftServer_InitSend(svr, MG_LINKID_CLIENT_SCRIPT, svr->clientScript, svr->clientScriptSize);
+ else
+ MysteryGiftServer_InitSend(svr, MG_LINKID_CLIENT_SCRIPT, cmd->ptr, cmd->parameter);
+ break;
+ case SVR_LOAD_EREADER_TRAINER:
+ AGB_ASSERT(cmd->parameter == 0);
+ 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->ptr, cmd->parameter);
+ break;
+ case SVR_LOAD_UNK_2:
+ MysteryGiftServer_InitSend(svr, MG_LINKID_UNK_2, cmd->ptr, cmd->parameter);
+ break;
+ case SVR_COPY_CARD:
+ AGB_ASSERT(cmd->parameter == 0);
+ memcpy(svr->card, cmd->ptr, sizeof(*svr->card));
+ break;
+ case SVR_COPY_NEWS:
+ AGB_ASSERT(cmd->parameter == 0);
+ memcpy(svr->news, cmd->ptr, sizeof(*svr->news));
+ break;
+ case SVR_COPY_STAMP:
+ AGB_ASSERT(cmd->parameter == 0);
+ svr->stamp = *(u32 *)cmd->ptr;
+ break;
+ case SVR_SET_RAM_SCRIPT:
+ svr->ramScript = cmd->ptr;
+ svr->ramScriptSize = cmd->parameter;
+ break;
+ case SVR_SET_CLIENT_SCRIPT:
+ svr->clientScript = cmd->ptr;
+ svr->clientScriptSize = cmd->parameter;
+ break;
+ case SVR_COPY_SAVED_CARD:
+ AGB_ASSERT(cmd->parameter == 0 && cmd->ptr == NULL);
+ memcpy(svr->card, GetSavedWonderCard(), sizeof(*svr->card));
+ DisableWonderCardSending(svr->card);
+ break;
+ case SVR_COPY_SAVED_NEWS:
+ AGB_ASSERT(cmd->parameter == 0 && cmd->ptr == NULL);
+ memcpy(svr->news, GetSavedWonderNews(), sizeof(*svr->news));
+ break;
+ case SVR_COPY_SAVED_RAM_SCRIPT:
+ AGB_ASSERT(cmd->parameter == 0 && cmd->ptr == NULL);
+ svr->ramScript = GetSavedRamScriptIfValid();
+ break;
+ case SVR_LOAD_UNK_1:
+ MysteryGiftServer_InitSend(svr, MG_LINKID_UNK_1, cmd->ptr, cmd->parameter);
+ break;
+ }
+
+ return SVR_RET_ACTIVE;
+}
+
+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 MysteryGiftServer_CallFunc(struct MysteryGiftServer * svr)
+{
+ u32 response;
+ AGB_ASSERT(svr->funcId < ARRAY_COUNT(sFuncTable));
+ response = sFuncTable[svr->funcId](svr);
+ AGB_ASSERT(svr->funcId < ARRAY_COUNT(sFuncTable));
+ return response;
+}
diff --git a/src/mystery_gift_view.c b/src/mystery_gift_view.c
new file mode 100644
index 000000000..0e1c11520
--- /dev/null
+++ b/src/mystery_gift_view.c
@@ -0,0 +1,936 @@
+#include "global.h"
+#include "bg.h"
+#include "gpu_regs.h"
+#include "palette.h"
+#include "decompress.h"
+#include "malloc.h"
+#include "menu.h"
+#include "pokemon_icon.h"
+#include "union_room.h"
+#include "list_menu.h"
+#include "text_window.h"
+#include "string_util.h"
+#include "link_rfu.h"
+#include "mystery_gift.h"
+#include "mystery_gift_menu.h"
+#include "mystery_gift_view.h"
+#include "constants/rgb.h"
+#include "constants/mystery_gift.h"
+
+struct WonderGraphics
+{
+ u8 titleTextPal:4;
+ u8 bodyTextPal:4;
+ u8 footerTextPal:4; // Card only
+ u8 stampShadowPal:4; // Card only
+ const u32 * tiles;
+ const u32 * map;
+ const u16 * pal;
+};
+
+//======================
+// Wonder Cards
+//======================
+
+enum {
+ CARD_WIN_HEADER,
+ CARD_WIN_BODY,
+ CARD_WIN_FOOTER,
+ CARD_WIN_COUNT
+};
+
+#define TAG_STAMP_SHADOW 0x8000
+
+struct CardStatTextData
+{
+ u8 width;
+ u8 statText[WONDER_CARD_TEXT_LENGTH + 1];
+ u8 statNumberText[4];
+};
+
+struct WonderCardData
+{
+ /*0000*/ struct WonderCard card;
+ /*014c*/ struct WonderCardMetadata cardMetadata;
+ /*0170*/ const struct WonderGraphics * gfx;
+ /*0174*/ u8 enterExitState;
+ /*0175*/ u8 statFooterWidth;
+ /*0176*/ u16 windowIds[CARD_WIN_COUNT];
+ /*017C*/ u8 monIconSpriteId;
+ /*017D*/ u8 stampSpriteIds[MAX_STAMP_CARD_STAMPS][2]; // 2 sprites each, 1 for the shadow and 1 for the Pokémon
+ /*018B*/ u8 titleText[WONDER_CARD_TEXT_LENGTH + 1];
+ /*01B4*/ u8 subtitleText[WONDER_CARD_TEXT_LENGTH + 1];
+ /*01DD*/ u8 idNumberText[7];
+ /*01E4*/ u8 bodyText[WONDER_CARD_BODY_TEXT_LINES][WONDER_CARD_TEXT_LENGTH + 1];
+ /*0288*/ u8 footerLine1Text[WONDER_CARD_TEXT_LENGTH + 1];
+ /*02B1*/ u8 giftText[WONDER_CARD_TEXT_LENGTH + 1];
+ /*02DC*/ struct CardStatTextData statTextData[8];
+ /*045C*/ u8 bgTilemapBuffer[0x1000];
+};
+
+EWRAM_DATA static struct WonderCardData * sWonderCardData = NULL;
+
+static void BufferCardText(void);
+static void DrawCardWindow(u8 whichWindow);
+static void CreateCardSprites(void);
+static void DestroyCardSprites(void);
+
+extern const struct OamData gOamData_AffineOff_ObjNormal_32x16;
+
+static const u8 sCard_TextColorTable[][3] = {
+ {TEXT_COLOR_TRANSPARENT, TEXT_COLOR_DARK_GRAY, TEXT_COLOR_LIGHT_GRAY},
+ {TEXT_COLOR_TRANSPARENT, TEXT_COLOR_WHITE, TEXT_COLOR_DARK_GRAY}
+};
+
+static const u8 ALIGNED(4) sCard_FooterTextOffsets[CARD_TYPE_COUNT] =
+{
+ [CARD_TYPE_GIFT] = 7,
+ [CARD_TYPE_STAMP] = 4,
+ [CARD_TYPE_LINK_STAT] = 7
+};
+
+static const struct WindowTemplate sCard_WindowTemplates[] = {
+ [CARD_WIN_HEADER] = {
+ .bg = 1,
+ .tilemapLeft = 1,
+ .tilemapTop = 1,
+ .width = 25,
+ .height = 4,
+ .paletteNum = 2,
+ .baseBlock = 0x029c
+ },
+ [CARD_WIN_BODY] = {
+ .bg = 1,
+ .tilemapLeft = 1,
+ .tilemapTop = 6,
+ .width = 28,
+ .height = 8,
+ .paletteNum = 2,
+ .baseBlock = 0x01bc
+ },
+ [CARD_WIN_FOOTER] = {
+ .bg = 1,
+ .tilemapLeft = 1,
+ .tilemapTop = 14,
+ .width = 28,
+ .height = 5,
+ .paletteNum = 2,
+ .baseBlock = 0x0130
+ }
+};
+
+static const u16 sWonderCardBgPal1[] = INCBIN_U16("graphics/wonder_card/bg1.gbapal");
+static const u16 sWonderCardBgPal2[] = INCBIN_U16("graphics/wonder_card/bg2.gbapal");
+static const u16 sWonderCardBgPal3[] = INCBIN_U16("graphics/wonder_card/bg3.gbapal");
+static const u16 sWonderCardBgPal4[] = INCBIN_U16("graphics/wonder_card/bg4.gbapal");
+static const u16 sWonderCardBgPal5[] = INCBIN_U16("graphics/wonder_card/bg5.gbapal");
+static const u16 sWonderCardBgPal6[] = INCBIN_U16("graphics/wonder_card/bg6.gbapal");
+static const u16 sWonderCardBgPal7[] = INCBIN_U16("graphics/wonder_card/bg7.gbapal");
+static const u16 sWonderCardBgPal8[] = INCBIN_U16("graphics/wonder_card/bg8.gbapal");
+static const u32 sWonderCardBgGfx1[] = INCBIN_U32("graphics/wonder_card/bg1.4bpp.lz");
+static const u32 sWonderCardBgTilemap1[] = INCBIN_U32("graphics/wonder_card/bg1.bin.lz");
+static const u32 sWonderCardBgGfx2[] = INCBIN_U32("graphics/wonder_card/bg2.4bpp.lz");
+static const u32 sWonderCardBgTilemap2[] = INCBIN_U32("graphics/wonder_card/bg2.bin.lz");
+static const u32 sWonderCardBgGfx3[] = INCBIN_U32("graphics/wonder_card/bg3.4bpp.lz");
+static const u32 sWonderCardBgTilemap3[] = INCBIN_U32("graphics/wonder_card/bg3.bin.lz");
+static const u32 sWonderCardBgGfx7[] = INCBIN_U32("graphics/wonder_card/bg7.4bpp.lz");
+static const u32 sWonderCardBgTilemap7[] = INCBIN_U32("graphics/wonder_card/bg7.bin.lz");
+static const u32 sWonderCardBgGfx8[] = INCBIN_U32("graphics/wonder_card/bg8.4bpp.lz");
+static const u32 sWonderCardBgTilemap8[] = INCBIN_U32("graphics/wonder_card/bg8.bin.lz");
+static const u16 sStampShadowPal1[] = INCBIN_U16("graphics/wonder_card/stamp_shadow_1.gbapal");
+static const u16 sStampShadowPal2[] = INCBIN_U16("graphics/wonder_card/stamp_shadow_2.gbapal");
+static const u16 sStampShadowPal3[] = INCBIN_U16("graphics/wonder_card/stamp_shadow_3.gbapal");
+static const u16 sStampShadowPal4[] = INCBIN_U16("graphics/wonder_card/stamp_shadow_4.gbapal");
+static const u16 sStampShadowPal5[] = INCBIN_U16("graphics/wonder_card/stamp_shadow_5.gbapal");
+static const u16 sStampShadowPal6[] = INCBIN_U16("graphics/wonder_card/stamp_shadow_6.gbapal");
+static const u16 sStampShadowPal7[] = INCBIN_U16("graphics/wonder_card/stamp_shadow_7.gbapal");
+static const u16 sStampShadowPal8[] = INCBIN_U16("graphics/wonder_card/stamp_shadow_8.gbapal");
+static const u32 sStampShadowGfx[] = INCBIN_U32("graphics/wonder_card/stamp_shadow.4bpp.lz");
+
+static const struct CompressedSpriteSheet sSpriteSheet_StampShadow = {
+ sStampShadowGfx, 0x100, TAG_STAMP_SHADOW
+};
+
+static const struct SpritePalette sSpritePalettes_StampShadow[] = {
+ {sStampShadowPal1, TAG_STAMP_SHADOW},
+ {sStampShadowPal2, TAG_STAMP_SHADOW},
+ {sStampShadowPal3, TAG_STAMP_SHADOW},
+ {sStampShadowPal4, TAG_STAMP_SHADOW},
+ {sStampShadowPal5, TAG_STAMP_SHADOW},
+ {sStampShadowPal6, TAG_STAMP_SHADOW},
+ {sStampShadowPal7, TAG_STAMP_SHADOW},
+ {sStampShadowPal8, TAG_STAMP_SHADOW}
+};
+
+static const struct SpriteTemplate sSpriteTemplate_StampShadow = {
+ .tileTag = TAG_STAMP_SHADOW,
+ .paletteTag = TAG_STAMP_SHADOW,
+ .oam = &gOamData_AffineOff_ObjNormal_32x16,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy
+};
+
+static const struct WonderGraphics sCardGraphics[NUM_WONDER_BGS] = {
+ {.titleTextPal = 1, .bodyTextPal = 0, .footerTextPal = 0, .stampShadowPal = 0, .tiles = sWonderCardBgGfx1, .map = sWonderCardBgTilemap1, .pal = sWonderCardBgPal1},
+ {.titleTextPal = 1, .bodyTextPal = 0, .footerTextPal = 0, .stampShadowPal = 1, .tiles = sWonderCardBgGfx2, .map = sWonderCardBgTilemap2, .pal = sWonderCardBgPal2},
+ {.titleTextPal = 1, .bodyTextPal = 0, .footerTextPal = 0, .stampShadowPal = 2, .tiles = sWonderCardBgGfx3, .map = sWonderCardBgTilemap3, .pal = sWonderCardBgPal3},
+ {.titleTextPal = 1, .bodyTextPal = 0, .footerTextPal = 0, .stampShadowPal = 3, .tiles = sWonderCardBgGfx3, .map = sWonderCardBgTilemap3, .pal = sWonderCardBgPal4},
+ {.titleTextPal = 1, .bodyTextPal = 0, .footerTextPal = 0, .stampShadowPal = 4, .tiles = sWonderCardBgGfx3, .map = sWonderCardBgTilemap3, .pal = sWonderCardBgPal5},
+ {.titleTextPal = 1, .bodyTextPal = 0, .footerTextPal = 0, .stampShadowPal = 5, .tiles = sWonderCardBgGfx3, .map = sWonderCardBgTilemap3, .pal = sWonderCardBgPal6},
+ {.titleTextPal = 1, .bodyTextPal = 0, .footerTextPal = 0, .stampShadowPal = 6, .tiles = sWonderCardBgGfx7, .map = sWonderCardBgTilemap7, .pal = sWonderCardBgPal7},
+ {.titleTextPal = 1, .bodyTextPal = 0, .footerTextPal = 0, .stampShadowPal = 7, .tiles = sWonderCardBgGfx8, .map = sWonderCardBgTilemap8, .pal = sWonderCardBgPal8}
+};
+
+bool32 WonderCard_Init(struct WonderCard * card, struct WonderCardMetadata * metadata)
+{
+ if (card == NULL || metadata == NULL)
+ return FALSE;
+ sWonderCardData = AllocZeroed(sizeof(*sWonderCardData));
+ if (sWonderCardData == NULL)
+ return FALSE;
+ sWonderCardData->card = *card;
+ sWonderCardData->cardMetadata = *metadata;
+ if (sWonderCardData->card.bgType >= NUM_WONDER_BGS)
+ sWonderCardData->card.bgType = 0;
+ if (sWonderCardData->card.type >= CARD_TYPE_COUNT)
+ sWonderCardData->card.type = 0;
+ if (sWonderCardData->card.maxStamps > MAX_STAMP_CARD_STAMPS)
+ sWonderCardData->card.maxStamps = 0;
+ sWonderCardData->gfx = &sCardGraphics[sWonderCardData->card.bgType];
+ return TRUE;
+}
+
+void WonderCard_Destroy(void)
+{
+ if (sWonderCardData != NULL)
+ {
+ *sWonderCardData = (struct WonderCardData){};
+ Free(sWonderCardData);
+ sWonderCardData = NULL;
+ }
+}
+
+s32 WonderCard_Enter(void)
+{
+ if (sWonderCardData == NULL)
+ return -1;
+ switch(sWonderCardData->enterExitState)
+ {
+ case 0:
+ BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK);
+ break;
+ case 1:
+ if (UpdatePaletteFade())
+ return 0;
+ break;
+ case 2:
+ FillBgTilemapBufferRect_Palette0(0, 0x000, 0, 0, 30, 20);
+ FillBgTilemapBufferRect_Palette0(1, 0x000, 0, 0, 30, 20);
+ FillBgTilemapBufferRect_Palette0(2, 0x000, 0, 0, 30, 20);
+ CopyBgTilemapBufferToVram(0);
+ CopyBgTilemapBufferToVram(1);
+ CopyBgTilemapBufferToVram(2);
+ DecompressAndCopyTileDataToVram(2, sWonderCardData->gfx->tiles, 0, 0x008, 0);
+ sWonderCardData->windowIds[CARD_WIN_HEADER] = AddWindow(&sCard_WindowTemplates[CARD_WIN_HEADER]);
+ sWonderCardData->windowIds[CARD_WIN_BODY] = AddWindow(&sCard_WindowTemplates[CARD_WIN_BODY]);
+ sWonderCardData->windowIds[CARD_WIN_FOOTER] = AddWindow(&sCard_WindowTemplates[CARD_WIN_FOOTER]);
+ break;
+ case 3:
+ if (FreeTempTileDataBuffersIfPossible())
+ return 0;
+ LoadPalette(GetTextWindowPalette(1), 0x20, 0x20);
+ gPaletteFade.bufferTransferDisabled = TRUE;
+ LoadPalette(sWonderCardData->gfx->pal, 0x10, 0x20);
+ LZ77UnCompWram(sWonderCardData->gfx->map, sWonderCardData->bgTilemapBuffer);
+ CopyRectToBgTilemapBufferRect(2, sWonderCardData->bgTilemapBuffer, 0, 0, 30, 20, 0, 0, 30, 20, 1, 0x008, 0);
+ CopyBgTilemapBufferToVram(2);
+ break;
+ case 4:
+ BufferCardText();
+ break;
+ case 5:
+ DrawCardWindow(CARD_WIN_HEADER);
+ DrawCardWindow(CARD_WIN_BODY);
+ DrawCardWindow(CARD_WIN_FOOTER);
+ CopyBgTilemapBufferToVram(1);
+ break;
+ case 6:
+ LoadMonIconPalettes();
+ break;
+ case 7:
+ ShowBg(1);
+ ShowBg(2);
+ gPaletteFade.bufferTransferDisabled = FALSE;
+ CreateCardSprites();
+ BeginNormalPaletteFade(PALETTES_ALL, 0, 16, 0, RGB_BLACK);
+ UpdatePaletteFade();
+ break;
+ default:
+ if (UpdatePaletteFade())
+ return 0;
+ sWonderCardData->enterExitState = 0;
+ return 1;
+ }
+ sWonderCardData->enterExitState++;
+ return 0;
+}
+
+s32 WonderCard_Exit(bool32 useCancel)
+{
+ if (sWonderCardData == NULL)
+ return -1;
+ switch (sWonderCardData->enterExitState)
+ {
+ case 0:
+ BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK);
+ break;
+ case 1:
+ if (UpdatePaletteFade())
+ return 0;
+ break;
+ case 2:
+ FillBgTilemapBufferRect_Palette0(0, 0x000, 0, 0, 30, 20);
+ FillBgTilemapBufferRect_Palette0(1, 0x000, 0, 0, 30, 20);
+ FillBgTilemapBufferRect_Palette0(2, 0x000, 0, 0, 30, 20);
+ CopyBgTilemapBufferToVram(0);
+ CopyBgTilemapBufferToVram(1);
+ CopyBgTilemapBufferToVram(2);
+ break;
+ case 3:
+ HideBg(1);
+ HideBg(2);
+ RemoveWindow(sWonderCardData->windowIds[CARD_WIN_FOOTER]);
+ RemoveWindow(sWonderCardData->windowIds[CARD_WIN_BODY]);
+ RemoveWindow(sWonderCardData->windowIds[CARD_WIN_HEADER]);
+ break;
+ case 4:
+ DestroyCardSprites();
+ FreeMonIconPalettes();
+ break;
+ case 5:
+ PrintMysteryGiftOrEReaderTopMenu(gGiftIsFromEReader, useCancel);
+ CopyBgTilemapBufferToVram(0);
+ BeginNormalPaletteFade(PALETTES_ALL, 0, 16, 0, RGB_BLACK);
+ break;
+ default:
+ if (UpdatePaletteFade())
+ return 0;
+ sWonderCardData->enterExitState = 0;
+ return 1;
+ }
+ sWonderCardData->enterExitState++;
+ return 0;
+}
+
+static void BufferCardText(void)
+{
+ u16 i = 0;
+ u16 charsUntilStat;
+ u16 stats[3] = {0, 0, 0};
+
+ // Copy title/subtitle text
+ memcpy(sWonderCardData->titleText, sWonderCardData->card.titleText, WONDER_CARD_TEXT_LENGTH);
+ sWonderCardData->titleText[WONDER_CARD_TEXT_LENGTH] = EOS;
+ memcpy(sWonderCardData->subtitleText, sWonderCardData->card.subtitleText, WONDER_CARD_TEXT_LENGTH);
+ sWonderCardData->subtitleText[WONDER_CARD_TEXT_LENGTH] = EOS;
+
+ // Copy card id number
+ if (sWonderCardData->card.idNumber > 999999)
+ sWonderCardData->card.idNumber = 999999;
+ ConvertIntToDecimalStringN(sWonderCardData->idNumberText, sWonderCardData->card.idNumber, STR_CONV_MODE_LEFT_ALIGN, 6);
+
+ // Copy body text
+ for (i = 0; i < WONDER_CARD_BODY_TEXT_LINES; i++)
+ {
+ memcpy(sWonderCardData->bodyText[i], sWonderCardData->card.bodyText[i], WONDER_CARD_TEXT_LENGTH);
+ sWonderCardData->bodyText[i][WONDER_CARD_TEXT_LENGTH] = EOS;
+ }
+
+ // Copy footer line 1
+ memcpy(sWonderCardData->footerLine1Text, sWonderCardData->card.footerLine1Text, WONDER_CARD_TEXT_LENGTH);
+ sWonderCardData->footerLine1Text[WONDER_CARD_TEXT_LENGTH] = EOS;
+
+ // Copy footer line 2
+ switch (sWonderCardData->card.type)
+ {
+ case CARD_TYPE_GIFT:
+ memcpy(sWonderCardData->giftText, sWonderCardData->card.footerLine2Text, WONDER_CARD_TEXT_LENGTH);
+ sWonderCardData->giftText[WONDER_CARD_TEXT_LENGTH] = EOS;
+ break;
+ case CARD_TYPE_STAMP:
+ sWonderCardData->giftText[0] = EOS;
+ break;
+ case CARD_TYPE_LINK_STAT:
+ sWonderCardData->giftText[0] = EOS;
+
+ // Load stats
+ stats[0] = sWonderCardData->cardMetadata.battlesWon < MAX_WONDER_CARD_STAT ? sWonderCardData->cardMetadata.battlesWon : MAX_WONDER_CARD_STAT;
+ stats[1] = sWonderCardData->cardMetadata.battlesLost < MAX_WONDER_CARD_STAT ? sWonderCardData->cardMetadata.battlesLost : MAX_WONDER_CARD_STAT;
+ stats[2] = sWonderCardData->cardMetadata.numTrades < MAX_WONDER_CARD_STAT ? sWonderCardData->cardMetadata.numTrades : MAX_WONDER_CARD_STAT;
+
+ // Init stat text arrays
+ for (i = 0; i < ARRAY_COUNT(sWonderCardData->statTextData); i++)
+ {
+ memset(sWonderCardData->statTextData[i].statNumberText, EOS, sizeof(sWonderCardData->statTextData[i].statNumberText));
+ memset(sWonderCardData->statTextData[i].statText, EOS, sizeof(sWonderCardData->statTextData[i].statText));
+ }
+
+ // Copy stat texts
+ for (i = 0, charsUntilStat = 0; i < WONDER_CARD_TEXT_LENGTH; i++)
+ {
+ if (sWonderCardData->card.footerLine2Text[i] != CHAR_DYNAMIC)
+ {
+ // Regular text, just copy as is
+ sWonderCardData->statTextData[sWonderCardData->statFooterWidth].statText[charsUntilStat] = sWonderCardData->card.footerLine2Text[i];
+ charsUntilStat++;
+ }
+ else
+ {
+ // Dynamic char encountered
+ // These are used to give the id of which stat to print
+ u8 id = sWonderCardData->card.footerLine2Text[i + 1];
+ if (id >= ARRAY_COUNT(stats))
+ {
+ // Invalid stat id, skip ahead
+ i += 2;
+ }
+ else
+ {
+ // Copy stat number
+ ConvertIntToDecimalStringN(sWonderCardData->statTextData[sWonderCardData->statFooterWidth].statNumberText, stats[id], STR_CONV_MODE_LEADING_ZEROS, 3);
+ sWonderCardData->statTextData[sWonderCardData->statFooterWidth].width = sWonderCardData->card.footerLine2Text[i + 2];
+ sWonderCardData->statFooterWidth++;
+ if (sWonderCardData->statFooterWidth >= ARRAY_COUNT(sWonderCardData->statTextData))
+ break;
+ charsUntilStat = 0;
+ i += 2;
+ }
+ }
+ }
+ }
+}
+
+static void DrawCardWindow(u8 whichWindow)
+{
+ s8 i = 0;
+ s32 windowId = sWonderCardData->windowIds[whichWindow];
+ PutWindowTilemap(windowId);
+ FillWindowPixelBuffer(windowId, 0);
+ switch (whichWindow)
+ {
+ case CARD_WIN_HEADER:
+ {
+ // Print card title/subtitle
+ s32 x;
+ AddTextPrinterParameterized3(windowId, 3, 0, 1, sCard_TextColorTable[sWonderCardData->gfx->titleTextPal], 0, sWonderCardData->titleText);
+ x = 160 - GetStringWidth(3, sWonderCardData->subtitleText, GetFontAttribute(3, FONTATTR_LETTER_SPACING));
+ if (x < 0)
+ x = 0;
+ AddTextPrinterParameterized3(windowId, 3, x, 17, sCard_TextColorTable[sWonderCardData->gfx->titleTextPal], 0, sWonderCardData->subtitleText);
+
+ // Print id number
+ if (sWonderCardData->card.idNumber != 0)
+ AddTextPrinterParameterized3(windowId, 1, 166, 17, sCard_TextColorTable[sWonderCardData->gfx->titleTextPal], 0, sWonderCardData->idNumberText);
+ break;
+ }
+ case CARD_WIN_BODY:
+ // Print body text
+ for (; i < WONDER_CARD_BODY_TEXT_LINES; i++)
+ AddTextPrinterParameterized3(windowId, 3, 0, 16 * i + 2, sCard_TextColorTable[sWonderCardData->gfx->bodyTextPal], 0, sWonderCardData->bodyText[i]);
+ break;
+ case CARD_WIN_FOOTER:
+ // Print footer line 1
+ AddTextPrinterParameterized3(windowId, 3, 0,
+ sCard_FooterTextOffsets[sWonderCardData->card.type],
+ sCard_TextColorTable[sWonderCardData->gfx->footerTextPal],
+ 0, sWonderCardData->footerLine1Text);
+
+ // Print footer line 2
+ if (sWonderCardData->card.type != CARD_TYPE_LINK_STAT)
+ {
+ // Print gift text
+ // Odd that CARD_TYPE_STAMP is not ignored, it has empty text for this
+ AddTextPrinterParameterized3(windowId, 3, 0,
+ 16 + sCard_FooterTextOffsets[sWonderCardData->card.type],
+ sCard_TextColorTable[sWonderCardData->gfx->footerTextPal],
+ 0, sWonderCardData->giftText);
+ }
+ else
+ {
+ s32 x = 0;
+ s32 y = sCard_FooterTextOffsets[sWonderCardData->card.type] + 16;
+ s32 spacing = GetFontAttribute(3, FONTATTR_LETTER_SPACING);
+ for (; i < sWonderCardData->statFooterWidth; i++)
+ {
+ // Print stat text
+ AddTextPrinterParameterized3(windowId, 3, x, y, sCard_TextColorTable[sWonderCardData->gfx->footerTextPal], 0, sWonderCardData->statTextData[i].statText);
+ if (sWonderCardData->statTextData[i].statNumberText[0] != EOS)
+ {
+ // Print stat number
+ x += GetStringWidth(3, sWonderCardData->statTextData[i].statText, spacing);
+ AddTextPrinterParameterized3(windowId, 3, x, y,
+ sCard_TextColorTable[sWonderCardData->gfx->footerTextPal],
+ 0, sWonderCardData->statTextData[i].statNumberText);
+ x += GetStringWidth(3, sWonderCardData->statTextData[i].statNumberText, spacing) + sWonderCardData->statTextData[i].width;
+ }
+ }
+ }
+ break;
+ }
+ CopyWindowToVram(windowId, 3);
+}
+
+static void CreateCardSprites(void)
+{
+ u8 i = 0;
+ sWonderCardData->monIconSpriteId = SPRITE_NONE;
+
+ // Create icon sprite
+ if (sWonderCardData->cardMetadata.iconSpecies != SPECIES_NONE)
+ {
+ sWonderCardData->monIconSpriteId = CreateMonIconNoPersonality(GetIconSpeciesNoPersonality(sWonderCardData->cardMetadata.iconSpecies), SpriteCallbackDummy, 220, 20, 0, FALSE);
+ gSprites[sWonderCardData->monIconSpriteId].oam.priority = 2;
+ }
+
+ // Create stamp sprites
+ if (sWonderCardData->card.maxStamps != 0 && sWonderCardData->card.type == CARD_TYPE_STAMP)
+ {
+ LoadCompressedSpriteSheetUsingHeap(&sSpriteSheet_StampShadow);
+ LoadSpritePalette(&sSpritePalettes_StampShadow[sWonderCardData->gfx->stampShadowPal]);
+ for (; i < sWonderCardData->card.maxStamps; i++)
+ {
+ sWonderCardData->stampSpriteIds[i][0] = SPRITE_NONE;
+ sWonderCardData->stampSpriteIds[i][1] = SPRITE_NONE;
+ sWonderCardData->stampSpriteIds[i][0] = CreateSprite(&sSpriteTemplate_StampShadow, 216 - 32 * i, 144, 8);
+ if (sWonderCardData->cardMetadata.stampData[STAMP_SPECIES][i] != SPECIES_NONE)
+ sWonderCardData->stampSpriteIds[i][1] = CreateMonIconNoPersonality(GetIconSpeciesNoPersonality(sWonderCardData->cardMetadata.stampData[STAMP_SPECIES][i]),
+ SpriteCallbackDummy,
+ 216 - 32 * i,
+ 136, 0, 0);
+ }
+ }
+}
+
+static void DestroyCardSprites(void)
+{
+ u8 i = 0;
+
+ // Destroy icon sprite
+ if (sWonderCardData->monIconSpriteId != SPRITE_NONE)
+ FreeAndDestroyMonIconSprite(&gSprites[sWonderCardData->monIconSpriteId]);
+
+ // Destroy stamp sprites
+ if (sWonderCardData->card.maxStamps != 0 && sWonderCardData->card.type == CARD_TYPE_STAMP)
+ {
+ for (; i < sWonderCardData->card.maxStamps; i++)
+ {
+ if (sWonderCardData->stampSpriteIds[i][0] != SPRITE_NONE)
+ DestroySprite(&gSprites[sWonderCardData->stampSpriteIds[i][0]]);
+ if (sWonderCardData->stampSpriteIds[i][1] != SPRITE_NONE)
+ FreeAndDestroyMonIconSprite(&gSprites[sWonderCardData->stampSpriteIds[i][1]]);
+ }
+ FreeSpriteTilesByTag(TAG_STAMP_SHADOW);
+ FreeSpritePaletteByTag(TAG_STAMP_SHADOW);
+ }
+}
+
+//======================
+// Wonder News
+//======================
+
+enum {
+ NEWS_WIN_TITLE,
+ NEWS_WIN_BODY,
+ NEWS_WIN_COUNT
+};
+
+#define TAG_ARROWS 0x1000
+
+struct WonderNewsData
+{
+ /*0000*/ struct WonderNews news;
+ /*01bc*/ const struct WonderGraphics * gfx;
+ /*01c0*/ u8 arrowsRemoved:1;
+ u8 enterExitState:7;
+ /*01c1*/ u8 arrowTaskId;
+ /*01c2*/ bool8 scrolling:1;
+ u8 scrollIncrement:7;
+ /*01c3*/ bool8 scrollingDown:1;
+ u8 scrollTotal:7;
+ /*01c4*/ u16 scrollEnd;
+ /*01c6*/ u16 scrollOffset;
+ /*01c8*/ u16 windowIds[NEWS_WIN_COUNT];
+ /*01cc*/ u8 unused[2];
+ /*01ce*/ u8 titleText[WONDER_NEWS_TEXT_LENGTH + 1];
+ /*01f7*/ u8 bodyText[WONDER_NEWS_BODY_TEXT_LINES][WONDER_NEWS_TEXT_LENGTH + 1];
+ /*0394*/ struct ScrollArrowsTemplate arrowsTemplate;
+ /*03a4*/ u8 bgTilemapBuffer[0x1000];
+};
+
+EWRAM_DATA static struct WonderNewsData * sWonderNewsData = NULL;
+
+static void BufferNewsText(void);
+static void DrawNewsWindows(void);
+static void UpdateNewsScroll(void);
+
+static const u8 sNews_TextColorTable[][3] = {
+ {TEXT_COLOR_TRANSPARENT, TEXT_COLOR_DARK_GRAY, TEXT_COLOR_LIGHT_GRAY},
+ {TEXT_COLOR_TRANSPARENT, TEXT_COLOR_WHITE, TEXT_COLOR_DARK_GRAY}
+};
+
+static const struct WindowTemplate sNews_WindowTemplates[] = {
+ [NEWS_WIN_TITLE] = {
+ .bg = 0,
+ .tilemapLeft = 1,
+ .tilemapTop = 0,
+ .width = 28,
+ .height = 3,
+ .paletteNum = 2,
+ .baseBlock = 0x2AC
+ },
+ [NEWS_WIN_BODY] = {
+ .bg = 2,
+ .tilemapLeft = 1,
+ .tilemapTop = 3,
+ .width = 28,
+ .height = 20,
+ .paletteNum = 2,
+ .baseBlock = 0x07C
+ }
+};
+
+static const struct ScrollArrowsTemplate sNews_ArrowsTemplate = {
+ .firstArrowType = SCROLL_ARROW_UP,
+ .firstX = 232,
+ .firstY = 24,
+ .secondArrowType = SCROLL_ARROW_DOWN,
+ .secondX = 232,
+ .secondY = 152,
+ .fullyUpThreshold = 0,
+ .fullyDownThreshold = 2,
+ .tileTag = TAG_ARROWS,
+ .palTag = TAG_ARROWS,
+ .palNum = 0
+};
+
+static const u16 sWonderNewsPal1[] = INCBIN_U16("graphics/wonder_news/bg1.gbapal");
+static const u16 sWonderNewsPal7[] = INCBIN_U16("graphics/wonder_news/bg7.gbapal");
+static const u16 sWonderNewsPal8[] = INCBIN_U16("graphics/wonder_news/bg8.gbapal");
+static const u32 sWonderNewsGfx1[] = INCBIN_U32("graphics/wonder_news/bg1.4bpp.lz");
+static const u32 sWonderNewsTilemap1[] = INCBIN_U32("graphics/wonder_news/bg1.bin.lz");
+static const u32 sWonderNewsGfx2[] = INCBIN_U32("graphics/wonder_news/bg2.4bpp.lz");
+static const u32 sWonderNewsTilemap2[] = INCBIN_U32("graphics/wonder_news/bg2.bin.lz");
+static const u32 sWonderNewsGfx3[] = INCBIN_U32("graphics/wonder_news/bg3.4bpp.lz");
+static const u32 sWonderNewsTilemap3[] = INCBIN_U32("graphics/wonder_news/bg3.bin.lz");
+static const u32 sWonderNewsGfx7[] = INCBIN_U32("graphics/wonder_news/bg7.4bpp.lz");
+static const u32 sWonderNewsTilemap7[] = INCBIN_U32("graphics/wonder_news/bg7.bin.lz");
+static const u32 sWonderNewsGfx8[] = INCBIN_U32("graphics/wonder_news/bg8.4bpp.lz");
+static const u32 sWonderNewsTilemap8[] = INCBIN_U32("graphics/wonder_news/bg8.bin.lz");
+
+static const struct WonderGraphics sNewsGraphics[NUM_WONDER_BGS] = {
+ {.titleTextPal = 1, .bodyTextPal = 0, .tiles = sWonderNewsGfx1, .map = sWonderNewsTilemap1, .pal = sWonderNewsPal1},
+ {.titleTextPal = 1, .bodyTextPal = 0, .tiles = sWonderNewsGfx2, .map = sWonderNewsTilemap2, .pal = sWonderCardBgPal2},
+ {.titleTextPal = 1, .bodyTextPal = 0, .tiles = sWonderNewsGfx3, .map = sWonderNewsTilemap3, .pal = sWonderCardBgPal3},
+ {.titleTextPal = 1, .bodyTextPal = 0, .tiles = sWonderNewsGfx3, .map = sWonderNewsTilemap3, .pal = sWonderCardBgPal4},
+ {.titleTextPal = 1, .bodyTextPal = 0, .tiles = sWonderNewsGfx3, .map = sWonderNewsTilemap3, .pal = sWonderCardBgPal5},
+ {.titleTextPal = 1, .bodyTextPal = 0, .tiles = sWonderNewsGfx3, .map = sWonderNewsTilemap3, .pal = sWonderCardBgPal6},
+ {.titleTextPal = 1, .bodyTextPal = 0, .tiles = sWonderNewsGfx7, .map = sWonderNewsTilemap7, .pal = sWonderNewsPal7},
+ {.titleTextPal = 1, .bodyTextPal = 0, .tiles = sWonderNewsGfx8, .map = sWonderNewsTilemap8, .pal = sWonderNewsPal8}
+};
+
+bool32 WonderNews_Init(const struct WonderNews * news)
+{
+ if (news == NULL)
+ return FALSE;
+ sWonderNewsData = AllocZeroed(sizeof(*sWonderNewsData));
+ if (sWonderNewsData == NULL)
+ return FALSE;
+ sWonderNewsData->news = *news;
+ if (sWonderNewsData->news.bgType >= NUM_WONDER_BGS)
+ sWonderNewsData->news.bgType = 0;
+ sWonderNewsData->gfx = &sNewsGraphics[sWonderNewsData->news.bgType];
+ sWonderNewsData->arrowTaskId = TASK_NONE;
+ return TRUE;
+}
+
+void WonderNews_Destroy(void)
+{
+ if (sWonderNewsData != NULL)
+ {
+ *sWonderNewsData = (struct WonderNewsData){};
+ Free(sWonderNewsData);
+ sWonderNewsData = NULL;
+ }
+}
+
+s32 WonderNews_Enter(void)
+{
+ if (sWonderNewsData == NULL)
+ return -1;
+
+ switch (sWonderNewsData->enterExitState)
+ {
+ case 0:
+ BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK);
+ break;
+ case 1:
+ if (UpdatePaletteFade())
+ return 0;
+ ChangeBgY(0, 0, 0);
+ ChangeBgY(1, 0, 0);
+ ChangeBgY(2, 0, 0);
+ ChangeBgY(3, 0, 0);
+ SetGpuReg(REG_OFFSET_WIN0H, WIN_RANGE(0, DISPLAY_WIDTH));
+ SetGpuReg(REG_OFFSET_WIN0V, WIN_RANGE(26, 152));
+ SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ);
+ SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG0 | WINOUT_WIN01_BG1 | WINOUT_WIN01_BG3 | WINOUT_WIN01_OBJ);
+ SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON);
+ break;
+ case 2:
+ FillBgTilemapBufferRect_Palette0(0, 0x000, 0, 0, 30, 20);
+ FillBgTilemapBufferRect_Palette0(1, 0x000, 0, 0, 30, 20);
+ FillBgTilemapBufferRect_Palette0(2, 0x000, 0, 0, 30, 20);
+ FillBgTilemapBufferRect_Palette0(3, 0x000, 0, 0, 30, 20);
+ CopyBgTilemapBufferToVram(0);
+ CopyBgTilemapBufferToVram(1);
+ CopyBgTilemapBufferToVram(2);
+ CopyBgTilemapBufferToVram(3);
+ DecompressAndCopyTileDataToVram(3, sWonderNewsData->gfx->tiles, 0, 8, 0);
+ sWonderNewsData->windowIds[NEWS_WIN_TITLE] = AddWindow(&sNews_WindowTemplates[NEWS_WIN_TITLE]);
+ sWonderNewsData->windowIds[NEWS_WIN_BODY] = AddWindow(&sNews_WindowTemplates[NEWS_WIN_BODY]);
+ break;
+ case 3:
+ if (FreeTempTileDataBuffersIfPossible())
+ return 0;
+ LoadPalette(GetTextWindowPalette(1), 0x20, 0x20);
+ gPaletteFade.bufferTransferDisabled = TRUE;
+ LoadPalette(sWonderNewsData->gfx->pal, 0x10, 0x20);
+ LZ77UnCompWram(sWonderNewsData->gfx->map, sWonderNewsData->bgTilemapBuffer);
+ CopyRectToBgTilemapBufferRect(1, sWonderNewsData->bgTilemapBuffer, 0, 0, 30, 3, 0, 0, 30, 3, 1, 8, 0);
+ CopyRectToBgTilemapBufferRect(3, sWonderNewsData->bgTilemapBuffer, 0, 3, 30, 23, 0, 3, 30, 23, 1, 8, 0);
+ CopyBgTilemapBufferToVram(1);
+ CopyBgTilemapBufferToVram(3);
+ break;
+ case 4:
+ BufferNewsText();
+ break;
+ case 5:
+ DrawNewsWindows();
+ CopyBgTilemapBufferToVram(0);
+ CopyBgTilemapBufferToVram(2);
+ break;
+ case 6:
+ ShowBg(1);
+ ShowBg(2);
+ ShowBg(3);
+ gPaletteFade.bufferTransferDisabled = FALSE;
+ sWonderNewsData->arrowTaskId = AddScrollIndicatorArrowPair(&sWonderNewsData->arrowsTemplate, &sWonderNewsData->scrollOffset);
+ BeginNormalPaletteFade(PALETTES_ALL, 0, 16, 0, RGB_BLACK);
+ UpdatePaletteFade();
+ break;
+ default:
+ if (UpdatePaletteFade())
+ return 0;
+ sWonderNewsData->enterExitState = 0;
+ return 1;
+ }
+
+ sWonderNewsData->enterExitState++;
+ return 0;
+}
+
+s32 WonderNews_Exit(bool32 useCancel)
+{
+ if (sWonderNewsData == NULL)
+ return -1;
+ switch (sWonderNewsData->enterExitState)
+ {
+ case 0:
+ BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK);
+ break;
+ case 1:
+ if (UpdatePaletteFade())
+ return 0;
+ ChangeBgY(2, 0, 0);
+ SetGpuReg(REG_OFFSET_WIN0H, 0);
+ SetGpuReg(REG_OFFSET_WIN0V, 0);
+ SetGpuReg(REG_OFFSET_WININ, 0);
+ SetGpuReg(REG_OFFSET_WINOUT, 0);
+ ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON);
+ break;
+ case 2:
+ FillBgTilemapBufferRect_Palette0(0, 0x000, 0, 0, 30, 20);
+ FillBgTilemapBufferRect_Palette0(1, 0x000, 0, 0, 30, 20);
+ FillBgTilemapBufferRect_Palette0(2, 0x000, 0, 0, 30, 24);
+ FillBgTilemapBufferRect_Palette0(3, 0x000, 0, 0, 30, 24);
+ CopyBgTilemapBufferToVram(0);
+ CopyBgTilemapBufferToVram(1);
+ CopyBgTilemapBufferToVram(2);
+ CopyBgTilemapBufferToVram(3);
+ break;
+ case 3:
+ HideBg(1);
+ HideBg(2);
+ RemoveWindow(sWonderNewsData->windowIds[NEWS_WIN_BODY]);
+ RemoveWindow(sWonderNewsData->windowIds[NEWS_WIN_TITLE]);
+ break;
+ case 4:
+ ChangeBgY(2, 0, 0);
+ ChangeBgY(3, 0, 0);
+ if (sWonderNewsData->arrowTaskId != TASK_NONE)
+ {
+ RemoveScrollIndicatorArrowPair(sWonderNewsData->arrowTaskId);
+ sWonderNewsData->arrowTaskId = TASK_NONE;
+ }
+ break;
+ case 5:
+ PrintMysteryGiftOrEReaderTopMenu(gGiftIsFromEReader, useCancel);
+ MG_DrawCheckerboardPattern(3);
+ CopyBgTilemapBufferToVram(0);
+ CopyBgTilemapBufferToVram(3);
+ BeginNormalPaletteFade(PALETTES_ALL, 0, 16, 0, RGB_BLACK);
+ break;
+ default:
+ if (UpdatePaletteFade())
+ return 0;
+ sWonderNewsData->enterExitState = 0;
+ return 1;
+ }
+ sWonderNewsData->enterExitState++;
+ return 0;
+}
+
+void WonderNews_RemoveScrollIndicatorArrowPair(void)
+{
+ if (!sWonderNewsData->arrowsRemoved && sWonderNewsData->arrowTaskId != TASK_NONE)
+ {
+ RemoveScrollIndicatorArrowPair(sWonderNewsData->arrowTaskId);
+ sWonderNewsData->arrowTaskId = TASK_NONE;
+ sWonderNewsData->arrowsRemoved = TRUE;
+ }
+}
+
+
+void WonderNews_AddScrollIndicatorArrowPair(void)
+{
+ if (sWonderNewsData->arrowsRemoved)
+ {
+ sWonderNewsData->arrowTaskId = AddScrollIndicatorArrowPair(&sWonderNewsData->arrowsTemplate, &sWonderNewsData->scrollOffset);
+ sWonderNewsData->arrowsRemoved = FALSE;
+ }
+}
+
+u32 WonderNews_GetInput(u16 input)
+{
+ if (sWonderNewsData->scrolling)
+ {
+ UpdateNewsScroll();
+ return NEWS_INPUT_NONE;
+ }
+ switch (input)
+ {
+ case A_BUTTON:
+ return NEWS_INPUT_A;
+ case B_BUTTON:
+ return NEWS_INPUT_B;
+ case DPAD_UP:
+ if (sWonderNewsData->scrollOffset == 0)
+ return NEWS_INPUT_NONE;
+ if (sWonderNewsData->arrowsRemoved)
+ return NEWS_INPUT_NONE;
+ sWonderNewsData->scrollingDown = FALSE;
+ break;
+ case DPAD_DOWN:
+ if (sWonderNewsData->scrollOffset == sWonderNewsData->scrollEnd)
+ return NEWS_INPUT_NONE;
+ if (sWonderNewsData->arrowsRemoved)
+ return NEWS_INPUT_NONE;
+ sWonderNewsData->scrollingDown = TRUE;
+ break;
+ default:
+ return NEWS_INPUT_NONE;
+ }
+
+ // Init scroll
+ sWonderNewsData->scrolling = TRUE;
+ sWonderNewsData->scrollIncrement = 2;
+ sWonderNewsData->scrollTotal = 0;
+ if (!sWonderNewsData->scrollingDown)
+ return NEWS_INPUT_SCROLL_UP;
+ else
+ return NEWS_INPUT_SCROLL_DOWN;
+}
+
+static void BufferNewsText(void)
+{
+ u8 i = 0;
+
+ // Copy title text
+ memcpy(sWonderNewsData->titleText, sWonderNewsData->news.titleText, WONDER_NEWS_TEXT_LENGTH);
+ sWonderNewsData->titleText[WONDER_NEWS_TEXT_LENGTH] = EOS;
+
+ // Copy body text
+ for (; i < WONDER_NEWS_BODY_TEXT_LINES; i++)
+ {
+ memcpy(sWonderNewsData->bodyText[i], sWonderNewsData->news.bodyText[i], WONDER_NEWS_TEXT_LENGTH);
+ sWonderNewsData->bodyText[i][WONDER_NEWS_TEXT_LENGTH] = EOS;
+ if (i > 7 && sWonderNewsData->bodyText[i][0] != EOS)
+ sWonderNewsData->scrollEnd++;
+ }
+ sWonderNewsData->arrowsTemplate = sNews_ArrowsTemplate;
+ sWonderNewsData->arrowsTemplate.fullyDownThreshold = sWonderNewsData->scrollEnd;
+}
+
+static void DrawNewsWindows(void)
+{
+ u8 i = 0;
+ s32 x;
+ PutWindowTilemap(sWonderNewsData->windowIds[NEWS_WIN_TITLE]);
+ PutWindowTilemap(sWonderNewsData->windowIds[NEWS_WIN_BODY]);
+ FillWindowPixelBuffer(sWonderNewsData->windowIds[NEWS_WIN_TITLE], 0);
+ FillWindowPixelBuffer(sWonderNewsData->windowIds[NEWS_WIN_BODY], 0);
+
+ // Print title text
+ x = (224 - GetStringWidth(3, sWonderNewsData->titleText, GetFontAttribute(3, FONTATTR_LETTER_SPACING))) / 2;
+ if (x < 0)
+ x = 0;
+ AddTextPrinterParameterized3(sWonderNewsData->windowIds[NEWS_WIN_TITLE], 3, x, 6, sNews_TextColorTable[sWonderNewsData->gfx->titleTextPal], 0, sWonderNewsData->titleText);
+
+ // Print body text
+ for (; i < WONDER_NEWS_BODY_TEXT_LINES; i++)
+ AddTextPrinterParameterized3(sWonderNewsData->windowIds[NEWS_WIN_BODY], 3, 0,
+ 16 * i + 2,
+ sNews_TextColorTable[sWonderNewsData->gfx->bodyTextPal],
+ 0, sWonderNewsData->bodyText[i]);
+
+ CopyWindowToVram(sWonderNewsData->windowIds[NEWS_WIN_TITLE], 3);
+ CopyWindowToVram(sWonderNewsData->windowIds[NEWS_WIN_BODY], 3);
+}
+
+static void UpdateNewsScroll(void)
+{
+ u16 bgMove = sWonderNewsData->scrollIncrement;
+ bgMove *= 256;
+ if (sWonderNewsData->scrollingDown)
+ {
+ ChangeBgY(2, bgMove, BG_COORD_ADD);
+ ChangeBgY(3, bgMove, BG_COORD_ADD);
+ }
+ else
+ {
+ ChangeBgY(2, bgMove, BG_COORD_SUB);
+ ChangeBgY(3, bgMove, BG_COORD_SUB);
+ }
+ sWonderNewsData->scrollTotal += sWonderNewsData->scrollIncrement;
+ if (sWonderNewsData->scrollTotal > 15)
+ {
+ if (sWonderNewsData->scrollingDown)
+ sWonderNewsData->scrollOffset++;
+ else
+ sWonderNewsData->scrollOffset--;
+ sWonderNewsData->scrolling = FALSE;
+ sWonderNewsData->scrollTotal = 0;
+ }
+}
diff --git a/src/new_game.c b/src/new_game.c
index 5bb3d44c5..4bd3d3704 100644
--- a/src/new_game.c
+++ b/src/new_game.c
@@ -43,7 +43,7 @@
#include "player_pc.h"
#include "field_specials.h"
#include "berry_powder.h"
-#include "mevent.h"
+#include "mystery_gift.h"
#include "union_room_chat.h"
extern const u8 EventScript_ResetAllMapFlags[];
@@ -200,7 +200,7 @@ void NewGameInitData(void)
ResetAllApprenticeData();
ClearRankingHallRecords();
InitMatchCallCounters();
- sub_801AFD8();
+ ClearMysteryGift();
WipeTrainerNameRecords();
ResetTrainerHillResults();
ResetContestLinkResults();
diff --git a/src/player_pc.c b/src/player_pc.c
index a4e7505b4..3b37b0219 100644
--- a/src/player_pc.c
+++ b/src/player_pc.c
@@ -396,7 +396,7 @@ static void InitPlayerPCMenu(u8 taskId)
else // Bedroom PC
windowTemplate = sWindowTemplates_MainMenus[WIN_MAIN_MENU_BEDROOM];
- windowTemplate.width = sub_81DB3D8(sPlayerPCMenuActions, sTopMenuOptionOrder, sTopMenuNumOptions);
+ windowTemplate.width = GetMaxWidthInSubsetOfMenuTable(sPlayerPCMenuActions, sTopMenuOptionOrder, sTopMenuNumOptions);
tWindowId = AddWindow(&windowTemplate);
SetStandardWindowBorderStyle(tWindowId, 0);
sub_81995E4(tWindowId, sTopMenuNumOptions, sPlayerPCMenuActions, sTopMenuOptionOrder);
diff --git a/src/pokedex.c b/src/pokedex.c
index eba97beb7..81d7c6730 100644
--- a/src/pokedex.c
+++ b/src/pokedex.c
@@ -104,13 +104,15 @@ enum
#define POKEBALL_ROTATION_TOP 64
#define POKEBALL_ROTATION_BOTTOM (POKEBALL_ROTATION_TOP - 16)
-// EWRAM
+// Coordinates of the Pokémon sprite on its page (info/cry screens)
+#define MON_PAGE_X 48
+#define MON_PAGE_Y 56
+
static EWRAM_DATA struct PokedexView *sPokedexView = NULL;
static EWRAM_DATA u16 sLastSelectedPokemon = 0;
static EWRAM_DATA u8 sPokeBallRotation = 0;
static EWRAM_DATA struct PokedexListItem *sPokedexListItem = NULL;
-// IWRAM common
// This is written to, but never read.
u8 gUnusedPokedexU8;
void (*gPokedexVBlankCB)(void);
@@ -239,7 +241,7 @@ static void SpriteCB_DexListStartMenuCursor(struct Sprite *sprite);
static void SpriteCB_PokedexListMonSprite(struct Sprite *sprite);
static u8 LoadInfoScreen(struct PokedexListItem*, u8 monSpriteId);
static bool8 IsInfoScreenScrolling(u8);
-static u8 sub_80BE9F8(struct PokedexListItem*, u8);
+static u8 StartInfoScreenScroll(struct PokedexListItem*, u8);
static void Task_LoadInfoScreen(u8);
static void Task_HandleInfoScreenInput(u8);
static void Task_SwitchScreensFromInfoScreen(u8);
@@ -268,7 +270,7 @@ static void PrintMonHeight(u16 height, u8 left, u8 top);
static void PrintMonWeight(u16 weight, u8 left, u8 top);
static void ResetOtherVideoRegisters(u16);
static u8 PrintCryScreenSpeciesName(u8, u16, u8, u8);
-static void PrintFootprint(u8 windowId, u16 dexNum);
+static void DrawFootprint(u8 windowId, u16 dexNum);
static u16 CreateSizeScreenTrainerPic(u16, s16, s16, s8);
static u16 GetNextPosition(u8, u16, u16, u16);
static u8 LoadSearchMenu(void);
@@ -1655,7 +1657,7 @@ void Task_OpenPokedexMainPage(u8 taskId)
gTasks[taskId].func = Task_HandlePokedexInput;
}
-#define tTaskId data[0]
+#define tLoadScreenTaskId data[0]
static void Task_HandlePokedexInput(u8 taskId)
{
@@ -1667,7 +1669,7 @@ static void Task_HandlePokedexInput(u8 taskId)
}
else
{
- if ((JOY_NEW(A_BUTTON)) && sPokedexView->pokedexList[sPokedexView->selectedPokemon].seen)
+ if (JOY_NEW(A_BUTTON) && sPokedexView->pokedexList[sPokedexView->selectedPokemon].seen)
{
UpdateSelectedMonSpriteId();
BeginNormalPaletteFade(~(1 << (gSprites[sPokedexView->selectedMonSpriteId].oam.paletteNum + 16)), 0, 0, 0x10, RGB_BLACK);
@@ -1688,7 +1690,7 @@ static void Task_HandlePokedexInput(u8 taskId)
{
PlaySE(SE_SELECT);
BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 0x10, RGB_BLACK);
- gTasks[taskId].tTaskId = LoadSearchMenu();
+ gTasks[taskId].tLoadScreenTaskId = LoadSearchMenu();
sPokedexView->screenSwitchState = 0;
sPokedexView->pokeBallRotationBackup = sPokedexView->pokeBallRotation;
sPokedexView->selectedPokemonBackup = sPokedexView->selectedPokemon;
@@ -1768,12 +1770,12 @@ static void Task_HandlePokedexStartMenuInput(u8 taskId)
gTasks[taskId].func = Task_HandlePokedexInput;
PlaySE(SE_SELECT);
}
- else if ((JOY_REPEAT(DPAD_UP)) && sPokedexView->menuCursorPos != 0)
+ else if (JOY_REPEAT(DPAD_UP) && sPokedexView->menuCursorPos != 0)
{
sPokedexView->menuCursorPos--;
PlaySE(SE_SELECT);
}
- else if ((JOY_REPEAT(DPAD_DOWN)) && sPokedexView->menuCursorPos < 3)
+ else if (JOY_REPEAT(DPAD_DOWN) && sPokedexView->menuCursorPos < 3)
{
sPokedexView->menuCursorPos++;
PlaySE(SE_SELECT);
@@ -1781,25 +1783,28 @@ static void Task_HandlePokedexStartMenuInput(u8 taskId)
}
}
+// Opening the info screen from list view. Pokémon sprite is moving to its new position, wait for it to arrive
static void Task_OpenInfoScreenAfterMonMovement(u8 taskId)
{
- if (gSprites[sPokedexView->selectedMonSpriteId].x == 48 && gSprites[sPokedexView->selectedMonSpriteId].y == 56)
+ if (gSprites[sPokedexView->selectedMonSpriteId].x == MON_PAGE_X && gSprites[sPokedexView->selectedMonSpriteId].y == MON_PAGE_Y)
{
sPokedexView->currentPageBackup = sPokedexView->currentPage;
- gTasks[taskId].tTaskId = LoadInfoScreen(&sPokedexView->pokedexList[sPokedexView->selectedPokemon], sPokedexView->selectedMonSpriteId);
+ gTasks[taskId].tLoadScreenTaskId = LoadInfoScreen(&sPokedexView->pokedexList[sPokedexView->selectedPokemon], sPokedexView->selectedMonSpriteId);
gTasks[taskId].func = Task_WaitForExitInfoScreen;
}
}
static void Task_WaitForExitInfoScreen(u8 taskId)
{
- if (gTasks[gTasks[taskId].tTaskId].isActive)
+ if (gTasks[gTasks[taskId].tLoadScreenTaskId].isActive)
{
- if (sPokedexView->currentPage == PAGE_INFO && !IsInfoScreenScrolling(gTasks[taskId].tTaskId) && TryDoInfoScreenScroll())
- sub_80BE9F8(&sPokedexView->pokedexList[sPokedexView->selectedPokemon], gTasks[taskId].tTaskId);
+ // While active, handle scroll input
+ if (sPokedexView->currentPage == PAGE_INFO && !IsInfoScreenScrolling(gTasks[taskId].tLoadScreenTaskId) && TryDoInfoScreenScroll())
+ StartInfoScreenScroll(&sPokedexView->pokedexList[sPokedexView->selectedPokemon], gTasks[taskId].tLoadScreenTaskId);
}
else
{
+ // Exiting, back to list view
sLastSelectedPokemon = sPokedexView->selectedPokemon;
sPokeBallRotation = sPokedexView->pokeBallRotation;
gTasks[taskId].func = Task_OpenPokedexMainPage;
@@ -1808,7 +1813,7 @@ static void Task_WaitForExitInfoScreen(u8 taskId)
static void Task_WaitForExitSearch(u8 taskId)
{
- if (!gTasks[gTasks[taskId].tTaskId].isActive)
+ if (!gTasks[gTasks[taskId].tLoadScreenTaskId].isActive)
{
ClearMonSprites();
@@ -1867,7 +1872,7 @@ static void Task_HandleSearchResultsInput(u8 taskId)
}
else
{
- if ((JOY_NEW(A_BUTTON)) && sPokedexView->pokedexList[sPokedexView->selectedPokemon].seen)
+ if (JOY_NEW(A_BUTTON) && sPokedexView->pokedexList[sPokedexView->selectedPokemon].seen)
{
u32 a;
@@ -1890,7 +1895,7 @@ static void Task_HandleSearchResultsInput(u8 taskId)
else if (JOY_NEW(SELECT_BUTTON))
{
BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 0x10, RGB_BLACK);
- gTasks[taskId].tTaskId = LoadSearchMenu();
+ gTasks[taskId].tLoadScreenTaskId = LoadSearchMenu();
sPokedexView->screenSwitchState = 0;
gTasks[taskId].func = Task_WaitForExitSearch;
PlaySE(SE_PC_LOGIN);
@@ -1970,12 +1975,12 @@ static void Task_HandleSearchResultsStartMenuInput(u8 taskId)
gTasks[taskId].func = Task_HandleSearchResultsInput;
PlaySE(SE_SELECT);
}
- else if ((JOY_REPEAT(DPAD_UP)) && sPokedexView->menuCursorPos)
+ else if (JOY_REPEAT(DPAD_UP) && sPokedexView->menuCursorPos)
{
sPokedexView->menuCursorPos--;
PlaySE(SE_SELECT);
}
- else if ((JOY_REPEAT(DPAD_DOWN)) && sPokedexView->menuCursorPos < 4)
+ else if (JOY_REPEAT(DPAD_DOWN) && sPokedexView->menuCursorPos < 4)
{
sPokedexView->menuCursorPos++;
PlaySE(SE_SELECT);
@@ -1985,10 +1990,10 @@ static void Task_HandleSearchResultsStartMenuInput(u8 taskId)
static void Task_OpenSearchResultsInfoScreenAfterMonMovement(u8 taskId)
{
- if (gSprites[sPokedexView->selectedMonSpriteId].x == 48 && gSprites[sPokedexView->selectedMonSpriteId].y == 56)
+ if (gSprites[sPokedexView->selectedMonSpriteId].x == MON_PAGE_X && gSprites[sPokedexView->selectedMonSpriteId].y == MON_PAGE_Y)
{
sPokedexView->currentPageBackup = sPokedexView->currentPage;
- gTasks[taskId].tTaskId = LoadInfoScreen(&sPokedexView->pokedexList[sPokedexView->selectedPokemon], sPokedexView->selectedMonSpriteId);
+ gTasks[taskId].tLoadScreenTaskId = LoadInfoScreen(&sPokedexView->pokedexList[sPokedexView->selectedPokemon], sPokedexView->selectedMonSpriteId);
sPokedexView->selectedMonSpriteId = -1;
gTasks[taskId].func = Task_WaitForExitSearchResultsInfoScreen;
}
@@ -1996,13 +2001,15 @@ static void Task_OpenSearchResultsInfoScreenAfterMonMovement(u8 taskId)
static void Task_WaitForExitSearchResultsInfoScreen(u8 taskId)
{
- if (gTasks[gTasks[taskId].tTaskId].isActive)
+ if (gTasks[gTasks[taskId].tLoadScreenTaskId].isActive)
{
- if (sPokedexView->currentPage == PAGE_INFO && !IsInfoScreenScrolling(gTasks[taskId].tTaskId) && TryDoInfoScreenScroll())
- sub_80BE9F8(&sPokedexView->pokedexList[sPokedexView->selectedPokemon], gTasks[taskId].tTaskId);
+ // While active, handle scroll input
+ if (sPokedexView->currentPage == PAGE_INFO && !IsInfoScreenScrolling(gTasks[taskId].tLoadScreenTaskId) && TryDoInfoScreenScroll())
+ StartInfoScreenScroll(&sPokedexView->pokedexList[sPokedexView->selectedPokemon], gTasks[taskId].tLoadScreenTaskId);
}
else
{
+ // Exiting, back to search results
gTasks[taskId].func = Task_OpenSearchResults;
}
}
@@ -2037,7 +2044,7 @@ static void Task_ClosePokedexFromSearchResultsStartMenu(u8 taskId)
}
}
-#undef tTaskId
+#undef tLoadScreenTaskId
// For loading main pokedex page or pokedex search results
static bool8 LoadPokedexListPage(u8 page)
@@ -2584,7 +2591,7 @@ static u16 TryDoPokedexScroll(u16 selectedMon, u16 ignored)
u16 startingPos;
u8 scrollDir = 0;
- if ((JOY_HELD(DPAD_UP)) && (selectedMon > 0))
+ if (JOY_HELD(DPAD_UP) && (selectedMon > 0))
{
scrollDir = 1;
selectedMon = GetNextPosition(1, selectedMon, 0, sPokedexView->pokemonListCount - 1);
@@ -2592,7 +2599,7 @@ static u16 TryDoPokedexScroll(u16 selectedMon, u16 ignored)
CreateMonListEntry(1, selectedMon, ignored);
PlaySE(SE_DEX_SCROLL);
}
- else if ((JOY_HELD(DPAD_DOWN)) && (selectedMon < sPokedexView->pokemonListCount - 1))
+ else if (JOY_HELD(DPAD_DOWN) && (selectedMon < sPokedexView->pokemonListCount - 1))
{
scrollDir = 2;
selectedMon = GetNextPosition(0, selectedMon, 0, sPokedexView->pokemonListCount - 1);
@@ -2600,7 +2607,7 @@ static u16 TryDoPokedexScroll(u16 selectedMon, u16 ignored)
CreateMonListEntry(2, selectedMon, ignored);
PlaySE(SE_DEX_SCROLL);
}
- else if ((JOY_NEW(DPAD_LEFT)) && (selectedMon > 0))
+ else if (JOY_NEW(DPAD_LEFT) && (selectedMon > 0))
{
startingPos = selectedMon;
@@ -2611,7 +2618,7 @@ static u16 TryDoPokedexScroll(u16 selectedMon, u16 ignored)
CreateMonSpritesAtPos(selectedMon, 0xE);
PlaySE(SE_DEX_PAGE);
}
- else if ((JOY_NEW(DPAD_RIGHT)) && (selectedMon < sPokedexView->pokemonListCount - 1))
+ else if (JOY_NEW(DPAD_RIGHT) && (selectedMon < sPokedexView->pokemonListCount - 1))
{
startingPos = selectedMon;
for (i = 0; i < 7; i++)
@@ -2660,7 +2667,7 @@ static bool8 TryDoInfoScreenScroll(void)
u16 nextPokemon;
u16 selectedPokemon = sPokedexView->selectedPokemon;
- if ((JOY_NEW(DPAD_UP)) && selectedPokemon)
+ if (JOY_NEW(DPAD_UP) && selectedPokemon)
{
nextPokemon = selectedPokemon;
while (nextPokemon != 0)
@@ -2683,7 +2690,7 @@ static bool8 TryDoInfoScreenScroll(void)
return TRUE;
}
}
- else if ((JOY_NEW(DPAD_DOWN)) && selectedPokemon < sPokedexView->pokemonListCount - 1)
+ else if (JOY_NEW(DPAD_DOWN) && selectedPokemon < sPokedexView->pokemonListCount - 1)
{
nextPokemon = selectedPokemon;
while (nextPokemon < sPokedexView->pokemonListCount - 1)
@@ -3000,16 +3007,16 @@ void SpriteCB_MoveMonForInfoScreen(struct Sprite *sprite)
sprite->oam.affineMode = ST_OAM_AFFINE_OFF;
sprite->x2 = 0;
sprite->y2 = 0;
- if (sprite->x != 48 || sprite->y != 56)
+ if (sprite->x != MON_PAGE_X || sprite->y != MON_PAGE_Y)
{
- if (sprite->x > 48)
+ if (sprite->x > MON_PAGE_X)
sprite->x--;
- if (sprite->x < 48)
+ if (sprite->x < MON_PAGE_X)
sprite->x++;
- if (sprite->y > 56)
+ if (sprite->y > MON_PAGE_Y)
sprite->y--;
- if (sprite->y < 56)
+ if (sprite->y < MON_PAGE_Y)
sprite->y++;
}
else
@@ -3163,7 +3170,12 @@ static void PrintInfoScreenText(const u8* str, u8 left, u8 top)
AddTextPrinterParameterized4(0, 1, left, top, 0, 0, color, -1, str);
}
-#define tMonSpriteId data[4]
+#define tScrolling data[0]
+#define tMonSpriteDone data[1]
+#define tBgLoaded data[2]
+#define tSkipCry data[3]
+#define tMonSpriteId data[4]
+#define tTrainerSpriteId data[5]
static u8 LoadInfoScreen(struct PokedexListItem* item, u8 monSpriteId)
{
@@ -3171,12 +3183,12 @@ static u8 LoadInfoScreen(struct PokedexListItem* item, u8 monSpriteId)
sPokedexListItem = item;
taskId = CreateTask(Task_LoadInfoScreen, 0);
- gTasks[taskId].data[0] = 0;
- gTasks[taskId].data[1] = 1;
- gTasks[taskId].data[2] = 0;
- gTasks[taskId].data[3] = 0;
+ gTasks[taskId].tScrolling = FALSE;
+ gTasks[taskId].tMonSpriteDone = TRUE; // Already has sprite from list view
+ gTasks[taskId].tBgLoaded = FALSE;
+ gTasks[taskId].tSkipCry = FALSE;
gTasks[taskId].tMonSpriteId = monSpriteId;
- gTasks[taskId].data[5] = 255;
+ gTasks[taskId].tTrainerSpriteId = SPRITE_NONE;
ResetBgsAndClearDma3BusyFlags(0);
InitBgsFromTemplates(0, sInfoScreen_BgTemplate, ARRAY_COUNT(sInfoScreen_BgTemplate));
SetBgTilemapBuffer(3, AllocZeroed(BG_SCREEN_SIZE));
@@ -3191,19 +3203,19 @@ static u8 LoadInfoScreen(struct PokedexListItem* item, u8 monSpriteId)
static bool8 IsInfoScreenScrolling(u8 taskId)
{
- if (gTasks[taskId].data[0] == 0 && gTasks[taskId].func == Task_HandleInfoScreenInput)
+ if (!gTasks[taskId].tScrolling && gTasks[taskId].func == Task_HandleInfoScreenInput)
return FALSE;
else
return TRUE;
}
-static u8 sub_80BE9F8(struct PokedexListItem *item, u8 taskId)
+static u8 StartInfoScreenScroll(struct PokedexListItem *item, u8 taskId)
{
sPokedexListItem = item;
- gTasks[taskId].data[0] = 1;
- gTasks[taskId].data[1] = 0;
- gTasks[taskId].data[2] = 0;
- gTasks[taskId].data[3] = 0;
+ gTasks[taskId].tScrolling = TRUE;
+ gTasks[taskId].tMonSpriteDone = FALSE;
+ gTasks[taskId].tBgLoaded = FALSE;
+ gTasks[taskId].tSkipCry = FALSE;
return taskId;
}
@@ -3221,9 +3233,9 @@ static void Task_LoadInfoScreen(u8 taskId)
gPokedexVBlankCB = gMain.vblankCallback;
SetVBlankCallback(NULL);
r2 = 0;
- if (gTasks[taskId].data[1] != 0)
+ if (gTasks[taskId].tMonSpriteDone)
r2 += DISPCNT_OBJ_ON;
- if (gTasks[taskId].data[2] != 0)
+ if (gTasks[taskId].tBgLoaded)
r2 |= DISPCNT_BG1_ON;
ResetOtherVideoRegisters(r2);
gMain.state = 1;
@@ -3235,7 +3247,7 @@ static void Task_LoadInfoScreen(u8 taskId)
FillWindowPixelBuffer(WIN_INFO, PIXEL_FILL(0));
PutWindowTilemap(WIN_INFO);
PutWindowTilemap(WIN_FOOTPRINT);
- PrintFootprint(WIN_FOOTPRINT, sPokedexListItem->dexNum);
+ DrawFootprint(WIN_FOOTPRINT, sPokedexListItem->dexNum);
CopyWindowToVram(WIN_FOOTPRINT, 2);
gMain.state++;
break;
@@ -3259,9 +3271,9 @@ static void Task_LoadInfoScreen(u8 taskId)
gMain.state++;
break;
case 5:
- if (gTasks[taskId].data[1] == 0)
+ if (!gTasks[taskId].tMonSpriteDone)
{
- gTasks[taskId].tMonSpriteId = (u16)CreateMonSpriteFromNationalDexNumber(sPokedexListItem->dexNum, 48, 56, 0);
+ gTasks[taskId].tMonSpriteId = (u16)CreateMonSpriteFromNationalDexNumber(sPokedexListItem->dexNum, MON_PAGE_X, MON_PAGE_Y, 0);
gSprites[gTasks[taskId].tMonSpriteId].oam.priority = 0;
}
gMain.state++;
@@ -3270,9 +3282,9 @@ static void Task_LoadInfoScreen(u8 taskId)
{
u32 preservedPalettes = 0;
- if (gTasks[taskId].data[2] != 0)
+ if (gTasks[taskId].tBgLoaded)
preservedPalettes = 0x14; // each bit represents a palette index
- if (gTasks[taskId].data[1] != 0)
+ if (gTasks[taskId].tMonSpriteDone)
preservedPalettes |= (1 << (gSprites[gTasks[taskId].tMonSpriteId].oam.paletteNum + 16));
BeginNormalPaletteFade(~preservedPalettes, 0, 16, 0, RGB_BLACK);
SetVBlankCallback(gPokedexVBlankCB);
@@ -3294,10 +3306,10 @@ static void Task_LoadInfoScreen(u8 taskId)
if (!gPaletteFade.active)
{
gMain.state++;
- if (gTasks[taskId].data[3] == 0)
+ if (!gTasks[taskId].tSkipCry)
{
StopCryAndClearCrySongs();
- PlayCry2(NationalPokedexNumToSpecies(sPokedexListItem->dexNum), 0, 0x7D, 0xA);
+ PlayCry2(NationalPokedexNumToSpecies(sPokedexListItem->dexNum), 0, 125, 10);
}
else
{
@@ -3310,10 +3322,10 @@ static void Task_LoadInfoScreen(u8 taskId)
gMain.state++;
break;
case 10:
- gTasks[taskId].data[0] = 0;
- gTasks[taskId].data[1] = 0;
- gTasks[taskId].data[2] = 1;
- gTasks[taskId].data[3] = 1;
+ gTasks[taskId].tScrolling = FALSE;
+ gTasks[taskId].tMonSpriteDone = FALSE; // Reload next time screen comes up
+ gTasks[taskId].tBgLoaded = TRUE;
+ gTasks[taskId].tSkipCry = TRUE;
gTasks[taskId].func = Task_HandleInfoScreenInput;
gMain.state = 0;
break;
@@ -3341,7 +3353,7 @@ static void FreeInfoScreenWindowAndBgBuffers(void)
static void Task_HandleInfoScreenInput(u8 taskId)
{
- if (gTasks[taskId].data[0] != 0)
+ if (gTasks[taskId].tScrolling)
{
// Scroll up/down
BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK);
@@ -3393,8 +3405,8 @@ static void Task_HandleInfoScreenInput(u8 taskId)
}
return;
}
- if (((JOY_NEW(DPAD_LEFT))
- || ((JOY_NEW(L_BUTTON)) && gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_LR))
+ if ((JOY_NEW(DPAD_LEFT)
+ || (JOY_NEW(L_BUTTON) && gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_LR))
&& sPokedexView->selectedScreen > 0)
{
sPokedexView->selectedScreen--;
@@ -3402,8 +3414,8 @@ static void Task_HandleInfoScreenInput(u8 taskId)
PlaySE(SE_DEX_PAGE);
return;
}
- if (((JOY_NEW(DPAD_RIGHT))
- || ((JOY_NEW(R_BUTTON)) && gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_LR))
+ if ((JOY_NEW(DPAD_RIGHT)
+ || (JOY_NEW(R_BUTTON) && gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_LR))
&& sPokedexView->selectedScreen < CANCEL_SCREEN)
{
sPokedexView->selectedScreen++;
@@ -3552,7 +3564,7 @@ static void Task_LoadCryScreen(u8 taskId)
gMain.state++;
break;
case 5:
- gTasks[taskId].tMonSpriteId = CreateMonSpriteFromNationalDexNumber(sPokedexListItem->dexNum, 48, 56, 0);
+ gTasks[taskId].tMonSpriteId = CreateMonSpriteFromNationalDexNumber(sPokedexListItem->dexNum, MON_PAGE_X, MON_PAGE_Y, 0);
gSprites[gTasks[taskId].tMonSpriteId].oam.priority = 0;
gDexCryScreenState = 0;
gMain.state++;
@@ -3640,8 +3652,8 @@ static void Task_HandleCryScreenInput(u8 taskId)
PlaySE(SE_PC_OFF);
return;
}
- if ((JOY_NEW(DPAD_LEFT))
- || ((JOY_NEW(L_BUTTON)) && gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_LR))
+ if (JOY_NEW(DPAD_LEFT)
+ || (JOY_NEW(L_BUTTON) && gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_LR))
{
BeginNormalPaletteFade(PALETTES_ALL & ~(0x14), 0, 0, 0x10, RGB_BLACK);
m4aMPlayContinue(&gMPlayInfo_BGM);
@@ -3650,8 +3662,8 @@ static void Task_HandleCryScreenInput(u8 taskId)
PlaySE(SE_DEX_PAGE);
return;
}
- if ((JOY_NEW(DPAD_RIGHT))
- || ((JOY_NEW(R_BUTTON)) && gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_LR))
+ if (JOY_NEW(DPAD_RIGHT)
+ || (JOY_NEW(R_BUTTON) && gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_LR))
{
if (!sPokedexListItem->owned)
{
@@ -3756,7 +3768,7 @@ static void Task_LoadSizeScreen(u8 taskId)
gSprites[spriteId].y2 = gPokedexEntries[sPokedexListItem->dexNum].trainerOffset;
SetOamMatrix(1, gPokedexEntries[sPokedexListItem->dexNum].trainerScale, 0, 0, gPokedexEntries[sPokedexListItem->dexNum].trainerScale);
LoadPalette(sSizeScreenSilhouette_Pal, (gSprites[spriteId].oam.paletteNum + 16) * 16, 0x20);
- gTasks[taskId].data[5] = spriteId;
+ gTasks[taskId].tTrainerSpriteId = spriteId;
gMain.state++;
break;
case 6:
@@ -3810,8 +3822,8 @@ static void Task_HandleSizeScreenInput(u8 taskId)
gTasks[taskId].func = Task_SwitchScreensFromSizeScreen;
PlaySE(SE_PC_OFF);
}
- else if ((JOY_NEW(DPAD_LEFT))
- || ((JOY_NEW(L_BUTTON)) && gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_LR))
+ else if (JOY_NEW(DPAD_LEFT)
+ || (JOY_NEW(L_BUTTON) && gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_LR))
{
BeginNormalPaletteFade(PALETTES_ALL & ~(0x14), 0, 0, 0x10, RGB_BLACK);
sPokedexView->screenSwitchState = 2;
@@ -3825,7 +3837,7 @@ static void Task_SwitchScreensFromSizeScreen(u8 taskId)
if (!gPaletteFade.active)
{
FreeAndDestroyMonPicSprite(gTasks[taskId].tMonSpriteId);
- FreeAndDestroyTrainerPicSprite(gTasks[taskId].data[5]);
+ FreeAndDestroyTrainerPicSprite(gTasks[taskId].tTrainerSpriteId);
switch (sPokedexView->screenSwitchState)
{
default:
@@ -3839,7 +3851,12 @@ static void Task_SwitchScreensFromSizeScreen(u8 taskId)
}
}
+#undef tScrolling
+#undef tMonSpriteDone
+#undef tBgLoaded
+#undef tSkipCry
#undef tMonSpriteId
+#undef tTrainerSpriteId
static void LoadScreenSelectBarMain(u16 unused)
{
@@ -3957,7 +3974,7 @@ static void Task_DisplayCaughtMonDexPage(u8 taskId)
FillWindowPixelBuffer(WIN_INFO, PIXEL_FILL(0));
PutWindowTilemap(WIN_INFO);
PutWindowTilemap(WIN_FOOTPRINT);
- PrintFootprint(WIN_FOOTPRINT, gTasks[taskId].tDexNum);
+ DrawFootprint(WIN_FOOTPRINT, gTasks[taskId].tDexNum);
CopyWindowToVram(WIN_FOOTPRINT, 2);
ResetPaletteFade();
LoadPokedexBgPalette(FALSE);
@@ -3974,7 +3991,7 @@ static void Task_DisplayCaughtMonDexPage(u8 taskId)
gTasks[taskId].tState++;
break;
case 4:
- spriteId = CreateMonSpriteFromNationalDexNumber(dexNum, 48, 56, 0);
+ spriteId = CreateMonSpriteFromNationalDexNumber(dexNum, MON_PAGE_X, MON_PAGE_Y, 0);
gSprites[spriteId].oam.priority = 0;
BeginNormalPaletteFade(PALETTES_ALL, 0, 0x10, 0, RGB_BLACK);
SetVBlankCallback(gPokedexVBlankCB);
@@ -4172,7 +4189,7 @@ static void PrintMonWeight(u16 weight, u8 left, u8 top)
if ((buffer[i] = (lbs / 100000) + CHAR_0) == CHAR_0 && !output)
{
- buffer[i++] = 0x77;
+ buffer[i++] = CHAR_SPACER;
}
else
{
@@ -4183,7 +4200,7 @@ static void PrintMonWeight(u16 weight, u8 left, u8 top)
lbs %= 100000;
if ((buffer[i] = (lbs / 10000) + CHAR_0) == CHAR_0 && !output)
{
- buffer[i++] = 0x77;
+ buffer[i++] = CHAR_SPACER;
}
else
{
@@ -4194,7 +4211,7 @@ static void PrintMonWeight(u16 weight, u8 left, u8 top)
lbs %= 10000;
if ((buffer[i] = (lbs / 1000) + CHAR_0) == CHAR_0 && !output)
{
- buffer[i++] = 0x77;
+ buffer[i++] = CHAR_SPACER;
}
else
{
@@ -4523,7 +4540,7 @@ static void UnusedPrintDecimalNum(u8 windowId, u16 b, u8 left, u8 top)
result = b / 1000;
if (result == 0)
{
- str[0] = 0x77;
+ str[0] = CHAR_SPACER;
outputted = FALSE;
}
else
@@ -4535,7 +4552,7 @@ static void UnusedPrintDecimalNum(u8 windowId, u16 b, u8 left, u8 top)
result = (b % 1000) / 100;
if (result == 0 && !outputted)
{
- str[1] = 0x77;
+ str[1] = CHAR_SPACER;
outputted = FALSE;
}
else
@@ -4551,36 +4568,35 @@ static void UnusedPrintDecimalNum(u8 windowId, u16 b, u8 left, u8 top)
PrintInfoSubMenuText(windowId, str, left, top);
}
-static void PrintFootprint(u8 windowId, u16 dexNum)
+static void DrawFootprint(u8 windowId, u16 dexNum)
{
- u8 image[32 * 4];
- const u8 * r12 = gMonFootprintTable[NationalPokedexNumToSpecies(dexNum)];
- u16 r5 = 0;
- u16 i;
- u16 j;
+ u8 footprint[32 * 4];
+ const u8 * footprintGfx = gMonFootprintTable[NationalPokedexNumToSpecies(dexNum)];
+ u16 tileIdx = 0;
+ u16 i, j;
for (i = 0; i < 32; i++)
{
- u8 r3 = r12[i];
+ u8 tile = footprintGfx[i];
for (j = 0; j < 4; j++)
{
- u8 value = ((r3 >> (2 * j)) & 1 ? 2 : 0);
- if ((2 << (2 * j)) & r3)
+ u8 value = ((tile >> (2 * j)) & 1 ? 2 : 0);
+ if (tile & (2 << (2 * j)))
value |= 0x20;
- image[r5] = value;
- r5++;
+ footprint[tileIdx] = value;
+ tileIdx++;
}
}
- CopyToWindowPixelBuffer(windowId, image, sizeof(image), 0);
+ CopyToWindowPixelBuffer(windowId, footprint, sizeof(footprint), 0);
}
-// Unused
-void sub_80C0DC0(u16 a, u16 b)
+// Unused Ruby/Sapphire function.
+static void RS_DrawFootprint(u16 offset, u16 tileNum)
{
- *(u16 *)(VRAM + a * 0x800 + 0x232) = 0xF000 + b + 0;
- *(u16 *)(VRAM + a * 0x800 + 0x234) = 0xF000 + b + 1;
- *(u16 *)(VRAM + a * 0x800 + 0x272) = 0xF000 + b + 2;
- *(u16 *)(VRAM + a * 0x800 + 0x274) = 0xF000 + b + 3;
+ *(u16 *)(VRAM + offset * 0x800 + 0x232) = 0xF000 + tileNum + 0;
+ *(u16 *)(VRAM + offset * 0x800 + 0x234) = 0xF000 + tileNum + 1;
+ *(u16 *)(VRAM + offset * 0x800 + 0x272) = 0xF000 + tileNum + 2;
+ *(u16 *)(VRAM + offset * 0x800 + 0x274) = 0xF000 + tileNum + 3;
}
static u16 GetNextPosition(u8 direction, u16 position, u16 min, u16 max)
@@ -4919,7 +4935,7 @@ static void Task_HandleSearchTopBarInput(u8 taskId)
}
return;
}
- if ((JOY_NEW(DPAD_LEFT)) && gTasks[taskId].tTopBarItem > SEARCH_TOPBAR_SEARCH)
+ if (JOY_NEW(DPAD_LEFT) && gTasks[taskId].tTopBarItem > SEARCH_TOPBAR_SEARCH)
{
PlaySE(SE_DEX_PAGE);
gTasks[taskId].tTopBarItem--;
@@ -4927,7 +4943,7 @@ static void Task_HandleSearchTopBarInput(u8 taskId)
CopyWindowToVram(0, 2);
CopyBgTilemapBufferToVram(3);
}
- if ((JOY_NEW(DPAD_RIGHT)) && gTasks[taskId].tTopBarItem < SEARCH_TOPBAR_CANCEL)
+ if (JOY_NEW(DPAD_RIGHT) && gTasks[taskId].tTopBarItem < SEARCH_TOPBAR_CANCEL)
{
PlaySE(SE_DEX_PAGE);
gTasks[taskId].tTopBarItem++;
@@ -5008,7 +5024,7 @@ static void Task_HandleSearchMenuInput(u8 taskId)
return;
}
- if ((JOY_NEW(DPAD_LEFT)) && movementMap[gTasks[taskId].tMenuItem][0] != 0xFF)
+ if (JOY_NEW(DPAD_LEFT) && movementMap[gTasks[taskId].tMenuItem][0] != 0xFF)
{
PlaySE(SE_SELECT);
gTasks[taskId].tMenuItem = movementMap[gTasks[taskId].tMenuItem][0];
@@ -5016,7 +5032,7 @@ static void Task_HandleSearchMenuInput(u8 taskId)
CopyWindowToVram(0, 2);
CopyBgTilemapBufferToVram(3);
}
- if ((JOY_NEW(DPAD_RIGHT)) && movementMap[gTasks[taskId].tMenuItem][1] != 0xFF)
+ if (JOY_NEW(DPAD_RIGHT) && movementMap[gTasks[taskId].tMenuItem][1] != 0xFF)
{
PlaySE(SE_SELECT);
gTasks[taskId].tMenuItem = movementMap[gTasks[taskId].tMenuItem][1];
@@ -5024,7 +5040,7 @@ static void Task_HandleSearchMenuInput(u8 taskId)
CopyWindowToVram(0, 2);
CopyBgTilemapBufferToVram(3);
}
- if ((JOY_NEW(DPAD_UP)) && movementMap[gTasks[taskId].tMenuItem][2] != 0xFF)
+ if (JOY_NEW(DPAD_UP) && movementMap[gTasks[taskId].tMenuItem][2] != 0xFF)
{
PlaySE(SE_SELECT);
gTasks[taskId].tMenuItem = movementMap[gTasks[taskId].tMenuItem][2];
@@ -5032,7 +5048,7 @@ static void Task_HandleSearchMenuInput(u8 taskId)
CopyWindowToVram(0, 2);
CopyBgTilemapBufferToVram(3);
}
- if ((JOY_NEW(DPAD_DOWN)) && movementMap[gTasks[taskId].tMenuItem][3] != 0xFF)
+ if (JOY_NEW(DPAD_DOWN) && movementMap[gTasks[taskId].tMenuItem][3] != 0xFF)
{
PlaySE(SE_SELECT);
gTasks[taskId].tMenuItem = movementMap[gTasks[taskId].tMenuItem][3];
diff --git a/src/pokemon_icon.c b/src/pokemon_icon.c
index 3cd80cf0d..58d0b3420 100644
--- a/src/pokemon_icon.c
+++ b/src/pokemon_icon.c
@@ -19,10 +19,8 @@ struct MonIconSpriteTemplate
u16 paletteTag;
};
-// static functions
static u8 CreateMonIconSprite(struct MonIconSpriteTemplate *, s16, s16, u8);
-
-// .rodata
+static void FreeAndDestroyMonIconSprite_(struct Sprite *sprite);
const u8 *const gMonIconTable[] =
{
@@ -925,7 +923,7 @@ const struct SpritePalette gMonIconPaletteTable[] =
{ gMonIconPalettes[5], POKE_ICON_BASE_PAL_TAG + 5 },
};
-const struct OamData sMonIconOamData =
+static const struct OamData sMonIconOamData =
{
.y = 0,
.affineMode = ST_OAM_AFFINE_OFF,
@@ -976,7 +974,7 @@ static const union AnimCmd sAnim_4[] =
ANIMCMD_JUMP(0),
};
-const union AnimCmd *const sMonIconAnims[] =
+static const union AnimCmd *const sMonIconAnims[] =
{
sAnim_0,
sAnim_1,
@@ -997,34 +995,34 @@ static const union AffineAnimCmd sAffineAnim_1[] =
AFFINEANIMCMD_END,
};
-const union AffineAnimCmd *const sMonIconAffineAnims[] =
+static const union AffineAnimCmd *const sMonIconAffineAnims[] =
{
sAffineAnim_0,
sAffineAnim_1,
};
-const u16 sSpriteImageSizes[3][4] =
+static const u16 sSpriteImageSizes[3][4] =
{
[ST_OAM_SQUARE] =
{
- [SPRITE_SIZE(8x8)] = 0x20,
- [SPRITE_SIZE(16x16)] = 0x80,
- [SPRITE_SIZE(32x32)] = 0x200,
- [SPRITE_SIZE(64x64)] = 0x800,
+ [SPRITE_SIZE(8x8)] = 8 * 8 / 2,
+ [SPRITE_SIZE(16x16)] = 16 * 16 / 2,
+ [SPRITE_SIZE(32x32)] = 32 * 32 / 2,
+ [SPRITE_SIZE(64x64)] = 64 * 64 / 2,
},
[ST_OAM_H_RECTANGLE] =
{
- [SPRITE_SIZE(16x8)] = 0x40,
- [SPRITE_SIZE(32x8)] = 0x80,
- [SPRITE_SIZE(32x16)] = 0x100,
- [SPRITE_SIZE(64x32)] = 0x400,
+ [SPRITE_SIZE(16x8)] = 16 * 8 / 2,
+ [SPRITE_SIZE(32x8)] = 32 * 8 / 2,
+ [SPRITE_SIZE(32x16)] = 32 * 16 / 2,
+ [SPRITE_SIZE(64x32)] = 64 * 32 / 2,
},
[ST_OAM_V_RECTANGLE] =
{
- [SPRITE_SIZE(8x16)] = 0x40,
- [SPRITE_SIZE(8x32)] = 0x80,
- [SPRITE_SIZE(16x32)] = 0x100,
- [SPRITE_SIZE(32x64)] = 0x400,
+ [SPRITE_SIZE(8x16)] = 8 * 16 / 2,
+ [SPRITE_SIZE(8x32)] = 8 * 32 / 2,
+ [SPRITE_SIZE(16x32)] = 16 * 32 / 2,
+ [SPRITE_SIZE(32x64)] = 32 * 64 / 2,
},
};
@@ -1131,7 +1129,7 @@ const u8 *GetMonIconPtr(u16 species, u32 personality, bool32 handleDeoxys)
void FreeAndDestroyMonIconSprite(struct Sprite *sprite)
{
- sub_80D328C(sprite);
+ FreeAndDestroyMonIconSprite_(sprite);
}
void LoadMonIconPalettes(void)
@@ -1198,7 +1196,7 @@ const u8* GetMonIconTiles(u16 species, bool32 handleDeoxys)
return iconSprite;
}
-void sub_80D304C(u16 offset)
+void TryLoadAllMonIconPalettesAtOffset(u16 offset)
{
s32 i;
const struct SpritePalette* monIconPalettePtr;
@@ -1206,7 +1204,7 @@ void sub_80D304C(u16 offset)
if (offset <= 0xA0)
{
monIconPalettePtr = gMonIconPaletteTable;
- for(i = 5; i >= 0; i--)
+ for(i = ARRAY_COUNT(gMonIconPaletteTable) - 1; i >= 0; i--)
{
LoadPalette(monIconPalettePtr->data, offset, 0x20);
offset += 0x10;
@@ -1294,7 +1292,7 @@ static u8 CreateMonIconSprite(struct MonIconSpriteTemplate *iconTemplate, s16 x,
return spriteId;
}
-void sub_80D328C(struct Sprite *sprite)
+static void FreeAndDestroyMonIconSprite_(struct Sprite *sprite)
{
struct SpriteFrameImage image = { NULL, sSpriteImageSizes[sprite->oam.shape][sprite->oam.size] };
sprite->images = &image;
diff --git a/src/pokemon_storage_system.c b/src/pokemon_storage_system.c
index bd0910658..e18a6db76 100644
--- a/src/pokemon_storage_system.c
+++ b/src/pokemon_storage_system.c
@@ -6980,7 +6980,7 @@ static void SetDisplayMonData(void *pokemon, u8 mode)
*(txtPtr)++ = TEXT_COLOR_DARK_GRAY;
*(txtPtr)++ = TEXT_COLOR_WHITE;
*(txtPtr)++ = TEXT_COLOR_LIGHT_GRAY;
- *(txtPtr)++ = CHAR_GENDERLESS;
+ *(txtPtr)++ = CHAR_SPACER; // Genderless
break;
}
@@ -8177,7 +8177,7 @@ static bool8 MultiMove_Start(void)
{
case 0:
HideBg(0);
- sub_80D304C(0x80);
+ TryLoadAllMonIconPalettesAtOffset(0x80);
sMultiMove->state++;
break;
case 1:
diff --git a/src/pokenav_conditions_1.c b/src/pokenav_conditions_1.c
index d2424629a..a01b93a80 100644
--- a/src/pokenav_conditions_1.c
+++ b/src/pokenav_conditions_1.c
@@ -372,7 +372,7 @@ u8 *CopyMonConditionNameGender(u8 *str, u16 id, bool8 arg3)
switch (gender)
{
default:
- *(str_++) = CHAR_GENDERLESS;
+ *(str_++) = CHAR_SPACER; // Genderless
break;
case MON_MALE:
*(str_++) = EXT_CTRL_CODE_BEGIN;
diff --git a/src/pokenav_conditions_3.c b/src/pokenav_conditions_3.c
index 219bb5a07..53987d11d 100644
--- a/src/pokenav_conditions_3.c
+++ b/src/pokenav_conditions_3.c
@@ -705,7 +705,7 @@ static void PrintSearchMonListItem(struct PokenavMonList * item, u8 * dest)
}
StringGetEnd10(gStringVar3);
- dest = sub_81DB494(dest, 1, gStringVar3, 60);
+ dest = GetStringClearToWidth(dest, 1, gStringVar3, 60);
switch (gender)
{
default:
@@ -723,5 +723,5 @@ static void PrintSearchMonListItem(struct PokenavMonList * item, u8 * dest)
*s++ = CHAR_EXTRA_SYMBOL;
*s++ = CHAR_LV_2;
ConvertIntToDecimalStringN(s, level, STR_CONV_MODE_LEFT_ALIGN, 3);
- sub_81DB494(dest, 1, gStringVar1, 40);
+ GetStringClearToWidth(dest, 1, gStringVar1, 40);
}
diff --git a/src/pokenav_match_call_1.c b/src/pokenav_match_call_1.c
index e9d4c0b67..64957995d 100755
--- a/src/pokenav_match_call_1.c
+++ b/src/pokenav_match_call_1.c
@@ -413,12 +413,12 @@ void BufferMatchCallNameAndDesc(struct PokenavMatchCallEntries *matchCallEntry,
if (className && trainerName)
{
- u8 *str2 = sub_81DB494(str, 7, className, 69);
- sub_81DB494(str2, 7, trainerName, 51);
+ u8 *str2 = GetStringClearToWidth(str, 7, className, 69);
+ GetStringClearToWidth(str2, 7, trainerName, 51);
}
else
{
- sub_81DB494(str, 7, NULL, 120);
+ GetStringClearToWidth(str, 7, NULL, 120);
}
}
diff --git a/src/pokenav_ribbons_1.c b/src/pokenav_ribbons_1.c
index 69326ad23..a8aaafa35 100644
--- a/src/pokenav_ribbons_1.c
+++ b/src/pokenav_ribbons_1.c
@@ -722,7 +722,7 @@ static void BufferRibbonMonInfoText(struct PokenavMonList * item0, u8 * dest)
}
StringGetEnd10(gStringVar3);
- dest = sub_81DB494(dest, 1, gStringVar3, 60);
+ dest = GetStringClearToWidth(dest, 1, gStringVar3, 60);
switch (gender)
{
default:
@@ -741,6 +741,6 @@ static void BufferRibbonMonInfoText(struct PokenavMonList * item0, u8 * dest)
*s++ = CHAR_EXTRA_SYMBOL;
*s++ = CHAR_LV_2;
ConvertIntToDecimalStringN(s, level, STR_CONV_MODE_LEFT_ALIGN, 3);
- dest = sub_81DB494(dest, 1, gStringVar1, 54);
+ dest = GetStringClearToWidth(dest, 1, gStringVar1, 54);
ConvertIntToDecimalStringN(dest, item->data, STR_CONV_MODE_RIGHT_ALIGN, 2);
}
diff --git a/src/rotating_tile_puzzle.c b/src/rotating_tile_puzzle.c
index 56be9736f..2e919f550 100644
--- a/src/rotating_tile_puzzle.c
+++ b/src/rotating_tile_puzzle.c
@@ -134,14 +134,14 @@ u16 MoveRotatingTileObjects(u8 puzzleNumber)
continue;
// Object is on a metatile after the puzzle tile section (never occurs, in both cases the puzzle tiles are last)
- if ((u8)((metatile - puzzleTileStart) / 8) >= 5)
+ if ((u8)((metatile - puzzleTileStart) / METATILE_ROW_WIDTH) >= 5)
continue;
// Object is on a metatile in puzzle tile section, but not one of the currently rotating color
- if ((u8)((metatile - puzzleTileStart) / 8) != puzzleNumber)
+ if ((u8)((metatile - puzzleTileStart) / METATILE_ROW_WIDTH) != puzzleNumber)
continue;
- puzzleTileNum = (u8)((metatile - puzzleTileStart) % 8);
+ puzzleTileNum = (u8)((metatile - puzzleTileStart) % METATILE_ROW_WIDTH);
// First 4 puzzle tiles are the colored arrows
if (puzzleTileNum < 4)
@@ -221,7 +221,7 @@ void TurnRotatingTileObjects(void)
// prevPuzzleTileNum will similarly be a number [0-3] representing the arrow tile the object just moved from
// All the puzzles are oriented counter-clockwise and can only move 1 step at a time, so the difference between the current tile and the previous tile will always either be -1 or 3 (0-1, 1-2, 2-3, 3-0)
// Which means tileDifference will always either be -1 or 3 after the below subtraction, and rotation will always be ROTATE_COUNTERCLOCKWISE after the following conditionals
- tileDifference = (u8)((metatile - puzzleTileStart) % 8);
+ tileDifference = (u8)((metatile - puzzleTileStart) % METATILE_ROW_WIDTH);
tileDifference -= (sRotatingTilePuzzle->objects[i].prevPuzzleTileNum);
// Always true, see above
@@ -331,7 +331,7 @@ static void TurnUnsavedRotatingTileObject(u8 eventTemplateId, u8 puzzleTileNum)
else
puzzleTileStart = METATILE_TrickHousePuzzle_Arrow_YellowOnWhite_Right;
- tileDifference = (u8)((metatile - puzzleTileStart) % 8);
+ tileDifference = (u8)((metatile - puzzleTileStart) % METATILE_ROW_WIDTH);
tileDifference -= puzzleTileNum;
if (tileDifference < 0 || tileDifference == 3)
diff --git a/src/save_location.c b/src/save_location.c
index aa56d7b16..b201ca1c0 100644
--- a/src/save_location.c
+++ b/src/save_location.c
@@ -2,14 +2,16 @@
#include "save_location.h"
#include "constants/maps.h"
+#define LIST_END 0xFFFF
+
static bool32 IsCurMapInLocationList(const u16 *list)
{
s32 i;
- u16 locSum = (gSaveBlock1Ptr->location.mapGroup << 8) + (gSaveBlock1Ptr->location.mapNum);
+ u16 map = (gSaveBlock1Ptr->location.mapGroup << 8) + gSaveBlock1Ptr->location.mapNum;
- for (i = 0; list[i] != 0xFFFF; i++)
+ for (i = 0; list[i] != LIST_END; i++)
{
- if (list[i] == locSum)
+ if (list[i] == map)
return TRUE;
}
@@ -56,7 +58,7 @@ static const u16 sSaveLocationPokeCenterList[] =
MAP_TRADE_CENTER,
MAP_RECORD_CORNER,
MAP_BATTLE_COLOSSEUM_4P,
- 0xFFFF,
+ LIST_END,
};
static bool32 IsCurMapPokeCenter(void)
@@ -67,7 +69,7 @@ static bool32 IsCurMapPokeCenter(void)
static const u16 sSaveLocationReloadLocList[] = // There's only 1 location, and it's presumed its for the save reload feature for battle tower.
{
MAP_BATTLE_FRONTIER_BATTLE_TOWER_LOBBY,
- 0xFFFF,
+ LIST_END,
};
static bool32 IsCurMapReloadLocation(void)
@@ -76,20 +78,20 @@ static bool32 IsCurMapReloadLocation(void)
}
// Nulled out list. Unknown what this would have been.
-static const u16 sUnknown_0861440E[] =
+static const u16 sEmptyMapList[] =
{
- 0xFFFF,
+ LIST_END,
};
-static bool32 sub_81AFCEC(void)
+static bool32 IsCurMapInEmptyList(void)
{
- return IsCurMapInLocationList(sUnknown_0861440E);
+ return IsCurMapInLocationList(sEmptyMapList);
}
static void TrySetPokeCenterWarpStatus(void)
{
- if (IsCurMapPokeCenter() == FALSE)
- gSaveBlock2Ptr->specialSaveWarpFlags &= ~(POKECENTER_SAVEWARP);
+ if (!IsCurMapPokeCenter())
+ gSaveBlock2Ptr->specialSaveWarpFlags &= ~POKECENTER_SAVEWARP;
else
gSaveBlock2Ptr->specialSaveWarpFlags |= POKECENTER_SAVEWARP;
}
@@ -97,16 +99,16 @@ static void TrySetPokeCenterWarpStatus(void)
static void TrySetReloadWarpStatus(void)
{
if (!IsCurMapReloadLocation())
- gSaveBlock2Ptr->specialSaveWarpFlags &= ~(LOBBY_SAVEWARP);
+ gSaveBlock2Ptr->specialSaveWarpFlags &= ~LOBBY_SAVEWARP;
else
gSaveBlock2Ptr->specialSaveWarpFlags |= LOBBY_SAVEWARP;
}
-// this function definitely sets a warp status, but because the list is empty, it's unknown what this does yet.
-static void sub_81AFD5C(void)
+// Unknown save warp flag. Never set because map list is empty.
+static void TrySetUnknownWarpStatus(void)
{
- if (!sub_81AFCEC())
- gSaveBlock2Ptr->specialSaveWarpFlags &= ~(UNK_SPECIAL_SAVE_WARP_FLAG_3);
+ if (!IsCurMapInEmptyList())
+ gSaveBlock2Ptr->specialSaveWarpFlags &= ~UNK_SPECIAL_SAVE_WARP_FLAG_3;
else
gSaveBlock2Ptr->specialSaveWarpFlags |= UNK_SPECIAL_SAVE_WARP_FLAG_3;
}
@@ -115,21 +117,21 @@ void TrySetMapSaveWarpStatus(void)
{
TrySetPokeCenterWarpStatus();
TrySetReloadWarpStatus();
- sub_81AFD5C();
+ TrySetUnknownWarpStatus();
}
-// In FRLG, only 0x1, 0x10, and 0x20 are set when the pokedex is received
-// 0x2, 0x4, 0x8, and 0x8000 are instead set by SetPostgameFlags
+// In FRLG, only bits 0, 4, and 5 are set when the pokedex is received.
+// Bits 1, 2, 3, and 15 are instead set by SetPostgameFlags.
// These flags are read by Pokemon Colosseum/XD for linking. XD Additionally requires FLAG_SYS_GAME_CLEAR
void SetUnlockedPokedexFlags(void)
{
- gSaveBlock2Ptr->gcnLinkFlags |= 0x8000;
- gSaveBlock2Ptr->gcnLinkFlags |= 0x1;
- gSaveBlock2Ptr->gcnLinkFlags |= 0x2;
- gSaveBlock2Ptr->gcnLinkFlags |= 0x4;
- gSaveBlock2Ptr->gcnLinkFlags |= 0x10;
- gSaveBlock2Ptr->gcnLinkFlags |= 0x20;
- gSaveBlock2Ptr->gcnLinkFlags |= 0x8;
+ gSaveBlock2Ptr->gcnLinkFlags |= (1 << 15);
+ gSaveBlock2Ptr->gcnLinkFlags |= (1 << 0);
+ gSaveBlock2Ptr->gcnLinkFlags |= (1 << 1);
+ gSaveBlock2Ptr->gcnLinkFlags |= (1 << 2);
+ gSaveBlock2Ptr->gcnLinkFlags |= (1 << 4);
+ gSaveBlock2Ptr->gcnLinkFlags |= (1 << 5);
+ gSaveBlock2Ptr->gcnLinkFlags |= (1 << 3);
}
void SetChampionSaveWarp(void)
diff --git a/src/scrcmd.c b/src/scrcmd.c
index de0ec7c26..3e3beee59 100644
--- a/src/scrcmd.c
+++ b/src/scrcmd.c
@@ -2230,7 +2230,7 @@ bool8 ScrCmd_checkmoneventlegal(struct ScriptContext *ctx)
}
// TODO: Should be renamed. Name implies general usage, but its specifically for Wonder Card
-// See GetSavedRamScriptIfValid, which is NULL if ValidateReceivedWonderCard returns FALSE
+// See GetSavedRamScriptIfValid, which is NULL if ValidateSavedWonderCard returns FALSE
bool8 ScrCmd_gotoram(struct ScriptContext *ctx)
{
const u8* script = GetSavedRamScriptIfValid();
diff --git a/src/script.c b/src/script.c
index 726c06543..b10e0db49 100644
--- a/src/script.c
+++ b/src/script.c
@@ -1,8 +1,9 @@
#include "global.h"
#include "script.h"
#include "event_data.h"
-#include "mevent.h"
+#include "mystery_gift.h"
#include "util.h"
+#include "constants/maps.h"
#include "constants/map_scripts.h"
#define RAM_SCRIPT_MAGIC 51
@@ -403,9 +404,9 @@ bool32 ValidateSavedRamScript(void)
struct RamScriptData *scriptData = &gSaveBlock1Ptr->ramScript.data;
if (scriptData->magic != RAM_SCRIPT_MAGIC)
return FALSE;
- if (scriptData->mapGroup != 0xFF)
+ if (scriptData->mapGroup != MAP_GROUP(UNDEFINED))
return FALSE;
- if (scriptData->mapNum != 0xFF)
+ if (scriptData->mapNum != MAP_NUM(UNDEFINED))
return FALSE;
if (scriptData->objectId != 0xFF)
return FALSE;
@@ -417,13 +418,13 @@ bool32 ValidateSavedRamScript(void)
u8 *GetSavedRamScriptIfValid(void)
{
struct RamScriptData *scriptData = &gSaveBlock1Ptr->ramScript.data;
- if (!ValidateReceivedWonderCard())
+ if (!ValidateSavedWonderCard())
return NULL;
if (scriptData->magic != RAM_SCRIPT_MAGIC)
return NULL;
- if (scriptData->mapGroup != 0xFF)
+ if (scriptData->mapGroup != MAP_GROUP(UNDEFINED))
return NULL;
- if (scriptData->mapNum != 0xFF)
+ if (scriptData->mapNum != MAP_NUM(UNDEFINED))
return NULL;
if (scriptData->objectId != 0xFF)
return NULL;
@@ -442,5 +443,5 @@ void InitRamScript_NoObjectEvent(u8 *script, u16 scriptSize)
{
if (scriptSize > sizeof(gSaveBlock1Ptr->ramScript.data.script))
scriptSize = sizeof(gSaveBlock1Ptr->ramScript.data.script);
- InitRamScript(script, scriptSize, 0xFF, 0xFF, 0xFF);
+ InitRamScript(script, scriptSize, MAP_GROUP(UNDEFINED), MAP_NUM(UNDEFINED), 0xFF);
}
diff --git a/src/starter_choose.c b/src/starter_choose.c
index 37c334680..d14846130 100644
--- a/src/starter_choose.c
+++ b/src/starter_choose.c
@@ -635,7 +635,7 @@ static u8 CreatePokemonFrontSprite(u16 species, u8 x, u8 y)
{
u8 spriteId;
- spriteId = CreatePicSprite2(species, SHINY_ODDS, 0, 1, x, y, 0xE, TAG_NONE);
+ spriteId = CreateMonPicSprite_Affine(species, SHINY_ODDS, 0, MON_PIC_AFFINE_FRONT, x, y, 14, TAG_NONE);
gSprites[spriteId].oam.priority = 0;
return spriteId;
}
diff --git a/src/trade.c b/src/trade.c
index 00db3c232..be2091ece 100644
--- a/src/trade.c
+++ b/src/trade.c
@@ -19,8 +19,8 @@
#include "load_save.h"
#include "mail.h"
#include "main.h"
-#include "mevent2.h"
#include "mystery_gift.h"
+#include "mystery_gift_menu.h"
#include "overworld.h"
#include "palette.h"
#include "party_menu.h"
@@ -4653,9 +4653,8 @@ static void CB2_SaveAndEndTrade(void)
if (!InUnionRoom())
IncrementGameStat(GAME_STAT_POKEMON_TRADES);
if (gWirelessCommType)
- {
- RecordIdOfWonderCardSenderByEventType(2, gLinkPlayers[GetMultiplayerId() ^ 1].trainerId);
- }
+ MysteryGift_TryIncrementStat(CARD_STAT_NUM_TRADES, gLinkPlayers[GetMultiplayerId() ^ 1].trainerId);
+
SetContinueGameWarpStatusToDynamicWarp();
sub_8153380();
gMain.state++;
diff --git a/src/trader.c b/src/trader.c
index f6d021dfe..98b4f464c 100644
--- a/src/trader.c
+++ b/src/trader.c
@@ -130,13 +130,13 @@ void Task_HandleGetDecorationMenuInput(u8 taskId)
}
}
-void ScrSpecial_GetTraderTradedFlag(void)
+void GetTraderTradedFlag(void)
{
struct MauvilleOldManTrader *trader = &gSaveBlock1Ptr->oldMan.trader;
gSpecialVar_Result = trader->alreadyTraded;
}
-void ScrSpecial_DoesPlayerHaveNoDecorations(void)
+void DoesPlayerHaveNoDecorations(void)
{
u8 i;
@@ -151,7 +151,7 @@ void ScrSpecial_DoesPlayerHaveNoDecorations(void)
gSpecialVar_Result = TRUE;
}
-void ScrSpecial_IsDecorationFull(void)
+void IsDecorationCategoryFull(void)
{
gSpecialVar_Result = FALSE;
if (gDecorations[gSpecialVar_0x8004].category != gDecorations[gSpecialVar_0x8006].category
@@ -162,7 +162,7 @@ void ScrSpecial_IsDecorationFull(void)
}
}
-void ScrSpecial_TraderMenuGiveDecoration(void)
+void TraderShowDecorationMenu(void)
{
CreateTask(ShowDecorationCategoriesWindow, 0);
}
@@ -190,7 +190,7 @@ void ExitTraderMenu(u8 taskId)
EnableBothScriptContexts();
}
-void ScrSpecial_TraderDoDecorationTrade(void)
+void TraderDoDecorationTrade(void)
{
struct MauvilleOldManTrader *trader = &gSaveBlock1Ptr->oldMan.trader;
@@ -202,7 +202,7 @@ void ScrSpecial_TraderDoDecorationTrade(void)
trader->alreadyTraded = TRUE;
}
-void ScrSpecial_TraderMenuGetDecoration(void)
+void TraderMenuGetDecoration(void)
{
u8 taskId = CreateTask(Task_HandleGetDecorationMenuInput, 0);
CreateAvailableDecorationsMenu(taskId);
diff --git a/src/trainer_card.c b/src/trainer_card.c
index c11ee83c0..bad015644 100755
--- a/src/trainer_card.c
+++ b/src/trainer_card.c
@@ -110,7 +110,7 @@ static bool8 HasAllFrontierSymbols(void);
static u8 GetRubyTrainerStars(struct TrainerCard*);
static u16 GetCaughtMonsCount(void);
static void SetPlayerCardData(struct TrainerCard*, u8);
-static void TrainerCard_GenerateCardForLinkPlayer(struct TrainerCard*);
+static void TrainerCard_GenerateCardForPlayer(struct TrainerCard*);
static u8 VersionToCardType(u8);
static void SetDataFromTrainerCard(void);
static void InitGpuRegs(void);
@@ -750,14 +750,14 @@ static void SetPlayerCardData(struct TrainerCard *trainerCard, u8 cardType)
}
}
-static void TrainerCard_GenerateCardForLinkPlayer(struct TrainerCard *trainerCard)
+static void TrainerCard_GenerateCardForPlayer(struct TrainerCard *trainerCard)
{
memset(trainerCard, 0, sizeof(struct TrainerCard));
trainerCard->version = GAME_VERSION;
SetPlayerCardData(trainerCard, CARD_TYPE_EMERALD);
- trainerCard->hasAllSymbols = HasAllFrontierSymbols();
+ trainerCard->hasAllFrontierSymbols = HasAllFrontierSymbols();
trainerCard->frontierBP = gSaveBlock2Ptr->frontier.cardBattlePoints;
- if (trainerCard->hasAllSymbols)
+ if (trainerCard->hasAllFrontierSymbols)
trainerCard->stars++;
if (trainerCard->gender == FEMALE)
@@ -766,14 +766,14 @@ static void TrainerCard_GenerateCardForLinkPlayer(struct TrainerCard *trainerCar
trainerCard->facilityClass = gLinkPlayerFacilityClasses[trainerCard->trainerId % NUM_MALE_LINK_FACILITY_CLASSES];
}
-void TrainerCard_GenerateCardForPlayer(struct TrainerCard *trainerCard)
+void TrainerCard_GenerateCardForLinkPlayer(struct TrainerCard *trainerCard)
{
memset(trainerCard, 0, 0x60);
trainerCard->version = GAME_VERSION;
SetPlayerCardData(trainerCard, CARD_TYPE_EMERALD);
- trainerCard->hasAllFrontierSymbols = HasAllFrontierSymbols();
- *((u16*)&trainerCard->berryCrushPoints) = gSaveBlock2Ptr->frontier.cardBattlePoints;
- if (trainerCard->hasAllFrontierSymbols)
+ trainerCard->linkHasAllFrontierSymbols = HasAllFrontierSymbols();
+ *((u16*)&trainerCard->linkPoints.frontier) = gSaveBlock2Ptr->frontier.cardBattlePoints;
+ if (trainerCard->linkHasAllFrontierSymbols)
trainerCard->stars++;
if (trainerCard->gender == FEMALE)
@@ -782,7 +782,7 @@ void TrainerCard_GenerateCardForPlayer(struct TrainerCard *trainerCard)
trainerCard->facilityClass = gLinkPlayerFacilityClasses[trainerCard->trainerId % NUM_MALE_LINK_FACILITY_CLASSES];
}
-void CopyTrainerCardData(struct TrainerCard *dst, u16 *src, u8 gameVersion)
+void CopyTrainerCardData(struct TrainerCard *dst, struct TrainerCard *src, u8 gameVersion)
{
memset(dst, 0, sizeof(struct TrainerCard));
dst->version = gameVersion;
@@ -797,9 +797,9 @@ void CopyTrainerCardData(struct TrainerCard *dst, u16 *src, u8 gameVersion)
break;
case CARD_TYPE_EMERALD:
memcpy(dst, src, 0x60);
- dst->berryCrushPoints = 0;
- dst->hasAllSymbols = src[29];
- dst->frontierBP = src[30];
+ dst->linkPoints.frontier = 0;
+ dst->hasAllFrontierSymbols = src->linkHasAllFrontierSymbols;
+ dst->frontierBP = *((u16*)&src->linkPoints.frontier);
break;
}
}
@@ -1243,13 +1243,13 @@ static void PrintTradesStringOnCard(void)
static void BufferBerryCrushPoints(void)
{
- if (sData->cardType == CARD_TYPE_FRLG && sData->trainerCard.berryCrushPoints)
- ConvertIntToDecimalStringN(sData->textBerryCrushPts, sData->trainerCard.berryCrushPoints, STR_CONV_MODE_RIGHT_ALIGN, 5);
+ if (sData->cardType == CARD_TYPE_FRLG && sData->trainerCard.linkPoints.berryCrush)
+ ConvertIntToDecimalStringN(sData->textBerryCrushPts, sData->trainerCard.linkPoints.berryCrush, STR_CONV_MODE_RIGHT_ALIGN, 5);
}
static void PrintBerryCrushStringOnCard(void)
{
- if (sData->cardType == CARD_TYPE_FRLG && sData->trainerCard.berryCrushPoints)
+ if (sData->cardType == CARD_TYPE_FRLG && sData->trainerCard.linkPoints.berryCrush)
PrintStatOnBackOfCard(4, gText_BerryCrush, sData->textBerryCrushPts, sTrainerCardStatColors);
}
@@ -1524,7 +1524,7 @@ static void DrawCardBackStats(void)
FillBgTilemapBufferRect(3, 141, 27, 9, 1, 1, 1);
FillBgTilemapBufferRect(3, 157, 27, 10, 1, 1, 1);
}
- if (sData->trainerCard.berryCrushPoints)
+ if (sData->trainerCard.linkPoints.berryCrush)
{
FillBgTilemapBufferRect(3, 141, 21, 13, 1, 1, 1);
FillBgTilemapBufferRect(3, 157, 21, 14, 1, 1, 1);
@@ -1803,7 +1803,7 @@ void ShowPlayerTrainerCard(void (*callback)(void))
sData->isLink = FALSE;
sData->language = GAME_LANGUAGE;
- TrainerCard_GenerateCardForLinkPlayer(&sData->trainerCard);
+ TrainerCard_GenerateCardForPlayer(&sData->trainerCard);
SetMainCallback2(CB2_InitTrainerCard);
}
diff --git a/src/trainer_pokemon_sprites.c b/src/trainer_pokemon_sprites.c
index 9e30f636e..a7289677e 100644
--- a/src/trainer_pokemon_sprites.c
+++ b/src/trainer_pokemon_sprites.c
@@ -9,8 +9,6 @@
#include "pokemon.h"
#include "constants/trainers.h"
-// Static type declarations
-
struct PicData
{
u8 *frames;
@@ -20,33 +18,26 @@ struct PicData
u8 active;
};
-// Static RAM declarations
#define PICS_COUNT 8
static EWRAM_DATA struct SpriteTemplate sCreatingSpriteTemplate = {};
static EWRAM_DATA struct PicData sSpritePics[PICS_COUNT] = {};
-// Static ROM declarations
-
-// .rodata
-
static const struct PicData sDummyPicData = {};
-static const struct OamData gUnknown_0860B064 =
+static const struct OamData sOamData_Normal =
{
.shape = SPRITE_SHAPE(64x64),
.size = SPRITE_SIZE(64x64)
};
-static const struct OamData gUnknown_0860B06C =
+static const struct OamData sOamData_Affine =
{
.affineMode = ST_OAM_AFFINE_NORMAL,
.shape = SPRITE_SHAPE(64x64),
.size = SPRITE_SIZE(64x64)
};
-// .text
-
static void DummyPicSpriteCallback(struct Sprite *sprite)
{
@@ -153,19 +144,15 @@ static u16 CreatePicSprite(u16 species, u32 otId, u32 personality, bool8 isFront
for (i = 0; i < PICS_COUNT; i ++)
{
if (!sSpritePics[i].active)
- {
break;
- }
}
if (i == PICS_COUNT)
- {
return 0xFFFF;
- }
+
framePics = Alloc(4 * 0x800);
if (!framePics)
- {
return 0xFFFF;
- }
+
images = Alloc(4 * sizeof(struct SpriteFrameImage));
if (!images)
{
@@ -183,7 +170,7 @@ static u16 CreatePicSprite(u16 species, u32 otId, u32 personality, bool8 isFront
images[j].size = 0x800;
}
sCreatingSpriteTemplate.tileTag = TAG_NONE;
- sCreatingSpriteTemplate.oam = &gUnknown_0860B064;
+ sCreatingSpriteTemplate.oam = &sOamData_Normal;
AssignSpriteAnimsTable(isTrainer);
sCreatingSpriteTemplate.images = images;
sCreatingSpriteTemplate.affineAnims = gDummySpriteAffineAnimTable;
@@ -191,9 +178,7 @@ static u16 CreatePicSprite(u16 species, u32 otId, u32 personality, bool8 isFront
LoadPicPaletteByTagOrSlot(species, otId, personality, paletteSlot, paletteTag, isTrainer);
spriteId = CreateSprite(&sCreatingSpriteTemplate, x, y, 0);
if (paletteTag == TAG_NONE)
- {
gSprites[spriteId].oam.paletteNum = paletteSlot;
- }
sSpritePics[i].frames = framePics;
sSpritePics[i].images = images;
sSpritePics[i].paletteTag = paletteTag;
@@ -207,39 +192,35 @@ static u16 CreatePicSprite_HandleDeoxys(u16 species, u32 otId, u32 personality,
return CreatePicSprite(species, otId, personality, isFrontPic, x, y, paletteSlot, paletteTag, isTrainer, FALSE);
}
-u16 CreatePicSprite2(u16 species, u32 otId, u32 personality, u8 flags, s16 x, s16 y, u8 paletteSlot, u16 paletteTag)
+u16 CreateMonPicSprite_Affine(u16 species, u32 otId, u32 personality, u8 flags, s16 x, s16 y, u8 paletteSlot, u16 paletteTag)
{
u8 *framePics;
struct SpriteFrameImage *images;
int j;
u8 i;
u8 spriteId;
- u8 flags2;
+ u8 type;
- for (i = 0; i < PICS_COUNT; i ++)
+ for (i = 0; i < PICS_COUNT; i++)
{
if (!sSpritePics[i].active)
- {
break;
- }
}
if (i == PICS_COUNT)
- {
return 0xFFFF;
- }
- framePics = Alloc(4 * 0x800);
+
+ framePics = Alloc(4 * MON_PIC_SIZE);
if (!framePics)
- {
return 0xFFFF;
- }
- if (flags & 0x80)
+
+ if (flags & F_MON_PIC_NO_AFFINE)
{
- flags &= 0x7F;
- flags2 = 3;
+ flags &= ~F_MON_PIC_NO_AFFINE;
+ type = MON_PIC_AFFINE_NONE;
}
else
{
- flags2 = flags;
+ type = flags;
}
images = Alloc(4 * sizeof(struct SpriteFrameImage));
if (!images)
@@ -254,34 +235,32 @@ u16 CreatePicSprite2(u16 species, u32 otId, u32 personality, u8 flags, s16 x, s1
}
for (j = 0; j < 4; j ++)
{
- images[j].data = framePics + 0x800 * j;
- images[j].size = 0x800;
+ images[j].data = framePics + MON_PIC_SIZE * j;
+ images[j].size = MON_PIC_SIZE;
}
sCreatingSpriteTemplate.tileTag = TAG_NONE;
sCreatingSpriteTemplate.anims = gMonFrontAnimsPtrTable[species];
sCreatingSpriteTemplate.images = images;
- if (flags2 == 0x01)
+ if (type == MON_PIC_AFFINE_FRONT)
{
sCreatingSpriteTemplate.affineAnims = gAffineAnims_BattleSpriteOpponentSide;
- sCreatingSpriteTemplate.oam = &gUnknown_0860B06C;
+ sCreatingSpriteTemplate.oam = &sOamData_Affine;
}
- else if (flags2 == 0x00)
+ else if (type == MON_PIC_AFFINE_BACK)
{
sCreatingSpriteTemplate.affineAnims = gAffineAnims_BattleSpritePlayerSide;
- sCreatingSpriteTemplate.oam = &gUnknown_0860B06C;
+ sCreatingSpriteTemplate.oam = &sOamData_Affine;
}
- else
+ else // MON_PIC_AFFINE_NONE
{
- sCreatingSpriteTemplate.oam = &gUnknown_0860B064;
+ sCreatingSpriteTemplate.oam = &sOamData_Normal;
sCreatingSpriteTemplate.affineAnims = gDummySpriteAffineAnimTable;
}
sCreatingSpriteTemplate.callback = DummyPicSpriteCallback;
LoadPicPaletteByTagOrSlot(species, otId, personality, paletteSlot, paletteTag, FALSE);
spriteId = CreateSprite(&sCreatingSpriteTemplate, x, y, 0);
if (paletteTag == TAG_NONE)
- {
gSprites[spriteId].oam.paletteNum = paletteSlot;
- }
sSpritePics[i].frames = framePics;
sSpritePics[i].images = images;
sSpritePics[i].paletteTag = paletteTag;
@@ -299,20 +278,15 @@ static u16 FreeAndDestroyPicSpriteInternal(u16 spriteId)
for (i = 0; i < PICS_COUNT; i ++)
{
if (sSpritePics[i].spriteId == spriteId)
- {
break;
- }
}
if (i == PICS_COUNT)
- {
return 0xFFFF;
- }
+
framePics = sSpritePics[i].frames;
images = sSpritePics[i].images;
if (sSpritePics[i].paletteTag != TAG_NONE)
- {
FreeSpritePaletteByTag(GetSpritePaletteTagByPaletteNum(gSprites[spriteId].oam.paletteNum));
- }
DestroySprite(&gSprites[spriteId]);
Free(framePics);
Free(images);
@@ -320,12 +294,11 @@ static u16 FreeAndDestroyPicSpriteInternal(u16 spriteId)
return 0;
}
-static u16 sub_818D65C(u16 species, u32 otId, u32 personality, bool8 isFrontPic, u8 paletteSlot, u8 windowId, bool8 isTrainer)
+static u16 LoadPicSpriteInWindow(u16 species, u32 otId, u32 personality, bool8 isFrontPic, u8 paletteSlot, u8 windowId, bool8 isTrainer)
{
if (DecompressPic_HandleDeoxys(species, personality, isFrontPic, (u8 *)GetWindowAttribute(windowId, WINDOW_TILE_DATA), FALSE))
- {
return 0xFFFF;
- }
+
LoadPicPaletteBySlot(species, otId, personality, paletteSlot, isTrainer);
return 0;
}
@@ -360,9 +333,10 @@ u16 FreeAndDestroyMonPicSprite(u16 spriteId)
return FreeAndDestroyPicSpriteInternal(spriteId);
}
-u16 sub_818D834(u16 species, u32 otId, u32 personality, bool8 isFrontPic, u8 paletteSlot, u8 windowId)
+// Unused
+static u16 LoadMonPicInWindow(u16 species, u32 otId, u32 personality, bool8 isFrontPic, u8 paletteSlot, u8 windowId)
{
- return sub_818D65C(species, otId, personality, isFrontPic, paletteSlot, windowId, FALSE);
+ return LoadPicSpriteInWindow(species, otId, personality, isFrontPic, paletteSlot, windowId, FALSE);
}
// Unused, FRLG only
@@ -381,9 +355,10 @@ u16 FreeAndDestroyTrainerPicSprite(u16 spriteId)
return FreeAndDestroyPicSpriteInternal(spriteId);
}
-u16 sub_818D904(u16 species, bool8 isFrontPic, u8 paletteSlot, u8 windowId)
+// Unused
+static u16 LoadTrainerPicInWindow(u16 species, bool8 isFrontPic, u8 paletteSlot, u8 windowId)
{
- return sub_818D65C(species, 0, 0, isFrontPic, paletteSlot, windowId, TRUE);
+ return LoadPicSpriteInWindow(species, 0, 0, isFrontPic, paletteSlot, windowId, TRUE);
}
u16 CreateTrainerCardTrainerPicSprite(u16 species, bool8 isFrontPic, u16 destX, u16 destY, u8 paletteSlot, u8 windowId)
@@ -395,13 +370,10 @@ u16 PlayerGenderToFrontTrainerPicId_Debug(u8 gender, bool8 getClass)
{
if (getClass == TRUE)
{
- switch (gender)
- {
- default:
+ if (gender != MALE)
return gFacilityClassToPicIndex[FACILITY_CLASS_MAY];
- case MALE:
+ else
return gFacilityClassToPicIndex[FACILITY_CLASS_BRENDAN];
- }
}
return gender;
}
diff --git a/src/tv.c b/src/tv.c
index 452923933..310163e94 100644
--- a/src/tv.c
+++ b/src/tv.c
@@ -1155,7 +1155,7 @@ void TryPutPokemonTodayOnAir(void)
show->pokemonToday.ball = itemLastUsed;
StringCopy(show->pokemonToday.playerName, gSaveBlock2Ptr->playerName);
StringCopy(show->pokemonToday.nickname, gBattleResults.caughtMonNick);
- language2 = sub_81DB604(show->pokemonToday.nickname);
+ language2 = GetNicknameLanguage(show->pokemonToday.nickname);
StripExtCtrlCodes(show->pokemonToday.nickname);
show->pokemonToday.species = gBattleResults.caughtMonSpecies;
StorePlayerIdInRecordMixShow(show);
diff --git a/src/union_room.c b/src/union_room.c
index a889490f1..18cb02c33 100644
--- a/src/union_room.c
+++ b/src/union_room.c
@@ -24,8 +24,8 @@
#include "load_save.h"
#include "menu.h"
#include "menu_helpers.h"
-#include "mevent.h"
#include "mystery_gift.h"
+#include "mystery_gift_menu.h"
#include "overworld.h"
#include "palette.h"
#include "party_menu.h"
@@ -219,7 +219,7 @@ static u16 ReadAsU16(const u8 *);
static void Task_TryBecomeLinkLeader(u8);
static void Task_TryJoinLinkGroup(u8);
static void Task_ListenToWireless(u8);
-static void Task_MEvent_Leader(u8);
+static void Task_SendMysteryGift(u8);
static void Task_CardOrNewsWithFriend(u8);
static void Task_CardOrNewsOverWireless(u8);
static void Task_RunUnionRoom(u8);
@@ -1533,17 +1533,21 @@ static void Task_ExchangeCards(u8 taskId)
for (i = 0; i < GetLinkPlayerCount(); i++)
{
recvBuff = gBlockRecvBuffer[i];
- CopyTrainerCardData(&gTrainerCards[i], recvBuff, gLinkPlayers[i].version);
+ CopyTrainerCardData(&gTrainerCards[i], (struct TrainerCard *)recvBuff, gLinkPlayers[i].version);
}
if (GetLinkPlayerCount() == 2)
{
+ // Note: hasAllFrontierSymbols is a re-used field.
+ // Here it is set by CreateTrainerCardInBuffer.
+ // If the player has a saved Wonder Card and it is the same Wonder Card
+ // as their partner then mystery gift stats are enabled.
recvBuff = gBlockRecvBuffer[GetMultiplayerId() ^ 1];
- MEventHandleReceivedWonderCard(recvBuff[48]);
+ MysteryGift_TryEnableStatsByFlagId(((struct TrainerCard *)recvBuff)->hasAllFrontierSymbols);
}
else
{
- ResetReceivedWonderCardFlag();
+ MysteryGift_DisableStats();
}
ResetBlockReceivedFlags();
@@ -1627,18 +1631,19 @@ static void CB2_TransitionToCableClub(void)
static void CreateTrainerCardInBuffer(void *dest, bool32 setWonderCard)
{
- u16 *argAsU16Ptr = dest;
+ struct TrainerCard * card = (struct TrainerCard *)dest;
+ TrainerCard_GenerateCardForLinkPlayer(card);
- TrainerCard_GenerateCardForPlayer((struct TrainerCard *)argAsU16Ptr);
+ // Below field is re-used, to be read by Task_ExchangeCards
if (setWonderCard)
- argAsU16Ptr[48] = GetWonderCardFlagID();
+ card->hasAllFrontierSymbols = GetWonderCardFlagID();
else
- argAsU16Ptr[48] = 0;
+ card->hasAllFrontierSymbols = 0;
}
static void Task_StartActivity(u8 taskId)
{
- ResetReceivedWonderCardFlag();
+ MysteryGift_DisableStats();
switch (gPlayerCurrActivity)
{
case ACTIVITY_BATTLE_SINGLE:
@@ -1858,12 +1863,13 @@ static void CreateTask_StartActivity(void)
gTasks[taskId].data[0] = 0;
}
-void MEvent_CreateTask_Leader(u32 activity)
+// Sending Wonder Card/News
+void CreateTask_SendMysteryGift(u32 activity)
{
u8 taskId;
struct WirelessLink_Leader *data;
- taskId = CreateTask(Task_MEvent_Leader, 0);
+ taskId = CreateTask(Task_SendMysteryGift, 0);
sWirelessLinkMain.leader = data = (void*)(gTasks[taskId].data);
data->state = 0;
@@ -1872,7 +1878,7 @@ void MEvent_CreateTask_Leader(u32 activity)
gSpecialVar_Result = LINKUP_ONGOING;
}
-static void Task_MEvent_Leader(u8 taskId)
+static void Task_SendMysteryGift(u8 taskId)
{
struct WirelessLink_Leader *data = sWirelessLinkMain.leader;
struct WindowTemplate winTemplate;
@@ -1934,7 +1940,7 @@ static void Task_MEvent_Leader(u8 taskId)
}
break;
case 6:
- if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, sText_LinkWithFriendDropped))
+ if (PrintMysteryGiftMenuMessage(&data->textState, sText_LinkWithFriendDropped))
{
data->playerCount = LeaderPrunePlayerList(data->playerList);
RedrawListMenu(data->listTaskId);
@@ -1945,7 +1951,7 @@ static void Task_MEvent_Leader(u8 taskId)
data->state = 7;
break;
case 7:
- switch (mevent_message_print_and_prompt_yes_no(&data->textState, &data->yesNoWindowId, 0, gStringVar4))
+ switch (DoMysteryGiftYesNo(&data->textState, &data->yesNoWindowId, 0, gStringVar4))
{
case 0:
LoadWirelessStatusIndicatorSpriteGfx();
@@ -2031,7 +2037,7 @@ static void Task_MEvent_Leader(u8 taskId)
data->state++;
break;
case 14:
- if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, sText_PleaseStartOver))
+ if (PrintMysteryGiftMenuMessage(&data->textState, sText_PleaseStartOver))
{
DestroyTask(taskId);
gSpecialVar_Result = LINKUP_FAILED;
@@ -2066,7 +2072,7 @@ static void Task_MEvent_Leader(u8 taskId)
}
}
-void MEvent_CreateTask_CardOrNewsWithFriend(u32 activity)
+void CreateTask_LinkMysteryGiftWithFriend(u32 activity)
{
u8 taskId;
struct WirelessLink_Group *data;
@@ -2209,7 +2215,7 @@ static void Task_CardOrNewsWithFriend(u8 taskId)
data->state++;
break;
case 9:
- if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, sLinkDroppedTexts[RfuGetStatus()]))
+ if (PrintMysteryGiftMenuMessage(&data->textState, sLinkDroppedTexts[RfuGetStatus()]))
{
DestroyWirelessStatusIndicatorSprite();
DestroyTask(taskId);
@@ -2235,7 +2241,7 @@ static void Task_CardOrNewsWithFriend(u8 taskId)
}
}
-void MEvent_CreateTask_CardOrNewsOverWireless(u32 activity)
+void CreateTask_LinkMysteryGiftOverWireless(u32 activity)
{
u8 taskId;
struct WirelessLink_Group *data;
@@ -2377,7 +2383,7 @@ static void Task_CardOrNewsOverWireless(u8 taskId)
data->state++;
break;
case 9:
- if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, sText_WirelessLinkDropped))
+ if (PrintMysteryGiftMenuMessage(&data->textState, sText_WirelessLinkDropped))
{
DestroyWirelessStatusIndicatorSprite();
DestroyTask(taskId);
@@ -2386,7 +2392,7 @@ static void Task_CardOrNewsOverWireless(u8 taskId)
}
break;
case 7:
- if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, sText_WirelessSearchCanceled))
+ if (PrintMysteryGiftMenuMessage(&data->textState, sText_WirelessSearchCanceled))
{
DestroyWirelessStatusIndicatorSprite();
DestroyTask(taskId);
@@ -2395,7 +2401,7 @@ static void Task_CardOrNewsOverWireless(u8 taskId)
}
break;
case 11:
- if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, sNoWonderSharedTexts[data->isWonderNews]))
+ if (PrintMysteryGiftMenuMessage(&data->textState, sNoWonderSharedTexts[data->isWonderNews]))
{
DestroyWirelessStatusIndicatorSprite();
DestroyTask(taskId);
diff --git a/src/union_room_chat.c b/src/union_room_chat.c
index adf496fe6..7debe3cd4 100755
--- a/src/union_room_chat.c
+++ b/src/union_room_chat.c
@@ -105,6 +105,17 @@ enum {
CHAT_EXIT_DISBANDED,
};
+enum {
+ GFXTAG_KEYBOARD_CURSOR,
+ GFXTAG_TEXT_ENTRY_ARROW,
+ GFXTAG_TEXT_ENTRY_CURSOR,
+ GFXTAG_RBUTTON_ICON,
+ GFXTAG_RBUTTON_LABELS,
+};
+
+// Shared by all above
+#define PALTAG_INTERFACE 0
+
struct UnionRoomChat
{
u32 filler1;
@@ -123,7 +134,7 @@ struct UnionRoomChat
u8 lastBufferCursorPos;
u8 bufferCursorPos;
u8 receivedPlayerIndex;
- u8 exitType;
+ u8 exitType; // CHAT_EXIT_*
bool8 changedRegisteredTexts;
u8 afterSaveTimer;
u8 messageEntryBuffer[2 * MAX_MESSAGE_LENGTH + 1];
@@ -249,9 +260,9 @@ static void CreateRButtonSprites(void);
static void ShowKeyboardSwapMenu(void);
static void HideKeyboardSwapMenu(void);
static void SetKeyboardCursorInvisibility(bool32);
-static bool32 sub_8020320(void);
+static bool32 SlideKeyboardPageOut(void);
static void PrintCurrentKeyboardPage(void);
-static bool32 sub_8020368(void);
+static bool32 SlideKeyboardPageIn(void);
static void MoveKeyboardCursor(void);
static void UpdateRButtonLabel(void);
static void AddStdMessageWindow(int, u16);
@@ -266,8 +277,8 @@ static void SetRegisteredTextPalette(bool32);
static void PrintChatMessage(u16, u8 *, u8);
static void StartKeyboardCursorAnim(void);
static bool32 TryKeyboardCursorReopen(void);
-static void sub_80207C0(s16);
-static void sub_8020818(s16);
+static void UpdateSlidingKeyboard(s16);
+static void FinishSlidingKeyboard(s16);
static bool32 Display_Dummy(u8 *);
static bool32 Display_LoadGfx(u8 *state);
static bool32 Display_ShowKeyboardSwapMenu(u8 *state);
@@ -550,36 +561,36 @@ static const struct BgTemplate sBgTemplates[] = {
static const struct WindowTemplate sWinTemplates[] = {
{
- .bg = 0x03,
- .tilemapLeft = 0x08,
- .tilemapTop = 0x01,
- .width = 0x15,
- .height = 0x13,
- .paletteNum = 0x0f,
+ .bg = 3,
+ .tilemapLeft = 8,
+ .tilemapTop = 1,
+ .width = 21,
+ .height = 19,
+ .paletteNum = 15,
.baseBlock = 0x0001,
}, {
- .bg = 0x01,
- .tilemapLeft = 0x09,
- .tilemapTop = 0x12,
- .width = 0x0f,
- .height = 0x02,
- .paletteNum = 0x0c,
+ .bg = 1,
+ .tilemapLeft = 9,
+ .tilemapTop = 18,
+ .width = 15,
+ .height = 2,
+ .paletteNum = 12,
.baseBlock = 0x007a,
}, {
- .bg = 0x01,
- .tilemapLeft = 0x00,
- .tilemapTop = 0x02,
- .width = 0x06,
- .height = 0x0f,
- .paletteNum = 0x07,
+ .bg = 1,
+ .tilemapLeft = 0,
+ .tilemapTop = 2,
+ .width = 6,
+ .height = 15,
+ .paletteNum = 7,
.baseBlock = 0x0020,
}, {
- .bg = 0x00,
- .tilemapLeft = 0x01,
- .tilemapTop = 0x02,
- .width = 0x07,
- .height = 0x09,
- .paletteNum = 0x0e,
+ .bg = 0,
+ .tilemapLeft = 1,
+ .tilemapTop = 2,
+ .width = 7,
+ .height = 9,
+ .paletteNum = 14,
.baseBlock = 0x0013,
}, DUMMY_WIN_TEMPLATE
};
@@ -783,8 +794,8 @@ static const union AnimCmd *const sAnims_KeyboardCursor[] = {
};
static const struct SpriteTemplate sSpriteTemplate_KeyboardCursor = {
- .tileTag = 0x0000,
- .paletteTag = 0x0000,
+ .tileTag = GFXTAG_KEYBOARD_CURSOR,
+ .paletteTag = PALTAG_INTERFACE,
.oam = &sOam_KeyboardCursor,
.anims = sAnims_KeyboardCursor,
.images = NULL,
@@ -799,8 +810,8 @@ static const struct OamData sOam_TextEntrySprite = {
};
static const struct SpriteTemplate sSpriteTemplate_TextEntryCursor = {
- .tileTag = 0x0002,
- .paletteTag = 0x0000,
+ .tileTag = GFXTAG_TEXT_ENTRY_CURSOR,
+ .paletteTag = PALTAG_INTERFACE,
.oam = &sOam_TextEntrySprite,
.anims = gDummySpriteAnimTable,
.images = NULL,
@@ -809,8 +820,8 @@ static const struct SpriteTemplate sSpriteTemplate_TextEntryCursor = {
};
static const struct SpriteTemplate sSpriteTemplate_TextEntryArrow = {
- .tileTag = 0x0001,
- .paletteTag = 0x0000,
+ .tileTag = GFXTAG_TEXT_ENTRY_ARROW,
+ .paletteTag = PALTAG_INTERFACE,
.oam = &sOam_TextEntrySprite,
.anims = gDummySpriteAnimTable,
.images = NULL,
@@ -858,8 +869,8 @@ static const union AnimCmd *const sAnims_RButtonLabels[] = {
};
static const struct SpriteTemplate sSpriteTemplate_RButtonIcon = {
- .tileTag = 0x0003,
- .paletteTag = 0x0000,
+ .tileTag = GFXTAG_RBUTTON_ICON,
+ .paletteTag = PALTAG_INTERFACE,
.oam = &sOam_RButtonIcon,
.anims = gDummySpriteAnimTable,
.images = NULL,
@@ -868,8 +879,8 @@ static const struct SpriteTemplate sSpriteTemplate_RButtonIcon = {
};
static const struct SpriteTemplate sSpriteTemplate_RButtonLabels = {
- .tileTag = 0x0004,
- .paletteTag = 0x0000,
+ .tileTag = GFXTAG_RBUTTON_LABELS,
+ .paletteTag = PALTAG_INTERFACE,
.oam = &sOam_RButtonLabel,
.anims = sAnims_RButtonLabels,
.images = NULL,
@@ -879,7 +890,7 @@ static const struct SpriteTemplate sSpriteTemplate_RButtonLabels = {
void EnterUnionRoomChat(void)
{
- sChat = Alloc(sizeof(struct UnionRoomChat));
+ sChat = Alloc(sizeof(*sChat));
InitUnionRoomChat(sChat);
gKeyRepeatStartDelay = 20;
SetVBlankCallback(NULL);
@@ -890,7 +901,7 @@ static void InitUnionRoomChat(struct UnionRoomChat *chat)
{
int i;
- chat->funcId = 0;
+ chat->funcId = CHAT_FUNC_JOIN;
chat->funcState = 0;
chat->currentPage = 0;
chat->currentCol = 0;
@@ -901,7 +912,7 @@ static void InitUnionRoomChat(struct UnionRoomChat *chat)
chat->messageEntryBuffer[0] = EOS;
chat->linkPlayerCount = GetLinkPlayerCount();
chat->multiplayerId = GetMultiplayerId();
- chat->exitType = 0;
+ chat->exitType = CHAT_EXIT_NONE;
chat->changedRegisteredTexts = FALSE;
PrepareSendBuffer_Null(chat->sendMessageBuffer);
for (i = 0; i < UNION_ROOM_KB_ROW_COUNT; i++)
@@ -969,6 +980,8 @@ static void CB2_UnionRoomChatMain(void)
static void Task_HandlePlayerInput(u8 taskId)
{
+ // If exitType is not CHAT_EXIT_NONE, begin exit function.
+ // Otherwise just call main function below.
switch (sChat->exitType)
{
case CHAT_EXIT_ONLY_LEADER:
@@ -1056,7 +1069,7 @@ static void Chat_HandleInput(void)
}
else
{
- SetChatFunction(5);
+ SetChatFunction(CHAT_FUNC_REGISTER);
}
}
else if (HandleDPadInput())
@@ -2080,7 +2093,7 @@ static void Task_ReceiveChatMessage(u8 taskId)
if (GetLinkPlayerCount() == 2)
{
Rfu_StopPartnerSearch();
- sChat->exitType = 1;
+ sChat->exitType = CHAT_EXIT_ONLY_LEADER;
DestroyTask(taskId);
return;
}
@@ -2091,12 +2104,12 @@ static void Task_ReceiveChatMessage(u8 taskId)
break;
case 5:
if (sChat->multiplayerId)
- sChat->exitType = 2;
+ sChat->exitType = CHAT_EXIT_DROPPED;
DestroyTask(taskId);
break;
case 6:
- sChat->exitType = 3;
+ sChat->exitType = CHAT_EXIT_DISBANDED;
DestroyTask(taskId);
break;
case 2:
@@ -2295,7 +2308,7 @@ static bool32 Display_SwitchPages(u8 *state)
{
case 0:
SetKeyboardCursorInvisibility(TRUE);
- if (sub_8020320())
+ if (SlideKeyboardPageOut())
return TRUE;
PrintCurrentKeyboardPage();
@@ -2306,7 +2319,7 @@ static bool32 Display_SwitchPages(u8 *state)
return TRUE;
break;
case 2:
- if (sub_8020368())
+ if (SlideKeyboardPageIn())
return TRUE;
MoveKeyboardCursor();
@@ -2928,26 +2941,29 @@ static void PrintCurrentKeyboardPage(void)
}
}
-static bool32 sub_8020320(void)
+#define KEYBOARD_HOFS_END 56
+
+static bool32 SlideKeyboardPageOut(void)
{
- if (sDisplay->bg1hofs < 56)
+ if (sDisplay->bg1hofs < KEYBOARD_HOFS_END)
{
sDisplay->bg1hofs += 12;
- if (sDisplay->bg1hofs >= 56)
- sDisplay->bg1hofs = 56;
+ if (sDisplay->bg1hofs >= KEYBOARD_HOFS_END)
+ sDisplay->bg1hofs = KEYBOARD_HOFS_END;
- if (sDisplay->bg1hofs < 56)
+ if (sDisplay->bg1hofs < KEYBOARD_HOFS_END)
{
- sub_80207C0(sDisplay->bg1hofs);
+ // Still sliding
+ UpdateSlidingKeyboard(sDisplay->bg1hofs);
return TRUE;
}
}
- sub_8020818(sDisplay->bg1hofs);
+ FinishSlidingKeyboard(sDisplay->bg1hofs);
return FALSE;
}
-static bool32 sub_8020368(void)
+static bool32 SlideKeyboardPageIn(void)
{
if (sDisplay->bg1hofs > 0)
{
@@ -2957,12 +2973,13 @@ static bool32 sub_8020368(void)
if (sDisplay->bg1hofs > 0)
{
- sub_80207C0(sDisplay->bg1hofs);
+ // Still sliding
+ UpdateSlidingKeyboard(sDisplay->bg1hofs);
return TRUE;
}
}
- sub_8020818(sDisplay->bg1hofs);
+ FinishSlidingKeyboard(sDisplay->bg1hofs);
return FALSE;
}
@@ -3049,8 +3066,8 @@ static void LoadChatWindowGfx(void)
ptr = DecompressAndCopyTileDataToVram(2, gUnionRoomChat_Background_Gfx, 0, 0, 0);
if (ptr)
{
- CpuFastCopy(&ptr[0x220], sDisplay->unk2128, 0x20);
- CpuFastCopy(&ptr[0x420], sDisplay->unk2148, 0x20);
+ CpuFastCopy(&ptr[0x220], sDisplay->unk2128, sizeof(sDisplay->unk2128));
+ CpuFastCopy(&ptr[0x420], sDisplay->unk2148, sizeof(sDisplay->unk2148));
}
CopyToBgTilemapBuffer(2, gUnionRoomChat_Background_Tilemap, 0, 0);
@@ -3059,13 +3076,13 @@ static void LoadChatWindowGfx(void)
static void sub_8020680(void)
{
- LoadPalette(sUnk_Palette1, 0x80, 0x20);
+ LoadPalette(sUnk_Palette1, 0x80, sizeof(sUnk_Palette1));
RequestDma3Fill(0, (void *)BG_CHAR_ADDR(1) + 0x20, 0x20, 1);
}
static void LoadChatMessagesWindow(void)
{
- LoadPalette(sUnk_Palette2, 0xF0, 0x20);
+ LoadPalette(sUnk_Palette2, 0xF0, sizeof(sUnk_Palette2));
PutWindowTilemap(0);
FillWindowPixelBuffer(0, PIXEL_FILL(1));
CopyWindowToVram(0, 3);
@@ -3113,13 +3130,13 @@ static void InitScanlineEffect(void)
ScanlineEffect_SetParams(params);
}
-static void sub_80207C0(s16 bg1hofs)
+static void UpdateSlidingKeyboard(s16 bg1hofs)
{
CpuFill16(bg1hofs, gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer], 0x120);
CpuFill16(0, gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer] + 0x90, 0x20);
}
-static void sub_8020818(s16 bg1hofs)
+static void FinishSlidingKeyboard(s16 bg1hofs)
{
CpuFill16(bg1hofs, gScanlineEffectRegBuffers[0], 0x120);
CpuFill16(0, gScanlineEffectRegBuffers[0] + 0x90, 0x20);
@@ -3134,7 +3151,7 @@ static bool32 TryAllocSprites(void)
LoadCompressedSpriteSheet(&sSpriteSheets[i]);
LoadSpritePalette(&sSpritePalette);
- sSprites = Alloc(sizeof(struct UnionRoomChatSprites));
+ sSprites = Alloc(sizeof(*sSprites));
if (!sSprites)
return FALSE;
@@ -3180,7 +3197,7 @@ static void MoveKeyboardCursor(void)
static void SetRegisteredTextPalette(bool32 registering)
{
const u16 *palette = &sUnionRoomChatInterfacePal[registering * 2 + 1];
- u8 index = IndexOfSpritePaletteTag(0);
+ u8 index = IndexOfSpritePaletteTag(PALTAG_INTERFACE);
LoadPalette(palette, index * 16 + 0x101, 4);
}
diff --git a/src/wild_encounter.c b/src/wild_encounter.c
index 5d7425762..458882853 100644
--- a/src/wild_encounter.c
+++ b/src/wild_encounter.c
@@ -613,7 +613,7 @@ bool8 StandardWildEncounter(u16 currMetaTileBehavior, u16 previousMetaTileBehavi
}
}
else if (MetatileBehavior_IsWaterWildEncounter(currMetaTileBehavior) == TRUE
- || (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING) && MetatileBehavior_IsBridge(currMetaTileBehavior) == TRUE))
+ || (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING) && MetatileBehavior_IsBridgeOverWater(currMetaTileBehavior) == TRUE))
{
if (AreLegendariesInSootopolisPreventingEncounters() == TRUE)
return FALSE;
diff --git a/src/wonder_news.c b/src/wonder_news.c
new file mode 100644
index 000000000..ec93d293e
--- /dev/null
+++ b/src/wonder_news.c
@@ -0,0 +1,160 @@
+#include "global.h"
+#include "mystery_gift.h"
+#include "random.h"
+#include "event_data.h"
+#include "wonder_news.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 GetNewsId(struct WonderNewsMetadata *);
+static void IncrementGetNewsCounter(struct WonderNewsMetadata *);
+static u32 GetNewsValByNewsType(struct WonderNewsMetadata *);
+static void IncrementSentNewsCounter(struct WonderNewsMetadata *);
+static void ResetSentNewsCounter(struct WonderNewsMetadata *);
+
+void GenerateRandomWonderNews(u32 newsType)
+{
+ struct WonderNewsMetadata *data = GetSavedWonderNewsMetadata();
+
+ data->newsType = newsType;
+ switch (newsType)
+ {
+ case WONDER_NEWS_NONE:
+ break;
+ case WONDER_NEWS_RECV_FRIEND:
+ case WONDER_NEWS_RECV_WIRELESS:
+ data->rand = (Random() % 15) + 16;
+ break;
+ case WONDER_NEWS_SENT:
+ data->rand = (Random() % 15) + 1;
+ break;
+ }
+}
+
+void InitSavedWonderNews(void)
+{
+ struct WonderNewsMetadata *data = GetSavedWonderNewsMetadata();
+
+ data->newsType = WONDER_NEWS_NONE;
+ data->sentCounter = 0;
+ data->getCounter = 0;
+ data->rand = 0;
+ VarSet(VAR_WONDER_NEWS_COUNTER, 0);
+}
+
+// Unused
+static void TryIncrementWonderNewsVar(void)
+{
+ u16 *var = GetVarPointer(VAR_WONDER_NEWS_COUNTER);
+ struct WonderNewsMetadata *data = GetSavedWonderNewsMetadata();
+
+ if (data->getCounter > 4 && ++(*var) >= 500)
+ {
+ data->getCounter = 0;
+ *var = 0;
+ }
+}
+
+// Unused
+u16 RetrieveWonderNewsVal(void)
+{
+ u16 *result = &gSpecialVar_Result;
+ struct WonderNewsMetadata *data = GetSavedWonderNewsMetadata();
+ u16 newsVal;
+
+ // Checks if Mystery Event is enabled, not Mystery Gift?
+ if (!IsMysteryEventEnabled() || !ValidateSavedWonderNews())
+ return 0;
+
+ newsVal = GetNewsValByNewsType(data);
+
+ switch (newsVal)
+ {
+ case NEWS_VAL_RECV_FRIEND:
+ *result = GetNewsId(data);
+ break;
+ case NEWS_VAL_RECV_WIRELESS:
+ *result = GetNewsId(data);
+ break;
+ case NEWS_VAL_SENT:
+ *result = GetNewsId(data);
+ IncrementSentNewsCounter(data);
+ break;
+ case NEWS_VAL_SENT_MAX:
+ *result = GetNewsId(data);
+ ResetSentNewsCounter(data);
+ break;
+ case NEWS_VAL_INVALID:
+ case NEWS_VAL_NONE:
+ case NEWS_VAL_GET_MAX:
+ break;
+ }
+
+ return newsVal;
+}
+
+static u32 GetNewsId(struct WonderNewsMetadata *data)
+{
+ u32 id;
+ data->newsType = WONDER_NEWS_NONE;
+ id = data->rand + 132;
+ data->rand = 0;
+ IncrementGetNewsCounter(data);
+ return id;
+}
+
+static void ResetSentNewsCounter(struct WonderNewsMetadata *data)
+{
+ data->sentCounter = 0;
+}
+
+static void IncrementSentNewsCounter(struct WonderNewsMetadata *data)
+{
+ data->sentCounter++;
+ if (data->sentCounter > 4)
+ data->sentCounter = 4;
+}
+
+static void IncrementGetNewsCounter(struct WonderNewsMetadata *data)
+{
+ data->getCounter++;
+ if (data->getCounter > 5)
+ data->getCounter = 5;
+}
+
+static u32 GetNewsValByNewsType(struct WonderNewsMetadata *data)
+{
+ if (data->getCounter == 5)
+ return NEWS_VAL_GET_MAX;
+
+ switch (data->newsType)
+ {
+ case WONDER_NEWS_NONE:
+ return NEWS_VAL_NONE;
+ case WONDER_NEWS_RECV_FRIEND:
+ return NEWS_VAL_RECV_FRIEND;
+ case WONDER_NEWS_RECV_WIRELESS:
+ return NEWS_VAL_RECV_WIRELESS;
+ case WONDER_NEWS_SENT:
+ if (data->sentCounter < 3)
+ return NEWS_VAL_SENT;
+ return NEWS_VAL_SENT_MAX;
+ default:
+ AGB_ASSERT(0);
+ return NEWS_VAL_INVALID;
+ }
+}