2017-09-11 11:35:41 +02:00
|
|
|
#ifndef GUARD_LINK_H
|
|
|
|
#define GUARD_LINK_H
|
|
|
|
|
|
|
|
#define MAX_LINK_PLAYERS 4
|
|
|
|
#define CMD_LENGTH 8
|
|
|
|
#define QUEUE_CAPACITY 50
|
|
|
|
#define BLOCK_BUFFER_SIZE 0x100
|
|
|
|
|
|
|
|
#define LINK_STAT_LOCAL_ID 0x00000003
|
|
|
|
#define LINK_STAT_PLAYER_COUNT 0x0000001C
|
|
|
|
#define LINK_STAT_PLAYER_COUNT_SHIFT 2
|
|
|
|
#define LINK_STAT_MASTER 0x00000020
|
|
|
|
#define LINK_STAT_MASTER_SHIFT 5
|
|
|
|
#define LINK_STAT_CONN_ESTABLISHED 0x00000040
|
|
|
|
#define LINK_STAT_CONN_ESTABLISHED_SHIFT 6
|
|
|
|
#define LINK_STAT_RECEIVED_NOTHING 0x00000100
|
|
|
|
#define LINK_STAT_RECEIVED_NOTHING_SHIFT 8
|
|
|
|
#define LINK_STAT_ERRORS 0x0007F000
|
|
|
|
|
|
|
|
#define EXTRACT_PLAYER_COUNT(status) \
|
|
|
|
(((status) & LINK_STAT_PLAYER_COUNT) >> LINK_STAT_PLAYER_COUNT_SHIFT)
|
|
|
|
#define EXTRACT_MASTER(status) \
|
|
|
|
(((status) >> LINK_STAT_MASTER_SHIFT) & 1)
|
|
|
|
#define EXTRACT_CONN_ESTABLISHED(status) \
|
|
|
|
(((status) >> LINK_STAT_CONN_ESTABLISHED_SHIFT) & 1)
|
|
|
|
#define EXTRACT_RECEIVED_NOTHING(status) \
|
|
|
|
(((status) >> LINK_STAT_RECEIVED_NOTHING_SHIFT) & 1)
|
|
|
|
|
|
|
|
#define MASTER_HANDSHAKE 0x8FFF
|
|
|
|
#define SLAVE_HANDSHAKE 0xB9A0
|
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
LINK_STATE_START0,
|
|
|
|
LINK_STATE_START1,
|
|
|
|
LINK_STATE_HANDSHAKE,
|
|
|
|
LINK_STATE_INIT_TIMER,
|
|
|
|
LINK_STATE_CONN_ESTABLISHED,
|
|
|
|
};
|
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
EXCHANGE_NOT_STARTED,
|
|
|
|
EXCHANGE_COMPLETE,
|
|
|
|
EXCHANGE_TIMED_OUT,
|
|
|
|
EXCHANGE_IN_PROGRESS,
|
|
|
|
};
|
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
QUEUE_FULL_NONE,
|
|
|
|
QUEUE_FULL_SEND,
|
|
|
|
QUEUE_FULL_RECV,
|
|
|
|
};
|
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
LAG_NONE,
|
|
|
|
LAG_MASTER,
|
|
|
|
LAG_SLAVE,
|
|
|
|
};
|
|
|
|
|
|
|
|
struct LinkPlayer
|
|
|
|
{
|
|
|
|
/* 0x00 */ u16 version;
|
|
|
|
/* 0x02 */ u16 lp_field_2;
|
|
|
|
/* 0x04 */ u32 trainerId;
|
|
|
|
/* 0x08 */ u8 name[11];
|
|
|
|
/* 0x13 */ u8 gender;
|
|
|
|
/* 0x14 */ u32 linkType;
|
|
|
|
/* 0x18 */ u16 lp_field_18;
|
|
|
|
/* 0x1A */ u16 language;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct LinkPlayerBlock
|
|
|
|
{
|
|
|
|
u8 magic1[16];
|
|
|
|
struct LinkPlayer linkPlayer;
|
|
|
|
u8 magic2[16];
|
|
|
|
};
|
|
|
|
|
|
|
|
// circular queues
|
|
|
|
|
|
|
|
struct SendQueue
|
|
|
|
{
|
|
|
|
u16 data[CMD_LENGTH][QUEUE_CAPACITY];
|
|
|
|
u8 pos;
|
|
|
|
u8 count;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct RecvQueue
|
|
|
|
{
|
|
|
|
u16 data[MAX_LINK_PLAYERS][CMD_LENGTH][QUEUE_CAPACITY];
|
|
|
|
u8 pos;
|
|
|
|
u8 count;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Link
|
|
|
|
{
|
|
|
|
u8 isMaster; // 0: slave, 8: master
|
|
|
|
u8 state;
|
|
|
|
u8 localId; // local multi-player ID
|
|
|
|
u8 playerCount;
|
|
|
|
u16 tempRecvBuffer[4];
|
|
|
|
bool8 receivedNothing;
|
|
|
|
s8 serialIntrCounter;
|
|
|
|
bool8 handshakeAsMaster;
|
|
|
|
u8 link_field_F;
|
|
|
|
|
|
|
|
// error conditions
|
|
|
|
bool8 hardwareError; // hardware reported an error
|
|
|
|
bool8 badChecksum; // checksum didn't match between devices
|
|
|
|
u8 queueFull; // send or recv queue out of space
|
|
|
|
u8 lag; // connection is lagging
|
|
|
|
|
|
|
|
u16 checksum;
|
|
|
|
|
|
|
|
u8 sendCmdIndex;
|
|
|
|
u8 recvCmdIndex;
|
|
|
|
|
|
|
|
struct SendQueue sendQueue;
|
|
|
|
struct RecvQueue recvQueue;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct BlockRequest
|
|
|
|
{
|
|
|
|
void * address;
|
|
|
|
u32 size;
|
|
|
|
};
|
|
|
|
|
|
|
|
extern const struct BlockRequest sBlockRequestLookupTable[5];
|
|
|
|
|
|
|
|
extern struct Link gLink;
|
|
|
|
extern u16 gRecvCmds[CMD_LENGTH][MAX_LINK_PLAYERS];
|
2017-11-08 03:45:44 +01:00
|
|
|
extern u8 gUnknown_020228C4[BLOCK_BUFFER_SIZE]; // gBlockSendBuffer
|
2017-09-11 11:35:41 +02:00
|
|
|
extern u8 gBlockSendBuffer[BLOCK_BUFFER_SIZE];
|
|
|
|
extern u16 gLinkType;
|
|
|
|
extern u32 gLinkStatus;
|
|
|
|
extern u16 gBlockRecvBuffer[MAX_LINK_PLAYERS][BLOCK_BUFFER_SIZE / 2];
|
|
|
|
extern u16 gSendCmd[CMD_LENGTH];
|
|
|
|
extern u8 gShouldAdvanceLinkState;
|
|
|
|
extern struct LinkPlayer gLinkPlayers[];
|
|
|
|
extern u16 word_3002910[];
|
|
|
|
extern bool8 gReceivedRemoteLinkPlayers;
|
2017-10-13 17:22:50 +02:00
|
|
|
extern bool8 gLinkVSyncDisabled;
|
2017-09-11 11:35:41 +02:00
|
|
|
|
|
|
|
void Task_DestroySelf(u8);
|
|
|
|
void OpenLink(void);
|
|
|
|
void CloseLink(void);
|
|
|
|
u16 LinkMain2(u16 *);
|
|
|
|
void sub_8007B14(void);
|
|
|
|
bool32 sub_8007B24(void);
|
|
|
|
void ClearLinkCallback(void);
|
|
|
|
void ClearLinkCallback_2(void);
|
|
|
|
u8 GetLinkPlayerCount(void);
|
|
|
|
void OpenLinkTimed(void);
|
|
|
|
u8 GetLinkPlayerDataExchangeStatusTimed(void);
|
|
|
|
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);
|
|
|
|
bool8 SendBlock(u8, void *, u16);
|
|
|
|
u8 GetBlockReceivedStatus(void);
|
|
|
|
void ResetBlockReceivedFlags(void);
|
|
|
|
void ResetBlockReceivedFlag(u8);
|
|
|
|
void SetLinkDebugValues(u32, u32);
|
|
|
|
u8 GetLinkPlayerCount_2(void);
|
|
|
|
bool8 IsLinkMaster(void);
|
|
|
|
void CB2_LinkError(void);
|
|
|
|
u8 GetSioMultiSI(void);
|
|
|
|
bool8 IsLinkConnectionEstablished(void);
|
|
|
|
void SetSuppressLinkErrorMessage(bool8);
|
|
|
|
bool8 HasLinkErrorOccurred(void);
|
|
|
|
void ResetSerial(void);
|
|
|
|
u32 LinkMain1(u8 *, u16 *, u16[CMD_LENGTH][MAX_LINK_PLAYERS]);
|
|
|
|
void LinkVSync(void);
|
|
|
|
void Timer3Intr(void);
|
|
|
|
void SerialCB(void);
|
2017-10-13 17:09:36 +02:00
|
|
|
u8 GetLinkPlayerCount(void);
|
2017-09-11 11:35:41 +02:00
|
|
|
|
2017-10-01 01:12:42 +02:00
|
|
|
void sub_800E0E8(void);
|
|
|
|
bool8 sub_800A520(void);
|
|
|
|
bool8 sub_8010500(void);
|
|
|
|
void sub_800DFB4(u8, u8);
|
2017-10-01 18:54:01 +02:00
|
|
|
void sub_800ADF8(void);
|
2017-10-13 17:22:50 +02:00
|
|
|
void sub_800B488(void);
|
|
|
|
void sub_8009734(void);
|
|
|
|
void sub_800A620(void);
|
|
|
|
void sub_8011BD0(void);
|
|
|
|
u8 sub_800ABAC(void);
|
|
|
|
u8 sub_800ABBC(void);
|
2017-10-22 18:43:15 +02:00
|
|
|
void sub_800AC34(void);
|
2017-10-01 01:12:42 +02:00
|
|
|
|
2017-11-08 02:25:24 +01:00
|
|
|
void sub_80097E8(void);
|
|
|
|
|
2017-11-08 04:14:40 +01:00
|
|
|
extern IWRAM_DATA struct LinkTestBGInfo gUnknown_03003130; // common
|
2017-11-08 02:25:24 +01:00
|
|
|
|
2017-09-11 11:35:41 +02:00
|
|
|
#endif // GUARD_LINK_H
|