summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/AgbRfu_LinkManager.h75
-rw-r--r--include/constants/union_room.h24
-rw-r--r--include/link.h36
-rw-r--r--include/link_rfu.h254
-rw-r--r--include/reload_save.h6
-rw-r--r--include/reset_save_heap.h12
-rw-r--r--include/save.h3
-rw-r--r--include/trade.h4
-rw-r--r--include/union_room.h112
-rw-r--r--include/union_room_player_avatar.h8
10 files changed, 281 insertions, 253 deletions
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/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..df2b80c4f 100644
--- a/include/link_rfu.h
+++ b/include/link_rfu.h
@@ -5,20 +5,25 @@
#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 RECV_QUEUE_NUM_SLOTS 32
#define RECV_QUEUE_SLOT_LENGTH (14 * MAX_RFU_PLAYERS)
@@ -41,12 +46,44 @@
#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
+#define CHILD_DATA_LENGTH 14
+
+// 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 +93,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
{
@@ -113,27 +167,28 @@ struct RfuBackupQueue
/* 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][CHILD_DATA_LENGTH];
+ /* 0x04c */ u8 childSendBuffer[CHILD_DATA_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 +199,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[RECV_QUEUE_SLOT_LENGTH];
+ /* 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 +265,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 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 +328,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
-
-struct WirelessGnameUnamePair
+// 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)
+
+// 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