diff --git a/.github/calcrom/calcrom.pl b/.github/calcrom/calcrom.pl index 4858babb9..c351c7612 100755 --- a/.github/calcrom/calcrom.pl +++ b/.github/calcrom/calcrom.pl @@ -1,9 +1,15 @@ #!/usr/bin/perl use IPC::Cmd qw[ run ]; +use Getopt::Long; + +my $usage = "Usage: calcrom.pl file.map [--data]\n"; + +my $showData; +GetOptions("data" => \$showData) or die $usage; (@ARGV == 1) - or die "ERROR: no map file specified.\n"; + or die $usage; open(my $file, $ARGV[0]) or die "ERROR: could not open file '$ARGV[0]'.\n"; @@ -149,17 +155,13 @@ else print "$undocumented symbols undocumented ($undocPct%)\n"; } -print "\n"; -my $dataTotal = $srcdata + $data; -my $srcDataPct = sprintf("%.4f", 100 * $srcdata / $dataTotal); -my $dataPct = sprintf("%.4f", 100 * $data / $dataTotal); +if ($showData) +{ + print "\n"; + my $dataTotal = $srcdata + $data; + my $srcDataPct = sprintf("%.4f", 100 * $srcdata / $dataTotal); + my $dataPct = sprintf("%.4f", 100 * $data / $dataTotal); -if ($data == 0) -{ - print "Data porting to C is 100% complete\n" -} -else -{ print "$dataTotal total bytes of data\n"; print "$srcdata bytes of data in src ($srcDataPct%)\n"; print "$data bytes of data in data ($dataPct%)\n"; diff --git a/common_syms/link_rfu_2.txt b/common_syms/link_rfu_2.txt index ac292845e..4b8f02bad 100644 --- a/common_syms/link_rfu_2.txt +++ b/common_syms/link_rfu_2.txt @@ -1,2 +1,2 @@ -gf_rfu_REQ_api -Rfu +gRfuAPIBuffer +gRfu diff --git a/data/specials.inc b/data/specials.inc index 30276f053..81b25c14d 100644 --- a/data/specials.inc +++ b/data/specials.inc @@ -43,7 +43,7 @@ gSpecials:: def_special CloseLink def_special ColosseumPlayerSpotTriggered def_special PlayerEnteredTradeSeat - def_special nullsub_37 + def_special Script_StartWiredTrade def_special CableClubSaveGame def_special TryBerryBlenderLinkup def_special GetLinkPartnerNames diff --git a/include/AgbRfu_LinkManager.h b/include/AgbRfu_LinkManager.h index d4ef13183..3b38b85fc 100644 --- a/include/AgbRfu_LinkManager.h +++ b/include/AgbRfu_LinkManager.h @@ -120,10 +120,10 @@ typedef struct InitializeParametersTag { // rfu_REQ_configSystem argument u8 maxMFrame; // Maximum number of times to re-transmit of RFU level u8 MC_TimerCount; // MC_Timer count (x16.7ms) - u16 availSlot_flag; // Use RFU-API constant "AVAIL_SLOT1-4" to specify the maximum number of child devices (1 - 4) that can be connected to a parent device. + u16 availSlot_flag; // Use RFU-API constant "AVAIL_SLOT1-4" to specify the maximum number of child devices (1 - 4) that can be connected to a parent device. // rfu_REQB_configGameData argument - u8 mboot_flag; // Multiplayer boot flag + u8 mboot_flag; // Multiplayer boot flag u16 serialNo; // Game serial number u8 *gameName; // Game name u8 *userName; // User name @@ -132,8 +132,8 @@ typedef struct InitializeParametersTag { u8 fastSearchParent_flag; // Flag indicating whether parent fast search operation to be performed by child. // Link recovery settings - u8 linkRecovery_enable; // Determines whether or not to execute the link recovery process when a link cut occurs - u16 linkRecovery_period; // Time to spend on the link recovery process (x 16.7 ms) Note: Runs for unlimited time when specifying 0. + u8 linkRecovery_enable; // Determines whether or not to execute the link recovery process when a link cut occurs + u16 linkRecovery_period; // Time to spend on the link recovery process (x 16.7 ms) Note: Runs for unlimited time when specifying 0. // Setting for NI-type data transmit/receive period u16 NI_failCounter_limit; // Limit for failCounter during NI type data transmit/receive (x 16.7 ms) Note: Runs for unlimited time when specifying 0. @@ -142,44 +142,49 @@ typedef struct InitializeParametersTag { // Timer that counts with the V-Blank cycle typedef struct VblankTimerTag { - u8 active; // Timer ON/OFF (bits 0 - 3 indicate ON/OFF for each connected slot) - u16 count_max; // Maximum count value (x16.7ms) + u8 active; // Timer ON/OFF (bits 0 - 3 indicate ON/OFF for each connected slot) + u16 count_max; // Maximum count value (x16.7ms) u16 count[RFU_CHILD_MAX]; // Current count value (x 16.7 ms) for each connected slot }VBL_TIMER; typedef struct linkManagerTag { - /* 0x000 */ u8 acceptSlot_flag; - /* 0x001 */ u8 acceptCount; - /* 0x002 */ vu8 childClockSlave_flag; - /* 0x003 */ vu8 parentAck_flag; - /* 0x004 */ u8 state; - /* 0x005 */ u8 next_state; - /* 0x006 */ u8 parent_child; - /* 0x007 */ u8 pcswitch_flag; - /* 0x008 */ u8 RFU_powerOn_flag; - /* 0x009 */ u8 linkRecovery_enable; - /* 0x00a */ u8 linkRecovery_start_flag; - /* 0x00b */ u8 fastSearchParent_flag; - /* 0x00c */ u8 connectSlot_flag_old; - /* 0x00d */ u8 reserveDisconnectSlot_flag; - /* 0x00e */ u8 active; - /* 0x00f */ u8 msc_exe_flag; - /* 0x010 */ u8 child_slot; - /* 0x011 */ u8 state_bak[2]; - /* 0x014 */ u16 param[2]; - /* 0x018 */ u16 NI_failCounter_limit; - /* 0x01a */ u16 connect_period; - /* 0x01c */ u16 pcswitch_period_bak; - /* 0x01e */ u16 work; - /* 0x020 */ u16 *acceptable_serialNo_list; - /* 0x024 */ VBL_TIMER nameAcceptTimer; - /* 0x030 */ VBL_TIMER linkRecoveryTimer; - /* 0x03c */ INIT_PARAM *init_param; - /* 0x040 */ void (*LMAN_callback)(u8, u8); - /* 0x044 */ void (*MSC_callback)(u16); + u8 acceptSlot_flag; // Connection slot of child for which Link Manager accepted connection, expressed in bits. (This bit is not dropped for a broken link but is dropped with complete disconnection.) + u8 acceptCount; // Number of child devices for which connections accepted by Link Manager. + vu8 childClockSlave_flag; // Flag indicating whether AGB clock slave state is currently being maintained by child. + vu8 parentAck_flag; // Flag indicating the child devices for which the parent received ACK by UNI commmunication. + u8 state; // Current link manager state + u8 next_state; // State that the link manager transitions to when it is next called. + u8 parent_child; // Shows whether operating on a parent or child. + u8 pcswitch_flag; // Flag for parent-child switching search. + u8 RFU_powerOn_flag; // Flag indicating whether RFU has been powered down. + u8 linkRecovery_enable; // ON/OFF flag for the link recovery process. + u8 linkRecovery_start_flag; // Link recovery start flag + u8 fastSearchParent_flag; // ON/OFF flag for parent fast search by child. + u8 connectSlot_flag_old; // Value of rfuLinkStatus->connectSlot_flag (internally used by the API) when the link manager was called previously. + u8 reserveDisconnectSlot_flag; // Bit indication of the child slot that was reject by child connection authentication and is waiting for disconnect. + u8 active; // Link manager operating flag (internally used by the API) + u8 msc_exe_flag; // MSC callback executing flag (internally used by the API) + u8 child_slot; // Slot number where child device connected (internally used by the API) + u8 state_bak[2]; // Backup of link manager state (internally used by the API) + u16 param[2]; // Region where parameters returned when LMAN callback occurs are stored. + u16 NI_failCounter_limit; // Period of failCounter during NI type data transmit/receive (x 16.7 ms) Note: Runs for unlimited time when specifying 0 + u16 connect_period; // Count for the period to execute a connection process (x 16.7 ms). Note: Runs for unlimited time when specifying 0. + u16 pcswitch_period_bak; // Backup for No. 3 SC period during parent-child switching search. + u16 work; // Work region used by the link manager. + u16 *acceptable_serialNo_list; // List of game serial numbers that can accept connections. (See Note below) + VBL_TIMER nameAcceptTimer; // Timer for period to receive game names from child device. + VBL_TIMER linkRecoveryTimer; // Timer for the link recovery process period for both parent and child. Note: Runs for unlimited time when specifying 0. + INIT_PARAM *init_param; // Pointer to parameter when executing initial setting process. + void (*LMAN_callback)(u8 msg,u8 param_count); // Pointer to user-defined LMAN callback routine generated by link manager operation. + void (*MSC_callback)(u16 REQ_commandID); // User-defined MSC callback function. (When defining the link manager, defines the MSC callback using rfu_LMAN_initializeManager or rfu_LMAN_setMSCCallback without using rfu_setMSCCallback.) } LINK_MANAGER; +/* Note: The acceptable_serialNo_list uses the following format to specify a list of game serial numbers that the parent device can accept connections from and terminates with 0xffff. (maximum 16 devices) + + u16 acceptable_serialNo_list[]={0x0001, 0x0002, 0x0003, 0xffff}; +*/ + extern struct linkManagerTag lman; u32 rfu_LMAN_REQBN_softReset_and_checkID(void); diff --git a/include/constants/map_scripts.h b/include/constants/map_scripts.h index 7a56cc908..c89df3948 100644 --- a/include/constants/map_scripts.h +++ b/include/constants/map_scripts.h @@ -13,14 +13,14 @@ Almost exclusively used to set metatiles on the map before it's first drawn 6. ON_FRAME_TABLE: Run every frame after the map has faded in, before player input is processed. - This is a table of scripts that each run if their condition is satisfied. + This is a table of scripts; only the first script whose condition is satisfied is run. Used to trigger an event, such as the player exiting the cable car or the SS Tidal sailor announcing progress 2. ON_TRANSITION: Run during the transition to the map Used to set map-specific flags/vars, update object positions/movement types, set weather, etc 5. ON_WARP_INTO_MAP_TABLE: Run after the map's objects are loaded. - This is a table of scripts that each run if their condition is satisfied. + This is a table of scripts; only the first script whose condition is satisfied is run. Used to add objects to the scene or update something about the player as they warp in (e.g. their facing dir or visibility) Note that ON_TRANSITION may also handle object visibility, but would do so by modifying a flag or var diff --git a/include/constants/union_room.h b/include/constants/union_room.h index d867fb340..6e08c9ebb 100644 --- a/include/constants/union_room.h +++ b/include/constants/union_room.h @@ -1,7 +1,11 @@ #ifndef GUARD_CONSTANTS_UNION_ROOM_H #define GUARD_CONSTANTS_UNION_ROOM_H -#define MAX_UNION_ROOM_PLAYERS 8 +// The number of possible group leaders visible in the Union Room. +// Note that this is different than the number of people actively +// connected as children via the Wireless Adapter, which cannot +// exceed RFU_CHILD_MAX (4), for a total of 5 including the player. +#define MAX_UNION_ROOM_LEADERS 8 #define UNION_ROOM_SPAWN_NONE 0 #define UNION_ROOM_SPAWN_IN 1 @@ -13,8 +17,8 @@ #define ACTIVITY_BATTLE_MULTI 3 #define ACTIVITY_TRADE 4 #define ACTIVITY_CHAT 5 -#define ACTIVITY_WONDER_CARD 6 -#define ACTIVITY_WONDER_NEWS 7 +#define ACTIVITY_WONDER_CARD_DUP 6 // Duplicates of later WONDER constants +#define ACTIVITY_WONDER_NEWS_DUP 7 // #define ACTIVITY_CARD 8 #define ACTIVITY_POKEMON_JUMP 9 #define ACTIVITY_BERRY_CRUSH 10 @@ -32,9 +36,8 @@ #define ACTIVITY_NPCTALK 19 #define ACTIVITY_PLYRTALK 20 -// Duplicate IDs? -#define ACTIVITY_WONDER_CARD2 21 -#define ACTIVITY_WONDER_NEWS2 22 +#define ACTIVITY_WONDER_CARD 21 +#define ACTIVITY_WONDER_NEWS 22 #define ACTIVITY_CONTEST_COOL 23 #define ACTIVITY_CONTEST_BEAUTY 24 @@ -46,15 +49,6 @@ #define IN_UNION_ROOM (1 << 6) -// Used in UR_AddTextPrinterParameterized -#define UR_COLOR_DKE_WHT_LTE 0 -#define UR_COLOR_RED_WHT_LTR 1 -#define UR_COLOR_GRN_WHT_LTG 2 -#define UR_COLOR_WHT_WHT_LTE 3 -#define UR_COLOR_WHT_DKE_LTE 4 -#define UR_COLOR_GRN_DN6_LTB 5 -#define UR_COLOR_DN5_DN6_LTB 6 - #define LINK_GROUP_SINGLE_BATTLE 0 #define LINK_GROUP_DOUBLE_BATTLE 1 #define LINK_GROUP_MULTI_BATTLE 2 diff --git a/include/link.h b/include/link.h index 5479d77d4..4e0491356 100644 --- a/include/link.h +++ b/include/link.h @@ -104,6 +104,14 @@ #define LINKTYPE_CONTEST_GMODE 0x6601 #define LINKTYPE_CONTEST_EMODE 0x6602 +enum { + BLOCK_REQ_SIZE_NONE, // Identical to 200 + BLOCK_REQ_SIZE_200, + BLOCK_REQ_SIZE_100, + BLOCK_REQ_SIZE_220, + BLOCK_REQ_SIZE_40, +}; + struct LinkStatus { u32 localId:2; @@ -227,8 +235,6 @@ struct BlockRequest u32 size; }; -extern const struct BlockRequest sBlockRequestLookupTable[5]; - extern struct Link gLink; extern u16 gRecvCmds[MAX_RFU_PLAYERS][CMD_LENGTH]; extern u8 gBlockSendBuffer[BLOCK_BUFFER_SIZE]; @@ -236,8 +242,7 @@ extern u16 gLinkType; extern u32 gLinkStatus; extern u16 gBlockRecvBuffer[MAX_RFU_PLAYERS][BLOCK_BUFFER_SIZE / 2]; extern u16 gSendCmd[CMD_LENGTH]; -extern struct LinkPlayer gLinkPlayers[5]; -extern u16 word_3002910[]; +extern struct LinkPlayer gLinkPlayers[MAX_RFU_PLAYERS]; extern bool8 gReceivedRemoteLinkPlayers; extern u32 gBerryBlenderKeySendAttempts; extern bool8 gLinkVSyncDisabled; @@ -249,8 +254,6 @@ void Task_DestroySelf(u8 taskId); void OpenLink(void); void CloseLink(void); u16 LinkMain2(const u16 *); -void sub_8007B14(void); -bool32 sub_8007B24(void); void ClearLinkCallback(void); void ClearLinkCallback_2(void); u8 GetLinkPlayerCount(void); @@ -259,10 +262,8 @@ u8 GetLinkPlayerDataExchangeStatusTimed(int lower, int upper); bool8 IsLinkPlayerDataExchangeComplete(void); u32 GetLinkPlayerTrainerId(u8); void ResetLinkPlayers(void); -void sub_8007E24(void); -void sub_8007E4C(void); u8 GetMultiplayerId(void); -u8 bitmask_all_link_players_but_self(void); +u8 BitmaskAllOtherLinkPlayers(void); bool8 SendBlock(u8, const void *, u16); u8 GetBlockReceivedStatus(void); void ResetBlockReceivedFlags(void); @@ -270,7 +271,7 @@ void ResetBlockReceivedFlag(u8); u8 GetLinkPlayerCount_2(void); bool8 IsLinkMaster(void); void CB2_LinkError(void); -u8 GetSioMultiSI(void); +bool8 GetSioMultiSI(void); bool8 IsLinkConnectionEstablished(void); bool8 HasLinkErrorOccurred(void); void ResetSerial(void); @@ -285,16 +286,14 @@ void CreateWirelessStatusIndicatorSprite(u8, u8); void SetLinkStandbyCallback(void); void SetWirelessCommType1(void); void CheckShouldAdvanceLinkState(void); -u8 IsLinkMaster(void); void SetCloseLinkCallback(void); bool8 HandleLinkConnection(void); void SetLinkDebugValues(u32 seed, u32 flags); void SetBerryBlenderLinkCallback(void); void SetSuppressLinkErrorMessage(bool8 flag); void ConvertLinkPlayerName(struct LinkPlayer *linkPlayer); -u8 GetSioMultiSI(void); void ClearSavedLinkPlayers(void); -void BufferLinkErrorInfo(u32 status, u8 lastSendQueueCount, u8 lastRecvQueueCount, bool8 disconnected); +void SetLinkErrorBuffer(u32 status, u8 lastSendQueueCount, u8 lastRecvQueueCount, bool8 disconnected); void LocalLinkPlayerToBlock(void); void LinkPlayerFromBlock(u32 who); bool32 Link_AnyPartnersPlayingFRLG_JP(void); @@ -312,8 +311,6 @@ extern bool8 gRemoteLinkPlayersNotReceived[MAX_LINK_PLAYERS]; extern u8 gBlockReceivedStatus[MAX_LINK_PLAYERS]; extern u16 gLinkHeldKeys; extern u32 gLinkStatus; -extern u8 gUnknown_030030E4; -extern u8 gUnknown_030030E8; extern bool8 gReadyToExitStandby[MAX_LINK_PLAYERS]; extern bool8 gReadyToCloseLink[MAX_LINK_PLAYERS]; extern u16 gReadyCloseLinkType; @@ -329,23 +326,14 @@ extern u8 gBlockRequestType; extern u8 gLastSendQueueCount; extern u8 gLastRecvQueueCount; extern u16 gLinkSavedIme; -extern u32 gFiller_03003074; -extern u32 gFiller_03003154; -extern u32 gFiller_03003158; -extern u32 gFiller_0300315c; -extern u32 gFiller_03004138; -extern u32 gFiller_0300413C; -extern u32 gFiller_03003080; extern struct LinkPlayer gLocalLinkPlayer; bool32 Link_AnyPartnersPlayingRubyOrSapphire(void); bool32 LinkDummy_Return2(void); void SetLocalLinkPlayerId(u8); u8 GetSavedPlayerCount(void); -void sub_8009FAC(void); bool8 SendBlockRequest(u8 type); u8 GetLinkPlayerCountAsBitFlags(void); -u8 sub_800A0C8(s32, s32); u8 GetSavedLinkPlayerCountAsBitFlags(void); void SetCloseLinkCallbackHandleJP(void); void CheckLinkPlayersMatchSaved(void); diff --git a/include/link_rfu.h b/include/link_rfu.h index e1c3a6fba..dfbc71657 100644 --- a/include/link_rfu.h +++ b/include/link_rfu.h @@ -5,29 +5,30 @@ #include "link.h" #include "AgbRfu_LinkManager.h" +#define RFUCMD_MASK 0xFF00 + #define RFUCMD_SEND_PACKET 0x2F00 #define RFUCMD_BLENDER_SEND_KEYS 0x4400 #define RFUCMD_READY_CLOSE_LINK 0x5F00 #define RFUCMD_READY_EXIT_STANDBY 0x6600 -#define RFUCMD_0x7700 0x7700 -#define RFUCMD_0x7800 0x7800 -#define RFUCMD_0x8800 0x8800 -#define RFUCMD_0x8900 0x8900 +#define RFUCMD_SEND_PLAYER_IDS 0x7700 +#define RFUCMD_SEND_PLAYER_IDS_NEW 0x7800 +#define RFUCMD_SEND_BLOCK_INIT 0x8800 +#define RFUCMD_SEND_BLOCK 0x8900 #define RFUCMD_SEND_BLOCK_REQ 0xA100 #define RFUCMD_SEND_HELD_KEYS 0xBE00 -#define RFUCMD_0xED00 0xED00 -#define RFUCMD_0xEE00 0xEE00 +#define RFUCMD_DISCONNECT 0xED00 +#define RFUCMD_DISCONNECT_PARENT 0xEE00 -#define RFU_SERIAL_7F7D 0x7F7D +#define RFU_SERIAL_GAME 0x0002 // Serial number for Pokémon game (FRLG or Emerald) +#define RFU_SERIAL_WONDER_DISTRIBUTOR 0x7F7D // Serial number for distributing Wonder Cards / News +#define RFU_SERIAL_UNKNOWN 0x0000 // Unreferenced acceptable serial number. Gamecube? +#define RFU_SERIAL_END 0xFFFF +#define COMM_SLOT_LENGTH 14 #define RECV_QUEUE_NUM_SLOTS 32 -#define RECV_QUEUE_SLOT_LENGTH (14 * MAX_RFU_PLAYERS) - #define SEND_QUEUE_NUM_SLOTS 40 -#define SEND_QUEUE_SLOT_LENGTH 14 - #define BACKUP_QUEUE_NUM_SLOTS 2 -#define BACKUP_QUEUE_SLOT_LENGTH 14 #define RFU_PACKET_SIZE 6 @@ -41,12 +42,42 @@ #define RFU_STATUS_WAIT_ACK_JOIN_GROUP 7 #define RFU_STATUS_LEAVE_GROUP_NOTICE 8 #define RFU_STATUS_LEAVE_GROUP 9 -#define RFU_STATUS_10 10 -#define RFU_STATUS_11 11 +#define RFU_STATUS_CHILD_LEAVE_READY 10 +#define RFU_STATUS_CHILD_LEAVE 11 #define RFU_STATUS_ACK_JOIN_GROUP 12 -// RfuTgtData.gname is read as these structs. -struct GFtgtGnameSub +// Values for disconnectMode +enum { + RFU_DISCONNECT_NONE, + RFU_DISCONNECT_ERROR, + RFU_DISCONNECT_NORMAL, +}; + +// Values for errorState +enum { + RFU_ERROR_STATE_NONE, + RFU_ERROR_STATE_OCCURRED, + RFU_ERROR_STATE_PROCESSED, + RFU_ERROR_STATE_DISCONNECTING, + RFU_ERROR_STATE_IGNORE, +}; + +// These error flags are set in errorInfo, and given as +// the uppermost 16 bits of 'status' for sLinkErrorBuffer. +// The first 8 bits are reserved for the link manager msg +// when the error occurred, and the last 8 bits are this +// sequence of presumably meaningful error flags, but +// ultimately sLinkErrorBuffer's status is never read. +#define F_RFU_ERROR_1 (1 << 8) +#define F_RFU_ERROR_2 (1 << 9) // Never set +#define F_RFU_ERROR_3 (1 << 10) // Never set +#define F_RFU_ERROR_4 (1 << 11) // Never set +#define F_RFU_ERROR_5 (1 << 12) +#define F_RFU_ERROR_6 (1 << 13) +#define F_RFU_ERROR_7 (1 << 14) +#define F_RFU_ERROR_8 (1 << 15) + +struct RfuGameCompatibilityData { u16 language:4; u16 hasNews:1; @@ -56,24 +87,41 @@ struct GFtgtGnameSub u16 hasNationalDex:1; u16 gameClear:1; u16 version:4; + u16 unused:2; u8 playerTrainerId[2]; }; -struct __attribute__((packed, aligned(2))) GFtgtGname +// This struct is sent via the Wireless Adapter as the game name or "gname" data. +// Gname is only applicable during Wireless Single Game Pak Multiplay, when the +// adapter needs this data for connection. Per the RFU manual, during "normal" +// wireless play (the kind the Pokémon games use) the gname data can be used for +// anything the developers want. This struct is what GF decided to use it for. +// It can be up to 13 bytes in size (RFU_GAME_NAME_LENGTH). +// The player's name is sent separately as the username ("uname"), and does not +// use a struct (gHostRfuUsername). +struct __attribute__((packed, aligned(2))) RfuGameData { - struct GFtgtGnameSub unk_00; - u8 child_sprite_gender[RFU_CHILD_MAX]; // u8 sprite_idx:3; - // u8 gender:1; - // u8 unk_4:3 - // u8 active:1 - u16 species:10; - u16 type:6; + struct RfuGameCompatibilityData compatibility; + u8 partnerInfo[RFU_CHILD_MAX]; + u16 tradeSpecies:10; + u16 tradeType:6; u8 activity:7; - u8 started:1; + u8 startedActivity:1; u8 playerGender:1; - u8 level:7; + u8 tradeLevel:7; u8 padding; -}; // size: RFU_GNAME_SIZE +}; + +// Constants for getting/setting information in 'partnerInfo' of RfuGameData. +// This data is used to determine what the link partners look like from +// the host's perspective. +// Bits 0-2 are a shortened trainerId +// Bit 3 is the player's gender +// Bits 4-6 are unknown/unused +// Bit 7 is an 'active' flag +#define PINFO_TID_MASK 0x7 +#define PINFO_GENDER_SHIFT 3 +#define PINFO_ACTIVE_FLAG (1 << 7) struct RfuBlockSend { @@ -89,7 +137,7 @@ struct RfuBlockSend struct RfuRecvQueue { - /* 0x000 */ u8 slots[RECV_QUEUE_NUM_SLOTS][RECV_QUEUE_SLOT_LENGTH]; + /* 0x000 */ u8 slots[RECV_QUEUE_NUM_SLOTS][COMM_SLOT_LENGTH * MAX_RFU_PLAYERS]; /* 0x8c0 */ vu8 recvSlot; /* 0x8c1 */ vu8 sendSlot; /* 0x8c2 */ vu8 count; @@ -98,7 +146,7 @@ struct RfuRecvQueue struct RfuSendQueue { - /* 0x000 */ u8 slots[SEND_QUEUE_NUM_SLOTS][SEND_QUEUE_SLOT_LENGTH]; + /* 0x000 */ u8 slots[SEND_QUEUE_NUM_SLOTS][COMM_SLOT_LENGTH]; /* 0x230 */ vu8 recvSlot; /* 0x231 */ vu8 sendSlot; /* 0x232 */ vu8 count; @@ -107,33 +155,34 @@ struct RfuSendQueue struct RfuBackupQueue { - /* 0x00 */ u8 slots[BACKUP_QUEUE_NUM_SLOTS][BACKUP_QUEUE_SLOT_LENGTH]; + /* 0x00 */ u8 slots[BACKUP_QUEUE_NUM_SLOTS][COMM_SLOT_LENGTH]; /* 0x1c */ vu8 recvSlot; /* 0x1d */ vu8 sendSlot; /* 0x1e */ vu8 count; }; -struct GFRfuManager +// Stores data needed for the RFU on GF's end +struct RfuManager { /* 0x000 */ void (*callback)(void); /* 0x004 */ u16 state; - /* 0x006 */ u8 filler_06[4]; - /* 0x00a */ u16 linkmanMsg; + /* 0x006 */ u8 unused1[4]; + /* 0x00a */ u16 errorInfo; /* 0x00c */ u8 parentChild; /* 0x00d */ u8 playerCount; - /* 0x00e */ bool8 unk_0e; - /* 0x00f */ u8 unk_0f; - /* 0x010 */ u16 unk_10; - /* 0x012 */ u16 unk_12; - /* 0x014 */ u8 unk_14[RFU_CHILD_MAX][14]; - /* 0x04c */ u8 unk_4c[14]; + /* 0x00e */ bool8 runParentMain2; + /* 0x00f */ u8 unused2; + /* 0x010 */ u16 errorParam0; + /* 0x012 */ u16 errorParam1; + /* 0x014 */ u8 childRecvBuffer[RFU_CHILD_MAX][COMM_SLOT_LENGTH]; + /* 0x04c */ u8 childSendBuffer[COMM_SLOT_LENGTH]; /* 0x05a */ u8 blockRequestType; - /* 0x05b */ u8 unk_5b; + /* 0x05b */ u8 blockSendAttempts; /* 0x05c */ bool8 blockReceived[MAX_RFU_PLAYERS]; /* 0x061 */ bool8 numBlocksReceived[MAX_RFU_PLAYERS]; /* 0x066 */ u8 idleTaskId; /* 0x067 */ u8 searchTaskId; - /* 0x068 */ u8 filler_68[4]; + /* 0x068 */ u8 unused3[4]; /* 0x06c */ struct RfuBlockSend sendBlock; /* 0x080 */ struct RfuBlockSend recvBlock[MAX_RFU_PLAYERS]; /* 0x0e4 */ bool8 readyCloseLink[MAX_RFU_PLAYERS]; @@ -144,59 +193,56 @@ struct GFRfuManager /* 0x0f1 */ u8 status; /* 0x0f2 */ u16 packet[RFU_PACKET_SIZE]; /* 0x0fe */ u16 resendExitStandbyTimer; - /* 0x100 */ u16 unk_100; - /* 0x102 */ u8 unk_102; - /* 0x103 */ u8 filler_103[0x10A - 0x103]; - /* 0x10A */ struct GFtgtGname unk_10A; + /* 0x100 */ u16 allReadyNum; + /* 0x102 */ u8 childSendCmdId; + /* 0x103 */ u8 unused4[7]; + /* 0x10A */ struct RfuGameData parent; u8 filler_; - u8 playerName[PLAYER_NAME_LENGTH + 1]; + u8 parentName[RFU_USER_NAME_LENGTH]; /* 0x124 */ struct RfuRecvQueue recvQueue; /* 0x9e8 */ struct RfuSendQueue sendQueue; /* 0xc1c */ struct RfuBackupQueue backupQueue; /* 0xc3c */ vu8 linkRecovered; - /* 0xc3d */ u8 unk_c3d; + /* 0xc3d */ u8 reconnectParentId; /* 0xc3e */ vu8 childSlot; - /* 0xc3f */ u8 unk_c3f[70]; - /* 0xc85 */ u8 unk_c85; - /* 0xc86 */ u8 recvStatus; - /* 0xc87 */ u8 recvCmds[5][7][2]; + /* 0xc3f */ u8 childRecvQueue[COMM_SLOT_LENGTH * MAX_RFU_PLAYERS]; + /* 0xc85 */ u8 leaveGroupStatus; + /* 0xc86 */ u8 childRecvStatus; + /* 0xc87 */ u8 recvCmds[MAX_RFU_PLAYERS][CMD_LENGTH - 1][2]; /* 0xccd */ u8 parentId; /* 0xcce */ u8 multiplayerId; - /* 0xccf */ u8 unk_ccf; - /* 0xcd0 */ vu8 unk_cd0; + /* 0xccf */ u8 connectParentFailures; + /* 0xcd0 */ vu8 childSendCount; /* 0xcd1 */ u8 partnerSendStatuses[RFU_CHILD_MAX]; /* 0xcd5 */ u8 partnerRecvStatuses[RFU_CHILD_MAX]; - /* 0xcd9 */ u8 unk_cd9; - /* 0xcda */ u8 unk_cda; - /* 0xcdb */ vbool8 unk_cdb; - /* 0xcdc */ vbool8 unk_cdc; - /* 0xcdd */ u8 unk_cdd; + /* 0xcd9 */ bool8 stopNewConnections; + /* 0xcda */ u8 parentSendSlot; + /* 0xcdb */ vbool8 parentFinished; + /* 0xcdc */ vbool8 parentMain2Failed; + /* 0xcdd */ u8 unused5; /* 0xcde */ u8 linkPlayerIdx[RFU_CHILD_MAX]; - /* 0xce2 */ u8 unk_ce2; - /* 0xce2 */ u8 unk_ce3; - /* 0xce4 */ u8 unk_ce4; - /* 0xce5 */ u8 unk_ce5; - /* 0xce5 */ u8 unk_ce6; + /* 0xce2 */ u8 parentSlots; + /* 0xce2 */ u8 disconnectSlots; + /* 0xce4 */ u8 disconnectMode; + /* 0xce5 */ u8 nextChildBits; + /* 0xce5 */ u8 newChildQueue; /* 0xce7 */ u8 acceptSlot_flag; - /* 0xce8 */ u8 unk_ce8; - /* 0xce9 */ u8 unk_ce9; - /* 0xcea */ u8 unk_cea[4]; - /* 0xcee */ u8 unk_cee[4]; + /* 0xce8 */ bool8 playerExchangeActive; + /* 0xce9 */ u8 incomingChild; + /* 0xcea */ u8 numChildRecvErrors[RFU_CHILD_MAX]; + /* 0xcee */ u8 childRecvIds[RFU_CHILD_MAX]; }; // size = 0xcf4 -// Exported RAM declarations - -extern struct GFtgtGname gHostRFUtgtGnameBuffer; -extern u8 gHostRFUtgtUnameBuffer[]; -extern struct GFRfuManager Rfu; +extern struct RfuGameData gHostRfuGameData; +extern u8 gHostRfuUsername[]; +extern struct RfuManager gRfu; extern u8 gWirelessStatusIndicatorSpriteId; -// Exported ROM declarations void WipeTrainerNameRecords(void); void InitRFUAPI(void); void LinkRfu_Shutdown(void); -void Rfu_SetBlockReceivedFlag(u8 who); -void Rfu_ResetBlockReceivedFlag(u8 who); +void Rfu_SetBlockReceivedFlag(u8 linkPlayerId); +void Rfu_ResetBlockReceivedFlag(u8 linkPlayerId); bool32 IsSendingKeysToRfu(void); void StartSendingKeysToRfu(void); void Rfu_SetBerryBlenderLinkCallback(void); @@ -213,61 +259,61 @@ void Rfu_SetLinkStandbyCallback(void); void ResetLinkRfuGFLayer(void); void UpdateWirelessStatusIndicatorSprite(void); void InitRFU(void); -bool32 sub_8010EC0(void); -bool32 sub_8010F1C(void); +bool32 RfuMain1(void); +bool32 RfuMain2(void); bool32 RfuHasErrored(void); bool32 IsRfuRecvQueueEmpty(void); u32 GetRfuRecvQueueLength(void); void RfuVSync(void); -void sub_80111B0(bool32 a0); +void RfuSetIgnoreError(bool32 enable); u8 RfuGetStatus(void); -struct GFtgtGname *GetHostRFUtgtGname(void); -void UpdateGameData_GroupLockedIn(u8 a0); -void GetLinkmanErrorParams(u32 a0); -void RfuSetStatus(u8 a0, u16 a1); -u8 sub_801048C(bool32 a0); -void LinkRfu3_SetGnameUnameFromStaticBuffers(struct GFtgtGname *buff1, u8 *buff2); -void SetHostRFUtgtGname(u8 activity, u32 child_sprite_genders, bool32 started); -void InitializeRfuLinkManager_LinkLeader(u32 a0); -bool32 sub_8012240(void); +struct RfuGameData *GetHostRfuGameData(void); +void UpdateGameData_GroupLockedIn(u8 startedActivity); +void RfuSetErrorParams(u32 errorInfo); +void RfuSetStatus(u8 status, u16 errorInfo); +u8 Rfu_SetLinkRecovery(bool32 enable); +void CopyHostRfuGameDataAndUsername(struct RfuGameData *gameData, u8 *username); +void SetHostRfuGameData(u8 activity, u32 partnerInfo, bool32 startedActivity); +void InitializeRfuLinkManager_LinkLeader(u32 groupMax); +bool32 IsRfuCommunicatingWithAllChildren(void); void LinkRfu_StopManagerAndFinalizeSlots(void); -bool32 sub_80105EC(void); +bool32 RfuTryDisconnectLeavingChildren(void); bool32 HasTrainerLeftPartnersList(u16 trainerId, const u8 *name); void SendRfuStatusToPartner(u8 status, u16 trainerId, const u8 *name); u32 WaitSendRfuStatusToPartner(u16 trainerId, const u8 *name); -void RequestDisconnectSlotByTrainerNameAndId(const u8 *a0, u16 a1); +void RequestDisconnectSlotByTrainerNameAndId(const u8 *name, u16 id); bool8 LmanAcceptSlotFlagIsNotZero(void); -bool32 WaitRfuState(bool32 a0); -void sub_801103C(void); +bool32 WaitRfuState(bool32 force); +void GetOtherPlayersInfoFlags(void); void InitializeRfuLinkManager_JoinGroup(void); void SendLeaveGroupNotice(void); -void RecordMixTrainerNames(void); +void SaveLinkTrainerNames(void); void LinkRfu_CreateConnectionAsParent(void); void LinkRfu_StopManagerBeforeEnteringChat(void); -void UpdateGameData_SetActivity(u8 activity, u32 flags, bool32 started); -void CreateTask_RfuReconnectWithParent(const u8 *src, u16 trainerId); -void SetGnameBufferWonderFlags(bool32 a0, bool32 a1); -void ClearAndInitHostRFUtgtGname(void); +void UpdateGameData_SetActivity(u8 activity, u32 partnerInfo, bool32 startedActivity); +void CreateTask_RfuReconnectWithParent(const u8 *name, u16 trainerId); +void SetHostRfuWonderFlags(bool32 hasNews, bool32 hasCard); +void ResetHostRfuGameData(void); void SetTradeBoardRegisteredMonInfo(u32 type, u32 species, u32 level); void InitializeRfuLinkManager_EnterUnionRoom(void); -void sub_8012188(const u8 *name, struct GFtgtGname *structPtr, u8 a2); +void TryConnectToUnionRoomParent(const u8 *name, struct RfuGameData *parent, u8 activity); bool32 IsUnionRoomListenTaskActive(void); void Rfu_SendPacket(void *data); bool32 PlayerHasMetTrainerBefore(u16 id, u8 *name); -void sub_8011DE0(u32 arg0); -u8 sub_801100C(s32 a0); -void sub_800EF7C(void); -bool8 LinkRfu_GetNameIfCompatible(struct GFtgtGname *buff1, u8 *buff2, u8 idx); -bool8 LinkRfu_GetNameIfSerial7F7D(struct GFtgtGname *buff1, u8 *buff2, u8 idx); -s32 sub_800E87C(u8 idx); +void Rfu_DisconnectPlayerById(u32 playerIdx); +u8 GetLinkPlayerInfoFlags(s32 playerId); +void StopUnionRoomLinkManager(void); +bool8 Rfu_GetCompatiblePlayerData(struct RfuGameData *gameData, u8 *username, u8 idx); +bool8 Rfu_GetWonderDistributorPlayerData(struct RfuGameData *gameData, u8 *username, u8 idx); +s32 Rfu_GetIndexOfNewestChild(u8 bits); void CreateTask_RfuIdle(void); void DestroyTask_RfuIdle(void); void ClearRecvCommands(void); void LinkRfu_FatalError(void); -bool32 sub_8011A9C(void); -void sub_80104B0(void); -void sub_8011A50(void); -void sub_80110B8(u32 a0); +bool32 Rfu_IsPlayerExchangeActive(void); +void Rfu_StopPartnerSearch(void); +void RfuSetNormalDisconnectMode(void); +void SetUnionRoomChatPlayerData(u32 numPlayers); bool32 IsRfuSerialNumberValid(u32 serialNo); bool8 IsRfuRecoveringFromLinkLoss(void); void RfuRecvQueue_Reset(struct RfuRecvQueue *queue); @@ -276,9 +322,9 @@ void RfuRecvQueue_Enqueue(struct RfuRecvQueue *queue, u8 *data); void RfuSendQueue_Enqueue(struct RfuSendQueue *queue, u8 *data); bool8 RfuRecvQueue_Dequeue(struct RfuRecvQueue *queue, u8 *dest); bool8 RfuSendQueue_Dequeue(struct RfuSendQueue *queue, u8 *dest); -void RfuBackupQueue_Enqueue(struct RfuBackupQueue *queue, const u8 *q2); -bool8 RfuBackupQueue_Dequeue(struct RfuBackupQueue *queue, u8 *q2); -void InitHostRFUtgtGname(struct GFtgtGname *data, u8 activity, bool32 started, s32 child_sprite_genders); +void RfuBackupQueue_Enqueue(struct RfuBackupQueue *queue, const u8 *data); +bool8 RfuBackupQueue_Dequeue(struct RfuBackupQueue *queue, u8 *src); +void InitHostRfuGameData(struct RfuGameData *data, u8 activity, bool32 startedActivity, s32 partnerInfo); void CreateWirelessStatusIndicatorSprite(u8 x, u8 y); void DestroyWirelessStatusIndicatorSprite(void); void LoadWirelessStatusIndicatorSpriteGfx(void); diff --git a/include/reload_save.h b/include/reload_save.h new file mode 100644 index 000000000..2ce05e53b --- /dev/null +++ b/include/reload_save.h @@ -0,0 +1,6 @@ +#ifndef GUARD_RELOAD_SAVE_H +#define GUARD_RELOAD_SAVE_H + +void ReloadSave(void); + +#endif // GUARD_RELOAD_SAVE_H diff --git a/include/reset_save_heap.h b/include/reset_save_heap.h deleted file mode 100644 index 12fd186ec..000000000 --- a/include/reset_save_heap.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef GUARD_RESET_SAVE_HEAP_H -#define GUARD_RESET_SAVE_HEAP_H - -// Exported type declarations - -// Exported RAM declarations - -// Exported ROM declarations - -void sub_81700F8(void); - -#endif //GUARD_RESET_SAVE_HEAP_H diff --git a/include/save.h b/include/save.h index 948530406..4eaa72458 100644 --- a/include/save.h +++ b/include/save.h @@ -36,6 +36,7 @@ struct SaveSectionOffsets // Emerald changes this definition to be the sectors per slot. #define NUM_SECTORS_PER_SLOT 16 +#define NUM_SAVE_SLOTS 2 #define UNKNOWN_CHECK_VALUE 0x8012025 #define SPECIAL_SECTION_SENTINEL 0xB39D @@ -104,7 +105,7 @@ bool8 sub_8153408(void); bool8 FullSaveGame(void); bool8 CheckSaveFile(void); u8 Save_LoadGameData(u8 saveType); -u16 sub_815355C(void); +u16 GetSaveBlocksPointersBaseOffset(void); u32 TryReadSpecialSaveSection(u8 sector, u8* dst); u32 TryWriteSpecialSaveSection(u8 sector, u8* src); void Task_LinkSave(u8 taskId); diff --git a/include/trade.h b/include/trade.h index bd8ef8f63..05a905ab3 100644 --- a/include/trade.h +++ b/include/trade.h @@ -16,8 +16,8 @@ extern const struct WindowTemplate gTradeEvolutionSceneYesNoWindowTemplate; s32 GetGameProgressForLinkTrade(void); void CB2_StartCreateTradeMenu(void); void CB2_LinkTrade(void); -int CanRegisterMonForTradingBoard(struct GFtgtGnameSub a0, u16, u16, u8); -int GetUnionRoomTradeMessageId(struct GFtgtGnameSub a0, struct GFtgtGnameSub a1, u16 a2, u16 a3, u8 a4, u16 a5, u8 a6); +int CanRegisterMonForTradingBoard(struct RfuGameCompatibilityData a0, u16, u16, u8); +int GetUnionRoomTradeMessageId(struct RfuGameCompatibilityData a0, struct RfuGameCompatibilityData a1, u16 a2, u16 a3, u8 a4, u16 a5, u8 a6); int CanSpinTradeMon(struct Pokemon*, u16); void InitTradeSequenceBgGpuRegs(void); void LinkTradeDrawWindow(void); diff --git a/include/union_room.h b/include/union_room.h index 563a048d3..b364e7559 100644 --- a/include/union_room.h +++ b/include/union_room.h @@ -5,50 +5,58 @@ #include "link.h" #include "constants/union_room.h" -// Exported type declarations +// In the Union Room the player is only ever connected to ≤ 4 other players. +// However, there can be up to MAX_UNION_ROOM_LEADERS (8) object events to +// represent leaders of recently discovered link groups, and each of those groups +// may have up to MAX_RFU_PLAYERS (5) players in it including the leader. +// These players are represented on-screen by NPC sprites drawn around the leader. +// Thus there can be 40 sprites of other players on-screen, in 8 groups of 5. +#define NUM_UNION_ROOM_SPRITES (MAX_UNION_ROOM_LEADERS * MAX_RFU_PLAYERS) -struct WirelessGnameUnamePair +// The maximum number of recently connected players that can be tracked. +// Note that this is significantly less than NUM_UNION_ROOM_SPRITES, i.e. not +// every player that can be shown in the Union Room can be tracked at once. +// Information such as a group member's gender can instead be read from partnerInfo +// of the leader's RfuGameData by tracking at least all of the group leaders. +#define MAX_RFU_PLAYER_LIST_SIZE 16 + +struct RfuPlayerData { - struct GFtgtGname gname; - u8 ALIGNED(4) playerName[PLAYER_NAME_LENGTH + 1]; + struct RfuGameData data; + u8 ALIGNED(4) name[RFU_USER_NAME_LENGTH]; }; -struct UnkStruct_x1C +struct RfuPlayer { - struct WirelessGnameUnamePair gname_uname; - u8 active:1; -}; - -struct UnkStruct_x20 -{ - struct WirelessGnameUnamePair gname_uname; + struct RfuPlayerData rfu; u16 timeoutCounter; u8 groupScheduledAnim:2; bool8 useRedText:1; // Never set - u8 field_1B; - u8 filler[3]; + u8 newPlayerCountdown; + u8 unused; }; -struct UnkStruct_Main0 +struct RfuPlayerList { - struct UnkStruct_x20 arr[MAX_UNION_ROOM_PLAYERS]; + struct RfuPlayer players[MAX_RFU_PLAYER_LIST_SIZE]; }; -struct UnkStruct_Main4 +struct RfuIncomingPlayer { - struct UnkStruct_x1C arr[MAX_RFU_PLAYERS]; + struct RfuPlayerData rfu; + bool8 active:1; }; -struct UnkStruct_Main8 +struct RfuIncomingPlayerList { - struct UnkStruct_x20 arr[MAX_RFU_PLAYERS]; + struct RfuIncomingPlayer players[MAX_RFU_PLAYERS]; }; struct WirelessLink_Leader { - struct UnkStruct_Main0 *field_0; - struct UnkStruct_Main4 *field_4; - struct UnkStruct_Main8 *field_8; + struct RfuPlayerList *playerList; + struct RfuIncomingPlayerList *incomingPlayerList; + struct RfuPlayerList *playerListBackup; u8 state; u8 textState; u8 delayTimerAfterOk; @@ -57,8 +65,8 @@ struct WirelessLink_Leader u8 nPlayerModeWindowId; u8 listTaskId; u8 playerCount; - u16 field_14; - u8 field_16; + u16 yesNoWindowId; + u8 unused; u8 listenTaskId; u8 activity; u8 joinRequestAnswer; @@ -67,20 +75,20 @@ struct WirelessLink_Leader struct WirelessLink_Group { - struct UnkStruct_Main0 *field_0; - struct UnkStruct_Main4 *field_4; + struct RfuPlayerList *playerList; + struct RfuIncomingPlayerList *incomingPlayerList; u8 state; u8 textState; - u8 field_A; + u8 delayTimerAfterOk; // Unused u8 listWindowId; u8 bButtonCancelWindowId; u8 playerNameAndIdWindowId; u8 listTaskId; u8 leaderId; - u8 field_10; + u8 unused; u8 listenTaskId; - u8 isWonderNews; - u8 field_13; + bool8 isWonderNews; + bool8 showListMenu; // Never set u8 refreshTimer; u8 delayBeforePrint; }; @@ -95,73 +103,59 @@ struct UnionRoomObject struct WirelessLink_URoom { - struct UnkStruct_Main0 *field_0; - struct UnkStruct_Main4 *field_4; - struct UnkStruct_Main0 *field_8; - struct UnkStruct_Main4 *field_C; + struct RfuPlayerList *playerList; + struct RfuIncomingPlayerList *incomingChildList; + struct RfuPlayerList *spawnPlayer; + struct RfuIncomingPlayerList *incomingParentList; u16 unknown; // Never read - u16 field_12; + u16 unreadPlayerId; u8 state; u8 stateAfterPrint; u8 textState; u8 filler[4]; u8 topListMenuWindowId; u8 topListMenuId; - u8 tradeBoardSelectWindowId; - u8 tradeBoardDetailsWindowId; + u8 tradeBoardMainWindowId; + u8 tradeBoardHeaderWindowId; u8 unused1; u8 searchTaskId; - u8 spriteIds[40]; + u8 spriteIds[NUM_UNION_ROOM_SPRITES]; u8 unused2; u8 tradeBoardListMenuId; u16 playerSendBuffer[6]; u8 activityRequestStrbufs[4][16]; u16 partnerYesNoResponse; u16 recvActivityRequest[3]; - struct UnionRoomObject objects[MAX_UNION_ROOM_PLAYERS]; + struct UnionRoomObject objects[MAX_UNION_ROOM_LEADERS]; u8 trainerCardStrBuffer[12][15]; u8 trainerCardColorStrBuffer[48]; u8 trainerCardMsgStrBuffer[200]; }; -union WirelessLink_Main -{ - struct WirelessLink_Leader *leader; - struct WirelessLink_Group *group; - struct WirelessLink_URoom *uRoom; -}; - struct UnionRoomTrade { u16 state; u16 type; u32 playerPersonality; u8 offerPlayerId; - u8 filler1; u16 playerSpecies; u16 playerLevel; u16 species; u16 level; - u16 filler2; u32 personality; }; -// Exported RAM declarations - extern u8 gPlayerCurrActivity; -extern union WirelessLink_Main gUnknown_02022C30; -extern struct GFtgtGnameSub gPartnerTgtGnameSub; +extern struct RfuGameCompatibilityData gRfuPartnerCompatibilityData; extern u16 gUnionRoomOfferedSpecies; extern u8 gUnionRoomRequestedMonType; -// Exported ROM declarations - u8 CreateTask_CreateTradeMenu(void); void SetUsingUnionRoomStartMenu(void); -void MEvent_CreateTask_CardOrNewsWithFriend(u32 arg0); -void MEvent_CreateTask_CardOrNewsOverWireless(u32 arg0); -void MEvent_CreateTask_Leader(u32 arg0); +void MEvent_CreateTask_CardOrNewsWithFriend(u32 activity); +void MEvent_CreateTask_CardOrNewsOverWireless(u32 activity); +void MEvent_CreateTask_Leader(u32 activity); u8 CreateTask_ListenToWireless(void); void StartUnionRoomBattle(u16 battleFlags); diff --git a/include/union_room_player_avatar.h b/include/union_room_player_avatar.h index c7add758a..508545a0e 100644 --- a/include/union_room_player_avatar.h +++ b/include/union_room_player_avatar.h @@ -3,12 +3,12 @@ u8 InitUnionRoomPlayerObjects(struct UnionRoomObject *players); void DestroyUnionRoomPlayerObjects(void); -void CreateGroupMemberSpritesInvisible(u8 *spriteIds, s32 playerIdx); -void DestroyGroupMemberSprites(u8 *spriteIds); +void CreateUnionRoomPlayerSprites(u8 *spriteIds, s32 leaderId); +void DestroyUnionRoomPlayerSprites(u8 *spriteIds); void SetTilesAroundUnionRoomPlayersPassable(void); void ScheduleUnionRoomPlayerRefresh(struct WirelessLink_URoom *uroom); void HandleUnionRoomPlayerRefresh(struct WirelessLink_URoom *uroom); -bool32 TryInteractWithUnionRoomMember(struct UnkStruct_Main0 *main0, s16 *directionPtr, s16 *playerIdxPtr, u8 *spriteIds); -void UpdateUnionRoomMemberFacing(u32 currDirection, u32 playerIdx, struct UnkStruct_Main0 *main0); +bool32 TryInteractWithUnionRoomMember(struct RfuPlayerList *list, s16 *memberIdPtr, s16 *leaderIdPtr, u8 *spriteIds); +void UpdateUnionRoomMemberFacing(u32 memberId, u32 leaderId, struct RfuPlayerList *list); #endif //GUARD_UNION_ROOM_PLAYER_AVATAR_H diff --git a/ld_script.txt b/ld_script.txt index 8c8f19015..218c6d3a5 100644 --- a/ld_script.txt +++ b/ld_script.txt @@ -256,7 +256,7 @@ SECTIONS { src/battle_controller_wally.o(.text); src/player_pc.o(.text); src/intro.o(.text); - src/reset_save_heap.o(.text); + src/reload_save.o(.text); src/field_region_map.o(.text); src/battle_anim_throw.o(.text); src/hall_of_fame.o(.text); diff --git a/src/battle_controllers.c b/src/battle_controllers.c index 0f3234579..0a8ecac02 100644 --- a/src/battle_controllers.c +++ b/src/battle_controllers.c @@ -789,7 +789,7 @@ static void Task_HandleSendLinkBuffersData(u8 taskId) gTasks[taskId].data[15] = 0; } blockSize = (gLinkBattleSendBuffer[gTasks[taskId].data[15] + LINK_BUFF_SIZE_LO] | (gLinkBattleSendBuffer[gTasks[taskId].data[15] + LINK_BUFF_SIZE_HI] << 8)) + LINK_BUFF_DATA; - SendBlock(bitmask_all_link_players_but_self(), &gLinkBattleSendBuffer[gTasks[taskId].data[15]], blockSize); + SendBlock(BitmaskAllOtherLinkPlayers(), &gLinkBattleSendBuffer[gTasks[taskId].data[15]], blockSize); gTasks[taskId].data[11]++; } else diff --git a/src/battle_main.c b/src/battle_main.c index 8481a108a..970473407 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -986,7 +986,7 @@ static void CB2_HandleStartBattle(void) gLinkPlayers[1].id = 1; } - SendBlock(bitmask_all_link_players_but_self(), &gBattleStruct->multiBuffer.linkBattlerHeader, sizeof(gBattleStruct->multiBuffer.linkBattlerHeader)); + SendBlock(BitmaskAllOtherLinkPlayers(), &gBattleStruct->multiBuffer.linkBattlerHeader, sizeof(gBattleStruct->multiBuffer.linkBattlerHeader)); gBattleCommunication[MULTIUSE_STATE] = 2; } if (gWirelessCommType) @@ -1024,7 +1024,7 @@ static void CB2_HandleStartBattle(void) case 3: if (IsLinkTaskFinished()) { - SendBlock(bitmask_all_link_players_but_self(), gPlayerParty, sizeof(struct Pokemon) * 2); + SendBlock(BitmaskAllOtherLinkPlayers(), gPlayerParty, sizeof(struct Pokemon) * 2); gBattleCommunication[MULTIUSE_STATE]++; } break; @@ -1039,7 +1039,7 @@ static void CB2_HandleStartBattle(void) case 7: if (IsLinkTaskFinished()) { - SendBlock(bitmask_all_link_players_but_self(), gPlayerParty + 2, sizeof(struct Pokemon) * 2); + SendBlock(BitmaskAllOtherLinkPlayers(), gPlayerParty + 2, sizeof(struct Pokemon) * 2); gBattleCommunication[MULTIUSE_STATE]++; } break; @@ -1054,7 +1054,7 @@ static void CB2_HandleStartBattle(void) case 11: if (IsLinkTaskFinished()) { - SendBlock(bitmask_all_link_players_but_self(), gPlayerParty + 4, sizeof(struct Pokemon) * 2); + SendBlock(BitmaskAllOtherLinkPlayers(), gPlayerParty + 4, sizeof(struct Pokemon) * 2); gBattleCommunication[MULTIUSE_STATE]++; } break; @@ -1096,7 +1096,7 @@ static void CB2_HandleStartBattle(void) case 16: if (IsLinkTaskFinished()) { - SendBlock(bitmask_all_link_players_but_self(), &gRecordedBattleRngSeed, sizeof(gRecordedBattleRngSeed)); + SendBlock(BitmaskAllOtherLinkPlayers(), &gRecordedBattleRngSeed, sizeof(gRecordedBattleRngSeed)); gBattleCommunication[MULTIUSE_STATE]++; } break; @@ -1188,7 +1188,7 @@ static void CB2_HandleStartMultiPartnerBattle(void) *(&gBattleStruct->multiBuffer.linkBattlerHeader.versionSignatureHi) = 3; BufferPartyVsScreenHealth_AtStart(); SetPlayerBerryDataInBattleStruct(); - SendBlock(bitmask_all_link_players_but_self(), &gBattleStruct->multiBuffer.linkBattlerHeader, sizeof(gBattleStruct->multiBuffer.linkBattlerHeader)); + SendBlock(BitmaskAllOtherLinkPlayers(), &gBattleStruct->multiBuffer.linkBattlerHeader, sizeof(gBattleStruct->multiBuffer.linkBattlerHeader)); gBattleCommunication[MULTIUSE_STATE] = 2; } @@ -1224,7 +1224,7 @@ static void CB2_HandleStartMultiPartnerBattle(void) case 3: if (IsLinkTaskFinished()) { - SendBlock(bitmask_all_link_players_but_self(), gPlayerParty, sizeof(struct Pokemon) * 2); + SendBlock(BitmaskAllOtherLinkPlayers(), gPlayerParty, sizeof(struct Pokemon) * 2); gBattleCommunication[MULTIUSE_STATE]++; } break; @@ -1248,7 +1248,7 @@ static void CB2_HandleStartMultiPartnerBattle(void) case 5: if (IsLinkTaskFinished()) { - SendBlock(bitmask_all_link_players_but_self(), gPlayerParty + 2, sizeof(struct Pokemon)); + SendBlock(BitmaskAllOtherLinkPlayers(), gPlayerParty + 2, sizeof(struct Pokemon)); gBattleCommunication[MULTIUSE_STATE]++; } break; @@ -1272,7 +1272,7 @@ static void CB2_HandleStartMultiPartnerBattle(void) case 7: if (IsLinkTaskFinished()) { - SendBlock(bitmask_all_link_players_but_self(), gEnemyParty, sizeof(struct Pokemon) * 2); + SendBlock(BitmaskAllOtherLinkPlayers(), gEnemyParty, sizeof(struct Pokemon) * 2); gBattleCommunication[MULTIUSE_STATE]++; } break; @@ -1290,7 +1290,7 @@ static void CB2_HandleStartMultiPartnerBattle(void) case 9: if (IsLinkTaskFinished()) { - SendBlock(bitmask_all_link_players_but_self(), gEnemyParty + 2, sizeof(struct Pokemon) * 2); + SendBlock(BitmaskAllOtherLinkPlayers(), gEnemyParty + 2, sizeof(struct Pokemon) * 2); gBattleCommunication[MULTIUSE_STATE]++; } break; @@ -1308,7 +1308,7 @@ static void CB2_HandleStartMultiPartnerBattle(void) case 11: if (IsLinkTaskFinished()) { - SendBlock(bitmask_all_link_players_but_self(), gEnemyParty + 4, sizeof(struct Pokemon) * 2); + SendBlock(BitmaskAllOtherLinkPlayers(), gEnemyParty + 4, sizeof(struct Pokemon) * 2); gBattleCommunication[MULTIUSE_STATE]++; } break; @@ -1350,7 +1350,7 @@ static void CB2_HandleStartMultiPartnerBattle(void) case 14: if (IsLinkTaskFinished()) { - SendBlock(bitmask_all_link_players_but_self(), &gRecordedBattleRngSeed, sizeof(gRecordedBattleRngSeed)); + SendBlock(BitmaskAllOtherLinkPlayers(), &gRecordedBattleRngSeed, sizeof(gRecordedBattleRngSeed)); gBattleCommunication[MULTIUSE_STATE]++; } break; @@ -1432,7 +1432,7 @@ static void CB2_PreInitMultiBattle(void) { sMultiPartnerPartyBuffer = Alloc(sizeof(struct UnknownPokemonStruct4) * ARRAY_COUNT(gMultiPartnerParty)); sub_80379F8(0); - SendBlock(bitmask_all_link_players_but_self(), sMultiPartnerPartyBuffer, sizeof(struct UnknownPokemonStruct4) * ARRAY_COUNT(gMultiPartnerParty)); + SendBlock(BitmaskAllOtherLinkPlayers(), sMultiPartnerPartyBuffer, sizeof(struct UnknownPokemonStruct4) * ARRAY_COUNT(gMultiPartnerParty)); gBattleCommunication[MULTIUSE_STATE]++; } break; @@ -1577,7 +1577,7 @@ static void CB2_HandleStartMultiBattle(void) BufferPartyVsScreenHealth_AtStart(); SetPlayerBerryDataInBattleStruct(); - SendBlock(bitmask_all_link_players_but_self(), &gBattleStruct->multiBuffer.linkBattlerHeader, sizeof(gBattleStruct->multiBuffer.linkBattlerHeader)); + SendBlock(BitmaskAllOtherLinkPlayers(), &gBattleStruct->multiBuffer.linkBattlerHeader, sizeof(gBattleStruct->multiBuffer.linkBattlerHeader)); gBattleCommunication[MULTIUSE_STATE]++; } if (gWirelessCommType) @@ -1634,7 +1634,7 @@ static void CB2_HandleStartMultiBattle(void) case 3: if (IsLinkTaskFinished()) { - SendBlock(bitmask_all_link_players_but_self(), gPlayerParty, sizeof(struct Pokemon) * 2); + SendBlock(BitmaskAllOtherLinkPlayers(), gPlayerParty, sizeof(struct Pokemon) * 2); gBattleCommunication[MULTIUSE_STATE]++; } break; @@ -1697,7 +1697,7 @@ static void CB2_HandleStartMultiBattle(void) case 5: if (IsLinkTaskFinished()) { - SendBlock(bitmask_all_link_players_but_self(), gPlayerParty + 2, sizeof(struct Pokemon)); + SendBlock(BitmaskAllOtherLinkPlayers(), gPlayerParty + 2, sizeof(struct Pokemon)); gBattleCommunication[MULTIUSE_STATE]++; } break; @@ -1796,7 +1796,7 @@ static void CB2_HandleStartMultiBattle(void) u32* ptr = gBattleStruct->multiBuffer.battleVideo; ptr[0] = gBattleTypeFlags; ptr[1] = gRecordedBattleRngSeed; // UB: overwrites berry data - SendBlock(bitmask_all_link_players_but_self(), ptr, sizeof(gBattleStruct->multiBuffer.battleVideo)); + SendBlock(BitmaskAllOtherLinkPlayers(), ptr, sizeof(gBattleStruct->multiBuffer.battleVideo)); gBattleCommunication[MULTIUSE_STATE]++; } break; diff --git a/src/battle_tower.c b/src/battle_tower.c index daf63d016..9c85882a4 100644 --- a/src/battle_tower.c +++ b/src/battle_tower.c @@ -2575,7 +2575,7 @@ static void LoadLinkMultiOpponentsData(void) challengeNum = gSaveBlock2Ptr->frontier.towerWinStreaks[battleMode][lvlMode] / 7; if (IsLinkTaskFinished()) { - SendBlock(bitmask_all_link_players_but_self(), &challengeNum, sizeof(challengeNum)); + SendBlock(BitmaskAllOtherLinkPlayers(), &challengeNum, sizeof(challengeNum)); gSpecialVar_Result = 1; } } @@ -2612,7 +2612,7 @@ static void LoadLinkMultiOpponentsData(void) case 2: if (IsLinkTaskFinished()) { - SendBlock(bitmask_all_link_players_but_self(), &gSaveBlock2Ptr->frontier.trainerIds, sizeof(gSaveBlock2Ptr->frontier.trainerIds)); + SendBlock(BitmaskAllOtherLinkPlayers(), &gSaveBlock2Ptr->frontier.trainerIds, sizeof(gSaveBlock2Ptr->frontier.trainerIds)); gSpecialVar_Result = 3; } break; diff --git a/src/berry_blender.c b/src/berry_blender.c index 6a3e9f291..9701c8c81 100644 --- a/src/berry_blender.c +++ b/src/berry_blender.c @@ -1355,7 +1355,7 @@ static void CB2_StartBlenderLink(void) { ResetBlockReceivedFlags(); if (GetMultiplayerId() == 0) - SendBlockRequest(4); + SendBlockRequest(BLOCK_REQ_SIZE_40); sBerryBlender->mainState++; } break; @@ -2069,7 +2069,7 @@ static bool32 CheckRecvCmdMatches(u16 recvCmd, u16 linkCmd, u16 rfuCmd) { if (gReceivedRemoteLinkPlayers && gWirelessCommType) { - if ((recvCmd & 0xFF00) == rfuCmd) + if ((recvCmd & RFUCMD_MASK) == rfuCmd) return TRUE; } else @@ -3135,7 +3135,7 @@ static void UpdateBlenderCenter(void) } else { - if ((gRecvCmds[0][BLENDER_COMM_INPUT_STATE] & 0xFF00) == RFUCMD_BLENDER_SEND_KEYS) + if ((gRecvCmds[0][BLENDER_COMM_INPUT_STATE] & RFUCMD_MASK) == RFUCMD_BLENDER_SEND_KEYS) { sBerryBlender->progressBarValue = gRecvCmds[0][BLENDER_COMM_PROGRESS_BAR]; sBerryBlender->arrowPos = gRecvCmds[0][BLENDER_COMM_ARROW_POS]; diff --git a/src/berry_crush.c b/src/berry_crush.c index 5c571778f..dcd7363bd 100755 --- a/src/berry_crush.c +++ b/src/berry_crush.c @@ -984,12 +984,12 @@ static u32 QuitBerryCrush(MainCallback exitCallback) return 0; } -#define ERROR_EXIT(exitCallback) \ - { \ - SetMainCallback2(exitCallback); \ - Rfu.unk_10 = 0; \ - Rfu.unk_12 = 0; \ - Rfu.errorState = 1; \ +#define ERROR_EXIT(exitCallback) \ + { \ + SetMainCallback2(exitCallback); \ + gRfu.errorParam0 = 0; \ + gRfu.errorParam1 = 0; \ + gRfu.errorState = RFU_ERROR_STATE_OCCURRED; \ } void StartBerryCrush(MainCallback exitCallback) @@ -2565,7 +2565,7 @@ static void HandlePartnerInput(struct BerryCrushGame *game) linkState = (struct BerryCrushGame_LinkState *)gRecvCmds[i]; // Skip player if we have not received a packet from them - if ((linkState->rfuCmd & 0xFF00) != RFUCMD_SEND_PACKET) + if ((linkState->rfuCmd & RFUCMD_MASK) != RFUCMD_SEND_PACKET) continue; if (linkState->sendFlag != SEND_GAME_STATE) continue; @@ -2805,7 +2805,7 @@ static void RecvLinkData(struct BerryCrushGame *game) for (i = 0; i < game->playerCount; i++) game->players[i].inputState = INPUT_STATE_NONE; - if ((gRecvCmds[0][0] & 0xFF00) != RFUCMD_SEND_PACKET) + if ((gRecvCmds[0][0] & RFUCMD_MASK) != RFUCMD_SEND_PACKET) { game->playedSound = FALSE; return; diff --git a/src/cable_club.c b/src/cable_club.c index 1b61023ec..8db583989 100644 --- a/src/cable_club.c +++ b/src/cable_club.c @@ -185,9 +185,9 @@ static bool32 CheckLinkCanceled(u8 taskId) return FALSE; } -static bool32 sub_80B25CC(u8 taskId) +static bool32 CheckSioErrored(u8 taskId) { - if (GetSioMultiSI() == 1) + if (GetSioMultiSI() == TRUE) { gTasks[taskId].func = Task_LinkupConnectionError; return TRUE; @@ -196,12 +196,12 @@ static bool32 sub_80B25CC(u8 taskId) } // Unused -static void sub_80B2600(u8 taskId) +static void Task_DelayedBlockRequest(u8 taskId) { gTasks[taskId].data[0]++; if (gTasks[taskId].data[0] == 10) { - SendBlockRequest(2); + SendBlockRequest(BLOCK_REQ_SIZE_100); DestroyTask(taskId); } } @@ -252,7 +252,7 @@ static void Task_LinkupAwaitConnection(u8 taskId) static void Task_LinkupConfirmWhenReady(u8 taskId) { if (CheckLinkCanceledBeforeConnection(taskId) == TRUE - || sub_80B25CC(taskId) == TRUE + || CheckSioErrored(taskId) == TRUE || CheckLinkErrored(taskId) == TRUE) return; @@ -269,7 +269,7 @@ static void Task_LinkupAwaitConfirmation(u8 taskId) s32 linkPlayerCount = GetLinkPlayerCount_2(); if (CheckLinkCanceledBeforeConnection(taskId) == TRUE - || sub_80B25CC(taskId) == TRUE + || CheckSioErrored(taskId) == TRUE || CheckLinkErrored(taskId) == TRUE) return; @@ -291,7 +291,7 @@ static void Task_LinkupAwaitConfirmation(u8 taskId) static void Task_LinkupTryConfirmation(u8 taskId) { if (CheckLinkCanceledBeforeConnection(taskId) == TRUE - || sub_80B25CC(taskId) == TRUE + || CheckSioErrored(taskId) == TRUE || CheckLinkErrored(taskId) == TRUE) return; @@ -424,7 +424,7 @@ static void Task_LinkupCheckStatusAfterConfirm(u8 taskId) 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; - SendBlockRequest(2); + SendBlockRequest(BLOCK_REQ_SIZE_100); } } @@ -1172,9 +1172,11 @@ static void CreateTask_StartWiredTrade(void) CreateTask(Task_StartWiredTrade, 80); } -void nullsub_37(void) +// Unused, implemented in Ruby/Sapphire +void Script_StartWiredTrade(void) { - + // CreateTask_StartWiredTrade(); + // ScriptContext1_Stop(); } void ColosseumPlayerSpotTriggered(void) @@ -1251,7 +1253,7 @@ void Task_WaitForLinkPlayerConnection(u8 taskId) #undef tTimer -static void sub_80B3AAC(u8 taskId) +static void Task_WaitExitToScript(u8 taskId) { if (!gReceivedRemoteLinkPlayers) { @@ -1261,10 +1263,10 @@ static void sub_80B3AAC(u8 taskId) } // Unused -static void sub_80B3AD0(u8 taskId) +static void ExitLinkToScript(u8 taskId) { SetCloseLinkCallback(); - gTasks[taskId].func = sub_80B3AAC; + gTasks[taskId].func = Task_WaitExitToScript; } #define tTimer data[1] diff --git a/src/contest_link.c b/src/contest_link.c index 42a320721..9a960e00a 100644 --- a/src/contest_link.c +++ b/src/contest_link.c @@ -22,7 +22,7 @@ static void Task_LinkContest_InitFlags(u8); bool32 LinkContest_SendBlock(void *src, u16 size) { memcpy(gDecompressionBuffer, src, size); - if (SendBlock(bitmask_all_link_players_but_self(), gDecompressionBuffer, size)) + if (SendBlock(BitmaskAllOtherLinkPlayers(), gDecompressionBuffer, size)) return TRUE; else return FALSE; @@ -162,7 +162,7 @@ void Task_LinkContest_CommunicateMonsRS(u8 taskId) // Only if leader. Request other players data if (++gTasks[taskId].tTimer > 300) { - SendBlockRequest(2); + SendBlockRequest(BLOCK_REQ_SIZE_100); gTasks[taskId].tState = 1; } break; @@ -238,7 +238,7 @@ void Task_LinkContest_CommunicateCategoryRS(u8 taskId) case 10: if (++gTasks[taskId].tTimer > 10) { - SendBlockRequest(2); + SendBlockRequest(BLOCK_REQ_SIZE_100); gTasks[taskId].tState = 1; } break; @@ -491,7 +491,7 @@ void Task_LinkContest_CommunicateLeaderIdsRS(u8 taskId) case 10: if (++gTasks[taskId].tTimer > 10) { - SendBlockRequest(2); + SendBlockRequest(BLOCK_REQ_SIZE_100); gTasks[taskId].tState = 1; } break; diff --git a/src/data/union_room.h b/src/data/union_room.h index 902853ddb..cf4b12b5d 100644 --- a/src/data/union_room.h +++ b/src/data/union_room.h @@ -1,29 +1,27 @@ -// const rom data - ALIGNED(4) static const u8 sText_EmptyString[] = _(""); -ALIGNED(4) const u8 sText_Colon[] = _(":"); -ALIGNED(4) const u8 sText_ID[] = _("{ID}"); -ALIGNED(4) const u8 sText_PleaseStartOver[] = _("Please start over from the beginning."); -ALIGNED(4) const u8 sText_WirelessSearchCanceled[] = _("The WIRELESS COMMUNICATION\nSYSTEM search has been canceled."); -ALIGNED(4) const u8 sText_AwaitingCommunucation2[] = _("Awaiting communication\nfrom another player."); // Unused -ALIGNED(4) const u8 sText_AwaitingCommunication[] = _("{STR_VAR_1}! Awaiting\ncommunication from another player."); -ALIGNED(4) const u8 sText_AwaitingLinkPressStart[] = _("{STR_VAR_1}! Awaiting link!\nPress START when everyone's ready."); -ALIGNED(4) const u8 sJPText_SingleBattle[] = _("シングルバトルを かいさいする"); -ALIGNED(4) const u8 sJPText_DoubleBattle[] = _("ダブルバトルを かいさいする"); -ALIGNED(4) const u8 sJPText_MultiBattle[] = _("マルチバトルを かいさいする"); -ALIGNED(4) const u8 sJPText_TradePokemon[] = _("ポケモンこうかんを かいさいする"); -ALIGNED(4) const u8 sJPText_Chat[] = _("チャットを かいさいする"); -ALIGNED(4) const u8 sJPText_DistWonderCard[] = _("ふしぎなカードをくばる"); -ALIGNED(4) const u8 sJPText_DistWonderNews[] = _("ふしぎなニュースをくばる"); -ALIGNED(4) const u8 sJPText_DistMysteryEvent[] = _("ふしぎなできごとを かいさいする"); // Unused -ALIGNED(4) const u8 sJPText_HoldPokemonJump[] = _("なわとびを かいさいする"); -ALIGNED(4) const u8 sJPText_HoldBerryCrush[] = _("きのみマッシャーを かいさいする"); -ALIGNED(4) const u8 sJPText_HoldBerryPicking[] = _("きのみどりを かいさいする"); -ALIGNED(4) const u8 sJPText_HoldSpinTrade[] = _("ぐるぐるこうかんを かいさいする"); -ALIGNED(4) const u8 sJPText_HoldSpinShop[] = _("ぐるぐるショップを かいさいする"); +ALIGNED(4) static const u8 sText_Colon[] = _(":"); +ALIGNED(4) static const u8 sText_ID[] = _("{ID}"); +ALIGNED(4) static const u8 sText_PleaseStartOver[] = _("Please start over from the beginning."); +ALIGNED(4) static const u8 sText_WirelessSearchCanceled[] = _("The WIRELESS COMMUNICATION\nSYSTEM search has been canceled."); +ALIGNED(4) static const u8 sText_AwaitingCommunucation2[] = _("Awaiting communication\nfrom another player."); // Unused +ALIGNED(4) static const u8 sText_AwaitingCommunication[] = _("{STR_VAR_1}! Awaiting\ncommunication from another player."); +ALIGNED(4) static const u8 sText_AwaitingLinkPressStart[] = _("{STR_VAR_1}! Awaiting link!\nPress START when everyone's ready."); +ALIGNED(4) static const u8 sJPText_SingleBattle[] = _("シングルバトルを かいさいする"); +ALIGNED(4) static const u8 sJPText_DoubleBattle[] = _("ダブルバトルを かいさいする"); +ALIGNED(4) static const u8 sJPText_MultiBattle[] = _("マルチバトルを かいさいする"); +ALIGNED(4) static const u8 sJPText_TradePokemon[] = _("ポケモンこうかんを かいさいする"); +ALIGNED(4) static const u8 sJPText_Chat[] = _("チャットを かいさいする"); +ALIGNED(4) static const u8 sJPText_DistWonderCard[] = _("ふしぎなカードをくばる"); +ALIGNED(4) static const u8 sJPText_DistWonderNews[] = _("ふしぎなニュースをくばる"); +ALIGNED(4) static const u8 sJPText_DistMysteryEvent[] = _("ふしぎなできごとを かいさいする"); // Unused +ALIGNED(4) static const u8 sJPText_HoldPokemonJump[] = _("なわとびを かいさいする"); +ALIGNED(4) static const u8 sJPText_HoldBerryCrush[] = _("きのみマッシャーを かいさいする"); +ALIGNED(4) static const u8 sJPText_HoldBerryPicking[] = _("きのみどりを かいさいする"); +ALIGNED(4) static const u8 sJPText_HoldSpinTrade[] = _("ぐるぐるこうかんを かいさいする"); +ALIGNED(4) static const u8 sJPText_HoldSpinShop[] = _("ぐるぐるショップを かいさいする"); // Unused -const u8 *const sJPLinkGroupActionTexts[] = { +static const u8 *const sJPLinkGroupActionTexts[] = { sJPText_SingleBattle, sJPText_DoubleBattle, sJPText_MultiBattle, @@ -40,14 +38,14 @@ const u8 *const sJPLinkGroupActionTexts[] = { sJPText_HoldSpinShop }; -const u8 sText_1PlayerNeeded[] = _("1 player\nneeded."); -const u8 sText_2PlayersNeeded[] = _("2 players\nneeded."); -const u8 sText_3PlayersNeeded[] = _("3 players\nneeded."); -const u8 sText_4PlayersNeeded[] = _("4 players\nneeded."); -const u8 sText_2PlayerMode[] = _("2-PLAYER\nMODE"); -const u8 sText_3PlayerMode[] = _("3-PLAYER\nMODE"); -const u8 sText_4PlayerMode[] = _("4-PLAYER\nMODE"); -const u8 sText_5PlayerMode[] = _("5-PLAYER\nMODE"); +static const u8 sText_1PlayerNeeded[] = _("1 player\nneeded."); +static const u8 sText_2PlayersNeeded[] = _("2 players\nneeded."); +static const u8 sText_3PlayersNeeded[] = _("3 players\nneeded."); +static const u8 sText_4PlayersNeeded[] = _("4 players\nneeded."); +static const u8 sText_2PlayerMode[] = _("2-PLAYER\nMODE"); +static const u8 sText_3PlayerMode[] = _("3-PLAYER\nMODE"); +static const u8 sText_4PlayerMode[] = _("4-PLAYER\nMODE"); +static const u8 sText_5PlayerMode[] = _("5-PLAYER\nMODE"); static const u8 *const sPlayersNeededOrModeTexts[][5] = { // 2 players required @@ -87,38 +85,38 @@ static const u8 *const sPlayersNeededOrModeTexts[][5] = { } }; -ALIGNED(4) const u8 sText_BButtonCancel[] = _("{B_BUTTON}CANCEL"); -ALIGNED(4) const u8 sJPText_SearchingForParticipants[] = _("ため\nさんかしゃ ぼしゅうちゅう です!"); // Unused, may have been cut off -ALIGNED(4) const u8 sText_PlayerContactedYouForXAccept[] = _("{STR_VAR_2} contacted you for\n{STR_VAR_1}. Accept?"); -ALIGNED(4) const u8 sText_PlayerContactedYouShareX[] = _("{STR_VAR_2} contacted you.\nWill you share {STR_VAR_1}?"); -ALIGNED(4) const u8 sText_PlayerContactedYouAddToMembers[] = _("{STR_VAR_2} contacted you.\nAdd to the members?"); -ALIGNED(4) const u8 sText_AreTheseMembersOK[] = _("{STR_VAR_1}!\nAre these members OK?"); -ALIGNED(4) const u8 sText_CancelModeWithTheseMembers[] = _("Cancel {STR_VAR_1} MODE\nwith these members?"); -ALIGNED(4) const u8 sText_AnOKWasSentToPlayer[] = _("An “OK” was sent\nto {STR_VAR_1}."); -ALIGNED(4) const u8 sText_OtherTrainerUnavailableNow[] = _("The other TRAINER doesn't appear\nto be available now…\p"); -ALIGNED(4) const u8 sText_CantTransmitTrainerTooFar[] = _("You can't transmit with a TRAINER\nwho is too far away.\p"); -ALIGNED(4) const u8 sText_TrainersNotReadyYet[] = _("The other TRAINER(S) is/are not\nready yet.\p"); +ALIGNED(4) static const u8 sText_BButtonCancel[] = _("{B_BUTTON}CANCEL"); +ALIGNED(4) static const u8 sJPText_SearchingForParticipants[] = _("ため\nさんかしゃ ぼしゅうちゅう です!"); // Unused, may have been cut off +ALIGNED(4) static const u8 sText_PlayerContactedYouForXAccept[] = _("{STR_VAR_2} contacted you for\n{STR_VAR_1}. Accept?"); +ALIGNED(4) static const u8 sText_PlayerContactedYouShareX[] = _("{STR_VAR_2} contacted you.\nWill you share {STR_VAR_1}?"); +ALIGNED(4) static const u8 sText_PlayerContactedYouAddToMembers[] = _("{STR_VAR_2} contacted you.\nAdd to the members?"); +ALIGNED(4) static const u8 sText_AreTheseMembersOK[] = _("{STR_VAR_1}!\nAre these members OK?"); +ALIGNED(4) static const u8 sText_CancelModeWithTheseMembers[] = _("Cancel {STR_VAR_1} MODE\nwith these members?"); +ALIGNED(4) static const u8 sText_AnOKWasSentToPlayer[] = _("An “OK” was sent\nto {STR_VAR_1}."); +ALIGNED(4) static const u8 sText_OtherTrainerUnavailableNow[] = _("The other TRAINER doesn't appear\nto be available now…\p"); +ALIGNED(4) static const u8 sText_CantTransmitTrainerTooFar[] = _("You can't transmit with a TRAINER\nwho is too far away.\p"); +ALIGNED(4) static const u8 sText_TrainersNotReadyYet[] = _("The other TRAINER(S) is/are not\nready yet.\p"); static const u8 *const sCantTransmitToTrainerTexts[] = { [UR_TRADE_PLAYER_NOT_READY - 1] = sText_CantTransmitTrainerTooFar, [UR_TRADE_PARTNER_NOT_READY - 1] = sText_TrainersNotReadyYet }; -ALIGNED(4) const u8 sText_ModeWithTheseMembersWillBeCanceled[] = _("The {STR_VAR_1} MODE with\nthese members will be canceled.{PAUSE 60}"); -ALIGNED(4) const u8 sText_MemberNoLongerAvailable[] = _("There is a member who can no\nlonger remain available.\p"); +ALIGNED(4) static const u8 sText_ModeWithTheseMembersWillBeCanceled[] = _("The {STR_VAR_1} MODE with\nthese members will be canceled.{PAUSE 60}"); +ALIGNED(4) static const u8 sText_MemberNoLongerAvailable[] = _("There is a member who can no\nlonger remain available.\p"); static const u8 *const sPlayerUnavailableTexts[] = { sText_OtherTrainerUnavailableNow, sText_MemberNoLongerAvailable }; -ALIGNED(4) const u8 sText_TrainerAppearsUnavailable[] = _("The other TRAINER appears\nunavailable…\p"); -ALIGNED(4) const u8 sText_PlayerSentBackOK[] = _("{STR_VAR_1} sent back an “OK”!"); -ALIGNED(4) const u8 sText_PlayerOKdRegistration[] = _("{STR_VAR_1} OK'd your registration as\na member."); -ALIGNED(4) const u8 sText_PlayerRepliedNo[] = _("{STR_VAR_1} replied, “No…”\p"); -ALIGNED(4) const u8 sText_AwaitingOtherMembers[] = _("{STR_VAR_1}!\nAwaiting other members!"); -ALIGNED(4) const u8 sText_QuitBeingMember[] = _("Quit being a member?"); -ALIGNED(4) const u8 sText_StoppedBeingMember[] = _("You stopped being a member.\p"); +ALIGNED(4) static const u8 sText_TrainerAppearsUnavailable[] = _("The other TRAINER appears\nunavailable…\p"); +ALIGNED(4) static const u8 sText_PlayerSentBackOK[] = _("{STR_VAR_1} sent back an “OK”!"); +ALIGNED(4) static const u8 sText_PlayerOKdRegistration[] = _("{STR_VAR_1} OK'd your registration as\na member."); +ALIGNED(4) static const u8 sText_PlayerRepliedNo[] = _("{STR_VAR_1} replied, “No…”\p"); +ALIGNED(4) static const u8 sText_AwaitingOtherMembers[] = _("{STR_VAR_1}!\nAwaiting other members!"); +ALIGNED(4) static const u8 sText_QuitBeingMember[] = _("Quit being a member?"); +ALIGNED(4) static const u8 sText_StoppedBeingMember[] = _("You stopped being a member.\p"); static const u8 *const sPlayerDisconnectedTexts[] = { [RFU_STATUS_OK] = NULL, @@ -133,12 +131,12 @@ static const u8 *const sPlayerDisconnectedTexts[] = { [RFU_STATUS_LEAVE_GROUP] = sText_StoppedBeingMember }; -ALIGNED(4) const u8 sText_WirelessLinkEstablished[] = _("The WIRELESS COMMUNICATION\nSYSTEM link has been established."); -ALIGNED(4) const u8 sText_WirelessLinkDropped[] = _("The WIRELESS COMMUNICATION\nSYSTEM link has been dropped…"); -ALIGNED(4) const u8 sText_LinkWithFriendDropped[] = _("The link with your friend has been\ndropped…"); -ALIGNED(4) const u8 sText_PlayerRepliedNo2[] = _("{STR_VAR_1} replied, “No…”"); +ALIGNED(4) static const u8 sText_WirelessLinkEstablished[] = _("The WIRELESS COMMUNICATION\nSYSTEM link has been established."); +ALIGNED(4) static const u8 sText_WirelessLinkDropped[] = _("The WIRELESS COMMUNICATION\nSYSTEM link has been dropped…"); +ALIGNED(4) static const u8 sText_LinkWithFriendDropped[] = _("The link with your friend has been\ndropped…"); +ALIGNED(4) static const u8 sText_PlayerRepliedNo2[] = _("{STR_VAR_1} replied, “No…”"); -const u8 *const sLinkDroppedTexts[] = { +static const u8 *const sLinkDroppedTexts[] = { [RFU_STATUS_OK] = NULL, [RFU_STATUS_FATAL_ERROR] = sText_LinkWithFriendDropped, [RFU_STATUS_CONNECTION_ERROR] = sText_LinkWithFriendDropped, @@ -151,8 +149,8 @@ const u8 *const sLinkDroppedTexts[] = { [RFU_STATUS_LEAVE_GROUP] = NULL }; -ALIGNED(4) const u8 sText_DoYouWantXMode[] = _("Do you want the {STR_VAR_2}\nMODE?"); -ALIGNED(4) const u8 sText_DoYouWantXMode2[] = _("Do you want the {STR_VAR_2}\nMODE?"); +ALIGNED(4) static const u8 sText_DoYouWantXMode[] = _("Do you want the {STR_VAR_2}\nMODE?"); +ALIGNED(4) static const u8 sText_DoYouWantXMode2[] = _("Do you want the {STR_VAR_2}\nMODE?"); // Unused static const u8 *const sDoYouWantModeTexts[] = { @@ -160,11 +158,14 @@ static const u8 *const sDoYouWantModeTexts[] = { sText_DoYouWantXMode2 }; -ALIGNED(4) const u8 sText_CommunicatingPleaseWait[] = _("Communicating…\nPlease wait."); // Unused -ALIGNED(4) const u8 sText_AwaitingPlayersResponseAboutTrade[] = _("Awaiting {STR_VAR_1}'s response about\nthe trade…"); -ALIGNED(4) const u8 sText_Communicating[] = _("Communicating{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.\n{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}."); -ALIGNED(4) const u8 sText_CommunicatingWithPlayer[] = _("Communicating with {STR_VAR_1}{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.\n{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}."); -ALIGNED(4) const u8 sText_PleaseWaitAWhile[] = _("Please wait a while{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.\n{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}."); +ALIGNED(4) static const u8 sText_CommunicatingPleaseWait[] = _("Communicating…\nPlease wait."); // Unused +ALIGNED(4) static const u8 sText_AwaitingPlayersResponseAboutTrade[] = _("Awaiting {STR_VAR_1}'s response about\nthe trade…"); +ALIGNED(4) static const u8 sText_Communicating[] = _("Communicating{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.\n" + "{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}."); +ALIGNED(4) static const u8 sText_CommunicatingWithPlayer[] = _("Communicating with {STR_VAR_1}{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.\n" + "{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}."); +ALIGNED(4) static const u8 sText_PleaseWaitAWhile[] = _("Please wait a while{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.\n" + "{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}.{PAUSE 15}."); static const u8 *const sCommunicatingWaitTexts[] = { sText_Communicating, @@ -172,10 +173,10 @@ static const u8 *const sCommunicatingWaitTexts[] = { sText_PleaseWaitAWhile }; -ALIGNED(4) const u8 sText_HiDoSomethingMale[] = _("Hiya! Is there something that you\nwanted to do?"); -ALIGNED(4) const u8 sText_HiDoSomethingFemale[] = _("Hello!\nWould you like to do something?"); -ALIGNED(4) const u8 sText_HiDoSomethingAgainMale[] = _("{STR_VAR_1}: Hiya, we meet again!\nWhat are you up for this time?"); -ALIGNED(4) const u8 sText_HiDoSomethingAgainFemale[] = _("{STR_VAR_1}: Oh! {PLAYER}, hello!\nWould you like to do something?"); +ALIGNED(4) static const u8 sText_HiDoSomethingMale[] = _("Hiya! Is there something that you\nwanted to do?"); +ALIGNED(4) static const u8 sText_HiDoSomethingFemale[] = _("Hello!\nWould you like to do something?"); +ALIGNED(4) static const u8 sText_HiDoSomethingAgainMale[] = _("{STR_VAR_1}: Hiya, we meet again!\nWhat are you up for this time?"); +ALIGNED(4) static const u8 sText_HiDoSomethingAgainFemale[] = _("{STR_VAR_1}: Oh! {PLAYER}, hello!\nWould you like to do something?"); static const u8 *const sHiDoSomethingTexts[][GENDER_COUNT] = { { @@ -187,10 +188,10 @@ static const u8 *const sHiDoSomethingTexts[][GENDER_COUNT] = { } }; -ALIGNED(4) const u8 sText_DoSomethingMale[] = _("Want to do something?"); -ALIGNED(4) const u8 sText_DoSomethingFemale[] = _("Would you like to do something?"); -ALIGNED(4) const u8 sText_DoSomethingAgainMale[] = _("{STR_VAR_1}: What would you like to\ndo now?"); -ALIGNED(4) const u8 sText_DoSomethingAgainFemale[] = _("{STR_VAR_1}: Want to do anything else?"); // Unused +ALIGNED(4) static const u8 sText_DoSomethingMale[] = _("Want to do something?"); +ALIGNED(4) static const u8 sText_DoSomethingFemale[] = _("Would you like to do something?"); +ALIGNED(4) static const u8 sText_DoSomethingAgainMale[] = _("{STR_VAR_1}: What would you like to\ndo now?"); +ALIGNED(4) static const u8 sText_DoSomethingAgainFemale[] = _("{STR_VAR_1}: Want to do anything else?"); // Unused // Unused static const u8 *const sDoSomethingTexts[][GENDER_COUNT] = { @@ -203,31 +204,31 @@ static const u8 *const sDoSomethingTexts[][GENDER_COUNT] = { } }; -ALIGNED(4) const u8 sText_SomebodyHasContactedYou[] = _("Somebody has contacted you.{PAUSE 60}"); -ALIGNED(4) const u8 sText_PlayerHasContactedYou[] = _("{STR_VAR_1} has contacted you.{PAUSE 60}"); +ALIGNED(4) static const u8 sText_SomebodyHasContactedYou[] = _("Somebody has contacted you.{PAUSE 60}"); +ALIGNED(4) static const u8 sText_PlayerHasContactedYou[] = _("{STR_VAR_1} has contacted you.{PAUSE 60}"); static const u8 *const sPlayerContactedYouTexts[] = { sText_SomebodyHasContactedYou, sText_PlayerHasContactedYou }; -ALIGNED(4) const u8 sText_AwaitingResponseFromTrainer[] = _("Awaiting a response from\nthe other TRAINER…"); -ALIGNED(4) const u8 sText_AwaitingResponseFromPlayer[] = _("Awaiting a response from\n{STR_VAR_1}…"); +ALIGNED(4) static const u8 sText_AwaitingResponseFromTrainer[] = _("Awaiting a response from\nthe other TRAINER…"); +ALIGNED(4) static const u8 sText_AwaitingResponseFromPlayer[] = _("Awaiting a response from\n{STR_VAR_1}…"); static const u8 *const sAwaitingResponseTexts[] = { sText_AwaitingResponseFromTrainer, sText_AwaitingResponseFromPlayer }; -ALIGNED(4) const u8 sText_ShowTrainerCard[] = _("The other TRAINER showed\nyou their TRAINER CARD.\pWould you like to show your\nTRAINER CARD?"); -ALIGNED(4) const u8 sText_BattleChallenge[] = _("The other TRAINER challenges you\nto battle.\pWill you accept the battle\nchallenge?"); -ALIGNED(4) const u8 sText_ChatInvitation[] = _("The other TRAINER invites you\nto chat.\pWill you accept the chat\ninvitation?"); -ALIGNED(4) const u8 sText_OfferToTradeMon[] = _("There is an offer to trade your\nregistered Lv. {DYNAMIC 0} {DYNAMIC 1}\pin exchange for a\nLv. {DYNAMIC 2} {DYNAMIC 3}.\pWill you accept this trade\noffer?"); -ALIGNED(4) const u8 sText_OfferToTradeEgg[] = _("There is an offer to trade your\nregistered EGG.\lWill you accept this trade offer?"); -ALIGNED(4) const u8 sText_ChatDropped[] = _("The chat has been dropped.\p"); -ALIGNED(4) const u8 sText_OfferDeclined1[] = _("You declined the offer.\p"); -ALIGNED(4) const u8 sText_OfferDeclined2[] = _("You declined the offer.\p"); -ALIGNED(4) const u8 sText_ChatEnded[] = _("The chat was ended.\p"); +ALIGNED(4) static const u8 sText_ShowTrainerCard[] = _("The other TRAINER showed\nyou their TRAINER CARD.\pWould you like to show your\nTRAINER CARD?"); +ALIGNED(4) static const u8 sText_BattleChallenge[] = _("The other TRAINER challenges you\nto battle.\pWill you accept the battle\nchallenge?"); +ALIGNED(4) static const u8 sText_ChatInvitation[] = _("The other TRAINER invites you\nto chat.\pWill you accept the chat\ninvitation?"); +ALIGNED(4) static const u8 sText_OfferToTradeMon[] = _("There is an offer to trade your\nregistered Lv. {DYNAMIC 0} {DYNAMIC 1}\pin exchange for a\nLv. {DYNAMIC 2} {DYNAMIC 3}.\pWill you accept this trade\noffer?"); +ALIGNED(4) static const u8 sText_OfferToTradeEgg[] = _("There is an offer to trade your\nregistered EGG.\lWill you accept this trade offer?"); +ALIGNED(4) static const u8 sText_ChatDropped[] = _("The chat has been dropped.\p"); +ALIGNED(4) static const u8 sText_OfferDeclined1[] = _("You declined the offer.\p"); +ALIGNED(4) static const u8 sText_OfferDeclined2[] = _("You declined the offer.\p"); +ALIGNED(4) static const u8 sText_ChatEnded[] = _("The chat was ended.\p"); // Unused static const u8 *const sInvitationTexts[] = { @@ -237,10 +238,10 @@ static const u8 *const sInvitationTexts[] = { sText_OfferToTradeMon }; -ALIGNED(4) const u8 sText_JoinChatMale[] = _("Oh, hey! We're in a chat right now.\nWant to join us?"); -ALIGNED(4) const u8 sText_PlayerJoinChatMale[] = _("{STR_VAR_1}: Hey, {PLAYER}!\nWe're having a chat right now.\lWant to join us?"); -ALIGNED(4) const u8 sText_JoinChatFemale[] = _("Oh, hi! We're having a chat now.\nWould you like to join us?"); -ALIGNED(4) const u8 sText_PlayerJoinChatFemale[] = _("{STR_VAR_1}: Oh, hi, {PLAYER}!\nWe're having a chat now.\lWould you like to join us?"); +ALIGNED(4) static const u8 sText_JoinChatMale[] = _("Oh, hey! We're in a chat right now.\nWant to join us?"); +ALIGNED(4) static const u8 sText_PlayerJoinChatMale[] = _("{STR_VAR_1}: Hey, {PLAYER}!\nWe're having a chat right now.\lWant to join us?"); +ALIGNED(4) static const u8 sText_JoinChatFemale[] = _("Oh, hi! We're having a chat now.\nWould you like to join us?"); +ALIGNED(4) static const u8 sText_PlayerJoinChatFemale[] = _("{STR_VAR_1}: Oh, hi, {PLAYER}!\nWe're having a chat now.\lWould you like to join us?"); static const u8 *const sJoinChatTexts[][GENDER_COUNT] = { { @@ -252,13 +253,13 @@ static const u8 *const sJoinChatTexts[][GENDER_COUNT] = { } }; -ALIGNED(4) const u8 sText_TrainerAppearsBusy[] = _("……\nThe TRAINER appears to be busy…\p"); -ALIGNED(4) const u8 sText_WaitForBattleMale[] = _("A battle, huh?\nAll right, just give me some time."); -ALIGNED(4) const u8 sText_WaitForChatMale[] = _("You want to chat, huh?\nSure, just wait a little."); -ALIGNED(4) const u8 sText_ShowTrainerCardMale[] = _("Sure thing! As my “Greetings,”\nhere's my TRAINER CARD."); -ALIGNED(4) const u8 sText_WaitForBattleFemale[] = _("A battle? Of course, but I need\ntime to get ready."); -ALIGNED(4) const u8 sText_WaitForChatFemale[] = _("Did you want to chat?\nOkay, but please wait a moment."); -ALIGNED(4) const u8 sText_ShowTrainerCardFemale[] = _("As my introduction, I'll show you\nmy TRAINER CARD."); +ALIGNED(4) static const u8 sText_TrainerAppearsBusy[] = _("……\nThe TRAINER appears to be busy…\p"); +ALIGNED(4) static const u8 sText_WaitForBattleMale[] = _("A battle, huh?\nAll right, just give me some time."); +ALIGNED(4) static const u8 sText_WaitForChatMale[] = _("You want to chat, huh?\nSure, just wait a little."); +ALIGNED(4) static const u8 sText_ShowTrainerCardMale[] = _("Sure thing! As my “Greetings,”\nhere's my TRAINER CARD."); +ALIGNED(4) static const u8 sText_WaitForBattleFemale[] = _("A battle? Of course, but I need\ntime to get ready."); +ALIGNED(4) static const u8 sText_WaitForChatFemale[] = _("Did you want to chat?\nOkay, but please wait a moment."); +ALIGNED(4) static const u8 sText_ShowTrainerCardFemale[] = _("As my introduction, I'll show you\nmy TRAINER CARD."); static const u8 *const sText_WaitOrShowCardTexts[GENDER_COUNT][4] = { { @@ -274,14 +275,14 @@ static const u8 *const sText_WaitOrShowCardTexts[GENDER_COUNT][4] = { } }; -ALIGNED(4) const u8 sText_WaitForChatMale2[] = _("You want to chat, huh?\nSure, just wait a little."); // Unused -ALIGNED(4) const u8 sText_DoneWaitingBattleMale[] = _("Thanks for waiting!\nLet's get our battle started!{PAUSE 60}"); -ALIGNED(4) const u8 sText_DoneWaitingChatMale[] = _("All right!\nLet's chat!{PAUSE 60}"); -ALIGNED(4) const u8 sText_DoneWaitingBattleFemale[] = _("Sorry I made you wait!\nLet's get started!{PAUSE 60}"); -ALIGNED(4) const u8 sText_DoneWaitingChatFemale[] = _("Sorry I made you wait!\nLet's chat.{PAUSE 60}"); -ALIGNED(4) const u8 sText_TradeWillBeStarted[] = _("The trade will be started.{PAUSE 60}"); -ALIGNED(4) const u8 sText_BattleWillBeStarted[] = _("The battle will be started.{PAUSE 60}"); -ALIGNED(4) const u8 sText_EnteringChat[] = _("Entering the chat…{PAUSE 60}"); +ALIGNED(4) static const u8 sText_WaitForChatMale2[] = _("You want to chat, huh?\nSure, just wait a little."); // Unused +ALIGNED(4) static const u8 sText_DoneWaitingBattleMale[] = _("Thanks for waiting!\nLet's get our battle started!{PAUSE 60}"); +ALIGNED(4) static const u8 sText_DoneWaitingChatMale[] = _("All right!\nLet's chat!{PAUSE 60}"); +ALIGNED(4) static const u8 sText_DoneWaitingBattleFemale[] = _("Sorry I made you wait!\nLet's get started!{PAUSE 60}"); +ALIGNED(4) static const u8 sText_DoneWaitingChatFemale[] = _("Sorry I made you wait!\nLet's chat.{PAUSE 60}"); +ALIGNED(4) static const u8 sText_TradeWillBeStarted[] = _("The trade will be started.{PAUSE 60}"); +ALIGNED(4) static const u8 sText_BattleWillBeStarted[] = _("The battle will be started.{PAUSE 60}"); +ALIGNED(4) static const u8 sText_EnteringChat[] = _("Entering the chat…{PAUSE 60}"); static const u8 *const sStartActivityTexts[][GENDER_COUNT][3] = { { @@ -307,36 +308,36 @@ static const u8 *const sStartActivityTexts[][GENDER_COUNT][3] = { } }; -ALIGNED(4) const u8 sText_BattleDeclinedMale[] = _("Sorry! My POKéMON don't seem to\nbe feeling too well right now.\lLet me battle you another time.\p"); -ALIGNED(4) const u8 sText_BattleDeclinedFemale[] = _("I'm terribly sorry, but my POKéMON\naren't feeling well…\pLet's battle another time.\p"); +ALIGNED(4) static const u8 sText_BattleDeclinedMale[] = _("Sorry! My POKéMON don't seem to\nbe feeling too well right now.\lLet me battle you another time.\p"); +ALIGNED(4) static const u8 sText_BattleDeclinedFemale[] = _("I'm terribly sorry, but my POKéMON\naren't feeling well…\pLet's battle another time.\p"); -const u8 *const sBattleDeclinedTexts[GENDER_COUNT] = { +static const u8 *const sBattleDeclinedTexts[GENDER_COUNT] = { sText_BattleDeclinedMale, sText_BattleDeclinedFemale }; -ALIGNED(4) const u8 sText_ShowTrainerCardDeclinedMale[] = _("Huh? My TRAINER CARD…\nWhere'd it go now?\lSorry! I'll show you another time!\p"); -ALIGNED(4) const u8 sText_ShowTrainerCardDeclinedFemale[] = _("Oh? Now where did I put my\nTRAINER CARD?…\lSorry! I'll show you later!\p"); +ALIGNED(4) static const u8 sText_ShowTrainerCardDeclinedMale[] = _("Huh? My TRAINER CARD…\nWhere'd it go now?\lSorry! I'll show you another time!\p"); +ALIGNED(4) static const u8 sText_ShowTrainerCardDeclinedFemale[] = _("Oh? Now where did I put my\nTRAINER CARD?…\lSorry! I'll show you later!\p"); -const u8 *const sShowTrainerCardDeclinedTexts[GENDER_COUNT] = { +static const u8 *const sShowTrainerCardDeclinedTexts[GENDER_COUNT] = { sText_ShowTrainerCardDeclinedMale, sText_ShowTrainerCardDeclinedFemale }; -ALIGNED(4) const u8 sText_IfYouWantToDoSomethingMale[] = _("If you want to do something with\nme, just give me a shout!\p"); -ALIGNED(4) const u8 sText_IfYouWantToDoSomethingFemale[] = _("If you want to do something with\nme, don't be shy.\p"); +ALIGNED(4) static const u8 sText_IfYouWantToDoSomethingMale[] = _("If you want to do something with\nme, just give me a shout!\p"); +ALIGNED(4) static const u8 sText_IfYouWantToDoSomethingFemale[] = _("If you want to do something with\nme, don't be shy.\p"); -const u8 *const sIfYouWantToDoSomethingTexts[GENDER_COUNT] = { +static const u8 *const sIfYouWantToDoSomethingTexts[GENDER_COUNT] = { sText_IfYouWantToDoSomethingMale, sText_IfYouWantToDoSomethingFemale }; -ALIGNED(4) const u8 sText_TrainerBattleBusy[] = _("Whoops! Sorry, but I have to do\nsomething else.\lAnother time, okay?\p"); -ALIGNED(4) const u8 sText_NeedTwoMonsOfLevel30OrLower1[] = _("If you want to battle, you need\ntwo POKéMON that are below\lLv. 30.\p"); -ALIGNED(4) const u8 sText_NeedTwoMonsOfLevel30OrLower2[] = _("For a battle, you need two\nPOKéMON that are below Lv. 30.\p"); +ALIGNED(4) static const u8 sText_TrainerBattleBusy[] = _("Whoops! Sorry, but I have to do\nsomething else.\lAnother time, okay?\p"); +ALIGNED(4) static const u8 sText_NeedTwoMonsOfLevel30OrLower1[] = _("If you want to battle, you need\ntwo POKéMON that are below\lLv. 30.\p"); +ALIGNED(4) static const u8 sText_NeedTwoMonsOfLevel30OrLower2[] = _("For a battle, you need two\nPOKéMON that are below Lv. 30.\p"); -ALIGNED(4) const u8 sText_DeclineChatMale[] = _("Oh, all right.\nCome see me anytime, okay?\p"); -ALIGNED(4) const u8 stext_DeclineChatFemale[] = _("Oh…\nPlease come by anytime.\p"); +ALIGNED(4) static const u8 sText_DeclineChatMale[] = _("Oh, all right.\nCome see me anytime, okay?\p"); +ALIGNED(4) static const u8 stext_DeclineChatFemale[] = _("Oh…\nPlease come by anytime.\p"); // Response from partner when player declines chat static const u8 *const sDeclineChatTexts[GENDER_COUNT] = { @@ -344,8 +345,8 @@ static const u8 *const sDeclineChatTexts[GENDER_COUNT] = { stext_DeclineChatFemale }; -ALIGNED(4) const u8 sText_ChatDeclinedMale[] = _("Oh, sorry!\nI just can't right this instant.\lLet's chat another time.\p"); -ALIGNED(4) const u8 sText_ChatDeclinedFemale[] = _("Oh, I'm sorry.\nI have too much to do right now.\lLet's chat some other time.\p"); +ALIGNED(4) static const u8 sText_ChatDeclinedMale[] = _("Oh, sorry!\nI just can't right this instant.\lLet's chat another time.\p"); +ALIGNED(4) static const u8 sText_ChatDeclinedFemale[] = _("Oh, I'm sorry.\nI have too much to do right now.\lLet's chat some other time.\p"); // Response from partner when they decline chat static const u8 *const sChatDeclinedTexts[GENDER_COUNT] = { @@ -353,16 +354,16 @@ static const u8 *const sChatDeclinedTexts[GENDER_COUNT] = { sText_ChatDeclinedFemale }; -ALIGNED(4) const u8 sText_YoureToughMale[] = _("Whoa!\nI can tell you're pretty tough!\p"); -ALIGNED(4) const u8 sText_UsedGoodMoveMale[] = _("You used that move?\nThat's good strategy!\p"); -ALIGNED(4) const u8 sText_BattleSurpriseMale[] = _("Way to go!\nThat was an eye-opener!\p"); -ALIGNED(4) const u8 sText_SwitchedMonsMale[] = _("Oh! How could you use that\nPOKéMON in that situation?\p"); -ALIGNED(4) const u8 sText_YoureToughFemale[] = _("That POKéMON…\nIt's been raised really well!\p"); -ALIGNED(4) const u8 sText_UsedGoodMoveFemale[] = _("That's it!\nThis is the right move now!\p"); -ALIGNED(4) const u8 sText_BattleSurpriseFemale[] = _("That's awesome!\nYou can battle that way?\p"); -ALIGNED(4) const u8 sText_SwitchedMonsFemale[] = _("You have exquisite timing for\nswitching POKéMON!\p"); +ALIGNED(4) static const u8 sText_YoureToughMale[] = _("Whoa!\nI can tell you're pretty tough!\p"); +ALIGNED(4) static const u8 sText_UsedGoodMoveMale[] = _("You used that move?\nThat's good strategy!\p"); +ALIGNED(4) static const u8 sText_BattleSurpriseMale[] = _("Way to go!\nThat was an eye-opener!\p"); +ALIGNED(4) static const u8 sText_SwitchedMonsMale[] = _("Oh! How could you use that\nPOKéMON in that situation?\p"); +ALIGNED(4) static const u8 sText_YoureToughFemale[] = _("That POKéMON…\nIt's been raised really well!\p"); +ALIGNED(4) static const u8 sText_UsedGoodMoveFemale[] = _("That's it!\nThis is the right move now!\p"); +ALIGNED(4) static const u8 sText_BattleSurpriseFemale[] = _("That's awesome!\nYou can battle that way?\p"); +ALIGNED(4) static const u8 sText_SwitchedMonsFemale[] = _("You have exquisite timing for\nswitching POKéMON!\p"); -const u8 *const sBattleReactionTexts[GENDER_COUNT][4] = { +static const u8 *const sBattleReactionTexts[GENDER_COUNT][4] = { { sText_YoureToughMale, sText_UsedGoodMoveMale, @@ -377,16 +378,16 @@ const u8 *const sBattleReactionTexts[GENDER_COUNT][4] = { } }; -ALIGNED(4) const u8 sText_LearnedSomethingMale[] = _("Oh, I see!\nThis is educational!\p"); -ALIGNED(4) const u8 sText_ThatsFunnyMale[] = _("Don't say anything funny anymore!\nI'm sore from laughing!\p"); -ALIGNED(4) const u8 sText_RandomChatMale1[] = _("Oh?\nSomething like that happened.\p"); -ALIGNED(4) const u8 sText_RandomChatMale2[] = _("Hmhm… What?\nSo is this what you're saying?\p"); -ALIGNED(4) const u8 sText_LearnedSomethingFemale[] = _("Is that right?\nI didn't know that.\p"); -ALIGNED(4) const u8 sText_ThatsFunnyFemale[] = _("Ahaha!\nWhat is that about?\p"); -ALIGNED(4) const u8 sText_RandomChatFemale1[] = _("Yes, that's exactly it!\nThat's what I meant.\p"); -ALIGNED(4) const u8 sText_RandomChatFemale2[] = _("In other words…\nYes! That's right!\p"); +ALIGNED(4) static const u8 sText_LearnedSomethingMale[] = _("Oh, I see!\nThis is educational!\p"); +ALIGNED(4) static const u8 sText_ThatsFunnyMale[] = _("Don't say anything funny anymore!\nI'm sore from laughing!\p"); +ALIGNED(4) static const u8 sText_RandomChatMale1[] = _("Oh?\nSomething like that happened.\p"); +ALIGNED(4) static const u8 sText_RandomChatMale2[] = _("Hmhm… What?\nSo is this what you're saying?\p"); +ALIGNED(4) static const u8 sText_LearnedSomethingFemale[] = _("Is that right?\nI didn't know that.\p"); +ALIGNED(4) static const u8 sText_ThatsFunnyFemale[] = _("Ahaha!\nWhat is that about?\p"); +ALIGNED(4) static const u8 sText_RandomChatFemale1[] = _("Yes, that's exactly it!\nThat's what I meant.\p"); +ALIGNED(4) static const u8 sText_RandomChatFemale2[] = _("In other words…\nYes! That's right!\p"); -const u8 *const sChatReactionTexts[GENDER_COUNT][4] = { +static const u8 *const sChatReactionTexts[GENDER_COUNT][4] = { { sText_LearnedSomethingMale, sText_ThatsFunnyMale, @@ -401,12 +402,12 @@ const u8 *const sChatReactionTexts[GENDER_COUNT][4] = { } }; -ALIGNED(4) const u8 sText_ShowedTrainerCardMale1[] = _("I'm just showing my TRAINER CARD\nas my way of greeting.\p"); -ALIGNED(4) const u8 sText_ShowedTrainerCardMale2[] = _("I hope I get to know you better!\p"); -ALIGNED(4) const u8 sText_ShowedTrainerCardFemale1[] = _("We're showing each other our\nTRAINER CARDS to get acquainted.\p"); -ALIGNED(4) const u8 sText_ShowedTrainerCardFemale2[] = _("Glad to meet you.\nPlease don't be a stranger!\p"); +ALIGNED(4) static const u8 sText_ShowedTrainerCardMale1[] = _("I'm just showing my TRAINER CARD\nas my way of greeting.\p"); +ALIGNED(4) static const u8 sText_ShowedTrainerCardMale2[] = _("I hope I get to know you better!\p"); +ALIGNED(4) static const u8 sText_ShowedTrainerCardFemale1[] = _("We're showing each other our\nTRAINER CARDS to get acquainted.\p"); +ALIGNED(4) static const u8 sText_ShowedTrainerCardFemale2[] = _("Glad to meet you.\nPlease don't be a stranger!\p"); -const u8 *const sTrainerCardReactionTexts[GENDER_COUNT][2] = { +static const u8 *const sTrainerCardReactionTexts[GENDER_COUNT][2] = { { sText_ShowedTrainerCardMale1, sText_ShowedTrainerCardMale2 @@ -417,12 +418,12 @@ const u8 *const sTrainerCardReactionTexts[GENDER_COUNT][2] = { } }; -ALIGNED(4) const u8 sText_MaleTraded1[] = _("Yeahah!\nI really wanted this POKéMON!\p"); -ALIGNED(4) const u8 sText_MaleTraded2[] = _("Finally, a trade got me that\nPOKéMON I'd wanted a long time.\p"); -ALIGNED(4) const u8 sText_FemaleTraded1[] = _("I'm trading POKéMON right now.\p"); -ALIGNED(4) const u8 sText_FemaleTraded2[] = _("I finally got that POKéMON I\nwanted in a trade!\p"); +ALIGNED(4) static const u8 sText_MaleTraded1[] = _("Yeahah!\nI really wanted this POKéMON!\p"); +ALIGNED(4) static const u8 sText_MaleTraded2[] = _("Finally, a trade got me that\nPOKéMON I'd wanted a long time.\p"); +ALIGNED(4) static const u8 sText_FemaleTraded1[] = _("I'm trading POKéMON right now.\p"); +ALIGNED(4) static const u8 sText_FemaleTraded2[] = _("I finally got that POKéMON I\nwanted in a trade!\p"); -const u8 *const sTradeReactionTexts[GENDER_COUNT][4] = { +static const u8 *const sTradeReactionTexts[GENDER_COUNT][4] = { { sText_MaleTraded1, sText_MaleTraded2 @@ -433,57 +434,66 @@ const u8 *const sTradeReactionTexts[GENDER_COUNT][4] = { } }; -ALIGNED(4) const u8 sText_XCheckedTradingBoard[] = _("{STR_VAR_1} checked the\nTRADING BOARD.\p"); -ALIGNED(4) const u8 sText_RegisterMonAtTradingBoard[] = _("Welcome to the TRADING BOARD.\pYou may register your POKéMON\nand offer it up for a trade.\pWould you like to register one of\nyour POKéMON?"); -ALIGNED(4) const u8 sText_TradingBoardInfo[] = _("This TRADING BOARD is used for\noffering a POKéMON for a trade.\pAll you need to do is register a\nPOKéMON for a trade.\pAnother TRAINER may offer a party\nPOKéMON in return for the trade.\pWe hope you will register POKéMON\nand trade them with many, many\lother TRAINERS.\pWould you like to register one of\nyour POKéMON?"); -ALIGNED(4) const u8 sText_ThankYouForRegistering[] = _("We have registered your POKéMON for\ntrade on the TRADING BOARD.\pThank you for using this service!\p"); // unused -ALIGNED(4) const u8 sText_NobodyHasRegistered[] = _("Nobody has registered any POKéMON\nfor trade on the TRADING BOARD.\p\n"); // unused -ALIGNED(4) const u8 sText_ChooseRequestedMonType[] = _("Please choose the type of POKéMON\nthat you would like in the trade.\n"); -ALIGNED(4) const u8 sText_WhichMonWillYouOffer[] = _("Which of your party POKéMON will\nyou offer in trade?\p"); -ALIGNED(4) const u8 sText_RegistrationCanceled[] = _("Registration has been canceled.\p"); -ALIGNED(4) const u8 sText_RegistraionCompleted[] = _("Registration has been completed.\p"); -ALIGNED(4) const u8 sText_TradeCanceled[] = _("The trade has been canceled.\p"); -ALIGNED(4) const u8 sText_CancelRegistrationOfMon[] = _("Cancel the registration of your\nLv. {STR_VAR_2} {STR_VAR_1}?"); -ALIGNED(4) const u8 sText_CancelRegistrationOfEgg[] = _("Cancel the registration of your\nEGG?"); -ALIGNED(4) const u8 sText_RegistrationCanceled2[] = _("The registration has been canceled.\p"); -ALIGNED(4) const u8 sText_TradeTrainersWillBeListed[] = _("TRAINERS wishing to make a trade\nwill be listed."); // unused -ALIGNED(4) const u8 sText_ChooseTrainerToTradeWith2[] = _("Please choose the TRAINER with whom\nyou would like to trade POKéMON."); // unused -ALIGNED(4) const u8 sText_AskTrainerToMakeTrade[] = _("Would you like to ask {STR_VAR_1} to\nmake a trade?"); -ALIGNED(4) const u8 sText_AwaitingResponseFromTrainer2[] = _("Awaiting a response from\nthe other TRAINER…"); // unused -ALIGNED(4) const u8 sText_NotRegisteredAMonForTrade[] = _("You have not registered a POKéMON\nfor trading.\p"); // unused -ALIGNED(4) const u8 sText_DontHaveTypeTrainerWants[] = _("You don't have a {STR_VAR_2}-type\nPOKéMON that {STR_VAR_1} wants.\p"); -ALIGNED(4) const u8 sText_DontHaveEggTrainerWants[] = _("You don't have an EGG that\n{STR_VAR_1} wants.\p"); -ALIGNED(4) const u8 sText_PlayerCantTradeForYourMon[] = _("{STR_VAR_1} can't make a trade for\nyour POKéMON right now.\p"); -ALIGNED(4) const u8 sText_CantTradeForPartnersMon[] = _("You can't make a trade for\n{STR_VAR_1}'s POKéMON right now.\p"); +ALIGNED(4) static const u8 sText_XCheckedTradingBoard[] = _("{STR_VAR_1} checked the\nTRADING BOARD.\p"); +ALIGNED(4) static const u8 sText_RegisterMonAtTradingBoard[] = _("Welcome to the TRADING BOARD.\pYou may register your POKéMON\nand offer it up for a trade.\pWould you like to register one of\nyour POKéMON?"); +ALIGNED(4) static const u8 sText_TradingBoardInfo[] = _("This TRADING BOARD is used for\n" + "offering a POKéMON for a trade.\p" + "All you need to do is register a\n" + "POKéMON for a trade.\p" + "Another TRAINER may offer a party\n" + "POKéMON in return for the trade.\p" + "We hope you will register POKéMON\n" + "and trade them with many, many\l" + "other TRAINERS.\p" + "Would you like to register one of\nyour POKéMON?"); +ALIGNED(4) static const u8 sText_ThankYouForRegistering[] = _("We have registered your POKéMON for\ntrade on the TRADING BOARD.\pThank you for using this service!\p"); // unused +ALIGNED(4) static const u8 sText_NobodyHasRegistered[] = _("Nobody has registered any POKéMON\nfor trade on the TRADING BOARD.\p\n"); // unused +ALIGNED(4) static const u8 sText_ChooseRequestedMonType[] = _("Please choose the type of POKéMON\nthat you would like in the trade.\n"); +ALIGNED(4) static const u8 sText_WhichMonWillYouOffer[] = _("Which of your party POKéMON will\nyou offer in trade?\p"); +ALIGNED(4) static const u8 sText_RegistrationCanceled[] = _("Registration has been canceled.\p"); +ALIGNED(4) static const u8 sText_RegistraionCompleted[] = _("Registration has been completed.\p"); +ALIGNED(4) static const u8 sText_TradeCanceled[] = _("The trade has been canceled.\p"); +ALIGNED(4) static const u8 sText_CancelRegistrationOfMon[] = _("Cancel the registration of your\nLv. {STR_VAR_2} {STR_VAR_1}?"); +ALIGNED(4) static const u8 sText_CancelRegistrationOfEgg[] = _("Cancel the registration of your\nEGG?"); +ALIGNED(4) static const u8 sText_RegistrationCanceled2[] = _("The registration has been canceled.\p"); +ALIGNED(4) static const u8 sText_TradeTrainersWillBeListed[] = _("TRAINERS wishing to make a trade\nwill be listed."); // unused +ALIGNED(4) static const u8 sText_ChooseTrainerToTradeWith2[] = _("Please choose the TRAINER with whom\nyou would like to trade POKéMON."); // unused +ALIGNED(4) static const u8 sText_AskTrainerToMakeTrade[] = _("Would you like to ask {STR_VAR_1} to\nmake a trade?"); +ALIGNED(4) static const u8 sText_AwaitingResponseFromTrainer2[] = _("Awaiting a response from\nthe other TRAINER…"); // unused +ALIGNED(4) static const u8 sText_NotRegisteredAMonForTrade[] = _("You have not registered a POKéMON\nfor trading.\p"); // unused +ALIGNED(4) static const u8 sText_DontHaveTypeTrainerWants[] = _("You don't have a {STR_VAR_2}-type\nPOKéMON that {STR_VAR_1} wants.\p"); +ALIGNED(4) static const u8 sText_DontHaveEggTrainerWants[] = _("You don't have an EGG that\n{STR_VAR_1} wants.\p"); +ALIGNED(4) static const u8 sText_PlayerCantTradeForYourMon[] = _("{STR_VAR_1} can't make a trade for\nyour POKéMON right now.\p"); +ALIGNED(4) static const u8 sText_CantTradeForPartnersMon[] = _("You can't make a trade for\n{STR_VAR_1}'s POKéMON right now.\p"); // Unused -const u8 *const sCantTradeMonTexts[] = { +static const u8 *const sCantTradeMonTexts[] = { sText_PlayerCantTradeForYourMon, sText_CantTradeForPartnersMon }; -ALIGNED(4) const u8 sText_TradeOfferRejected[] = _("Your trade offer was rejected.\p"); -ALIGNED(4) const u8 sText_EggTrade[] = _("EGG TRADE"); -ALIGNED(4) const u8 sText_ChooseJoinCancel[] = _("{DPAD_UPDOWN}CHOOSE {A_BUTTON}JOIN {B_BUTTON}CANCEL"); -ALIGNED(4) const u8 sText_ChooseTrainer[] = _("Please choose a TRAINER."); -ALIGNED(4) const u8 sText_ChooseTrainerSingleBattle[] = _("Please choose a TRAINER for\na SINGLE BATTLE."); -ALIGNED(4) const u8 sText_ChooseTrainerDoubleBattle[] = _("Please choose a TRAINER for\na DOUBLE BATTLE."); -ALIGNED(4) const u8 sText_ChooseLeaderMultiBattle[] = _("Please choose the LEADER\nfor a MULTI BATTLE."); -ALIGNED(4) const u8 sText_ChooseTrainerToTradeWith[] = _("Please choose the TRAINER to\ntrade with."); -ALIGNED(4) const u8 sText_ChooseTrainerToShareWonderCards[] = _("Please choose the TRAINER who is\nsharing WONDER CARDS."); -ALIGNED(4) const u8 sText_ChooseTrainerToShareWonderNews[] = _("Please choose the TRAINER who is\nsharing WONDER NEWS."); -ALIGNED(4) const u8 sText_ChooseLeaderPokemonJump[] = _("Jump with mini POKéMON!\nPlease choose the LEADER."); -ALIGNED(4) const u8 sText_ChooseLeaderBerryCrush[] = _("BERRY CRUSH!\nPlease choose the LEADER."); -ALIGNED(4) const u8 sText_ChooseLeaderBerryPicking[] = _("DODRIO BERRY-PICKING!\nPlease choose the LEADER."); -ALIGNED(4) const u8 sText_ChooseLeaderBerryBlender[] = _("BERRY BLENDER!\nPlease choose the LEADER."); -ALIGNED(4) const u8 sText_ChooseLeaderRecordCorner[] = _("RECORD CORNER!\nPlease choose the LEADER."); -ALIGNED(4) const u8 sText_ChooseLeaderCoolContest[] = _("COOLNESS CONTEST!\nPlease choose the LEADER."); -ALIGNED(4) const u8 sText_ChooseLeaderBeautyContest[] = _("BEAUTY CONTEST!\nPlease choose the LEADER."); -ALIGNED(4) const u8 sText_ChooseLeaderCuteContest[] = _("CUTENESS CONTEST!\nPlease choose the LEADER."); -ALIGNED(4) const u8 sText_ChooseLeaderSmartContest[] = _("SMARTNESS CONTEST!\nPlease choose the LEADER."); -ALIGNED(4) const u8 sText_ChooseLeaderToughContest[] = _("TOUGHNESS CONTEST!\nPlease choose the LEADER."); -ALIGNED(4) const u8 sText_ChooseLeaderBattleTowerLv50[] = _("BATTLE TOWER LEVEL 50!\nPlease choose the LEADER."); -ALIGNED(4) const u8 sText_ChooseLeaderBattleTowerOpenLv[] = _("BATTLE TOWER OPEN LEVEL!\nPlease choose the LEADER."); +ALIGNED(4) static const u8 sText_TradeOfferRejected[] = _("Your trade offer was rejected.\p"); +ALIGNED(4) static const u8 sText_EggTrade[] = _("EGG TRADE"); +ALIGNED(4) static const u8 sText_ChooseJoinCancel[] = _("{DPAD_UPDOWN}CHOOSE {A_BUTTON}JOIN {B_BUTTON}CANCEL"); +ALIGNED(4) static const u8 sText_ChooseTrainer[] = _("Please choose a TRAINER."); +ALIGNED(4) static const u8 sText_ChooseTrainerSingleBattle[] = _("Please choose a TRAINER for\na SINGLE BATTLE."); +ALIGNED(4) static const u8 sText_ChooseTrainerDoubleBattle[] = _("Please choose a TRAINER for\na DOUBLE BATTLE."); +ALIGNED(4) static const u8 sText_ChooseLeaderMultiBattle[] = _("Please choose the LEADER\nfor a MULTI BATTLE."); +ALIGNED(4) static const u8 sText_ChooseTrainerToTradeWith[] = _("Please choose the TRAINER to\ntrade with."); +ALIGNED(4) static const u8 sText_ChooseTrainerToShareWonderCards[] = _("Please choose the TRAINER who is\nsharing WONDER CARDS."); +ALIGNED(4) static const u8 sText_ChooseTrainerToShareWonderNews[] = _("Please choose the TRAINER who is\nsharing WONDER NEWS."); +ALIGNED(4) static const u8 sText_ChooseLeaderPokemonJump[] = _("Jump with mini POKéMON!\nPlease choose the LEADER."); +ALIGNED(4) static const u8 sText_ChooseLeaderBerryCrush[] = _("BERRY CRUSH!\nPlease choose the LEADER."); +ALIGNED(4) static const u8 sText_ChooseLeaderBerryPicking[] = _("DODRIO BERRY-PICKING!\nPlease choose the LEADER."); +ALIGNED(4) static const u8 sText_ChooseLeaderBerryBlender[] = _("BERRY BLENDER!\nPlease choose the LEADER."); +ALIGNED(4) static const u8 sText_ChooseLeaderRecordCorner[] = _("RECORD CORNER!\nPlease choose the LEADER."); +ALIGNED(4) static const u8 sText_ChooseLeaderCoolContest[] = _("COOLNESS CONTEST!\nPlease choose the LEADER."); +ALIGNED(4) static const u8 sText_ChooseLeaderBeautyContest[] = _("BEAUTY CONTEST!\nPlease choose the LEADER."); +ALIGNED(4) static const u8 sText_ChooseLeaderCuteContest[] = _("CUTENESS CONTEST!\nPlease choose the LEADER."); +ALIGNED(4) static const u8 sText_ChooseLeaderSmartContest[] = _("SMARTNESS CONTEST!\nPlease choose the LEADER."); +ALIGNED(4) static const u8 sText_ChooseLeaderToughContest[] = _("TOUGHNESS CONTEST!\nPlease choose the LEADER."); +ALIGNED(4) static const u8 sText_ChooseLeaderBattleTowerLv50[] = _("BATTLE TOWER LEVEL 50!\nPlease choose the LEADER."); +ALIGNED(4) static const u8 sText_ChooseLeaderBattleTowerOpenLv[] = _("BATTLE TOWER OPEN LEVEL!\nPlease choose the LEADER."); static const u8 *const sChooseTrainerTexts[NUM_LINK_GROUP_TYPES] = { @@ -511,53 +521,53 @@ static const u8 *const sChooseTrainerTexts[NUM_LINK_GROUP_TYPES] = [LINK_GROUP_BATTLE_TOWER_OPEN] = sText_ChooseLeaderBattleTowerOpenLv }; -ALIGNED(4) const u8 sText_SearchingForWirelessSystemWait[] = _("Searching for a WIRELESS\nCOMMUNICATION SYSTEM. Wait..."); -ALIGNED(4) const u8 sText_MustHaveTwoMonsForDoubleBattle[] = _("For a DOUBLE BATTLE, you must have\nat least two POKéMON.\p"); // Unused -ALIGNED(4) const u8 sText_AwaitingPlayersResponse[] = _("Awaiting {STR_VAR_1}'s response…"); -ALIGNED(4) const u8 sText_PlayerHasBeenAskedToRegisterYouPleaseWait[] = _("{STR_VAR_1} has been asked to register\nyou as a member. Please wait."); -ALIGNED(4) const u8 sText_AwaitingResponseFromWirelessSystem[] = _("Awaiting a response from the\nWIRELESS COMMUNICATION SYSTEM."); -ALIGNED(4) const u8 sText_PleaseWaitForOtherTrainersToGather[] = _("Please wait for other TRAINERS to\ngather and get ready."); // Unused -ALIGNED(4) const u8 sText_NoCardsSharedRightNow[] = _("No CARDS appear to be shared \nright now."); -ALIGNED(4) const u8 sText_NoNewsSharedRightNow[] = _("No NEWS appears to be shared\nright now."); +ALIGNED(4) static const u8 sText_SearchingForWirelessSystemWait[] = _("Searching for a WIRELESS\nCOMMUNICATION SYSTEM. Wait..."); +ALIGNED(4) static const u8 sText_MustHaveTwoMonsForDoubleBattle[] = _("For a DOUBLE BATTLE, you must have\nat least two POKéMON.\p"); // Unused +ALIGNED(4) static const u8 sText_AwaitingPlayersResponse[] = _("Awaiting {STR_VAR_1}'s response…"); +ALIGNED(4) static const u8 sText_PlayerHasBeenAskedToRegisterYouPleaseWait[] = _("{STR_VAR_1} has been asked to register\nyou as a member. Please wait."); +ALIGNED(4) static const u8 sText_AwaitingResponseFromWirelessSystem[] = _("Awaiting a response from the\nWIRELESS COMMUNICATION SYSTEM."); +ALIGNED(4) static const u8 sText_PleaseWaitForOtherTrainersToGather[] = _("Please wait for other TRAINERS to\ngather and get ready."); // Unused +ALIGNED(4) static const u8 sText_NoCardsSharedRightNow[] = _("No CARDS appear to be shared \nright now."); +ALIGNED(4) static const u8 sText_NoNewsSharedRightNow[] = _("No NEWS appears to be shared\nright now."); -const u8 *const sNoWonderSharedTexts[] = { +static const u8 *const sNoWonderSharedTexts[] = { sText_NoCardsSharedRightNow, sText_NoNewsSharedRightNow }; -ALIGNED(4) const u8 sText_Battle[] = _("BATTLE"); -ALIGNED(4) const u8 sText_Chat2[] = _("CHAT"); -ALIGNED(4) const u8 sText_Greetings[] = _("GREETINGS"); -ALIGNED(4) const u8 sText_Exit[] = _("EXIT"); -ALIGNED(4) const u8 sText_Exit2[] = _("EXIT"); -ALIGNED(4) const u8 sText_Info[] = _("INFO"); -ALIGNED(4) const u8 sText_NameWantedOfferLv[] = _("NAME{CLEAR_TO 0x3C}WANTED{CLEAR_TO 0x6E}OFFER{CLEAR_TO 0xC6}LV."); -ALIGNED(4) const u8 sText_SingleBattle[] = _("SINGLE BATTLE"); -ALIGNED(4) const u8 sText_DoubleBattle[] = _("DOUBLE BATTLE"); -ALIGNED(4) const u8 sText_MultiBattle[] = _("MULTI BATTLE"); -ALIGNED(4) const u8 sText_PokemonTrades[] = _("POKéMON TRADES"); -ALIGNED(4) const u8 sText_Chat[] = _("CHAT"); -ALIGNED(4) const u8 sText_Cards[] = _("CARDS"); -ALIGNED(4) const u8 sText_WonderCards[] = _("WONDER CARDS"); -ALIGNED(4) const u8 sText_WonderNews[] = _("WONDER NEWS"); -ALIGNED(4) const u8 sText_PokemonJump[] = _("POKéMON JUMP"); -ALIGNED(4) const u8 sText_BerryCrush[] = _("BERRY CRUSH"); -ALIGNED(4) const u8 sText_BerryPicking[] = _("BERRY-PICKING"); -ALIGNED(4) const u8 sText_Search[] = _("SEARCH"); -ALIGNED(4) const u8 sText_BerryBlender[] = _("BERRY BLENDER"); -ALIGNED(4) const u8 sText_RecordCorner[] = _("RECORD CORNER"); -ALIGNED(4) const u8 sText_CoolContest[] = _("COOL CONTEST"); -ALIGNED(4) const u8 sText_BeautyContest[] = _("BEAUTY CONTEST"); -ALIGNED(4) const u8 sText_CuteContest[] = _("CUTE CONTEST"); -ALIGNED(4) const u8 sText_SmartContest[] = _("SMART CONTEST"); -ALIGNED(4) const u8 sText_ToughContest[] = _("TOUGH CONTEST"); -ALIGNED(4) const u8 sText_BattleTowerLv50[] = _("BATTLE TOWER LV. 50"); -ALIGNED(4) const u8 sText_BattleTowerOpenLv[] = _("BATTLE TOWER OPEN LEVEL"); -ALIGNED(4) const u8 sText_ItsNormalCard[] = _("It's a NORMAL CARD."); -ALIGNED(4) const u8 sText_ItsBronzeCard[] = _("It's a BRONZE CARD!"); -ALIGNED(4) const u8 sText_ItsCopperCard[] = _("It's a COPPER CARD!"); -ALIGNED(4) const u8 sText_ItsSilverCard[] = _("It's a SILVER CARD!"); -ALIGNED(4) const u8 sText_ItsGoldCard[] = _("It's a GOLD CARD!"); +ALIGNED(4) static const u8 sText_Battle[] = _("BATTLE"); +ALIGNED(4) static const u8 sText_Chat2[] = _("CHAT"); +ALIGNED(4) static const u8 sText_Greetings[] = _("GREETINGS"); +ALIGNED(4) static const u8 sText_Exit[] = _("EXIT"); +ALIGNED(4) static const u8 sText_Exit2[] = _("EXIT"); +ALIGNED(4) static const u8 sText_Info[] = _("INFO"); +ALIGNED(4) static const u8 sText_NameWantedOfferLv[] = _("NAME{CLEAR_TO 60}WANTED{CLEAR_TO 110}OFFER{CLEAR_TO 198}LV."); +ALIGNED(4) static const u8 sText_SingleBattle[] = _("SINGLE BATTLE"); +ALIGNED(4) static const u8 sText_DoubleBattle[] = _("DOUBLE BATTLE"); +ALIGNED(4) static const u8 sText_MultiBattle[] = _("MULTI BATTLE"); +ALIGNED(4) static const u8 sText_PokemonTrades[] = _("POKéMON TRADES"); +ALIGNED(4) static const u8 sText_Chat[] = _("CHAT"); +ALIGNED(4) static const u8 sText_Cards[] = _("CARDS"); +ALIGNED(4) static const u8 sText_WonderCards[] = _("WONDER CARDS"); +ALIGNED(4) static const u8 sText_WonderNews[] = _("WONDER NEWS"); +ALIGNED(4) static const u8 sText_PokemonJump[] = _("POKéMON JUMP"); +ALIGNED(4) static const u8 sText_BerryCrush[] = _("BERRY CRUSH"); +ALIGNED(4) static const u8 sText_BerryPicking[] = _("BERRY-PICKING"); +ALIGNED(4) static const u8 sText_Search[] = _("SEARCH"); +ALIGNED(4) static const u8 sText_BerryBlender[] = _("BERRY BLENDER"); +ALIGNED(4) static const u8 sText_RecordCorner[] = _("RECORD CORNER"); +ALIGNED(4) static const u8 sText_CoolContest[] = _("COOL CONTEST"); +ALIGNED(4) static const u8 sText_BeautyContest[] = _("BEAUTY CONTEST"); +ALIGNED(4) static const u8 sText_CuteContest[] = _("CUTE CONTEST"); +ALIGNED(4) static const u8 sText_SmartContest[] = _("SMART CONTEST"); +ALIGNED(4) static const u8 sText_ToughContest[] = _("TOUGH CONTEST"); +ALIGNED(4) static const u8 sText_BattleTowerLv50[] = _("BATTLE TOWER LV. 50"); +ALIGNED(4) static const u8 sText_BattleTowerOpenLv[] = _("BATTLE TOWER OPEN LEVEL"); +ALIGNED(4) static const u8 sText_ItsNormalCard[] = _("It's a NORMAL CARD."); +ALIGNED(4) static const u8 sText_ItsBronzeCard[] = _("It's a BRONZE CARD!"); +ALIGNED(4) static const u8 sText_ItsCopperCard[] = _("It's a COPPER CARD!"); +ALIGNED(4) static const u8 sText_ItsSilverCard[] = _("It's a SILVER CARD!"); +ALIGNED(4) static const u8 sText_ItsGoldCard[] = _("It's a GOLD CARD!"); static const u8 *const sCardColorTexts[] = { sText_ItsNormalCard, @@ -567,17 +577,17 @@ static const u8 *const sCardColorTexts[] = { sText_ItsGoldCard }; -ALIGNED(4) const u8 sText_TrainerCardInfoPage1[] = _("This is {DYNAMIC 0} {DYNAMIC 1}'s\nTRAINER CARD…\l{DYNAMIC 2}\pPOKéDEX: {DYNAMIC 3}\nTIME: {DYNAMIC 4}:{DYNAMIC 5}\p"); -ALIGNED(4) const u8 sText_TrainerCardInfoPage2[] = _("BATTLES: WINS: {DYNAMIC 0} LOSSES: {DYNAMIC 2}\nTRADES: {DYNAMIC 3}\p“{DYNAMIC 4} {DYNAMIC 5}\n{DYNAMIC 6} {DYNAMIC 7}”\p"); -ALIGNED(4) const u8 sText_GladToMeetYouMale[] = _("{DYNAMIC 1}: Glad to have met you!{PAUSE 60}"); -ALIGNED(4) const u8 sText_GladToMeetYouFemale[] = _("{DYNAMIC 1}: Glad to meet you!{PAUSE 60}"); +ALIGNED(4) static const u8 sText_TrainerCardInfoPage1[] = _("This is {DYNAMIC 0} {DYNAMIC 1}'s\nTRAINER CARD…\l{DYNAMIC 2}\pPOKéDEX: {DYNAMIC 3}\nTIME: {DYNAMIC 4}:{DYNAMIC 5}\p"); +ALIGNED(4) static const u8 sText_TrainerCardInfoPage2[] = _("BATTLES: WINS: {DYNAMIC 0} LOSSES: {DYNAMIC 2}\nTRADES: {DYNAMIC 3}\p“{DYNAMIC 4} {DYNAMIC 5}\n{DYNAMIC 6} {DYNAMIC 7}”\p"); +ALIGNED(4) static const u8 sText_GladToMeetYouMale[] = _("{DYNAMIC 1}: Glad to have met you!{PAUSE 60}"); +ALIGNED(4) static const u8 sText_GladToMeetYouFemale[] = _("{DYNAMIC 1}: Glad to meet you!{PAUSE 60}"); -const u8 *const sGladToMeetYouTexts[GENDER_COUNT] = { +static const u8 *const sGladToMeetYouTexts[GENDER_COUNT] = { sText_GladToMeetYouMale, sText_GladToMeetYouFemale }; -ALIGNED(4) const u8 sText_FinishedCheckingPlayersTrainerCard[] = _("Finished checking {DYNAMIC 1}'s\nTRAINER CARD.{PAUSE 60}"); +ALIGNED(4) static const u8 sText_FinishedCheckingPlayersTrainerCard[] = _("Finished checking {DYNAMIC 1}'s\nTRAINER CARD.{PAUSE 60}"); static const u8 *const sLinkGroupActivityNameTexts[] = { [ACTIVITY_NONE] = sText_EmptyString, @@ -586,8 +596,8 @@ static const u8 *const sLinkGroupActivityNameTexts[] = { [ACTIVITY_BATTLE_MULTI] = sText_MultiBattle, [ACTIVITY_TRADE] = sText_PokemonTrades, [ACTIVITY_CHAT] = sText_Chat, - [ACTIVITY_WONDER_CARD] = sText_WonderCards, - [ACTIVITY_WONDER_NEWS] = sText_WonderNews, + [ACTIVITY_WONDER_CARD_DUP] = sText_WonderCards, + [ACTIVITY_WONDER_NEWS_DUP] = sText_WonderNews, [ACTIVITY_CARD] = sText_Cards, [ACTIVITY_POKEMON_JUMP] = sText_PokemonJump, [ACTIVITY_BERRY_CRUSH] = sText_BerryCrush, @@ -601,8 +611,8 @@ static const u8 *const sLinkGroupActivityNameTexts[] = { [ACTIVITY_DECLINE] = sText_EmptyString, [ACTIVITY_NPCTALK] = sText_EmptyString, [ACTIVITY_PLYRTALK] = sText_EmptyString, - [ACTIVITY_WONDER_CARD2] = sText_WonderCards, - [ACTIVITY_WONDER_NEWS2] = sText_WonderNews, + [ACTIVITY_WONDER_CARD] = sText_WonderCards, + [ACTIVITY_WONDER_NEWS] = sText_WonderNews, [ACTIVITY_CONTEST_COOL] = sText_CoolContest, [ACTIVITY_CONTEST_BEAUTY] = sText_BeautyContest, [ACTIVITY_CONTEST_CUTE] = sText_CuteContest, @@ -612,12 +622,12 @@ static const u8 *const sLinkGroupActivityNameTexts[] = { }; static const struct WindowTemplate sWindowTemplate_BButtonCancel = { - .bg = 0x00, - .tilemapLeft = 0x00, - .tilemapTop = 0x00, - .width = 0x1E, - .height = 0x02, - .paletteNum = 0x0F, + .bg = 0, + .tilemapLeft = 0, + .tilemapTop = 0, + .width = 30, + .height = 2, + .paletteNum = 15, .baseBlock = 0x0008 }; @@ -712,27 +722,27 @@ static const struct ListMenuTemplate sListMenuTemplate_PossibleGroupMembers = { .cursorKind = 1 }; -const struct WindowTemplate gUnknown_082F0174 = { - .bg = 0x00, - .tilemapLeft = 0x01, - .tilemapTop = 0x03, - .width = 0x11, - .height = 0x0a, - .paletteNum = 0x0f, +static const struct WindowTemplate sWindowTemplate_GroupList = { + .bg = 0, + .tilemapLeft = 1, + .tilemapTop = 3, + .width = 17, + .height = 10, + .paletteNum = 15, .baseBlock = 0x0044 }; -const struct WindowTemplate gUnknown_082F017C = { - .bg = 0x00, - .tilemapLeft = 0x14, - .tilemapTop = 0x03, - .width = 0x07, - .height = 0x04, - .paletteNum = 0x0f, +static const struct WindowTemplate sWindowTemplate_PlayerNameAndId = { + .bg = 0, + .tilemapLeft = 20, + .tilemapTop = 3, + .width = 7, + .height = 4, + .paletteNum = 15, .baseBlock = 0x00ee }; -const struct ListMenuItem gUnknown_082F0184[] = { +static const struct ListMenuItem sUnionRoomGroupsMenuItems[] = { { sText_EmptyString, 0 }, { sText_EmptyString, 1 }, { sText_EmptyString, 2 }, @@ -752,10 +762,10 @@ const struct ListMenuItem gUnknown_082F0184[] = { }; static const struct ListMenuTemplate sListMenuTemplate_UnionRoomGroups = { - .items = gUnknown_082F0184, + .items = sUnionRoomGroupsMenuItems, .moveCursorFunc = ListMenuDefaultCursorMoveFunc, .itemPrintFunc = ListMenuItemPrintFunc_UnionRoomGroups, - .totalItems = ARRAY_COUNT(gUnknown_082F0184), + .totalItems = ARRAY_COUNT(sUnionRoomGroupsMenuItems), .maxShowed = 5, .windowId = 0, .header_X = 0, @@ -773,27 +783,27 @@ static const struct ListMenuTemplate sListMenuTemplate_UnionRoomGroups = { }; static const struct WindowTemplate sWindowTemplate_InviteToActivity = { - .bg = 0x00, - .tilemapLeft = 0x14, - .tilemapTop = 0x05, - .width = 0x10, - .height = 0x08, - .paletteNum = 0x0f, + .bg = 0, + .tilemapLeft = 20, + .tilemapTop = 5, + .width = 16, + .height = 8, + .paletteNum = 15, .baseBlock = 0x0001 }; -const struct ListMenuItem gUnknown_082F0224[] = { - { sText_Greetings, 0x208 }, - { sText_Battle, 0x241 }, - { sText_Chat2, 0x245 }, - { sText_Exit, 0x040 } +static const struct ListMenuItem sInviteToActivityMenuItems[] = { + { sText_Greetings, ACTIVITY_CARD | LINK_GROUP_CAPACITY(0, 2)}, + { sText_Battle, ACTIVITY_BATTLE_SINGLE | IN_UNION_ROOM | LINK_GROUP_CAPACITY(0, 2)}, + { sText_Chat2, ACTIVITY_CHAT | IN_UNION_ROOM | LINK_GROUP_CAPACITY(0, 2)}, + { sText_Exit, ACTIVITY_NONE | IN_UNION_ROOM } }; static const struct ListMenuTemplate sListMenuTemplate_InviteToActivity = { - .items = gUnknown_082F0224, + .items = sInviteToActivityMenuItems, .moveCursorFunc = ListMenuDefaultCursorMoveFunc, .itemPrintFunc = NULL, - .totalItems = ARRAY_COUNT(gUnknown_082F0224), + .totalItems = ARRAY_COUNT(sInviteToActivityMenuItems), .maxShowed = 4, .windowId = 0, .header_X = 0, @@ -811,12 +821,12 @@ static const struct ListMenuTemplate sListMenuTemplate_InviteToActivity = { }; static const struct WindowTemplate sWindowTemplate_RegisterForTrade = { - .bg = 0x00, - .tilemapLeft = 0x12, - .tilemapTop = 0x07, - .width = 0x10, - .height = 0x06, - .paletteNum = 0x0f, + .bg = 0, + .tilemapLeft = 18, + .tilemapTop = 7, + .width = 16, + .height = 6, + .paletteNum = 15, .baseBlock = 0x0001 }; @@ -847,13 +857,13 @@ static const struct ListMenuTemplate sListMenuTemplate_RegisterForTrade = { .cursorKind = 0 }; -const struct WindowTemplate gUnknown_082F0294 = { - .bg = 0x00, - .tilemapLeft = 0x14, - .tilemapTop = 0x01, - .width = 0x10, - .height = 0x0c, - .paletteNum = 0x0f, +static const struct WindowTemplate sWindowTemplate_TradingBoardRequestType = { + .bg = 0, + .tilemapLeft = 20, + .tilemapTop = 1, + .width = 16, + .height = 12, + .paletteNum = 15, .baseBlock = 0x0001 }; @@ -899,23 +909,23 @@ static const struct ListMenuTemplate sMenuTemplate_TradingBoardRequestType = { .cursorKind = 0 }; -static const struct WindowTemplate sWindowTemplate_TradingBoard = { - .bg = 0x00, - .tilemapLeft = 0x01, - .tilemapTop = 0x01, - .width = 0x1c, - .height = 0x02, - .paletteNum = 0x0d, +static const struct WindowTemplate sWindowTemplate_TradingBoardHeader = { + .bg = 0, + .tilemapLeft = 1, + .tilemapTop = 1, + .width = 28, + .height = 2, + .paletteNum = 13, .baseBlock = 0x0001 }; -const struct WindowTemplate gUnknown_082F034C = { - .bg = 0x00, - .tilemapLeft = 0x01, - .tilemapTop = 0x05, - .width = 0x1c, - .height = 0x0c, - .paletteNum = 0x0d, +static const struct WindowTemplate sWindowTemplate_TradingBoardMain = { + .bg = 0, + .tilemapLeft = 1, + .tilemapTop = 5, + .width = 28, + .height = 12, + .paletteNum = 13, .baseBlock = 0x0039 }; @@ -953,13 +963,14 @@ static const struct ListMenuTemplate sTradeBoardListMenuTemplate = { .cursorKind = 0 }; -const struct WindowTemplate UnrefWindowTemplate_082F03B4 = { - .bg = 0x00, - .tilemapLeft = 0x01, - .tilemapTop = 0x05, - .width = 0x1c, - .height = 0x0c, - .paletteNum = 0x0d, +// Unused +static const struct WindowTemplate sWindowTemplate_Unused = { + .bg = 0, + .tilemapLeft = 1, + .tilemapTop = 5, + .width = 28, + .height = 12, + .paletteNum = 13, .baseBlock = 0x0039 }; @@ -983,10 +994,10 @@ static const struct ListMenuItem sEmptyListMenuItems[] = { }; // Unused -static const struct ListMenuTemplate sUnknownListMenuTemplate = { +static const struct ListMenuTemplate sEmptyListMenuTemplate = { .items = sEmptyListMenuItems, .moveCursorFunc = ListMenuDefaultCursorMoveFunc, - .itemPrintFunc = nullsub_14, + .itemPrintFunc = ItemPrintFunc_EmptyList, .totalItems = ARRAY_COUNT(sEmptyListMenuItems), .maxShowed = 4, .windowId = 0, @@ -1004,18 +1015,18 @@ static const struct ListMenuTemplate sUnknownListMenuTemplate = { .cursorKind = 0 }; -const struct WirelessGnameUnamePair sWirelessGnameUnamePair_Dummy = {0}; +static const struct RfuPlayerData sUnionRoomPlayer_DummyRfu = {0}; -ALIGNED(4) const u8 sAcceptedActivityIds_SingleBattle[] = {ACTIVITY_BATTLE_SINGLE, 0xff}; -ALIGNED(4) const u8 sAcceptedActivityIds_DoubleBattle[] = {ACTIVITY_BATTLE_DOUBLE, 0xff}; -ALIGNED(4) const u8 sAcceptedActivityIds_MultiBattle[] = {ACTIVITY_BATTLE_MULTI, 0xff}; -ALIGNED(4) const u8 sAcceptedActivityIds_Trade[] = {ACTIVITY_TRADE, 0xff}; -ALIGNED(4) const u8 sAcceptedActivityIds_PokemonJump[] = {ACTIVITY_POKEMON_JUMP, 0xff}; -ALIGNED(4) const u8 sAcceptedActivityIds_BerryCrush[] = {ACTIVITY_BERRY_CRUSH, 0xff}; -ALIGNED(4) const u8 sAcceptedActivityIds_BerryPicking[] = {ACTIVITY_BERRY_PICK, 0xff}; -ALIGNED(4) const u8 sAcceptedActivityIds_WonderCard[] = {ACTIVITY_WONDER_CARD2, 0xff}; -ALIGNED(4) const u8 sAcceptedActivityIds_WonderNews[] = {ACTIVITY_WONDER_NEWS2, 0xff}; -ALIGNED(4) const u8 sAcceptedActivityIds_Resume[] = { +ALIGNED(4) static const u8 sAcceptedActivityIds_SingleBattle[] = {ACTIVITY_BATTLE_SINGLE, 0xff}; +ALIGNED(4) static const u8 sAcceptedActivityIds_DoubleBattle[] = {ACTIVITY_BATTLE_DOUBLE, 0xff}; +ALIGNED(4) static const u8 sAcceptedActivityIds_MultiBattle[] = {ACTIVITY_BATTLE_MULTI, 0xff}; +ALIGNED(4) static const u8 sAcceptedActivityIds_Trade[] = {ACTIVITY_TRADE, 0xff}; +ALIGNED(4) static const u8 sAcceptedActivityIds_PokemonJump[] = {ACTIVITY_POKEMON_JUMP, 0xff}; +ALIGNED(4) static const u8 sAcceptedActivityIds_BerryCrush[] = {ACTIVITY_BERRY_CRUSH, 0xff}; +ALIGNED(4) static const u8 sAcceptedActivityIds_BerryPicking[] = {ACTIVITY_BERRY_PICK, 0xff}; +ALIGNED(4) static const u8 sAcceptedActivityIds_WonderCard[] = {ACTIVITY_WONDER_CARD, 0xff}; +ALIGNED(4) static const u8 sAcceptedActivityIds_WonderNews[] = {ACTIVITY_WONDER_NEWS, 0xff}; +ALIGNED(4) static const u8 sAcceptedActivityIds_Resume[] = { IN_UNION_ROOM | ACTIVITY_NONE, IN_UNION_ROOM | ACTIVITY_BATTLE_SINGLE, IN_UNION_ROOM | ACTIVITY_TRADE, @@ -1027,8 +1038,8 @@ ALIGNED(4) const u8 sAcceptedActivityIds_Resume[] = { IN_UNION_ROOM | ACTIVITY_PLYRTALK, 0xff }; -ALIGNED(4) const u8 sAcceptedActivityIds_Init[] = {ACTIVITY_SEARCH, 0xff}; -ALIGNED(4) const u8 sAcceptedActivityIds_Unk11[] = { +ALIGNED(4) static const u8 sAcceptedActivityIds_Init[] = {ACTIVITY_SEARCH, 0xff}; +ALIGNED(4) static const u8 sAcceptedActivityIds_Unk11[] = { ACTIVITY_BATTLE_SINGLE, ACTIVITY_BATTLE_DOUBLE, ACTIVITY_BATTLE_MULTI, @@ -1036,22 +1047,22 @@ ALIGNED(4) const u8 sAcceptedActivityIds_Unk11[] = { ACTIVITY_POKEMON_JUMP, ACTIVITY_BERRY_CRUSH, ACTIVITY_BERRY_PICK, - ACTIVITY_WONDER_CARD2, - ACTIVITY_WONDER_NEWS2, + ACTIVITY_WONDER_CARD, + ACTIVITY_WONDER_NEWS, ACTIVITY_SPIN_TRADE, 0xff }; -ALIGNED(4) const u8 sAcceptedActivityIds_RecordCorner[] = {ACTIVITY_RECORD_CORNER, 0xff}; -ALIGNED(4) const u8 sAcceptedActivityIds_BerryBlender[] = {ACTIVITY_BERRY_BLENDER, 0xff}; -ALIGNED(4) const u8 sAcceptedActivityIds_CoolContest[] = {ACTIVITY_CONTEST_COOL, 0xff}; -ALIGNED(4) const u8 sAcceptedActivityIds_BeautyContest[] = {ACTIVITY_CONTEST_BEAUTY, 0xff}; -ALIGNED(4) const u8 sAcceptedActivityIds_CuteContest[] = {ACTIVITY_CONTEST_CUTE, 0xff}; -ALIGNED(4) const u8 sAcceptedActivityIds_SmartContest[] = {ACTIVITY_CONTEST_SMART, 0xff}; -ALIGNED(4) const u8 sAcceptedActivityIds_ToughContest[] = {ACTIVITY_CONTEST_TOUGH, 0xff}; -ALIGNED(4) const u8 sAcceptedActivityIds_BattleTower[] = {ACTIVITY_BATTLE_TOWER, 0xff}; -ALIGNED(4) const u8 sAcceptedActivityIds_BattleTowerOpen[] = {ACTIVITY_BATTLE_TOWER_OPEN, 0xff}; +ALIGNED(4) static const u8 sAcceptedActivityIds_RecordCorner[] = {ACTIVITY_RECORD_CORNER, 0xff}; +ALIGNED(4) static const u8 sAcceptedActivityIds_BerryBlender[] = {ACTIVITY_BERRY_BLENDER, 0xff}; +ALIGNED(4) static const u8 sAcceptedActivityIds_CoolContest[] = {ACTIVITY_CONTEST_COOL, 0xff}; +ALIGNED(4) static const u8 sAcceptedActivityIds_BeautyContest[] = {ACTIVITY_CONTEST_BEAUTY, 0xff}; +ALIGNED(4) static const u8 sAcceptedActivityIds_CuteContest[] = {ACTIVITY_CONTEST_CUTE, 0xff}; +ALIGNED(4) static const u8 sAcceptedActivityIds_SmartContest[] = {ACTIVITY_CONTEST_SMART, 0xff}; +ALIGNED(4) static const u8 sAcceptedActivityIds_ToughContest[] = {ACTIVITY_CONTEST_TOUGH, 0xff}; +ALIGNED(4) static const u8 sAcceptedActivityIds_BattleTower[] = {ACTIVITY_BATTLE_TOWER, 0xff}; +ALIGNED(4) static const u8 sAcceptedActivityIds_BattleTowerOpen[] = {ACTIVITY_BATTLE_TOWER_OPEN, 0xff}; -const u8 *const sAcceptedActivityIds[NUM_LINK_GROUP_TYPES] = { +static const u8 *const sAcceptedActivityIds[NUM_LINK_GROUP_TYPES] = { [LINK_GROUP_SINGLE_BATTLE] = sAcceptedActivityIds_SingleBattle, [LINK_GROUP_DOUBLE_BATTLE] = sAcceptedActivityIds_DoubleBattle, [LINK_GROUP_MULTI_BATTLE] = sAcceptedActivityIds_MultiBattle, @@ -1085,8 +1096,8 @@ static const u8 sLinkGroupToURoomActivity[NUM_LINK_GROUP_TYPES + 2] = [LINK_GROUP_POKEMON_JUMP] = ACTIVITY_POKEMON_JUMP, [LINK_GROUP_BERRY_CRUSH] = ACTIVITY_BERRY_CRUSH, [LINK_GROUP_BERRY_PICKING] = ACTIVITY_BERRY_PICK, - [LINK_GROUP_WONDER_CARD] = ACTIVITY_WONDER_CARD2, - [LINK_GROUP_WONDER_NEWS] = ACTIVITY_WONDER_NEWS2, + [LINK_GROUP_WONDER_CARD] = ACTIVITY_WONDER_CARD, + [LINK_GROUP_WONDER_NEWS] = ACTIVITY_WONDER_NEWS, [LINK_GROUP_UNION_ROOM_RESUME] = ACTIVITY_NONE, [LINK_GROUP_UNION_ROOM_INIT] = ACTIVITY_NONE, [LINK_GROUP_UNK_11] = ACTIVITY_NONE, diff --git a/src/dodrio_berry_picking.c b/src/dodrio_berry_picking.c index e5ff1d184..d7361ce96 100644 --- a/src/dodrio_berry_picking.c +++ b/src/dodrio_berry_picking.c @@ -3106,7 +3106,7 @@ static u32 RecvPacket_ReadyToStart(u32 playerId) { struct ReadyToStartPacket *packet; - if ((gRecvCmds[0][0] & 0xFF00) != RFUCMD_SEND_PACKET) + if ((gRecvCmds[0][0] & RFUCMD_MASK) != RFUCMD_SEND_PACKET) return FALSE; packet = (void *)&gRecvCmds[playerId][1]; @@ -3233,7 +3233,7 @@ static bool32 RecvPacket_GameState(u32 playerId, struct GameStatePacket *packet; struct DodrioGame_Berries *berries = &player->berries; - if ((gRecvCmds[0][0] & 0xFF00) != RFUCMD_SEND_PACKET) + if ((gRecvCmds[0][0] & RFUCMD_MASK) != RFUCMD_SEND_PACKET) return FALSE; packet = (void *)&gRecvCmds[0][1]; @@ -3310,7 +3310,7 @@ static bool32 RecvPacket_PickState(u32 playerId, u8 *pickState) { struct PickStatePacket *packet; - if ((gRecvCmds[0][0] & 0xFF00) != RFUCMD_SEND_PACKET) + if ((gRecvCmds[0][0] & RFUCMD_MASK) != RFUCMD_SEND_PACKET) return FALSE; packet = (void *)&gRecvCmds[playerId][1]; @@ -3341,7 +3341,7 @@ static bool32 RecvPacket_ReadyToEnd(u32 playerId) { struct ReadyToEndPacket *packet; - if ((gRecvCmds[0][0] & 0xFF00) != RFUCMD_SEND_PACKET) + if ((gRecvCmds[0][0] & RFUCMD_MASK) != RFUCMD_SEND_PACKET) return FALSE; packet = (void *)&gRecvCmds[playerId][1]; diff --git a/src/field_player_avatar.c b/src/field_player_avatar.c index 51e49629c..276fb44b2 100644 --- a/src/field_player_avatar.c +++ b/src/field_player_avatar.c @@ -1138,22 +1138,22 @@ u8 player_get_pos_including_state_based_drift(s16 *x, s16 *y) switch (object->movementActionId) { - case MOVEMENT_ACTION_WALK_NORMAL_DOWN: - case MOVEMENT_ACTION_PLAYER_RUN_DOWN: - (*y)++; - return TRUE; - case MOVEMENT_ACTION_WALK_NORMAL_UP: - case MOVEMENT_ACTION_PLAYER_RUN_UP: - (*y)--; - return TRUE; - case MOVEMENT_ACTION_WALK_NORMAL_LEFT: - case MOVEMENT_ACTION_PLAYER_RUN_LEFT: - (*x)--; - return TRUE; - case MOVEMENT_ACTION_WALK_NORMAL_RIGHT: - case MOVEMENT_ACTION_PLAYER_RUN_RIGHT: - (*x)++; - return TRUE; + case MOVEMENT_ACTION_WALK_NORMAL_DOWN: + case MOVEMENT_ACTION_PLAYER_RUN_DOWN: + (*y)++; + return TRUE; + case MOVEMENT_ACTION_WALK_NORMAL_UP: + case MOVEMENT_ACTION_PLAYER_RUN_UP: + (*y)--; + return TRUE; + case MOVEMENT_ACTION_WALK_NORMAL_LEFT: + case MOVEMENT_ACTION_PLAYER_RUN_LEFT: + (*x)--; + return TRUE; + case MOVEMENT_ACTION_WALK_NORMAL_RIGHT: + case MOVEMENT_ACTION_PLAYER_RUN_RIGHT: + (*x)++; + return TRUE; } } diff --git a/src/field_screen_effect.c b/src/field_screen_effect.c index fbe725c0b..65611c0f1 100644 --- a/src/field_screen_effect.c +++ b/src/field_screen_effect.c @@ -204,7 +204,7 @@ static void Task_ReturnToFieldWirelessLink(u8 taskId) if (!IsLinkTaskFinished()) { if (++task->data[1] > 1800) - GetLinkmanErrorParams(0x6000); + RfuSetErrorParams(F_RFU_ERROR_6 | F_RFU_ERROR_7); } else { diff --git a/src/field_specials.c b/src/field_specials.c index c3bd62946..ab02f9938 100644 --- a/src/field_specials.c +++ b/src/field_specials.c @@ -3775,7 +3775,7 @@ static void Task_LinkRetireStatusWithBattleTowerPartner(u8 taskId) { // Send value of gSpecialVar_0x8004 to leader // Will either be BATTLE_TOWER_LINK_CONTINUE or BATTLE_TOWER_LINK_RETIRE - SendBlock(bitmask_all_link_players_but_self(), &gSpecialVar_0x8004, sizeof(gSpecialVar_0x8004)); + SendBlock(BitmaskAllOtherLinkPlayers(), &gSpecialVar_0x8004, sizeof(gSpecialVar_0x8004)); gTasks[taskId].tState++; } } @@ -3824,7 +3824,7 @@ static void Task_LinkRetireStatusWithBattleTowerPartner(u8 taskId) else { // Send whether or not play should continue - SendBlock(bitmask_all_link_players_but_self(), &gSpecialVar_Result, sizeof(gSpecialVar_Result)); + SendBlock(BitmaskAllOtherLinkPlayers(), &gSpecialVar_Result, sizeof(gSpecialVar_Result)); gTasks[taskId].tState++; } } diff --git a/src/intro.c b/src/intro.c index d027c7230..5cf99c97e 100644 --- a/src/intro.c +++ b/src/intro.c @@ -1142,7 +1142,7 @@ void CB2_InitCopyrightScreenAfterBootup(void) { if (!SetUpCopyrightScreen()) { - SetSaveBlocksPointers(sub_815355C()); + SetSaveBlocksPointers(GetSaveBlocksPointersBaseOffset()); ResetMenuAndMonGlobals(); Save_ResetSaveCounters(); Save_LoadGameData(SAVE_NORMAL); diff --git a/src/librfu_rfu.c b/src/librfu_rfu.c index de0056464..9a5db6d9d 100644 --- a/src/librfu_rfu.c +++ b/src/librfu_rfu.c @@ -1,6 +1,14 @@ #include #include "librfu.h" +// If expanding the length of the player name and wireless link functionality is +// desired, ensure that the name string is limited in size when it's copied from the +// saveblock to any Rfu-related fields (e.g. in SetHostRfuUsername). +// If wireless link functionality is not desired ignore or delete this warning. +#if RFU_USER_NAME_LENGTH < (PLAYER_NAME_LENGTH + 1) +#warning "The Wireless Adapter hardware expects a username of no more than 8 bytes." +#endif + struct LLSFStruct { u8 frameSize; diff --git a/src/link.c b/src/link.c index 97b3dfe91..66549f648 100644 --- a/src/link.c +++ b/src/link.c @@ -1,7 +1,7 @@ #include "global.h" #include "m4a.h" #include "malloc.h" -#include "reset_save_heap.h" +#include "reload_save.h" #include "save.h" #include "bg.h" #include "window.h" @@ -108,7 +108,7 @@ static EWRAM_DATA u16 sTimeOutCounter = 0; EWRAM_DATA struct LinkPlayer gLocalLinkPlayer = {}; EWRAM_DATA struct LinkPlayer gLinkPlayers[MAX_RFU_PLAYERS] = {}; static EWRAM_DATA struct LinkPlayer sSavedLinkPlayers[MAX_RFU_PLAYERS] = {}; -EWRAM_DATA struct { +static EWRAM_DATA struct { u32 status; u8 lastRecvQueueCount; u8 lastSendQueueCount; @@ -140,7 +140,7 @@ static void LinkCB_WaitCloseLinkWithJP(void); static void LinkCB_Standby(void); static void LinkCB_StandbyForAll(void); -static void CheckErrorStatus(void); +static void TrySetLinkErrorBuffer(void); static void CB2_PrintErrorMessage(void); static bool8 IsSioMultiMaster(void); static void SetWirelessCommType0_Internal(void); @@ -166,11 +166,11 @@ static const u16 sLinkTestDigitsGfx[] = INCBIN_U16("graphics/interface/link_test static const u8 sUnusedTransparentWhite[] = _("{HIGHLIGHT TRANSPARENT}{COLOR WHITE}"); static const u16 sCommErrorBg_Gfx[] = INCBIN_U16("graphics/interface/comm_error_bg.4bpp"); static const struct BlockRequest sBlockRequests[] = { - {gBlockSendBuffer, 200}, - {gBlockSendBuffer, 200}, - {gBlockSendBuffer, 100}, - {gBlockSendBuffer, 220}, - {gBlockSendBuffer, 40} + [BLOCK_REQ_SIZE_NONE] = {gBlockSendBuffer, 200}, + [BLOCK_REQ_SIZE_200] = {gBlockSendBuffer, 200}, + [BLOCK_REQ_SIZE_100] = {gBlockSendBuffer, 100}, + [BLOCK_REQ_SIZE_220] = {gBlockSendBuffer, 220}, + [BLOCK_REQ_SIZE_40] = {gBlockSendBuffer, 40} }; static const u8 sBGControlRegs[] = { REG_OFFSET_BG0CNT, @@ -394,9 +394,7 @@ void CloseLink(void) { gReceivedRemoteLinkPlayers = FALSE; if (gWirelessCommType) - { LinkRfu_Shutdown(); - } sLinkOpen = FALSE; DisableSerial(); } @@ -485,22 +483,18 @@ u16 LinkMain2(const u16 *heldKeys) u8 i; if (!sLinkOpen) - { return 0; - } + for (i = 0; i < CMD_LENGTH; i++) - { gSendCmd[i] = 0; - } + gLinkHeldKeys = *heldKeys; if (gLinkStatus & LINK_STAT_CONN_ESTABLISHED) { ProcessRecvCmds(SIO_MULTI_CNT->id); if (gLinkCallback != NULL) - { gLinkCallback(); - } - CheckErrorStatus(); + TrySetLinkErrorBuffer(); } return gLinkStatus; } @@ -1029,7 +1023,7 @@ u8 GetMultiplayerId(void) return SIO_MULTI_CNT->id; } -u8 bitmask_all_link_players_but_self(void) +u8 BitmaskAllOtherLinkPlayers(void) { u8 mpId; @@ -1563,10 +1557,13 @@ static void LinkCB_StandbyForAll(void) } } -static void CheckErrorStatus(void) +static void TrySetLinkErrorBuffer(void) { + // Check if a link error has occurred if (sLinkOpen && EXTRACT_LINK_ERRORS(gLinkStatus)) { + // Link error has occurred, handle message details if + // necessary, then stop the link. if (!gSuppressLinkErrorMessage) { sLinkErrorBuffer.status = gLinkStatus; @@ -1579,7 +1576,7 @@ static void CheckErrorStatus(void) } } -void BufferLinkErrorInfo(u32 status, u8 lastSendQueueCount, u8 lastRecvQueueCount, bool8 disconnected) +void SetLinkErrorBuffer(u32 status, u8 lastSendQueueCount, u8 lastRecvQueueCount, bool8 disconnected) { sLinkErrorBuffer.status = status; sLinkErrorBuffer.lastSendQueueCount = lastSendQueueCount; @@ -1709,7 +1706,7 @@ static void CB2_PrintErrorMessage(void) PlaySE(SE_PIN); gWirelessCommType = 0; sLinkErrorBuffer.disconnected = FALSE; - sub_81700F8(); + ReloadSave(); } } else if (gWirelessCommType == 2) @@ -1731,12 +1728,12 @@ static void CB2_PrintErrorMessage(void) bool8 GetSioMultiSI(void) { - return (REG_SIOCNT & 0x04) != 0; + return (REG_SIOCNT & SIO_MULTI_SI) != 0; } static bool8 IsSioMultiMaster(void) { - return (REG_SIOCNT & 0x8) && !(REG_SIOCNT & 0x04); + return (REG_SIOCNT & SIO_MULTI_SD) && (REG_SIOCNT & SIO_MULTI_SI) == 0; } bool8 IsLinkConnectionEstablished(void) @@ -1782,10 +1779,10 @@ void LinkPlayerFromBlock(u32 who) SetMainCallback2(CB2_LinkError); } +// When this function returns TRUE the callbacks are skipped bool8 HandleLinkConnection(void) { - bool32 r4; - bool32 r5; + bool32 main1Failed, main2Failed; if (gWirelessCommType == 0) { @@ -1796,11 +1793,13 @@ bool8 HandleLinkConnection(void) } else { - r4 = sub_8010EC0(); - r5 = sub_8010F1C(); + main1Failed = RfuMain1(); // Always returns FALSE + main2Failed = RfuMain2(); if (IsSendingKeysOverCable() == TRUE) { - if (r4 == TRUE || IsRfuRecvQueueEmpty() || r5) + // This will never be reached. + // IsSendingKeysOverCable is always FALSE for wireless communication + if (main1Failed == TRUE || IsRfuRecvQueueEmpty() || main2Failed) return TRUE; } } @@ -1916,9 +1915,7 @@ u32 LinkMain1(u8 *shouldAdvanceLinkState, u16 *sendCmd, u16 (*recvCmds)[CMD_LENG break; case 1: if (gLink.isMaster == LINK_MASTER && gLink.playerCount > 1) - { gLink.handshakeAsMaster = TRUE; - } break; case 2: gLink.state = LINK_STATE_START0; @@ -1974,20 +1971,14 @@ u32 LinkMain1(u8 *shouldAdvanceLinkState, u16 *sendCmd, u16 (*recvCmds)[CMD_LENG } if (gLink.lag == LAG_MASTER) - { retVal |= LINK_STAT_ERROR_LAG_MASTER; - } if (gLink.localId >= MAX_LINK_PLAYERS) - { retVal |= LINK_STAT_ERROR_INVALID_ID; - } retVal2 = retVal; if (gLink.lag == LAG_SLAVE) - { retVal2 |= LINK_STAT_ERROR_LAG_SLAVE; - } return retVal2; } diff --git a/src/link_rfu_2.c b/src/link_rfu_2.c index 2d85bb81a..f2caef949 100644 --- a/src/link_rfu_2.c +++ b/src/link_rfu_2.c @@ -18,48 +18,86 @@ #include "save.h" #include "mystery_gift.h" +enum { + RFUSTATE_INIT, + RFUSTATE_INIT_END, + RFUSTATE_PARENT_CONNECT, + RFUSTATE_PARENT_CONNECT_END, + RFUSTATE_STOP_MANAGER, + RFUSTATE_STOP_MANAGER_END, + RFUSTATE_CHILD_CONNECT, + RFUSTATE_CHILD_CONNECT_END, + RFUSTATE_UNUSED, + RFUSTATE_RECONNECTED, + RFUSTATE_CONNECTED, + RFUSTATE_CHILD_TRY_JOIN, + RFUSTATE_CHILD_JOINED, + RFUSTATE_UR_PLAYER_EXCHANGE, + RFUSTATE_UR_STOP_MANAGER, + RFUSTATE_UR_STOP_MANAGER_END, + RFUSTATE_UR_FINALIZE, +}; +// These states are used for different purposes +// depending on the link mode (parent, child, union room) +#define RFUSTATE_PARENT_FINALIZE_START 17 +#define RFUSTATE_PARENT_FINALIZE 18 +#define RFUSTATE_UR_CONNECT 17 +#define RFUSTATE_UR_CONNECT_END 18 +#define RFUSTATE_FINALIZED 20 + +// States for the 'receiving' field of RfuBlockSend +enum { + RECV_STATE_READY, + RECV_STATE_RECEIVING, + RECV_STATE_FINISHED, +}; + struct SioInfo { - char magic[15]; // PokemonSioInfo + char magic[sizeof("PokemonSioInfo")]; u8 playerCount; u8 linkPlayerIdx[RFU_CHILD_MAX]; struct LinkPlayer linkPlayers[MAX_RFU_PLAYERS]; u8 filler[92]; }; +// Struct is mostly empty, presumably because usage of +// its fields was largely removed before release struct RfuDebug { - u8 filler0[6]; - u16 unk_06; - u8 filler1[6]; - vu8 unk_0e; - u8 unk_0f; - u8 filler2[84]; - u16 unk_64; - u8 filler3[29]; - u8 unk_83; - u8 filler4[88]; + u8 unused0[6]; + u16 recvCount; + u8 unused1[6]; + vu8 unkFlag; + u8 childJoinCount; + u8 unused2[84]; + u16 blockSendFailures; + u8 unused3[29]; + u8 blockSendTime; + u8 unused4[88]; }; -u32 gf_rfu_REQ_api[RFU_API_BUFF_SIZE_RAM / 4]; -struct GFRfuManager Rfu; +u32 gRfuAPIBuffer[RFU_API_BUFF_SIZE_RAM / 4]; +struct RfuManager gRfu; static u8 sHeldKeyCount; -static u8 sResendBlock8[16]; -static u16 sResendBlock16[8]; +static u8 sResendBlock8[CMD_LENGTH * 2]; +static u16 sResendBlock16[CMD_LENGTH]; -EWRAM_DATA struct GFtgtGname gHostRFUtgtGnameBuffer = {}; -EWRAM_DATA u8 gHostRFUtgtUnameBuffer[PLAYER_NAME_LENGTH + 1] = {}; +EWRAM_DATA struct RfuGameData gHostRfuGameData = {}; +EWRAM_DATA u8 gHostRfuUsername[RFU_USER_NAME_LENGTH] = {}; static EWRAM_DATA INIT_PARAM sRfuReqConfig = {}; static EWRAM_DATA struct RfuDebug sRfuDebug = {}; static void ResetSendDataManager(struct RfuBlockSend *); -static void sub_800EAB4(void); -static void sub_800EAFC(void); -static void sub_800ED34(u16); -static void sub_800EDBC(u16); +static void InitChildRecvBuffers(void); +static void InitParentSendData(void); +static void MSCCallback_Child(u16); +static void MSCCallback_Parent(u16); static void UpdateBackupQueue(void); -static void Task_ExchangeLinkPlayers(u8); +static void Task_PlayerExchange(u8); +static void Task_PlayerExchangeUpdate(u8); +static void Task_PlayerExchangeChat(u8); static void RfuHandleReceiveCommand(u8); static void CallRfuFunc(void); static void RfuPrepareSendBuffer(u16); @@ -68,16 +106,14 @@ static void SendNextBlock(void); static void SendLastBlock(void); static u8 GetPartnerIndexByNameAndTrainerID(const u8 *, u16); static void UpdateChildStatuses(void); -static s32 sub_80107A0(void); -static void sub_801084C(u8); +static s32 GetJoinGroupStatus(void); static void ClearSelectedLinkPlayerIds(u16); static void ValidateAndReceivePokemonSioInfo(void *); -static void sub_8010D0C(u8); -static void sub_80115EC(s32); -static void sub_8011BF8(void); +static void ParentResetChildRecvMetadata(s32); +static void CB2_RfuIdle(void); static void RfuReqDisconnectSlot(u32); -static void sub_8011E94(u32, u32); -static void sub_801209C(u8); +static void SendDisconnectCommand(u32, u32); +static void Task_TryConnectToUnionRoomParent(u8); static void Debug_PrintEmpty(void); static void Task_Idle(u8); @@ -86,13 +122,13 @@ static const INIT_PARAM sRfuReqConfigTemplate = { .MC_TimerCount = 32, .availSlot_flag = 0, .mboot_flag = 0, - .serialNo = 2, - .gameName = (void *)&gHostRFUtgtGnameBuffer, - .userName = gHostRFUtgtUnameBuffer, + .serialNo = RFU_SERIAL_GAME, + .gameName = (void *)&gHostRfuGameData, + .userName = gHostRfuUsername, .fastSearchParent_flag = TRUE, .linkRecovery_enable = FALSE, .linkRecovery_period = 600, - .NI_failCounter_limit = 0x12c + .NI_failCounter_limit = 300 }; static const u8 sAvailSlots[] = { @@ -102,64 +138,97 @@ static const u8 sAvailSlots[] = { [4] = AVAIL_SLOT4 }; +#define BLOCK_MASK(bitNum)((1 << (bitNum)) - 1) static const u32 sAllBlocksReceived[] = { - 0x000000, - 0x000001, - 0x000003, - 0x000007, - 0x00000f, - 0x00001f, - 0x00003f, - 0x00007f, - 0x0000ff, - 0x0001ff, - 0x0003ff, - 0x0007ff, - 0x000fff, - 0x001fff, - 0x003fff, - 0x007fff, - 0x00ffff, - 0x01ffff, - 0x03ffff, - 0x07ffff, - 0x0fffff, - 0x1fffff, - 0x3fffff, - 0x7fffff, - 0xffffff + BLOCK_MASK(0), + BLOCK_MASK(1), + BLOCK_MASK(2), + BLOCK_MASK(3), + BLOCK_MASK(4), + BLOCK_MASK(5), + BLOCK_MASK(6), + BLOCK_MASK(7), + BLOCK_MASK(8), + BLOCK_MASK(9), + BLOCK_MASK(10), + BLOCK_MASK(11), + BLOCK_MASK(12), + BLOCK_MASK(13), + BLOCK_MASK(14), + BLOCK_MASK(15), + BLOCK_MASK(16), + BLOCK_MASK(17), + BLOCK_MASK(18), + BLOCK_MASK(19), + BLOCK_MASK(20), + BLOCK_MASK(21), + BLOCK_MASK(22), + BLOCK_MASK(23), + BLOCK_MASK(24), }; +#undef BLOCK_MASK -static const u8 sUnknown_082ED68C[] = { +static const u8 sSlotToLinkPlayerTableId[] = { 0, 0, 1, 1, 2, 2, 2, 2, 3 }; -static const u8 sUnknown_082ED695[] = { - 0, 1, 1, 2, - 1, 2, 2, 3, - 1, 2, 2, 3, - 2, 3, 3, 4 +// Effectively just returns the number of bits set in the index value +// Used for masks of the other players, MAX_RFU_PLAYERS - 1 excludes self +static const u8 sPlayerBitsToCount[1 << (MAX_RFU_PLAYERS - 1)] = { + 0, // 0000 + 1, // 0001 + 1, // 0010 + 2, // 0011 + 1, // 0100 + 2, // 0101 + 2, // 0110 + 3, // 0111 + 1, // 1000 + 2, // 1001 + 2, // 1010 + 3, // 1011 + 2, // 1100 + 3, // 1101 + 3, // 1110 + 4 // 1111 }; -static const u8 sUnknown_082ED6A5[] = { - 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 +// If the 4 bits representing child slots were an array, this table +// would return the index of the most recently set bit +static const u8 sPlayerBitsToNewChildIdx[1 << (MAX_RFU_PLAYERS - 1)] = { + 0, // 0000 + 0, // 0001 + 1, // 0010 + 0, // 0011 + 2, // 0100 + 0, // 0101 + 1, // 0110 + 0, // 0111 + 3, // 1000 + 0, // 1001 + 1, // 1010 + 0, // 1011 + 2, // 1100 + 0, // 1101 + 1, // 1110 + 0 // 1111 }; static const struct BlockRequest sBlockRequests[] = { - { gBlockSendBuffer, 200 }, - { gBlockSendBuffer, 200 }, - { gBlockSendBuffer, 100 }, - { gBlockSendBuffer, 220 }, - { gBlockSendBuffer, 40 } + [BLOCK_REQ_SIZE_NONE] = { gBlockSendBuffer, 200 }, + [BLOCK_REQ_SIZE_200] = { gBlockSendBuffer, 200 }, + [BLOCK_REQ_SIZE_100] = { gBlockSendBuffer, 100 }, + [BLOCK_REQ_SIZE_220] = { gBlockSendBuffer, 220 }, + [BLOCK_REQ_SIZE_40] = { gBlockSendBuffer, 40 } }; static const u16 sAcceptedSerialNos[] = { - 0x0002, - RFU_SERIAL_7F7D, - 0x0000, - 0xFFFF + RFU_SERIAL_GAME, + RFU_SERIAL_WONDER_DISTRIBUTOR, + RFU_SERIAL_UNKNOWN, + RFU_SERIAL_END }; static const char sASCII_RfuCmds[][15] = { @@ -184,21 +253,22 @@ static const char sASCII_RecoverCmds[][16] = { "RECOVER FAILED" }; -static const TaskFunc sUnknown_082ED7E0[] = { - sub_801084C, - Task_ExchangeLinkPlayers, - sub_8010D0C +// List of additional tasks to destroy (if active) when the RFU shuts down +static const TaskFunc sShutdownTasks[] = { + Task_PlayerExchange, + Task_PlayerExchangeUpdate, + Task_PlayerExchangeChat }; static const char sASCII_PokemonSioInfo[] = "PokemonSioInfo"; static const char sASCII_LinkLossDisconnect[] = "LINK LOSS DISCONNECT!"; static const char sASCII_LinkLossRecoveryNow[] = "LINK LOSS RECOVERY NOW"; -ALIGNED(4) static const char sASCII_30Commas[31] = {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','\0'}; -static const char sASCII_15Commas[16] = {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','\0'}; -static const char sASCII_8Commas[9] = {' ',' ',' ',' ',' ',' ',' ',' ','\0'}; -ALIGNED(4) static const char sASCII_Space[2] = {' ','\0'}; -static const char sASCII_Asterisk[2] = {'*','\0'}; -static const char sASCII_NowSlot[8] = "NOWSLOT"; +ALIGNED(4) static const char sASCII_30Spaces[] = {" "}; +static const char sASCII_15Spaces[] = {" "}; +static const char sASCII_8Spaces[] = {" "}; +ALIGNED(4) static const char sASCII_Space[] = {" "}; +static const char sASCII_Asterisk[] = {"*"}; +static const char sASCII_NowSlot[] = "NOWSLOT"; static const char sASCII_ClockCmds[][12] = { " ", @@ -208,7 +278,7 @@ static const char sASCII_ClockCmds[][12] = { "CLOCK SLAVE" }; -static const char sASCII_ChildParentSearch[3][8] = { +static const char sASCII_ChildParentSearch[][8] = { "CHILD ", "PARENT", "SEARCH" @@ -227,21 +297,17 @@ static void Debug_PrintNum(u16 num, u8 x, u8 y, u8 numDigits) void ResetLinkRfuGFLayer(void) { s32 i; - u8 errorState = Rfu.errorState; - CpuFill16(0, &Rfu, sizeof Rfu); - Rfu.errorState = errorState; - Rfu.parentChild = 0xFF; - if (Rfu.errorState != 4) - { - Rfu.errorState = 0; - } + u8 errorState = gRfu.errorState; + CpuFill16(0, &gRfu, sizeof(gRfu)); + gRfu.errorState = errorState; + gRfu.parentChild = 0xFF; + if (gRfu.errorState != RFU_ERROR_STATE_IGNORE) + gRfu.errorState = RFU_ERROR_STATE_NONE; for (i = 0; i < MAX_RFU_PLAYERS; i++) - { - ResetSendDataManager(&Rfu.recvBlock[i]); - } - ResetSendDataManager(&Rfu.sendBlock); - RfuRecvQueue_Reset(&Rfu.recvQueue); - RfuSendQueue_Reset(&Rfu.sendQueue); + ResetSendDataManager(&gRfu.recvBlock[i]); + ResetSendDataManager(&gRfu.sendBlock); + RfuRecvQueue_Reset(&gRfu.recvQueue); + RfuSendQueue_Reset(&gRfu.sendQueue); CpuFill16(0, gSendCmd, sizeof gSendCmd); CpuFill16(0, gRecvCmds, sizeof gRecvCmds); CpuFill16(0, gLinkPlayers, sizeof gLinkPlayers); @@ -262,158 +328,159 @@ void InitRFU(void) void InitRFUAPI(void) { - if (!rfu_initializeAPI((void *)gf_rfu_REQ_api, sizeof gf_rfu_REQ_api, gIntrTable + 1, TRUE)) + if (!rfu_initializeAPI((void *)gRfuAPIBuffer, sizeof(gRfuAPIBuffer), &gIntrTable[1], TRUE)) { gLinkType = 0; ClearSavedLinkPlayers(); - sub_80111B0(FALSE); + RfuSetIgnoreError(FALSE); ResetLinkRfuGFLayer(); - rfu_setTimerInterrupt(3, gIntrTable + 2); + rfu_setTimerInterrupt(3, &gIntrTable[2]); } } -static void Task_LinkLeaderSearchForChildren(u8 taskId) +static void Task_ParentSearchForChildren(u8 taskId) { UpdateChildStatuses(); - switch (Rfu.state) + switch (gRfu.state) { - case 0: + case RFUSTATE_INIT: rfu_LMAN_initializeRFU(&sRfuReqConfig); - Rfu.state = 1; + gRfu.state = RFUSTATE_INIT_END; gTasks[taskId].data[1] = 1; break; - case 1: + case RFUSTATE_INIT_END: break; - case 2: - rfu_LMAN_establishConnection(Rfu.parentChild, 0, 240, (u16 *)sAcceptedSerialNos); - Rfu.state = 3; + case RFUSTATE_PARENT_CONNECT: + rfu_LMAN_establishConnection(gRfu.parentChild, 0, 240, (u16 *)sAcceptedSerialNos); + gRfu.state = RFUSTATE_PARENT_CONNECT_END; gTasks[taskId].data[1] = 6; break; - case 3: + case RFUSTATE_PARENT_CONNECT_END: break; - case 4: + case RFUSTATE_STOP_MANAGER: rfu_LMAN_stopManager(FALSE); - Rfu.state = 5; + gRfu.state = RFUSTATE_STOP_MANAGER_END; break; - case 5: + case RFUSTATE_STOP_MANAGER_END: break; - case 18: - Rfu.unk_cdb = FALSE; - rfu_LMAN_setMSCCallback(sub_800EDBC); - sub_800EAB4(); - sub_800EAFC(); - Rfu.state = 20; + case RFUSTATE_PARENT_FINALIZE: + gRfu.parentFinished = FALSE; + rfu_LMAN_setMSCCallback(MSCCallback_Parent); + InitChildRecvBuffers(); + InitParentSendData(); + gRfu.state = RFUSTATE_FINALIZED; gTasks[taskId].data[1] = 8; - CreateTask(sub_801084C, 5); + CreateTask(Task_PlayerExchange, 5); DestroyTask(taskId); break; } } -s32 sub_800E87C(u8 idx) +s32 Rfu_GetIndexOfNewestChild(u8 bits) { - return sUnknown_082ED6A5[idx]; + return sPlayerBitsToNewChildIdx[bits]; } -void sub_800E88C(s32 r2, s32 r5) +static void SetLinkPlayerIdsFromSlots(s32 baseSlots, s32 addSlots) { u8 i; - u8 r4 = 1; - s32 r1 = r2; - s32 r6 = 0; - if (r5 == -1) + u8 baseId = 1; + s32 baseSlotsCopy = baseSlots; + s32 newId = 0; + if (addSlots == -1) { - for (i = 0; i < RFU_CHILD_MAX; r2 >>= 1, i++) + // Initialize + for (i = 0; i < RFU_CHILD_MAX; baseSlots >>= 1, i++) { - if (r2 & 1) + if (baseSlots & 1) { - Rfu.linkPlayerIdx[i] = r4; - r4++; + gRfu.linkPlayerIdx[i] = baseId; + baseId++; } } } else { - for (i = 0; i < RFU_CHILD_MAX; r1 >>= 1, i++) + // Clear id for any empty slot + for (i = 0; i < RFU_CHILD_MAX; baseSlotsCopy >>= 1, i++) { - if (!(r1 & 1)) - { - Rfu.linkPlayerIdx[i] = 0; - } + if (!(baseSlotsCopy & 1)) + gRfu.linkPlayerIdx[i] = 0; } - for (r4 = RFU_CHILD_MAX; r4 != 0; r4--) + + // Get starting id by checking existing slots + for (baseId = RFU_CHILD_MAX; baseId != 0; baseId--) { - for (i = 0; i < RFU_CHILD_MAX && Rfu.linkPlayerIdx[i] != r4; i++); + for (i = 0; i < RFU_CHILD_MAX && gRfu.linkPlayerIdx[i] != baseId; i++) + ; if (i == RFU_CHILD_MAX) - { - r6 = r4; - } + newId = baseId; } - for (r5 &= ~r2, i = 0; i < RFU_CHILD_MAX; r5 >>= 1, i++) + + // Set id for new slots + for (addSlots &= ~baseSlots, i = 0; i < RFU_CHILD_MAX; addSlots >>= 1, i++) { - if (r5 & 1) - { - Rfu.linkPlayerIdx[i] = r6++; - } + if (addSlots & 1) + gRfu.linkPlayerIdx[i] = newId++; } } } -static void Task_JoinGroupSearchForParent(u8 taskId) +static void Task_ChildSearchForParent(u8 taskId) { - switch (Rfu.state) + switch (gRfu.state) { - case 0: + case RFUSTATE_INIT: rfu_LMAN_initializeRFU((INIT_PARAM *)&sRfuReqConfigTemplate); - Rfu.state = 1; + gRfu.state = RFUSTATE_INIT_END; gTasks[taskId].data[1] = 1; break; - case 1: + case RFUSTATE_INIT_END: break; - case 6: - rfu_LMAN_establishConnection(Rfu.parentChild, 0, 240, (u16 *)sAcceptedSerialNos); - Rfu.state = 7; + case RFUSTATE_CHILD_CONNECT: + rfu_LMAN_establishConnection(gRfu.parentChild, 0, 240, (u16 *)sAcceptedSerialNos); + gRfu.state = RFUSTATE_CHILD_CONNECT_END; gTasks[taskId].data[1] = 7; break; - case 7: + case RFUSTATE_CHILD_CONNECT_END: break; - case 9: + case RFUSTATE_RECONNECTED: gTasks[taskId].data[1] = 10; break; - case 11: - switch (sub_80107A0()) + case RFUSTATE_CHILD_TRY_JOIN: + switch (GetJoinGroupStatus()) { case RFU_STATUS_JOIN_GROUP_OK: - Rfu.state = 12; + gRfu.state = RFUSTATE_CHILD_JOINED; break; case RFU_STATUS_JOIN_GROUP_NO: case RFU_STATUS_LEAVE_GROUP: rfu_LMAN_requestChangeAgbClockMaster(); - Rfu.unk_ce4 = 2; + gRfu.disconnectMode = RFU_DISCONNECT_NORMAL; DestroyTask(taskId); break; } break; - case 12: + case RFUSTATE_CHILD_JOINED: { - u8 bmChildSlot = 1 << Rfu.childSlot; - rfu_clearSlot(TYPE_NI_SEND | TYPE_NI_RECV, Rfu.childSlot); - rfu_setRecvBuffer(TYPE_UNI, Rfu.childSlot, Rfu.unk_c3f, 70); - rfu_UNI_setSendData(bmChildSlot, Rfu.unk_4c, sizeof(Rfu.unk_4c)); + u8 bmChildSlot = 1 << gRfu.childSlot; + rfu_clearSlot(TYPE_NI_SEND | TYPE_NI_RECV, gRfu.childSlot); + rfu_setRecvBuffer(TYPE_UNI, gRfu.childSlot, gRfu.childRecvQueue, sizeof(gRfu.childRecvQueue)); + rfu_UNI_setSendData(bmChildSlot, gRfu.childSendBuffer, sizeof(gRfu.childSendBuffer)); gTasks[taskId].data[1] = 8; DestroyTask(taskId); - if (sRfuDebug.unk_0f == 0) + if (sRfuDebug.childJoinCount == 0) { Debug_PrintEmpty(); - sRfuDebug.unk_0f++; + sRfuDebug.childJoinCount++; } - CreateTask(sub_801084C, 5); + CreateTask(Task_PlayerExchange, 5); break; } } } -static void sub_800EAB4(void) +static void InitChildRecvBuffers(void) { u8 i; u8 acceptSlot = lman.acceptSlot_flag; @@ -421,79 +488,77 @@ static void sub_800EAB4(void) { if (acceptSlot & 1) { - rfu_setRecvBuffer(TYPE_UNI, i, Rfu.unk_14[i], 14); + rfu_setRecvBuffer(TYPE_UNI, i, gRfu.childRecvBuffer[i], sizeof(gRfu.childRecvBuffer[0])); rfu_clearSlot(TYPE_UNI_SEND | TYPE_UNI_RECV, i); } acceptSlot >>= 1; } } -static void sub_800EAFC(void) +static void InitParentSendData(void) { u8 acceptSlot = lman.acceptSlot_flag; - rfu_UNI_setSendData(acceptSlot, Rfu.recvCmds, 70); - Rfu.unk_cda = sub_800E87C(acceptSlot); - Rfu.unk_ce2 = acceptSlot; - sub_800E88C(acceptSlot, -1); - Rfu.parentChild = MODE_PARENT; + rfu_UNI_setSendData(acceptSlot, gRfu.recvCmds, sizeof(gRfu.recvCmds)); + gRfu.parentSendSlot = Rfu_GetIndexOfNewestChild(acceptSlot); + gRfu.parentSlots = acceptSlot; + SetLinkPlayerIdsFromSlots(acceptSlot, -1); + gRfu.parentChild = MODE_PARENT; } -static void Task_LinkRfu_UnionRoomListen(u8 taskId) +#define tConnectingForChat data[7] + +static void Task_UnionRoomListen(u8 taskId) { - if (GetHostRFUtgtGname()->activity == (ACTIVITY_PLYRTALK | IN_UNION_ROOM) && RfuGetStatus() == RFU_STATUS_NEW_CHILD_DETECTED) + if (GetHostRfuGameData()->activity == (ACTIVITY_PLYRTALK | IN_UNION_ROOM) && RfuGetStatus() == RFU_STATUS_NEW_CHILD_DETECTED) { rfu_REQ_disconnect(lman.acceptSlot_flag); rfu_waitREQComplete(); RfuSetStatus(RFU_STATUS_OK, 0); } - switch (Rfu.state) + switch (gRfu.state) { - case 0: + case RFUSTATE_INIT: rfu_LMAN_initializeRFU(&sRfuReqConfig); - Rfu.state = 1; + gRfu.state = RFUSTATE_INIT_END; gTasks[taskId].data[1] = 1; break; - case 1: + case RFUSTATE_INIT_END: break; - case 17: - rfu_LMAN_establishConnection(2, 0, 240, (u16 *)sAcceptedSerialNos); - rfu_LMAN_setMSCCallback(sub_800ED34); - Rfu.state = 18; + case RFUSTATE_UR_CONNECT: + rfu_LMAN_establishConnection(MODE_P_C_SWITCH, 0, 240, (u16 *)sAcceptedSerialNos); + rfu_LMAN_setMSCCallback(MSCCallback_Child); + gRfu.state = RFUSTATE_UR_CONNECT_END; break; - case 18: + case RFUSTATE_UR_CONNECT_END: break; - case 13: - if (rfu_UNI_setSendData(1 << Rfu.childSlot, Rfu.unk_4c, sizeof(Rfu.unk_4c)) == 0) + case RFUSTATE_UR_PLAYER_EXCHANGE: + if (rfu_UNI_setSendData(1 << gRfu.childSlot, gRfu.childSendBuffer, sizeof(gRfu.childSendBuffer)) == 0) { - Rfu.parentChild = MODE_CHILD; + gRfu.parentChild = MODE_CHILD; DestroyTask(taskId); - if (gTasks[taskId].data[7]) - { - CreateTask(sub_8010D0C, 1); - } + if (gTasks[taskId].tConnectingForChat) + CreateTask(Task_PlayerExchangeChat, 1); else - { - CreateTask(sub_801084C, 5); - } + CreateTask(Task_PlayerExchange, 5); } break; - case 14: - rfu_LMAN_stopManager(0); - Rfu.state = 15; + case RFUSTATE_UR_STOP_MANAGER: + rfu_LMAN_stopManager(FALSE); + gRfu.state = RFUSTATE_UR_STOP_MANAGER_END; break; - case 15: + case RFUSTATE_UR_STOP_MANAGER_END: break; - case 16: - Rfu.unk_cdb = FALSE; - rfu_LMAN_setMSCCallback(sub_800EDBC); + case RFUSTATE_UR_FINALIZE: + gRfu.parentFinished = FALSE; + rfu_LMAN_setMSCCallback(MSCCallback_Parent); UpdateGameData_GroupLockedIn(TRUE); - sub_800EAB4(); - sub_800EAFC(); - Rfu.state = 20; + InitChildRecvBuffers(); + InitParentSendData(); + gRfu.state = RFUSTATE_FINALIZED; gTasks[taskId].data[1] = 8; - Rfu.parentChild = MODE_PARENT; - CreateTask(sub_801084C, 5); - Rfu.unk_ce8 = TRUE; + gRfu.parentChild = MODE_PARENT; + CreateTask(Task_PlayerExchange, 5); + gRfu.playerExchangeActive = TRUE; DestroyTask(taskId); break; } @@ -509,31 +574,32 @@ void LinkRfu_StopManagerBeforeEnteringChat(void) rfu_LMAN_stopManager(FALSE); } -static void sub_800ED34(u16 unused) +// Argument is provided by the RFU and is unused. +static void MSCCallback_Child(u16 REQ_commandID) { s32 i; - for (i = 0; i < (int)ARRAY_COUNT(Rfu.unk_4c); i++) - { - Rfu.unk_4c[i] = 0; - } + for (i = 0; i < COMM_SLOT_LENGTH; i++) + gRfu.childSendBuffer[i] = 0; + rfu_REQ_recvData(); rfu_waitREQComplete(); - if (gRfuSlotStatusUNI[Rfu.childSlot]->recv.newDataFlag) + if (gRfuSlotStatusUNI[gRfu.childSlot]->recv.newDataFlag) { - Rfu.unk_cd0++; - RfuRecvQueue_Enqueue(&Rfu.recvQueue, Rfu.unk_c3f); - sRfuDebug.unk_06++; + gRfu.childSendCount++; + RfuRecvQueue_Enqueue(&gRfu.recvQueue, gRfu.childRecvQueue); + sRfuDebug.recvCount++; UpdateBackupQueue(); - rfu_UNI_readySendData(Rfu.childSlot); - rfu_UNI_clearRecvNewDataFlag(Rfu.childSlot); + rfu_UNI_readySendData(gRfu.childSlot); + rfu_UNI_clearRecvNewDataFlag(gRfu.childSlot); } rfu_LMAN_REQ_sendData(TRUE); } -static void sub_800EDBC(u16 unused) +// Argument is provided by the RFU and is unused. +static void MSCCallback_Parent(u16 REQ_commandID) { - Rfu.unk_cdb = TRUE; + gRfu.parentFinished = TRUE; } void LinkRfu_Shutdown(void) @@ -541,158 +607,156 @@ void LinkRfu_Shutdown(void) u8 i; rfu_LMAN_powerDownRFU(); - if (Rfu.parentChild == MODE_PARENT) + if (gRfu.parentChild == MODE_PARENT) { - if (FuncIsActiveTask(Task_LinkLeaderSearchForChildren) == TRUE) + // Stop parent searching for children + if (FuncIsActiveTask(Task_ParentSearchForChildren) == TRUE) { - DestroyTask(Rfu.searchTaskId); + DestroyTask(gRfu.searchTaskId); ResetLinkRfuGFLayer(); } } - else if (Rfu.parentChild == MODE_CHILD) + else if (gRfu.parentChild == MODE_CHILD) { - if (FuncIsActiveTask(Task_JoinGroupSearchForParent) == TRUE) + // Stop child searching for parent + if (FuncIsActiveTask(Task_ChildSearchForParent) == TRUE) { - DestroyTask(Rfu.searchTaskId); + DestroyTask(gRfu.searchTaskId); ResetLinkRfuGFLayer(); } } - else if (Rfu.parentChild == 2) + else if (gRfu.parentChild == MODE_P_C_SWITCH) { - if (FuncIsActiveTask(Task_LinkRfu_UnionRoomListen) == TRUE) + // Stop parent-child switching mode (union room) + if (FuncIsActiveTask(Task_UnionRoomListen) == TRUE) { - DestroyTask(Rfu.searchTaskId); + DestroyTask(gRfu.searchTaskId); ResetLinkRfuGFLayer(); } } - for (i = 0; i < ARRAY_COUNT(sUnknown_082ED7E0); i++) + + // Destroy additional tasks + for (i = 0; i < ARRAY_COUNT(sShutdownTasks); i++) { - if (FuncIsActiveTask(sUnknown_082ED7E0[i]) == TRUE) - { - DestroyTask(FindTaskIdByFunc(sUnknown_082ED7E0[i])); - } + if (FuncIsActiveTask(sShutdownTasks[i]) == TRUE) + DestroyTask(FindTaskIdByFunc(sShutdownTasks[i])); } } -static void CreateTask_LinkLeaderSearchForChildren(void) +static void CreateTask_ParentSearchForChildren(void) { - Rfu.searchTaskId = CreateTask(Task_LinkLeaderSearchForChildren, 1); + gRfu.searchTaskId = CreateTask(Task_ParentSearchForChildren, 1); } -static bool8 sub_800EE94(void) +// If no parent ID (or if child connection not ready) can't reconnect with parent yet +static bool8 CanTryReconnectParent(void) { - if (Rfu.state == 7 && Rfu.parentId) + if (gRfu.state == RFUSTATE_CHILD_CONNECT_END && gRfu.parentId) + return TRUE; + return FALSE; +} + +static bool32 TryReconnectParent(void) +{ + if (gRfu.state == RFUSTATE_CHILD_CONNECT_END && !rfu_LMAN_CHILD_connectParent(gRfuLinkStatus->partner[gRfu.reconnectParentId].id, 240)) { + gRfu.state = RFUSTATE_RECONNECTED; return TRUE; } return FALSE; } -static bool32 IsParentSuccessfullyReconnected(void) +static void CreateTask_ChildSearchForParent(void) { - if (Rfu.state == 7 && !rfu_LMAN_CHILD_connectParent(gRfuLinkStatus->partner[Rfu.unk_c3d].id, 240)) - { - Rfu.state = 9; - return TRUE; - } - return FALSE; -} - -static void CreateTask_JoinGroupSearchForParent(void) -{ - Rfu.searchTaskId = CreateTask(Task_JoinGroupSearchForParent, 1); + gRfu.searchTaskId = CreateTask(Task_ChildSearchForParent, 1); } bool8 LmanAcceptSlotFlagIsNotZero(void) { if (lman.acceptSlot_flag) - { return TRUE; - } return FALSE; } void LinkRfu_StopManagerAndFinalizeSlots(void) { - Rfu.state = 4; - Rfu.acceptSlot_flag = lman.acceptSlot_flag; + gRfu.state = RFUSTATE_STOP_MANAGER; + gRfu.acceptSlot_flag = lman.acceptSlot_flag; } bool32 WaitRfuState(bool32 force) { - if (Rfu.state == 17 || force) + if (gRfu.state == RFUSTATE_PARENT_FINALIZE_START || force) { - Rfu.state = 18; + gRfu.state = RFUSTATE_PARENT_FINALIZE; return TRUE; } return FALSE; } -void sub_800EF7C(void) +void StopUnionRoomLinkManager(void) { - Rfu.state = 14; + gRfu.state = RFUSTATE_UR_STOP_MANAGER; } -static void sub_800EF88(u8 a0) +// Unused +static void ReadySendDataForSlots(u8 slots) { u8 i; for (i = 0; i < RFU_CHILD_MAX; i++) { - if (a0 & 1) + if (slots & 1) { rfu_UNI_readySendData(i); break; } - a0 >>= 1; + slots >>= 1; } } -static void sub_800EFB0(void) +static void ReadAllPlayerRecvCmds(void) { s32 i, j; - for (i = 0; i < 5; i++) + for (i = 0; i < MAX_RFU_PLAYERS; i++) { - struct GFRfuManager *ptr = &Rfu; - for (j = 0; j < 7; j++) + struct RfuManager *rfu = &gRfu; + for (j = 0; j < CMD_LENGTH - 1; j++) { - ptr->recvCmds[i][j][1] = gRecvCmds[i][j] >> 8; - ptr->recvCmds[i][j][0] = gRecvCmds[i][j]; + rfu->recvCmds[i][j][1] = gRecvCmds[i][j] >> 8; + rfu->recvCmds[i][j][0] = gRecvCmds[i][j]; } } CpuFill16(0, gRecvCmds, sizeof gRecvCmds); } -static void sub_800F014(void) +static void MoveSendCmdToRecv(void) { s32 i; for (i = 0; i < CMD_LENGTH - 1; i++) - { gRecvCmds[0][i] = gSendCmd[i]; - } + for (i = 0; i < CMD_LENGTH - 1; i++) - { gSendCmd[i] = 0; - } } static void UpdateBackupQueue(void) { - if (Rfu.linkRecovered) + if (gRfu.linkRecovered) { - bool8 backupEmpty = RfuBackupQueue_Dequeue(&Rfu.backupQueue, Rfu.unk_4c); + bool8 backupEmpty = RfuBackupQueue_Dequeue(&gRfu.backupQueue, gRfu.childSendBuffer); - if (Rfu.backupQueue.count == 0) - Rfu.linkRecovered = FALSE; + if (gRfu.backupQueue.count == 0) + gRfu.linkRecovered = FALSE; if (backupEmpty) return; } - if (!Rfu.linkRecovered) + if (!gRfu.linkRecovered) { - RfuSendQueue_Dequeue(&Rfu.sendQueue, Rfu.unk_4c); - RfuBackupQueue_Enqueue(&Rfu.backupQueue, Rfu.unk_4c); + RfuSendQueue_Dequeue(&gRfu.sendQueue, gRfu.childSendBuffer); + RfuBackupQueue_Enqueue(&gRfu.backupQueue, gRfu.childSendBuffer); } } @@ -701,26 +765,20 @@ bool32 IsRfuRecvQueueEmpty(void) s32 i; s32 j; - if (gRfuLinkStatus->sendSlotUNIFlag == 0) - { + if (!gRfuLinkStatus->sendSlotUNIFlag) return FALSE; - } + for (i = 0; i < MAX_RFU_PLAYERS; i++) - { for (j = 0; j < CMD_LENGTH - 1; j++) - { if (gRecvCmds[i][j] != 0) - { return FALSE; - } - } - } + return TRUE; } -static bool32 sub_800F0F8(void) +static bool32 RfuMain1_Parent(void) { - if (Rfu.state < 20) + if (gRfu.state < RFUSTATE_FINALIZED) { rfu_REQ_recvData(); rfu_waitREQComplete(); @@ -728,19 +786,19 @@ static bool32 sub_800F0F8(void) } else { - Rfu.unk_cdb = FALSE; - if ((Rfu.unk_ce2 & gRfuLinkStatus->connSlotFlag) == Rfu.unk_ce2 && (Rfu.unk_ce2 & gRfuLinkStatus->connSlotFlag)) + gRfu.parentFinished = FALSE; + if ((gRfu.parentSlots & gRfuLinkStatus->connSlotFlag) == gRfu.parentSlots && (gRfu.parentSlots & gRfuLinkStatus->connSlotFlag)) { - if (!Rfu.unk_cdc) + if (!gRfu.parentMain2Failed) { - if (Rfu.unk_ce3) + if (gRfu.disconnectSlots) { - RfuReqDisconnectSlot(Rfu.unk_ce3); - Rfu.unk_ce3 = 0; - if (Rfu.unk_ce4 == 1) + RfuReqDisconnectSlot(gRfu.disconnectSlots); + gRfu.disconnectSlots = 0; + if (gRfu.disconnectMode == RFU_DISCONNECT_ERROR) { - RfuSetStatus(RFU_STATUS_CONNECTION_ERROR, 0x8000); - GetLinkmanErrorParams(0x8000); + RfuSetStatus(RFU_STATUS_CONNECTION_ERROR, F_RFU_ERROR_8); + RfuSetErrorParams(F_RFU_ERROR_8); return FALSE; } if (!lman.acceptSlot_flag) @@ -750,67 +808,65 @@ static bool32 sub_800F0F8(void) return FALSE; } } - sub_800EFB0(); - rfu_UNI_readySendData(Rfu.unk_cda); + ReadAllPlayerRecvCmds(); + rfu_UNI_readySendData(gRfu.parentSendSlot); rfu_LMAN_REQ_sendData(TRUE); } else { rfu_REQ_PARENT_resumeRetransmitAndChange(); } - Rfu.unk_0e = TRUE; + gRfu.runParentMain2 = TRUE; } } return FALSE; } -static bool32 sub_800F1E0(void) +static bool32 RfuMain2_Parent(void) { u16 i; u16 flags; u8 r0; u16 j; - u8 retval; + bool8 failed; - if (Rfu.state >= 20 && Rfu.unk_0e == TRUE) + if (gRfu.state >= RFUSTATE_FINALIZED && gRfu.runParentMain2 == TRUE) { rfu_waitREQComplete(); - while (Rfu.unk_cdb == FALSE) + while (gRfu.parentFinished == FALSE) { - if (Rfu.errorState != 0) - { + if (gRfu.errorState != RFU_ERROR_STATE_NONE) return FALSE; - } } rfu_REQ_recvData(); rfu_waitREQComplete(); - if ((lman.parentAck_flag & Rfu.unk_ce2) == Rfu.unk_ce2) + if ((lman.parentAck_flag & gRfu.parentSlots) == gRfu.parentSlots) { - Rfu.unk_cdc = FALSE; - sRfuDebug.unk_06++; + gRfu.parentMain2Failed = FALSE; + sRfuDebug.recvCount++; flags = lman.acceptSlot_flag; for (i = 0; i < RFU_CHILD_MAX; i++) { if (flags & 1) { - if (Rfu.unk_14[i][1]) + if (gRfu.childRecvBuffer[i][1]) { - if (Rfu.unk_cee[i] != 0xFF && (Rfu.unk_14[i][0] >> 5) != ((Rfu.unk_cee[i] + 1) & 7)) + if (gRfu.childRecvIds[i] != 0xFF && (gRfu.childRecvBuffer[i][0] >> 5) != ((gRfu.childRecvIds[i] + 1) & 7)) { - if (++Rfu.unk_cea[i] > 4) - GetLinkmanErrorParams(0x8100); + if (++gRfu.numChildRecvErrors[i] > 4) + RfuSetErrorParams(F_RFU_ERROR_8 | F_RFU_ERROR_1); } else { - Rfu.unk_cee[i] = Rfu.unk_14[i][0] / 32; - Rfu.unk_cea[i] = 0; - Rfu.unk_14[i][0] &= 0x1f; - r0 = Rfu.linkPlayerIdx[i]; - for (j = 0; j < 7; j++) + gRfu.childRecvIds[i] = gRfu.childRecvBuffer[i][0] / 32; + gRfu.numChildRecvErrors[i] = 0; + gRfu.childRecvBuffer[i][0] &= 0x1f; + r0 = gRfu.linkPlayerIdx[i]; + for (j = 0; j < CMD_LENGTH - 1; j++) { - gRecvCmds[r0][j] = (Rfu.unk_14[i][(j << 1) + 1] << 8) | Rfu.unk_14[i][(j << 1) + 0]; - Rfu.unk_14[i][(j << 1) + 1] = 0; - Rfu.unk_14[i][(j << 1) + 0] = 0; + gRecvCmds[r0][j] = (gRfu.childRecvBuffer[i][(j << 1) + 1] << 8) | gRfu.childRecvBuffer[i][(j << 1) + 0]; + gRfu.childRecvBuffer[i][(j << 1) + 1] = 0; + gRfu.childRecvBuffer[i][(j << 1) + 0] = 0; } } } @@ -818,102 +874,99 @@ static bool32 sub_800F1E0(void) } flags >>= 1; } - sub_800F014(); + MoveSendCmdToRecv(); RfuHandleReceiveCommand(0); CallRfuFunc(); - if (Rfu.unk_ce5 && !Rfu.unk_cd9) + if (gRfu.nextChildBits && !gRfu.stopNewConnections) { - sRfuDebug.unk_0e = FALSE; - rfu_clearSlot(TYPE_UNI_SEND | TYPE_UNI_RECV, Rfu.unk_cda); + sRfuDebug.unkFlag = FALSE; + rfu_clearSlot(TYPE_UNI_SEND | TYPE_UNI_RECV, gRfu.parentSendSlot); for (i = 0; i < RFU_CHILD_MAX; i++) { - if ((Rfu.unk_ce5 >> i) & 1) - { - rfu_setRecvBuffer(TYPE_UNI, i, Rfu.unk_14[i], 14); - } + if ((gRfu.nextChildBits >> i) & 1) + rfu_setRecvBuffer(TYPE_UNI, i, gRfu.childRecvBuffer[i], sizeof(gRfu.childRecvBuffer[0])); } - sub_800E88C(Rfu.unk_ce2, Rfu.unk_ce2 | Rfu.unk_ce5); - Rfu.unk_ce9 = Rfu.unk_ce5; - Rfu.unk_ce2 |= Rfu.unk_ce5; - Rfu.unk_ce5 = 0; - rfu_UNI_setSendData(Rfu.unk_ce2, Rfu.recvCmds, 70); - Rfu.unk_cda = sub_800E87C(Rfu.unk_ce2); - CreateTask(Task_ExchangeLinkPlayers, 0); + SetLinkPlayerIdsFromSlots(gRfu.parentSlots, gRfu.parentSlots | gRfu.nextChildBits); + gRfu.incomingChild = gRfu.nextChildBits; + gRfu.parentSlots |= gRfu.nextChildBits; + gRfu.nextChildBits = 0; + rfu_UNI_setSendData(gRfu.parentSlots, gRfu.recvCmds, sizeof(gRfu.recvCmds)); + gRfu.parentSendSlot = Rfu_GetIndexOfNewestChild(gRfu.parentSlots); + CreateTask(Task_PlayerExchangeUpdate, 0); } } else { - Rfu.unk_cdc = TRUE; - Rfu.unk_0e = FALSE; + gRfu.parentMain2Failed = TRUE; + gRfu.runParentMain2 = FALSE; } - Rfu.unk_0e = FALSE; + gRfu.runParentMain2 = FALSE; } - retval = Rfu.unk_cdc; - return gRfuLinkStatus->sendSlotUNIFlag ? retval & 1 : FALSE; + failed = gRfu.parentMain2Failed; + return gRfuLinkStatus->sendSlotUNIFlag ? failed & 1 : FALSE; } -static void sub_800F498(u16 *a0, u8 *a1) +static void ChildBuildSendCmd(u16 *sendCmd, u8 *dst) { s32 i; - if (a0[0]) + if (sendCmd[0]) { - a0[0] |= (Rfu.unk_102 << 5); - Rfu.unk_102 = (Rfu.unk_102 + 1) & 7; - for (i = 0; i < 7; i++) + sendCmd[0] |= (gRfu.childSendCmdId << 5); + gRfu.childSendCmdId = (gRfu.childSendCmdId + 1) & 7; + for (i = 0; i < CMD_LENGTH - 1; i++) { - a1[2 * i + 1] = a0[i] >> 8; - a1[2 * i + 0] = a0[i]; + dst[2 * i + 1] = sendCmd[i] >> 8; + dst[2 * i + 0] = sendCmd[i]; } } else { - for (i = 0; i < 14; i++) - a1[i] = 0; + for (i = 0; i < COMM_SLOT_LENGTH; i++) + dst[i] = 0; } } -static bool32 RfuProcessEnqueuedRecvBlock(void) +static bool32 RfuMain1_Child(void) { u8 i; u8 j; - u8 sp00[MAX_RFU_PLAYERS * (2 * (CMD_LENGTH - 1))]; - u8 sp48[2 * (CMD_LENGTH - 1)]; + u8 recv[MAX_RFU_PLAYERS * (2 * (CMD_LENGTH - 1))]; + u8 send[2 * (CMD_LENGTH - 1)]; u8 status; - RfuRecvQueue_Dequeue(&Rfu.recvQueue, sp00); + RfuRecvQueue_Dequeue(&gRfu.recvQueue, recv); for (i = 0; i < MAX_RFU_PLAYERS; i++) { for (j = 0; j < CMD_LENGTH - 1; j++) - { - gRecvCmds[i][j] = (sp00[i * 14 + (j << 1) + 1] << 8) | sp00[i * 14 + (j << 1) + 0]; - } + gRecvCmds[i][j] = (recv[i * COMM_SLOT_LENGTH + (j * 2) + 1] << 8) + | recv[i * COMM_SLOT_LENGTH + (j * 2) + 0]; } RfuHandleReceiveCommand(0); - if (lman.childClockSlave_flag == 0 && Rfu.unk_ce4) + if (lman.childClockSlave_flag == 0 && gRfu.disconnectMode != RFU_DISCONNECT_NONE) { rfu_REQ_disconnect(gRfuLinkStatus->connSlotFlag | gRfuLinkStatus->linkLossSlotFlag); rfu_waitREQComplete(); status = RfuGetStatus(); if (status != RFU_STATUS_FATAL_ERROR && status != RFU_STATUS_JOIN_GROUP_NO && status != RFU_STATUS_LEAVE_GROUP) - RfuSetStatus(RFU_STATUS_CONNECTION_ERROR, 0x9000); + RfuSetStatus(RFU_STATUS_CONNECTION_ERROR, F_RFU_ERROR_5 | F_RFU_ERROR_8); rfu_clearAllSlot(); gReceivedRemoteLinkPlayers = FALSE; - Rfu.callback = NULL; - if (Rfu.unk_ce4 == 1) + gRfu.callback = NULL; + if (gRfu.disconnectMode == RFU_DISCONNECT_ERROR) { - RfuSetStatus(RFU_STATUS_CONNECTION_ERROR, 0x9000); - GetLinkmanErrorParams(0x9000); + RfuSetStatus(RFU_STATUS_CONNECTION_ERROR, F_RFU_ERROR_5 | F_RFU_ERROR_8); + RfuSetErrorParams(F_RFU_ERROR_5 | F_RFU_ERROR_8); } lman.state = lman.next_state = 0; - Rfu.unk_ce4 = 0; + gRfu.disconnectMode = RFU_DISCONNECT_NONE; } - if (Rfu.unk_cd0) + if (gRfu.childSendCount) { - Rfu.unk_cd0--; + gRfu.childSendCount--; CallRfuFunc(); - sub_800F498(gSendCmd, sp48); - RfuSendQueue_Enqueue(&Rfu.sendQueue, sp48); + ChildBuildSendCmd(gSendCmd, send); + RfuSendQueue_Enqueue(&gRfu.sendQueue, send); for (i = 0; i < CMD_LENGTH - 1; i++) gSendCmd[i] = 0; } @@ -924,25 +977,26 @@ static void HandleSendFailure(u8 unused, u32 flags) { s32 i, j, temp; - const u8 *r10 = Rfu.sendBlock.payload; - for (i = 0; i < Rfu.sendBlock.count; i++) + const u8 *payload = gRfu.sendBlock.payload; + for (i = 0; i < gRfu.sendBlock.count; i++) { if (!(flags & 1)) { - sResendBlock16[0] = RFUCMD_0x8900 | i; - for (j = 0; j < 7; j++) + sResendBlock16[0] = RFUCMD_SEND_BLOCK | i; + for (j = 0; j < CMD_LENGTH - 1; j++) { - temp = j << 1; - sResendBlock16[j + 1] = (r10[12 * i + temp + 1] << 8) | r10[12 * i + temp + 0]; + temp = j * 2; + sResendBlock16[j + 1] = (payload[(COMM_SLOT_LENGTH - 2) * i + temp + 1] << 8) + | payload[(COMM_SLOT_LENGTH - 2) * i + temp + 0]; } - for (j = 0; j < 7; j++) + for (j = 0; j < CMD_LENGTH - 1; j++) { - temp = j << 1; + temp = j * 2; sResendBlock8[temp + 1] = sResendBlock16[j] >> 8; sResendBlock8[temp + 0] = sResendBlock16[j]; } - RfuSendQueue_Enqueue(&Rfu.sendQueue, sResendBlock8); - Rfu.sendBlock.failedFlags |= (1 << i); + RfuSendQueue_Enqueue(&gRfu.sendQueue, sResendBlock8); + gRfu.sendBlock.failedFlags |= (1 << i); } flags >>= 1; } @@ -950,32 +1004,30 @@ static void HandleSendFailure(u8 unused, u32 flags) void Rfu_SetBlockReceivedFlag(u8 linkPlayerId) { - if (Rfu.parentChild == MODE_PARENT && linkPlayerId) - Rfu.numBlocksReceived[linkPlayerId] = 1; + if (gRfu.parentChild == MODE_PARENT && linkPlayerId) + gRfu.numBlocksReceived[linkPlayerId] = 1; else - Rfu.blockReceived[linkPlayerId] = TRUE; + gRfu.blockReceived[linkPlayerId] = TRUE; } void Rfu_ResetBlockReceivedFlag(u8 linkPlayerId) { - Rfu.blockReceived[linkPlayerId] = FALSE; - Rfu.recvBlock[linkPlayerId].receiving = 0; + gRfu.blockReceived[linkPlayerId] = FALSE; + gRfu.recvBlock[linkPlayerId].receiving = RECV_STATE_READY; } -static u8 sub_800F74C(const u8 *a0) +static u8 LoadLinkPlayerIds(const u8 *ids) { u8 i; - - if (Rfu.parentChild == MODE_PARENT) + if (gRfu.parentChild == MODE_PARENT) return FALSE; for (i = 0; i < RFU_CHILD_MAX; i++) - { - Rfu.linkPlayerIdx[i] = a0[i]; - } - return a0[Rfu.childSlot]; + gRfu.linkPlayerIdx[i] = ids[i]; + + return ids[gRfu.childSlot]; } -static void RfuFunc_SendKeysToRfu(void) +static void SendKeysToRfu(void) { if (gReceivedRemoteLinkPlayers && gHeldKeyCodeToSend != LINK_KEY_CODE_NULL @@ -987,24 +1039,24 @@ static void RfuFunc_SendKeysToRfu(void) } } -struct GFtgtGname *GetHostRFUtgtGname(void) +struct RfuGameData *GetHostRfuGameData(void) { - return &gHostRFUtgtGnameBuffer; + return &gHostRfuGameData; } bool32 IsSendingKeysToRfu(void) { - return Rfu.callback == RfuFunc_SendKeysToRfu; + return gRfu.callback == SendKeysToRfu; } void StartSendingKeysToRfu(void) { - Rfu.callback = RfuFunc_SendKeysToRfu; + gRfu.callback = SendKeysToRfu; } void ClearLinkRfuCallback(void) { - Rfu.callback = NULL; + gRfu.callback = NULL; } static void Rfu_BerryBlenderSendHeldKeys(void) @@ -1017,8 +1069,8 @@ static void Rfu_BerryBlenderSendHeldKeys(void) void Rfu_SetBerryBlenderLinkCallback(void) { - if (Rfu.callback == NULL) - Rfu.callback = Rfu_BerryBlenderSendHeldKeys; + if (gRfu.callback == NULL) + gRfu.callback = Rfu_BerryBlenderSendHeldKeys; } static void RfuHandleReceiveCommand(u8 unused) @@ -1028,42 +1080,42 @@ static void RfuHandleReceiveCommand(u8 unused) for (i = 0; i < MAX_RFU_PLAYERS; i++) { - switch (gRecvCmds[i][0] & 0xff00) + switch (gRecvCmds[i][0] & RFUCMD_MASK) { - case RFUCMD_0x7800: - if (Rfu.parentChild == MODE_CHILD && gReceivedRemoteLinkPlayers) + case RFUCMD_SEND_PLAYER_IDS_NEW: + if (gRfu.parentChild == MODE_CHILD && gReceivedRemoteLinkPlayers) return; // fallthrough - case RFUCMD_0x7700: + case RFUCMD_SEND_PLAYER_IDS: if (gRfuLinkStatus->parentChild == MODE_CHILD) { - Rfu.playerCount = gRecvCmds[i][1]; - Rfu.multiplayerId = sub_800F74C((u8 *)(gRecvCmds[i] + 2)); + gRfu.playerCount = gRecvCmds[i][1]; + gRfu.multiplayerId = LoadLinkPlayerIds((u8 *)(gRecvCmds[i] + 2)); } break; - case RFUCMD_0x8800: - if (Rfu.recvBlock[i].receiving == 0) + case RFUCMD_SEND_BLOCK_INIT: + if (gRfu.recvBlock[i].receiving == RECV_STATE_READY) { - Rfu.recvBlock[i].next = 0; - Rfu.recvBlock[i].count = gRecvCmds[i][1]; - Rfu.recvBlock[i].owner = gRecvCmds[i][2]; - Rfu.recvBlock[i].receivedFlags = 0; - Rfu.recvBlock[i].receiving = 1; - Rfu.blockReceived[i] = FALSE; + gRfu.recvBlock[i].next = 0; + gRfu.recvBlock[i].count = gRecvCmds[i][1]; + gRfu.recvBlock[i].owner = gRecvCmds[i][2]; + gRfu.recvBlock[i].receivedFlags = 0; + gRfu.recvBlock[i].receiving = RECV_STATE_RECEIVING; + gRfu.blockReceived[i] = FALSE; } break; - case RFUCMD_0x8900: - if (Rfu.recvBlock[i].receiving == 1) + case RFUCMD_SEND_BLOCK: + if (gRfu.recvBlock[i].receiving == RECV_STATE_RECEIVING) { - Rfu.recvBlock[i].next = gRecvCmds[i][0] & 0xff; - Rfu.recvBlock[i].receivedFlags |= (1 << Rfu.recvBlock[i].next); + gRfu.recvBlock[i].next = gRecvCmds[i][0] & 0xff; + gRfu.recvBlock[i].receivedFlags |= (1 << gRfu.recvBlock[i].next); for (j = 0; j < 6; j++) - gBlockRecvBuffer[i][Rfu.recvBlock[i].next * 6 + j] = gRecvCmds[i][j + 1]; - if (Rfu.recvBlock[i].receivedFlags == sAllBlocksReceived[Rfu.recvBlock[i].count]) + gBlockRecvBuffer[i][gRfu.recvBlock[i].next * 6 + j] = gRecvCmds[i][j + 1]; + if (gRfu.recvBlock[i].receivedFlags == sAllBlocksReceived[gRfu.recvBlock[i].count]) { - Rfu.recvBlock[i].receiving = 2; + gRfu.recvBlock[i].receiving = RECV_STATE_FINISHED; Rfu_SetBlockReceivedFlag(i); - if (GetHostRFUtgtGname()->activity == (ACTIVITY_CHAT | IN_UNION_ROOM) && gReceivedRemoteLinkPlayers != 0 && Rfu.parentChild == MODE_CHILD) + if (GetHostRfuGameData()->activity == (ACTIVITY_CHAT | IN_UNION_ROOM) && gReceivedRemoteLinkPlayers != 0 && gRfu.parentChild == MODE_CHILD) ValidateAndReceivePokemonSioInfo(gBlockRecvBuffer); } } @@ -1072,40 +1124,42 @@ static void RfuHandleReceiveCommand(u8 unused) Rfu_InitBlockSend(sBlockRequests[gRecvCmds[i][1]].address, (u16)sBlockRequests[gRecvCmds[i][1]].size); break; case RFUCMD_READY_CLOSE_LINK: - Rfu.readyCloseLink[i] = TRUE; + gRfu.readyCloseLink[i] = TRUE; break; case RFUCMD_READY_EXIT_STANDBY: - if (Rfu.unk_100 == gRecvCmds[i][1]) - Rfu.readyExitStandby[i] = TRUE; + if (gRfu.allReadyNum == gRecvCmds[i][1]) + gRfu.readyExitStandby[i] = TRUE; break; - case RFUCMD_0xED00: - if (Rfu.parentChild == MODE_CHILD) + case RFUCMD_DISCONNECT: + if (gRfu.parentChild == MODE_CHILD) { + // Disconnect child if (gReceivedRemoteLinkPlayers) { if (gRecvCmds[i][1] & gRfuLinkStatus->connSlotFlag) { gReceivedRemoteLinkPlayers = 0; rfu_LMAN_requestChangeAgbClockMaster(); - Rfu.unk_ce4 = gRecvCmds[i][2]; + gRfu.disconnectMode = gRecvCmds[i][2]; } - Rfu.playerCount = gRecvCmds[i][3]; + gRfu.playerCount = gRecvCmds[i][3]; ClearSelectedLinkPlayerIds(gRecvCmds[i][1]); } } else { - RfuPrepareSendBuffer(RFUCMD_0xEE00); + // Disconnect parent + RfuPrepareSendBuffer(RFUCMD_DISCONNECT_PARENT); gSendCmd[1] = gRecvCmds[i][1]; gSendCmd[2] = gRecvCmds[i][2]; gSendCmd[3] = gRecvCmds[i][3]; } break; - case RFUCMD_0xEE00: - if (Rfu.parentChild == MODE_PARENT) + case RFUCMD_DISCONNECT_PARENT: + if (gRfu.parentChild == MODE_PARENT) { - Rfu.unk_ce3 |= gRecvCmds[i][1]; - Rfu.unk_ce4 = gRecvCmds[i][2]; + gRfu.disconnectSlots |= gRecvCmds[i][1]; + gRfu.disconnectMode = gRecvCmds[i][2]; ClearSelectedLinkPlayerIds(gRecvCmds[i][1]); } break; @@ -1114,38 +1168,38 @@ static void RfuHandleReceiveCommand(u8 unused) gLinkPartnersHeldKeys[i] = gRecvCmds[i][1]; break; } - if (Rfu.parentChild == MODE_PARENT && Rfu.numBlocksReceived[i]) + if (gRfu.parentChild == MODE_PARENT && gRfu.numBlocksReceived[i]) { - if (Rfu.numBlocksReceived[i] == 4) + if (gRfu.numBlocksReceived[i] == 4) { - Rfu.blockReceived[i] = TRUE; - Rfu.numBlocksReceived[i] = 0; + gRfu.blockReceived[i] = TRUE; + gRfu.numBlocksReceived[i] = 0; } else - Rfu.numBlocksReceived[i]++; + gRfu.numBlocksReceived[i]++; } } } -static bool8 AreNoPlayersReceiving(void) +static bool8 AreAllPlayersReadyToReceive(void) { s32 i; for (i = 0; i < MAX_RFU_PLAYERS; i++) { - if (Rfu.recvBlock[i].receiving) + if (gRfu.recvBlock[i].receiving != RECV_STATE_READY) return FALSE; } return TRUE; } -static bool8 sub_800FC88(void) +static bool8 AreAllPlayersFinishedReceiving(void) { s32 i; - for (i = 0; i < Rfu.playerCount; i++) + for (i = 0; i < gRfu.playerCount; i++) { - if (Rfu.recvBlock[i].receiving != 2 || Rfu.blockReceived[i] != TRUE) + if (gRfu.recvBlock[i].receiving != RECV_STATE_FINISHED || gRfu.blockReceived[i] != TRUE) return FALSE; } return TRUE; @@ -1159,7 +1213,7 @@ static void ResetSendDataManager(struct RfuBlockSend *data) data->receivedFlags = 0; data->sending = FALSE; data->owner = 0; - data->receiving = 0; + data->receiving = RECV_STATE_READY; } u8 Rfu_GetBlockReceivedStatus(void) @@ -1169,10 +1223,8 @@ u8 Rfu_GetBlockReceivedStatus(void) for (i = 0; i < MAX_RFU_PLAYERS; i++) { - if (Rfu.recvBlock[i].receiving == 2 && Rfu.blockReceived[i] == TRUE) - { + if (gRfu.recvBlock[i].receiving == RECV_STATE_FINISHED && gRfu.blockReceived[i] == TRUE) flags |= (1 << i); - } } return flags; } @@ -1186,26 +1238,26 @@ static void RfuPrepareSendBuffer(u16 command) gSendCmd[0] = command; switch (command) { - case RFUCMD_0x8800: - gSendCmd[1] = Rfu.sendBlock.count; - gSendCmd[2] = Rfu.sendBlock.owner + 0x80; + case RFUCMD_SEND_BLOCK_INIT: + gSendCmd[1] = gRfu.sendBlock.count; + gSendCmd[2] = gRfu.sendBlock.owner + 0x80; break; case RFUCMD_SEND_BLOCK_REQ: - if (AreNoPlayersReceiving()) - gSendCmd[1] = Rfu.blockRequestType; + if (AreAllPlayersReadyToReceive()) + gSendCmd[1] = gRfu.blockRequestType; break; - case RFUCMD_0x7700: - case RFUCMD_0x7800: - tmp = Rfu.unk_ce2 ^ Rfu.unk_ce3; - Rfu.playerCount = sUnknown_082ED695[tmp] + 1; - gSendCmd[1] = Rfu.playerCount; - buff = (u8 *)(gSendCmd + 2); + case RFUCMD_SEND_PLAYER_IDS: + case RFUCMD_SEND_PLAYER_IDS_NEW: + tmp = gRfu.parentSlots ^ gRfu.disconnectSlots; + gRfu.playerCount = sPlayerBitsToCount[tmp] + 1; + gSendCmd[1] = gRfu.playerCount; + buff = (u8 *)&gSendCmd[2]; for (i = 0; i < RFU_CHILD_MAX; i++) - buff[i] = Rfu.linkPlayerIdx[i]; + buff[i] = gRfu.linkPlayerIdx[i]; break; case RFUCMD_READY_EXIT_STANDBY: case RFUCMD_READY_CLOSE_LINK: - gSendCmd[1] = Rfu.unk_100; + gSendCmd[1] = gRfu.allReadyNum; break; case RFUCMD_BLENDER_SEND_KEYS: gSendCmd[0] = command; @@ -1213,14 +1265,13 @@ static void RfuPrepareSendBuffer(u16 command) break; case RFUCMD_SEND_PACKET: for (i = 0; i < RFU_PACKET_SIZE; i++) - gSendCmd[1 + i] = Rfu.packet[i]; + gSendCmd[1 + i] = gRfu.packet[i]; break; case RFUCMD_SEND_HELD_KEYS: gSendCmd[1] = gHeldKeyCodeToSend; break; - case RFUCMD_0xEE00: - break; - case RFUCMD_0xED00: + case RFUCMD_DISCONNECT_PARENT: + case RFUCMD_DISCONNECT: break; } } @@ -1229,7 +1280,7 @@ void Rfu_SendPacket(void *data) { if (gSendCmd[0] == 0 && !RfuHasErrored()) { - memcpy(Rfu.packet, data, sizeof(Rfu.packet)); + memcpy(gRfu.packet, data, sizeof(gRfu.packet)); RfuPrepareSendBuffer(RFUCMD_SEND_PACKET); } } @@ -1237,31 +1288,31 @@ void Rfu_SendPacket(void *data) bool32 Rfu_InitBlockSend(const u8 *src, size_t size) { bool8 r4; - if (Rfu.callback != NULL) + if (gRfu.callback != NULL) return FALSE; if (gSendCmd[0] != 0) return FALSE; - if (Rfu.sendBlock.sending) + if (gRfu.sendBlock.sending) { - sRfuDebug.unk_83++; + sRfuDebug.blockSendTime++; return FALSE; } r4 = (size % 12) != 0; - Rfu.sendBlock.owner = GetMultiplayerId(); - Rfu.sendBlock.sending = TRUE; - Rfu.sendBlock.count = (size / 12) + r4; - Rfu.sendBlock.next = 0; - if (size > 0x100) - Rfu.sendBlock.payload = src; + gRfu.sendBlock.owner = GetMultiplayerId(); + gRfu.sendBlock.sending = TRUE; + gRfu.sendBlock.count = (size / 12) + r4; + gRfu.sendBlock.next = 0; + if (size > BLOCK_BUFFER_SIZE) + gRfu.sendBlock.payload = src; else { if (src != gBlockSendBuffer) memcpy(gBlockSendBuffer, src, size); - Rfu.sendBlock.payload = gBlockSendBuffer; + gRfu.sendBlock.payload = gBlockSendBuffer; } - RfuPrepareSendBuffer(RFUCMD_0x8800); - Rfu.callback = HandleBlockSend; - Rfu.unk_5b = 0; + RfuPrepareSendBuffer(RFUCMD_SEND_BLOCK_INIT); + gRfu.callback = HandleBlockSend; + gRfu.blockSendAttempts = 0; return TRUE; } @@ -1269,16 +1320,16 @@ static void HandleBlockSend(void) { if (gSendCmd[0] == 0) { - RfuPrepareSendBuffer(RFUCMD_0x8800); - if (Rfu.parentChild == MODE_PARENT) + RfuPrepareSendBuffer(RFUCMD_SEND_BLOCK_INIT); + if (gRfu.parentChild == MODE_PARENT) { - if (++Rfu.unk_5b > 2) - Rfu.callback = SendNextBlock; + if (++gRfu.blockSendAttempts > 2) + gRfu.callback = SendNextBlock; } else { - if ((gRecvCmds[GetMultiplayerId()][0] & 0xff00) == RFUCMD_0x8800) - Rfu.callback = SendNextBlock; + if ((gRecvCmds[GetMultiplayerId()][0] & RFUCMD_MASK) == RFUCMD_SEND_BLOCK_INIT) + gRfu.callback = SendNextBlock; } } } @@ -1286,126 +1337,134 @@ static void HandleBlockSend(void) static void SendNextBlock(void) { s32 i; - const u8 *src = Rfu.sendBlock.payload; - gSendCmd[0] = RFUCMD_0x8900 | Rfu.sendBlock.next; + const u8 *src = gRfu.sendBlock.payload; + gSendCmd[0] = RFUCMD_SEND_BLOCK | gRfu.sendBlock.next; for (i = 0; i < CMD_LENGTH - 1; i++) - gSendCmd[i + 1] = (src[(i << 1) + Rfu.sendBlock.next * 12 + 1] << 8) | src[(i << 1) + Rfu.sendBlock.next * 12 + 0]; - Rfu.sendBlock.next++; - if (Rfu.sendBlock.count <= Rfu.sendBlock.next) + gSendCmd[i + 1] = (src[(i << 1) + gRfu.sendBlock.next * 12 + 1] << 8) | src[(i << 1) + gRfu.sendBlock.next * 12 + 0]; + gRfu.sendBlock.next++; + if (gRfu.sendBlock.count <= gRfu.sendBlock.next) { - Rfu.sendBlock.sending = FALSE; - Rfu.callback = SendLastBlock; + gRfu.sendBlock.sending = FALSE; + gRfu.callback = SendLastBlock; } } static void SendLastBlock(void) { - const u8 *src = Rfu.sendBlock.payload; + const u8 *src = gRfu.sendBlock.payload; u8 mpId = GetMultiplayerId(); s32 i; - if (Rfu.parentChild == MODE_CHILD) + if (gRfu.parentChild == MODE_CHILD) { - gSendCmd[0] = RFUCMD_0x8900 | (Rfu.sendBlock.count - 1); + gSendCmd[0] = RFUCMD_SEND_BLOCK | (gRfu.sendBlock.count - 1); for (i = 0; i < CMD_LENGTH - 1; i++) - gSendCmd[i + 1] = (src[(i << 1) + (Rfu.sendBlock.count - 1) * 12 + 1] << 8) | src[(i << 1) + (Rfu.sendBlock.count - 1) * 12 + 0]; - if ((u8)gRecvCmds[mpId][0] == Rfu.sendBlock.count - 1) + gSendCmd[i + 1] = (src[(i << 1) + (gRfu.sendBlock.count - 1) * 12 + 1] << 8) | src[(i << 1) + (gRfu.sendBlock.count - 1) * 12 + 0]; + if ((u8)gRecvCmds[mpId][0] == gRfu.sendBlock.count - 1) { - if (Rfu.recvBlock[mpId].receivedFlags != sAllBlocksReceived[Rfu.recvBlock[mpId].count]) + if (gRfu.recvBlock[mpId].receivedFlags != sAllBlocksReceived[gRfu.recvBlock[mpId].count]) { - HandleSendFailure(mpId, Rfu.recvBlock[mpId].receivedFlags); - sRfuDebug.unk_64++; + HandleSendFailure(mpId, gRfu.recvBlock[mpId].receivedFlags); + sRfuDebug.blockSendFailures++; } else - Rfu.callback = NULL; + { + gRfu.callback = NULL; + } } } else - Rfu.callback = NULL; + { + gRfu.callback = NULL; + } } bool8 Rfu_SendBlockRequest(u8 type) { - Rfu.blockRequestType = type; + gRfu.blockRequestType = type; RfuPrepareSendBuffer(RFUCMD_SEND_BLOCK_REQ); return TRUE; } -static void sub_801011C(void) +static void RfuShutdownAfterDisconnect(void) { rfu_clearAllSlot(); rfu_LMAN_powerDownRFU(); gReceivedRemoteLinkPlayers = 0; - Rfu.isShuttingDown = TRUE; - Rfu.callback = NULL; + gRfu.isShuttingDown = TRUE; + gRfu.callback = NULL; } static void DisconnectRfu(void) { rfu_REQ_disconnect(gRfuLinkStatus->connSlotFlag | gRfuLinkStatus->linkLossSlotFlag); rfu_waitREQComplete(); - sub_801011C(); + RfuShutdownAfterDisconnect(); } static void TryDisconnectRfu(void) { - if (Rfu.parentChild == MODE_CHILD) + if (gRfu.parentChild == MODE_CHILD) { rfu_LMAN_requestChangeAgbClockMaster(); - Rfu.unk_ce4 = 2; + gRfu.disconnectMode = RFU_DISCONNECT_NORMAL; } else - Rfu.callback = DisconnectRfu; + { + gRfu.callback = DisconnectRfu; + } } void LinkRfu_FatalError(void) { rfu_LMAN_requestChangeAgbClockMaster(); - Rfu.unk_ce4 = 1; - Rfu.unk_ce3 = gRfuLinkStatus->connSlotFlag | gRfuLinkStatus->linkLossSlotFlag; + gRfu.disconnectMode = RFU_DISCONNECT_ERROR; + gRfu.disconnectSlots = gRfuLinkStatus->connSlotFlag | gRfuLinkStatus->linkLossSlotFlag; } // RFU equivalent of LinkCB_WaitCloseLink static void WaitAllReadyToCloseLink(void) { s32 i; - u8 playerCount = Rfu.playerCount; + u8 playerCount = gRfu.playerCount; s32 count = 0; // Wait for all players to be ready for (i = 0; i < MAX_RFU_PLAYERS; i++) { - if (Rfu.readyCloseLink[i]) + if (gRfu.readyCloseLink[i]) count++; } if (count == playerCount) { // All ready, close link gBattleTypeFlags &= ~BATTLE_TYPE_LINK_IN_BATTLE; - if (Rfu.parentChild == MODE_CHILD) + if (gRfu.parentChild == MODE_CHILD) { - Rfu.errorState = 3; + gRfu.errorState = RFU_ERROR_STATE_DISCONNECTING; TryDisconnectRfu(); } else - Rfu.callback = TryDisconnectRfu; + { + gRfu.callback = TryDisconnectRfu; + } } } static void SendReadyCloseLink(void) { - if (gSendCmd[0] == 0 && Rfu.unk_ce8 == 0) + if (gSendCmd[0] == 0 && !gRfu.playerExchangeActive) { RfuPrepareSendBuffer(RFUCMD_READY_CLOSE_LINK); - Rfu.callback = WaitAllReadyToCloseLink; + gRfu.callback = WaitAllReadyToCloseLink; } } static void Task_TryReadyCloseLink(u8 taskId) { - if (Rfu.callback == NULL) + if (gRfu.callback == NULL) { - Rfu.unk_cd9 = 1; - Rfu.callback = SendReadyCloseLink; + gRfu.stopNewConnections = TRUE; + gRfu.callback = SendReadyCloseLink; DestroyTask(taskId); } } @@ -1423,34 +1482,34 @@ static void SendReadyExitStandbyUntilAllReady(void) if (GetMultiplayerId() != 0) { - if (Rfu.recvQueue.count == 0 && Rfu.resendExitStandbyTimer > 60) + if (gRfu.recvQueue.count == 0 && gRfu.resendExitStandbyTimer > 60) { RfuPrepareSendBuffer(RFUCMD_READY_EXIT_STANDBY); - Rfu.resendExitStandbyTimer = 0; + gRfu.resendExitStandbyTimer = 0; } } playerCount = GetLinkPlayerCount(); for (i = 0; i < playerCount; i++) { - if (!Rfu.readyExitStandby[i]) + if (!gRfu.readyExitStandby[i]) break; } if (i == playerCount) { for (i = 0; i < MAX_RFU_PLAYERS; i++) - Rfu.readyExitStandby[i] = FALSE; - Rfu.unk_100++; - Rfu.callback = NULL; + gRfu.readyExitStandby[i] = FALSE; + gRfu.allReadyNum++; + gRfu.callback = NULL; } - Rfu.resendExitStandbyTimer++; + gRfu.resendExitStandbyTimer++; } static void LinkLeaderReadyToExitStandby(void) { - if (Rfu.recvQueue.count == 0 && gSendCmd[0] == 0) + if (gRfu.recvQueue.count == 0 && gSendCmd[0] == 0) { RfuPrepareSendBuffer(RFUCMD_READY_EXIT_STANDBY); - Rfu.callback = SendReadyExitStandbyUntilAllReady; + gRfu.callback = SendReadyExitStandbyUntilAllReady; } } @@ -1463,10 +1522,10 @@ static void Rfu_LinkStandby(void) if (GetMultiplayerId() != 0) { // Not link leader, send exit standby when ready - if (Rfu.recvQueue.count == 0 && gSendCmd[0] == 0) + if (gRfu.recvQueue.count == 0 && gSendCmd[0] == 0) { RfuPrepareSendBuffer(RFUCMD_READY_EXIT_STANDBY); - Rfu.callback = SendReadyExitStandbyUntilAllReady; + gRfu.callback = SendReadyExitStandbyUntilAllReady; } } else @@ -1475,15 +1534,15 @@ static void Rfu_LinkStandby(void) playerCount = GetLinkPlayerCount(); for (i = 1; i < playerCount; i++) { - if (!Rfu.readyExitStandby[i]) + if (!gRfu.readyExitStandby[i]) break; } if (i == playerCount) { - if (Rfu.recvQueue.count == 0 && gSendCmd[0] == 0) + if (gRfu.recvQueue.count == 0 && gSendCmd[0] == 0) { RfuPrepareSendBuffer(RFUCMD_READY_EXIT_STANDBY); - Rfu.callback = LinkLeaderReadyToExitStandby; + gRfu.callback = LinkLeaderReadyToExitStandby; } } } @@ -1491,10 +1550,10 @@ static void Rfu_LinkStandby(void) void Rfu_SetLinkStandbyCallback(void) { - if (Rfu.callback == NULL) + if (gRfu.callback == NULL) { - Rfu.callback = Rfu_LinkStandby; - Rfu.resendExitStandbyTimer = 0; + gRfu.callback = Rfu_LinkStandby; + gRfu.resendExitStandbyTimer = 0; } } @@ -1503,49 +1562,49 @@ bool32 IsRfuSerialNumberValid(u32 serialNo) s32 i; for (i = 0; sAcceptedSerialNos[i] != serialNo; i++) { - if (sAcceptedSerialNos[i] == 0xFFFF) + if (sAcceptedSerialNos[i] == RFU_SERIAL_END) return FALSE; } return TRUE; } -u8 sub_801048C(bool32 a0) +u8 Rfu_SetLinkRecovery(bool32 enable) { - if (a0 == FALSE) + if (enable == FALSE) return rfu_LMAN_setLinkRecovery(0, 0); rfu_LMAN_setLinkRecovery(1, 600); return 0; } -void sub_80104B0(void) +void Rfu_StopPartnerSearch(void) { - Rfu.unk_cd9 = 1; + gRfu.stopNewConnections = TRUE; rfu_LMAN_stopManager(FALSE); } u8 Rfu_GetMultiplayerId(void) { - if (Rfu.parentChild == MODE_PARENT) + if (gRfu.parentChild == MODE_PARENT) return 0; - return Rfu.multiplayerId; + return gRfu.multiplayerId; } u8 Rfu_GetLinkPlayerCount(void) { - return Rfu.playerCount; + return gRfu.playerCount; } bool8 IsLinkRfuTaskFinished(void) { - if (Rfu.status == RFU_STATUS_CONNECTION_ERROR) + if (gRfu.status == RFU_STATUS_CONNECTION_ERROR) return FALSE; - return Rfu.callback ? FALSE : TRUE; + return gRfu.callback ? FALSE : TRUE; } static void CallRfuFunc(void) { - if (Rfu.callback) - Rfu.callback(); + if (gRfu.callback) + gRfu.callback(); } static bool8 CheckForLeavingGroupMembers(void) @@ -1554,23 +1613,23 @@ static bool8 CheckForLeavingGroupMembers(void) bool8 memberLeft = FALSE; for (i = 0; i < RFU_CHILD_MAX; i++) { - if (Rfu.partnerSendStatuses[i] < RFU_STATUS_JOIN_GROUP_OK - || Rfu.partnerSendStatuses[i] > RFU_STATUS_JOIN_GROUP_NO) + if (gRfu.partnerSendStatuses[i] < RFU_STATUS_JOIN_GROUP_OK + || gRfu.partnerSendStatuses[i] > RFU_STATUS_JOIN_GROUP_NO) { if (gRfuSlotStatusNI[i]->recv.state == SLOT_STATE_RECV_SUCCESS || gRfuSlotStatusNI[i]->recv.state == SLOT_STATE_RECV_SUCCESS_AND_SENDSIDE_UNKNOWN) { - if (Rfu.partnerRecvStatuses[i] == RFU_STATUS_LEAVE_GROUP_NOTICE) + if (gRfu.partnerRecvStatuses[i] == RFU_STATUS_LEAVE_GROUP_NOTICE) { - Rfu.partnerSendStatuses[i] = RFU_STATUS_LEAVE_GROUP; - Rfu.partnerRecvStatuses[i] = RFU_STATUS_10; + gRfu.partnerSendStatuses[i] = RFU_STATUS_LEAVE_GROUP; + gRfu.partnerRecvStatuses[i] = RFU_STATUS_CHILD_LEAVE_READY; rfu_clearSlot(TYPE_NI_RECV, i); - rfu_NI_setSendData(1 << i, 8, &Rfu.partnerSendStatuses[i], 1); + rfu_NI_setSendData(1 << i, 8, &gRfu.partnerSendStatuses[i], 1); memberLeft = TRUE; } } - else if (gRfuSlotStatusNI[Rfu.childSlot]->recv.state == SLOT_STATE_RECV_FAILED) + else if (gRfuSlotStatusNI[gRfu.childSlot]->recv.state == SLOT_STATE_RECV_FAILED) rfu_clearSlot(TYPE_NI_RECV, i); { @@ -1580,27 +1639,33 @@ static bool8 CheckForLeavingGroupMembers(void) return memberLeft; } -bool32 sub_80105EC(void) +bool32 RfuTryDisconnectLeavingChildren(void) { - u8 flags = 0; + u8 childrenLeaving = 0; s32 i; + + // Check all children, get those waiting to be disconnected for (i = 0; i < RFU_CHILD_MAX; i++) { - if (Rfu.partnerRecvStatuses[i] == RFU_STATUS_11) + if (gRfu.partnerRecvStatuses[i] == RFU_STATUS_CHILD_LEAVE) { - flags |= (1 << i); - Rfu.partnerRecvStatuses[i] = RFU_STATUS_OK; + childrenLeaving |= (1 << i); + gRfu.partnerRecvStatuses[i] = RFU_STATUS_OK; } } - if (flags) + + // Disconnect any leaving children + if (childrenLeaving) { - rfu_REQ_disconnect(flags); + rfu_REQ_disconnect(childrenLeaving); rfu_waitREQComplete(); } + + // Return true if any children have left or are still waiting to leave for (i = 0; i < RFU_CHILD_MAX; i++) { - if (Rfu.partnerRecvStatuses[i] == RFU_STATUS_10 - || Rfu.partnerRecvStatuses[i] == RFU_STATUS_11) + if (gRfu.partnerRecvStatuses[i] == RFU_STATUS_CHILD_LEAVE_READY + || gRfu.partnerRecvStatuses[i] == RFU_STATUS_CHILD_LEAVE) return TRUE; } return FALSE; @@ -1611,7 +1676,7 @@ bool32 HasTrainerLeftPartnersList(u16 trainerId, const u8 *name) u8 idx = GetPartnerIndexByNameAndTrainerID(name, trainerId); if (idx == 0xFF) return TRUE; - if (Rfu.partnerSendStatuses[idx] == RFU_STATUS_LEAVE_GROUP) + if (gRfu.partnerSendStatuses[idx] == RFU_STATUS_LEAVE_GROUP) return TRUE; return FALSE; } @@ -1619,16 +1684,16 @@ bool32 HasTrainerLeftPartnersList(u16 trainerId, const u8 *name) void SendRfuStatusToPartner(u8 status, u16 trainerId, const u8 *name) { u8 idx = GetPartnerIndexByNameAndTrainerID(name, trainerId); - Rfu.partnerSendStatuses[idx] = status; + gRfu.partnerSendStatuses[idx] = status; rfu_clearSlot(TYPE_NI_SEND, idx); - rfu_NI_setSendData(1 << idx, 8, &Rfu.partnerSendStatuses[idx], 1); + rfu_NI_setSendData(1 << idx, 8, &gRfu.partnerSendStatuses[idx], 1); } void SendLeaveGroupNotice(void) { - Rfu.unk_c85 = RFU_STATUS_LEAVE_GROUP_NOTICE; - rfu_clearSlot(TYPE_NI_SEND, Rfu.childSlot); - rfu_NI_setSendData(1 << Rfu.childSlot, 8, &Rfu.unk_c85, 1); + gRfu.leaveGroupStatus = RFU_STATUS_LEAVE_GROUP_NOTICE; + rfu_clearSlot(TYPE_NI_SEND, gRfu.childSlot); + rfu_NI_setSendData(1 << gRfu.childSlot, 8, &gRfu.leaveGroupStatus, 1); } u32 WaitSendRfuStatusToPartner(u16 trainerId, const u8 *name) @@ -1651,114 +1716,116 @@ static void UpdateChildStatuses(void) if (gRfuSlotStatusNI[i]->send.state == SLOT_STATE_SEND_SUCCESS || gRfuSlotStatusNI[i]->send.state == SLOT_STATE_SEND_FAILED) { - if (Rfu.partnerRecvStatuses[i] == RFU_STATUS_10) - Rfu.partnerRecvStatuses[i] = RFU_STATUS_11; + if (gRfu.partnerRecvStatuses[i] == RFU_STATUS_CHILD_LEAVE_READY) + gRfu.partnerRecvStatuses[i] = RFU_STATUS_CHILD_LEAVE; rfu_clearSlot(TYPE_NI_SEND, i); } } } -static s32 sub_80107A0(void) +static s32 GetJoinGroupStatus(void) { s32 status = RFU_STATUS_OK; - if (Rfu.unk_c85 == 8) + if (gRfu.leaveGroupStatus == RFU_STATUS_LEAVE_GROUP_NOTICE) { - if (gRfuSlotStatusNI[Rfu.childSlot]->send.state == SLOT_STATE_SEND_SUCCESS - || gRfuSlotStatusNI[Rfu.childSlot]->send.state == SLOT_STATE_SEND_FAILED) - rfu_clearSlot(TYPE_NI_SEND, Rfu.childSlot); + if (gRfuSlotStatusNI[gRfu.childSlot]->send.state == SLOT_STATE_SEND_SUCCESS + || gRfuSlotStatusNI[gRfu.childSlot]->send.state == SLOT_STATE_SEND_FAILED) + rfu_clearSlot(TYPE_NI_SEND, gRfu.childSlot); } - if (gRfuSlotStatusNI[Rfu.childSlot]->recv.state == SLOT_STATE_RECV_SUCCESS - || gRfuSlotStatusNI[Rfu.childSlot]->recv.state == SLOT_STATE_RECV_SUCCESS_AND_SENDSIDE_UNKNOWN) + if (gRfuSlotStatusNI[gRfu.childSlot]->recv.state == SLOT_STATE_RECV_SUCCESS + || gRfuSlotStatusNI[gRfu.childSlot]->recv.state == SLOT_STATE_RECV_SUCCESS_AND_SENDSIDE_UNKNOWN) { - rfu_clearSlot(TYPE_NI_RECV, Rfu.childSlot); - RfuSetStatus(Rfu.recvStatus, 0); - status = Rfu.recvStatus; + rfu_clearSlot(TYPE_NI_RECV, gRfu.childSlot); + RfuSetStatus(gRfu.childRecvStatus, 0); + status = gRfu.childRecvStatus; } - else if (gRfuSlotStatusNI[Rfu.childSlot]->recv.state == SLOT_STATE_RECV_FAILED) + else if (gRfuSlotStatusNI[gRfu.childSlot]->recv.state == SLOT_STATE_RECV_FAILED) { - rfu_clearSlot(TYPE_NI_RECV, Rfu.childSlot); + rfu_clearSlot(TYPE_NI_RECV, gRfu.childSlot); status = RFU_STATUS_JOIN_GROUP_NO; } return status; } -static void sub_801084C(u8 taskId) +#define tState data[0] + +static void Task_PlayerExchange(u8 taskId) { s32 i; - if (Rfu.status == RFU_STATUS_FATAL_ERROR || Rfu.status == RFU_STATUS_CONNECTION_ERROR) + if (gRfu.status == RFU_STATUS_FATAL_ERROR || gRfu.status == RFU_STATUS_CONNECTION_ERROR) { - Rfu.unk_ce8 = 0; + gRfu.playerExchangeActive = FALSE; DestroyTask(taskId); } - switch (gTasks[taskId].data[0]) + switch (gTasks[taskId].tState) { case 0: - if (AreNoPlayersReceiving()) + if (AreAllPlayersReadyToReceive()) { ResetBlockReceivedFlags(); LocalLinkPlayerToBlock(); - gTasks[taskId].data[0]++; + gTasks[taskId].tState++; } break; case 1: - if (Rfu.parentChild == MODE_PARENT) + if (gRfu.parentChild == MODE_PARENT) { if (gReceivedRemoteLinkPlayers) - RfuPrepareSendBuffer(RFUCMD_0x7800); + RfuPrepareSendBuffer(RFUCMD_SEND_PLAYER_IDS_NEW); else - RfuPrepareSendBuffer(RFUCMD_0x7700); - gTasks[taskId].data[0] = 101; + RfuPrepareSendBuffer(RFUCMD_SEND_PLAYER_IDS); + gTasks[taskId].tState = 101; } else - gTasks[taskId].data[0] = 2; + gTasks[taskId].tState = 2; break; case 101: if (gSendCmd[0] == 0) - gTasks[taskId].data[0] = 2; + gTasks[taskId].tState = 2; break; case 2: - if (Rfu.playerCount) - gTasks[taskId].data[0]++; + if (gRfu.playerCount) + gTasks[taskId].tState++; break; case 3: - if (Rfu.parentChild == MODE_PARENT) + if (gRfu.parentChild == MODE_PARENT) { - if (AreNoPlayersReceiving()) + if (AreAllPlayersReadyToReceive()) { - Rfu.blockRequestType = 0; + gRfu.blockRequestType = BLOCK_REQ_SIZE_NONE; RfuPrepareSendBuffer(RFUCMD_SEND_BLOCK_REQ); - gTasks[taskId].data[0]++; + gTasks[taskId].tState++; } } else - gTasks[taskId].data[0]++; + gTasks[taskId].tState++; break; case 4: - if (sub_800FC88()) - gTasks[taskId].data[0]++; + if (AreAllPlayersFinishedReceiving()) + gTasks[taskId].tState++; break; case 5: - for (i = 0; i < Rfu.playerCount; i++) + for (i = 0; i < gRfu.playerCount; i++) { LinkPlayerFromBlock(i); Rfu_ResetBlockReceivedFlag(i); } - gTasks[taskId].data[0]++; + gTasks[taskId].tState++; break; case 6: DestroyTask(taskId); gReceivedRemoteLinkPlayers = TRUE; - Rfu.unk_ce8 = FALSE; + gRfu.playerExchangeActive = FALSE; rfu_LMAN_setLinkRecovery(1, 600); - if (Rfu.unk_ce6) + if (gRfu.newChildQueue) { for (i = 0; i < RFU_CHILD_MAX; i++) { - if ((Rfu.unk_ce6 >> i) & 1) + if ((gRfu.newChildQueue >> i) & 1) { - Rfu.unk_ce5 = 1 << i; - Rfu.unk_ce6 ^= (1 << i); + gRfu.nextChildBits = 1 << i; + gRfu.newChildQueue ^= (1 << i); } } } @@ -1773,16 +1840,16 @@ static void ClearSelectedLinkPlayerIds(u16 selected) for (i = 0; i < RFU_CHILD_MAX; i++) { if ((selected >> i) & 1) - Rfu.linkPlayerIdx[i] = 0; + gRfu.linkPlayerIdx[i] = 0; } } static void ReceiveRfuLinkPlayers(const struct SioInfo *sioInfo) { s32 i; - Rfu.playerCount = sioInfo->playerCount; + gRfu.playerCount = sioInfo->playerCount; for (i = 0; i < RFU_CHILD_MAX; i++) - Rfu.linkPlayerIdx[i] = sioInfo->linkPlayerIdx[i]; + gRfu.linkPlayerIdx[i] = sioInfo->linkPlayerIdx[i]; for (i = 0; i < MAX_RFU_PLAYERS; i++) { gLinkPlayers[i] = sioInfo->linkPlayers[i]; @@ -1800,74 +1867,75 @@ static void ValidateAndReceivePokemonSioInfo(void *recvBuffer) } } -static void Task_ExchangeLinkPlayers(u8 taskId) +// Equivalent to Task_PlayerExchange, but for when new children arrive after the first exchange +static void Task_PlayerExchangeUpdate(u8 taskId) { s32 i; - struct LinkPlayerBlock *r2; - struct SioInfo *r5; - u8 r4 = Rfu.linkPlayerIdx[sUnknown_082ED68C[Rfu.unk_ce9]]; - if (Rfu.status == RFU_STATUS_FATAL_ERROR || Rfu.status == RFU_STATUS_CONNECTION_ERROR) + struct LinkPlayerBlock *playerBlock; + struct SioInfo *sio; + u8 playerId = gRfu.linkPlayerIdx[sSlotToLinkPlayerTableId[gRfu.incomingChild]]; + if (gRfu.status == RFU_STATUS_FATAL_ERROR || gRfu.status == RFU_STATUS_CONNECTION_ERROR) { - Rfu.unk_ce8 = 0; + gRfu.playerExchangeActive = FALSE; DestroyTask(taskId); } - switch (gTasks[taskId].data[0]) + switch (gTasks[taskId].tState) { case 0: if (gSendCmd[0] == 0) { - ResetBlockReceivedFlag(r4); - RfuPrepareSendBuffer(RFUCMD_0x7800); - gTasks[taskId].data[0]++; + ResetBlockReceivedFlag(playerId); + RfuPrepareSendBuffer(RFUCMD_SEND_PLAYER_IDS_NEW); + gTasks[taskId].tState++; } break; case 1: if (gSendCmd[0] == 0) - gTasks[taskId].data[0]++; + gTasks[taskId].tState++; break; case 2: - if ((GetBlockReceivedStatus() >> r4) & 1) + if ((GetBlockReceivedStatus() >> playerId) & 1) { - ResetBlockReceivedFlag(r4); - r2 = (struct LinkPlayerBlock *)gBlockRecvBuffer[r4]; - gLinkPlayers[r4] = r2->linkPlayer; - ConvertLinkPlayerName(gLinkPlayers + r4); - gTasks[taskId].data[0]++; + ResetBlockReceivedFlag(playerId); + playerBlock = (struct LinkPlayerBlock *)gBlockRecvBuffer[playerId]; + gLinkPlayers[playerId] = playerBlock->linkPlayer; + ConvertLinkPlayerName(&gLinkPlayers[playerId]); + gTasks[taskId].tState++; } break; case 3: - r5 = (struct SioInfo *)gBlockSendBuffer; - memcpy(r5->magic, sASCII_PokemonSioInfo, sizeof sASCII_PokemonSioInfo); - r5->playerCount = Rfu.playerCount; + sio = (struct SioInfo *)gBlockSendBuffer; + memcpy(sio->magic, sASCII_PokemonSioInfo, sizeof sASCII_PokemonSioInfo); + sio->playerCount = gRfu.playerCount; for (i = 0; i < RFU_CHILD_MAX; i++) - r5->linkPlayerIdx[i] = Rfu.linkPlayerIdx[i]; - memcpy(r5->linkPlayers, gLinkPlayers, sizeof gLinkPlayers); - gTasks[taskId].data[0]++; + sio->linkPlayerIdx[i] = gRfu.linkPlayerIdx[i]; + memcpy(sio->linkPlayers, gLinkPlayers, sizeof gLinkPlayers); + gTasks[taskId].tState++; // fallthrough case 4: - r5 = (struct SioInfo *)gBlockSendBuffer; - r5->playerCount = Rfu.playerCount; + sio = (struct SioInfo *)gBlockSendBuffer; + sio->playerCount = gRfu.playerCount; for (i = 0; i < RFU_CHILD_MAX; i++) - r5->linkPlayerIdx[i] = Rfu.linkPlayerIdx[i]; - memcpy(r5->linkPlayers, gLinkPlayers, sizeof gLinkPlayers); + sio->linkPlayerIdx[i] = gRfu.linkPlayerIdx[i]; + memcpy(sio->linkPlayers, gLinkPlayers, sizeof(gLinkPlayers)); if (SendBlock(0, gBlockSendBuffer, 0xa0)) - gTasks[taskId].data[0]++; + gTasks[taskId].tState++; break; case 5: if (IsLinkTaskFinished() && GetBlockReceivedStatus() & 1) { CpuFill16(0, gBlockRecvBuffer, sizeof(struct SioInfo)); ResetBlockReceivedFlag(0); - Rfu.unk_ce8 = 0; - if (Rfu.unk_ce6) + gRfu.playerExchangeActive = FALSE; + if (gRfu.newChildQueue) { - for (i = 0; i < 4; i++) + for (i = 0; i < RFU_CHILD_MAX; i++) { - if ((Rfu.unk_ce6 >> i) & 1) + if ((gRfu.newChildQueue >> i) & 1) { - Rfu.unk_ce5 = 1 << i; - Rfu.unk_ce6 ^= (1 << i); - Rfu.unk_ce8 = 1; + gRfu.nextChildBits = 1 << i; + gRfu.newChildQueue ^= (1 << i); + gRfu.playerExchangeActive = TRUE; break; } } @@ -1878,23 +1946,24 @@ static void Task_ExchangeLinkPlayers(u8 taskId) } } -static void sub_8010D0C(u8 taskId) +// Equivalent to Task_PlayerExchange but for chatting with a Union Room partner +static void Task_PlayerExchangeChat(u8 taskId) { - if (Rfu.status == RFU_STATUS_FATAL_ERROR || Rfu.status == RFU_STATUS_CONNECTION_ERROR) + if (gRfu.status == RFU_STATUS_FATAL_ERROR || gRfu.status == RFU_STATUS_CONNECTION_ERROR) DestroyTask(taskId); - switch (gTasks[taskId].data[0]) + switch (gTasks[taskId].tState) { case 0: - if (Rfu.playerCount) + if (gRfu.playerCount) { LocalLinkPlayerToBlock(); SendBlock(0, gBlockSendBuffer, sizeof(struct LinkPlayerBlock)); - gTasks[taskId].data[0]++; + gTasks[taskId].tState++; } break; case 1: if (IsLinkTaskFinished()) - gTasks[taskId].data[0]++; + gTasks[taskId].tState++; break; case 2: if (GetBlockReceivedStatus() & 1) @@ -1910,28 +1979,28 @@ static void sub_8010D0C(u8 taskId) static void RfuCheckErrorStatus(void) { - if (Rfu.errorState == 1 && lman.childClockSlave_flag == 0) + 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) gWirelessCommType = 2; SetMainCallback2(CB2_LinkError); gMain.savedCallback = CB2_LinkError; - BufferLinkErrorInfo((Rfu.linkmanMsg << 16) | (Rfu.unk_10 << 8) | Rfu.unk_12, Rfu.recvQueue.count, Rfu.sendQueue.count, RfuGetStatus() == RFU_STATUS_CONNECTION_ERROR); - Rfu.errorState = 2; + SetLinkErrorBuffer((gRfu.errorInfo << 16) | (gRfu.errorParam0 << 8) | gRfu.errorParam1, gRfu.recvQueue.count, gRfu.sendQueue.count, RfuGetStatus() == RFU_STATUS_CONNECTION_ERROR); + gRfu.errorState = RFU_ERROR_STATE_PROCESSED; CloseLink(); } - else if (Rfu.sendQueue.full == TRUE || Rfu.recvQueue.full == TRUE) + else if (gRfu.sendQueue.full == TRUE || gRfu.recvQueue.full == TRUE) { if (lman.childClockSlave_flag) rfu_LMAN_requestChangeAgbClockMaster(); - RfuSetStatus(RFU_STATUS_FATAL_ERROR, 0x7000); - GetLinkmanErrorParams(0x7000); + RfuSetStatus(RFU_STATUS_FATAL_ERROR, F_RFU_ERROR_5 | F_RFU_ERROR_6 | F_RFU_ERROR_7); + RfuSetErrorParams(F_RFU_ERROR_5 | F_RFU_ERROR_6 | F_RFU_ERROR_7); } } -static void rfu_REQ_recvData_then_sendData(void) +static void RfuMain1_UnionRoom(void) { - if (lman.parent_child == 1) + if (lman.parent_child == MODE_PARENT) { rfu_REQ_recvData(); rfu_waitREQComplete(); @@ -1939,184 +2008,190 @@ static void rfu_REQ_recvData_then_sendData(void) } } -bool32 sub_8010EC0(void) +// Rfu equivalent of LinkMain1 +bool32 RfuMain1(void) { bool32 retval = FALSE; - Rfu.parentId = 0; + gRfu.parentId = 0; rfu_LMAN_manager_entity(Random2()); - if (!Rfu.isShuttingDown) + if (!gRfu.isShuttingDown) { - switch (Rfu.parentChild) + switch (gRfu.parentChild) { case MODE_PARENT: - sub_800F0F8(); + RfuMain1_Parent(); break; case MODE_CHILD: - retval = RfuProcessEnqueuedRecvBlock(); + retval = RfuMain1_Child(); break; - case 2: - rfu_REQ_recvData_then_sendData(); + case MODE_P_C_SWITCH: + RfuMain1_UnionRoom(); break; } } return retval; } -bool32 sub_8010F1C(void) +// Rfu equivalent of LinkMain2 +bool32 RfuMain2(void) { bool32 retval = FALSE; - if (!Rfu.isShuttingDown) + if (!gRfu.isShuttingDown) { - if (Rfu.parentChild == MODE_PARENT) - retval = sub_800F1E0(); + if (gRfu.parentChild == MODE_PARENT) + retval = RfuMain2_Parent(); RfuCheckErrorStatus(); } return retval; } -static void CopyPlayerNameToUnameBuffer(void) +static void SetHostRfuUsername(void) { - StringCopy(gHostRFUtgtUnameBuffer, gSaveBlock2Ptr->playerName); + StringCopy(gHostRfuUsername, gSaveBlock2Ptr->playerName); } -void ClearAndInitHostRFUtgtGname(void) +void ResetHostRfuGameData(void) { - memset(&gHostRFUtgtGnameBuffer, 0, RFU_GAME_NAME_LENGTH); - InitHostRFUtgtGname(&gHostRFUtgtGnameBuffer, ACTIVITY_NONE, FALSE, 0); + memset(&gHostRfuGameData, 0, RFU_GAME_NAME_LENGTH); + InitHostRfuGameData(&gHostRfuGameData, ACTIVITY_NONE, FALSE, 0); } -void SetHostRFUtgtGname(u8 activity, u32 child_sprite_genders, bool32 started) +void SetHostRfuGameData(u8 activity, u32 partnerInfo, bool32 startedActivity) { - InitHostRFUtgtGname(&gHostRFUtgtGnameBuffer, activity, started, child_sprite_genders); + InitHostRfuGameData(&gHostRfuGameData, activity, startedActivity, partnerInfo); } -void SetGnameBufferWonderFlags(bool32 hasNews, bool32 hasCard) +void SetHostRfuWonderFlags(bool32 hasNews, bool32 hasCard) { - gHostRFUtgtGnameBuffer.unk_00.hasNews = hasNews; - gHostRFUtgtGnameBuffer.unk_00.hasCard = hasCard; + gHostRfuGameData.compatibility.hasNews = hasNews; + gHostRfuGameData.compatibility.hasCard = hasCard; } void SetTradeBoardRegisteredMonInfo(u32 type, u32 species, u32 level) { - gHostRFUtgtGnameBuffer.type = type; - gHostRFUtgtGnameBuffer.species = species; - gHostRFUtgtGnameBuffer.level = level; + gHostRfuGameData.tradeType = type; + gHostRfuGameData.tradeSpecies = species; + gHostRfuGameData.tradeLevel = level; } -u8 sub_801100C(s32 a0) +u8 GetLinkPlayerInfoFlags(s32 playerId) { - u8 retval = 0x80; - retval |= (gLinkPlayers[a0].gender << 3); - retval |= (gLinkPlayers[a0].trainerId & 7); + u8 retval = PINFO_ACTIVE_FLAG; + retval |= (gLinkPlayers[playerId].gender << PINFO_GENDER_SHIFT); + retval |= (gLinkPlayers[playerId].trainerId & PINFO_TID_MASK); return retval; } -void sub_801103C(void) +void GetOtherPlayersInfoFlags(void) { - struct GFtgtGname *r5 = &gHostRFUtgtGnameBuffer; + struct RfuGameData *data = &gHostRfuGameData; s32 i; for (i = 1; i < GetLinkPlayerCount(); i++) - r5->child_sprite_gender[i - 1] = sub_801100C(i); + data->partnerInfo[i - 1] = GetLinkPlayerInfoFlags(i); } -void UpdateGameData_GroupLockedIn(bool8 started) +void UpdateGameData_GroupLockedIn(bool8 startedActivity) { - gHostRFUtgtGnameBuffer.started = started; - rfu_REQ_configGameData(0, 2, (void *)&gHostRFUtgtGnameBuffer, gHostRFUtgtUnameBuffer); + gHostRfuGameData.startedActivity = startedActivity; + rfu_REQ_configGameData(0, RFU_SERIAL_GAME, (void *)&gHostRfuGameData, gHostRfuUsername); } -void UpdateGameData_SetActivity(u8 activity, u32 flags, bool32 started) +void UpdateGameData_SetActivity(u8 activity, u32 partnerInfo, bool32 startedActivity) { if (activity != ACTIVITY_NONE) - SetHostRFUtgtGname(activity, flags, started); - rfu_REQ_configGameData(0, 2, (void *)&gHostRFUtgtGnameBuffer, gHostRFUtgtUnameBuffer); + SetHostRfuGameData(activity, partnerInfo, startedActivity); + rfu_REQ_configGameData(0, RFU_SERIAL_GAME, (void *)&gHostRfuGameData, gHostRfuUsername); } -void sub_80110B8(u32 a0) +void SetUnionRoomChatPlayerData(u32 numPlayers) { s32 i; u32 numConnectedChildren; - u32 child_sprite_genders; - s32 r8; + u32 partnerInfo; + s32 slots; - if (GetHostRFUtgtGname()->activity == (ACTIVITY_CHAT | IN_UNION_ROOM)) + if (GetHostRfuGameData()->activity == (ACTIVITY_CHAT | IN_UNION_ROOM)) { numConnectedChildren = 0; - child_sprite_genders = 0; - r8 = Rfu.unk_ce2 ^ Rfu.unk_ce3; - for (i = 0; i < 4; i++) + partnerInfo = 0; + slots = gRfu.parentSlots ^ gRfu.disconnectSlots; + for (i = 0; i < RFU_CHILD_MAX; i++) { - if ((r8 >> i) & 1) + if ((slots >> i) & 1) { - child_sprite_genders |= ((0x80 | ((gLinkPlayers[Rfu.linkPlayerIdx[i]].gender & 1) << 3) | (gLinkPlayers[Rfu.linkPlayerIdx[i]].trainerId & 7)) << (numConnectedChildren << 3)); + // Only trainerId is shifted by the number of children, so the active flag and gender + // are only ever set for the first child + partnerInfo |= ((PINFO_ACTIVE_FLAG + | ((gLinkPlayers[gRfu.linkPlayerIdx[i]].gender & 1) << PINFO_GENDER_SHIFT) + | (gLinkPlayers[gRfu.linkPlayerIdx[i]].trainerId & PINFO_TID_MASK)) << (numConnectedChildren * 8)); numConnectedChildren++; - if (numConnectedChildren == a0 - 1) + if (numConnectedChildren == numPlayers - 1) break; } } - UpdateGameData_SetActivity((ACTIVITY_CHAT | IN_UNION_ROOM), child_sprite_genders, FALSE); + UpdateGameData_SetActivity(ACTIVITY_CHAT | IN_UNION_ROOM, partnerInfo, FALSE); } } -void GetLinkmanErrorParams(u32 msg) +void RfuSetErrorParams(u32 errorInfo) { - if (Rfu.errorState == 0) + if (gRfu.errorState == RFU_ERROR_STATE_NONE) { - Rfu.unk_10 = lman.param[0]; - Rfu.unk_12 = lman.param[1]; - Rfu.linkmanMsg = msg; - Rfu.errorState = 1; + gRfu.errorParam0 = lman.param[0]; + gRfu.errorParam1 = lman.param[1]; + gRfu.errorInfo = errorInfo; + gRfu.errorState = RFU_ERROR_STATE_OCCURRED; } } static void ResetErrorState(void) { - Rfu.errorState = 0; + gRfu.errorState = RFU_ERROR_STATE_NONE; } -void sub_80111B0(bool32 a0) +void RfuSetIgnoreError(bool32 enable) { - if (!a0) - Rfu.errorState = 0; + if (!enable) + gRfu.errorState = RFU_ERROR_STATE_NONE; else - Rfu.errorState = 4; + gRfu.errorState = RFU_ERROR_STATE_IGNORE; } -static void sub_80111DC(void) +static void DisconnectNewChild(void) { - sub_8011E94(lman.acceptSlot_flag, 1); - Rfu.callback = NULL; + SendDisconnectCommand(lman.acceptSlot_flag, RFU_DISCONNECT_ERROR); + gRfu.callback = NULL; } -static void sub_80111FC(void) +static void StartDisconnectNewChild(void) { - Rfu.callback = sub_80111DC; + gRfu.callback = DisconnectNewChild; } -static void sub_801120C(u8 msg, u8 paramCount) +static void LinkManagerCB_Parent(u8 msg, u8 paramCount) { u8 i; u8 disconnectFlag = 0; switch (msg) { case LMAN_MSG_INITIALIZE_COMPLETED: - Rfu.state = 2; + gRfu.state = RFUSTATE_PARENT_CONNECT; break; case LMAN_MSG_NEW_CHILD_CONNECT_DETECTED: break; case LMAN_MSG_NEW_CHILD_CONNECT_ACCEPTED: - sub_80115EC(lman.param[0]); + ParentResetChildRecvMetadata(lman.param[0]); for (i = 0; i < RFU_CHILD_MAX; i++) { if ((lman.param[0] >> i) & 1) { - struct GFtgtGname *structPtr = (void *)gRfuLinkStatus->partner[i].gname; - if (structPtr->activity == GetHostRFUtgtGname()->activity) + struct RfuGameData *data = (void *)gRfuLinkStatus->partner[i].gname; + if (data->activity == GetHostRfuGameData()->activity) { - Rfu.partnerSendStatuses[i] = RFU_STATUS_OK; - Rfu.partnerRecvStatuses[i] = RFU_STATUS_OK; - rfu_setRecvBuffer(TYPE_NI, i, &Rfu.partnerRecvStatuses[i], 1); + gRfu.partnerSendStatuses[i] = RFU_STATUS_OK; + gRfu.partnerRecvStatuses[i] = RFU_STATUS_OK; + rfu_setRecvBuffer(TYPE_NI, i, &gRfu.partnerRecvStatuses[i], sizeof(gRfu.partnerRecvStatuses[0])); } else { @@ -2135,104 +2210,103 @@ static void sub_801120C(u8 msg, u8 paramCount) case LMAN_MSG_SEARCH_CHILD_PERIOD_EXPIRED: break; case LMAN_MSG_END_WAIT_CHILD_NAME: - if (Rfu.acceptSlot_flag != lman.acceptSlot_flag) + if (gRfu.acceptSlot_flag != lman.acceptSlot_flag) { - rfu_REQ_disconnect(Rfu.acceptSlot_flag ^ lman.acceptSlot_flag); + rfu_REQ_disconnect(gRfu.acceptSlot_flag ^ lman.acceptSlot_flag); rfu_waitREQComplete(); } - Rfu.state = 17; + gRfu.state = RFUSTATE_PARENT_FINALIZE_START; break; case LMAN_MSG_LINK_LOSS_DETECTED_AND_START_RECOVERY: - Rfu.linkLossRecoveryState = 1; + gRfu.linkLossRecoveryState = 1; break; case LMAN_MSG_LINK_RECOVERY_SUCCESSED: - Rfu.linkLossRecoveryState = 3; + gRfu.linkLossRecoveryState = 3; break; case LMAN_MSG_LINK_LOSS_DETECTED_AND_DISCONNECTED: case LMAN_MSG_LINK_RECOVERY_FAILED_AND_DISCONNECTED: - Rfu.linkLossRecoveryState = 4; - Rfu.unk_ce2 &= ~lman.param[0]; + gRfu.linkLossRecoveryState = 4; + gRfu.parentSlots &= ~lman.param[0]; if (gReceivedRemoteLinkPlayers == 1) { - if (Rfu.unk_ce2 == 0) - GetLinkmanErrorParams(msg); + if (gRfu.parentSlots == 0) + RfuSetErrorParams(msg); else - sub_80111FC(); + StartDisconnectNewChild(); } RfuSetStatus(RFU_STATUS_CONNECTION_ERROR, msg); break; - case 0x34: - break; + case 0x34: // ? Not a valid LMAN_MSG value case LMAN_MSG_RFU_POWER_DOWN: case LMAN_MSG_MANAGER_STOPPED: case LMAN_MSG_MANAGER_FORCED_STOPPED_AND_RFU_RESET: break; case LMAN_MSG_LMAN_API_ERROR_RETURN: RfuSetStatus(RFU_STATUS_FATAL_ERROR, msg); - GetLinkmanErrorParams(msg); - Rfu.isShuttingDown = TRUE; + RfuSetErrorParams(msg); + gRfu.isShuttingDown = TRUE; break; case LMAN_MSG_REQ_API_ERROR: case LMAN_MSG_WATCH_DOG_TIMER_ERROR: case LMAN_MSG_CLOCK_SLAVE_MS_CHANGE_ERROR_BY_DMA: case LMAN_MSG_RFU_FATAL_ERROR: - GetLinkmanErrorParams(msg); + RfuSetErrorParams(msg); RfuSetStatus(RFU_STATUS_FATAL_ERROR, msg); - Rfu.unk_cdb = TRUE; + gRfu.parentFinished = TRUE; break; } } -void sub_8011404(u8 msg, u8 unused1) +static void LinkManagerCB_Child(u8 msg, u8 unused1) { switch (msg) { case LMAN_MSG_INITIALIZE_COMPLETED: - Rfu.state = 6; + gRfu.state = RFUSTATE_CHILD_CONNECT; break; case LMAN_MSG_PARENT_FOUND: - Rfu.parentId = lman.param[0]; + gRfu.parentId = lman.param[0]; break; case LMAN_MSG_SEARCH_PARENT_PERIOD_EXPIRED: break; case LMAN_MSG_CONNECT_PARENT_SUCCESSED: - Rfu.childSlot = lman.param[0]; + gRfu.childSlot = lman.param[0]; break; case LMAN_MSG_CONNECT_PARENT_FAILED: RfuSetStatus(RFU_STATUS_CONNECTION_ERROR, msg); break; case LMAN_MSG_CHILD_NAME_SEND_COMPLETED: - Rfu.state = 11; - Rfu.unk_c85 = 0; - Rfu.recvStatus = RFU_STATUS_OK; - rfu_setRecvBuffer(TYPE_NI, Rfu.childSlot, &Rfu.recvStatus, 1); - rfu_setRecvBuffer(TYPE_UNI, Rfu.childSlot, Rfu.unk_c3f, 70); + gRfu.state = RFUSTATE_CHILD_TRY_JOIN; + gRfu.leaveGroupStatus = RFU_STATUS_OK; + gRfu.childRecvStatus = RFU_STATUS_OK; + rfu_setRecvBuffer(TYPE_NI, gRfu.childSlot, &gRfu.childRecvStatus, sizeof(gRfu.childRecvStatus)); + rfu_setRecvBuffer(TYPE_UNI, gRfu.childSlot, gRfu.childRecvQueue, sizeof(gRfu.childRecvQueue)); break; case LMAN_MSG_CHILD_NAME_SEND_FAILED_AND_DISCONNECTED: RfuSetStatus(RFU_STATUS_CONNECTION_ERROR, msg); break; case LMAN_MSG_LINK_LOSS_DETECTED_AND_DISCONNECTED: - Rfu.linkLossRecoveryState = 2; - if (Rfu.recvStatus == RFU_STATUS_JOIN_GROUP_NO) + gRfu.linkLossRecoveryState = 2; + if (gRfu.childRecvStatus == RFU_STATUS_JOIN_GROUP_NO) break; case LMAN_MSG_LINK_RECOVERY_FAILED_AND_DISCONNECTED: - if (Rfu.linkLossRecoveryState != 2) - Rfu.linkLossRecoveryState = 4; - if (Rfu.recvStatus != RFU_STATUS_LEAVE_GROUP) + if (gRfu.linkLossRecoveryState != 2) + gRfu.linkLossRecoveryState = 4; + if (gRfu.childRecvStatus != RFU_STATUS_LEAVE_GROUP) RfuSetStatus(RFU_STATUS_CONNECTION_ERROR, msg); Debug_PrintString(sASCII_LinkLossDisconnect, 5, 5); if (gReceivedRemoteLinkPlayers == 1) - GetLinkmanErrorParams(msg); + RfuSetErrorParams(msg); break; case LMAN_MSG_LINK_LOSS_DETECTED_AND_START_RECOVERY: - Rfu.linkLossRecoveryState = 1; + gRfu.linkLossRecoveryState = 1; Debug_PrintString(sASCII_LinkLossRecoveryNow, 5, 5); break; case LMAN_MSG_LINK_RECOVERY_SUCCESSED: - Rfu.linkLossRecoveryState = 3; - Rfu.linkRecovered = TRUE; + gRfu.linkLossRecoveryState = 3; + gRfu.linkRecovered = TRUE; break; - case 0x34: + case 0x34: // ? Not a valid LMAN_MSG value break; case LMAN_MSG_RFU_POWER_DOWN: case LMAN_MSG_MANAGER_STOPPED: @@ -2240,45 +2314,45 @@ void sub_8011404(u8 msg, u8 unused1) break; case LMAN_MSG_LMAN_API_ERROR_RETURN: RfuSetStatus(RFU_STATUS_FATAL_ERROR, msg); - GetLinkmanErrorParams(msg); - Rfu.isShuttingDown = TRUE; + RfuSetErrorParams(msg); + gRfu.isShuttingDown = TRUE; break; case LMAN_MSG_REQ_API_ERROR: case LMAN_MSG_WATCH_DOG_TIMER_ERROR: case LMAN_MSG_CLOCK_SLAVE_MS_CHANGE_ERROR_BY_DMA: case LMAN_MSG_RFU_FATAL_ERROR: RfuSetStatus(RFU_STATUS_FATAL_ERROR, msg); - GetLinkmanErrorParams(msg); - Rfu.unk_cdb = TRUE; + RfuSetErrorParams(msg); + gRfu.parentFinished = TRUE; break; } } -static void sub_80115EC(s32 a0) +static void ParentResetChildRecvMetadata(s32 slot) { s32 i; for (i = 0; i < RFU_CHILD_MAX; i++) { - if ((a0 >> i) & 1) + if ((slot >> i) & 1) { - Rfu.unk_cea[i] = 0; - Rfu.unk_cee[i] = 0xFF; + gRfu.numChildRecvErrors[i] = 0; + gRfu.childRecvIds[i] = 0xFF; } } } -static u8 GetNewChildrenInUnionRoomChat(s32 a0) +static u8 GetNewChildrenInUnionRoomChat(s32 emptySlotMask) { u8 ret = 0; u8 i; for (i = 0; i < RFU_CHILD_MAX; i++) { - if ((a0 >> i) & 1) + if ((emptySlotMask >> i) & 1) { - struct GFtgtGname *structPtr = (void *)gRfuLinkStatus->partner[i].gname; - if (structPtr->activity == (ACTIVITY_CHAT | IN_UNION_ROOM)) + struct RfuGameData *data = (void *)gRfuLinkStatus->partner[i].gname; + if (data->activity == (ACTIVITY_CHAT | IN_UNION_ROOM)) ret |= (1 << i); } } @@ -2286,78 +2360,78 @@ static u8 GetNewChildrenInUnionRoomChat(s32 a0) return ret; } -static void sub_8011674(u8 msg, u8 paramCount) +static void LinkManagerCB_UnionRoom(u8 msg, u8 paramCount) { - u8 r1; + u8 acceptSlot; switch (msg) { case LMAN_MSG_INITIALIZE_COMPLETED: - Rfu.state = 17; + gRfu.state = RFUSTATE_UR_CONNECT; break; case LMAN_MSG_NEW_CHILD_CONNECT_DETECTED: RfuSetStatus(RFU_STATUS_NEW_CHILD_DETECTED, 0); break; case LMAN_MSG_NEW_CHILD_CONNECT_ACCEPTED: - if (GetHostRFUtgtGname()->activity == (ACTIVITY_CHAT | IN_UNION_ROOM) && Rfu.unk_cd9 == 0) + if (GetHostRfuGameData()->activity == (ACTIVITY_CHAT | IN_UNION_ROOM) && !gRfu.stopNewConnections) { - u8 idx = GetNewChildrenInUnionRoomChat(lman.param[0]); - if (idx != 0) + u8 newChildren = GetNewChildrenInUnionRoomChat(lman.param[0]); + if (newChildren != 0) { - r1 = 1 << sub_800E87C(idx); - if (Rfu.unk_ce6 == 0 && Rfu.unk_ce8 == 0) + acceptSlot = 1 << Rfu_GetIndexOfNewestChild(newChildren); + if (gRfu.newChildQueue == 0 && !gRfu.playerExchangeActive) { - Rfu.unk_ce5 = r1; - Rfu.unk_ce6 |= (r1 ^ idx); - Rfu.unk_ce8 = TRUE; + gRfu.nextChildBits = acceptSlot; + gRfu.newChildQueue |= (acceptSlot ^ newChildren); + gRfu.playerExchangeActive = TRUE; } else { - Rfu.unk_ce6 |= idx; + gRfu.newChildQueue |= newChildren; } } - if (idx != lman.param[0]) + if (newChildren != lman.param[0]) { - Rfu.unk_ce3 |= (idx ^ lman.param[0]); - Rfu.unk_ce4 = 2; + gRfu.disconnectSlots |= (newChildren ^ lman.param[0]); + gRfu.disconnectMode = RFU_DISCONNECT_NORMAL; } } - else if (GetHostRFUtgtGname()->activity == (ACTIVITY_PLYRTALK | IN_UNION_ROOM)) + else if (GetHostRfuGameData()->activity == (ACTIVITY_PLYRTALK | IN_UNION_ROOM)) { rfu_REQ_disconnect(lman.acceptSlot_flag); rfu_waitREQComplete(); } - sub_80115EC(lman.param[0]); + ParentResetChildRecvMetadata(lman.param[0]); break; case LMAN_MSG_NEW_CHILD_CONNECT_REJECTED: break; case LMAN_MSG_SEARCH_CHILD_PERIOD_EXPIRED: break; case LMAN_MSG_END_WAIT_CHILD_NAME: - if (GetHostRFUtgtGname()->activity != (ACTIVITY_CHAT | IN_UNION_ROOM) && lman.acceptCount > 1) + if (GetHostRfuGameData()->activity != (ACTIVITY_CHAT | IN_UNION_ROOM) && lman.acceptCount > 1) { - r1 = 1 << sub_800E87C(lman.param[0]); - rfu_REQ_disconnect(lman.acceptSlot_flag ^ r1); + acceptSlot = 1 << Rfu_GetIndexOfNewestChild(lman.param[0]); + rfu_REQ_disconnect(lman.acceptSlot_flag ^ acceptSlot); rfu_waitREQComplete(); } - if (Rfu.state == 15) - Rfu.state = 16; + if (gRfu.state == RFUSTATE_UR_STOP_MANAGER_END) + gRfu.state = RFUSTATE_UR_FINALIZE; break; break; case LMAN_MSG_PARENT_FOUND: - Rfu.parentId = lman.param[0]; + gRfu.parentId = lman.param[0]; break; case LMAN_MSG_SEARCH_PARENT_PERIOD_EXPIRED: break; case LMAN_MSG_CONNECT_PARENT_SUCCESSED: - Rfu.childSlot = lman.param[0]; + gRfu.childSlot = lman.param[0]; break; case LMAN_MSG_CONNECT_PARENT_FAILED: - Rfu.state = 18; - if (Rfu.unk_ccf < 2) + gRfu.state = RFUSTATE_UR_CONNECT_END; + if (gRfu.connectParentFailures < 2) { - Rfu.unk_ccf++; - CreateTask(sub_801209C, 2); + gRfu.connectParentFailures++; + CreateTask(Task_TryConnectToUnionRoomParent, 2); } else { @@ -2365,51 +2439,53 @@ static void sub_8011674(u8 msg, u8 paramCount) } break; case LMAN_MSG_CHILD_NAME_SEND_COMPLETED: - Rfu.state = 13; + gRfu.state = RFUSTATE_UR_PLAYER_EXCHANGE; RfuSetStatus(RFU_STATUS_CHILD_SEND_COMPLETE, 0); - rfu_setRecvBuffer(TYPE_UNI, Rfu.childSlot, Rfu.unk_c3f, 70); + rfu_setRecvBuffer(TYPE_UNI, gRfu.childSlot, gRfu.childRecvQueue, sizeof(gRfu.childRecvQueue)); break; case LMAN_MSG_CHILD_NAME_SEND_FAILED_AND_DISCONNECTED: RfuSetStatus(RFU_STATUS_CONNECTION_ERROR, msg); break; case LMAN_MSG_LINK_LOSS_DETECTED_AND_START_RECOVERY: if (lman.acceptSlot_flag & lman.param[0]) - Rfu.linkLossRecoveryState = 1; + gRfu.linkLossRecoveryState = 1; break; case LMAN_MSG_LINK_RECOVERY_SUCCESSED: - Rfu.linkLossRecoveryState = 3; + gRfu.linkLossRecoveryState = 3; if (gRfuLinkStatus->parentChild == MODE_CHILD) - Rfu.linkRecovered = TRUE; + gRfu.linkRecovered = TRUE; break; case LMAN_MSG_LINK_LOSS_DETECTED_AND_DISCONNECTED: - Rfu.linkLossRecoveryState = 2; + gRfu.linkLossRecoveryState = 2; case LMAN_MSG_LINK_RECOVERY_FAILED_AND_DISCONNECTED: - if (Rfu.linkLossRecoveryState != 2) - Rfu.linkLossRecoveryState = 4; - if (Rfu.parentChild == MODE_PARENT) + if (gRfu.linkLossRecoveryState != 2) + gRfu.linkLossRecoveryState = 4; + if (gRfu.parentChild == MODE_PARENT) { if (gReceivedRemoteLinkPlayers == 1) { - Rfu.unk_ce2 &= ~(lman.param[0]); - if (Rfu.unk_ce2 == 0) - GetLinkmanErrorParams(msg); + gRfu.parentSlots &= ~(lman.param[0]); + if (gRfu.parentSlots == 0) + RfuSetErrorParams(msg); else - sub_80111FC(); + StartDisconnectNewChild(); } } - else if (Rfu.unk_ce4 != 2 && gReceivedRemoteLinkPlayers == 1) + else if (gRfu.disconnectMode != RFU_DISCONNECT_NORMAL && gReceivedRemoteLinkPlayers == 1) { - GetLinkmanErrorParams(msg); - rfu_LMAN_stopManager(0); + RfuSetErrorParams(msg); + rfu_LMAN_stopManager(FALSE); } - if (gRfuLinkStatus->parentChild == MODE_NEUTRAL && lman.pcswitch_flag == 0 && FuncIsActiveTask(Task_LinkRfu_UnionRoomListen) == TRUE) - Rfu.state = 17; + if (gRfuLinkStatus->parentChild == MODE_NEUTRAL + && !lman.pcswitch_flag + && FuncIsActiveTask(Task_UnionRoomListen) == TRUE) + gRfu.state = RFUSTATE_UR_CONNECT; RfuSetStatus(RFU_STATUS_CONNECTION_ERROR, msg); break; case LMAN_MSG_LINK_DISCONNECTED_BY_USER: - Rfu.unk_ce3 = 0; + gRfu.disconnectSlots = 0; break; case LMAN_MSG_RFU_POWER_DOWN: case LMAN_MSG_MANAGER_STOPPED: @@ -2417,34 +2493,34 @@ static void sub_8011674(u8 msg, u8 paramCount) break; case LMAN_MSG_LMAN_API_ERROR_RETURN: RfuSetStatus(RFU_STATUS_FATAL_ERROR, msg); - GetLinkmanErrorParams(msg); - Rfu.isShuttingDown = TRUE; + RfuSetErrorParams(msg); + gRfu.isShuttingDown = TRUE; break; case LMAN_MSG_REQ_API_ERROR: case LMAN_MSG_WATCH_DOG_TIMER_ERROR: case LMAN_MSG_CLOCK_SLAVE_MS_CHANGE_ERROR_BY_DMA: case LMAN_MSG_RFU_FATAL_ERROR: - GetLinkmanErrorParams(msg); + RfuSetErrorParams(msg); RfuSetStatus(RFU_STATUS_FATAL_ERROR, msg); - Rfu.unk_cdb = FALSE; + gRfu.parentFinished = FALSE; break; } } -void sub_8011A50(void) +void RfuSetNormalDisconnectMode(void) { - Rfu.unk_ce4 = 2; + gRfu.disconnectMode = RFU_DISCONNECT_NORMAL; } -void RfuSetStatus(u8 status, u16 msg) +void RfuSetStatus(u8 status, u16 errorInfo) { - Rfu.status = status; - Rfu.linkmanMsg = msg; + gRfu.status = status; + gRfu.errorInfo = errorInfo; } u8 RfuGetStatus(void) { - return Rfu.status; + return gRfu.status; } bool32 RfuHasErrored(void) @@ -2457,14 +2533,14 @@ bool32 RfuHasErrored(void) return FALSE; } -bool32 sub_8011A9C(void) +bool32 Rfu_IsPlayerExchangeActive(void) { - return Rfu.unk_ce8; + return gRfu.playerExchangeActive; } bool8 Rfu_IsMaster(void) { - return Rfu.parentChild; + return gRfu.parentChild; } void RfuVSync(void) @@ -2477,14 +2553,15 @@ void ClearRecvCommands(void) CpuFill32(0, gRecvCmds, sizeof(gRecvCmds)); } -static void sub_8011AE8(void) +static void VBlank_RfuIdle(void) { LoadOam(); ProcessSpriteCopyRequests(); TransferPlttBuffer(); } -static void sub_8011AFC(void) +// Unused +static void Debug_RfuIdle(void) { s32 i; @@ -2492,14 +2569,14 @@ static void sub_8011AFC(void) FreeAllSpritePalettes(); ResetTasks(); ResetPaletteFade(); - SetVBlankCallback(sub_8011AE8); + SetVBlankCallback(VBlank_RfuIdle); if (IsWirelessAdapterConnected()) { gLinkType = LINKTYPE_TRADE; SetWirelessCommType1(); OpenLink(); SeedRng(gMain.vblankCounter2); - for (i = 0; i < 4; i++) + for (i = 0; i < TRAINER_ID_LENGTH; i++) gSaveBlock2Ptr->playerTrainerId[i] = Random() % 256; SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_BG0_ON | DISPCNT_BG2_ON | DISPCNT_OBJ_1D_MAP); @@ -2508,28 +2585,28 @@ static void sub_8011AFC(void) BuildOamBuffer(); UpdatePaletteFade(); CreateTask_RfuIdle(); - SetMainCallback2(sub_8011BF8); + SetMainCallback2(CB2_RfuIdle); } } bool32 IsUnionRoomListenTaskActive(void) { - return FuncIsActiveTask(Task_LinkRfu_UnionRoomListen); + return FuncIsActiveTask(Task_UnionRoomListen); } void CreateTask_RfuIdle(void) { if (!FuncIsActiveTask(Task_Idle)) - Rfu.idleTaskId = CreateTask(Task_Idle, 0); + gRfu.idleTaskId = CreateTask(Task_Idle, 0); } void DestroyTask_RfuIdle(void) { if (FuncIsActiveTask(Task_Idle) == TRUE) - DestroyTask(Rfu.idleTaskId); + DestroyTask(gRfu.idleTaskId); } -static void sub_8011BF8(void) +static void CB2_RfuIdle(void) { RunTasks(); AnimateSprites(); @@ -2537,33 +2614,33 @@ static void sub_8011BF8(void) UpdatePaletteFade(); } -void InitializeRfuLinkManager_LinkLeader(u32 a0) +void InitializeRfuLinkManager_LinkLeader(u32 groupMax) { - Rfu.parentChild = MODE_PARENT; - CopyPlayerNameToUnameBuffer(); - rfu_LMAN_initializeManager(sub_801120C, NULL); + gRfu.parentChild = MODE_PARENT; + SetHostRfuUsername(); + rfu_LMAN_initializeManager(LinkManagerCB_Parent, NULL); sRfuReqConfig = sRfuReqConfigTemplate; - sRfuReqConfig.availSlot_flag = sAvailSlots[a0 - 1]; - CreateTask_LinkLeaderSearchForChildren(); + sRfuReqConfig.availSlot_flag = sAvailSlots[groupMax - 1]; + CreateTask_ParentSearchForChildren(); } void InitializeRfuLinkManager_JoinGroup(void) { - Rfu.parentChild = MODE_CHILD; - CopyPlayerNameToUnameBuffer(); - rfu_LMAN_initializeManager(sub_8011404, sub_800ED34); - CreateTask_JoinGroupSearchForParent(); + gRfu.parentChild = MODE_CHILD; + SetHostRfuUsername(); + rfu_LMAN_initializeManager(LinkManagerCB_Child, MSCCallback_Child); + CreateTask_ChildSearchForParent(); } void InitializeRfuLinkManager_EnterUnionRoom(void) { - Rfu.parentChild = 2; - CopyPlayerNameToUnameBuffer(); - rfu_LMAN_initializeManager(sub_8011674, NULL); + gRfu.parentChild = MODE_P_C_SWITCH; + SetHostRfuUsername(); + rfu_LMAN_initializeManager(LinkManagerCB_UnionRoom, NULL); sRfuReqConfig = sRfuReqConfigTemplate; sRfuReqConfig.linkRecovery_enable = 0; sRfuReqConfig.linkRecovery_period = 600; - Rfu.searchTaskId = CreateTask(Task_LinkRfu_UnionRoomListen, 1); + gRfu.searchTaskId = CreateTask(Task_UnionRoomListen, 1); } static u16 ReadU16(const void *ptr) @@ -2597,10 +2674,10 @@ static void RfuReqDisconnectSlot(u32 slot) { rfu_REQ_disconnect(slot); rfu_waitREQComplete(); - Rfu.unk_ce2 &= ~(slot); - rfu_clearSlot(1, Rfu.unk_cda); - rfu_UNI_setSendData(Rfu.unk_ce2, Rfu.recvCmds, 70); - Rfu.unk_cda = sub_800E87C(Rfu.unk_ce2); + gRfu.parentSlots &= ~slot; + rfu_clearSlot(1, gRfu.parentSendSlot); + rfu_UNI_setSendData(gRfu.parentSlots, gRfu.recvCmds, sizeof(gRfu.recvCmds)); + gRfu.parentSendSlot = Rfu_GetIndexOfNewestChild(gRfu.parentSlots); } void RequestDisconnectSlotByTrainerNameAndId(const u8 *name, u16 id) @@ -2610,132 +2687,147 @@ void RequestDisconnectSlotByTrainerNameAndId(const u8 *name, u16 id) RfuReqDisconnectSlot(1 << var); } -void sub_8011DE0(u32 a0) +void Rfu_DisconnectPlayerById(u32 playerIdx) { - if (a0 != 0) + if (playerIdx != 0) { s32 i; - u8 var = 0; + u8 toDisconnect = 0; for (i = 0; i < RFU_CHILD_MAX; i++) { - if (Rfu.linkPlayerIdx[i] == a0 && (Rfu.unk_ce2 >> i) & 1) - var |= 1 << i; + if (gRfu.linkPlayerIdx[i] == playerIdx && (gRfu.parentSlots >> i) & 1) + toDisconnect |= 1 << i; } - if (var) - sub_8011E94(var, 2); + if (toDisconnect) + SendDisconnectCommand(toDisconnect, RFU_DISCONNECT_NORMAL); } } -static void sub_8011E2C(u8 taskId) +#define tDisconnectPlayers data[0] +#define tDisconnectMode data[1] + +static void Task_SendDisconnectCommand(u8 taskId) { - if (gSendCmd[0] == 0 && Rfu.unk_ce8 == 0) + if (gSendCmd[0] == 0 && !gRfu.playerExchangeActive) { - RfuPrepareSendBuffer(RFUCMD_0xED00); - gSendCmd[1] = gTasks[taskId].data[0]; - gSendCmd[2] = gTasks[taskId].data[1]; - Rfu.playerCount -= sUnknown_082ED695[gTasks[taskId].data[0]]; - gSendCmd[3] = Rfu.playerCount; + RfuPrepareSendBuffer(RFUCMD_DISCONNECT); + gSendCmd[1] = gTasks[taskId].tDisconnectPlayers; + gSendCmd[2] = gTasks[taskId].tDisconnectMode; + gRfu.playerCount -= sPlayerBitsToCount[gTasks[taskId].tDisconnectPlayers]; + gSendCmd[3] = gRfu.playerCount; DestroyTask(taskId); } } -static void sub_8011E94(u32 a0, u32 a1) +static void SendDisconnectCommand(u32 playersToDisconnect, u32 disconnectMode) { - u8 taskId = FindTaskIdByFunc(sub_8011E2C); + u8 taskId = FindTaskIdByFunc(Task_SendDisconnectCommand); if (taskId == TASK_NONE) { - taskId = CreateTask(sub_8011E2C, 5); - gTasks[taskId].data[0] = a0; + taskId = CreateTask(Task_SendDisconnectCommand, 5); + gTasks[taskId].tDisconnectPlayers = playersToDisconnect; } else { - gTasks[taskId].data[0] |= a0; + // Task is already active, just add the new players to disconnect + gTasks[taskId].tDisconnectPlayers |= playersToDisconnect; } - gTasks[taskId].data[1] = a1; + gTasks[taskId].tDisconnectMode = disconnectMode; } +#undef tDisconnectMode + +#define tTime data[15] + static void Task_RfuReconnectWithParent(u8 taskId) { s16 *data = gTasks[taskId].data; - if (sub_800EE94()) + if (CanTryReconnectParent()) { u8 id = GetPartnerIndexByNameAndTrainerID((u8*)data, ReadU16(&data[8])); if (id != 0xFF) { if (gRfuLinkStatus->partner[id].slot != 0xFF) { - Rfu.unk_c3d = id; - if (IsParentSuccessfullyReconnected()) + gRfu.reconnectParentId = id; + if (TryReconnectParent()) DestroyTask(taskId); } - else if (GetHostRFUtgtGname()->activity == ACTIVITY_WONDER_CARD2 - || GetHostRFUtgtGname()->activity == ACTIVITY_WONDER_NEWS2) + else if (GetHostRfuGameData()->activity == ACTIVITY_WONDER_CARD + || GetHostRfuGameData()->activity == ACTIVITY_WONDER_NEWS) { - data[15]++; + tTime++; } else { - RfuSetStatus(RFU_STATUS_CONNECTION_ERROR, 0x7000); + // Error, unable to reconnect to parent + RfuSetStatus(RFU_STATUS_CONNECTION_ERROR, F_RFU_ERROR_5 | F_RFU_ERROR_6 | F_RFU_ERROR_7); DestroyTask(taskId); } } else { - data[15]++; - Rfu.unk_c3d = id; + tTime++; + gRfu.reconnectParentId = id; } } else { - data[15]++; + tTime++; } - if (data[15] > 240) + if (tTime > 240) { - RfuSetStatus(RFU_STATUS_CONNECTION_ERROR, 0x7000); + // Timeout error + RfuSetStatus(RFU_STATUS_CONNECTION_ERROR, F_RFU_ERROR_5 | F_RFU_ERROR_6 | F_RFU_ERROR_7); DestroyTask(taskId); } } +#undef tTime + void CreateTask_RfuReconnectWithParent(const u8 *name, u16 trainerId) { u8 taskId; s16 *data; - Rfu.status = RFU_STATUS_OK; + gRfu.status = RFU_STATUS_OK; taskId = CreateTask(Task_RfuReconnectWithParent, 3); data = gTasks[taskId].data; StringCopy((u8*)(data), name); data[8] = trainerId; } -static bool32 ShouldRejectPartnerConnectionBasedOnActivity(s16 activity, struct GFtgtGname *partnerGname) +static bool32 IsPartnerActivityIncompatible(s16 activity, struct RfuGameData *partner) { - if (GetHostRFUtgtGname()->activity == (ACTIVITY_CHAT | IN_UNION_ROOM)) + if (GetHostRfuGameData()->activity == (ACTIVITY_CHAT | IN_UNION_ROOM)) { - if (partnerGname->activity != (ACTIVITY_CHAT | IN_UNION_ROOM)) + // Host trying to chat, but partner isn't + if (partner->activity != (ACTIVITY_CHAT | IN_UNION_ROOM)) return TRUE; } - else if (partnerGname->activity != IN_UNION_ROOM) + else if (partner->activity != IN_UNION_ROOM) { + // Partner not in union room return TRUE; } else if (activity == (ACTIVITY_TRADE | IN_UNION_ROOM)) { - struct GFtgtGname *tradeGname = &Rfu.unk_10A; - if (tradeGname->species == SPECIES_EGG) + // Verify that the trade offered hasn't changed + struct RfuGameData *original = &gRfu.parent; + if (original->tradeSpecies == SPECIES_EGG) { - if (partnerGname->species == tradeGname->species) + if (partner->tradeSpecies == original->tradeSpecies) return FALSE; else return TRUE; } - else if (partnerGname->species != tradeGname->species - || partnerGname->level != tradeGname->level - || partnerGname->type != tradeGname->type) + else if (partner->tradeSpecies != original->tradeSpecies + || partner->tradeLevel != original->tradeLevel + || partner->tradeType != original->tradeType) { return TRUE; } @@ -2744,79 +2836,91 @@ static bool32 ShouldRejectPartnerConnectionBasedOnActivity(s16 activity, struct return FALSE; } -static void sub_801209C(u8 taskId) +#define tTime data[0] +#define tActivity data[1] + +static void Task_TryConnectToUnionRoomParent(u8 taskId) { - if (Rfu.status == RFU_STATUS_NEW_CHILD_DETECTED) + // Stop task if player is the new parent + if (gRfu.status == RFU_STATUS_NEW_CHILD_DETECTED) DestroyTask(taskId); - if (++gTasks[taskId].data[0] > 300) + if (++gTasks[taskId].tTime > 300) { - RfuSetStatus(RFU_STATUS_CONNECTION_ERROR, 0x7000); + // Timeout error + RfuSetStatus(RFU_STATUS_CONNECTION_ERROR, F_RFU_ERROR_5 | F_RFU_ERROR_6 | F_RFU_ERROR_7); DestroyTask(taskId); } - if (Rfu.parentId != 0 && lman.parent_child == 0) + // Check if parent should be searched for + if (gRfu.parentId != 0 && lman.parent_child == MODE_CHILD) { - u16 trainerId = ReadU16(Rfu.unk_10A.unk_00.playerTrainerId); - u8 id = GetPartnerIndexByNameAndTrainerID(Rfu.playerName, trainerId); + // Search for parent + u16 trainerId = ReadU16(gRfu.parent.compatibility.playerTrainerId); + u8 id = GetPartnerIndexByNameAndTrainerID(gRfu.parentName, trainerId); if (id != 0xFF) { - if (!ShouldRejectPartnerConnectionBasedOnActivity(gTasks[taskId].data[1], (void *)gRfuLinkStatus->partner[id].gname)) + // Parent found, try to connect + if (!IsPartnerActivityIncompatible(gTasks[taskId].tActivity, (void *)gRfuLinkStatus->partner[id].gname)) { - if (gRfuLinkStatus->partner[id].slot != 0xFF && !rfu_LMAN_CHILD_connectParent(gRfuLinkStatus->partner[id].id, 0x5A)) + if (gRfuLinkStatus->partner[id].slot != 0xFF && !rfu_LMAN_CHILD_connectParent(gRfuLinkStatus->partner[id].id, 90)) { - Rfu.state = 0xA; + // Succesfully connected to parent + gRfu.state = RFUSTATE_CONNECTED; DestroyTask(taskId); } } else { - RfuSetStatus(RFU_STATUS_CONNECTION_ERROR, 0x7000); + // Incompatible partner activity + RfuSetStatus(RFU_STATUS_CONNECTION_ERROR, F_RFU_ERROR_5 | F_RFU_ERROR_6 | F_RFU_ERROR_7); DestroyTask(taskId); } } } } -void sub_8012188(const u8 *name, struct GFtgtGname *structPtr, u8 activity) +void TryConnectToUnionRoomParent(const u8 *name, struct RfuGameData *parent, u8 activity) { - u8 taskId, taskId2; + u8 taskId, listenTaskId; - Rfu.unk_ccf = 0; - Rfu.status = RFU_STATUS_OK; - StringCopy(Rfu.playerName, name); - memcpy(&Rfu.unk_10A, structPtr, RFU_GAME_NAME_LENGTH); + gRfu.connectParentFailures = 0; + gRfu.status = RFU_STATUS_OK; + StringCopy(gRfu.parentName, name); + memcpy(&gRfu.parent, parent, RFU_GAME_NAME_LENGTH); rfu_LMAN_forceChangeSP(); - taskId = CreateTask(sub_801209C, 2); - gTasks[taskId].data[1] = activity; - taskId2 = FindTaskIdByFunc(Task_LinkRfu_UnionRoomListen); + taskId = CreateTask(Task_TryConnectToUnionRoomParent, 2); + gTasks[taskId].tActivity = activity; + listenTaskId = FindTaskIdByFunc(Task_UnionRoomListen); if (activity == (ACTIVITY_CHAT | IN_UNION_ROOM)) { - if (taskId2 != TASK_NONE) - gTasks[taskId2].data[7] = 1; + if (listenTaskId != TASK_NONE) + gTasks[listenTaskId].tConnectingForChat = TRUE; } else { - if (taskId2 != TASK_NONE) - gTasks[taskId2].data[7] = 0; + if (listenTaskId != TASK_NONE) + gTasks[listenTaskId].tConnectingForChat = FALSE; } } bool8 IsRfuRecoveringFromLinkLoss(void) { - if (Rfu.linkLossRecoveryState == 1) + if (gRfu.linkLossRecoveryState == 1) return TRUE; else return FALSE; } -bool32 sub_8012240(void) +bool32 IsRfuCommunicatingWithAllChildren(void) { s32 i; - for (i = 0; i < RFU_CHILD_MAX; i++) { - if ((lman.acceptSlot_flag >> i) & 1 && Rfu.partnerSendStatuses[i] == RFU_STATUS_OK) + // RFU_STATUS_OK is the default status. + // If any connected child is receiving a status other + // than OK, then the parent is communicating with them + if ((lman.acceptSlot_flag >> i) & 1 && gRfu.partnerSendStatuses[i] == RFU_STATUS_OK) return FALSE; } @@ -2826,19 +2930,17 @@ bool32 sub_8012240(void) static void Debug_PrintEmpty(void) { s32 i; - for (i = 0; i < 20; i++) - Debug_PrintString(sASCII_30Commas, 0, i); + Debug_PrintString(sASCII_30Spaces, 0, i); } static void Debug_PrintStatus(void) { s32 i, j; - - Debug_PrintNum(GetBlockReceivedStatus(), 0x1C, 0x13, 2); - Debug_PrintNum(gRfuLinkStatus->connSlotFlag, 0x14, 1, 1); - Debug_PrintNum(gRfuLinkStatus->linkLossSlotFlag, 0x17, 1, 1); - if (Rfu.parentChild == MODE_PARENT) + Debug_PrintNum(GetBlockReceivedStatus(), 28, 19, 2); + Debug_PrintNum(gRfuLinkStatus->connSlotFlag, 20, 1, 1); + Debug_PrintNum(gRfuLinkStatus->linkLossSlotFlag, 23, 1, 1); + if (gRfu.parentChild == MODE_PARENT) { for (i = 0; i < RFU_CHILD_MAX; i++) { @@ -2846,29 +2948,27 @@ static void Debug_PrintStatus(void) { Debug_PrintNum(gRfuLinkStatus->partner[i].serialNo, 1, i + 3, 4); Debug_PrintString((void*)gRfuLinkStatus->partner[i].gname, 6, i + 3); - Debug_PrintString(gRfuLinkStatus->partner[i].uname, 0x16, i + 3); + Debug_PrintString(gRfuLinkStatus->partner[i].uname, 22, i + 3); } } for (i = 0; i < RFU_CHILD_MAX; i++) { - for (j = 0; j < (int)ARRAY_COUNT(Rfu.unk_14[0]); j++) - { - Debug_PrintNum(Rfu.unk_14[i][j], j * 2, i + 11, 2); - } + for (j = 0; j < COMM_SLOT_LENGTH; j++) + Debug_PrintNum(gRfu.childRecvBuffer[i][j], j * 2, i + 11, 2); } - Debug_PrintString(sASCII_NowSlot, 1, 0xF); + Debug_PrintString(sASCII_NowSlot, 1, 15); } else if (gRfuLinkStatus->connSlotFlag != 0 && gRfuLinkStatus->getNameFlag != 0) { for (i = 0; i < RFU_CHILD_MAX; i++) { Debug_PrintNum(0, 1, i + 3, 4); - Debug_PrintString(sASCII_15Commas, 6, i + 3); - Debug_PrintString(sASCII_8Commas, 0x16, i + 3); + Debug_PrintString(sASCII_15Spaces, 6, i + 3); + Debug_PrintString(sASCII_8Spaces, 22, i + 3); } - Debug_PrintNum(gRfuLinkStatus->partner[Rfu.childSlot].serialNo, 1, 3, 4); - Debug_PrintString((void*)gRfuLinkStatus->partner[Rfu.childSlot].gname, 6, 3); - Debug_PrintString(gRfuLinkStatus->partner[Rfu.childSlot].uname, 0x16, 3); + Debug_PrintNum(gRfuLinkStatus->partner[gRfu.childSlot].serialNo, 1, 3, 4); + Debug_PrintString((void*)gRfuLinkStatus->partner[gRfu.childSlot].gname, 6, 3); + Debug_PrintString(gRfuLinkStatus->partner[gRfu.childSlot].uname, 22, 3); } else { @@ -2878,26 +2978,26 @@ static void Debug_PrintStatus(void) { Debug_PrintNum(gRfuLinkStatus->partner[i].serialNo, 1, i + 3, 4); Debug_PrintNum(gRfuLinkStatus->partner[i].id, 6, i + 3, 4); - Debug_PrintString(gRfuLinkStatus->partner[i].uname, 0x16, i + 3); + Debug_PrintString(gRfuLinkStatus->partner[i].uname, 22, i + 3); } } for (; i < RFU_CHILD_MAX; i++) { Debug_PrintNum(0, 1, i + 3, 4); - Debug_PrintString(sASCII_15Commas, 6, i + 3); - Debug_PrintString(sASCII_8Commas, 0x16, i + 3); + Debug_PrintString(sASCII_15Spaces, 6, i + 3); + Debug_PrintString(sASCII_8Spaces, 22, i + 3); } } } static u32 GetRfuSendQueueLength(void) { - return Rfu.sendQueue.count; + return gRfu.sendQueue.count; } u32 GetRfuRecvQueueLength(void) { - return Rfu.recvQueue.count; + return gRfu.recvQueue.count; } static void Task_Idle(u8 taskId) diff --git a/src/link_rfu_3.c b/src/link_rfu_3.c index 50828f656..571f305d0 100644 --- a/src/link_rfu_3.c +++ b/src/link_rfu_3.c @@ -15,6 +15,9 @@ enum { WIRELESS_STATUS_ANIM_ERROR, }; +#define TAG_GFX_STATUS_INDICATOR 0xD431 +#define TAG_PAL_STATUS_INDICATOR 0xD432 + #define UNUSED_QUEUE_NUM_SLOTS 2 #define UNUSED_QUEUE_SLOT_LENGTH 256 @@ -29,7 +32,7 @@ struct RfuUnusedQueue EWRAM_DATA u8 gWirelessStatusIndicatorSpriteId = 0; -static u8 sUnknown_03000D74; +static u8 sSequenceArrayValOffset; static const u16 sWirelessLinkIconPalette[] = INCBIN_U16("graphics/interface/wireless_link_icon.gbapal"); static const u32 sWirelessLinkIconPic[] = INCBIN_U32("graphics/interface/wireless_link_icon.4bpp.lz"); @@ -290,16 +293,16 @@ static const union AnimCmd *const sWirelessStatusIndicatorAnims[] = { }; static const struct CompressedSpriteSheet sWirelessStatusIndicatorSpriteSheet = { - sWirelessLinkIconPic, 0x0380, 0xD431 + sWirelessLinkIconPic, 0x0380, TAG_GFX_STATUS_INDICATOR }; static const struct SpritePalette sWirelessStatusIndicatorSpritePalette = { - sWirelessLinkIconPalette, 0xD432 + sWirelessLinkIconPalette, TAG_PAL_STATUS_INDICATOR }; static const struct SpriteTemplate sWirelessStatusIndicatorSpriteTemplate = { - .tileTag = 0xD431, - .paletteTag = 0xD432, + .tileTag = TAG_GFX_STATUS_INDICATOR, + .paletteTag = TAG_PAL_STATUS_INDICATOR, .oam = &sWirelessStatusIndicatorOamData, .anims = sWirelessStatusIndicatorAnims, .images = NULL, @@ -314,10 +317,8 @@ void RfuRecvQueue_Reset(struct RfuRecvQueue *queue) for (i = 0; i < RECV_QUEUE_NUM_SLOTS; i++) { - for (j = 0; j < RECV_QUEUE_SLOT_LENGTH; j++) - { + for (j = 0; j < COMM_SLOT_LENGTH * MAX_RFU_PLAYERS; j++) queue->slots[i][j] = 0; - } } queue->sendSlot = 0; queue->recvSlot = 0; @@ -332,10 +333,8 @@ void RfuSendQueue_Reset(struct RfuSendQueue *queue) for (i = 0; i < SEND_QUEUE_NUM_SLOTS; i++) { - for (j = 0; j < SEND_QUEUE_SLOT_LENGTH; j++) - { + for (j = 0; j < COMM_SLOT_LENGTH; j++) queue->slots[i][j] = 0; - } } queue->sendSlot = 0; queue->recvSlot = 0; @@ -351,9 +350,7 @@ static void RfuUnusedQueue_Reset(struct RfuUnusedQueue *queue) for (i = 0; i < UNUSED_QUEUE_NUM_SLOTS; i++) { for (j = 0; j < UNUSED_QUEUE_SLOT_LENGTH; j++) - { queue->slots[i][j] = 0; - } } queue->sendSlot = 0; queue->recvSlot = 0; @@ -372,21 +369,21 @@ void RfuRecvQueue_Enqueue(struct RfuRecvQueue *queue, u8 *data) imeBak = REG_IME; REG_IME = 0; count = 0; - for (i = 0; i < RECV_QUEUE_SLOT_LENGTH; i += RECV_QUEUE_SLOT_LENGTH / MAX_RFU_PLAYERS) + for (i = 0; i < COMM_SLOT_LENGTH * MAX_RFU_PLAYERS; i += COMM_SLOT_LENGTH) { if (data[i] == 0 && data[i + 1] == 0) count++; } if (count != MAX_RFU_PLAYERS) { - for (i = 0; i < RECV_QUEUE_SLOT_LENGTH; i++) + for (i = 0; i < COMM_SLOT_LENGTH * MAX_RFU_PLAYERS; i++) queue->slots[queue->recvSlot][i] = data[i]; queue->recvSlot++; queue->recvSlot %= RECV_QUEUE_NUM_SLOTS; queue->count++; - for (i = 0; i < RECV_QUEUE_SLOT_LENGTH; i++) + for (i = 0; i < COMM_SLOT_LENGTH * MAX_RFU_PLAYERS; i++) data[i] = 0; } REG_IME = imeBak; @@ -406,22 +403,20 @@ void RfuSendQueue_Enqueue(struct RfuSendQueue *queue, u8 *data) { imeBak = REG_IME; REG_IME = 0; - for (i = 0; i < SEND_QUEUE_SLOT_LENGTH; i++) + for (i = 0; i < COMM_SLOT_LENGTH; i++) { if (data[i] != 0) break; } - if (i != SEND_QUEUE_SLOT_LENGTH) + if (i != COMM_SLOT_LENGTH) { - for (i = 0; i < SEND_QUEUE_SLOT_LENGTH; i++) - { + for (i = 0; i < COMM_SLOT_LENGTH; i++) queue->slots[queue->recvSlot][i] = data[i]; - } queue->recvSlot++; queue->recvSlot %= SEND_QUEUE_NUM_SLOTS; queue->count++; - for (i = 0; i < SEND_QUEUE_SLOT_LENGTH; i++) + for (i = 0; i < COMM_SLOT_LENGTH; i++) data[i] = 0; } REG_IME = imeBak; @@ -441,13 +436,13 @@ bool8 RfuRecvQueue_Dequeue(struct RfuRecvQueue *queue, u8 *src) REG_IME = 0; if (queue->recvSlot == queue->sendSlot || queue->full) { - for (i = 0; i < RECV_QUEUE_SLOT_LENGTH; i++) + for (i = 0; i < COMM_SLOT_LENGTH * MAX_RFU_PLAYERS; i++) src[i] = 0; REG_IME = imeBak; return FALSE; } - for (i = 0; i < RECV_QUEUE_SLOT_LENGTH; i++) + for (i = 0; i < COMM_SLOT_LENGTH * MAX_RFU_PLAYERS; i++) { src[i] = queue->slots[queue->sendSlot][i]; } @@ -468,7 +463,7 @@ bool8 RfuSendQueue_Dequeue(struct RfuSendQueue *queue, u8 *src) imeBak = REG_IME; REG_IME = 0; - for (i = 0; i < SEND_QUEUE_SLOT_LENGTH; i++) + for (i = 0; i < COMM_SLOT_LENGTH; i++) src[i] = queue->slots[queue->sendSlot][i]; queue->sendSlot++; @@ -488,7 +483,7 @@ void RfuBackupQueue_Enqueue(struct RfuBackupQueue *queue, const u8 *data) } else { - for (i = 0; i < BACKUP_QUEUE_SLOT_LENGTH; i++) + for (i = 0; i < COMM_SLOT_LENGTH; i++) queue->slots[queue->recvSlot][i] = data[i]; queue->recvSlot++; @@ -510,7 +505,7 @@ bool8 RfuBackupQueue_Dequeue(struct RfuBackupQueue *queue, u8 *src) if (src != NULL) { - for (i = 0; i < BACKUP_QUEUE_SLOT_LENGTH; i++) + for (i = 0; i < COMM_SLOT_LENGTH; i++) src[i] = queue->slots[queue->sendSlot][i]; } queue->sendSlot++; @@ -555,46 +550,57 @@ static bool8 RfuUnusedQueue_Dequeue(struct RfuUnusedQueue *queue, u8 *dest) } // Unused -static void sub_800DBF8(u8 *q1, u8 mode) +// Populates an array with a sequence of numbers (which numbers depends on the mode) +// and sets the final element to the total of the other elements +#define SEQ_ARRAY_MAX_SIZE 200 +static void PopulateArrayWithSequence(u8 *arr, u8 mode) { s32 i; u8 rval; - u16 r5 = 0; + u16 total = 0; switch (mode) { case 0: - for (i = 0; i < 200; i++) + // Populate with numbers 1-200 + // Total will be 20100 + for (i = 0; i < SEQ_ARRAY_MAX_SIZE; i++) { - q1[i] = i + 1; - r5 += i + 1; + arr[i] = i + 1; + total += i + 1; } - *((u16 *)(q1 + i)) = r5; + *((u16 *)(arr + i)) = total; break; case 1: + // Populate with numbers 1-100 + // Total will be 5050 for (i = 0; i < 100; i++) { - q1[i] = i + 1; - r5 += i + 1; + arr[i] = i + 1; + total += i + 1; } - *((u16 *)(q1 + 200)) = r5; + *((u16 *)(arr + SEQ_ARRAY_MAX_SIZE)) = total; break; case 2: - for (i = 0; i < 200; i++) + // Populate with random numbers 0-255 + // Total will be a number 0-51000 + for (i = 0; i < SEQ_ARRAY_MAX_SIZE; i++) { rval = Random(); - q1[i] = rval; - r5 += rval; + arr[i] = rval; + total += rval; } - *((u16 *)(q1 + i)) = r5; + *((u16 *)(arr + i)) = total; break; case 3: - for (i = 0; i < 200; i++) + // Populate with numbers 1-200 + sSequenceArrayValOffset + // Total will be a number 20100-51000 + for (i = 0; i < SEQ_ARRAY_MAX_SIZE; i++) { - q1[i] = i + 1 + sUnknown_03000D74; - r5 += (i + 1 + sUnknown_03000D74) & 0xFF; + arr[i] = i + 1 + sSequenceArrayValOffset; + total += (i + 1 + sSequenceArrayValOffset) & 0xFF; } - *((u16 *)(q1 + i)) = r5; - sUnknown_03000D74++; + *((u16 *)(arr + i)) = total; + sSequenceArrayValOffset++; break; } } @@ -606,9 +612,7 @@ static void PkmnStrToASCII(u8 *asciiStr, const u8 *pkmnStr) s32 i; for (i = 0; pkmnStr[i] != EOS; i++) - { asciiStr[i] = sWireless_RSEtoASCIITable[pkmnStr[i]]; - } asciiStr[i] = 0; } @@ -617,9 +621,7 @@ static void ASCIIToPkmnStr(u8 *pkmnStr, const u8 *asciiStr) s32 i; for (i = 0; asciiStr[i] != 0; i++) - { pkmnStr[i] = sWireless_ASCIItoRSETable[asciiStr[i]]; - } pkmnStr[i] = EOS; } @@ -655,33 +657,32 @@ static u8 GetConnectedChildStrength(u8 maxFlags) return 0; } -void InitHostRFUtgtGname(struct GFtgtGname *data, u8 activity, bool32 started, s32 child_sprite_genders) +void InitHostRfuGameData(struct RfuGameData *data, u8 activity, bool32 startedActivity, s32 partnerInfo) { s32 i; - for (i = 0; i < 2; i++) - { - data->unk_00.playerTrainerId[i] = gSaveBlock2Ptr->playerTrainerId[i]; - } + for (i = 0; i < (s32)ARRAY_COUNT(data->compatibility.playerTrainerId); i++) + data->compatibility.playerTrainerId[i] = gSaveBlock2Ptr->playerTrainerId[i]; + for (i = 0; i < RFU_CHILD_MAX; i++) { - data->child_sprite_gender[i] = child_sprite_genders; - child_sprite_genders >>= 8; + data->partnerInfo[i] = partnerInfo; + partnerInfo >>= 8; // Each element is 1 byte } data->playerGender = gSaveBlock2Ptr->playerGender; data->activity = activity; - data->started = started; - data->unk_00.language = GAME_LANGUAGE; - data->unk_00.version = GAME_VERSION; - data->unk_00.hasNews = FALSE; - data->unk_00.hasCard = FALSE; - data->unk_00.unknown = FALSE; - data->unk_00.isChampion = FlagGet(FLAG_IS_CHAMPION); - data->unk_00.hasNationalDex = IsNationalPokedexEnabled(); - data->unk_00.gameClear = FlagGet(FLAG_SYS_GAME_CLEAR); + data->startedActivity = startedActivity; + data->compatibility.language = GAME_LANGUAGE; + data->compatibility.version = GAME_VERSION; + data->compatibility.hasNews = FALSE; + data->compatibility.hasCard = FALSE; + data->compatibility.unknown = FALSE; + data->compatibility.isChampion = FlagGet(FLAG_IS_CHAMPION); + data->compatibility.hasNationalDex = IsNationalPokedexEnabled(); + data->compatibility.gameClear = FlagGet(FLAG_SYS_GAME_CLEAR); } -bool8 LinkRfu_GetNameIfCompatible(struct GFtgtGname *buff1, u8 *buff2, u8 idx) +bool8 Rfu_GetCompatiblePlayerData(struct RfuGameData *gameData, u8 *username, u8 idx) { bool8 retVal; @@ -690,13 +691,13 @@ bool8 LinkRfu_GetNameIfCompatible(struct GFtgtGname *buff1, u8 *buff2, u8 idx) retVal = TRUE; if (IsRfuSerialNumberValid(gRfuLinkStatus->partner[idx].serialNo) && ((gRfuLinkStatus->getNameFlag >> idx) & 1)) { - memcpy(buff1, gRfuLinkStatus->partner[idx].gname, RFU_GAME_NAME_LENGTH); - memcpy(buff2, gRfuLinkStatus->partner[idx].uname, PLAYER_NAME_LENGTH + 1); + memcpy(gameData, gRfuLinkStatus->partner[idx].gname, RFU_GAME_NAME_LENGTH); + memcpy(username, gRfuLinkStatus->partner[idx].uname, RFU_USER_NAME_LENGTH); } else { - memset(buff1, 0, RFU_GAME_NAME_LENGTH); - memset(buff2, 0, PLAYER_NAME_LENGTH + 1); + memset(gameData, 0, RFU_GAME_NAME_LENGTH); + memset(username, 0, RFU_USER_NAME_LENGTH); } } else @@ -704,39 +705,39 @@ bool8 LinkRfu_GetNameIfCompatible(struct GFtgtGname *buff1, u8 *buff2, u8 idx) retVal = FALSE; if (IsRfuSerialNumberValid(gRfuLinkStatus->partner[idx].serialNo)) { - memcpy(buff1, gRfuLinkStatus->partner[idx].gname, RFU_GAME_NAME_LENGTH); - memcpy(buff2, gRfuLinkStatus->partner[idx].uname, PLAYER_NAME_LENGTH + 1); + memcpy(gameData, gRfuLinkStatus->partner[idx].gname, RFU_GAME_NAME_LENGTH); + memcpy(username, gRfuLinkStatus->partner[idx].uname, RFU_USER_NAME_LENGTH); } else { - memset(buff1, 0, RFU_GAME_NAME_LENGTH); - memset(buff2, 0, PLAYER_NAME_LENGTH + 1); + memset(gameData, 0, RFU_GAME_NAME_LENGTH); + memset(username, 0, RFU_USER_NAME_LENGTH); } } return retVal; } -bool8 LinkRfu_GetNameIfSerial7F7D(struct GFtgtGname *buff1, u8 *buff2, u8 idx) +bool8 Rfu_GetWonderDistributorPlayerData(struct RfuGameData *gameData, u8 *username, u8 idx) { bool8 retVal = FALSE; - if (gRfuLinkStatus->partner[idx].serialNo == RFU_SERIAL_7F7D) + if (gRfuLinkStatus->partner[idx].serialNo == RFU_SERIAL_WONDER_DISTRIBUTOR) { - memcpy(buff1, gRfuLinkStatus->partner[idx].gname, RFU_GAME_NAME_LENGTH); - memcpy(buff2, gRfuLinkStatus->partner[idx].uname, PLAYER_NAME_LENGTH + 1); + memcpy(gameData, gRfuLinkStatus->partner[idx].gname, RFU_GAME_NAME_LENGTH); + memcpy(username, gRfuLinkStatus->partner[idx].uname, RFU_USER_NAME_LENGTH); retVal = TRUE; } else { - memset(buff1, 0, RFU_GAME_NAME_LENGTH); - memset(buff2, 0, PLAYER_NAME_LENGTH + 1); + memset(gameData, 0, RFU_GAME_NAME_LENGTH); + memset(username, 0, RFU_USER_NAME_LENGTH); } return retVal; } -void LinkRfu3_SetGnameUnameFromStaticBuffers(struct GFtgtGname *buff1, u8 *buff2) +void CopyHostRfuGameDataAndUsername(struct RfuGameData *gameData, u8 *username) { - memcpy(buff1, &gHostRFUtgtGnameBuffer, RFU_GAME_NAME_LENGTH); - memcpy(buff2, gHostRFUtgtUnameBuffer, PLAYER_NAME_LENGTH + 1); + memcpy(gameData, &gHostRfuGameData, RFU_GAME_NAME_LENGTH); + memcpy(username, gHostRfuUsername, RFU_USER_NAME_LENGTH); } #define sNextAnimNum data[0] @@ -754,8 +755,8 @@ void CreateWirelessStatusIndicatorSprite(u8 x, u8 y) if (x == 0 && y == 0) { - x = 0xE7; - y = 0x08; + x = 231; + y = 8; } if (gRfuLinkStatus->parentChild == MODE_PARENT) { @@ -788,9 +789,7 @@ void DestroyWirelessStatusIndicatorSprite(void) void LoadWirelessStatusIndicatorSpriteGfx(void) { if (GetSpriteTileStartByTag(sWirelessStatusIndicatorSpriteSheet.tag) == 0xFFFF) - { LoadCompressedSpriteSheet(&sWirelessStatusIndicatorSpriteSheet); - } LoadSpritePalette(&sWirelessStatusIndicatorSpritePalette); gWirelessStatusIndicatorSpriteId = SPRITE_NONE; } @@ -802,9 +801,7 @@ static u8 GetParentSignalStrength(void) for (i = 0; i < RFU_CHILD_MAX; i++) { if (flags & 1) - { return gRfuLinkStatus->strength[i]; - } flags >>= 1; } return 0; @@ -827,40 +824,33 @@ void UpdateWirelessStatusIndicatorSprite(void) struct Sprite *sprite = &gSprites[gWirelessStatusIndicatorSpriteId]; u8 signalStrength = RFU_LINK_ICON_LEVEL4_MAX; u8 i = 0; + + // Get weakest signal strength if (gRfuLinkStatus->parentChild == MODE_PARENT) { for (i = 0; i < GetLinkPlayerCount() - 1; i++) { if (signalStrength >= GetConnectedChildStrength(i + 1)) - { signalStrength = GetConnectedChildStrength(i + 1); - } } } else { signalStrength = GetParentSignalStrength(); } + + // Set signal strength sprite anim number if (IsRfuRecoveringFromLinkLoss() == TRUE) - { sprite->sNextAnimNum = WIRELESS_STATUS_ANIM_ERROR; - } else if (signalStrength <= RFU_LINK_ICON_LEVEL1_MAX) - { sprite->sNextAnimNum = WIRELESS_STATUS_ANIM_SEARCHING; - } else if (signalStrength >= RFU_LINK_ICON_LEVEL2_MIN && signalStrength <= RFU_LINK_ICON_LEVEL2_MAX) - { sprite->sNextAnimNum = WIRELESS_STATUS_ANIM_1_BAR; - } else if (signalStrength >= RFU_LINK_ICON_LEVEL3_MIN && signalStrength <= RFU_LINK_ICON_LEVEL3_MAX) - { sprite->sNextAnimNum = WIRELESS_STATUS_ANIM_2_BARS; - } else if (signalStrength >= RFU_LINK_ICON_LEVEL4_MIN) - { sprite->sNextAnimNum = WIRELESS_STATUS_ANIM_3_BARS; - } + if (sprite->sNextAnimNum != sprite->sSavedAnimNum) { SetWirelessStatusIndicatorAnim(sprite, sprite->sNextAnimNum); @@ -871,9 +861,7 @@ void UpdateWirelessStatusIndicatorSprite(void) sprite->sFrameIdx++; sprite->sFrameDelay = 0; if (sprite->anims[sprite->sCurrAnimNum][sprite->sFrameIdx].type == -2) - { sprite->sFrameIdx = 0; - } } else { @@ -884,11 +872,9 @@ void UpdateWirelessStatusIndicatorSprite(void) gMain.oamBuffer[125].y = sprite->y + sprite->centerToCornerVecY; gMain.oamBuffer[125].paletteNum = sprite->oam.paletteNum; gMain.oamBuffer[125].tileNum = sprite->sTileStart + sprite->anims[sprite->sCurrAnimNum][sprite->sFrameIdx].frame.imageValue; - CpuCopy16(gMain.oamBuffer + 125, (struct OamData *)OAM + 125, sizeof(struct OamData)); + CpuCopy16(&gMain.oamBuffer[125], (struct OamData *)OAM + 125, sizeof(struct OamData)); if (RfuGetStatus() == RFU_STATUS_FATAL_ERROR) - { DestroyWirelessStatusIndicatorSprite(); - } } } @@ -919,14 +905,14 @@ static bool32 NameIsNotEmpty(const u8 *name) } // Save the currently connected players into the trainer records, shifting all previous records down. -void RecordMixTrainerNames(void) +void SaveLinkTrainerNames(void) { if (gWirelessCommType != 0) { s32 i; s32 j; s32 nextSpace; - s32 connectedTrainerRecordIndices[5]; + s32 connectedTrainerRecordIndices[MAX_RFU_PLAYERS]; struct TrainerNameRecord *newRecords = calloc(ARRAY_COUNT(gSaveBlock1Ptr->trainerNameRecords), sizeof(struct TrainerNameRecord)); // Check if we already have a record saved for connected trainers. @@ -936,9 +922,7 @@ void RecordMixTrainerNames(void) for (j = 0; j < (int)ARRAY_COUNT(gSaveBlock1Ptr->trainerNameRecords); j++) { if ((u16)gLinkPlayers[i].trainerId == gSaveBlock1Ptr->trainerNameRecords[j].trainerId && StringCompare(gLinkPlayers[i].name, gSaveBlock1Ptr->trainerNameRecords[j].trainerName) == 0) - { connectedTrainerRecordIndices[i] = j; - } } } @@ -952,9 +936,7 @@ void RecordMixTrainerNames(void) // If we already had a record for this trainer, wipe it so that the next step doesn't duplicate it. if (connectedTrainerRecordIndices[i] >= 0) - { - memset(gSaveBlock1Ptr->trainerNameRecords[connectedTrainerRecordIndices[i]].trainerName, 0, 8); - } + memset(gSaveBlock1Ptr->trainerNameRecords[connectedTrainerRecordIndices[i]].trainerName, 0, PLAYER_NAME_LENGTH + 1); nextSpace++; } } @@ -967,9 +949,7 @@ void RecordMixTrainerNames(void) { CopyTrainerRecord(&newRecords[nextSpace], gSaveBlock1Ptr->trainerNameRecords[i].trainerId, gSaveBlock1Ptr->trainerNameRecords[i].trainerName); if (++nextSpace >= (int)ARRAY_COUNT(gSaveBlock1Ptr->trainerNameRecords)) - { break; - } } } @@ -1001,6 +981,6 @@ void WipeTrainerNameRecords(void) for (i = 0; i < (int)ARRAY_COUNT(gSaveBlock1Ptr->trainerNameRecords); i++) { gSaveBlock1Ptr->trainerNameRecords[i].trainerId = 0; - CpuFill16(0, gSaveBlock1Ptr->trainerNameRecords[i].trainerName, 8); + CpuFill16(0, gSaveBlock1Ptr->trainerNameRecords[i].trainerName, PLAYER_NAME_LENGTH + 1); } } diff --git a/src/load_save.c b/src/load_save.c index eec8f91ae..0112f2a8f 100644 --- a/src/load_save.c +++ b/src/load_save.c @@ -71,6 +71,7 @@ void ClearSav1(void) CpuFill16(0, &gSaveblock1, sizeof(struct SaveBlock1) + sizeof(gSaveblock1_DMA)); } +// Offset is the sum of the trainer id bytes void SetSaveBlocksPointers(u16 offset) { struct SaveBlock1** sav1_LocalVar = &gSaveBlock1Ptr; diff --git a/src/mystery_gift.c b/src/mystery_gift.c index afbe50e4d..6ae6a9534 100644 --- a/src/mystery_gift.c +++ b/src/mystery_gift.c @@ -510,13 +510,9 @@ void MG_DrawCheckerboardPattern(u32 bg) 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); - } } } } @@ -593,10 +589,8 @@ bool32 unref_HideDownArrowAndWaitButton(u8 * textState) { case 0: HideDownArrow(); - if (({JOY_NEW(A_BUTTON | B_BUTTON);})) - { + if (JOY_NEW(A_BUTTON | B_BUTTON)) (*textState)++; - } break; case 1: ShowDownArrow(); @@ -609,9 +603,8 @@ bool32 unref_HideDownArrowAndWaitButton(u8 * textState) static bool32 PrintStringAndWait2Seconds(u8 * counter, const u8 * str) { if (*counter == 0) - { AddTextPrinterToWindow1(str); - } + if (++(*counter) > 120) { *counter = 0; @@ -632,27 +625,20 @@ static u32 MysteryGift_HandleThreeOptionMenu(u8 * unused0, u16 * unused1, u8 whi 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, 0x00A, 0xE0); if (response != -1) { @@ -672,13 +658,9 @@ s8 mevent_message_print_and_prompt_yes_no(u8 * textState, u16 * windowId, bool8 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); @@ -689,19 +671,15 @@ s8 mevent_message_print_and_prompt_yes_no(u8 * textState, u16 * windowId, bool8 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 == -1 || input == 0 || input == 1) + if (input == MENU_B_PRESSED || input == 0 || input == 1) { *textState = 0; rbox_fill_rectangle(*windowId); @@ -711,16 +689,16 @@ s8 mevent_message_print_and_prompt_yes_no(u8 * textState, u16 * windowId, bool8 return input; } break; - case 0xFF: + case (u8)MENU_B_PRESSED: *textState = 0; rbox_fill_rectangle(*windowId); ClearWindowTilemap(*windowId); CopyWindowToVram(*windowId, 1); RemoveWindow(*windowId); - return -1; + return MENU_B_PRESSED; } - return -2; + return MENU_NOTHING_CHOSEN; } static s32 HandleMysteryGiftListMenu(u8 * textState, u16 * windowId, bool32 cannotToss, bool32 cannotSend) @@ -1237,21 +1215,21 @@ void task00_mystery_gift(u8 taskId) case 0: if (data->source == 1) { - MEvent_CreateTask_CardOrNewsWithFriend(ACTIVITY_WONDER_CARD2); + MEvent_CreateTask_CardOrNewsWithFriend(ACTIVITY_WONDER_CARD); } else if (data->source == 0) { - MEvent_CreateTask_CardOrNewsOverWireless(ACTIVITY_WONDER_CARD2); + MEvent_CreateTask_CardOrNewsOverWireless(ACTIVITY_WONDER_CARD); } break; case 1: if (data->source == 1) { - MEvent_CreateTask_CardOrNewsWithFriend(ACTIVITY_WONDER_NEWS2); + MEvent_CreateTask_CardOrNewsWithFriend(ACTIVITY_WONDER_NEWS); } else if (data->source == 0) { - MEvent_CreateTask_CardOrNewsOverWireless(ACTIVITY_WONDER_NEWS2); + MEvent_CreateTask_CardOrNewsOverWireless(ACTIVITY_WONDER_NEWS); } break; } @@ -1594,10 +1572,10 @@ void task00_mystery_gift(u8 taskId) switch (data->IsCardOrNews) { case 0: - MEvent_CreateTask_Leader(ACTIVITY_WONDER_CARD2); + MEvent_CreateTask_Leader(ACTIVITY_WONDER_CARD); break; case 1: - MEvent_CreateTask_Leader(ACTIVITY_WONDER_NEWS2); + MEvent_CreateTask_Leader(ACTIVITY_WONDER_NEWS); break; } data->source = 1; diff --git a/src/naming_screen.c b/src/naming_screen.c index 19da9da02..f6558921b 100644 --- a/src/naming_screen.c +++ b/src/naming_screen.c @@ -286,19 +286,26 @@ static const struct WindowTemplate sWindowTemplates[WIN_COUNT + 1] = // This handles what characters get inserted when a key is pressed // The keys shown on the keyboard are handled separately by sNamingScreenKeyboardText -static const u8 sKeyboardChars[KBPAGE_COUNT * KBROW_COUNT * KBCOL_COUNT] = __( - "abcdef ." - "ghijkl ," - "mnopqrs " - "tuvwxyz " - "ABCDEF ." - "GHIJKL ," - "MNOPQRS " - "TUVWXYZ " - "01234 " - "56789 " - "!?♂♀/- " - "…“”‘' "); +static const u8 sKeyboardChars[KBPAGE_COUNT][KBROW_COUNT][KBCOL_COUNT] = { + [KEYBOARD_LETTERS_LOWER] = { + __("abcdef ."), + __("ghijkl ,"), + __("mnopqrs "), + __("tuvwxyz "), + }, + [KEYBOARD_LETTERS_UPPER] = { + __("ABCDEF ."), + __("GHIJKL ,"), + __("MNOPQRS "), + __("TUVWXYZ "), + }, + [KEYBOARD_SYMBOLS] = { + __("01234 "), + __("56789 "), + __("!?♂♀/- "), + __("…“”‘' "), + } +}; static const u8 sPageColumnCounts[KBPAGE_COUNT] = { [KEYBOARD_LETTERS_LOWER] = KBCOL_COUNT, @@ -1780,7 +1787,7 @@ static void DrawGenderIcon(void) static u8 GetCharAtKeyboardPos(s16 x, s16 y) { - return sKeyboardChars[x + y * KBCOL_COUNT + CurrentPageToKeyboardId() * KBCOL_COUNT * KBROW_COUNT]; + return sKeyboardChars[CurrentPageToKeyboardId()][y][x]; } diff --git a/src/overworld.c b/src/overworld.c index 71cfeaac9..a8d9a4a83 100644 --- a/src/overworld.c +++ b/src/overworld.c @@ -2898,7 +2898,7 @@ bool32 IsSendingKeysOverCable(void) static u32 GetLinkSendQueueLength(void) { if (gWirelessCommType != 0) - return Rfu.sendQueue.count; + return gRfu.sendQueue.count; else return gLink.sendQueue.count; } diff --git a/src/party_menu.c b/src/party_menu.c index 5711c3055..0381509c6 100755 --- a/src/party_menu.c +++ b/src/party_menu.c @@ -3522,7 +3522,7 @@ static void CursorCb_Register(u8 taskId) u16 species = GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_SPECIES); u8 isEventLegal = GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_EVENT_LEGAL); - switch (CanRegisterMonForTradingBoard(*(struct GFtgtGnameSub *)GetHostRFUtgtGname(), species2, species, isEventLegal)) + switch (CanRegisterMonForTradingBoard(*(struct RfuGameCompatibilityData *)GetHostRfuGameData(), species2, species, isEventLegal)) { case CANT_REGISTER_MON: StringExpandPlaceholders(gStringVar4, gText_PkmnCantBeTradedNow); @@ -3548,7 +3548,7 @@ static void CursorCb_Trade1(u8 taskId) u16 species2 = GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_SPECIES2); u16 species = GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_SPECIES); u8 isEventLegal = GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_EVENT_LEGAL); - u32 stringId = GetUnionRoomTradeMessageId(*(struct GFtgtGnameSub *)GetHostRFUtgtGname(), gPartnerTgtGnameSub, species2, gUnionRoomOfferedSpecies, gUnionRoomRequestedMonType, species, isEventLegal); + u32 stringId = GetUnionRoomTradeMessageId(*(struct RfuGameCompatibilityData *)GetHostRfuGameData(), gRfuPartnerCompatibilityData, species2, gUnionRoomOfferedSpecies, gUnionRoomRequestedMonType, species, isEventLegal); if (stringId != UR_TRADE_MSG_NONE) { diff --git a/src/pokemon_jump.c b/src/pokemon_jump.c index 57f1d6e93..ab86ee09f 100755 --- a/src/pokemon_jump.c +++ b/src/pokemon_jump.c @@ -2202,7 +2202,7 @@ static int GetPlayersAtJumpPeak(void) static bool32 AreLinkQueuesEmpty(void) { - return !Rfu.recvQueue.count && !Rfu.sendQueue.count; + return !gRfu.recvQueue.count && !gRfu.sendQueue.count; } static int GetNumPlayersForBonus(u8 *arg0) @@ -3945,7 +3945,7 @@ static bool32 RecvPacket_MonInfo(int multiplayerId, struct PokemonJump_MonInfo * { struct MonInfoPacket packet; - if ((gRecvCmds[multiplayerId][0] & 0xFF00) != RFUCMD_SEND_PACKET) + if ((gRecvCmds[multiplayerId][0] & RFUCMD_MASK) != RFUCMD_SEND_PACKET) return FALSE; memcpy(&packet, &gRecvCmds[multiplayerId][1], sizeof(packet)); @@ -4010,7 +4010,7 @@ static bool32 RecvPacket_LeaderState(struct PokemonJump_Player *player, struct P { struct LeaderStatePacket packet; - if ((gRecvCmds[0][0] & 0xFF00) != RFUCMD_SEND_PACKET) + if ((gRecvCmds[0][0] & RFUCMD_MASK) != RFUCMD_SEND_PACKET) return FALSE; memcpy(&packet, &gRecvCmds[0][1], sizeof(packet)); @@ -4057,7 +4057,7 @@ static bool32 RecvPacket_MemberStateToLeader(struct PokemonJump_Player *player, { struct MemberStatePacket packet; - if ((gRecvCmds[multiplayerId][0] & 0xFF00) != RFUCMD_SEND_PACKET) + if ((gRecvCmds[multiplayerId][0] & RFUCMD_MASK) != RFUCMD_SEND_PACKET) return FALSE; memcpy(&packet, &gRecvCmds[multiplayerId][1], sizeof(packet)); @@ -4078,7 +4078,7 @@ static bool32 RecvPacket_MemberStateToMember(struct PokemonJump_Player *player, { struct MemberStatePacket packet; - if ((gRecvCmds[multiplayerId][0] & 0xFF00) != RFUCMD_SEND_PACKET) + if ((gRecvCmds[multiplayerId][0] & RFUCMD_MASK) != RFUCMD_SEND_PACKET) return FALSE; memcpy(&packet, &gRecvCmds[multiplayerId][1], sizeof(packet)); diff --git a/src/record_mixing.c b/src/record_mixing.c index 6b538eaf4..ad97b6af5 100644 --- a/src/record_mixing.c +++ b/src/record_mixing.c @@ -499,7 +499,7 @@ static void Task_SendPacket(u8 taskId) break; case 1: if (GetMultiplayerId() == 0) - SendBlockRequest(1); + SendBlockRequest(BLOCK_REQ_SIZE_200); task->data[0]++; break; case 2: @@ -981,7 +981,7 @@ static void Task_DoRecordMixing(u8 taskId) // Mixing Emerald records. case 6: - if (!sub_801048C(FALSE)) + if (!Rfu_SetLinkRecovery(FALSE)) { CreateTask(Task_LinkSave, 5); task->data[0]++; @@ -992,7 +992,7 @@ static void Task_DoRecordMixing(u8 taskId) { if (gWirelessCommType) { - sub_801048C(TRUE); + Rfu_SetLinkRecovery(TRUE); task->data[0] = 8; } else diff --git a/src/reset_save_heap.c b/src/reload_save.c similarity index 75% rename from src/reset_save_heap.c rename to src/reload_save.c index 577a48b0d..cdbb2f227 100644 --- a/src/reset_save_heap.c +++ b/src/reload_save.c @@ -8,17 +8,17 @@ #include "overworld.h" #include "malloc.h" -void sub_81700F8(void) +// Reloads the game, continuing from the point of the last save +// Used to gracefully exit after a link connection error +void ReloadSave(void) { - u16 imeBackup; - - imeBackup = REG_IME; + u16 imeBackup = REG_IME; REG_IME = 0; RegisterRamReset(RESET_EWRAM); ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_FORCED_BLANK); REG_IME = imeBackup; gMain.inBattle = FALSE; - SetSaveBlocksPointers(sub_815355C()); + SetSaveBlocksPointers(GetSaveBlocksPointersBaseOffset()); ResetMenuAndMonGlobals(); Save_ResetSaveCounters(); Save_LoadGameData(SAVE_NORMAL); diff --git a/src/save.c b/src/save.c index 52301df03..40fce4e8a 100644 --- a/src/save.c +++ b/src/save.c @@ -43,11 +43,12 @@ static u8 HandleWriteSector(u16 a1, const struct SaveSectionLocation *location); // (u8 *)structure was removed from the first statement of the macro in Emerald. // This is because malloc is used to allocate addresses so storing the raw // addresses should not be done in the offsets information. -#define SAVEBLOCK_CHUNK(structure, chunkNum) \ -{ \ - chunkNum * SECTOR_DATA_SIZE, \ - min(sizeof(structure) - chunkNum * SECTOR_DATA_SIZE, SECTOR_DATA_SIZE) \ -} \ +#define SAVEBLOCK_CHUNK(structure, chunkNum) \ +{ \ + chunkNum * SECTOR_DATA_SIZE, \ + sizeof(structure) >= chunkNum * SECTOR_DATA_SIZE ? \ + min(sizeof(structure) - chunkNum * SECTOR_DATA_SIZE, SECTOR_DATA_SIZE) : 0 \ +} static const struct SaveSectionOffsets sSaveSectionOffsets[] = { @@ -126,16 +127,16 @@ static bool32 SetDamagedSectorBits(u8 op, u8 bit) return retVal; } -static u8 SaveWriteToFlash(u16 a1, const struct SaveSectionLocation *location) +static u8 SaveWriteToFlash(u16 sectorId, const struct SaveSectionLocation *location) { u32 status; u16 i; gFastSaveSection = &gSaveDataBuffer; - if (a1 != 0xFFFF) // for link + if (sectorId != 0xFFFF) // for link { - status = HandleWriteSector(a1, location); + status = HandleWriteSector(sectorId, location); } else { @@ -169,7 +170,7 @@ static u8 HandleWriteSector(u16 sectorId, const struct SaveSectionLocation *loca sector = sectorId + gLastWrittenSector; sector %= SECTOR_SAVE_SLOT_LENGTH; - sector += SECTOR_SAVE_SLOT_LENGTH * (gSaveCounter % 2); + sector += SECTOR_SAVE_SLOT_LENGTH * (gSaveCounter % NUM_SAVE_SLOTS); data = location[sectorId].data; size = location[sectorId].size; @@ -292,7 +293,7 @@ static u8 ClearSaveData_2(u16 sectorId, const struct SaveSectionLocation *locati sector = sectorId + gLastWrittenSector; sector %= SECTOR_SAVE_SLOT_LENGTH; - sector += SECTOR_SAVE_SLOT_LENGTH * (gSaveCounter % 2); + sector += SECTOR_SAVE_SLOT_LENGTH * (gSaveCounter % NUM_SAVE_SLOTS); data = location[sectorId].data; size = location[sectorId].size; @@ -362,7 +363,7 @@ static u8 sav12_xor_get(u16 sectorId, const struct SaveSectionLocation *location sector = sectorId + gLastWrittenSector; // no sub 1? sector %= SECTOR_SAVE_SLOT_LENGTH; - sector += SECTOR_SAVE_SLOT_LENGTH * (gSaveCounter % 2); + sector += SECTOR_SAVE_SLOT_LENGTH * (gSaveCounter % NUM_SAVE_SLOTS); if (ProgramFlashByte(sector, sizeof(struct UnkSaveSection), 0x25)) { @@ -385,7 +386,7 @@ static u8 sub_8152CAC(u16 sectorId, const struct SaveSectionLocation *location) sector = sectorId + gLastWrittenSector - 1; sector %= SECTOR_SAVE_SLOT_LENGTH; - sector += SECTOR_SAVE_SLOT_LENGTH * (gSaveCounter % 2); + sector += SECTOR_SAVE_SLOT_LENGTH * (gSaveCounter % NUM_SAVE_SLOTS); if (ProgramFlashByte(sector, sizeof(struct UnkSaveSection), ((u8 *)gFastSaveSection)[sizeof(struct UnkSaveSection)])) { @@ -408,7 +409,7 @@ static u8 sub_8152D44(u16 sectorId, const struct SaveSectionLocation *location) sector = sectorId + gLastWrittenSector - 1; // no sub 1? sector %= SECTOR_SAVE_SLOT_LENGTH; - sector += SECTOR_SAVE_SLOT_LENGTH * (gSaveCounter % 2); + sector += SECTOR_SAVE_SLOT_LENGTH * (gSaveCounter % NUM_SAVE_SLOTS); if (ProgramFlashByte(sector, sizeof(struct UnkSaveSection), 0x25)) { @@ -446,12 +447,12 @@ static u8 sub_8152E10(u16 a1, const struct SaveSectionLocation *location) { u16 i; u16 checksum; - u16 v3 = SECTOR_SAVE_SLOT_LENGTH * (gSaveCounter % 2); + u16 slotOffset = SECTOR_SAVE_SLOT_LENGTH * (gSaveCounter % NUM_SAVE_SLOTS); u16 id; for (i = 0; i < SECTOR_SAVE_SLOT_LENGTH; i++) { - DoReadFlashWholeSection(i + v3, gFastSaveSection); + DoReadFlashWholeSection(i + slotOffset, gFastSaveSection); id = gFastSaveSection->id; if (id == 0) gLastWrittenSector = i; @@ -824,27 +825,29 @@ u8 Save_LoadGameData(u8 saveType) return status; } -u16 sub_815355C(void) +u16 GetSaveBlocksPointersBaseOffset(void) { - u16 i, v3; + u16 i, slotOffset; struct SaveSection* savSection; savSection = gFastSaveSection = &gSaveDataBuffer; if (gFlashMemoryPresent != TRUE) - return SAVE_STATUS_EMPTY; + return 0; UpdateSaveAddresses(); GetSaveValidStatus(gRamSaveSectionLocations); - v3 = SECTOR_SAVE_SLOT_LENGTH * (gSaveCounter % 2); + slotOffset = SECTOR_SAVE_SLOT_LENGTH * (gSaveCounter % NUM_SAVE_SLOTS); for (i = 0; i < SECTOR_SAVE_SLOT_LENGTH; i++) { - DoReadFlashWholeSection(i + v3, gFastSaveSection); - if (gFastSaveSection->id == 0) - return savSection->data[10] + - savSection->data[11] + - savSection->data[12] + - savSection->data[13]; + DoReadFlashWholeSection(i + slotOffset, gFastSaveSection); + + // Base offset for SaveBlock2 is calculated using the trainer id + if (gFastSaveSection->id == SECTOR_ID_SAVEBLOCK2) + return savSection->data[offsetof(struct SaveBlock2, playerTrainerId[0])] + + savSection->data[offsetof(struct SaveBlock2, playerTrainerId[1])] + + savSection->data[offsetof(struct SaveBlock2, playerTrainerId[2])] + + savSection->data[offsetof(struct SaveBlock2, playerTrainerId[3])]; } - return SAVE_STATUS_EMPTY; + return 0; } u32 TryReadSpecialSaveSection(u8 sector, u8* dst) diff --git a/src/trade.c b/src/trade.c index 526a9ac39..d1fc14efe 100644 --- a/src/trade.c +++ b/src/trade.c @@ -274,7 +274,7 @@ static bool32 IsLinkTradeTaskFinished(void) { if (gPlayerCurrActivity == ACTIVITY_29) { - if (gRfuSlotStatusNI[sub_800E87C(lman.acceptSlot_flag)]->send.state == 0) + if (gRfuSlotStatusNI[Rfu_GetIndexOfNewestChild(lman.acceptSlot_flag)]->send.state == 0) return TRUE; else return FALSE; @@ -459,7 +459,7 @@ static void CB2_CreateTradeMenu(void) sTradeMenuData->timer = 0; if (gWirelessCommType) { - sub_801048C(TRUE); + Rfu_SetLinkRecovery(TRUE); SetLinkStandbyCallback(); } } @@ -1008,9 +1008,7 @@ static bool8 BufferTradeParties(void) break; case 3: if (id == 0) - { - RequestLinkData(1); - } + RequestLinkData(BLOCK_REQ_SIZE_200); sTradeMenuData->bufferPartyState++; break; case 4: @@ -1027,9 +1025,7 @@ static bool8 BufferTradeParties(void) break; case 7: if (id == 0) - { - RequestLinkData(1); - } + RequestLinkData(BLOCK_REQ_SIZE_200); sTradeMenuData->bufferPartyState++; break; case 8: @@ -1046,9 +1042,7 @@ static bool8 BufferTradeParties(void) break; case 11: if (id == 0) - { - RequestLinkData(1); - } + RequestLinkData(BLOCK_REQ_SIZE_200); sTradeMenuData->bufferPartyState++; break; case 12: @@ -1065,9 +1059,7 @@ static bool8 BufferTradeParties(void) break; case 15: if (id == 0) - { - RequestLinkData(3); - } + RequestLinkData(BLOCK_REQ_SIZE_220); sTradeMenuData->bufferPartyState++; break; case 16: @@ -1084,9 +1076,7 @@ static bool8 BufferTradeParties(void) break; case 19: if (id == 0) - { - RequestLinkData(4); - } + RequestLinkData(BLOCK_REQ_SIZE_40); sTradeMenuData->bufferPartyState++; break; case 20: @@ -1719,7 +1709,7 @@ static void CancelTrade_2(void) static void LinkTradeWaitForQueue(void) { - if (!sub_801048C(FALSE) && GetNumQueuedActions() == 0) + if (!Rfu_SetLinkRecovery(FALSE) && GetNumQueuedActions() == 0) { SetLinkStandbyCallback(); sTradeMenuData->tradeMenuFunc = TRADEMENUFUNC_START_LINK_TRADE; @@ -2448,80 +2438,70 @@ static bool32 IsDeoxysOrMewUntradable(u16 species, bool8 isEventLegal) return FALSE; } -int GetUnionRoomTradeMessageId(struct GFtgtGnameSub rfuPlayer, struct GFtgtGnameSub rfuPartner, u16 playerSpecies2, u16 partnerSpecies, u8 requestedType, u16 playerSpecies, u8 isEventLegal) +int GetUnionRoomTradeMessageId(struct RfuGameCompatibilityData player, struct RfuGameCompatibilityData partner, u16 playerSpecies2, u16 partnerSpecies, u8 requestedType, u16 playerSpecies, u8 isEventLegal) { - bool8 playerHasNationalDex = rfuPlayer.hasNationalDex; - bool8 playerIsChampion = rfuPlayer.isChampion; - bool8 partnerHasNationalDex = rfuPartner.hasNationalDex; - bool8 partnerIsChampion = rfuPartner.isChampion; - u8 r1 = rfuPartner.version; + bool8 playerHasNationalDex = player.hasNationalDex; + bool8 playerIsChampion = player.isChampion; + bool8 partnerHasNationalDex = partner.hasNationalDex; + bool8 partnerIsChampion = partner.isChampion; + u8 partnerVersion = partner.version; - if (r1 != VERSION_EMERALD) + // If partner is not using Emerald, both players must be champion + if (partnerVersion != VERSION_EMERALD) { if (!playerIsChampion) - { return UR_TRADE_MSG_CANT_TRADE_WITH_PARTNER_1; - } else if (!partnerIsChampion) - { return UR_TRADE_MSG_CANT_TRADE_WITH_PARTNER_2; - } } + // Cannot trade illegitimate Deoxys/Mew if (IsDeoxysOrMewUntradable(playerSpecies, isEventLegal)) - { return UR_TRADE_MSG_MON_CANT_BE_TRADED_2; - } if (partnerSpecies == SPECIES_EGG) { + // If partner is trading an Egg then the player must also be trading an Egg if (playerSpecies2 != partnerSpecies) - { return UR_TRADE_MSG_NOT_EGG; - } } else { - if (gBaseStats[playerSpecies2].type1 != requestedType && gBaseStats[playerSpecies2].type2 != requestedType) - { + // Player's Pokémon must be of the type the partner requested + if (gBaseStats[playerSpecies2].type1 != requestedType + && gBaseStats[playerSpecies2].type2 != requestedType) return UR_TRADE_MSG_NOT_MON_PARTNER_WANTS; - } } + // If the player is trading an Egg then the partner must also be trading an Egg + // Odd that this wasn't checked earlier, as by this point we know either the partner doesn't have an Egg or that both do. if (playerSpecies2 == SPECIES_EGG && playerSpecies2 != partnerSpecies) - { return UR_TRADE_MSG_MON_CANT_BE_TRADED_1; - } + // If the player doesn't have the National Dex then Eggs and non-Hoenn Pokémon can't be traded if (!playerHasNationalDex) { if (playerSpecies2 == SPECIES_EGG) - { return UR_TRADE_MSG_EGG_CANT_BE_TRADED; - } if (!IsSpeciesInHoennDex(playerSpecies2)) - { return UR_TRADE_MSG_MON_CANT_BE_TRADED_2; - } if (!IsSpeciesInHoennDex(partnerSpecies)) - { return UR_TRADE_MSG_PARTNERS_MON_CANT_BE_TRADED; - } } + // If the partner doesn't have the National Dex then the player's offer has to be a Hoenn Pokémon if (!partnerHasNationalDex && !IsSpeciesInHoennDex(playerSpecies2)) - { return UR_TRADE_MSG_PARTNER_CANT_ACCEPT_MON; - } + // Trade is allowed return UR_TRADE_MSG_NONE; } -int CanRegisterMonForTradingBoard(struct GFtgtGnameSub rfuPlayer, u16 species2, u16 species, u8 isEventLegal) +int CanRegisterMonForTradingBoard(struct RfuGameCompatibilityData player, u16 species2, u16 species, u8 isEventLegal) { - bool8 hasNationalDex = rfuPlayer.hasNationalDex; + bool8 hasNationalDex = player.hasNationalDex; if (IsDeoxysOrMewUntradable(species, isEventLegal)) return CANT_REGISTER_MON; @@ -2551,9 +2531,7 @@ int CanSpinTradeMon(struct Pokemon *mon, u16 monIdx) { speciesArray[i] = GetMonData(&mon[i], MON_DATA_SPECIES2); if (speciesArray[i] == SPECIES_EGG) - { speciesArray[i] = SPECIES_NONE; - } } versions = 0; @@ -2563,13 +2541,9 @@ int CanSpinTradeMon(struct Pokemon *mon, u16 monIdx) version = gLinkPlayers[i].version & 0xFF; if (version == VERSION_FIRE_RED || version == VERSION_LEAF_GREEN) - { versions = 0; - } else - { versions |= 1; - } } for (i = 0; i < GetLinkPlayerCount(); i++) @@ -2600,9 +2574,7 @@ int CanSpinTradeMon(struct Pokemon *mon, u16 monIdx) for (i = 0; i < gPlayerPartyCount; i++) { if (monIdx != i) - { numMonsLeft += speciesArray[i]; - } } if (!numMonsLeft) @@ -3096,7 +3068,7 @@ static void TrySendTradeFinishData(void) case 1: if (IsLinkTaskFinished()) { - SendBlock(bitmask_all_link_players_but_self(), sTradeData->linkData, sizeof(sTradeData->linkData)); + SendBlock(BitmaskAllOtherLinkPlayers(), sTradeData->linkData, sizeof(sTradeData->linkData)); sTradeData->sendTradeFinishState++; } // fallthrough @@ -4632,7 +4604,7 @@ static void CB2_TryFinishTrade(void) && sTradeData->partnerLinkFlagFinishTrade == READY_FINISH_TRADE) { sTradeData->linkData[0] = LINKCMD_CONFIRM_FINISH_TRADE; - SendBlock(bitmask_all_link_players_but_self(), sTradeData->linkData, sizeof(sTradeData->linkData)); + SendBlock(BitmaskAllOtherLinkPlayers(), sTradeData->linkData, sizeof(sTradeData->linkData)); sTradeData->playerLinkFlagFinishTrade = FINISH_TRADE; sTradeData->partnerLinkFlagFinishTrade = FINISH_TRADE; } diff --git a/src/union_room.c b/src/union_room.c index fb1604879..db2d0247b 100644 --- a/src/union_room.c +++ b/src/union_room.c @@ -130,7 +130,7 @@ enum { LL_STATE_PRINT_AWAITING_PLAYERS, LL_STATE_AWAIT_PLAYERS, LL_STATE_ACCEPT_NEW_MEMBER_PROMPT, - LL_STATE_9 = 9, + LL_STATE_WAIT_DISCONNECT_CHILD = 9, LL_STATE_MEMBER_LEFT, LL_STATE_ACCEPT_NEW_MEMBER_PROMPT_HANDLE_INPUT, LL_STATE_UPDATE_AFTER_JOIN_REQUEST, @@ -175,23 +175,46 @@ enum { LG_STATE_SHUTDOWN = 23, }; +// Color types for PrintUnionRoomText +enum { + UR_COLOR_DEFAULT, + UR_COLOR_RED, + UR_COLOR_GREEN, + UR_COLOR_WHITE, + UR_COLOR_CANCEL, + UR_COLOR_TRADE_BOARD_SELF, + UR_COLOR_TRADE_BOARD_OTHER, +}; + +// Return values for HandlePlayerListUpdate +enum { + PLIST_NONE, + PLIST_NEW_PLAYER, + PLIST_RECENT_UPDATE, + PLIST_UNUSED, + PLIST_CONTACTED, +}; + static EWRAM_DATA u8 sUnionRoomPlayerName[12] = {}; EWRAM_DATA u8 gPlayerCurrActivity = 0; static EWRAM_DATA u8 sPlayerActivityGroupSize = 0; -static EWRAM_DATA union WirelessLink_Main sWirelessLinkMain = {}; +static EWRAM_DATA union +{ + struct WirelessLink_Leader *leader; + struct WirelessLink_Group *group; + struct WirelessLink_URoom *uRoom; +} sWirelessLinkMain = {}; static EWRAM_DATA u32 sUnused = 0; -EWRAM_DATA struct GFtgtGnameSub gPartnerTgtGnameSub = {}; +EWRAM_DATA struct RfuGameCompatibilityData gRfuPartnerCompatibilityData = {}; EWRAM_DATA u16 gUnionRoomOfferedSpecies = 0; EWRAM_DATA u8 gUnionRoomRequestedMonType = 0; static EWRAM_DATA struct UnionRoomTrade sUnionRoomTrade = {}; -// IWRAM vars static struct WirelessLink_Leader *sLeader; static struct WirelessLink_Group *sGroup; static struct WirelessLink_URoom *sURoom; -// this file's functions -static void UR_AddTextPrinterParameterized(u8, u8, const u8 *, u8, u8, u8); +static void PrintUnionRoomText(u8, u8, const u8 *, u8, u8, u8); static u16 ReadAsU16(const u8 *); static void Task_TryBecomeLinkLeader(u8); static void Task_TryJoinLinkGroup(u8); @@ -200,87 +223,86 @@ static void Task_MEvent_Leader(u8); static void Task_CardOrNewsWithFriend(u8); static void Task_CardOrNewsOverWireless(u8); static void Task_RunUnionRoom(u8); -static void ClearUnkStruct_x1CArray(struct UnkStruct_Main4 *, u8); -static void ClearUnkStruct_x20Array(struct UnkStruct_x20 *, u8); -static u8 CreateTask_ListenForPartnersWithCompatibleSerialNos(struct UnkStruct_Main4 *, u32); -static u8 CreateTask_ListenForPartnersWithSerial7F7D(struct UnkStruct_Main4 *, u32 ); +static void ClearIncomingPlayerList(struct RfuIncomingPlayerList *, u8); +static void ClearRfuPlayerList(struct RfuPlayer *, u8); +static u8 CreateTask_ListenForCompatiblePartners(struct RfuIncomingPlayerList *, u32); +static u8 CreateTask_ListenForWonderDistributor(struct RfuIncomingPlayerList *, u32 ); static bool8 PrintOnTextbox(u8 *, const u8 *); static bool8 Leader_SetStateIfMemberListChanged(struct WirelessLink_Leader *, u32, u32); -static u8 sub_8013398(struct UnkStruct_Main0 *); +static u8 LeaderPrunePlayerList(struct RfuPlayerList *); static s8 UnionRoomHandleYesNo(u8 *, bool32); -static void IntlConvPartnerUname7(u8 *, struct UnkStruct_x20 *); +static void CopyAndTranslatePlayerName(u8 *, struct RfuPlayer *); static void Leader_DestroyResources(struct WirelessLink_Leader *); static void CreateTask_RunScriptAndFadeToActivity(void); -static u8 LeaderUpdateGroupMembership(struct UnkStruct_Main0 *); -static void PrintGroupMemberCandidateOnWindowWithColor(u8, u8, u8, struct UnkStruct_x20 *, u8, u8 ); -static u32 Findx20Inx1CArray(struct UnkStruct_x20 *, struct UnkStruct_x1C *); -static u8 Appendx1Ctox20(struct UnkStruct_x20 *, struct UnkStruct_x1C *, u8); +static u8 LeaderUpdateGroupMembership(struct RfuPlayerList *); +static void PrintGroupCandidateOnWindow(u8, u8, u8, struct RfuPlayer *, u8, u8 ); +static u32 GetNewIncomingPlayerId(struct RfuPlayer *, struct RfuIncomingPlayer *); +static u8 TryAddIncomingPlayerToList(struct RfuPlayer *, struct RfuIncomingPlayer *, u8); static u8 GetNewLeaderCandidate(void); static u32 IsTryingToTradeAcrossVersionTooSoon(struct WirelessLink_Group *, s32); static void AskToJoinRfuGroup(struct WirelessLink_Group *, s32); static void JoinGroup_EnableScriptContexts(void); -static void PrintUnionRoomGroupOnWindow(u8, u8, u8, struct UnkStruct_x20 *, u8, u8); -static bool32 AreUnionRoomPlayerGnamesDifferent(struct WirelessGnameUnamePair *, struct WirelessGnameUnamePair *); +static void PrintGroupMemberOnWindow(u8, u8, u8, struct RfuPlayer *, u8, u8); +static bool32 ArePlayerDataDifferent(struct RfuPlayerData *, struct RfuPlayerData *); static u32 GetPartyPositionOfRegisteredMon(struct UnionRoomTrade *, u8); static void ResetUnionRoomTrade(struct UnionRoomTrade *); static void CreateTask_StartActivity(void); -static bool32 HasWonderCardOrNewsByLinkGroup(struct GFtgtGname *, s16); -static u8 CreateTask_SearchForChildOrParent(struct UnkStruct_Main4 *, struct UnkStruct_Main4 *, u32); +static bool32 HasWonderCardOrNewsByLinkGroup(struct RfuGameData *, s16); +static u8 CreateTask_SearchForChildOrParent(struct RfuIncomingPlayerList *, struct RfuIncomingPlayerList *, u32); static bool32 RegisterTradeMonAndGetIsEgg(u32, struct UnionRoomTrade *); static void RegisterTradeMon(u32, struct UnionRoomTrade *); -static void UR_EnableScriptContext2AndFreezeObjectEvents(void); +static void StartScriptInteraction(void); static bool32 IsPlayerFacingTradingBoard(void); static u8 HandlePlayerListUpdate(void); static bool32 PollPartnerYesNoResponse(struct WirelessLink_URoom *); static void ReceiveUnionRoomActivityPacket(struct WirelessLink_URoom *); -static u8 GetActivePartnerSpriteGenderParam(struct WirelessLink_URoom *); -static bool32 UnionRoom_HandleContactFromOtherPlayer(struct WirelessLink_URoom *); -static bool32 UR_RunTextPrinters_CheckPrinter0Active(void); -static s32 GetUnionRoomPlayerGender(s32, struct UnkStruct_Main0 *); -static s32 UnionRoomGetPlayerInteractionResponse(struct UnkStruct_Main0 *, u8, u8, u32); +static u8 GetActivePartnersInfo(struct WirelessLink_URoom *); +static bool32 HandleContactFromOtherPlayer(struct WirelessLink_URoom *); +static bool32 UR_RunTextPrinters(void); +static s32 GetUnionRoomPlayerGender(s32, struct RfuPlayerList *); +static s32 UnionRoomGetPlayerInteractionResponse(struct RfuPlayerList *, u8, u8, u32); static void HandleCancelActivity(bool32); static s32 ListMenuHandler_AllItemsAvailable(u8 *, u8 *, u8 *, const struct WindowTemplate *, const struct ListMenuTemplate *); -static s32 TradeBoardMenuHandler(u8 *, u8 *, u8 *, u8 *, const struct WindowTemplate *, const struct ListMenuTemplate *, struct UnkStruct_Main0 *); -static s32 GetIndexOfNthTradeBoardOffer(struct UnkStruct_x20 *, s32); +static s32 TradeBoardMenuHandler(u8 *, u8 *, u8 *, u8 *, const struct WindowTemplate *, const struct ListMenuTemplate *, struct RfuPlayerList *); +static s32 GetIndexOfNthTradeBoardOffer(struct RfuPlayer *, s32); static bool32 HasAtLeastTwoMonsOfLevel30OrLower(void); static u32 GetResponseIdx_InviteToURoomActivity(s32); static void ViewURoomPartnerTrainerCard(u8 *, struct WirelessLink_URoom *, bool8); static void GetURoomActivityRejectMsg(u8 *, s32, u32); -static u32 ConvPartnerUnameAndGetWhetherMetAlready(struct UnkStruct_x20 *); +static u32 ConvPartnerUnameAndGetWhetherMetAlready(struct RfuPlayer *); static void GetURoomActivityStartMsg(u8 *, u8); static void UR_ClearBg0(void); static s32 IsRequestedTypeOrEggInPlayerParty(u32, u32); static bool32 UR_PrintFieldMessage(const u8 *); static s32 GetChatLeaderActionRequestMessage(u8 *, u32, u16 *, struct WirelessLink_URoom *); static void Task_InitUnionRoom(u8 taskId); -static bool8 AreGnameUnameDifferent(struct WirelessGnameUnamePair*, const struct WirelessGnameUnamePair*); -static void ItemPrintFunc_PossibleGroupMembers(u8 windowId, u32 id, u8 y); -static void ListMenuItemPrintFunc_UnionRoomGroups(u8 windowId, u32 id, u8 y); -static void TradeBoardListMenuItemPrintFunc(u8 windowId, u32 id, u8 y); -static void nullsub_14(u8 windowId, u32 id, u8 y); +static bool8 ArePlayersDifferent(struct RfuPlayerData*, const struct RfuPlayerData*); +static void ItemPrintFunc_PossibleGroupMembers(u8, u32, u8); +static void ListMenuItemPrintFunc_UnionRoomGroups(u8, u32, u8); +static void TradeBoardListMenuItemPrintFunc(u8, u32, u8); +static void ItemPrintFunc_EmptyList(u8, u32, u8); #include "data/union_room.h" -// code static void PrintNumPlayersWaitingForMsg(u8 windowId, u8 capacityCode, u8 stringId) { FillWindowPixelBuffer(windowId, PIXEL_FILL(1)); switch (capacityCode << 8) { case LINK_GROUP_CAPACITY(0, 2): - UR_AddTextPrinterParameterized(windowId, 1, sPlayersNeededOrModeTexts[0][stringId - 1], 0, 1, UR_COLOR_DKE_WHT_LTE); + PrintUnionRoomText(windowId, 1, sPlayersNeededOrModeTexts[0][stringId - 1], 0, 1, UR_COLOR_DEFAULT); break; case LINK_GROUP_CAPACITY(0, 4): - UR_AddTextPrinterParameterized(windowId, 1, sPlayersNeededOrModeTexts[1][stringId - 1], 0, 1, UR_COLOR_DKE_WHT_LTE); + PrintUnionRoomText(windowId, 1, sPlayersNeededOrModeTexts[1][stringId - 1], 0, 1, UR_COLOR_DEFAULT); break; case LINK_GROUP_CAPACITY(2, 5): - UR_AddTextPrinterParameterized(windowId, 1, sPlayersNeededOrModeTexts[2][stringId - 1], 0, 1, UR_COLOR_DKE_WHT_LTE); + PrintUnionRoomText(windowId, 1, sPlayersNeededOrModeTexts[2][stringId - 1], 0, 1, UR_COLOR_DEFAULT); break; case LINK_GROUP_CAPACITY(3, 5): - UR_AddTextPrinterParameterized(windowId, 1, sPlayersNeededOrModeTexts[3][stringId - 1], 0, 1, UR_COLOR_DKE_WHT_LTE); + PrintUnionRoomText(windowId, 1, sPlayersNeededOrModeTexts[3][stringId - 1], 0, 1, UR_COLOR_DEFAULT); break; case LINK_GROUP_CAPACITY(2, 4): - UR_AddTextPrinterParameterized(windowId, 1, sPlayersNeededOrModeTexts[4][stringId - 1], 0, 1, UR_COLOR_DKE_WHT_LTE); + PrintUnionRoomText(windowId, 1, sPlayersNeededOrModeTexts[4][stringId - 1], 0, 1, UR_COLOR_DEFAULT); break; } @@ -292,13 +314,13 @@ static void PrintPlayerNameAndIdOnWindow(u8 windowId) u8 text[30]; u8 *txtPtr; - UR_AddTextPrinterParameterized(windowId, 1, gSaveBlock2Ptr->playerName, 0, 1, UR_COLOR_DKE_WHT_LTE); + PrintUnionRoomText(windowId, 1, gSaveBlock2Ptr->playerName, 0, 1, UR_COLOR_DEFAULT); txtPtr = StringCopy(text, sText_ID); ConvertIntToDecimalStringN(txtPtr, ReadAsU16(gSaveBlock2Ptr->playerTrainerId), STR_CONV_MODE_LEADING_ZEROS, 5); - UR_AddTextPrinterParameterized(windowId, 1, text, 0, 0x11, UR_COLOR_DKE_WHT_LTE); + PrintUnionRoomText(windowId, 1, text, 0, 17, UR_COLOR_DEFAULT); } -static void StringExpandPlaceholders_AwaitingCommFromAnother(u8 *dst, u8 caseId) +static void GetAwaitingCommunicationText(u8 *dst, u8 caseId) { switch (caseId) { @@ -313,8 +335,8 @@ static void StringExpandPlaceholders_AwaitingCommFromAnother(u8 *dst, u8 caseId) case ACTIVITY_BATTLE_TOWER_OPEN: case ACTIVITY_RECORD_CORNER: case ACTIVITY_BERRY_BLENDER: - case ACTIVITY_WONDER_CARD2: - case ACTIVITY_WONDER_NEWS2: + case ACTIVITY_WONDER_CARD: + case ACTIVITY_WONDER_NEWS: case ACTIVITY_CONTEST_COOL: case ACTIVITY_CONTEST_BEAUTY: case ACTIVITY_CONTEST_CUTE: @@ -377,24 +399,24 @@ static void Task_TryBecomeLinkLeader(u8 taskId) gSpecialVar_0x8004++; gPlayerCurrActivity = sLinkGroupToActivityAndCapacity[gSpecialVar_0x8004]; sPlayerActivityGroupSize = sLinkGroupToActivityAndCapacity[gSpecialVar_0x8004] >> 8; - SetHostRFUtgtGname(gPlayerCurrActivity, 0, 0); + SetHostRfuGameData(gPlayerCurrActivity, 0, FALSE); SetWirelessCommType1(); OpenLink(); InitializeRfuLinkManager_LinkLeader(GROUP_MAX(sPlayerActivityGroupSize)); data->state = LL_STATE_INIT2; break; case LL_STATE_INIT2: - data->field_4 = AllocZeroed(4 * sizeof(struct UnkStruct_x1C)); - data->field_0 = AllocZeroed(5 * sizeof(struct UnkStruct_x20)); - data->field_8 = AllocZeroed(5 * sizeof(struct UnkStruct_x20)); - ClearUnkStruct_x1CArray(data->field_4, 4); - ClearUnkStruct_x20Array(data->field_0->arr, 5); - LinkRfu3_SetGnameUnameFromStaticBuffers(&data->field_0->arr[0].gname_uname.gname, data->field_0->arr[0].gname_uname.playerName); - data->field_0->arr[0].timeoutCounter = 0; - data->field_0->arr[0].groupScheduledAnim = UNION_ROOM_SPAWN_IN; - data->field_0->arr[0].useRedText = FALSE; - data->field_0->arr[0].field_1B = 0; - data->listenTaskId = CreateTask_ListenForPartnersWithCompatibleSerialNos(data->field_4, 0xFF); + data->incomingPlayerList = AllocZeroed(RFU_CHILD_MAX * sizeof(struct RfuIncomingPlayer)); + data->playerList = AllocZeroed(MAX_RFU_PLAYERS * sizeof(struct RfuPlayer)); + data->playerListBackup = AllocZeroed(MAX_RFU_PLAYERS * sizeof(struct RfuPlayer)); + ClearIncomingPlayerList(data->incomingPlayerList, RFU_CHILD_MAX); + ClearRfuPlayerList(data->playerList->players, MAX_RFU_PLAYERS); + CopyHostRfuGameDataAndUsername(&data->playerList->players[0].rfu.data, data->playerList->players[0].rfu.name); + data->playerList->players[0].timeoutCounter = 0; + data->playerList->players[0].groupScheduledAnim = UNION_ROOM_SPAWN_IN; + data->playerList->players[0].useRedText = FALSE; + data->playerList->players[0].newPlayerCountdown = 0; + data->listenTaskId = CreateTask_ListenForCompatiblePartners(data->incomingPlayerList, 0xFF); data->bButtonCancelWindowId = AddWindow(&sWindowTemplate_BButtonCancel); switch (GROUP_MAX(sPlayerActivityGroupSize)) { @@ -410,7 +432,7 @@ static void Task_TryBecomeLinkLeader(u8 taskId) data->nPlayerModeWindowId = AddWindow(&sWindowTemplate_NumPlayerMode); FillWindowPixelBuffer(data->bButtonCancelWindowId, PIXEL_FILL(2)); - UR_AddTextPrinterParameterized(data->bButtonCancelWindowId, 0, sText_BButtonCancel, 8, 1, 4); + PrintUnionRoomText(data->bButtonCancelWindowId, 0, sText_BButtonCancel, 8, 1, UR_COLOR_CANCEL); PutWindowTilemap(data->bButtonCancelWindowId); CopyWindowToVram(data->bButtonCancelWindowId, 2); @@ -438,7 +460,7 @@ static void Task_TryBecomeLinkLeader(u8 taskId) } else { - StringExpandPlaceholders_AwaitingCommFromAnother(gStringVar4, gPlayerCurrActivity); + GetAwaitingCommunicationText(gStringVar4, gPlayerCurrActivity); } PrintNumPlayersWaitingForMsg(data->nPlayerModeWindowId, sPlayerActivityGroupSize, data->playerCount); @@ -462,22 +484,24 @@ static void Task_TryBecomeLinkLeader(u8 taskId) if (GROUP_MIN(sPlayerActivityGroupSize) != 0 && data->playerCount > GROUP_MIN(sPlayerActivityGroupSize) - 1 && GROUP_MAX(sPlayerActivityGroupSize) != 0 - && sub_8012240() + && IsRfuCommunicatingWithAllChildren() && JOY_NEW(START_BUTTON)) { data->state = LL_STATE_MEMBERS_OK_PROMPT; LinkRfu_StopManagerAndFinalizeSlots(); } - if (data->state == LL_STATE_AWAIT_PLAYERS && sub_80105EC()) + if (data->state == LL_STATE_AWAIT_PLAYERS && RfuTryDisconnectLeavingChildren()) { - data->state = LL_STATE_9; + // At least 1 group member has left or is trying to leave + data->state = LL_STATE_WAIT_DISCONNECT_CHILD; } break; - case LL_STATE_9: - if (!sub_80105EC()) + case LL_STATE_WAIT_DISCONNECT_CHILD: + // Resume after ensuring all members trying to leave have left + if (!RfuTryDisconnectLeavingChildren()) { data->state = LL_STATE_AWAIT_PLAYERS; - data->playerCount = sub_8013398(data->field_0); + data->playerCount = LeaderPrunePlayerList(data->playerList); } break; case LL_STATE_MEMBER_LEFT: @@ -491,7 +515,7 @@ static void Task_TryBecomeLinkLeader(u8 taskId) #endif if (PrintOnTextbox(&data->textState, sPlayerUnavailableTexts[id])) { - data->playerCount = sub_8013398(data->field_0); + data->playerCount = LeaderPrunePlayerList(data->playerList); RedrawListMenu(data->listTaskId); data->state = LL_STATE_GET_AWAITING_PLAYERS_TEXT; } @@ -510,44 +534,44 @@ static void Task_TryBecomeLinkLeader(u8 taskId) } break; case LL_STATE_ACCEPT_NEW_MEMBER_PROMPT_HANDLE_INPUT: - switch (UnionRoomHandleYesNo(&data->textState, HasTrainerLeftPartnersList(ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.unk_00.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.playerName))) + switch (UnionRoomHandleYesNo(&data->textState, HasTrainerLeftPartnersList(ReadAsU16(data->playerList->players[data->playerCount].rfu.data.compatibility.playerTrainerId), data->playerList->players[data->playerCount].rfu.name))) { case 0: // YES LoadWirelessStatusIndicatorSpriteGfx(); CreateWirelessStatusIndicatorSprite(0, 0); data->joinRequestAnswer = RFU_STATUS_JOIN_GROUP_OK; - SendRfuStatusToPartner(data->joinRequestAnswer, ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.unk_00.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.playerName); + SendRfuStatusToPartner(data->joinRequestAnswer, ReadAsU16(data->playerList->players[data->playerCount].rfu.data.compatibility.playerTrainerId), data->playerList->players[data->playerCount].rfu.name); data->state = LL_STATE_UPDATE_AFTER_JOIN_REQUEST; break; case 1: // NO - case -1: + case MENU_B_PRESSED: data->joinRequestAnswer = RFU_STATUS_JOIN_GROUP_NO; - SendRfuStatusToPartner(data->joinRequestAnswer, ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.unk_00.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.playerName); + SendRfuStatusToPartner(data->joinRequestAnswer, ReadAsU16(data->playerList->players[data->playerCount].rfu.data.compatibility.playerTrainerId), data->playerList->players[data->playerCount].rfu.name); data->state = LL_STATE_UPDATE_AFTER_JOIN_REQUEST; break; case -3: - data->state = LL_STATE_9; + data->state = LL_STATE_WAIT_DISCONNECT_CHILD; break; } break; case LL_STATE_UPDATE_AFTER_JOIN_REQUEST: - val = WaitSendRfuStatusToPartner(ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.unk_00.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.playerName); + val = WaitSendRfuStatusToPartner(ReadAsU16(data->playerList->players[data->playerCount].rfu.data.compatibility.playerTrainerId), data->playerList->players[data->playerCount].rfu.name); if (val == 1) // Send complete { if (data->joinRequestAnswer == RFU_STATUS_JOIN_GROUP_OK) { - data->field_0->arr[data->playerCount].field_1B = 0; + data->playerList->players[data->playerCount].newPlayerCountdown = 0; RedrawListMenu(data->listTaskId); data->playerCount++; if (data->playerCount == GROUP_MAX(sPlayerActivityGroupSize)) { - if (GROUP_MIN2(sPlayerActivityGroupSize) != 0 || data->playerCount == 4) + if (GROUP_MIN2(sPlayerActivityGroupSize) != 0 || data->playerCount == RFU_CHILD_MAX) { data->state = LL_STATE_MEMBERS_OK_PROMPT; } else { - IntlConvPartnerUname7(gStringVar1, &data->field_0->arr[data->playerCount - 1]); + CopyAndTranslatePlayerName(gStringVar1, &data->playerList->players[data->playerCount - 1]); StringExpandPlaceholders(gStringVar4, sText_AnOKWasSentToPlayer); data->state = LL_STATE_ACCEPTED_FINAL_MEMBER; } @@ -562,9 +586,9 @@ static void Task_TryBecomeLinkLeader(u8 taskId) } else // Member disconnected { - RequestDisconnectSlotByTrainerNameAndId(data->field_0->arr[data->playerCount].gname_uname.playerName, ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.unk_00.playerTrainerId)); - data->field_0->arr[data->playerCount].groupScheduledAnim = UNION_ROOM_SPAWN_NONE; - sub_8013398(data->field_0); + RequestDisconnectSlotByTrainerNameAndId(data->playerList->players[data->playerCount].rfu.name, ReadAsU16(data->playerList->players[data->playerCount].rfu.data.compatibility.playerTrainerId)); + data->playerList->players[data->playerCount].groupScheduledAnim = UNION_ROOM_SPAWN_NONE; + LeaderPrunePlayerList(data->playerList); RedrawListMenu(data->listTaskId); data->state = LL_STATE_GET_AWAITING_PLAYERS_TEXT; } @@ -596,7 +620,7 @@ static void Task_TryBecomeLinkLeader(u8 taskId) data->state = LL_STATE_CONFIRMED_MEMBERS; break; case 1: // NO - case -1: + case MENU_B_PRESSED: if (GROUP_MIN2(sPlayerActivityGroupSize) != 0) data->state = LL_STATE_CANCEL_WITH_MSG; else @@ -615,7 +639,7 @@ static void Task_TryBecomeLinkLeader(u8 taskId) data->state = LL_STATE_SHUTDOWN_AND_FAIL; break; case 1: // NO - case -1: + case MENU_B_PRESSED: if (GROUP_MIN2(sPlayerActivityGroupSize) != 0) data->state = LL_STATE_MEMBERS_OK_PROMPT; else if (data->playerCount == GROUP_MAX(sPlayerActivityGroupSize)) @@ -682,7 +706,7 @@ static void Task_TryBecomeLinkLeader(u8 taskId) if (gReceivedRemoteLinkPlayers != 0) { if (IsActivityWithVariableGroupSize(gPlayerCurrActivity)) - sub_801103C(); + GetOtherPlayersInfoFlags(); UpdateGameData_GroupLockedIn(TRUE); CreateTask_RunScriptAndFadeToActivity(); Leader_DestroyResources(data); @@ -706,9 +730,9 @@ static void Leader_DestroyResources(struct WirelessLink_Leader *data) RemoveWindow(data->bButtonCancelWindowId); DestroyTask(data->listenTaskId); - Free(data->field_8); - Free(data->field_0); - Free(data->field_4); + Free(data->playerListBackup); + Free(data->playerList); + Free(data->incomingPlayerList); } static void Leader_GetAcceptNewMemberPrompt(u8 *dst, u8 caseId) @@ -722,8 +746,8 @@ static void Leader_GetAcceptNewMemberPrompt(u8 *dst, u8 caseId) case ACTIVITY_BATTLE_TOWER: StringExpandPlaceholders(dst, sText_PlayerContactedYouForXAccept); break; - case ACTIVITY_WONDER_CARD2: - case ACTIVITY_WONDER_NEWS2: + case ACTIVITY_WONDER_CARD: + case ACTIVITY_WONDER_NEWS: StringExpandPlaceholders(dst, sText_PlayerContactedYouShareX); break; case ACTIVITY_BATTLE_MULTI: @@ -766,8 +790,8 @@ static void GetYouAskedToJoinGroupPleaseWaitMessage(u8 *dst, u8 caseId) case ACTIVITY_TRADE: case ACTIVITY_BATTLE_TOWER: case ACTIVITY_BATTLE_TOWER_OPEN: - case ACTIVITY_WONDER_CARD2: - case ACTIVITY_WONDER_NEWS2: + case ACTIVITY_WONDER_CARD: + case ACTIVITY_WONDER_NEWS: StringExpandPlaceholders(dst, sText_AwaitingPlayersResponse); break; case ACTIVITY_BATTLE_MULTI: @@ -795,8 +819,8 @@ static void GetGroupLeaderSentAnOKMessage(u8 *dst, u8 caseId) case ACTIVITY_TRADE: case ACTIVITY_BATTLE_TOWER: case ACTIVITY_BATTLE_TOWER_OPEN: - case ACTIVITY_WONDER_CARD2: - case ACTIVITY_WONDER_NEWS2: + case ACTIVITY_WONDER_CARD: + case ACTIVITY_WONDER_NEWS: StringExpandPlaceholders(dst, sText_PlayerSentBackOK); break; case ACTIVITY_BATTLE_MULTI: @@ -817,12 +841,12 @@ static void GetGroupLeaderSentAnOKMessage(u8 *dst, u8 caseId) static bool8 Leader_SetStateIfMemberListChanged(struct WirelessLink_Leader *data, u32 joinedState, u32 droppedState) { - switch (LeaderUpdateGroupMembership(data->field_0)) + switch (LeaderUpdateGroupMembership(data->playerList)) { case UNION_ROOM_SPAWN_IN: PlaySE(SE_PC_LOGIN); RedrawListMenu(data->listTaskId); - IntlConvPartnerUname7(gStringVar2, &data->field_0->arr[data->playerCount]); + CopyAndTranslatePlayerName(gStringVar2, &data->playerList->players[data->playerCount]); Leader_GetAcceptNewMemberPrompt(gStringVar4, gPlayerCurrActivity); data->state = joinedState; break; @@ -839,23 +863,23 @@ static bool8 Leader_SetStateIfMemberListChanged(struct WirelessLink_Leader *data static void ItemPrintFunc_PossibleGroupMembers(u8 windowId, u32 id, u8 y) { struct WirelessLink_Leader *data = sWirelessLinkMain.leader; - u8 colorIdx = UR_COLOR_DKE_WHT_LTE; + u8 colorIdx = UR_COLOR_DEFAULT; - switch (data->field_0->arr[id].groupScheduledAnim) + switch (data->playerList->players[id].groupScheduledAnim) { case UNION_ROOM_SPAWN_IN: - if (data->field_0->arr[id].field_1B != 0) - colorIdx = UR_COLOR_GRN_WHT_LTG; + if (data->playerList->players[id].newPlayerCountdown != 0) + colorIdx = UR_COLOR_GREEN; break; case UNION_ROOM_SPAWN_OUT: - colorIdx = UR_COLOR_RED_WHT_LTR; + colorIdx = UR_COLOR_RED; break; } - PrintGroupMemberCandidateOnWindowWithColor(windowId, 0, y, &data->field_0->arr[id], colorIdx, id); + PrintGroupCandidateOnWindow(windowId, 0, y, &data->playerList->players[id], colorIdx, id); } -static u8 LeaderUpdateGroupMembership(struct UnkStruct_Main0 *arg0) +static u8 LeaderUpdateGroupMembership(struct RfuPlayerList *list) { struct WirelessLink_Leader *data = sWirelessLinkMain.leader; u8 ret = UNION_ROOM_SPAWN_NONE; @@ -864,31 +888,33 @@ static u8 LeaderUpdateGroupMembership(struct UnkStruct_Main0 *arg0) for (i = 1; i < MAX_RFU_PLAYERS; i++) { - u16 var = data->field_0->arr[i].groupScheduledAnim; + u16 var = data->playerList->players[i].groupScheduledAnim; if (var == UNION_ROOM_SPAWN_IN) { - id = Findx20Inx1CArray(&data->field_0->arr[i], data->field_4->arr); + id = GetNewIncomingPlayerId(&data->playerList->players[i], data->incomingPlayerList->players); if (id != 0xFF) { - data->field_0->arr[i].gname_uname = data->field_4->arr[id].gname_uname; - data->field_0->arr[i].timeoutCounter = 1; + // New incoming player + data->playerList->players[i].rfu = data->incomingPlayerList->players[id].rfu; + data->playerList->players[i].timeoutCounter = 1; } else { - data->field_0->arr[i].groupScheduledAnim = UNION_ROOM_SPAWN_OUT; + // No new incoming player + data->playerList->players[i].groupScheduledAnim = UNION_ROOM_SPAWN_OUT; ret = UNION_ROOM_SPAWN_OUT; } } } for (id = 0; id < RFU_CHILD_MAX; id++) - Appendx1Ctox20(data->field_0->arr, &data->field_4->arr[id], MAX_RFU_PLAYERS); + TryAddIncomingPlayerToList(data->playerList->players, &data->incomingPlayerList->players[id], MAX_RFU_PLAYERS); if (ret != UNION_ROOM_SPAWN_OUT) { for (id = 0; id < MAX_RFU_PLAYERS; id++) { - if (data->field_0->arr[id].field_1B != 0) + if (data->playerList->players[id].newPlayerCountdown != 0) ret = UNION_ROOM_SPAWN_IN; } } @@ -896,7 +922,7 @@ static u8 LeaderUpdateGroupMembership(struct UnkStruct_Main0 *arg0) return ret; } -static u8 sub_8013398(struct UnkStruct_Main0 *arg0) +static u8 LeaderPrunePlayerList(struct RfuPlayerList *list) { struct WirelessLink_Leader *data = sWirelessLinkMain.leader; u8 copiedCount; @@ -904,14 +930,14 @@ static u8 sub_8013398(struct UnkStruct_Main0 *arg0) u8 playerCount; for (i = 0; i < MAX_RFU_PLAYERS; i++) - data->field_8->arr[i] = data->field_0->arr[i]; + data->playerListBackup->players[i] = data->playerList->players[i]; copiedCount = 0; for (i = 0; i < MAX_RFU_PLAYERS; i++) { - if (data->field_8->arr[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN) + if (data->playerListBackup->players[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN) { - data->field_0->arr[copiedCount] = data->field_8->arr[i]; + data->playerList->players[copiedCount] = data->playerListBackup->players[i]; copiedCount++; } } @@ -919,18 +945,18 @@ static u8 sub_8013398(struct UnkStruct_Main0 *arg0) playerCount = copiedCount; for (; copiedCount < MAX_RFU_PLAYERS; copiedCount++) { - data->field_0->arr[copiedCount].gname_uname = sWirelessGnameUnamePair_Dummy; - data->field_0->arr[copiedCount].timeoutCounter = 0; - data->field_0->arr[copiedCount].groupScheduledAnim = UNION_ROOM_SPAWN_NONE; - data->field_0->arr[copiedCount].useRedText = FALSE; - data->field_0->arr[copiedCount].field_1B = 0; + data->playerList->players[copiedCount].rfu = sUnionRoomPlayer_DummyRfu; + data->playerList->players[copiedCount].timeoutCounter = 0; + data->playerList->players[copiedCount].groupScheduledAnim = UNION_ROOM_SPAWN_NONE; + data->playerList->players[copiedCount].useRedText = FALSE; + data->playerList->players[copiedCount].newPlayerCountdown = 0; } for (i = 0; i < MAX_RFU_PLAYERS; i++) { - if (data->field_0->arr[i].groupScheduledAnim != UNION_ROOM_SPAWN_IN) + if (data->playerList->players[i].groupScheduledAnim != UNION_ROOM_SPAWN_IN) continue; - if (data->field_0->arr[i].field_1B != 64) + if (data->playerList->players[i].newPlayerCountdown != 64) continue; playerCount = i; @@ -965,12 +991,12 @@ static void Task_TryJoinLinkGroup(u8 taskId) if (gSpecialVar_0x8004 == LINK_GROUP_BATTLE_TOWER && gSaveBlock2Ptr->frontier.lvlMode == FRONTIER_LVL_OPEN) gSpecialVar_0x8004++; gPlayerCurrActivity = sLinkGroupToURoomActivity[gSpecialVar_0x8004]; - SetHostRFUtgtGname(gPlayerCurrActivity, 0, 0); + SetHostRfuGameData(gPlayerCurrActivity, 0, FALSE); SetWirelessCommType1(); OpenLink(); InitializeRfuLinkManager_JoinGroup(); - data->field_4 = AllocZeroed(4 * sizeof(struct UnkStruct_x1C)); - data->field_0 = AllocZeroed(16 * sizeof(struct UnkStruct_x20)); + data->incomingPlayerList = AllocZeroed(RFU_CHILD_MAX * sizeof(struct RfuIncomingPlayer)); + data->playerList = AllocZeroed(MAX_RFU_PLAYER_LIST_SIZE * sizeof(struct RfuPlayer)); data->state = LG_STATE_CHOOSE_LEADER_MSG; break; case LG_STATE_CHOOSE_LEADER_MSG: @@ -978,15 +1004,15 @@ static void Task_TryJoinLinkGroup(u8 taskId) data->state = LG_STATE_INIT_WINDOWS; break; case LG_STATE_INIT_WINDOWS: - ClearUnkStruct_x1CArray(data->field_4, 4); - ClearUnkStruct_x20Array(data->field_0->arr, 16); - data->listenTaskId = CreateTask_ListenForPartnersWithCompatibleSerialNos(data->field_4, gSpecialVar_0x8004); + ClearIncomingPlayerList(data->incomingPlayerList, RFU_CHILD_MAX); + ClearRfuPlayerList(data->playerList->players, MAX_RFU_PLAYER_LIST_SIZE); + data->listenTaskId = CreateTask_ListenForCompatiblePartners(data->incomingPlayerList, gSpecialVar_0x8004); data->bButtonCancelWindowId = AddWindow(&sWindowTemplate_BButtonCancel); - data->listWindowId = AddWindow(&gUnknown_082F0174); - data->playerNameAndIdWindowId = AddWindow(&gUnknown_082F017C); + data->listWindowId = AddWindow(&sWindowTemplate_GroupList); + data->playerNameAndIdWindowId = AddWindow(&sWindowTemplate_PlayerNameAndId); FillWindowPixelBuffer(data->bButtonCancelWindowId, PIXEL_FILL(2)); - UR_AddTextPrinterParameterized(data->bButtonCancelWindowId, 0, sText_ChooseJoinCancel, 8, 1, 4); + PrintUnionRoomText(data->bButtonCancelWindowId, 0, sText_ChooseJoinCancel, 8, 1, UR_COLOR_CANCEL); PutWindowTilemap(data->bButtonCancelWindowId); CopyWindowToVram(data->bButtonCancelWindowId, 2); @@ -1014,12 +1040,12 @@ static void Task_TryJoinLinkGroup(u8 taskId) break; case 0: id = ListMenu_ProcessInput(data->listTaskId); - if (JOY_NEW(A_BUTTON) && id != -1) + if (JOY_NEW(A_BUTTON) && id != MENU_B_PRESSED) { // this unused variable along with the assignment is needed to match - u32 activity = data->field_0->arr[id].gname_uname.gname.activity; + u32 activity = data->playerList->players[id].rfu.data.activity; - if (data->field_0->arr[id].groupScheduledAnim == UNION_ROOM_SPAWN_IN && !data->field_0->arr[id].gname_uname.gname.started) + if (data->playerList->players[id].groupScheduledAnim == UNION_ROOM_SPAWN_IN && !data->playerList->players[id].rfu.data.startedActivity) { u32 readyStatus = IsTryingToTradeAcrossVersionTooSoon(data, id); if (readyStatus == UR_TRADE_READY) @@ -1055,14 +1081,14 @@ static void Task_TryJoinLinkGroup(u8 taskId) GetYouAskedToJoinGroupPleaseWaitMessage(gStringVar4, gPlayerCurrActivity); if (PrintOnTextbox(&data->textState, gStringVar4)) { - IntlConvPartnerUname7(gStringVar1, &data->field_0->arr[data->leaderId]); + CopyAndTranslatePlayerName(gStringVar1, &data->playerList->players[data->leaderId]); data->state = LG_STATE_MAIN; } break; case LG_STATE_MAIN: if (gReceivedRemoteLinkPlayers) { - gPlayerCurrActivity = data->field_0->arr[data->leaderId].gname_uname.gname.activity; + gPlayerCurrActivity = data->playerList->players[data->leaderId].rfu.data.activity; RfuSetStatus(RFU_STATUS_OK, 0); switch (gPlayerCurrActivity) { @@ -1079,8 +1105,8 @@ static void Task_TryJoinLinkGroup(u8 taskId) case ACTIVITY_BATTLE_TOWER_OPEN: case ACTIVITY_RECORD_CORNER: case ACTIVITY_BERRY_BLENDER: - case ACTIVITY_WONDER_CARD2: - case ACTIVITY_WONDER_NEWS2: + case ACTIVITY_WONDER_CARD: + case ACTIVITY_WONDER_NEWS: case ACTIVITY_CONTEST_COOL: case ACTIVITY_CONTEST_BEAUTY: case ACTIVITY_CONTEST_CUTE: @@ -1160,7 +1186,7 @@ static void Task_TryJoinLinkGroup(u8 taskId) RedrawListMenu(data->listTaskId); break; case 1: // NO - case -1: + case MENU_B_PRESSED: data->state = LG_STATE_ASK_JOIN_GROUP; RedrawListMenu(data->listTaskId); break; @@ -1189,8 +1215,8 @@ static void Task_TryJoinLinkGroup(u8 taskId) RemoveWindow(data->listWindowId); RemoveWindow(data->bButtonCancelWindowId); DestroyTask(data->listenTaskId); - Free(data->field_0); - Free(data->field_4); + Free(data->playerList); + Free(data->incomingPlayerList); data->state++; break; case LG_STATE_RFU_ERROR_SHUTDOWN: @@ -1238,13 +1264,13 @@ static void Task_TryJoinLinkGroup(u8 taskId) static u32 IsTryingToTradeAcrossVersionTooSoon(struct WirelessLink_Group *data, s32 id) { - struct UnkStruct_x20 *structPtr = &data->field_0->arr[id]; + struct RfuPlayer *partner = &data->playerList->players[id]; - if (gPlayerCurrActivity == ACTIVITY_TRADE && structPtr->gname_uname.gname.unk_00.version != VERSION_EMERALD) + if (gPlayerCurrActivity == ACTIVITY_TRADE && partner->rfu.data.compatibility.version != VERSION_EMERALD) { if (!(gSaveBlock2Ptr->specialSaveWarpFlags & CHAMPION_SAVEWARP)) return UR_TRADE_PLAYER_NOT_READY; - else if (structPtr->gname_uname.gname.unk_00.isChampion) + else if (partner->rfu.data.compatibility.isChampion) return UR_TRADE_READY; } else @@ -1261,9 +1287,9 @@ static void AskToJoinRfuGroup(struct WirelessLink_Group *data, s32 id) LoadWirelessStatusIndicatorSpriteGfx(); CreateWirelessStatusIndicatorSprite(0, 0); RedrawListMenu(data->listTaskId); - IntlConvPartnerUname7(gStringVar1, &data->field_0->arr[data->leaderId]); + CopyAndTranslatePlayerName(gStringVar1, &data->playerList->players[data->leaderId]); UpdateGameData_SetActivity(sLinkGroupToURoomActivity[gSpecialVar_0x8004], 0, TRUE); - CreateTask_RfuReconnectWithParent(data->field_0->arr[data->leaderId].gname_uname.playerName, ReadAsU16(data->field_0->arr[data->leaderId].gname_uname.gname.unk_00.playerTrainerId)); + CreateTask_RfuReconnectWithParent(data->playerList->players[data->leaderId].rfu.name, ReadAsU16(data->playerList->players[data->leaderId].rfu.data.compatibility.playerTrainerId)); } u8 CreateTask_ListenToWireless(void) @@ -1289,19 +1315,19 @@ static void Task_ListenToWireless(u8 taskId) switch (data->state) { case 0: - SetHostRFUtgtGname(0, 0, 0); + SetHostRfuGameData(ACTIVITY_NONE, 0, FALSE); SetWirelessCommType1(); OpenLink(); InitializeRfuLinkManager_JoinGroup(); - sub_80111B0(TRUE); - data->field_4 = AllocZeroed(4 * sizeof(struct UnkStruct_x1C)); - data->field_0 = AllocZeroed(16 * sizeof(struct UnkStruct_x20)); + RfuSetIgnoreError(TRUE); + data->incomingPlayerList = AllocZeroed(RFU_CHILD_MAX * sizeof(struct RfuIncomingPlayer)); + data->playerList = AllocZeroed(MAX_RFU_PLAYER_LIST_SIZE * sizeof(struct RfuPlayer)); data->state = 2; break; case 2: - ClearUnkStruct_x1CArray(data->field_4, 4); - ClearUnkStruct_x20Array(data->field_0->arr, 16); - data->listenTaskId = CreateTask_ListenForPartnersWithCompatibleSerialNos(data->field_4, 0xFF); + ClearIncomingPlayerList(data->incomingPlayerList, RFU_CHILD_MAX); + ClearRfuPlayerList(data->playerList->players, MAX_RFU_PLAYER_LIST_SIZE); + data->listenTaskId = CreateTask_ListenForCompatiblePartners(data->incomingPlayerList, 0xFF); data->leaderId = 0; data->state = 3; break; @@ -1313,8 +1339,8 @@ static void Task_ListenToWireless(u8 taskId) break; case 10: DestroyTask(data->listenTaskId); - Free(data->field_0); - Free(data->field_4); + Free(data->playerList); + Free(data->incomingPlayerList); LinkRfu_Shutdown(); data->state++; break; @@ -1349,27 +1375,26 @@ static bool32 IsPartnerActivityAcceptable(u32 activity, u32 linkGroup) return FALSE; } -static u8 URoomGroupListGetTextColor(struct WirelessLink_Group *data, u32 id) +static u8 GetGroupListTextColor(struct WirelessLink_Group *data, u32 id) { - if (data->field_0->arr[id].groupScheduledAnim == UNION_ROOM_SPAWN_IN) + if (data->playerList->players[id].groupScheduledAnim == UNION_ROOM_SPAWN_IN) { - if (data->field_0->arr[id].gname_uname.gname.started) - return UR_COLOR_WHT_WHT_LTE; - else if (data->field_0->arr[id].useRedText) - return UR_COLOR_RED_WHT_LTR; - else if (data->field_0->arr[id].field_1B != 0) - return UR_COLOR_GRN_WHT_LTG; + if (data->playerList->players[id].rfu.data.startedActivity) + return UR_COLOR_WHITE; + else if (data->playerList->players[id].useRedText) + return UR_COLOR_RED; + else if (data->playerList->players[id].newPlayerCountdown != 0) + return UR_COLOR_GREEN; } - - return UR_COLOR_DKE_WHT_LTE; + return UR_COLOR_DEFAULT; } static void ListMenuItemPrintFunc_UnionRoomGroups(u8 windowId, u32 id, u8 y) { struct WirelessLink_Group *data = sWirelessLinkMain.group; - u8 colorId = URoomGroupListGetTextColor(data, id); + u8 colorId = GetGroupListTextColor(data, id); - PrintUnionRoomGroupOnWindow(windowId, 8, y, &data->field_0->arr[id], colorId, id); + PrintGroupMemberOnWindow(windowId, 8, y, &data->playerList->players[id], colorId, id); } static u8 GetNewLeaderCandidate(void) @@ -1379,48 +1404,48 @@ static u8 GetNewLeaderCandidate(void) u8 i; s32 id; - for (i = 0; i < 16; i++) + for (i = 0; i < MAX_RFU_PLAYER_LIST_SIZE; i++) { - if (data->field_0->arr[i].groupScheduledAnim != UNION_ROOM_SPAWN_NONE) + if (data->playerList->players[i].groupScheduledAnim != UNION_ROOM_SPAWN_NONE) { - id = Findx20Inx1CArray(&data->field_0->arr[i], data->field_4->arr); + id = GetNewIncomingPlayerId(&data->playerList->players[i], data->incomingPlayerList->players); if (id != 0xFF) { - if (data->field_0->arr[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN) + if (data->playerList->players[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN) { - if (AreUnionRoomPlayerGnamesDifferent(&data->field_0->arr[i].gname_uname, &data->field_4->arr[id].gname_uname)) + if (ArePlayerDataDifferent(&data->playerList->players[i].rfu, &data->incomingPlayerList->players[id].rfu)) { - data->field_0->arr[i].gname_uname = data->field_4->arr[id].gname_uname; - data->field_0->arr[i].field_1B = 64; + data->playerList->players[i].rfu = data->incomingPlayerList->players[id].rfu; + data->playerList->players[i].newPlayerCountdown = 64; ret = 1; } else { - if (data->field_0->arr[i].field_1B != 0) + if (data->playerList->players[i].newPlayerCountdown != 0) { - data->field_0->arr[i].field_1B--; - if (data->field_0->arr[i].field_1B == 0) + data->playerList->players[i].newPlayerCountdown--; + if (data->playerList->players[i].newPlayerCountdown == 0) ret = 2; } } } else { - data->field_0->arr[i].groupScheduledAnim = UNION_ROOM_SPAWN_IN; - data->field_0->arr[i].field_1B = 64; + data->playerList->players[i].groupScheduledAnim = UNION_ROOM_SPAWN_IN; + data->playerList->players[i].newPlayerCountdown = 64; ret = 1; } - data->field_0->arr[i].timeoutCounter = 0; + data->playerList->players[i].timeoutCounter = 0; } else { - if (data->field_0->arr[i].groupScheduledAnim != UNION_ROOM_SPAWN_OUT) + if (data->playerList->players[i].groupScheduledAnim != UNION_ROOM_SPAWN_OUT) { - data->field_0->arr[i].timeoutCounter++; - if (data->field_0->arr[i].timeoutCounter >= 300) + data->playerList->players[i].timeoutCounter++; + if (data->playerList->players[i].timeoutCounter >= 300) { - data->field_0->arr[i].groupScheduledAnim = UNION_ROOM_SPAWN_OUT; + data->playerList->players[i].groupScheduledAnim = UNION_ROOM_SPAWN_OUT; ret = 2; } } @@ -1430,7 +1455,7 @@ static u8 GetNewLeaderCandidate(void) for (id = 0; id < RFU_CHILD_MAX; id++) { - if (Appendx1Ctox20(data->field_0->arr, &data->field_4->arr[id], 16) != 0xFF) + if (TryAddIncomingPlayerToList(data->playerList->players, &data->incomingPlayerList->players[id], MAX_RFU_PLAYER_LIST_SIZE) != 0xFF) ret = 1; } @@ -1496,7 +1521,7 @@ static void Task_ExchangeCards(u8 taskId) { case 0: if (GetMultiplayerId() == 0) - SendBlockRequest(2); + SendBlockRequest(BLOCK_REQ_SIZE_100); gTasks[taskId].data[0]++; break; case 1: @@ -1625,7 +1650,7 @@ static void Task_StartActivity(u8 taskId) case ACTIVITY_BERRY_PICK: case ACTIVITY_SPIN_TRADE: case ACTIVITY_RECORD_CORNER: - RecordMixTrainerNames(); + SaveLinkTrainerNames(); break; } @@ -1689,7 +1714,7 @@ static void Task_StartActivity(u8 taskId) else { LinkRfu_StopManagerBeforeEnteringChat(); - SetHostRFUtgtGname(69, 0, 1); + SetHostRfuGameData(ACTIVITY_CHAT | IN_UNION_ROOM, 0, TRUE); } EnterUnionRoomChat(); break; @@ -1738,7 +1763,7 @@ static void Task_RunScriptAndFadeToActivity(u8 taskId) sendBuff[1] = GetMonData(&gPlayerParty[gSelectedOrderFromParty[1] - 1], MON_DATA_SPECIES, NULL); gMain.savedCallback = NULL; data[0] = 4; - RecordMixTrainerNames(); + SaveLinkTrainerNames(); ResetBlockReceivedFlags(); break; case ACTIVITY_BERRY_BLENDER: @@ -1747,7 +1772,7 @@ static void Task_RunScriptAndFadeToActivity(u8 taskId) case ACTIVITY_CONTEST_CUTE: case ACTIVITY_CONTEST_SMART: case ACTIVITY_CONTEST_TOUGH: - RecordMixTrainerNames(); + SaveLinkTrainerNames(); DestroyTask(taskId); default: EnableBothScriptContexts(); @@ -1858,29 +1883,29 @@ static void Task_MEvent_Leader(u8 taskId) case 0: gPlayerCurrActivity = data->activity; sPlayerActivityGroupSize = 2; - SetHostRFUtgtGname(data->activity, 0, 0); - SetGnameBufferWonderFlags(FALSE, FALSE); + SetHostRfuGameData(data->activity, 0, FALSE); + SetHostRfuWonderFlags(FALSE, FALSE); SetWirelessCommType1(); OpenLink(); InitializeRfuLinkManager_LinkLeader(2); data->state = 1; break; case 1: - data->field_4 = AllocZeroed(4 * sizeof(struct UnkStruct_x1C)); - data->field_0 = AllocZeroed(5 * sizeof(struct UnkStruct_x20)); - data->field_8 = AllocZeroed(5 * sizeof(struct UnkStruct_x20)); - ClearUnkStruct_x1CArray(data->field_4, 4); - ClearUnkStruct_x20Array(data->field_0->arr, 5); - LinkRfu3_SetGnameUnameFromStaticBuffers(&data->field_0->arr[0].gname_uname.gname, data->field_0->arr[0].gname_uname.playerName); - data->field_0->arr[0].timeoutCounter = 0; - data->field_0->arr[0].groupScheduledAnim = UNION_ROOM_SPAWN_IN; - data->field_0->arr[0].useRedText = FALSE; - data->field_0->arr[0].field_1B = 0; - data->listenTaskId = CreateTask_ListenForPartnersWithCompatibleSerialNos(data->field_4, 0xFF); + data->incomingPlayerList = AllocZeroed(RFU_CHILD_MAX * sizeof(struct RfuIncomingPlayer)); + data->playerList = AllocZeroed(MAX_RFU_PLAYERS * sizeof(struct RfuPlayer)); + data->playerListBackup = AllocZeroed(MAX_RFU_PLAYERS * sizeof(struct RfuPlayer)); + ClearIncomingPlayerList(data->incomingPlayerList, RFU_CHILD_MAX); + ClearRfuPlayerList(data->playerList->players, MAX_RFU_PLAYERS); + CopyHostRfuGameDataAndUsername(&data->playerList->players[0].rfu.data, data->playerList->players[0].rfu.name); + data->playerList->players[0].timeoutCounter = 0; + data->playerList->players[0].groupScheduledAnim = UNION_ROOM_SPAWN_IN; + data->playerList->players[0].useRedText = FALSE; + data->playerList->players[0].newPlayerCountdown = 0; + data->listenTaskId = CreateTask_ListenForCompatiblePartners(data->incomingPlayerList, 0xFF); winTemplate = sWindowTemplate_PlayerList; winTemplate.baseBlock = GetMysteryGiftBaseBlock(); - winTemplate.paletteNum = 0xC; + winTemplate.paletteNum = 12; data->listWindowId = AddWindow(&winTemplate); MG_DrawTextBorder(data->listWindowId); gMultiuseListMenuTemplate = sListMenuTemplate_PossibleGroupMembers; @@ -1893,7 +1918,7 @@ static void Task_MEvent_Leader(u8 taskId) break; case 2: StringCopy(gStringVar1, sLinkGroupActivityNameTexts[gPlayerCurrActivity]); - StringExpandPlaceholders_AwaitingCommFromAnother(gStringVar4, gPlayerCurrActivity); + GetAwaitingCommunicationText(gStringVar4, gPlayerCurrActivity); data->state = 3; break; case 3: @@ -1911,7 +1936,7 @@ static void Task_MEvent_Leader(u8 taskId) case 6: if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, sText_LinkWithFriendDropped)) { - data->playerCount = sub_8013398(data->field_0); + data->playerCount = LeaderPrunePlayerList(data->playerList); RedrawListMenu(data->listTaskId); data->state = 2; } @@ -1920,44 +1945,44 @@ static void Task_MEvent_Leader(u8 taskId) data->state = 7; break; case 7: - switch (mevent_message_print_and_prompt_yes_no(&data->textState, &data->field_14, 0, gStringVar4)) + switch (mevent_message_print_and_prompt_yes_no(&data->textState, &data->yesNoWindowId, 0, gStringVar4)) { case 0: LoadWirelessStatusIndicatorSpriteGfx(); CreateWirelessStatusIndicatorSprite(0, 0); - data->field_0->arr[data->playerCount].field_1B = 0; + data->playerList->players[data->playerCount].newPlayerCountdown = 0; RedrawListMenu(data->listTaskId); data->joinRequestAnswer = RFU_STATUS_JOIN_GROUP_OK; - SendRfuStatusToPartner(data->joinRequestAnswer, ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.unk_00.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.playerName); + SendRfuStatusToPartner(data->joinRequestAnswer, ReadAsU16(data->playerList->players[data->playerCount].rfu.data.compatibility.playerTrainerId), data->playerList->players[data->playerCount].rfu.name); data->state = 8; break; case 1: - case -1: + case MENU_B_PRESSED: data->joinRequestAnswer = RFU_STATUS_JOIN_GROUP_NO; - SendRfuStatusToPartner(data->joinRequestAnswer, ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.unk_00.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.playerName); + SendRfuStatusToPartner(data->joinRequestAnswer, ReadAsU16(data->playerList->players[data->playerCount].rfu.data.compatibility.playerTrainerId), data->playerList->players[data->playerCount].rfu.name); data->state = 8; break; } break; case 8: - val = WaitSendRfuStatusToPartner(ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.unk_00.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.playerName); + val = WaitSendRfuStatusToPartner(ReadAsU16(data->playerList->players[data->playerCount].rfu.data.compatibility.playerTrainerId), data->playerList->players[data->playerCount].rfu.name); if (val == 1) // Send complete { if (data->joinRequestAnswer == RFU_STATUS_JOIN_GROUP_OK) { - data->field_0->arr[data->playerCount].field_1B = 0; + data->playerList->players[data->playerCount].newPlayerCountdown = 0; RedrawListMenu(data->listTaskId); data->playerCount++; - IntlConvPartnerUname7(gStringVar1, &data->field_0->arr[data->playerCount - 1]); + CopyAndTranslatePlayerName(gStringVar1, &data->playerList->players[data->playerCount - 1]); StringExpandPlaceholders(gStringVar4, sText_AnOKWasSentToPlayer); data->state = 9; LinkRfu_StopManagerAndFinalizeSlots(); } else { - RequestDisconnectSlotByTrainerNameAndId(data->field_0->arr[data->playerCount].gname_uname.playerName, ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.unk_00.playerTrainerId)); - data->field_0->arr[data->playerCount].groupScheduledAnim = UNION_ROOM_SPAWN_NONE; - sub_8013398(data->field_0); + RequestDisconnectSlotByTrainerNameAndId(data->playerList->players[data->playerCount].rfu.name, ReadAsU16(data->playerList->players[data->playerCount].rfu.data.compatibility.playerTrainerId)); + data->playerList->players[data->playerCount].groupScheduledAnim = UNION_ROOM_SPAWN_NONE; + LeaderPrunePlayerList(data->playerList); RedrawListMenu(data->listTaskId); data->state = 2; } @@ -2000,9 +2025,9 @@ static void Task_MEvent_Leader(u8 taskId) CopyBgTilemapBufferToVram(0); RemoveWindow(data->listWindowId); DestroyTask(data->listenTaskId); - Free(data->field_8); - Free(data->field_0); - Free(data->field_4); + Free(data->playerListBackup); + Free(data->playerList); + Free(data->incomingPlayerList); data->state++; break; case 14: @@ -2028,9 +2053,9 @@ static void Task_MEvent_Leader(u8 taskId) CopyBgTilemapBufferToVram(0); RemoveWindow(data->listWindowId); DestroyTask(data->listenTaskId); - Free(data->field_8); - Free(data->field_0); - Free(data->field_4); + Free(data->playerListBackup); + Free(data->playerList); + Free(data->incomingPlayerList); SetLinkStandbyCallback(); data->state++; break; @@ -2052,25 +2077,25 @@ void MEvent_CreateTask_CardOrNewsWithFriend(u32 activity) data->state = 0; data->textState = 0; - data->isWonderNews = activity - ACTIVITY_WONDER_CARD2; + data->isWonderNews = activity - ACTIVITY_WONDER_CARD; gSpecialVar_Result = LINKUP_ONGOING; } static void Task_CardOrNewsWithFriend(u8 taskId) { s32 id; - struct WindowTemplate winTemplate1, winTemplate2; + struct WindowTemplate listWinTemplate, playerNameWinTemplate; struct WirelessLink_Group *data = sWirelessLinkMain.group; switch (data->state) { case 0: - SetHostRFUtgtGname(data->isWonderNews + ACTIVITY_WONDER_CARD2, 0, 0); + SetHostRfuGameData(data->isWonderNews + ACTIVITY_WONDER_CARD, 0, FALSE); SetWirelessCommType1(); OpenLink(); InitializeRfuLinkManager_JoinGroup(); - data->field_4 = AllocZeroed(4 * sizeof(struct UnkStruct_x1C)); - data->field_0 = AllocZeroed(16 * sizeof(struct UnkStruct_x20)); + data->incomingPlayerList = AllocZeroed(RFU_CHILD_MAX * sizeof(struct RfuIncomingPlayer)); + data->playerList = AllocZeroed(MAX_RFU_PLAYER_LIST_SIZE * sizeof(struct RfuPlayer)); data->state = 1; break; case 1: @@ -2078,18 +2103,18 @@ static void Task_CardOrNewsWithFriend(u8 taskId) data->state = 2; break; case 2: - ClearUnkStruct_x1CArray(data->field_4, 4); - ClearUnkStruct_x20Array(data->field_0->arr, 16); - data->listenTaskId = CreateTask_ListenForPartnersWithCompatibleSerialNos(data->field_4, data->isWonderNews + LINK_GROUP_WONDER_CARD); + ClearIncomingPlayerList(data->incomingPlayerList, RFU_CHILD_MAX); + ClearRfuPlayerList(data->playerList->players, MAX_RFU_PLAYER_LIST_SIZE); + data->listenTaskId = CreateTask_ListenForCompatiblePartners(data->incomingPlayerList, data->isWonderNews + LINK_GROUP_WONDER_CARD); - winTemplate1 = gUnknown_082F0174; - winTemplate1.baseBlock = GetMysteryGiftBaseBlock(); - winTemplate1.paletteNum = 0xC; - data->listWindowId = AddWindow(&winTemplate1); + listWinTemplate = sWindowTemplate_GroupList; + listWinTemplate.baseBlock = GetMysteryGiftBaseBlock(); + listWinTemplate.paletteNum = 12; + data->listWindowId = AddWindow(&listWinTemplate); - winTemplate2 = gUnknown_082F017C; - winTemplate2.paletteNum = 0xC; - data->playerNameAndIdWindowId = AddWindow(&winTemplate2); + playerNameWinTemplate = sWindowTemplate_PlayerNameAndId; + playerNameWinTemplate.paletteNum = 12; + data->playerNameAndIdWindowId = AddWindow(&playerNameWinTemplate); MG_DrawTextBorder(data->listWindowId); gMultiuseListMenuTemplate = sListMenuTemplate_UnionRoomGroups; @@ -2121,16 +2146,16 @@ static void Task_CardOrNewsWithFriend(u8 taskId) { // this unused variable along with the assignment is needed to match u32 unusedVar; - unusedVar = data->field_0->arr[id].gname_uname.gname.activity; + unusedVar = data->playerList->players[id].rfu.data.activity; - if (data->field_0->arr[id].groupScheduledAnim == UNION_ROOM_SPAWN_IN && !data->field_0->arr[id].gname_uname.gname.started) + if (data->playerList->players[id].groupScheduledAnim == UNION_ROOM_SPAWN_IN && !data->playerList->players[id].rfu.data.startedActivity) { data->leaderId = id; LoadWirelessStatusIndicatorSpriteGfx(); CreateWirelessStatusIndicatorSprite(0, 0); RedrawListMenu(data->listTaskId); - IntlConvPartnerUname7(gStringVar1, &data->field_0->arr[data->leaderId]); - CreateTask_RfuReconnectWithParent(data->field_0->arr[data->leaderId].gname_uname.playerName, ReadAsU16(data->field_0->arr[data->leaderId].gname_uname.gname.unk_00.playerTrainerId)); + CopyAndTranslatePlayerName(gStringVar1, &data->playerList->players[data->leaderId]); + CreateTask_RfuReconnectWithParent(data->playerList->players[data->leaderId].rfu.name, ReadAsU16(data->playerList->players[data->leaderId].rfu.data.compatibility.playerTrainerId)); PlaySE(SE_POKENAV_ON); data->state = 4; } @@ -2148,13 +2173,13 @@ static void Task_CardOrNewsWithFriend(u8 taskId) break; case 4: AddTextPrinterToWindow1(sText_AwaitingPlayersResponse); - IntlConvPartnerUname7(gStringVar1, &data->field_0->arr[data->leaderId]); + CopyAndTranslatePlayerName(gStringVar1, &data->playerList->players[data->leaderId]); data->state = 5; break; case 5: if (gReceivedRemoteLinkPlayers) { - gPlayerCurrActivity = data->field_0->arr[data->leaderId].gname_uname.gname.activity; + gPlayerCurrActivity = data->playerList->players[data->leaderId].rfu.data.activity; data->state = 10; } @@ -2179,8 +2204,8 @@ static void Task_CardOrNewsWithFriend(u8 taskId) RemoveWindow(data->playerNameAndIdWindowId); RemoveWindow(data->listWindowId); DestroyTask(data->listenTaskId); - Free(data->field_0); - Free(data->field_4); + Free(data->playerList); + Free(data->incomingPlayerList); data->state++; break; case 9: @@ -2221,7 +2246,7 @@ void MEvent_CreateTask_CardOrNewsOverWireless(u32 activity) data->state = 0; data->textState = 0; - data->isWonderNews = activity - ACTIVITY_WONDER_CARD2; + data->isWonderNews = activity - ACTIVITY_WONDER_CARD; gSpecialVar_Result = LINKUP_ONGOING; } @@ -2234,12 +2259,12 @@ static void Task_CardOrNewsOverWireless(u8 taskId) switch (data->state) { case 0: - SetHostRFUtgtGname(0, 0, 0); + SetHostRfuGameData(ACTIVITY_NONE, 0, FALSE); SetWirelessCommType1(); OpenLink(); InitializeRfuLinkManager_JoinGroup(); - data->field_4 = AllocZeroed(4 * sizeof(struct UnkStruct_x1C)); - data->field_0 = AllocZeroed(16 * sizeof(struct UnkStruct_x20)); + data->incomingPlayerList = AllocZeroed(RFU_CHILD_MAX * sizeof(struct RfuIncomingPlayer)); + data->playerList = AllocZeroed(MAX_RFU_PLAYER_LIST_SIZE * sizeof(struct RfuPlayer)); data->state = 1; break; case 1: @@ -2247,13 +2272,13 @@ static void Task_CardOrNewsOverWireless(u8 taskId) data->state = 2; break; case 2: - ClearUnkStruct_x1CArray(data->field_4, 4); - ClearUnkStruct_x20Array(data->field_0->arr, 16); - data->listenTaskId = CreateTask_ListenForPartnersWithSerial7F7D(data->field_4, data->isWonderNews + LINK_GROUP_WONDER_CARD); + ClearIncomingPlayerList(data->incomingPlayerList, RFU_CHILD_MAX); + ClearRfuPlayerList(data->playerList->players, MAX_RFU_PLAYER_LIST_SIZE); + data->listenTaskId = CreateTask_ListenForWonderDistributor(data->incomingPlayerList, data->isWonderNews + LINK_GROUP_WONDER_CARD); - if (data->field_13 != 0) + if (data->showListMenu) { - winTemplate = gUnknown_082F0174; + winTemplate = sWindowTemplate_GroupList; winTemplate.baseBlock = GetMysteryGiftBaseBlock(); data->listWindowId = AddWindow(&winTemplate); @@ -2275,23 +2300,23 @@ static void Task_CardOrNewsOverWireless(u8 taskId) case 1: PlaySE(SE_PC_LOGIN); default: - if (data->field_13 != 0) + if (data->showListMenu) RedrawListMenu(data->listTaskId); break; case 0: - if (data->field_13 != 0) + if (data->showListMenu) id = ListMenu_ProcessInput(data->listTaskId); if (data->refreshTimer > 120) { - if (data->field_0->arr[0].groupScheduledAnim == UNION_ROOM_SPAWN_IN && !data->field_0->arr[0].gname_uname.gname.started) + if (data->playerList->players[0].groupScheduledAnim == UNION_ROOM_SPAWN_IN && !data->playerList->players[0].rfu.data.startedActivity) { - if (HasWonderCardOrNewsByLinkGroup(&data->field_0->arr[0].gname_uname.gname, data->isWonderNews + LINK_GROUP_WONDER_CARD)) + if (HasWonderCardOrNewsByLinkGroup(&data->playerList->players[0].rfu.data, data->isWonderNews + LINK_GROUP_WONDER_CARD)) { data->leaderId = 0; data->refreshTimer = 0; LoadWirelessStatusIndicatorSpriteGfx(); CreateWirelessStatusIndicatorSprite(0, 0); - CreateTask_RfuReconnectWithParent(data->field_0->arr[0].gname_uname.playerName, ReadAsU16(data->field_0->arr[0].gname_uname.gname.unk_00.playerTrainerId)); + CreateTask_RfuReconnectWithParent(data->playerList->players[0].rfu.name, ReadAsU16(data->playerList->players[0].rfu.data.compatibility.playerTrainerId)); PlaySE(SE_POKENAV_ON); data->state = 4; } @@ -2313,13 +2338,13 @@ static void Task_CardOrNewsOverWireless(u8 taskId) break; case 4: AddTextPrinterToWindow1(sText_AwaitingResponseFromWirelessSystem); - IntlConvPartnerUname7(gStringVar1, &data->field_0->arr[data->leaderId]); + CopyAndTranslatePlayerName(gStringVar1, &data->playerList->players[data->leaderId]); data->state = 5; break; case 5: if (gReceivedRemoteLinkPlayers) { - gPlayerCurrActivity = data->field_0->arr[data->leaderId].gname_uname.gname.activity; + gPlayerCurrActivity = data->playerList->players[data->leaderId].rfu.data.activity; data->state = 12; } @@ -2340,15 +2365,15 @@ static void Task_CardOrNewsOverWireless(u8 taskId) case 8: case 10: case 12: - if (data->field_13 != 0) + if (data->showListMenu) { DestroyListMenuTask(data->listTaskId, 0, 0); CopyBgTilemapBufferToVram(0); RemoveWindow(data->listWindowId); } DestroyTask(data->listenTaskId); - Free(data->field_0); - Free(data->field_4); + Free(data->playerList); + Free(data->incomingPlayerList); data->state++; break; case 9: @@ -2393,7 +2418,7 @@ void RunUnionRoom(void) { struct WirelessLink_URoom *uroom; - ClearAndInitHostRFUtgtGname(); + ResetHostRfuGameData(); CreateTask(Task_RunUnionRoom, 10); // dumb line needed to match @@ -2406,7 +2431,7 @@ void RunUnionRoom(void) uroom->state = UR_STATE_INIT; uroom->textState = 0; uroom->unknown = 0; - uroom->field_12 = 0; + uroom->unreadPlayerId = 0; gSpecialVar_Result = 0; ListMenuLoadStdPalAt(0xD0, 1); @@ -2436,14 +2461,18 @@ static void ScheduleFieldMessageAndExit(const u8 *src) StringExpandPlaceholders(gStringVar4, src); } -static void sub_80156B0(struct WirelessLink_URoom *uroom) +static void CopyPlayerListToBuffer(struct WirelessLink_URoom *uroom) { - memcpy(&gDecompressionBuffer[0x3F00], uroom->field_0, 0x100); + memcpy(&gDecompressionBuffer[sizeof(gDecompressionBuffer) - (MAX_UNION_ROOM_LEADERS * sizeof(struct RfuPlayer))], + uroom->playerList, + MAX_UNION_ROOM_LEADERS * sizeof(struct RfuPlayer)); } -static void sub_80156C8(struct WirelessLink_URoom *uroom) +static void CopyPlayerListFromBuffer(struct WirelessLink_URoom *uroom) { - memcpy(uroom->field_0, &gDecompressionBuffer[0x3F00], 0x100); + memcpy(uroom->playerList, + &gDecompressionBuffer[sizeof(gDecompressionBuffer) - (MAX_UNION_ROOM_LEADERS * sizeof(struct RfuPlayer))], + MAX_UNION_ROOM_LEADERS * sizeof(struct RfuPlayer)); } static void Task_RunUnionRoom(u8 taskId) @@ -2457,31 +2486,31 @@ static void Task_RunUnionRoom(u8 taskId) switch (uroom->state) { case UR_STATE_INIT: - uroom->field_4 = AllocZeroed(RFU_CHILD_MAX * sizeof(struct UnkStruct_x1C)); - uroom->field_C = AllocZeroed(RFU_CHILD_MAX * sizeof(struct UnkStruct_x1C)); - uroom->field_0 = AllocZeroed(8 * sizeof(struct UnkStruct_x20)); - uroom->field_8 = AllocZeroed(sizeof(struct UnkStruct_x20)); - ClearUnkStruct_x20Array(uroom->field_0->arr, ARRAY_COUNT(uroom->field_0->arr)); + uroom->incomingChildList = AllocZeroed(RFU_CHILD_MAX * sizeof(struct RfuIncomingPlayer)); + uroom->incomingParentList = AllocZeroed(RFU_CHILD_MAX * sizeof(struct RfuIncomingPlayer)); + uroom->playerList = AllocZeroed(MAX_UNION_ROOM_LEADERS * sizeof(struct RfuPlayer)); + uroom->spawnPlayer = AllocZeroed(sizeof(struct RfuPlayer)); + ClearRfuPlayerList(uroom->playerList->players, MAX_UNION_ROOM_LEADERS); gPlayerCurrActivity = IN_UNION_ROOM; - uroom->searchTaskId = CreateTask_SearchForChildOrParent(uroom->field_C, uroom->field_4, LINK_GROUP_UNION_ROOM_RESUME); + uroom->searchTaskId = CreateTask_SearchForChildOrParent(uroom->incomingParentList, uroom->incomingChildList, LINK_GROUP_UNION_ROOM_RESUME); InitUnionRoomPlayerObjects(uroom->objects); SetTilesAroundUnionRoomPlayersPassable(); uroom->state = UR_STATE_INIT_OBJECTS; break; case UR_STATE_INIT_OBJECTS: - CreateGroupMemberSpritesInvisible(uroom->spriteIds, taskData[0]); + CreateUnionRoomPlayerSprites(uroom->spriteIds, taskData[0]); if (++taskData[0] == 8) uroom->state = UR_STATE_INIT_LINK; break; case UR_STATE_INIT_LINK: - SetHostRFUtgtGname(IN_UNION_ROOM, 0, 0); + SetHostRfuGameData(IN_UNION_ROOM, 0, FALSE); SetTradeBoardRegisteredMonInfo(sUnionRoomTrade.type, sUnionRoomTrade.playerSpecies, sUnionRoomTrade.playerLevel); SetWirelessCommType1(); OpenLink(); InitializeRfuLinkManager_EnterUnionRoom(); - ClearUnkStruct_x20Array(&uroom->field_8->arr[0], 1); - ClearUnkStruct_x1CArray(uroom->field_4, 4); - ClearUnkStruct_x1CArray(uroom->field_C, 4); + ClearRfuPlayerList(&uroom->spawnPlayer->players[0], 1); + ClearIncomingPlayerList(uroom->incomingChildList, RFU_CHILD_MAX); + ClearIncomingPlayerList(uroom->incomingParentList, RFU_CHILD_MAX); gSpecialVar_Result = 0; uroom->state = UR_STATE_CHECK_SELECTING_MON; break; @@ -2511,7 +2540,7 @@ static void Task_RunUnionRoom(u8 taskId) } break; case URTRADE_STATE_OFFERING: - sub_80156C8(uroom); + CopyPlayerListFromBuffer(uroom); taskData[1] = sUnionRoomTrade.offerPlayerId; if (id >= PARTY_SIZE) { @@ -2562,10 +2591,10 @@ static void Task_RunUnionRoom(u8 taskId) { if (JOY_NEW(A_BUTTON)) { - if (TryInteractWithUnionRoomMember(uroom->field_0, &taskData[0], &taskData[1], uroom->spriteIds)) + if (TryInteractWithUnionRoomMember(uroom->playerList, &taskData[0], &taskData[1], uroom->spriteIds)) { PlaySE(SE_SELECT); - UR_EnableScriptContext2AndFreezeObjectEvents(); + StartScriptInteraction(); uroom->state = UR_STATE_INTERACT_WITH_PLAYER; break; } @@ -2573,7 +2602,7 @@ static void Task_RunUnionRoom(u8 taskId) { UpdateGameData_SetActivity(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); PlaySE(SE_PC_LOGIN); - UR_EnableScriptContext2AndFreezeObjectEvents(); + StartScriptInteraction(); StringCopy(gStringVar1, gSaveBlock2Ptr->playerName); uroom->state = UR_STATE_CHECK_TRADING_BOARD; break; @@ -2582,16 +2611,16 @@ static void Task_RunUnionRoom(u8 taskId) switch (HandlePlayerListUpdate()) { - case 1: + case PLIST_NEW_PLAYER: PlaySE(SE_PC_LOGIN); - case 2: + case PLIST_RECENT_UPDATE: ScheduleUnionRoomPlayerRefresh(uroom); break; - case 4: + case PLIST_CONTACTED: uroom->state = UR_STATE_PLAYER_CONTACTED_YOU; - UR_EnableScriptContext2AndFreezeObjectEvents(); + StartScriptInteraction(); SetTradeBoardRegisteredMonInfo(TYPE_NORMAL, SPECIES_NONE, 0); - UpdateGameData_SetActivity(ACTIVITY_NPCTALK | IN_UNION_ROOM, GetActivePartnerSpriteGenderParam(uroom), FALSE); + UpdateGameData_SetActivity(ACTIVITY_NPCTALK | IN_UNION_ROOM, GetActivePartnersInfo(uroom), FALSE); break; } HandleUnionRoomPlayerRefresh(uroom); @@ -2605,17 +2634,17 @@ static void Task_RunUnionRoom(u8 taskId) } break; case UR_STATE_INTERACT_WITH_PLAYER: - UR_RunTextPrinters_CheckPrinter0Active(); - playerGender = GetUnionRoomPlayerGender(taskData[1], uroom->field_0); + UR_RunTextPrinters(); + playerGender = GetUnionRoomPlayerGender(taskData[1], uroom->playerList); UpdateGameData_SetActivity(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); - switch (UnionRoomGetPlayerInteractionResponse(uroom->field_0, taskData[0], taskData[1], playerGender)) + switch (UnionRoomGetPlayerInteractionResponse(uroom->playerList, taskData[0], taskData[1], playerGender)) { case 0: // Player is or was just doing an activity uroom->state = UR_STATE_PRINT_AND_EXIT; break; case 1: // Link communicating - sub_8012188(uroom->field_0->arr[taskData[1]].gname_uname.playerName, &uroom->field_0->arr[taskData[1]].gname_uname.gname, gPlayerCurrActivity); - uroom->field_12 = id; // Should be just 0, but won't match any other way. + TryConnectToUnionRoomParent(uroom->playerList->players[taskData[1]].rfu.name, &uroom->playerList->players[taskData[1]].rfu.data, gPlayerCurrActivity); + uroom->unreadPlayerId = id; // Should be just 0, but won't match any other way. uroom->state = UR_STATE_TRY_COMMUNICATING; break; case 2: // Ask to join chat @@ -2624,7 +2653,7 @@ static void Task_RunUnionRoom(u8 taskId) } break; case UR_STATE_TRY_COMMUNICATING: - UR_RunTextPrinters_CheckPrinter0Active(); + UR_RunTextPrinters(); switch (RfuGetStatus()) { case RFU_STATUS_NEW_CHILD_DETECTED: @@ -2662,13 +2691,13 @@ static void Task_RunUnionRoom(u8 taskId) if (!gReceivedRemoteLinkPlayers) { HandleCancelActivity(FALSE); - UpdateUnionRoomMemberFacing(taskData[0], taskData[1], uroom->field_0); + UpdateUnionRoomMemberFacing(taskData[0], taskData[1], uroom->playerList); uroom->state = UR_STATE_INIT_LINK; } break; case UR_STATE_DO_SOMETHING_PROMPT: - id = ConvPartnerUnameAndGetWhetherMetAlready(&uroom->field_0->arr[taskData[1]]); - playerGender = GetUnionRoomPlayerGender(taskData[1], uroom->field_0); + id = ConvPartnerUnameAndGetWhetherMetAlready(&uroom->playerList->players[taskData[1]]); + playerGender = GetUnionRoomPlayerGender(taskData[1], uroom->playerList); ScheduleFieldMessageWithFollowupState(UR_STATE_HANDLE_DO_SOMETHING_PROMPT_INPUT, sHiDoSomethingTexts[id][playerGender]); break; case UR_STATE_HANDLE_DO_SOMETHING_PROMPT_INPUT: @@ -2686,7 +2715,7 @@ static void Task_RunUnionRoom(u8 taskId) else { uroom->partnerYesNoResponse = 0; - playerGender = GetUnionRoomPlayerGender(taskData[1], uroom->field_0); + playerGender = GetUnionRoomPlayerGender(taskData[1], uroom->playerList); if (input == -2 || input == IN_UNION_ROOM) { uroom->playerSendBuffer[0] = IN_UNION_ROOM; @@ -2697,7 +2726,7 @@ static void Task_RunUnionRoom(u8 taskId) else { gPlayerCurrActivity = input; - sPlayerActivityGroupSize = (u32)(input) >> 8; + sPlayerActivityGroupSize = (u32)input >> 8; // Extract capacity from sInviteToActivityMenuItems if (gPlayerCurrActivity == (ACTIVITY_BATTLE_SINGLE | IN_UNION_ROOM) && !HasAtLeastTwoMonsOfLevel30OrLower()) { ScheduleFieldMessageWithFollowupState(UR_STATE_DO_SOMETHING_PROMPT, sText_NeedTwoMonsOfLevel30OrLower1); @@ -2718,7 +2747,7 @@ static void Task_RunUnionRoom(u8 taskId) break; case UR_STATE_SEND_ACTIVITY_REQUEST: PollPartnerYesNoResponse(uroom); - playerGender = GetUnionRoomPlayerGender(taskData[1], uroom->field_0); + playerGender = GetUnionRoomPlayerGender(taskData[1], uroom->playerList); id = GetResponseIdx_InviteToURoomActivity(uroom->playerSendBuffer[0] & 0x3F); if (PrintOnTextbox(&uroom->textState, sText_WaitOrShowCardTexts[playerGender][id])) { @@ -2768,8 +2797,8 @@ static void Task_RunUnionRoom(u8 taskId) break; case UR_STATE_DO_SOMETHING_PROMPT_2: // Identical to UR_STATE_DO_SOMETHING_PROMPT - id = ConvPartnerUnameAndGetWhetherMetAlready(&uroom->field_0->arr[taskData[1]]); - playerGender = GetUnionRoomPlayerGender(taskData[1], uroom->field_0); + id = ConvPartnerUnameAndGetWhetherMetAlready(&uroom->playerList->players[taskData[1]]); + playerGender = GetUnionRoomPlayerGender(taskData[1], uroom->playerList); ScheduleFieldMessageWithFollowupState(UR_STATE_HANDLE_DO_SOMETHING_PROMPT_INPUT, sHiDoSomethingTexts[id][playerGender]); break; case UR_STATE_PRINT_CARD_INFO: @@ -2804,14 +2833,14 @@ static void Task_RunUnionRoom(u8 taskId) CopyBgTilemapBufferToVram(0); gPlayerCurrActivity = ACTIVITY_CHAT | IN_UNION_ROOM; UpdateGameData_SetActivity(ACTIVITY_CHAT | IN_UNION_ROOM, 0, TRUE); - sub_8012188(uroom->field_0->arr[taskData[1]].gname_uname.playerName, &uroom->field_0->arr[taskData[1]].gname_uname.gname, gPlayerCurrActivity); - uroom->field_12 = taskData[1]; + TryConnectToUnionRoomParent(uroom->playerList->players[taskData[1]].rfu.name, &uroom->playerList->players[taskData[1]].rfu.data, gPlayerCurrActivity); + uroom->unreadPlayerId = taskData[1]; uroom->state = UR_STATE_TRY_ACCEPT_CHAT_REQUEST_DELAY; taskData[3] = 0; break; case 1: // NO - case -1: - playerGender = GetUnionRoomPlayerGender(taskData[1], uroom->field_0); + case MENU_B_PRESSED: + playerGender = GetUnionRoomPlayerGender(taskData[1], uroom->playerList); ScheduleFieldMessageAndExit(sDeclineChatTexts[playerGender]); break; } @@ -2832,7 +2861,7 @@ static void Task_RunUnionRoom(u8 taskId) break; case RFU_STATUS_FATAL_ERROR: case RFU_STATUS_CONNECTION_ERROR: - playerGender = GetUnionRoomPlayerGender(taskData[1], uroom->field_0); + playerGender = GetUnionRoomPlayerGender(taskData[1], uroom->playerList); UpdateGameData_SetActivity(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); if (IsUnionRoomListenTaskActive() == TRUE) ScheduleFieldMessageAndExit(sChatDeclinedTexts[playerGender]); @@ -2848,7 +2877,7 @@ static void Task_RunUnionRoom(u8 taskId) case UR_STATE_ACCEPT_CHAT_REQUEST: if (RfuHasErrored()) { - playerGender = GetUnionRoomPlayerGender(taskData[1], uroom->field_0); + playerGender = GetUnionRoomPlayerGender(taskData[1], uroom->playerList); UpdateGameData_SetActivity(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); if (IsUnionRoomListenTaskActive() == TRUE) ScheduleFieldMessageAndExit(sChatDeclinedTexts[playerGender]); @@ -2860,7 +2889,7 @@ static void Task_RunUnionRoom(u8 taskId) break; case UR_STATE_PLAYER_CONTACTED_YOU: PlaySE(SE_DING_DONG); - sub_800EF7C(); + StopUnionRoomLinkManager(); uroom->state = UR_STATE_RECV_CONTACT_DATA; uroom->recvActivityRequest[0] = 0; break; @@ -2894,9 +2923,9 @@ static void Task_RunUnionRoom(u8 taskId) break; case UR_STATE_HANDLE_CONTACT_DATA: ReceiveUnionRoomActivityPacket(uroom); - if (UnionRoom_HandleContactFromOtherPlayer(uroom) && JOY_NEW(B_BUTTON)) + if (HandleContactFromOtherPlayer(uroom) && JOY_NEW(B_BUTTON)) { - sub_8011DE0(1); + Rfu_DisconnectPlayerById(1); StringCopy(gStringVar4, sText_ChatEnded); uroom->state = UR_STATE_CANCEL_REQUEST_PRINT_MSG; } @@ -2910,11 +2939,11 @@ static void Task_RunUnionRoom(u8 taskId) case 0: // ACCEPT uroom->playerSendBuffer[0] = ACTIVITY_ACCEPT | IN_UNION_ROOM; if (gPlayerCurrActivity == (ACTIVITY_CHAT | IN_UNION_ROOM)) - UpdateGameData_SetActivity(gPlayerCurrActivity | IN_UNION_ROOM, sub_801100C(1), FALSE); + UpdateGameData_SetActivity(gPlayerCurrActivity | IN_UNION_ROOM, GetLinkPlayerInfoFlags(1), FALSE); else - UpdateGameData_SetActivity(gPlayerCurrActivity | IN_UNION_ROOM, sub_801100C(1), TRUE); + UpdateGameData_SetActivity(gPlayerCurrActivity | IN_UNION_ROOM, GetLinkPlayerInfoFlags(1), TRUE); - uroom->field_8->arr[0].field_1B = 0; + uroom->spawnPlayer->players[0].newPlayerCountdown = 0; taskData[3] = 0; if (gPlayerCurrActivity == (ACTIVITY_BATTLE_SINGLE | IN_UNION_ROOM)) { @@ -2944,7 +2973,7 @@ static void Task_RunUnionRoom(u8 taskId) } break; case 1: // DECLINE - case -1: + case MENU_B_PRESSED: uroom->playerSendBuffer[0] = ACTIVITY_DECLINE | IN_UNION_ROOM; Rfu_SendPacket(uroom->playerSendBuffer); uroom->state = UR_STATE_DECLINE_ACTIVITY_REQUEST; @@ -2983,16 +3012,16 @@ static void Task_RunUnionRoom(u8 taskId) uroom->state = UR_STATE_START_ACTIVITY_FREE_UROOM; break; case UR_STATE_START_ACTIVITY_FREE_UROOM: - Free(uroom->field_8); - Free(uroom->field_0); - Free(uroom->field_C); - Free(uroom->field_4); + Free(uroom->spawnPlayer); + Free(uroom->playerList); + Free(uroom->incomingParentList); + Free(uroom->incomingChildList); DestroyTask(uroom->searchTaskId); - DestroyGroupMemberSprites(uroom->spriteIds); + DestroyUnionRoomPlayerSprites(uroom->spriteIds); uroom->state = UR_STATE_START_ACTIVITY_FADE; break; case UR_STATE_START_ACTIVITY_FADE: - BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 0x10, RGB_BLACK); + BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK); uroom->state = UR_STATE_START_ACTIVITY; break; case UR_STATE_START_ACTIVITY: @@ -3005,20 +3034,20 @@ static void Task_RunUnionRoom(u8 taskId) } break; case UR_STATE_INTERACT_WITH_ATTENDANT: - if (GetHostRFUtgtGname()->species == SPECIES_NONE) + if (GetHostRfuGameData()->tradeSpecies == SPECIES_NONE) { uroom->state = UR_STATE_REGISTER_PROMPT; } else { - if (GetHostRFUtgtGname()->species == SPECIES_EGG) + if (GetHostRfuGameData()->tradeSpecies == SPECIES_EGG) { StringCopy(gStringVar4, sText_CancelRegistrationOfEgg); } else { - StringCopy(gStringVar1, gSpeciesNames[GetHostRFUtgtGname()->species]); - ConvertIntToDecimalStringN(gStringVar2, GetHostRFUtgtGname()->level, STR_CONV_MODE_LEFT_ALIGN, 3); + StringCopy(gStringVar1, gSpeciesNames[GetHostRfuGameData()->tradeSpecies]); + ConvertIntToDecimalStringN(gStringVar2, GetHostRfuGameData()->tradeLevel, STR_CONV_MODE_LEFT_ALIGN, 3); StringExpandPlaceholders(gStringVar4, sText_CancelRegistrationOfMon); } ScheduleFieldMessageWithFollowupState(UR_STATE_CANCEL_REGISTRATION_PROMPT, gStringVar4); @@ -3030,8 +3059,8 @@ static void Task_RunUnionRoom(u8 taskId) break; case UR_STATE_REGISTER_PROMPT_HANDLE_INPUT: input = ListMenuHandler_AllItemsAvailable(&uroom->textState, - &uroom->tradeBoardSelectWindowId, - &uroom->tradeBoardDetailsWindowId, + &uroom->tradeBoardMainWindowId, + &uroom->tradeBoardHeaderWindowId, &sWindowTemplate_RegisterForTrade, &sListMenuTemplate_RegisterForTrade); if (input != -1) @@ -3069,9 +3098,9 @@ static void Task_RunUnionRoom(u8 taskId) break; case UR_STATE_REGISTER_REQUEST_TYPE: input = ListMenuHandler_AllItemsAvailable(&uroom->textState, - &uroom->tradeBoardSelectWindowId, - &uroom->tradeBoardDetailsWindowId, - &gUnknown_082F0294, + &uroom->tradeBoardMainWindowId, + &uroom->tradeBoardHeaderWindowId, + &sWindowTemplate_TradingBoardRequestType, &sMenuTemplate_TradingBoardRequestType); if (input != -1) { @@ -3101,7 +3130,7 @@ static void Task_RunUnionRoom(u8 taskId) uroom->state = UR_STATE_CANCEL_REGISTRATION; break; case 1: // NO - case -1: + case MENU_B_PRESSED: HandleCancelActivity(TRUE); uroom->state = UR_STATE_MAIN; break; @@ -3125,7 +3154,13 @@ static void Task_RunUnionRoom(u8 taskId) uroom->state = UR_STATE_TRADING_BOARD_HANDLE_INPUT; break; case UR_STATE_TRADING_BOARD_HANDLE_INPUT: - input = TradeBoardMenuHandler(&uroom->textState, &uroom->tradeBoardSelectWindowId, &uroom->tradeBoardListMenuId, &uroom->tradeBoardDetailsWindowId, &gUnknown_082F034C, &sTradeBoardListMenuTemplate, uroom->field_0); + input = TradeBoardMenuHandler(&uroom->textState, + &uroom->tradeBoardMainWindowId, + &uroom->tradeBoardListMenuId, + &uroom->tradeBoardHeaderWindowId, + &sWindowTemplate_TradingBoardMain, + &sTradeBoardListMenuTemplate, + uroom->playerList); if (input != -1) { switch (input) @@ -3137,21 +3172,21 @@ static void Task_RunUnionRoom(u8 taskId) break; default: UR_ClearBg0(); - switch (IsRequestedTypeOrEggInPlayerParty(uroom->field_0->arr[input].gname_uname.gname.type, uroom->field_0->arr[input].gname_uname.gname.species)) + switch (IsRequestedTypeOrEggInPlayerParty(uroom->playerList->players[input].rfu.data.tradeType, uroom->playerList->players[input].rfu.data.tradeSpecies)) { case UR_TRADE_MATCH: - IntlConvPartnerUname7(gStringVar1, &uroom->field_0->arr[input]); + CopyAndTranslatePlayerName(gStringVar1, &uroom->playerList->players[input]); ScheduleFieldMessageWithFollowupState(UR_STATE_TRADE_PROMPT, sText_AskTrainerToMakeTrade); taskData[1] = input; break; case UR_TRADE_NOTYPE: - IntlConvPartnerUname7(gStringVar1, &uroom->field_0->arr[input]); - StringCopy(gStringVar2, gTypeNames[uroom->field_0->arr[input].gname_uname.gname.type]); + CopyAndTranslatePlayerName(gStringVar1, &uroom->playerList->players[input]); + StringCopy(gStringVar2, gTypeNames[uroom->playerList->players[input].rfu.data.tradeType]); ScheduleFieldMessageWithFollowupState(UR_STATE_TRADING_BOARD_LOAD, sText_DontHaveTypeTrainerWants); break; case UR_TRADE_NOEGG: - IntlConvPartnerUname7(gStringVar1, &uroom->field_0->arr[input]); - StringCopy(gStringVar2, gTypeNames[uroom->field_0->arr[input].gname_uname.gname.type]); + CopyAndTranslatePlayerName(gStringVar1, &uroom->playerList->players[input]); + StringCopy(gStringVar2, gTypeNames[uroom->playerList->players[input].rfu.data.tradeType]); ScheduleFieldMessageWithFollowupState(UR_STATE_TRADING_BOARD_LOAD, sText_DontHaveEggTrainerWants); break; } @@ -3165,8 +3200,8 @@ static void Task_RunUnionRoom(u8 taskId) case 0: // YES uroom->state = UR_STATE_TRADE_SELECT_MON; break; - case -1: // NO - case 1: + case MENU_B_PRESSED: + case 1: // NO HandleCancelActivity(TRUE); uroom->state = UR_STATE_MAIN; break; @@ -3176,19 +3211,19 @@ static void Task_RunUnionRoom(u8 taskId) if (PrintOnTextbox(&uroom->textState, sText_WhichMonWillYouOffer)) { sUnionRoomTrade.state = URTRADE_STATE_OFFERING; - memcpy(&gPartnerTgtGnameSub, &uroom->field_0->arr[taskData[1]].gname_uname.gname.unk_00, sizeof(gPartnerTgtGnameSub)); - gUnionRoomRequestedMonType = uroom->field_0->arr[taskData[1]].gname_uname.gname.type; - gUnionRoomOfferedSpecies = uroom->field_0->arr[taskData[1]].gname_uname.gname.species; + memcpy(&gRfuPartnerCompatibilityData, &uroom->playerList->players[taskData[1]].rfu.data.compatibility, sizeof(gRfuPartnerCompatibilityData)); + gUnionRoomRequestedMonType = uroom->playerList->players[taskData[1]].rfu.data.tradeType; + gUnionRoomOfferedSpecies = uroom->playerList->players[taskData[1]].rfu.data.tradeSpecies; gFieldCallback = FieldCB_ContinueScriptUnionRoom; ChooseMonForTradingBoard(PARTY_MENU_TYPE_UNION_ROOM_TRADE, CB2_ReturnToField); - sub_80156B0(uroom); + CopyPlayerListToBuffer(uroom); sUnionRoomTrade.offerPlayerId = taskData[1]; } break; case UR_STATE_TRADE_OFFER_MON: gPlayerCurrActivity = ACTIVITY_TRADE | IN_UNION_ROOM; - sub_8012188(uroom->field_0->arr[taskData[1]].gname_uname.playerName, &uroom->field_0->arr[taskData[1]].gname_uname.gname, gPlayerCurrActivity); - IntlConvPartnerUname7(gStringVar1, &uroom->field_0->arr[taskData[1]]); + TryConnectToUnionRoomParent(uroom->playerList->players[taskData[1]].rfu.name, &uroom->playerList->players[taskData[1]].rfu.data, gPlayerCurrActivity); + CopyAndTranslatePlayerName(gStringVar1, &uroom->playerList->players[taskData[1]]); UR_PrintFieldMessage(sCommunicatingWaitTexts[2]); uroom->state = UR_STATE_TRY_COMMUNICATING; break; @@ -3196,7 +3231,7 @@ static void Task_RunUnionRoom(u8 taskId) if (PrintOnTextbox(&uroom->textState, gStringVar4)) { HandleCancelActivity(TRUE); - UpdateUnionRoomMemberFacing(taskData[0], taskData[1], uroom->field_0); + UpdateUnionRoomMemberFacing(taskData[0], taskData[1], uroom->playerList); uroom->state = UR_STATE_MAIN; } break; @@ -3215,7 +3250,7 @@ void SetUsingUnionRoomStartMenu(void) static void ReceiveUnionRoomActivityPacket(struct WirelessLink_URoom *data) { - if (gRecvCmds[1][1] != 0 && (gRecvCmds[1][0] & 0xFF00) == 0x2F00) + if (gRecvCmds[1][1] != 0 && (gRecvCmds[1][0] & RFUCMD_MASK) == RFUCMD_SEND_PACKET) { data->recvActivityRequest[0] = gRecvCmds[1][1]; if (gRecvCmds[1][1] == (ACTIVITY_TRADE | IN_UNION_ROOM)) @@ -3226,7 +3261,7 @@ static void ReceiveUnionRoomActivityPacket(struct WirelessLink_URoom *data) } } -static bool32 UnionRoom_HandleContactFromOtherPlayer(struct WirelessLink_URoom *uroom) +static bool32 HandleContactFromOtherPlayer(struct WirelessLink_URoom *uroom) { if (uroom->recvActivityRequest[0] != 0) { @@ -3264,7 +3299,7 @@ void InitUnionRoom(void) data->state = 0; data->textState = 0; data->unknown = 0; - data->field_12 = 0; + data->unreadPlayerId = 0; sUnionRoomPlayerName[0] = EOS; } @@ -3280,38 +3315,38 @@ static void Task_InitUnionRoom(u8 taskId) data->state = 1; break; case 1: - SetHostRFUtgtGname(ACTIVITY_SEARCH, 0, 0); + SetHostRfuGameData(ACTIVITY_SEARCH, 0, FALSE); SetWirelessCommType1(); OpenLink(); InitializeRfuLinkManager_EnterUnionRoom(); - sub_80111B0(TRUE); + RfuSetIgnoreError(TRUE); data->state = 2; break; case 2: - data->field_4 = AllocZeroed(4 * sizeof(struct UnkStruct_x1C)); - ClearUnkStruct_x1CArray(data->field_4, 4); - data->field_C = AllocZeroed(4 * sizeof(struct UnkStruct_x1C)); - ClearUnkStruct_x1CArray(data->field_C, 4); - data->field_0 = AllocZeroed(8 * sizeof(struct UnkStruct_x20)); - ClearUnkStruct_x20Array(data->field_0->arr, 8); - data->field_8 = AllocZeroed(sizeof(struct UnkStruct_x20)); - ClearUnkStruct_x20Array(&data->field_8->arr[0], 1); - data->searchTaskId = CreateTask_SearchForChildOrParent(data->field_C, data->field_4, 10); + data->incomingChildList = AllocZeroed(RFU_CHILD_MAX * sizeof(struct RfuIncomingPlayer)); + ClearIncomingPlayerList(data->incomingChildList, RFU_CHILD_MAX); + data->incomingParentList = AllocZeroed(RFU_CHILD_MAX * sizeof(struct RfuIncomingPlayer)); + ClearIncomingPlayerList(data->incomingParentList, RFU_CHILD_MAX); + data->playerList = AllocZeroed(MAX_UNION_ROOM_LEADERS * sizeof(struct RfuPlayer)); + ClearRfuPlayerList(data->playerList->players, MAX_UNION_ROOM_LEADERS); + data->spawnPlayer = AllocZeroed(sizeof(struct RfuPlayer)); + ClearRfuPlayerList(&data->spawnPlayer->players[0], 1); + data->searchTaskId = CreateTask_SearchForChildOrParent(data->incomingParentList, data->incomingChildList, LINK_GROUP_UNION_ROOM_INIT); data->state = 3; break; case 3: switch (HandlePlayerListUpdate()) { - case 1: - case 2: + case PLIST_NEW_PLAYER: + case PLIST_RECENT_UPDATE: if (sUnionRoomPlayerName[0] == EOS) { - for (i = 0; i < PLAYER_NAME_LENGTH + 1; i++) + for (i = 0; i < MAX_UNION_ROOM_LEADERS; i++) { - if (data->field_0->arr[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN) + if (data->playerList->players[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN) { - IntlConvPartnerUname7(text, &data->field_0->arr[i]); - if (PlayerHasMetTrainerBefore(ReadAsU16(data->field_0->arr[i].gname_uname.gname.unk_00.playerTrainerId), text)) + CopyAndTranslatePlayerName(text, &data->playerList->players[i]); + if (PlayerHasMetTrainerBefore(ReadAsU16(data->playerList->players[i].rfu.data.compatibility.playerTrainerId), text)) { StringCopy(sUnionRoomPlayerName, text); break; @@ -3320,15 +3355,15 @@ static void Task_InitUnionRoom(u8 taskId) } } break; - case 3: + case PLIST_UNUSED: break; } break; case 4: - free(data->field_8); - free(data->field_0); - free(data->field_C); - free(data->field_4); + free(data->spawnPlayer); + free(data->playerList); + free(data->incomingParentList); + free(data->incomingChildList); DestroyTask(data->searchTaskId); free(sWirelessLinkMain.uRoom); LinkRfu_Shutdown(); @@ -3356,160 +3391,150 @@ static u8 HandlePlayerListUpdate(void) s32 i; u8 j; struct WirelessLink_URoom *data = sWirelessLinkMain.uRoom; - s32 r7 = 0; + s32 retVal = PLIST_NONE; for (i = 0; i < RFU_CHILD_MAX; i++) { - if (AreGnameUnameDifferent(&data->field_C->arr[i].gname_uname, &sWirelessGnameUnamePair_Dummy) == TRUE) + if (ArePlayersDifferent(&data->incomingParentList->players[i].rfu, &sUnionRoomPlayer_DummyRfu) == TRUE) { - data->field_8->arr[0].gname_uname = data->field_C->arr[i].gname_uname; - data->field_8->arr[0].timeoutCounter = 0; - data->field_8->arr[0].groupScheduledAnim = UNION_ROOM_SPAWN_IN; - data->field_8->arr[0].field_1B = 1; - return 4; + data->spawnPlayer->players[0].rfu = data->incomingParentList->players[i].rfu; + data->spawnPlayer->players[0].timeoutCounter = 0; + data->spawnPlayer->players[0].groupScheduledAnim = UNION_ROOM_SPAWN_IN; + data->spawnPlayer->players[0].newPlayerCountdown = 1; + return PLIST_CONTACTED; } } - for (j = 0; j < ARRAY_COUNT(data->field_0->arr); j++) + for (j = 0; j < MAX_UNION_ROOM_LEADERS; j++) { - if (data->field_0->arr[j].groupScheduledAnim != UNION_ROOM_SPAWN_NONE) + if (data->playerList->players[j].groupScheduledAnim != UNION_ROOM_SPAWN_NONE) { - i = Findx20Inx1CArray(&data->field_0->arr[j], &data->field_4->arr[0]); + i = GetNewIncomingPlayerId(&data->playerList->players[j], &data->incomingChildList->players[0]); if (i != 0xFF) { - if (data->field_0->arr[j].groupScheduledAnim == UNION_ROOM_SPAWN_IN) + if (data->playerList->players[j].groupScheduledAnim == UNION_ROOM_SPAWN_IN) { - if (AreUnionRoomPlayerGnamesDifferent(&data->field_0->arr[j].gname_uname, &data->field_4->arr[i].gname_uname)) + if (ArePlayerDataDifferent(&data->playerList->players[j].rfu, &data->incomingChildList->players[i].rfu)) { - data->field_0->arr[j].gname_uname = data->field_4->arr[i].gname_uname; - data->field_0->arr[j].field_1B = 64; - r7 = 1; + data->playerList->players[j].rfu = data->incomingChildList->players[i].rfu; + data->playerList->players[j].newPlayerCountdown = 64; + retVal = PLIST_NEW_PLAYER; } - else if (data->field_0->arr[j].field_1B != 0) + else if (data->playerList->players[j].newPlayerCountdown != 0) { - data->field_0->arr[j].field_1B--; - if (data->field_0->arr[j].field_1B == 0) - r7 = 2; + data->playerList->players[j].newPlayerCountdown--; + if (data->playerList->players[j].newPlayerCountdown == 0) + retVal = PLIST_RECENT_UPDATE; } } else { - data->field_0->arr[j].groupScheduledAnim = UNION_ROOM_SPAWN_IN; - data->field_0->arr[j].field_1B = 0; - r7 = 2; + data->playerList->players[j].groupScheduledAnim = UNION_ROOM_SPAWN_IN; + data->playerList->players[j].newPlayerCountdown = 0; + retVal = PLIST_RECENT_UPDATE; } - data->field_0->arr[j].timeoutCounter = 0; + data->playerList->players[j].timeoutCounter = 0; } - else if (data->field_0->arr[j].groupScheduledAnim != UNION_ROOM_SPAWN_OUT) + else if (data->playerList->players[j].groupScheduledAnim != UNION_ROOM_SPAWN_OUT) { - data->field_0->arr[j].timeoutCounter++; - if (data->field_0->arr[j].timeoutCounter >= 600) + data->playerList->players[j].timeoutCounter++; + if (data->playerList->players[j].timeoutCounter >= 600) { - data->field_0->arr[j].groupScheduledAnim = UNION_ROOM_SPAWN_OUT; - r7 = 2; + data->playerList->players[j].groupScheduledAnim = UNION_ROOM_SPAWN_OUT; + retVal = PLIST_RECENT_UPDATE; } } - else if (data->field_0->arr[j].groupScheduledAnim == UNION_ROOM_SPAWN_OUT) + else if (data->playerList->players[j].groupScheduledAnim == UNION_ROOM_SPAWN_OUT) { - data->field_0->arr[j].timeoutCounter++; - if (data->field_0->arr[j].timeoutCounter >= 900) - { - ClearUnkStruct_x20Array(&data->field_0->arr[j], 1); - } + data->playerList->players[j].timeoutCounter++; + if (data->playerList->players[j].timeoutCounter >= 900) + ClearRfuPlayerList(&data->playerList->players[j], 1); } } } for (i = 0; i < RFU_CHILD_MAX; i++) - { - if (Appendx1Ctox20(&data->field_0->arr[0], &data->field_4->arr[i], MAX_UNION_ROOM_PLAYERS) != 0xFF) - r7 = 1; - } + if (TryAddIncomingPlayerToList(&data->playerList->players[0], &data->incomingChildList->players[i], MAX_UNION_ROOM_LEADERS) != 0xFF) + retVal = PLIST_NEW_PLAYER; - return r7; + return retVal; } static void Task_SearchForChildOrParent(u8 taskId) { s32 i, j; - struct WirelessGnameUnamePair gname_uname; - struct UnkStruct_Main4 **ptr = (void*) gTasks[taskId].data; + struct RfuPlayerData rfu; + struct RfuIncomingPlayerList **list = (void*) gTasks[taskId].data; bool8 isParent; for (i = 0; i < RFU_CHILD_MAX; i++) { - isParent = LinkRfu_GetNameIfCompatible(&gname_uname.gname, gname_uname.playerName, i); - if (!IsPartnerActivityAcceptable(gname_uname.gname.activity, gTasks[taskId].data[4])) - { - gname_uname = sWirelessGnameUnamePair_Dummy; - } - if (gname_uname.gname.unk_00.language == LANGUAGE_JAPANESE) - { - gname_uname = sWirelessGnameUnamePair_Dummy; - } + isParent = Rfu_GetCompatiblePlayerData(&rfu.data, rfu.name, i); + + if (!IsPartnerActivityAcceptable(rfu.data.activity, gTasks[taskId].data[4])) + rfu = sUnionRoomPlayer_DummyRfu; + if (rfu.data.compatibility.language == LANGUAGE_JAPANESE) + rfu = sUnionRoomPlayer_DummyRfu; + if (!isParent) { for (j = 0; j < i; j++) { - if (!AreGnameUnameDifferent(&ptr[1]->arr[j].gname_uname, &gname_uname)) - { - gname_uname = sWirelessGnameUnamePair_Dummy; - } + if (!ArePlayersDifferent(&list[1]->players[j].rfu, &rfu)) + rfu = sUnionRoomPlayer_DummyRfu; } - ptr[1]->arr[i].gname_uname = gname_uname; - ptr[1]->arr[i].active = AreGnameUnameDifferent(&ptr[1]->arr[i].gname_uname, &sWirelessGnameUnamePair_Dummy); + list[1]->players[i].rfu = rfu; + list[1]->players[i].active = ArePlayersDifferent(&list[1]->players[i].rfu, &sUnionRoomPlayer_DummyRfu); } else { - ptr[0]->arr[i].gname_uname = gname_uname; - ptr[0]->arr[i].active = AreGnameUnameDifferent(&ptr[0]->arr[i].gname_uname, &sWirelessGnameUnamePair_Dummy); + list[0]->players[i].rfu = rfu; + list[0]->players[i].active = ArePlayersDifferent(&list[0]->players[i].rfu, &sUnionRoomPlayer_DummyRfu); } } } -static u8 CreateTask_SearchForChildOrParent(struct UnkStruct_Main4 * main4_parent, struct UnkStruct_Main4 * main4_child, u32 linkGroup) +static u8 CreateTask_SearchForChildOrParent(struct RfuIncomingPlayerList * parentList, struct RfuIncomingPlayerList * childList, u32 linkGroup) { u8 taskId = CreateTask(Task_SearchForChildOrParent, 0); - struct UnkStruct_Main4 ** data = (void *)gTasks[taskId].data; - data[0] = main4_parent; - data[1] = main4_child; + struct RfuIncomingPlayerList ** data = (void *)gTasks[taskId].data; + data[0] = parentList; + data[1] = childList; gTasks[taskId].data[4] = linkGroup; return taskId; } -static void Task_ListenForPartnersWithCompatibleSerialNos(u8 taskId) +static void Task_ListenForCompatiblePartners(u8 taskId) { s32 i, j; - struct UnkStruct_Main4 **ptr = (void*) gTasks[taskId].data; + struct RfuIncomingPlayerList **list = (void*) gTasks[taskId].data; for (i = 0; i < RFU_CHILD_MAX; i++) { - LinkRfu_GetNameIfCompatible(&ptr[0]->arr[i].gname_uname.gname, ptr[0]->arr[i].gname_uname.playerName, i); - if (!IsPartnerActivityAcceptable(ptr[0]->arr[i].gname_uname.gname.activity, gTasks[taskId].data[2])) + Rfu_GetCompatiblePlayerData(&list[0]->players[i].rfu.data, list[0]->players[i].rfu.name, i); + if (!IsPartnerActivityAcceptable(list[0]->players[i].rfu.data.activity, gTasks[taskId].data[2])) { - ptr[0]->arr[i].gname_uname = sWirelessGnameUnamePair_Dummy; + list[0]->players[i].rfu = sUnionRoomPlayer_DummyRfu; } for (j = 0; j < i; j++) { - if (!AreGnameUnameDifferent(&ptr[0]->arr[j].gname_uname, &ptr[0]->arr[i].gname_uname)) - { - ptr[0]->arr[i].gname_uname = sWirelessGnameUnamePair_Dummy; - } + if (!ArePlayersDifferent(&list[0]->players[j].rfu, &list[0]->players[i].rfu)) + list[0]->players[i].rfu = sUnionRoomPlayer_DummyRfu; } - ptr[0]->arr[i].active = AreGnameUnameDifferent(&ptr[0]->arr[i].gname_uname, &sWirelessGnameUnamePair_Dummy); + list[0]->players[i].active = ArePlayersDifferent(&list[0]->players[i].rfu, &sUnionRoomPlayer_DummyRfu); } } -static bool32 HasWonderCardOrNewsByLinkGroup(struct GFtgtGname *gname, s16 linkGroup) +static bool32 HasWonderCardOrNewsByLinkGroup(struct RfuGameData *data, s16 linkGroup) { if (linkGroup == LINK_GROUP_WONDER_CARD) { - if (!gname->unk_00.hasCard) + if (!data->compatibility.hasCard) return FALSE; else return TRUE; } else if (linkGroup == LINK_GROUP_WONDER_NEWS) { - if (!gname->unk_00.hasNews) + if (!data->compatibility.hasNews) return FALSE; else return TRUE; @@ -3520,35 +3545,34 @@ static bool32 HasWonderCardOrNewsByLinkGroup(struct GFtgtGname *gname, s16 linkG } } -static void Task_ListenForPartnersWithSerial7F7D(u8 taskId) +static void Task_ListenForWonderDistributor(u8 taskId) { s32 i; - struct UnkStruct_Main4 **ptr = (void*) gTasks[taskId].data; + struct RfuIncomingPlayerList **list = (void*) gTasks[taskId].data; for (i = 0; i < RFU_CHILD_MAX; i++) { - if (LinkRfu_GetNameIfSerial7F7D(&ptr[0]->arr[i].gname_uname.gname, ptr[0]->arr[i].gname_uname.playerName, i)) - { - HasWonderCardOrNewsByLinkGroup(&ptr[0]->arr[i].gname_uname.gname, gTasks[taskId].data[2]); - } - ptr[0]->arr[i].active = AreGnameUnameDifferent(&ptr[0]->arr[i].gname_uname, &sWirelessGnameUnamePair_Dummy); + if (Rfu_GetWonderDistributorPlayerData(&list[0]->players[i].rfu.data, list[0]->players[i].rfu.name, i)) + HasWonderCardOrNewsByLinkGroup(&list[0]->players[i].rfu.data, gTasks[taskId].data[2]); + + list[0]->players[i].active = ArePlayersDifferent(&list[0]->players[i].rfu, &sUnionRoomPlayer_DummyRfu); } } -static u8 CreateTask_ListenForPartnersWithCompatibleSerialNos(struct UnkStruct_Main4 * main4, u32 linkGroup) +static u8 CreateTask_ListenForCompatiblePartners(struct RfuIncomingPlayerList * list, u32 linkGroup) { - u8 taskId = CreateTask(Task_ListenForPartnersWithCompatibleSerialNos, 0); - struct UnkStruct_Main4 **ptr = (void*) gTasks[taskId].data; - ptr[0] = main4; + u8 taskId = CreateTask(Task_ListenForCompatiblePartners, 0); + struct RfuIncomingPlayerList **oldList = (void*) gTasks[taskId].data; + oldList[0] = list; gTasks[taskId].data[2] = linkGroup; return taskId; } -static u8 CreateTask_ListenForPartnersWithSerial7F7D(struct UnkStruct_Main4 * main4, u32 linkGroup) +static u8 CreateTask_ListenForWonderDistributor(struct RfuIncomingPlayerList * list, u32 linkGroup) { - u8 taskId = CreateTask(Task_ListenForPartnersWithSerial7F7D, 0); - struct UnkStruct_Main4 **ptr = (void*) gTasks[taskId].data; - ptr[0] = main4; + u8 taskId = CreateTask(Task_ListenForWonderDistributor, 0); + struct RfuIncomingPlayerList **oldList = (void*) gTasks[taskId].data; + oldList[0] = list; gTasks[taskId].data[2] = linkGroup; return taskId; } @@ -3562,7 +3586,7 @@ static bool32 UR_PrintFieldMessage(const u8 *src) return FALSE; } -static bool32 UR_RunTextPrinters_CheckPrinter0Active(void) +static bool32 UR_RunTextPrinters(void) { if (!RunTextPrintersAndIsPrinter0Active()) return TRUE; @@ -3600,9 +3624,7 @@ static s8 UnionRoomHandleYesNo(u8 *state, bool32 noDraw) { case 0: if (noDraw) - { return -3; - } DisplayYesNoMenuDefaultYes(); (*state)++; break; @@ -3614,14 +3636,14 @@ static s8 UnionRoomHandleYesNo(u8 *state, bool32 noDraw) return -3; } input = Menu_ProcessInputNoWrapClearOnChoose(); - if (input == -1 || input == 0 || input == 1) + if (input == MENU_B_PRESSED || input == 0 || input == 1) { *state = 0; return input; } break; } - return -2; + return MENU_NOTHING_CHOSEN; } static u8 CreateTradeBoardWindow(const struct WindowTemplate * template) @@ -3629,7 +3651,7 @@ static u8 CreateTradeBoardWindow(const struct WindowTemplate * template) u8 windowId = AddWindow(template); DrawStdWindowFrame(windowId, FALSE); FillWindowPixelBuffer(windowId, PIXEL_FILL(15)); - UR_AddTextPrinterParameterized(windowId, 1, sText_NameWantedOfferLv, 8, 1, 6); + PrintUnionRoomText(windowId, 1, sText_NameWantedOfferLv, 8, 1, UR_COLOR_TRADE_BOARD_OTHER); CopyWindowToVram(windowId, 2); PutWindowTilemap(windowId); return windowId; @@ -3651,13 +3673,11 @@ static s32 ListMenuHandler_AllItemsAvailable(u8 *state, u8 *windowId, u8 *listMe winTemplateCopy = *winTemplate; maxWidth = Intl_GetListMenuWidth(menuTemplate); if (winTemplateCopy.width > maxWidth) - { winTemplateCopy.width = maxWidth; - } + if (winTemplateCopy.tilemapLeft + winTemplateCopy.width > 29) - { winTemplateCopy.tilemapLeft = max(29 - winTemplateCopy.width, 0); - } + *windowId = AddWindow(&winTemplateCopy); DrawStdWindowFrame(*windowId, FALSE); gMultiuseListMenuTemplate = *menuTemplate; @@ -3690,7 +3710,10 @@ static s32 ListMenuHandler_AllItemsAvailable(u8 *state, u8 *windowId, u8 *listMe return -1; } -static s32 TradeBoardMenuHandler(u8 *state, u8 *windowId, u8 *listMenuId, u8 *tradeBoardWindowId, const struct WindowTemplate *winTemplate, const struct ListMenuTemplate *menuTemplate, struct UnkStruct_Main0 *traders) +static s32 TradeBoardMenuHandler(u8 *state, u8 *mainWindowId, u8 *listMenuId, u8 *headerWindowId, + const struct WindowTemplate *winTemplate, + const struct ListMenuTemplate *menuTemplate, + struct RfuPlayerList *list) { s32 input; s32 idx; @@ -3698,16 +3721,16 @@ static s32 TradeBoardMenuHandler(u8 *state, u8 *windowId, u8 *listMenuId, u8 *tr switch (*state) { case 0: - *tradeBoardWindowId = CreateTradeBoardWindow(&sWindowTemplate_TradingBoard); - *windowId = AddWindow(winTemplate); - DrawStdWindowFrame(*windowId, FALSE); + *headerWindowId = CreateTradeBoardWindow(&sWindowTemplate_TradingBoardHeader); + *mainWindowId = AddWindow(winTemplate); + DrawStdWindowFrame(*mainWindowId, FALSE); gMultiuseListMenuTemplate = *menuTemplate; - gMultiuseListMenuTemplate.windowId = *windowId; + gMultiuseListMenuTemplate.windowId = *mainWindowId; *listMenuId = ListMenuInit(&gMultiuseListMenuTemplate, 0, 1); (*state)++; break; case 1: - CopyWindowToVram(*windowId, TRUE); + CopyWindowToVram(*mainWindowId, TRUE); (*state)++; break; case 2: @@ -3717,19 +3740,19 @@ static s32 TradeBoardMenuHandler(u8 *state, u8 *windowId, u8 *listMenuId, u8 *tr if (input == 8 || JOY_NEW(B_BUTTON)) { DestroyListMenuTask(*listMenuId, NULL, NULL); - RemoveWindow(*windowId); - DeleteTradeBoardWindow(*tradeBoardWindowId); + RemoveWindow(*mainWindowId); + DeleteTradeBoardWindow(*headerWindowId); *state = 0; return -2; } else { - idx = GetIndexOfNthTradeBoardOffer(traders->arr, input); + idx = GetIndexOfNthTradeBoardOffer(list->players, input); if (idx >= 0) { DestroyListMenuTask(*listMenuId, NULL, NULL); - RemoveWindow(*windowId); - DeleteTradeBoardWindow(*tradeBoardWindowId); + RemoveWindow(*mainWindowId); + DeleteTradeBoardWindow(*headerWindowId); *state = 0; return idx; } @@ -3756,7 +3779,7 @@ static void JoinGroup_EnableScriptContexts(void) EnableBothScriptContexts(); } -static void UR_AddTextPrinterParameterized(u8 windowId, u8 fontId, const u8 *str, u8 x, u8 y, u8 colorIdx) +static void PrintUnionRoomText(u8 windowId, u8 fontId, const u8 *str, u8 x, u8 y, u8 colorIdx) { struct TextPrinterTemplate printerTemplate; @@ -3772,49 +3795,49 @@ static void UR_AddTextPrinterParameterized(u8 windowId, u8 fontId, const u8 *str gTextFlags.useAlternateDownArrow = FALSE; switch (colorIdx) { - case UR_COLOR_DKE_WHT_LTE: + case UR_COLOR_DEFAULT: printerTemplate.letterSpacing = 0; printerTemplate.lineSpacing = 0; printerTemplate.fgColor = TEXT_COLOR_DARK_GRAY; printerTemplate.bgColor = TEXT_COLOR_WHITE; printerTemplate.shadowColor = TEXT_COLOR_LIGHT_GRAY; break; - case UR_COLOR_RED_WHT_LTR: + case UR_COLOR_RED: printerTemplate.letterSpacing = 0; printerTemplate.lineSpacing = 0; printerTemplate.fgColor = TEXT_COLOR_RED; printerTemplate.bgColor = TEXT_COLOR_WHITE; printerTemplate.shadowColor = TEXT_COLOR_LIGHT_RED; break; - case UR_COLOR_GRN_WHT_LTG: + case UR_COLOR_GREEN: printerTemplate.letterSpacing = 0; printerTemplate.lineSpacing = 0; printerTemplate.fgColor = TEXT_COLOR_GREEN; printerTemplate.bgColor = TEXT_COLOR_WHITE; printerTemplate.shadowColor = TEXT_COLOR_LIGHT_GREEN; break; - case UR_COLOR_WHT_WHT_LTE: + case UR_COLOR_WHITE: printerTemplate.letterSpacing = 0; printerTemplate.lineSpacing = 0; printerTemplate.fgColor = TEXT_COLOR_WHITE; printerTemplate.bgColor = TEXT_COLOR_WHITE; printerTemplate.shadowColor = TEXT_COLOR_LIGHT_GRAY; break; - case UR_COLOR_WHT_DKE_LTE: + case UR_COLOR_CANCEL: printerTemplate.letterSpacing = 0; printerTemplate.lineSpacing = 0; printerTemplate.fgColor = TEXT_COLOR_WHITE; printerTemplate.bgColor = TEXT_COLOR_DARK_GRAY; printerTemplate.shadowColor = TEXT_COLOR_LIGHT_GRAY; break; - case UR_COLOR_GRN_DN6_LTB: + case UR_COLOR_TRADE_BOARD_SELF: printerTemplate.letterSpacing = 0; printerTemplate.lineSpacing = 0; printerTemplate.fgColor = TEXT_COLOR_LIGHT_GREEN; printerTemplate.bgColor = TEXT_DYNAMIC_COLOR_6; printerTemplate.shadowColor = TEXT_COLOR_LIGHT_BLUE; break; - case UR_COLOR_DN5_DN6_LTB: + case UR_COLOR_TRADE_BOARD_OTHER: printerTemplate.letterSpacing = 0; printerTemplate.lineSpacing = 0; printerTemplate.fgColor = TEXT_DYNAMIC_COLOR_5; @@ -3823,124 +3846,111 @@ static void UR_AddTextPrinterParameterized(u8 windowId, u8 fontId, const u8 *str break; } - AddTextPrinter(&printerTemplate, 0xFF, NULL); + AddTextPrinter(&printerTemplate, TEXT_SPEED_FF, NULL); } -static void ClearUnkStruct_x20Array(struct UnkStruct_x20 *arr, u8 count) +static void ClearRfuPlayerList(struct RfuPlayer *players, u8 count) { s32 i; for (i = 0; i < count; i++) { - arr[i].gname_uname = sWirelessGnameUnamePair_Dummy; - arr[i].timeoutCounter = 255; - arr[i].groupScheduledAnim = UNION_ROOM_SPAWN_NONE; - arr[i].useRedText = FALSE; - arr[i].field_1B = 0; + players[i].rfu = sUnionRoomPlayer_DummyRfu; + players[i].timeoutCounter = 255; + players[i].groupScheduledAnim = UNION_ROOM_SPAWN_NONE; + players[i].useRedText = FALSE; + players[i].newPlayerCountdown = 0; } } -static void ClearUnkStruct_x1CArray(struct UnkStruct_Main4 *main4, u8 count) +static void ClearIncomingPlayerList(struct RfuIncomingPlayerList *list, u8 count) { s32 i; for (i = 0; i < RFU_CHILD_MAX; i++) { - main4->arr[i].gname_uname = sWirelessGnameUnamePair_Dummy; - main4->arr[i].active = FALSE; + list->players[i].rfu = sUnionRoomPlayer_DummyRfu; + list->players[i].active = FALSE; } } -static bool8 AreGnameUnameDifferent(struct WirelessGnameUnamePair* pair1, const struct WirelessGnameUnamePair* pair2) +// Checks player name and trainer id, returns TRUE if they are not the same +static bool8 ArePlayersDifferent(struct RfuPlayerData* player1, const struct RfuPlayerData* player2) { s32 i; for (i = 0; i < 2; i++) { - if (pair1->gname.unk_00.playerTrainerId[i] != pair2->gname.unk_00.playerTrainerId[i]) - { + if (player1->data.compatibility.playerTrainerId[i] != player2->data.compatibility.playerTrainerId[i]) return TRUE; - } } for (i = 0; i < PLAYER_NAME_LENGTH + 1; i++) { - if (pair1->playerName[i] != pair2->playerName[i]) - { + if (player1->name[i] != player2->name[i]) return TRUE; - } } return FALSE; } -static bool32 AreUnionRoomPlayerGnamesDifferent(struct WirelessGnameUnamePair *pair1, struct WirelessGnameUnamePair *pair2) +static bool32 ArePlayerDataDifferent(struct RfuPlayerData *player1, struct RfuPlayerData *player2) { s32 i; - if (pair1->gname.activity != pair2->gname.activity) - { + if (player1->data.activity != player2->data.activity) return TRUE; - } - if (pair1->gname.started != pair2->gname.started) - { + if (player1->data.startedActivity != player2->data.startedActivity) return TRUE; - } for (i = 0; i < RFU_CHILD_MAX; i++) { - if (pair1->gname.child_sprite_gender[i] != pair2->gname.child_sprite_gender[i]) - { + if (player1->data.partnerInfo[i] != player2->data.partnerInfo[i]) return TRUE; - } } - if (pair1->gname.species != pair2->gname.species) - { + if (player1->data.tradeSpecies != player2->data.tradeSpecies) return TRUE; - } - if (pair1->gname.type != pair2->gname.type) - { + if (player1->data.tradeType != player2->data.tradeType) return TRUE; - } return FALSE; } -static u32 Findx20Inx1CArray(struct UnkStruct_x20 *arg0, struct UnkStruct_x1C *arg1) +static u32 GetNewIncomingPlayerId(struct RfuPlayer *player, struct RfuIncomingPlayer *incomingPlayer) { - u8 result = 0xFF; + u8 result = 0xFF; // None s32 i; for (i = 0; i < RFU_CHILD_MAX; i++) { - if (arg1[i].active && !AreGnameUnameDifferent(&arg0->gname_uname, &arg1[i].gname_uname)) + if (incomingPlayer[i].active && !ArePlayersDifferent(&player->rfu, &incomingPlayer[i].rfu)) { result = i; - arg1[i].active = FALSE; + incomingPlayer[i].active = FALSE; } } return result; } -static u8 Appendx1Ctox20(struct UnkStruct_x20 *arg0, struct UnkStruct_x1C *arg1, u8 max) +static u8 TryAddIncomingPlayerToList(struct RfuPlayer *players, struct RfuIncomingPlayer *incomingPlayer, u8 max) { s32 i; - if (arg1->active) + if (incomingPlayer->active) { for (i = 0; i < max; i++) { - if (arg0[i].groupScheduledAnim == UNION_ROOM_SPAWN_NONE) + if (players[i].groupScheduledAnim == UNION_ROOM_SPAWN_NONE) { - arg0[i].gname_uname = arg1->gname_uname; - arg0[i].timeoutCounter = 0; - arg0[i].groupScheduledAnim = UNION_ROOM_SPAWN_IN; - arg0[i].field_1B = 64; - arg1->active = FALSE; + players[i].rfu = incomingPlayer->rfu; + players[i].timeoutCounter = 0; + players[i].groupScheduledAnim = UNION_ROOM_SPAWN_IN; + players[i].newPlayerCountdown = 64; + incomingPlayer->active = FALSE; return i; } } @@ -3949,39 +3959,39 @@ static u8 Appendx1Ctox20(struct UnkStruct_x20 *arg0, struct UnkStruct_x1C *arg1, return 0xFF; } -static void PrintUnionRoomGroupOnWindow(u8 windowId, u8 x, u8 y, struct UnkStruct_x20 *group, u8 colorIdx, u8 id) +static void PrintGroupMemberOnWindow(u8 windowId, u8 x, u8 y, struct RfuPlayer *player, u8 colorIdx, u8 id) { u8 activity; u8 trainerId[6]; ConvertIntToDecimalStringN(gStringVar4, id + 1, STR_CONV_MODE_LEADING_ZEROS, 2); StringAppend(gStringVar4, sText_Colon); - UR_AddTextPrinterParameterized(windowId, 1, gStringVar4, x, y, 0); + PrintUnionRoomText(windowId, 1, gStringVar4, x, y, UR_COLOR_DEFAULT); x += 18; - activity = group->gname_uname.gname.activity; - if (group->groupScheduledAnim == UNION_ROOM_SPAWN_IN && !(activity & IN_UNION_ROOM)) + activity = player->rfu.data.activity; + if (player->groupScheduledAnim == UNION_ROOM_SPAWN_IN && !(activity & IN_UNION_ROOM)) { - IntlConvPartnerUname7(gStringVar4, group); - UR_AddTextPrinterParameterized(windowId, 1, gStringVar4, x, y, colorIdx); - ConvertIntToDecimalStringN(trainerId, group->gname_uname.gname.unk_00.playerTrainerId[0] | (group->gname_uname.gname.unk_00.playerTrainerId[1] << 8), STR_CONV_MODE_LEADING_ZEROS, 5); + CopyAndTranslatePlayerName(gStringVar4, player); + PrintUnionRoomText(windowId, 1, gStringVar4, x, y, colorIdx); + ConvertIntToDecimalStringN(trainerId, player->rfu.data.compatibility.playerTrainerId[0] | (player->rfu.data.compatibility.playerTrainerId[1] << 8), STR_CONV_MODE_LEADING_ZEROS, 5); StringCopy(gStringVar4, sText_ID); StringAppend(gStringVar4, trainerId); - UR_AddTextPrinterParameterized(windowId, 1, gStringVar4, GetStringRightAlignXOffset(1, gStringVar4, 0x88), y, colorIdx); + PrintUnionRoomText(windowId, 1, gStringVar4, GetStringRightAlignXOffset(1, gStringVar4, 0x88), y, colorIdx); } } -static void PrintGroupMemberCandidateOnWindowWithColor(u8 windowId, u8 x, u8 y, struct UnkStruct_x20 *group, u8 colorIdx, u8 id) +static void PrintGroupCandidateOnWindow(u8 windowId, u8 x, u8 y, struct RfuPlayer *player, u8 colorIdx, u8 id) { u8 trainerId[6]; - if (group->groupScheduledAnim == UNION_ROOM_SPAWN_IN) + if (player->groupScheduledAnim == UNION_ROOM_SPAWN_IN) { - IntlConvPartnerUname7(gStringVar4, group); - UR_AddTextPrinterParameterized(windowId, 1, gStringVar4, x, y, colorIdx); - ConvertIntToDecimalStringN(trainerId, group->gname_uname.gname.unk_00.playerTrainerId[0] | (group->gname_uname.gname.unk_00.playerTrainerId[1] << 8), STR_CONV_MODE_LEADING_ZEROS, 5); + CopyAndTranslatePlayerName(gStringVar4, player); + PrintUnionRoomText(windowId, 1, gStringVar4, x, y, colorIdx); + ConvertIntToDecimalStringN(trainerId, player->rfu.data.compatibility.playerTrainerId[0] | (player->rfu.data.compatibility.playerTrainerId[1] << 8), STR_CONV_MODE_LEADING_ZEROS, 5); StringCopy(gStringVar4, sText_ID); StringAppend(gStringVar4, trainerId); - UR_AddTextPrinterParameterized(windowId, 1, gStringVar4, GetStringRightAlignXOffset(1, gStringVar4, 0x68), y, colorIdx); + PrintUnionRoomText(windowId, 1, gStringVar4, GetStringRightAlignXOffset(1, gStringVar4, 0x68), y, colorIdx); } } @@ -4018,24 +4028,24 @@ static u32 GetResponseIdx_InviteToURoomActivity(s32 activity) } } -static u32 ConvPartnerUnameAndGetWhetherMetAlready(struct UnkStruct_x20 *arg0) +static u32 ConvPartnerUnameAndGetWhetherMetAlready(struct RfuPlayer *player) { u8 name[30]; - IntlConvPartnerUname7(name, arg0); - return PlayerHasMetTrainerBefore(ReadAsU16(arg0->gname_uname.gname.unk_00.playerTrainerId), name); + CopyAndTranslatePlayerName(name, player); + return PlayerHasMetTrainerBefore(ReadAsU16(player->rfu.data.compatibility.playerTrainerId), name); } -static s32 UnionRoomGetPlayerInteractionResponse(struct UnkStruct_Main0 *main0, bool8 overrideGender, u8 playerIdx, u32 playerGender) +static s32 UnionRoomGetPlayerInteractionResponse(struct RfuPlayerList *list, bool8 overrideGender, u8 playerIdx, u32 playerGender) { bool32 metBefore; - struct UnkStruct_x20 * r5 = &main0->arr[playerIdx]; + struct RfuPlayer * player = &list->players[playerIdx]; - if (!r5->gname_uname.gname.started && !overrideGender) + if (!player->rfu.data.startedActivity && !overrideGender) { - IntlConvPartnerUname7(gStringVar1, r5); - metBefore = PlayerHasMetTrainerBefore(ReadAsU16(r5->gname_uname.gname.unk_00.playerTrainerId), gStringVar1); - if (r5->gname_uname.gname.activity == (ACTIVITY_CHAT | IN_UNION_ROOM)) + CopyAndTranslatePlayerName(gStringVar1, player); + metBefore = PlayerHasMetTrainerBefore(ReadAsU16(player->rfu.data.compatibility.playerTrainerId), gStringVar1); + if (player->rfu.data.activity == (ACTIVITY_CHAT | IN_UNION_ROOM)) { StringExpandPlaceholders(gStringVar4, sJoinChatTexts[metBefore][playerGender]); return 2; @@ -4048,12 +4058,12 @@ static s32 UnionRoomGetPlayerInteractionResponse(struct UnkStruct_Main0 *main0, } else { - IntlConvPartnerUname7(gStringVar1, r5); + CopyAndTranslatePlayerName(gStringVar1, player); if (overrideGender) { - playerGender = (r5->gname_uname.gname.unk_00.playerTrainerId[overrideGender + 1] >> 3) & 1; + playerGender = (player->rfu.data.compatibility.playerTrainerId[overrideGender + 1] >> 3) & 1; } - switch (r5->gname_uname.gname.activity & 0x3F) + switch (player->rfu.data.activity & 0x3F) { case ACTIVITY_BATTLE_SINGLE: StringExpandPlaceholders(gStringVar4, sBattleReactionTexts[playerGender][Random() % ARRAY_COUNT(sBattleReactionTexts[0])]); @@ -4075,88 +4085,82 @@ static s32 UnionRoomGetPlayerInteractionResponse(struct UnkStruct_Main0 *main0, } } -void nullsub_14(u8 windowId, u32 itemId, u8 y) +void ItemPrintFunc_EmptyList(u8 windowId, u32 itemId, u8 y) { } -static void TradeBoardPrintItemInfo(u8 windowId, u8 y, struct GFtgtGname * gname, const u8 * uname, u8 colorIdx) +static void TradeBoardPrintItemInfo(u8 windowId, u8 y, struct RfuGameData * data, const u8 * playerName, u8 colorIdx) { u8 levelStr[4]; - u16 species = gname->species; - u8 type = gname->type; - u8 level = gname->level; + u16 species = data->tradeSpecies; + u8 type = data->tradeType; + u8 level = data->tradeLevel; - UR_AddTextPrinterParameterized(windowId, 1, uname, 8, y, colorIdx); + PrintUnionRoomText(windowId, 1, playerName, 8, y, colorIdx); if (species == SPECIES_EGG) { - UR_AddTextPrinterParameterized(windowId, 1, sText_EggTrade, 68, y, colorIdx); + PrintUnionRoomText(windowId, 1, sText_EggTrade, 68, y, colorIdx); } else { BlitMenuInfoIcon(windowId, type + 1, 68, y); - UR_AddTextPrinterParameterized(windowId, 1, gSpeciesNames[species], 118, y, colorIdx); + PrintUnionRoomText(windowId, 1, gSpeciesNames[species], 118, y, colorIdx); ConvertIntToDecimalStringN(levelStr, level, STR_CONV_MODE_RIGHT_ALIGN, 3); - UR_AddTextPrinterParameterized(windowId, 1, levelStr, 198, y, colorIdx); + PrintUnionRoomText(windowId, 1, levelStr, 198, y, colorIdx); } } static void TradeBoardListMenuItemPrintFunc(u8 windowId, u32 itemId, u8 y) { - struct WirelessLink_Leader *data = sWirelessLinkMain.leader; - struct GFtgtGname *rfu; + struct WirelessLink_Leader *leader = sWirelessLinkMain.leader; + struct RfuGameData *gameData; s32 i, j; u8 playerName[11]; - if (itemId == -3 && y == sTradeBoardListMenuTemplate.upText_Y) + if (itemId == LIST_HEADER && y == sTradeBoardListMenuTemplate.upText_Y) { - rfu = GetHostRFUtgtGname(); - if (rfu->species != SPECIES_NONE) - { - TradeBoardPrintItemInfo(windowId, y, rfu, gSaveBlock2Ptr->playerName, 5); - } + gameData = GetHostRfuGameData(); + if (gameData->tradeSpecies != SPECIES_NONE) + TradeBoardPrintItemInfo(windowId, y, gameData, gSaveBlock2Ptr->playerName, UR_COLOR_TRADE_BOARD_SELF); } else { j = 0; - for (i = 0; i < (int)ARRAY_COUNT(data->field_0->arr); i++) + for (i = 0; i < MAX_UNION_ROOM_LEADERS; i++) { - if (data->field_0->arr[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN && data->field_0->arr[i].gname_uname.gname.species != SPECIES_NONE) - { + if (leader->playerList->players[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN && leader->playerList->players[i].rfu.data.tradeSpecies != SPECIES_NONE) j++; - } + if (j == itemId + 1) { - IntlConvPartnerUname7(playerName, &data->field_0->arr[i]); - TradeBoardPrintItemInfo(windowId, y, &data->field_0->arr[i].gname_uname.gname, playerName, 6); + CopyAndTranslatePlayerName(playerName, &leader->playerList->players[i]); + TradeBoardPrintItemInfo(windowId, y, &leader->playerList->players[i].rfu.data, playerName, UR_COLOR_TRADE_BOARD_OTHER); break; } } } } -static s32 GetIndexOfNthTradeBoardOffer(struct UnkStruct_x20 * arg, s32 n) +static s32 GetIndexOfNthTradeBoardOffer(struct RfuPlayer * players, s32 n) { s32 i; s32 j = 0; - for (i = 0; i < 8; i++) + for (i = 0; i < MAX_UNION_ROOM_LEADERS; i++) { - if (arg[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN && arg[i].gname_uname.gname.species != SPECIES_NONE) - { + if (players[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN && players[i].rfu.data.tradeSpecies != SPECIES_NONE) j++; - } + if (j == n + 1) - { return i; - } } return -1; } -static s32 GetUnionRoomPlayerGender(s32 playerIdx, struct UnkStruct_Main0 *main0) +static s32 GetUnionRoomPlayerGender(s32 playerIdx, struct RfuPlayerList *list) { - return main0->arr[playerIdx].gname_uname.gname.playerGender; + return list->players[playerIdx].rfu.data.playerGender; } static s32 IsRequestedTypeOrEggInPlayerParty(u32 type, u32 species) @@ -4169,9 +4173,7 @@ static s32 IsRequestedTypeOrEggInPlayerParty(u32 type, u32 species) { species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2); if (species == SPECIES_EGG) - { return UR_TRADE_MATCH; - } } return UR_TRADE_NOEGG; } @@ -4181,9 +4183,7 @@ static s32 IsRequestedTypeOrEggInPlayerParty(u32 type, u32 species) { species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2); if (gBaseStats[species].type1 == type || gBaseStats[species].type2 == type) - { return UR_TRADE_MATCH; - } } return UR_TRADE_NOTYPE; } @@ -4248,7 +4248,7 @@ static s32 GetChatLeaderActionRequestMessage(u8 *dst, u32 gender, u16 *activityD StringCopy(uroom->activityRequestStrbufs[1], gSpeciesNames[sUnionRoomTrade.playerSpecies]); for (i = 0; i < RFU_CHILD_MAX; i++) { - if (gRfuLinkStatus->partner[i].serialNo == 2) + if (gRfuLinkStatus->partner[i].serialNo == RFU_SERIAL_GAME) { ConvertIntToDecimalStringN(uroom->activityRequestStrbufs[2], activityData[2], STR_CONV_MODE_LEFT_ALIGN, 3); StringCopy(uroom->activityRequestStrbufs[3], gSpeciesNames[activityData[1]]); @@ -4263,9 +4263,7 @@ static s32 GetChatLeaderActionRequestMessage(u8 *dst, u32 gender, u16 *activityD else { for (i = 0; i < RFU_CHILD_MAX; i++) - { DynamicPlaceholderTextUtil_SetPlaceholderPtr(i, uroom->activityRequestStrbufs[i]); - } DynamicPlaceholderTextUtil_ExpandPlaceholders(dst, sText_OfferToTradeMon); } result = 1; @@ -4303,9 +4301,9 @@ static bool32 PollPartnerYesNoResponse(struct WirelessLink_URoom *data) bool32 InUnionRoom(void) { - return gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(UNION_ROOM) - && gSaveBlock1Ptr->location.mapNum == MAP_NUM(UNION_ROOM) - ? TRUE : FALSE; + return gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(UNION_ROOM) + && gSaveBlock1Ptr->location.mapNum == MAP_NUM(UNION_ROOM) + ? TRUE : FALSE; } static bool32 HasAtLeastTwoMonsOfLevel30OrLower(void) @@ -4316,10 +4314,8 @@ static bool32 HasAtLeastTwoMonsOfLevel30OrLower(void) for (i = 0; i < gPlayerPartyCount; i++) { if (GetMonData(&gPlayerParty[i], MON_DATA_LEVEL) <= 30 - && GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2) != SPECIES_EGG) - { + && GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2) != SPECIES_EGG) count++; - } } if (count > 1) @@ -4328,16 +4324,16 @@ static bool32 HasAtLeastTwoMonsOfLevel30OrLower(void) return FALSE; } -static void ResetUnionRoomTrade(struct UnionRoomTrade *uroomTrade) +static void ResetUnionRoomTrade(struct UnionRoomTrade *trade) { - uroomTrade->state = URTRADE_STATE_NONE; - uroomTrade->type = 0; - uroomTrade->playerPersonality = 0; - uroomTrade->playerSpecies = 0; - uroomTrade->playerLevel = 0; - uroomTrade->species = 0; - uroomTrade->level = 0; - uroomTrade->personality = 0; + trade->state = URTRADE_STATE_NONE; + trade->type = 0; + trade->playerPersonality = 0; + trade->playerSpecies = SPECIES_NONE; + trade->playerLevel = 0; + trade->species = SPECIES_NONE; + trade->level = 0; + trade->personality = 0; } void Script_ResetUnionRoomTrade(void) @@ -4372,31 +4368,26 @@ static u32 GetPartyPositionOfRegisteredMon(struct UnionRoomTrade *trade, u8 mult u16 cur_species; s32 i; - // player if (multiplayerId == 0) { species = trade->playerSpecies; personality = trade->playerPersonality; } - // partner else { species = trade->species; personality = trade->personality; } + // Find party position by comparing to personality and species for (i = 0; i < gPlayerPartyCount; i++) { cur_personality = GetMonData(&gPlayerParty[i], MON_DATA_PERSONALITY); if (cur_personality != personality) - { continue; - } cur_species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2); if (cur_species != species) - { continue; - } response = i; break; } @@ -4417,23 +4408,23 @@ static void HandleCancelActivity(bool32 setData) } } -static void UR_EnableScriptContext2AndFreezeObjectEvents(void) +static void StartScriptInteraction(void) { ScriptContext2_Enable(); FreezeObjects_WaitForPlayer(); } -static u8 GetActivePartnerSpriteGenderParam(struct WirelessLink_URoom *data) +static u8 GetActivePartnersInfo(struct WirelessLink_URoom *data) { - u8 retVal = 0x80; + u8 retVal = PINFO_ACTIVE_FLAG; u8 i; for (i = 0; i < RFU_CHILD_MAX; i++) { - if (data->field_C->arr[i].active) + if (data->incomingParentList->players[i].active) { - retVal |= data->field_C->arr[i].gname_uname.gname.playerGender << 3; - retVal |= data->field_C->arr[i].gname_uname.gname.unk_00.playerTrainerId[0] & 7; + retVal |= data->incomingParentList->players[i].rfu.data.playerGender << PINFO_GENDER_SHIFT; + retVal |= data->incomingParentList->players[i].rfu.data.compatibility.playerTrainerId[0] & PINFO_TID_MASK; break; } } @@ -4470,17 +4461,13 @@ static void ViewURoomPartnerTrainerCard(u8 *unused, struct WirelessLink_URoom *d n = trainerCard->linkBattleWins; if (n > 9999) - { n = 9999; - } ConvertIntToDecimalStringN(data->trainerCardStrBuffer[0], n, STR_CONV_MODE_LEFT_ALIGN, 4); DynamicPlaceholderTextUtil_SetPlaceholderPtr(0, data->trainerCardStrBuffer[0]); n = trainerCard->linkBattleLosses; if (n > 9999) - { n = 9999; - } ConvertIntToDecimalStringN(data->trainerCardStrBuffer[1], n, STR_CONV_MODE_LEFT_ALIGN, 4); DynamicPlaceholderTextUtil_SetPlaceholderPtr(2, data->trainerCardStrBuffer[1]); @@ -4508,8 +4495,8 @@ static void ViewURoomPartnerTrainerCard(u8 *unused, struct WirelessLink_URoom *d } } -static void IntlConvPartnerUname7(u8 *dest, struct UnkStruct_x20 *arg1) +static void CopyAndTranslatePlayerName(u8 *dest, struct RfuPlayer *player) { - StringCopy7(dest, arg1->gname_uname.playerName); - ConvertInternationalString(dest, arg1->gname_uname.gname.unk_00.language); + StringCopy7(dest, player->rfu.name); + ConvertInternationalString(dest, player->rfu.data.compatibility.language); } diff --git a/src/union_room_chat.c b/src/union_room_chat.c index 577784300..adf496fe6 100755 --- a/src/union_room_chat.c +++ b/src/union_room_chat.c @@ -997,7 +997,7 @@ static void Chat_Join(void) sChat->funcState++; // fall through case 1: - if (IsLinkTaskFinished() && !sub_8011A9C()) + if (IsLinkTaskFinished() && !Rfu_IsPlayerExchangeActive()) { if (SendBlock(0, sChat->sendMessageBuffer, sizeof(sChat->sendMessageBuffer))) sChat->funcState++; @@ -1198,7 +1198,7 @@ static void Chat_AskQuitChatting(void) sChat->funcState = 3; break; case 0: - sub_80104B0(); + Rfu_StopPartnerSearch(); PrepareSendBuffer_Disband(sChat->sendMessageBuffer); sChat->funcState = 4; sChat->tryQuitAgainTimer = 0; @@ -1206,7 +1206,7 @@ static void Chat_AskQuitChatting(void) } break; case 4: - if (IsLinkTaskFinished() && !sub_8011A9C() && SendBlock(0, sChat->sendMessageBuffer, sizeof(sChat->sendMessageBuffer))) + if (IsLinkTaskFinished() && !Rfu_IsPlayerExchangeActive() && SendBlock(0, sChat->sendMessageBuffer, sizeof(sChat->sendMessageBuffer))) { if (!sChat->multiplayerId) sChat->funcState = 6; @@ -1257,15 +1257,15 @@ static void Chat_Exit(void) } break; case 3: - if (IsLinkTaskFinished() && !sub_8011A9C() && SendBlock(0, sChat->sendMessageBuffer, sizeof(sChat->sendMessageBuffer))) + if (IsLinkTaskFinished() && !Rfu_IsPlayerExchangeActive() && SendBlock(0, sChat->sendMessageBuffer, sizeof(sChat->sendMessageBuffer))) sChat->funcState++; break; case 4: - if ((GetBlockReceivedStatus() & 1) && !sub_8011A9C()) + if ((GetBlockReceivedStatus() & 1) && !Rfu_IsPlayerExchangeActive()) sChat->funcState++; break; case 5: - if (IsLinkTaskFinished() && !sub_8011A9C()) + if (IsLinkTaskFinished() && !Rfu_IsPlayerExchangeActive()) { SetCloseLinkCallback(); sChat->exitDelayTimer = 0; @@ -1300,7 +1300,7 @@ static void Chat_Drop(void) } break; case 1: - if (!IsDisplaySubtaskActive(0) && IsLinkTaskFinished() && !sub_8011A9C()) + if (!IsDisplaySubtaskActive(0) && IsLinkTaskFinished() && !Rfu_IsPlayerExchangeActive()) { SetCloseLinkCallback(); sChat->exitDelayTimer = 0; @@ -1346,7 +1346,7 @@ static void Chat_Disbanded(void) } break; case 2: - if (IsDisplaySubtaskActive(0) != TRUE && IsLinkTaskFinished() && !sub_8011A9C()) + if (IsDisplaySubtaskActive(0) != TRUE && IsLinkTaskFinished() && !Rfu_IsPlayerExchangeActive()) { SetCloseLinkCallback(); sChat->exitDelayTimer = 0; @@ -1384,7 +1384,7 @@ static void Chat_SendMessage(void) sChat->funcState++; // fall through case 1: - if (IsLinkTaskFinished() == TRUE && !sub_8011A9C() && SendBlock(0, sChat->sendMessageBuffer, sizeof(sChat->sendMessageBuffer))) + if (IsLinkTaskFinished() == TRUE && !Rfu_IsPlayerExchangeActive() && SendBlock(0, sChat->sendMessageBuffer, sizeof(sChat->sendMessageBuffer))) sChat->funcState++; break; case 2: @@ -1819,7 +1819,7 @@ static void PrepareSendBuffer_Leave(u8 *buffer) buffer[0] = CHAT_MESSAGE_LEAVE; StringCopy(&buffer[1], gSaveBlock2Ptr->playerName); buffer[1 + (PLAYER_NAME_LENGTH + 1)] = sChat->multiplayerId; - sub_8011A50(); + RfuSetNormalDisconnectMode(); } static void PrepareSendBuffer_Drop(u8 *buffer) @@ -2028,7 +2028,7 @@ static void Task_ReceiveChatMessage(u8 taskId) } tBlockReceivedStatus = GetBlockReceivedStatus(); - if (!tBlockReceivedStatus && sub_8011A9C()) + if (!tBlockReceivedStatus && Rfu_IsPlayerExchangeActive()) return; tI = 0; @@ -2079,13 +2079,12 @@ static void Task_ReceiveChatMessage(u8 taskId) { if (GetLinkPlayerCount() == 2) { - sub_80104B0(); + Rfu_StopPartnerSearch(); sChat->exitType = 1; DestroyTask(taskId); return; } - - sub_8011DE0(tCurrLinkPlayer); + Rfu_DisconnectPlayerById(tCurrLinkPlayer); } tState = 3; @@ -2101,10 +2100,10 @@ static void Task_ReceiveChatMessage(u8 taskId) DestroyTask(taskId); break; case 2: - if (!sub_8011A9C()) + if (!Rfu_IsPlayerExchangeActive()) { if (!sChat->multiplayerId) - sub_80110B8(sChat->linkPlayerCount); + SetUnionRoomChatPlayerData(sChat->linkPlayerCount); tState = 1; } diff --git a/src/union_room_player_avatar.c b/src/union_room_player_avatar.c index 77eee6e4a..225386165 100644 --- a/src/union_room_player_avatar.c +++ b/src/union_room_player_avatar.c @@ -9,8 +9,12 @@ #include "constants/event_objects.h" #include "constants/event_object_movement.h" -#define UR_SPRITE_START_ID (MAX_SPRITES - MAX_UNION_ROOM_PLAYERS) -#define UR_PLAYER_SPRITE_ID(playerIdx, facingDir)(5 * playerIdx + facingDir) +#define UR_SPRITE_START_ID (MAX_SPRITES - MAX_UNION_ROOM_LEADERS) + +// Each parent player can lead a group of up to MAX_RFU_PLAYERS (including themselves). +// Multiply the leader's id by MAX_RFU_PLAYERS and add the member's id (0 if the leader) to +// get the sprite index of that player. +#define UR_PLAYER_SPRITE_ID(leaderId, memberId)(MAX_RFU_PLAYERS * leaderId + memberId) static EWRAM_DATA struct UnionRoomObject * sUnionObjWork = NULL; static EWRAM_DATA u32 sUnionObjRefreshTimer = 0; @@ -19,7 +23,8 @@ static u8 CreateTask_AnimateUnionRoomPlayers(void); static u32 IsUnionRoomPlayerInvisible(u32, u32); static void SetUnionRoomObjectFacingDirection(s32, s32, u8); -static const u8 sUnionRoomObjGfxIds[GENDER_COUNT][MAX_UNION_ROOM_PLAYERS + 2] = { +// + 2 is just to match, those elements are empty and never read +static const u8 sUnionRoomObjGfxIds[GENDER_COUNT][MAX_UNION_ROOM_LEADERS + 2] = { [MALE] = { OBJ_EVENT_GFX_MAN_3, OBJ_EVENT_GFX_BLACK_BELT, @@ -42,7 +47,7 @@ static const u8 sUnionRoomObjGfxIds[GENDER_COUNT][MAX_UNION_ROOM_PLAYERS + 2] = } }; -static const s16 sUnionRoomPlayerCoords[MAX_UNION_ROOM_PLAYERS][2] = { +static const s16 sUnionRoomPlayerCoords[MAX_UNION_ROOM_LEADERS][2] = { { 4, 6}, {13, 8}, {10, 6}, @@ -53,12 +58,16 @@ static const s16 sUnionRoomPlayerCoords[MAX_UNION_ROOM_PLAYERS][2] = { { 7, 8} }; -static const s8 sFacingDirectionOffsets[][2] = { - [DIR_NONE] = { 0, 0}, - [DIR_SOUTH] = { 1, 0}, - [DIR_NORTH] = { 0, -1}, - [DIR_WEST] = {-1, 0}, - [DIR_EAST] = { 0, 1} +// If there's a group of players interacting in the Union Room, the group +// leader will be at one of the positions above and each member in the group +// will be at one of the offsets from that position below. The leader will +// be at the first offset (0,0), as they're at the center. +static const s8 sUnionRoomGroupOffsets[MAX_RFU_PLAYERS][2] = { + { 0, 0}, // Center + { 1, 0}, // Left + { 0, -1}, // Top + {-1, 0}, // Right + { 0, 1} // Bottom }; static const u8 sOppositeFacingDirection[] = { @@ -69,12 +78,14 @@ static const u8 sOppositeFacingDirection[] = { [DIR_EAST] = DIR_WEST }; -static const u8 sNextFacingDirection[] = { - [DIR_NONE] = DIR_SOUTH, - [DIR_SOUTH] = DIR_WEST, - [DIR_NORTH] = DIR_SOUTH, - [DIR_WEST] = DIR_EAST, - [DIR_EAST] = DIR_NORTH +// Compare to sUnionRoomGroupOffsets, the direction each group member +// needs to be facing in order to face the group leader in the center. +static const u8 sMemberFacingDirections[MAX_RFU_PLAYERS] = { + DIR_SOUTH, // Leader, but never read + DIR_WEST, + DIR_SOUTH, + DIR_EAST, + DIR_NORTH }; static const u8 sUnionRoomLocalIds[] = { @@ -118,21 +129,22 @@ static bool32 IsPlayerStandingStill(void) return FALSE; } +// Gender and trainer id are used to determine which sprite a player appears as static u8 GetUnionRoomPlayerGraphicsId(u32 gender, u32 id) { - return sUnionRoomObjGfxIds[gender][id % MAX_UNION_ROOM_PLAYERS]; + return sUnionRoomObjGfxIds[gender][id % MAX_UNION_ROOM_LEADERS]; } -static void GetUnionRoomPlayerFacingCoords(u32 playerIdx, u32 direction, s32 * x, s32 * y) +static void GetUnionRoomPlayerCoords(u32 leaderId, u32 memberId, s32 * x, s32 * y) { - *x = sUnionRoomPlayerCoords[playerIdx][0] + sFacingDirectionOffsets[direction][0] + MAP_OFFSET; - *y = sUnionRoomPlayerCoords[playerIdx][1] + sFacingDirectionOffsets[direction][1] + MAP_OFFSET; + *x = sUnionRoomPlayerCoords[leaderId][0] + sUnionRoomGroupOffsets[memberId][0] + MAP_OFFSET; + *y = sUnionRoomPlayerCoords[leaderId][1] + sUnionRoomGroupOffsets[memberId][1] + MAP_OFFSET; } -static bool32 IsUnionRoomPlayerFacingTileAt(u32 playerIdx, u32 direction, s32 x, s32 y) +static bool32 IsUnionRoomPlayerAt(u32 leaderId, u32 memberId, s32 x, s32 y) { - if ((sUnionRoomPlayerCoords[playerIdx][0] + sFacingDirectionOffsets[direction][0] + MAP_OFFSET == x) - && (sUnionRoomPlayerCoords[playerIdx][1] + sFacingDirectionOffsets[direction][1] + MAP_OFFSET == y)) + if ((sUnionRoomPlayerCoords[leaderId][0] + sUnionRoomGroupOffsets[memberId][0] + MAP_OFFSET == x) + && (sUnionRoomPlayerCoords[leaderId][1] + sUnionRoomGroupOffsets[memberId][1] + MAP_OFFSET == y)) return TRUE; else return FALSE; @@ -153,62 +165,50 @@ static void ShowUnionRoomPlayer(u32 player_idx) FlagClear(FLAG_HIDE_UNION_ROOM_PLAYER_1 + player_idx); } -static void SetUnionRoomPlayerGfx(u32 playerIdx, u32 gfxId) +static void SetUnionRoomPlayerGfx(u32 leaderId, u32 gfxId) { - VarSet(VAR_OBJ_GFX_ID_0 + playerIdx, gfxId); + VarSet(VAR_OBJ_GFX_ID_0 + leaderId, gfxId); } -static void CreateUnionRoomPlayerObjectEvent(u32 playerIdx) +static void CreateUnionRoomPlayerObjectEvent(u32 leaderId) { - TrySpawnObjectEvent(sUnionRoomLocalIds[playerIdx], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup); + TrySpawnObjectEvent(sUnionRoomLocalIds[leaderId], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup); } -static void RemoveUnionRoomPlayerObjectEvent(u32 playerIdx) +static void RemoveUnionRoomPlayerObjectEvent(u32 leaderId) { - RemoveObjectEventByLocalIdAndMap(sUnionRoomLocalIds[playerIdx], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup); + RemoveObjectEventByLocalIdAndMap(sUnionRoomLocalIds[leaderId], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup); } -static bool32 SetUnionRoomPlayerEnterExitMovement(u32 playerIdx, const u8 * movement) +static bool32 SetUnionRoomPlayerEnterExitMovement(u32 leaderId, const u8 * movement) { u8 objectId; struct ObjectEvent * object; - if (TryGetObjectEventIdByLocalIdAndMap(sUnionRoomLocalIds[playerIdx], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, &objectId)) - { + if (TryGetObjectEventIdByLocalIdAndMap(sUnionRoomLocalIds[leaderId], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, &objectId)) return FALSE; - } object = &gObjectEvents[objectId]; if (ObjectEventIsMovementOverridden(object)) - { return FALSE; - } if (ObjectEventSetHeldMovement(object, *movement)) - { return FALSE; - } return TRUE; } -static bool32 TryReleaseUnionRoomPlayerObjectEvent(u32 playerIdx) +static bool32 TryReleaseUnionRoomPlayerObjectEvent(u32 leaderId) { u8 objectId; struct ObjectEvent * object; - if (TryGetObjectEventIdByLocalIdAndMap(sUnionRoomLocalIds[playerIdx], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, &objectId)) - { + if (TryGetObjectEventIdByLocalIdAndMap(sUnionRoomLocalIds[leaderId], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, &objectId)) return TRUE; - } + object = &gObjectEvents[objectId]; if (!ObjectEventClearHeldMovementIfFinished(object)) - { return FALSE; - } + if (!ScriptContext2_IsEnabled()) - { UnfreezeObjectEvent(object); - } else - { FreezeObjectEvent(object); - } return TRUE; } @@ -218,7 +218,7 @@ u8 InitUnionRoomPlayerObjects(struct UnionRoomObject * players) sUnionObjRefreshTimer = 0; sUnionObjWork = players; - for (i = 0; i < MAX_UNION_ROOM_PLAYERS; i++) + for (i = 0; i < MAX_UNION_ROOM_LEADERS; i++) { players[i].state = 0; players[i].gfxId = 0; @@ -228,22 +228,22 @@ u8 InitUnionRoomPlayerObjects(struct UnionRoomObject * players) return CreateTask_AnimateUnionRoomPlayers(); } -static bool32 AnimateUnionRoomPlayerDespawn(s8 * state, u32 playerIdx, struct UnionRoomObject * ptr) +static bool32 AnimateUnionRoomPlayerDespawn(s8 * state, u32 leaderId, struct UnionRoomObject * object) { switch (*state) { case 0: - if (SetUnionRoomPlayerEnterExitMovement(playerIdx, sMovement_UnionPlayerExit) == TRUE) + if (SetUnionRoomPlayerEnterExitMovement(leaderId, sMovement_UnionPlayerExit) == TRUE) { - HideUnionRoomPlayer(playerIdx); + HideUnionRoomPlayer(leaderId); (*state)++; } break; case 1: - if (TryReleaseUnionRoomPlayerObjectEvent(playerIdx)) + if (TryReleaseUnionRoomPlayerObjectEvent(leaderId)) { - RemoveUnionRoomPlayerObjectEvent(playerIdx); - HideUnionRoomPlayer(playerIdx); + RemoveUnionRoomPlayerObjectEvent(leaderId); + HideUnionRoomPlayer(leaderId); *state = 0; return TRUE; } @@ -252,7 +252,7 @@ static bool32 AnimateUnionRoomPlayerDespawn(s8 * state, u32 playerIdx, struct Un return FALSE; } -static bool32 AnimateUnionRoomPlayerSpawn(s8 * state, u32 playerIdx, struct UnionRoomObject * ptr) +static bool32 AnimateUnionRoomPlayerSpawn(s8 * state, u32 leaderId, struct UnionRoomObject * object) { s16 x, y; @@ -260,32 +260,24 @@ static bool32 AnimateUnionRoomPlayerSpawn(s8 * state, u32 playerIdx, struct Unio { case 0: if (!IsPlayerStandingStill()) - { break; - } PlayerGetDestCoords(&x, &y); - if (IsUnionRoomPlayerFacingTileAt(playerIdx, 0, x, y) == TRUE) - { + if (IsUnionRoomPlayerAt(leaderId, 0, x, y) == TRUE) break; - } player_get_pos_including_state_based_drift(&x, &y); - if (IsUnionRoomPlayerFacingTileAt(playerIdx, 0, x, y) == TRUE) - { + if (IsUnionRoomPlayerAt(leaderId, 0, x, y) == TRUE) break; - } - SetUnionRoomPlayerGfx(playerIdx, ptr->gfxId); - CreateUnionRoomPlayerObjectEvent(playerIdx); - ShowUnionRoomPlayer(playerIdx); + SetUnionRoomPlayerGfx(leaderId, object->gfxId); + CreateUnionRoomPlayerObjectEvent(leaderId); + ShowUnionRoomPlayer(leaderId); (*state)++; // fallthrough case 3: // incorrect? - if (SetUnionRoomPlayerEnterExitMovement(playerIdx, sMovement_UnionPlayerEnter) == TRUE) - { + if (SetUnionRoomPlayerEnterExitMovement(leaderId, sMovement_UnionPlayerEnter) == TRUE) (*state)++; - } break; case 2: - if (TryReleaseUnionRoomPlayerObjectEvent(playerIdx)) + if (TryReleaseUnionRoomPlayerObjectEvent(leaderId)) { *state = 0; return TRUE; @@ -295,38 +287,38 @@ static bool32 AnimateUnionRoomPlayerSpawn(s8 * state, u32 playerIdx, struct Unio return FALSE; } -static bool32 SpawnGroupLeader(u32 playerIdx, u32 gender, u32 id) +static bool32 SpawnGroupLeader(u32 leaderId, u32 gender, u32 id) { - struct UnionRoomObject * ptr = &sUnionObjWork[playerIdx]; - ptr->schedAnim = UNION_ROOM_SPAWN_IN; - ptr->gfxId = GetUnionRoomPlayerGraphicsId(gender, id); + struct UnionRoomObject * object = &sUnionObjWork[leaderId]; + object->schedAnim = UNION_ROOM_SPAWN_IN; + object->gfxId = GetUnionRoomPlayerGraphicsId(gender, id); - if (ptr->state == 0) + if (object->state == 0) return TRUE; else return FALSE; } -static bool32 DespawnGroupLeader(u32 playerIdx) +static bool32 DespawnGroupLeader(u32 leaderId) { - struct UnionRoomObject * ptr = &sUnionObjWork[playerIdx]; - ptr->schedAnim = UNION_ROOM_SPAWN_OUT; + struct UnionRoomObject * object = &sUnionObjWork[leaderId]; + object->schedAnim = UNION_ROOM_SPAWN_OUT; - if (ptr->state == 1) + if (object->state == 1) return TRUE; else return FALSE; } -static void AnimateUnionRoomPlayer(u32 playerIdx, struct UnionRoomObject * ptr) +static void AnimateUnionRoomPlayer(u32 leaderId, struct UnionRoomObject * object) { - switch (ptr->state) + switch (object->state) { case 0: - if (ptr->schedAnim == UNION_ROOM_SPAWN_IN) + if (object->schedAnim == UNION_ROOM_SPAWN_IN) { - ptr->state = 2; - ptr->animState = 0; + object->state = 2; + object->animState = 0; } else { @@ -334,23 +326,23 @@ static void AnimateUnionRoomPlayer(u32 playerIdx, struct UnionRoomObject * ptr) } // fallthrough case 2: - if (!IsUnionRoomPlayerInvisible(playerIdx, 0) && ptr->schedAnim == UNION_ROOM_SPAWN_OUT) + if (!IsUnionRoomPlayerInvisible(leaderId, 0) && object->schedAnim == UNION_ROOM_SPAWN_OUT) { - ptr->state = 0; - ptr->animState = 0; - RemoveUnionRoomPlayerObjectEvent(playerIdx); - HideUnionRoomPlayer(playerIdx); + object->state = 0; + object->animState = 0; + RemoveUnionRoomPlayerObjectEvent(leaderId); + HideUnionRoomPlayer(leaderId); } - else if (AnimateUnionRoomPlayerSpawn(&ptr->animState, playerIdx, ptr) == TRUE) + else if (AnimateUnionRoomPlayerSpawn(&object->animState, leaderId, object) == TRUE) { - ptr->state = 1; + object->state = 1; } break; case 1: - if (ptr->schedAnim == UNION_ROOM_SPAWN_OUT) + if (object->schedAnim == UNION_ROOM_SPAWN_OUT) { - ptr->state = 3; - ptr->animState = 0; + object->state = 3; + object->animState = 0; } else { @@ -358,19 +350,17 @@ static void AnimateUnionRoomPlayer(u32 playerIdx, struct UnionRoomObject * ptr) } // fallthrough case 3: - if (AnimateUnionRoomPlayerDespawn(&ptr->animState, playerIdx, ptr) == 1) - { - ptr->state = 0; - } + if (AnimateUnionRoomPlayerDespawn(&object->animState, leaderId, object) == 1) + object->state = 0; break; } - ptr->schedAnim = UNION_ROOM_SPAWN_NONE; + object->schedAnim = UNION_ROOM_SPAWN_NONE; } static void Task_AnimateUnionRoomPlayers(u8 taskId) { s32 i; - for (i = 0; i < MAX_UNION_ROOM_PLAYERS; i++) + for (i = 0; i < MAX_UNION_ROOM_LEADERS; i++) AnimateUnionRoomPlayer(i, &sUnionObjWork[i]); } @@ -386,15 +376,13 @@ static void DestroyTask_AnimateUnionRoomPlayers(void) { u8 taskId = FindTaskIdByFunc(Task_AnimateUnionRoomPlayers); if (taskId < NUM_TASKS) - { DestroyTask(taskId); - } } void DestroyUnionRoomPlayerObjects(void) { s32 i; - for (i = 0; i < MAX_UNION_ROOM_PLAYERS; i++) + for (i = 0; i < MAX_UNION_ROOM_LEADERS; i++) { if (!IsUnionRoomPlayerHidden(i)) { @@ -406,120 +394,119 @@ void DestroyUnionRoomPlayerObjects(void) DestroyTask_AnimateUnionRoomPlayers(); } -void CreateGroupMemberSpritesInvisible(u8 * spriteIds, s32 playerIdx) +void CreateUnionRoomPlayerSprites(u8 * spriteIds, s32 leaderId) { - s32 direction; - - for (direction = DIR_NONE; direction <= DIR_EAST; direction++) + s32 memberId; + for (memberId = 0; memberId < MAX_RFU_PLAYERS; memberId++) { - s32 id = UR_PLAYER_SPRITE_ID(playerIdx, direction); + s32 id = UR_PLAYER_SPRITE_ID(leaderId, memberId); spriteIds[id] = CreateObjectSprite(OBJ_EVENT_GFX_MAN_4, id - UR_SPRITE_START_ID, - sUnionRoomPlayerCoords[playerIdx][0] + sFacingDirectionOffsets[direction][0], - sUnionRoomPlayerCoords[playerIdx][1] + sFacingDirectionOffsets[direction][1], + sUnionRoomPlayerCoords[leaderId][0] + sUnionRoomGroupOffsets[memberId][0], + sUnionRoomPlayerCoords[leaderId][1] + sUnionRoomGroupOffsets[memberId][1], 3, 1); SetObjectEventSpriteInvisibility(id - UR_SPRITE_START_ID, TRUE); } } -void DestroyGroupMemberSprites(u8 * spriteIds) +void DestroyUnionRoomPlayerSprites(u8 * spriteIds) { s32 i; - for (i = 0; i < UR_PLAYER_SPRITE_ID(MAX_UNION_ROOM_PLAYERS, 0); i++) + for (i = 0; i < NUM_UNION_ROOM_SPRITES; i++) DestroySprite(&gSprites[spriteIds[i]]); } +// Clear the impassable metatiles around the group leaders that get set +// to prevent the player from walking through the group member sprites. void SetTilesAroundUnionRoomPlayersPassable(void) { - s32 i, direction, x, y; - for (i = 0; i < MAX_UNION_ROOM_PLAYERS; i++) + s32 i, memberId, x, y; + for (i = 0; i < MAX_UNION_ROOM_LEADERS; i++) { - for (direction = DIR_NONE; direction <= DIR_EAST; direction++) + for (memberId = 0; memberId < MAX_RFU_PLAYERS; memberId++) { - GetUnionRoomPlayerFacingCoords(i, direction, &x, &y); + GetUnionRoomPlayerCoords(i, memberId, &x, &y); MapGridSetMetatileImpassabilityAt(x, y, FALSE); } } } -static u8 GetNewFacingDirectionForUnionRoomPlayer(u32 direction, u32 playerIdx, struct GFtgtGname * gname) +static u8 GetNewFacingDirectionForUnionRoomPlayer(u32 memberId, u32 leaderId, struct RfuGameData * gameData) { - if (direction != DIR_NONE) - return sNextFacingDirection[direction]; - else if (gname->activity == (ACTIVITY_CHAT | IN_UNION_ROOM)) + if (memberId) // If not leader + return sMemberFacingDirections[memberId]; + else if (gameData->activity == (ACTIVITY_CHAT | IN_UNION_ROOM)) return DIR_SOUTH; else return DIR_EAST; } -static bool32 IsUnionRoomPlayerInvisible(u32 playerIdx, u32 direction) +static bool32 IsUnionRoomPlayerInvisible(u32 leaderId, u32 memberId) { - return IsObjectEventSpriteInvisible(UR_PLAYER_SPRITE_ID(playerIdx, direction) - UR_SPRITE_START_ID); + return IsObjectEventSpriteInvisible(UR_PLAYER_SPRITE_ID(leaderId, memberId) - UR_SPRITE_START_ID); } -static void SpawnGroupMember(u32 playerIdx, u32 direction, u8 graphicsId, struct GFtgtGname * gname) +static void SpawnGroupMember(u32 leaderId, u32 memberId, u8 graphicsId, struct RfuGameData * gameData) { s32 x, y; - s32 id = UR_PLAYER_SPRITE_ID(playerIdx, direction); - if (IsUnionRoomPlayerInvisible(playerIdx, direction) == TRUE) + s32 id = UR_PLAYER_SPRITE_ID(leaderId, memberId); + if (IsUnionRoomPlayerInvisible(leaderId, memberId) == TRUE) { SetObjectEventSpriteInvisibility(id - UR_SPRITE_START_ID, FALSE); SetObjectEventSpriteAnim(id - UR_SPRITE_START_ID, UNION_ROOM_SPAWN_IN); } SetObjectEventSpriteGraphics(id - UR_SPRITE_START_ID, graphicsId); - SetUnionRoomObjectFacingDirection(direction, playerIdx, GetNewFacingDirectionForUnionRoomPlayer(direction, playerIdx, gname)); - GetUnionRoomPlayerFacingCoords(playerIdx, direction, &x, &y); + SetUnionRoomObjectFacingDirection(memberId, leaderId, GetNewFacingDirectionForUnionRoomPlayer(memberId, leaderId, gameData)); + GetUnionRoomPlayerCoords(leaderId, memberId, &x, &y); MapGridSetMetatileImpassabilityAt(x, y, TRUE); } -static void DespawnGroupMember(u32 playerIdx, u32 direction) +static void DespawnGroupMember(u32 leaderId, u32 memberId) { s32 x, y; - SetObjectEventSpriteAnim(UR_PLAYER_SPRITE_ID(playerIdx, direction) - UR_SPRITE_START_ID, UNION_ROOM_SPAWN_OUT); - GetUnionRoomPlayerFacingCoords(playerIdx, direction, &x, &y); + SetObjectEventSpriteAnim(UR_PLAYER_SPRITE_ID(leaderId, memberId) - UR_SPRITE_START_ID, UNION_ROOM_SPAWN_OUT); + GetUnionRoomPlayerCoords(leaderId, memberId, &x, &y); MapGridSetMetatileImpassabilityAt(x, y, FALSE); } -static void AssembleGroup(u32 playerIdx, struct GFtgtGname * gname) +static void AssembleGroup(u32 leaderId, struct RfuGameData * gameData) { s16 x, y, x2, y2; s32 i; PlayerGetDestCoords(&x, &y); player_get_pos_including_state_based_drift(&x2, &y2); - if (IsObjectEventSpriteInvisible(UR_PLAYER_SPRITE_ID(playerIdx, 0) - UR_SPRITE_START_ID) == TRUE) + if (IsObjectEventSpriteInvisible(UR_PLAYER_SPRITE_ID(leaderId, 0) - UR_SPRITE_START_ID) == TRUE) { - if (IsUnionRoomPlayerFacingTileAt(playerIdx, 0, x, y) == TRUE || IsUnionRoomPlayerFacingTileAt(playerIdx, 0, x2, y2) == TRUE) - { + if (IsUnionRoomPlayerAt(leaderId, 0, x, y) == TRUE || IsUnionRoomPlayerAt(leaderId, 0, x2, y2) == TRUE) return; - } - SpawnGroupMember(playerIdx, 0, GetUnionRoomPlayerGraphicsId(gname->playerGender, gname->unk_00.playerTrainerId[0]), gname); + SpawnGroupMember(leaderId, 0, GetUnionRoomPlayerGraphicsId(gameData->playerGender, gameData->compatibility.playerTrainerId[0]), gameData); } - for (i = 1; i < 5; i++) + for (i = 1; i < MAX_RFU_PLAYERS; i++) { - if (gname->child_sprite_gender[i - 1] == 0) + if (gameData->partnerInfo[i - 1] == 0) { - DespawnGroupMember(playerIdx, i); + DespawnGroupMember(leaderId, i); } - else if (IsUnionRoomPlayerFacingTileAt(playerIdx, i, x, y) == FALSE && IsUnionRoomPlayerFacingTileAt(playerIdx, i, x2, y2) == FALSE) + else if (IsUnionRoomPlayerAt(leaderId, i, x, y) == FALSE && IsUnionRoomPlayerAt(leaderId, i, x2, y2) == FALSE) { - SpawnGroupMember(playerIdx, i, GetUnionRoomPlayerGraphicsId((gname->child_sprite_gender[i - 1] >> 3) & 1, gname->child_sprite_gender[i - 1] & 7), gname); + SpawnGroupMember(leaderId, i, GetUnionRoomPlayerGraphicsId((gameData->partnerInfo[i - 1] >> PINFO_GENDER_SHIFT) & 1, + gameData->partnerInfo[i - 1] & PINFO_TID_MASK), + gameData); } } } -static void SpawnGroupLeaderAndMembers(u32 playerIdx, struct GFtgtGname * gname) +static void SpawnGroupLeaderAndMembers(u32 leaderId, struct RfuGameData * gameData) { u32 i; - switch (gname->activity) + switch (gameData->activity) { case ACTIVITY_NONE | IN_UNION_ROOM: case ACTIVITY_PLYRTALK | IN_UNION_ROOM: - SpawnGroupLeader(playerIdx, gname->playerGender, gname->unk_00.playerTrainerId[0]); - for (i = 0; i < 5; i++) - { - DespawnGroupMember(playerIdx, i); - } + SpawnGroupLeader(leaderId, gameData->playerGender, gameData->compatibility.playerTrainerId[0]); + for (i = 0; i < MAX_RFU_PLAYERS; i++) + DespawnGroupMember(leaderId, i); break; case ACTIVITY_BATTLE_SINGLE | IN_UNION_ROOM: case ACTIVITY_TRADE | IN_UNION_ROOM: @@ -528,37 +515,31 @@ static void SpawnGroupLeaderAndMembers(u32 playerIdx, struct GFtgtGname * gname) case ACTIVITY_ACCEPT | IN_UNION_ROOM: case ACTIVITY_DECLINE | IN_UNION_ROOM: case ACTIVITY_NPCTALK | IN_UNION_ROOM: - DespawnGroupLeader(playerIdx); - AssembleGroup(playerIdx, gname); + DespawnGroupLeader(leaderId); + AssembleGroup(leaderId, gameData); break; } } -static void DespawnGroupLeaderAndMembers(u32 r5, struct GFtgtGname *gname) +static void DespawnGroupLeaderAndMembers(u32 leaderId, struct RfuGameData *gameData) { s32 i; - DespawnGroupLeader(r5); - for (i = 0; i < 5; i++) - { - DespawnGroupMember(r5, i); - } + DespawnGroupLeader(leaderId); + for (i = 0; i < MAX_RFU_PLAYERS; i++) + DespawnGroupMember(leaderId, i); } static void UpdateUnionRoomPlayerSprites(struct WirelessLink_URoom *uroom) { s32 i; - struct UnkStruct_x20 * r4; + struct RfuPlayer * leaders; sUnionObjRefreshTimer = 0; - for (i = 0, r4 = uroom->field_0->arr; i < MAX_UNION_ROOM_PLAYERS; i++) + for (i = 0, leaders = uroom->playerList->players; i < MAX_UNION_ROOM_LEADERS; i++) { - if (r4[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN) - { - SpawnGroupLeaderAndMembers(i, &r4[i].gname_uname.gname); - } - else if (r4[i].groupScheduledAnim == UNION_ROOM_SPAWN_OUT) - { - DespawnGroupLeaderAndMembers(i, &r4[i].gname_uname.gname); - } + if (leaders[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN) + SpawnGroupLeaderAndMembers(i, &leaders[i].rfu.data); + else if (leaders[i].groupScheduledAnim == UNION_ROOM_SPAWN_OUT) + DespawnGroupLeaderAndMembers(i, &leaders[i].rfu.data); } } @@ -570,64 +551,56 @@ void ScheduleUnionRoomPlayerRefresh(struct WirelessLink_URoom *uroom) void HandleUnionRoomPlayerRefresh(struct WirelessLink_URoom *uroom) { if (++sUnionObjRefreshTimer > 300) - { UpdateUnionRoomPlayerSprites(uroom); - } } -bool32 TryInteractWithUnionRoomMember(struct UnkStruct_Main0 *main0, s16 *directionPtr, s16 *playerIdxPtr, u8 *spriteIds) +bool32 TryInteractWithUnionRoomMember(struct RfuPlayerList *list, s16 *memberIdPtr, s16 *leaderIdPtr, u8 *spriteIds) { s16 x, y; - s32 i, direction; - struct UnkStruct_x20 * r4; + s32 i, memberId; + struct RfuPlayer * leaders; if (!IsPlayerStandingStill()) - { return FALSE; - } + GetXYCoordsOneStepInFrontOfPlayer(&x, &y); - for (i = 0, r4 = main0->arr; i < MAX_UNION_ROOM_PLAYERS; i++) + for (i = 0, leaders = list->players; i < MAX_UNION_ROOM_LEADERS; i++) { - for (direction = DIR_NONE; direction <= DIR_EAST; direction++) + for (memberId = 0; memberId < MAX_RFU_PLAYERS; memberId++) { - s32 id = UR_PLAYER_SPRITE_ID(i, direction); - if (x != sUnionRoomPlayerCoords[i][0] + sFacingDirectionOffsets[direction][0] + 7) - { + s32 id = UR_PLAYER_SPRITE_ID(i, memberId); + + // Is the player in front of a group member position? + if (x != sUnionRoomPlayerCoords[i][0] + sUnionRoomGroupOffsets[memberId][0] + 7) continue; - } - if (y != sUnionRoomPlayerCoords[i][1] + sFacingDirectionOffsets[direction][1] + 7) - { + if (y != sUnionRoomPlayerCoords[i][1] + sUnionRoomGroupOffsets[memberId][1] + 7) continue; - } + + // Has a group member spawned at this position? if (IsObjectEventSpriteInvisible(id - UR_SPRITE_START_ID)) - { continue; - } if (IsObjectEventSpriteAnimating(id - UR_SPRITE_START_ID)) - { continue; - } - if (r4[i].groupScheduledAnim != UNION_ROOM_SPAWN_IN) - { + if (leaders[i].groupScheduledAnim != UNION_ROOM_SPAWN_IN) continue; - } - // Face player - SetUnionRoomObjectFacingDirection(direction, i, sOppositeFacingDirection[GetPlayerFacingDirection()]); - *directionPtr = direction; - *playerIdxPtr = i; + + // Interaction attempt successful, face player + SetUnionRoomObjectFacingDirection(memberId, i, sOppositeFacingDirection[GetPlayerFacingDirection()]); + *memberIdPtr = memberId; + *leaderIdPtr = i; return TRUE; } } return FALSE; } -static void SetUnionRoomObjectFacingDirection(s32 currDirection, s32 playerIdx, u8 newDirection) +static void SetUnionRoomObjectFacingDirection(s32 memberId, s32 leaderId, u8 newDirection) { - TurnObjectEventSprite(5 * playerIdx - UR_SPRITE_START_ID + currDirection, newDirection); + TurnObjectEventSprite(MAX_RFU_PLAYERS * leaderId - UR_SPRITE_START_ID + memberId, newDirection); // should be line below, but order is swapped here - // TurnObjectEventSprite(UR_PLAYER_SPRITE_ID(playerIdx, currDirection) - UR_SPRITE_START_ID, newDirection); + // TurnObjectEventSprite(UR_PLAYER_SPRITE_ID(leaderId, memberId) - UR_SPRITE_START_ID, newDirection); } -void UpdateUnionRoomMemberFacing(u32 currDirection, u32 playerIdx, struct UnkStruct_Main0 *main0) +void UpdateUnionRoomMemberFacing(u32 memberId, u32 leaderId, struct RfuPlayerList *list) { - return SetUnionRoomObjectFacingDirection(currDirection, playerIdx, GetNewFacingDirectionForUnionRoomPlayer(currDirection, playerIdx, &main0->arr[playerIdx].gname_uname.gname)); + return SetUnionRoomObjectFacingDirection(memberId, leaderId, GetNewFacingDirectionForUnionRoomPlayer(memberId, leaderId, &list->players[leaderId].rfu.data)); } diff --git a/src/wireless_communication_status_screen.c b/src/wireless_communication_status_screen.c index a58444f36..5c5272a44 100644 --- a/src/wireless_communication_status_screen.c +++ b/src/wireless_communication_status_screen.c @@ -114,8 +114,8 @@ static const u8 sActivityGroupInfo[][3] = { {ACTIVITY_BATTLE_DOUBLE, GROUPTYPE_BATTLE, 2}, {ACTIVITY_BATTLE_MULTI, GROUPTYPE_BATTLE, 4}, {ACTIVITY_TRADE, GROUPTYPE_TRADE, 2}, - {ACTIVITY_WONDER_CARD, GROUPTYPE_TOTAL, 2}, - {ACTIVITY_WONDER_NEWS, GROUPTYPE_TOTAL, 2}, + {ACTIVITY_WONDER_CARD_DUP, GROUPTYPE_TOTAL, 2}, + {ACTIVITY_WONDER_NEWS_DUP, GROUPTYPE_TOTAL, 2}, {ACTIVITY_POKEMON_JUMP, GROUPTYPE_TOTAL, 0}, {ACTIVITY_BERRY_CRUSH, GROUPTYPE_TOTAL, 0}, {ACTIVITY_BERRY_PICK, GROUPTYPE_TOTAL, 0}, @@ -132,8 +132,8 @@ static const u8 sActivityGroupInfo[][3] = { {ACTIVITY_NPCTALK | IN_UNION_ROOM, GROUPTYPE_UNION, 2}, {ACTIVITY_ACCEPT | IN_UNION_ROOM, GROUPTYPE_UNION, 1}, {ACTIVITY_DECLINE | IN_UNION_ROOM, GROUPTYPE_UNION, 1}, - {ACTIVITY_WONDER_CARD2, GROUPTYPE_TOTAL, 2}, - {ACTIVITY_WONDER_NEWS2, GROUPTYPE_TOTAL, 2}, + {ACTIVITY_WONDER_CARD, GROUPTYPE_TOTAL, 2}, + {ACTIVITY_WONDER_NEWS, GROUPTYPE_TOTAL, 2}, {ACTIVITY_CONTEST_COOL, GROUPTYPE_TOTAL, 0}, {ACTIVITY_CONTEST_BEAUTY, GROUPTYPE_TOTAL, 0}, {ACTIVITY_CONTEST_CUTE, GROUPTYPE_TOTAL, 0}, @@ -347,10 +347,10 @@ static void WCSS_AddTextPrinterParameterized(u8 windowId, u8 fontId, const u8 * AddTextPrinterParameterized4(windowId, fontId, x, y, 0, 0, color, -1, str); } -static u32 CountPlayersInGroupAndGetActivity(struct UnkStruct_x20 * unk20, u32 * groupCounts) +static u32 CountPlayersInGroupAndGetActivity(struct RfuPlayer * player, u32 * groupCounts) { int i, j, k; - u32 activity = unk20->gname_uname.gname.activity; + u32 activity = player->rfu.data.activity; #define group_activity(i) (sActivityGroupInfo[(i)][0]) #define group_type(i) (sActivityGroupInfo[(i)][1]) @@ -358,15 +358,13 @@ static u32 CountPlayersInGroupAndGetActivity(struct UnkStruct_x20 * unk20, u32 * for (i = 0; i < ARRAY_COUNT(sActivityGroupInfo); i++) { - if (activity == group_activity(i) && unk20->groupScheduledAnim == UNION_ROOM_SPAWN_IN) + if (activity == group_activity(i) && player->groupScheduledAnim == UNION_ROOM_SPAWN_IN) { if (group_players(i) == 0) { k = 0; for (j = 0; j < RFU_CHILD_MAX; j++) - { - if (unk20->gname_uname.gname.child_sprite_gender[j] != 0) k++; - } + if (player->rfu.data.partnerInfo[j] != 0) k++; k++; groupCounts[group_type(i)] += k; } @@ -398,12 +396,12 @@ static bool32 UpdateCommunicationCounts(u32 * groupCounts, u32 * prevGroupCounts { bool32 activitiesChanged = FALSE; u32 groupCountBuffer[NUM_GROUPTYPES] = {0, 0, 0, 0}; - struct UnkStruct_x20 ** data = (void *)gTasks[taskId].data; + struct RfuPlayer ** players = (void *)gTasks[taskId].data; s32 i; for (i = 0; i < NUM_TASK_DATA; i++) { - u32 activity = CountPlayersInGroupAndGetActivity(&(*data)[i], groupCountBuffer); + u32 activity = CountPlayersInGroupAndGetActivity(&(*players)[i], groupCountBuffer); if (activity != activities[i]) { activities[i] = activity;