diff options
Diffstat (limited to 'include/link.h')
-rw-r--r-- | include/link.h | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/include/link.h b/include/link.h new file mode 100644 index 000000000..1f91ebfeb --- /dev/null +++ b/include/link.h @@ -0,0 +1,198 @@ +#ifndef GUARD_LINK_H +#define GUARD_LINK_H + +#define MAX_LINK_PLAYERS 4 +#define MAX_RFU_PLAYERS 5 +#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; // battle bank in battles + /* 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[MAX_RFU_PLAYERS][CMD_LENGTH]; +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; +extern bool8 gLinkVSyncDisabled; + +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 RFUVSync(void); +void Timer3Intr(void); +void SerialCB(void); +u8 GetLinkPlayerCount(void); +bool32 InUnionRoom(void); + +void sub_800E0E8(void); +bool8 sub_800A520(void); +bool8 sub_8010500(void); +void sub_800DFB4(u8, u8); +void sub_800ADF8(void); +void sub_800B488(void); +void sub_8009734(void); +void sub_800A620(void); +void sub_8011BD0(void); +u8 sub_800ABAC(void); +u8 sub_800ABBC(void); +void sub_800AC34(void); + +#endif // GUARD_LINK_H |