From 8a793e73a515e9c66aa98ef6c14e923b18dd4ce3 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Fri, 19 Aug 2022 15:22:32 -0400 Subject: [PATCH 1/8] Sync link_rfu_2 --- common_syms/link_rfu_2.txt | 4 +- include/link_rfu.h | 28 +++++----- include/trade.h | 4 +- include/union_room.h | 4 +- src/link_rfu_2.c | 102 ++++++++++++++++++------------------- src/link_rfu_3.c | 12 ++--- src/party_menu.c | 4 +- src/rfu_union_tool.c | 10 ++-- src/trade.c | 4 +- src/union_room.c | 10 ++-- 10 files changed, 91 insertions(+), 91 deletions(-) diff --git a/common_syms/link_rfu_2.txt b/common_syms/link_rfu_2.txt index 5e6f69ff6..abd9a5f93 100644 --- a/common_syms/link_rfu_2.txt +++ b/common_syms/link_rfu_2.txt @@ -1,3 +1,3 @@ -gHostRFUtgtGnameBuffer +gHostRfuGameData Rfu -gHostRFUtgtUnameBuffer +gHostRfuUsername diff --git a/include/link_rfu.h b/include/link_rfu.h index 1792781ff..1e4a72c6c 100644 --- a/include/link_rfu.h +++ b/include/link_rfu.h @@ -57,7 +57,7 @@ #define RFU_RECV_FINISHED 2 // RfuTgtData.gname is read as these structs. -struct GFtgtGnameSub +struct RfuGameCompatibilityData { u16 language:4; u16 hasNews:1; @@ -71,9 +71,9 @@ struct GFtgtGnameSub u8 playerTrainerId[2]; }; -struct __attribute__((packed, aligned(2))) GFtgtGname +struct __attribute__((packed, aligned(2))) RfuGameData { - struct GFtgtGnameSub unk_00; + struct RfuGameCompatibilityData unk_00; u8 child_sprite_gender[RFU_CHILD_MAX]; // u8 sprite_idx:3; // u8 gender:1; // u8 unk_4:3 @@ -139,7 +139,7 @@ struct RfuUnusedQueue /* 0x203 */ vu8 full; }; -typedef struct UnkRfuStruct_2 +struct RfuManager { /* 0x000 */ void (*RfuFunc)(void); /* 0x004 */ u16 state; @@ -204,11 +204,11 @@ typedef struct UnkRfuStruct_2 /* 0x9a1 */ u8 unk_ce9; /* 0x9a2 */ u8 unk_cea[RFU_CHILD_MAX]; /* 0x9a6 */ u8 unk_cee[RFU_CHILD_MAX]; -} GF_RFU_MANAGER; // size: 0x9AC +}; // size: 0x9AC -extern struct GFtgtGname gHostRFUtgtGnameBuffer; -extern u8 gHostRFUtgtUnameBuffer[]; -extern GF_RFU_MANAGER Rfu; +extern struct RfuGameData gHostRfuGameData; +extern u8 gHostRfuUsername[]; +extern struct RfuManager Rfu; // GameFreak signatures void AddTextPrinterToWindow1(const u8 *str); @@ -246,7 +246,7 @@ void LinkRfu_Shutdown(void); void LinkRfu_CreateIdleTask(void); bool8 ToggleLMANlinkRecovery(bool32 enable); void var_800D_set_xB(void); -struct GFtgtGname *GetHostRFUtgtGname(void); +struct RfuGameData *GetHostRFUtgtGname(void); void UpdateWirelessStatusIndicatorSprite(void); void InitRFU(void); bool32 RfuHasErrored(void); @@ -262,7 +262,7 @@ bool8 RfuBackupQueue_Dequeue(struct RfuBackupQueue *queue, u8 *dest); void RfuBackupQueue_Enqueue(struct RfuBackupQueue *queue, const u8 *dest); bool8 RfuRecvQueue_Dequeue(struct RfuRecvQueue * queue, u8 *dest); void RfuSendQueue_Enqueue(struct RfuSendQueue * queue, u8 *src); -void InitHostRFUtgtGname(struct GFtgtGname *data, u8 activity, bool32 started, s32 child_sprite_genders); +void InitHostRFUtgtGname(struct RfuGameData *data, u8 activity, bool32 started, s32 child_sprite_genders); void UpdateGameData_GroupLockedIn(bool8 started); bool32 IsRfuSerialNumberValid(u32 serialNo); bool8 IsRfuRecoveringFromLinkLoss(void); @@ -277,7 +277,7 @@ u32 WaitSendByteToPartnerByIdAndName(u16 a0, const u8 *a1); void SetHostRFUtgtGname(u8 activity, u32 child_sprite_genders, u32 a2); void InitializeRfuLinkManager_LinkLeader(u32 availSlots); void RequestDisconnectSlotByTrainerNameAndId(const u8 *trainerName, u16 trainerId); -void LinkRfu3_SetGnameUnameFromStaticBuffers(struct GFtgtGname *gname, u8 *uname); +void LinkRfu3_SetGnameUnameFromStaticBuffers(struct RfuGameData *gname, u8 *uname); void InitializeRfuLinkManager_JoinGroup(void); void SendLeaveGroupNotice(void); void CreateTask_RfuReconnectWithParent(const u8 *src, u16 trainerId); @@ -292,10 +292,10 @@ void RfuUpdatePlayerGnameStateAndSend(u32 type, u32 species, u32 level); bool32 IsUnionRoomListenTaskActive(void); void InitializeRfuLinkManager_EnterUnionRoom(void); void sub_80FBD6C(u32 a0); -void sub_80FC114(const u8 *name, struct GFtgtGname *structPtr, u8 a2); +void sub_80FC114(const u8 *name, struct RfuGameData *structPtr, u8 a2); bool32 PlayerHasMetTrainerBefore(u16 id, u8 *name); -bool8 LinkRfu_GetNameIfCompatible(struct GFtgtGname *gname, u8 *uname, u8 idx); -bool8 LinkRfu_GetNameIfSerial7F7D(struct GFtgtGname *gname, u8 *uname, u8 idx); +bool8 LinkRfu_GetNameIfCompatible(struct RfuGameData *gname, u8 *uname, u8 idx); +bool8 LinkRfu_GetNameIfSerial7F7D(struct RfuGameData *gname, u8 *uname, u8 idx); bool32 RfuHasFoundNewLeader(void); void Rfu_UnionRoomChat_StopLinkManager(void); void sub_80FB9D0(void); diff --git a/include/trade.h b/include/trade.h index 036c470a1..ede68b05d 100644 --- a/include/trade.h +++ b/include/trade.h @@ -15,8 +15,8 @@ extern const u8 gText_GenderlessSymbol[]; extern const u16 gTradeOrHatchMonShadowTilemap[]; void CB2_ReturnFromLinkTrade(void); s32 Trade_CalcLinkPlayerCompatibilityParam(void); -s32 CanRegisterMonForTradingBoard(struct GFtgtGnameSub rfuPlayer, u16 species2, u16 species, u8 isEventLegal); -s32 GetUnionRoomTradeMessageId(struct GFtgtGnameSub rfuPlayer, struct GFtgtGnameSub rfuPartner, u16 playerSpecies2, u16 partnerSpecies, u8 requestedType, u16 playerSpecies, u8 isEventLegal); +s32 CanRegisterMonForTradingBoard(struct RfuGameCompatibilityData rfuPlayer, u16 species2, u16 species, u8 isEventLegal); +s32 GetUnionRoomTradeMessageId(struct RfuGameCompatibilityData rfuPlayer, struct RfuGameCompatibilityData rfuPartner, u16 playerSpecies2, u16 partnerSpecies, u8 requestedType, u16 playerSpecies, u8 isEventLegal); void CB2_ReturnToTradeMenuFromSummary(void); #endif //GUARD_TRADE_H diff --git a/include/union_room.h b/include/union_room.h index d520e8763..c39513ec2 100644 --- a/include/union_room.h +++ b/include/union_room.h @@ -14,7 +14,7 @@ struct UnionGnameUnamePair { - struct GFtgtGname gname; + struct RfuGameData gname; u8 ALIGNED(4) uname[PLAYER_NAME_LENGTH + 1]; }; @@ -158,7 +158,7 @@ struct UnionRoomTrade u32 personality; }; -extern struct GFtgtGnameSub gPartnerTgtGnameSub; +extern struct RfuGameCompatibilityData gPartnerTgtGnameSub; extern u16 gUnionRoomOfferedSpecies; extern u8 gUnionRoomRequestedMonType; diff --git a/src/link_rfu_2.c b/src/link_rfu_2.c index 2cac8210a..3d5f5b11e 100644 --- a/src/link_rfu_2.c +++ b/src/link_rfu_2.c @@ -13,37 +13,37 @@ struct SioInfo { - char magic[15]; // PokemonSioInfo + char magic[sizeof("PokemonSioInfo")]; u8 playerCount; u8 linkPlayerIdx[RFU_CHILD_MAX]; struct LinkPlayer linkPlayers[MAX_RFU_PLAYERS]; - u8 fill_a0[0x5c]; + u8 filler[92]; }; struct RfuDebug { - u8 fill_00[6]; - u16 unk_06; - u8 fill_08[6]; - vu8 unk_0e; - u8 unk_0f; - u8 fill_10[0x54]; - u16 unk_64; - u8 fill_66[0x1d]; - u8 unk_83; - u8 fill_84[0x58]; + u8 unused0[6]; + u16 recvCount; + u8 unused1[6]; + vu8 unkFlag; + bool8 childJoined; + u8 unused2[84]; + u16 blockSendFailures; + u8 unused3[29]; + u8 blockSendTime; + u8 unused4[88]; }; static EWRAM_DATA INIT_PARAM sRfuReqConfig = {}; static EWRAM_DATA struct RfuDebug sRfuDebug = {}; -static u32 gf_rfu_REQ_api[RFU_API_BUFF_SIZE_RAM / 4]; -static u8 sResendBlock8[14]; -static u16 sResendBlock16[7]; +static u32 sRfuAPIBuffer[RFU_API_BUFF_SIZE_RAM / 4]; +static u8 sResendBlock8[CMD_LENGTH * 2]; +static u16 sResendBlock16[CMD_LENGTH]; -struct GFtgtGname gHostRFUtgtGnameBuffer; -GF_RFU_MANAGER Rfu; -u8 gHostRFUtgtUnameBuffer[PLAYER_NAME_LENGTH + 1]; +struct RfuGameData gHostRfuGameData; +struct RfuManager Rfu; +u8 gHostRfuUsername[PLAYER_NAME_LENGTH + 1]; static void sub_80F8AA4(void); static void sub_80F8AEC(void); @@ -80,8 +80,8 @@ static const INIT_PARAM sRfuReqConfigTemplate = { .availSlot_flag = 0, .mboot_flag = 0, .serialNo = 0x0002, - .gameName = (void *)&gHostRFUtgtGnameBuffer, - .userName = gHostRFUtgtUnameBuffer, + .gameName = (void *)&gHostRfuGameData, + .userName = gHostRfuUsername, .fastSearchParent_flag = TRUE, .linkRecovery_enable = FALSE, .linkRecovery_period = 600, @@ -257,7 +257,7 @@ void InitRFU(void) void InitRFUAPI(void) { - if (!rfu_initializeAPI(gf_rfu_REQ_api, RFU_API_BUFF_SIZE_RAM, gIntrTable + 1, TRUE)) + if (!rfu_initializeAPI(sRfuAPIBuffer, RFU_API_BUFF_SIZE_RAM, gIntrTable + 1, TRUE)) { gLinkType = 0; // ClearSavedLinkPlayers(); // Em fix @@ -402,10 +402,10 @@ static void Task_JoinGroupSearchForParent(u8 taskId) rfu_UNI_setSendData(bmChildSlot, Rfu.lastCmdBeforeCommInterrupt, sizeof(Rfu.lastCmdBeforeCommInterrupt)); gTasks[taskId].data[1] = 8; DestroyTask(taskId); - if (sRfuDebug.unk_0f == 0) + if (!sRfuDebug.childJoined) { Debug_PrintEmpty(); - sRfuDebug.unk_0f++; + sRfuDebug.childJoined++; } CreateTask(sub_80FA834, 5); break; @@ -523,7 +523,7 @@ static void MscCallback_Child(u16 unused) { Rfu.sem_UNI_SendRecv++; RfuRecvQueue_Enqueue(&Rfu.recvQueue, Rfu.unk_c3f); - sRfuDebug.unk_06++; + sRfuDebug.recvCount++; UpdateBackupQueue(); rfu_UNI_readySendData(Rfu.child_slot); rfu_UNI_clearRecvNewDataFlag(Rfu.child_slot); @@ -662,7 +662,7 @@ static void MoveRecvCmdsToRfuBuffer(void) for (i = 0; i < MAX_RFU_PLAYERS; i++) { - GF_RFU_MANAGER *ptr = &Rfu; + struct RfuManager *ptr = &Rfu; for (j = 0; j < CMD_LENGTH - 1; j++) { ptr->recvCmds[i][j][1] = gRecvCmds[i][j] >> 8; @@ -797,7 +797,7 @@ static bool32 sub_80F9204(void) if ((lman.parentAck_flag & Rfu.bm_PartnerFlags) == Rfu.bm_PartnerFlags) { Rfu.unk_cdc = 0; - sRfuDebug.unk_06++; + sRfuDebug.recvCount++; flags = lman.acceptSlot_flag; for (i = 0; i < RFU_CHILD_MAX; i++) { @@ -833,7 +833,7 @@ static bool32 sub_80F9204(void) CallRfuFunc(); if (Rfu.bmChatLeaderMaybe && !Rfu.linkClosing) { - sRfuDebug.unk_0e = FALSE; + sRfuDebug.unkFlag = FALSE; rfu_clearSlot(TYPE_UNI_SEND | TYPE_UNI_RECV, Rfu.unk_cda); for (i = 0; i < RFU_CHILD_MAX; i++) { @@ -1000,9 +1000,9 @@ static void RfuFunc_SendKeysToRfu(void) } } -struct GFtgtGname *GetHostRFUtgtGname(void) +struct RfuGameData *GetHostRFUtgtGname(void) { - return &gHostRFUtgtGnameBuffer; + return &gHostRfuGameData; } bool32 IsSendingKeysToRfu(void) @@ -1239,7 +1239,7 @@ bool32 Rfu_InitBlockSend(const u8 *src, size_t size) return FALSE; if (Rfu.sendBlock.sending != 0) { - sRfuDebug.unk_83++; + sRfuDebug.blockSendTime++; return FALSE; } sizeHasModulo = (size % 12) != 0; @@ -1308,7 +1308,7 @@ static void SendLastBlock(void) if (Rfu.recvBlock[mpId].receivedFlags != sAllBlocksReceived[Rfu.recvBlock[mpId].count]) { HandleSendFailure(mpId, Rfu.recvBlock[mpId].receivedFlags); - sRfuDebug.unk_64++; + sRfuDebug.blockSendFailures++; } else Rfu.RfuFunc = NULL; @@ -1965,44 +1965,44 @@ bool32 LinkRfuMain2(void) static void CopyPlayerNameToUnameBuffer(void) { - StringCopy(gHostRFUtgtUnameBuffer, gSaveBlock2Ptr->playerName); + StringCopy(gHostRfuUsername, gSaveBlock2Ptr->playerName); } void ClearAndInitHostRFUtgtGname(void) { - memset(&gHostRFUtgtGnameBuffer, 0, RFU_GAME_NAME_LENGTH); - InitHostRFUtgtGname(&gHostRFUtgtGnameBuffer, ACTIVITY_NONE, FALSE, 0); + memset(&gHostRfuGameData, 0, RFU_GAME_NAME_LENGTH); + InitHostRFUtgtGname(&gHostRfuGameData, ACTIVITY_NONE, FALSE, 0); } void SetHostRFUtgtGname(u8 activity, u32 child_sprite_genders, u32 started) { - InitHostRFUtgtGname(&gHostRFUtgtGnameBuffer, activity, started, child_sprite_genders); + InitHostRFUtgtGname(&gHostRfuGameData, activity, started, child_sprite_genders); } void SetGnameBufferWonderFlags(bool32 hasNews, bool32 hasCard) { - gHostRFUtgtGnameBuffer.unk_00.hasNews = hasNews; - gHostRFUtgtGnameBuffer.unk_00.hasCard = hasCard; + gHostRfuGameData.unk_00.hasNews = hasNews; + gHostRfuGameData.unk_00.hasCard = hasCard; } void RfuUpdatePlayerGnameStateAndSend(u32 type, u32 species, u32 level) { - gHostRFUtgtGnameBuffer.type = type; - gHostRFUtgtGnameBuffer.species = species; - gHostRFUtgtGnameBuffer.level = level; + gHostRfuGameData.type = type; + gHostRfuGameData.species = species; + gHostRfuGameData.level = level; } void UpdateGameData_GroupLockedIn(bool8 started) { - gHostRFUtgtGnameBuffer.started = started; - rfu_REQ_configGameData(0, 0x0002, (void *)&gHostRFUtgtGnameBuffer, gHostRFUtgtUnameBuffer); + gHostRfuGameData.started = started; + rfu_REQ_configGameData(0, 0x0002, (void *)&gHostRfuGameData, gHostRfuUsername); } void UpdateGameDataWithActivitySpriteGendersFlag(u8 activity, u32 child_sprite_genders, u32 started) { if (activity) SetHostRFUtgtGname(activity, child_sprite_genders, started); - rfu_REQ_configGameData(0, 0x0002, (void *)&gHostRFUtgtGnameBuffer, gHostRFUtgtUnameBuffer); + rfu_REQ_configGameData(0, 0x0002, (void *)&gHostRfuGameData, gHostRfuUsername); } void sub_80FB030(u32 linkPlayerCount) @@ -2086,7 +2086,7 @@ static void LmanCallback_Parent2(u8 msg, u8 param_count) { if ((lman.param[0] >> i) & 1) { - struct GFtgtGname *structPtr = (void *)&gRfuLinkStatus->partner[i].gname; + struct RfuGameData *structPtr = (void *)&gRfuLinkStatus->partner[i].gname; if (structPtr->activity == GetHostRFUtgtGname()->activity) { Rfu.partnerSendStatuses[i] = RFU_STATUS_OK; @@ -2254,7 +2254,7 @@ static u8 GetNewChildrenInUnionRoomChat(s32 bmNewChildSlot) { if ((bmNewChildSlot >> i) & 1) { - struct GFtgtGname *structPtr = (void *)&gRfuLinkStatus->partner[i].gname; + struct RfuGameData *structPtr = (void *)&gRfuLinkStatus->partner[i].gname; if (structPtr->activity == (ACTIVITY_CHAT | IN_UNION_ROOM)) ret |= (1 << i); } @@ -2564,7 +2564,7 @@ static u8 GetPartnerIndexByNameAndTrainerID(const u8 *trainerName, u16 trainerId for (i = 0; i < RFU_CHILD_MAX; i++) { - u16 partnerTrainerId = ReadU16(((struct GFtgtGname *)gRfuLinkStatus->partner[i].gname)->unk_00.playerTrainerId); + u16 partnerTrainerId = ReadU16(((struct RfuGameData *)gRfuLinkStatus->partner[i].gname)->unk_00.playerTrainerId); if (IsRfuSerialNumberValid(gRfuLinkStatus->partner[i].serialNo) && !StringCompare(trainerName, gRfuLinkStatus->partner[i].uname) && trainerId == partnerTrainerId) @@ -2696,7 +2696,7 @@ void CreateTask_RfuReconnectWithParent(const u8 *trainerName, u16 trainerId) data[8] = trainerId; } -static bool32 ShouldRejectPartnerConnectionBasedOnActivity(s16 activity, struct GFtgtGname *partnerGname) +static bool32 ShouldRejectPartnerConnectionBasedOnActivity(s16 activity, struct RfuGameData *partnerGname) { if (GetHostRFUtgtGname()->activity == (ACTIVITY_CHAT | IN_UNION_ROOM)) { @@ -2709,7 +2709,7 @@ static bool32 ShouldRejectPartnerConnectionBasedOnActivity(s16 activity, struct } else if (activity == (ACTIVITY_TRADE | IN_UNION_ROOM)) { - struct GFtgtGname *myTradeGname = (struct GFtgtGname *)&Rfu.tgtData.gname; + struct RfuGameData *myTradeGname = (struct RfuGameData *)&Rfu.tgtData.gname; if (myTradeGname->species == SPECIES_EGG) { if (partnerGname->species == myTradeGname->species) @@ -2741,11 +2741,11 @@ static void sub_80FC028(u8 taskId) if (Rfu.parentId != 0 && lman.parent_child == MODE_CHILD) { - u16 trainerId = ReadU16(((struct GFtgtGname *)&Rfu.tgtData.gname)->unk_00.playerTrainerId); + u16 trainerId = ReadU16(((struct RfuGameData *)&Rfu.tgtData.gname)->unk_00.playerTrainerId); u8 id = GetPartnerIndexByNameAndTrainerID(Rfu.tgtData.uname, trainerId); if (id != 0xFF) { - if (!ShouldRejectPartnerConnectionBasedOnActivity(gTasks[taskId].data[1], (struct GFtgtGname *)&gRfuLinkStatus->partner[id].gname)) + if (!ShouldRejectPartnerConnectionBasedOnActivity(gTasks[taskId].data[1], (struct RfuGameData *)&gRfuLinkStatus->partner[id].gname)) { if (gRfuLinkStatus->partner[id].slot != 0xFF && !rfu_LMAN_CHILD_connectParent(gRfuLinkStatus->partner[id].id, 90)) { @@ -2762,7 +2762,7 @@ static void sub_80FC028(u8 taskId) } } -void sub_80FC114(const u8 *name, struct GFtgtGname *structPtr, u8 activity) +void sub_80FC114(const u8 *name, struct RfuGameData *structPtr, u8 activity) { u8 taskId, taskId2; diff --git a/src/link_rfu_3.c b/src/link_rfu_3.c index de0a63490..fb6828053 100644 --- a/src/link_rfu_3.c +++ b/src/link_rfu_3.c @@ -661,7 +661,7 @@ static u8 GetConnectedChildStrength(u8 maxFlags) return 0; } -void InitHostRFUtgtGname(struct GFtgtGname *data, u8 activity, bool32 started, s32 child_sprite_genders) +void InitHostRFUtgtGname(struct RfuGameData *data, u8 activity, bool32 started, s32 child_sprite_genders) { s32 i; @@ -694,7 +694,7 @@ void InitHostRFUtgtGname(struct GFtgtGname *data, u8 activity, bool32 started, s * Otherwise, blanks these. * ========================================================== */ -bool8 LinkRfu_GetNameIfCompatible(struct GFtgtGname *gname, u8 *uname, u8 idx) +bool8 LinkRfu_GetNameIfCompatible(struct RfuGameData *gname, u8 *uname, u8 idx) { bool8 retVal; @@ -735,7 +735,7 @@ bool8 LinkRfu_GetNameIfCompatible(struct GFtgtGname *gname, u8 *uname, u8 idx) * which comes from ??? * ========================================================== */ -bool8 LinkRfu_GetNameIfSerial7F7D(struct GFtgtGname *gname, u8 *uname, u8 idx) +bool8 LinkRfu_GetNameIfSerial7F7D(struct RfuGameData *gname, u8 *uname, u8 idx) { bool8 retVal = FALSE; if (gRfuLinkStatus->partner[idx].serialNo == RFU_SERIAL_7F7D) @@ -752,10 +752,10 @@ bool8 LinkRfu_GetNameIfSerial7F7D(struct GFtgtGname *gname, u8 *uname, u8 idx) return retVal; } -void LinkRfu3_SetGnameUnameFromStaticBuffers(struct GFtgtGname *gname, u8 *uname) +void LinkRfu3_SetGnameUnameFromStaticBuffers(struct RfuGameData *gname, u8 *uname) { - memcpy(gname, &gHostRFUtgtGnameBuffer, RFU_GAME_NAME_LENGTH); - memcpy(uname, gHostRFUtgtUnameBuffer, RFU_USER_NAME_LENGTH); + memcpy(gname, &gHostRfuGameData, RFU_GAME_NAME_LENGTH); + memcpy(uname, gHostRfuUsername, RFU_USER_NAME_LENGTH); } #define sNextAnimNum data[0] diff --git a/src/party_menu.c b/src/party_menu.c index ee2800801..ad8300a9f 100644 --- a/src/party_menu.c +++ b/src/party_menu.c @@ -3874,7 +3874,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 *)GetHostRFUtgtGname(), species2, species, isEventLegal)) { case CANT_REGISTER_MON: StringExpandPlaceholders(gStringVar4, gText_PkmnCantBeTradedNow); @@ -3900,7 +3900,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 *)GetHostRFUtgtGname(), gPartnerTgtGnameSub, species2, gUnionRoomOfferedSpecies, gUnionRoomRequestedMonType, species, isEventLegal); if (stringId != UR_TRADE_MSG_NONE) { diff --git a/src/rfu_union_tool.c b/src/rfu_union_tool.c index d6c1c411e..0d848a69e 100644 --- a/src/rfu_union_tool.c +++ b/src/rfu_union_tool.c @@ -466,7 +466,7 @@ void MakeGroupAssemblyAreasPassable(void) } } -static u8 UnionPartnerObjectGetFacing(u32 member, u32 group, struct GFtgtGname * gname) +static u8 UnionPartnerObjectGetFacing(u32 member, u32 group, struct RfuGameData * gname) { if (member != 0) { @@ -487,7 +487,7 @@ static u32 RfuUnionGroupMemberIsInvisible(u32 group, u32 member) return RfuUnionObjectIsInvisible(5 * group + member - 0x38); } -static void SpawnGroupMember(u32 groupNo, u32 memberNo, u8 direction, struct GFtgtGname * gname) +static void SpawnGroupMember(u32 groupNo, u32 memberNo, u8 direction, struct RfuGameData * gname) { s32 x, y; s32 objId = 5 * groupNo + memberNo; @@ -510,7 +510,7 @@ static void DespawnGroupMember(u32 group, u32 member) MapGridSetMetatileImpassabilityAt(x, y, FALSE); } -static void AssembleGroup(u32 group, struct GFtgtGname * gname) +static void AssembleGroup(u32 group, struct RfuGameData * gname) { s16 x, y, x2, y2; s32 i; @@ -538,7 +538,7 @@ static void AssembleGroup(u32 group, struct GFtgtGname * gname) } } -static void SpawnGroupLeaderAndMembers(u32 group, struct GFtgtGname * gname) +static void SpawnGroupLeaderAndMembers(u32 group, struct RfuGameData * gname) { u32 i; switch (gname->activity) @@ -566,7 +566,7 @@ static void SpawnGroupLeaderAndMembers(u32 group, struct GFtgtGname * gname) } } -static void DespawnGroupLeaderAndMembers(u32 group, struct GFtgtGname * gname) +static void DespawnGroupLeaderAndMembers(u32 group, struct RfuGameData * gname) { s32 i; DespawnGroupLeader(group); diff --git a/src/trade.c b/src/trade.c index 392a23061..92d14090d 100644 --- a/src/trade.c +++ b/src/trade.c @@ -2730,7 +2730,7 @@ static bool32 IsDeoxysOrMewUntradable(u16 species, bool8 isEventLegal) return FALSE; } -int GetUnionRoomTradeMessageId(struct GFtgtGnameSub playerSub, struct GFtgtGnameSub partnerSub, u16 species1, u16 species2, u8 type, u16 species3, u8 isEventLegal) +int GetUnionRoomTradeMessageId(struct RfuGameCompatibilityData playerSub, struct RfuGameCompatibilityData partnerSub, u16 species1, u16 species2, u8 type, u16 species3, u8 isEventLegal) { u8 playerHasNationalDex = playerSub.hasNationalDex; u8 playerIsChampion = playerSub.isChampion; @@ -2810,7 +2810,7 @@ int GetUnionRoomTradeMessageId(struct GFtgtGnameSub playerSub, struct GFtgtGname return 0; } -int CanRegisterMonForTradingBoard(struct GFtgtGnameSub playerSub, u16 species2, u16 species, u8 isEventLegal) +int CanRegisterMonForTradingBoard(struct RfuGameCompatibilityData playerSub, u16 species2, u16 species, u8 isEventLegal) { u8 canTradeEggAndNational = playerSub.hasNationalDex; diff --git a/src/union_room.c b/src/union_room.c index cc7df613a..00baa9802 100644 --- a/src/union_room.c +++ b/src/union_room.c @@ -53,7 +53,7 @@ static EWRAM_DATA u8 sPlayerCurrActivity = 0; static EWRAM_DATA u8 sPlayerActivityGroupSize = 0; static EWRAM_DATA union UnkUnion_Main sUnionRoomMain = {}; static EWRAM_DATA u32 sUnref_203B060 = 0; -EWRAM_DATA struct GFtgtGnameSub gPartnerTgtGnameSub = {}; +EWRAM_DATA struct RfuGameCompatibilityData gPartnerTgtGnameSub = {}; EWRAM_DATA u16 gUnionRoomOfferedSpecies = SPECIES_NONE; EWRAM_DATA u8 gUnionRoomRequestedMonType = TYPE_NORMAL; static EWRAM_DATA struct UnionRoomTrade sUnionRoomTrade = {}; @@ -86,7 +86,7 @@ static bool32 UnionRoom_HandleContactFromOtherPlayer(struct UnkStruct_URoom * uR static void Task_InitUnionRoom(u8 taskId); static u8 HandlePlayerListUpdate(void); static u8 CreateTask_SearchForChildOrParent(struct UnkStruct_Main4 * main4, struct UnkStruct_Main4 * arg1, u32 arg2); -static bool32 GetGnameWonderFlagByLinkGroup(struct GFtgtGname * gname, s16 linkGroup); +static bool32 GetGnameWonderFlagByLinkGroup(struct RfuGameData * gname, s16 linkGroup); static u8 CreateTask_ListenForPartnersWithCompatibleSerialNos(struct UnkStruct_Main4 * main4, u32 linkGroup); static u8 CreateTask_ListenForPartnersWithSerial7F7D(struct UnkStruct_Main4 * main4, u32 linkGroup); static bool32 UR_PrintFieldMessage(const u8 * str); @@ -3719,7 +3719,7 @@ static void Task_ListenForPartnersWithCompatibleSerialNos(u8 taskId) } } -static bool32 GetGnameWonderFlagByLinkGroup(struct GFtgtGname * gname, s16 linkGroup) +static bool32 GetGnameWonderFlagByLinkGroup(struct RfuGameData * gname, s16 linkGroup) { if (linkGroup == LINK_GROUP_WONDER_CARD) { @@ -4315,7 +4315,7 @@ static void nullsub_92(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 * gname, const u8 * uname, u8 colorIdx) { u8 level_t[4]; u16 species = gname->species; @@ -4339,7 +4339,7 @@ static void TradeBoardPrintItemInfo(u8 windowId, u8 y, struct GFtgtGname * gname static void TradeBoardListMenuItemPrintFunc(u8 windowId, u32 itemId, u8 y) { struct UnkStruct_Leader * leader = sUnionRoomMain.leader; - struct GFtgtGname * rfu; + struct RfuGameData * rfu; s32 i, j; u8 uname[RFU_USER_NAME_LENGTH]; From b3c47d0059c20fbdaf2f16c26971259e006e70e4 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Mon, 7 Nov 2022 10:59:49 -0500 Subject: [PATCH 2/8] Finish syncing link_rfu_2 --- common_syms/link_rfu_2.txt | 2 +- include/gba/types.h | 3 + include/link.h | 3 +- include/link_rfu.h | 246 ++- include/mystery_gift_menu.h | 2 +- src/battle_controllers.c | 2 +- src/berry_crush.c | 6 +- src/link.c | 28 +- src/link_rfu_2.c | 2148 ++++++++++---------- src/link_rfu_3.c | 84 +- src/main.c | 2 +- src/mystery_gift_menu.c | 6 +- src/overworld.c | 2 +- src/party_menu.c | 4 +- src/pokemon_jump.c | 2 +- src/rfu_union_tool.c | 8 +- src/trade.c | 8 +- src/union_room.c | 204 +- src/union_room_chat.c | 30 +- src/wireless_communication_status_screen.c | 2 +- 20 files changed, 1437 insertions(+), 1355 deletions(-) diff --git a/common_syms/link_rfu_2.txt b/common_syms/link_rfu_2.txt index abd9a5f93..3a84c23bf 100644 --- a/common_syms/link_rfu_2.txt +++ b/common_syms/link_rfu_2.txt @@ -1,3 +1,3 @@ gHostRfuGameData -Rfu +gRfu gHostRfuUsername diff --git a/include/gba/types.h b/include/gba/types.h index 7163f925f..35d02e263 100644 --- a/include/gba/types.h +++ b/include/gba/types.h @@ -27,6 +27,9 @@ typedef double f64; typedef u8 bool8; typedef u16 bool16; typedef u32 bool32; +typedef vu8 vbool8; +typedef vu16 vbool16; +typedef vu32 vbool32; struct BgCnt { diff --git a/include/link.h b/include/link.h index 74a94920c..1ac0913a2 100644 --- a/include/link.h +++ b/include/link.h @@ -250,7 +250,7 @@ void SetSuppressLinkErrorMessage(bool8); bool8 HasLinkErrorOccurred(void); void ResetSerial(void); u32 LinkMain1(u8 *, u16 *, u16[MAX_RFU_PLAYERS][CMD_LENGTH]); -void RFUVSync(void); +void RfuVSync(void); void Timer3Intr(void); void SerialCB(void); u8 GetLinkPlayerCount(void); @@ -258,7 +258,6 @@ bool32 InUnionRoom(void); void SetLinkStandbyCallback(void); void SetWirelessCommType1(void); -void LinkRfu_DestroyIdleTask(void); void SetCloseLinkCallback(void); void OpenLink(void); bool8 IsLinkMaster(void); diff --git a/include/link_rfu.h b/include/link_rfu.h index e22414786..f203d30a3 100644 --- a/include/link_rfu.h +++ b/include/link_rfu.h @@ -6,33 +6,29 @@ #include "link.h" #include "AgbRfu_LinkManager.h" -#define RFUCMD_MASK 0xFF00 +#define RFUCMD_MASK 0xFF00 -#define RFUCMD_SEND_PACKET 0x2F00 -#define RFUCMD_READY_CLOSE_LINK 0x5f00 -#define RFUCMD_READY_EXIT_STANDBY 0x6600 -#define RFUCMD_PLAYERS_LIST 0x7700 -#define RFUCMD_PLAYERS_LIST_2 0x7800 -#define RFUCMD_SEND_BLOCK_INIT 0x8800 -#define RFUCMD_SEND_BLOCK_STEP 0x8900 -#define RFUCMD_SEND_BLOCK_REQ 0xa100 -#define RFUCMD_SEND_HELD_KEYS 0xbe00 -#define RFUCMD_PARENT_DISCONNECT 0xed00 -#define RFUCMD_CHILD_DISCONNECT 0xee00 +#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_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_DISCONNECT 0xED00 +#define RFUCMD_DISCONNECT_PARENT 0xEE00 -#define RFU_PACKET_SIZE 6 - -#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_END 0xFFFF +#define COMM_SLOT_LENGTH 14 #define RECV_QUEUE_NUM_SLOTS 20 -#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 UNUSED_QUEUE_NUM_SLOTS 2 #define UNUSED_QUEUE_SLOT_LENGTH 256 @@ -48,13 +44,40 @@ #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 -#define RFU_RECV_IDLE 0 -#define RFU_RECV_RECEIVING 1 -#define RFU_RECV_FINISHED 2 +// 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) // RfuTgtData.gname is read as these structs. struct RfuGameCompatibilityData @@ -62,36 +85,47 @@ struct RfuGameCompatibilityData u16 language:4; u16 hasNews:1; u16 hasCard:1; - u16 unknown:1; + u16 unknown:1; // Never read u16 isChampion:1; u16 hasNationalDex:1; u16 gameClear:1; u16 version:4; - u16 unk_01_6:2; + u16 unused:2; u8 playerTrainerId[2]; }; +// 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 RfuGameCompatibilityData 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 - -struct Padded_U8 -{ - u8 value; }; +// 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 { /* 0x00 */ u16 next; @@ -106,7 +140,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]; /* 0x578 */ vu8 recv_slot; /* 0x579 */ vu8 send_slot; /* 0x57a */ vu8 count; @@ -115,7 +149,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 recv_slot; /* 0x231 */ vu8 send_slot; /* 0x232 */ vu8 count; @@ -124,7 +158,7 @@ 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 recv_slot; /* 0x1d */ vu8 send_slot; /* 0x1e */ vu8 count; @@ -141,24 +175,24 @@ struct RfuUnusedQueue struct RfuManager { - /* 0x000 */ void (*RfuFunc)(void); + /* 0x000 */ void (*callback)(void); /* 0x004 */ u16 state; - /* 0x006 */ u8 filler_06[4]; - /* 0x00a */ u16 linkman_msg; - /* 0x00c */ u8 parent_child; + /* 0x006 */ u8 unused1[4]; + /* 0x00a */ u16 errorInfo; + /* 0x00c */ u8 parentChild; /* 0x00d */ u8 playerCount; - /* 0x00e */ u8 unk_0e; - /* 0x00f */ u8 unk_0f; - /* 0x010 */ u16 linkman_param[2]; - /* 0x014 */ u8 main_UNI_recvBuffer[RFU_CHILD_MAX][14]; - /* 0x04c */ u8 lastCmdBeforeCommInterrupt[14]; - /* 0x05a */ u8 cmdA100_blockRequestType; + /* 0x00e */ bool8 runParentMain2; + /* 0x00f */ u8 unused2; + /* 0x010 */ u16 errorParams[2]; + /* 0x014 */ u8 childRecvBuffer[RFU_CHILD_MAX][COMM_SLOT_LENGTH]; + /* 0x04c */ u8 childSendBuffer[COMM_SLOT_LENGTH]; + /* 0x05a */ u8 blockRequestType; /* 0x05b */ u8 sendBlockInitDelay; /* 0x05c */ bool8 blockReceived[MAX_RFU_PLAYERS]; /* 0x061 */ u8 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]; @@ -170,45 +204,45 @@ struct RfuManager /* 0x0f2 */ u16 packet[RFU_PACKET_SIZE]; /* 0x0fe */ u16 resendExitStandbyTimer; /* 0x100 */ u16 resendExitStandbyCount; - /* 0x102 */ u8 unk_102; - /* 0x104 */ struct RfuTgtData tgtData; + /* 0x102 */ u8 childSendCmdId; + /* 0x104 */ struct RfuTgtData parent; /* 0x124 */ struct RfuRecvQueue recvQueue; /* 0x6a0 */ struct RfuSendQueue sendQueue; /* 0x8d4 */ struct RfuBackupQueue backupQueue; /* 0x8f4 */ vu8 linkRecovered; - /* 0x8f5 */ u8 reconnectedParentIdx; - /* 0x8f6 */ vu8 child_slot; - /* 0x8f7 */ u8 unk_c3f[70]; + /* 0x8f5 */ u8 reconnectParentId; + /* 0x8f6 */ vu8 childSlot; + /* 0x8f7 */ u8 childRecvQueue[COMM_SLOT_LENGTH * MAX_RFU_PLAYERS]; /* 0x93d */ u8 sendStatus; /* 0x93e */ u8 recvStatus; - /* 0x93f */ u8 recvCmds[MAX_RFU_PLAYERS][7][2]; + /* 0x93f */ u8 recvCmds[MAX_RFU_PLAYERS][CMD_LENGTH - 1][2]; /* 0x985 */ u8 parentId; /* 0x986 */ u8 multiplayerId; // childId - /* 0x987 */ u8 unk_ccf; - /* 0x988 */ vu8 sem_UNI_SendRecv; + /* 0x987 */ u8 connectParentFailures; + /* 0x988 */ vu8 childSendCount; /* 0x989 */ u8 partnerSendStatuses[RFU_CHILD_MAX]; /* 0x98d */ u8 partnerRecvStatuses[RFU_CHILD_MAX]; - /* 0x991 */ u8 linkClosing; - /* 0x992 */ u8 unk_cda; - /* 0x993 */ volatile bool8 unk_cdb; - /* 0x994 */ volatile bool8 unk_cdc; - /* 0x995 */ u8 unk_cdd; + /* 0x991 */ bool8 stopNewConnections; + /* 0x992 */ u8 parentSendSlot; + /* 0x993 */ vbool8 parentFinished; + /* 0x994 */ vbool8 parentMain2Failed; + /* 0x995 */ u8 unused5; /* 0x996 */ u8 linkPlayerIdx[RFU_CHILD_MAX]; - /* 0x99a */ u8 bm_PartnerFlags; - /* 0x99b */ u8 bm_DisconnectSlot; - /* 0x99c */ u8 unk_ce4; - /* 0x99d */ u8 bmChatLeaderMaybe; - /* 0x99e */ u8 unionRoomChatters; + /* 0x99a */ u8 parentSlots; + /* 0x99b */ u8 disconnectSlots; + /* 0x99c */ u8 disconnectMode; + /* 0x99d */ u8 nextChildBits; + /* 0x99e */ u8 newChildQueue; /* 0x99f */ u8 acceptSlot_flag; - /* 0x9a0 */ bool8 foundNewLeaderMaybe; - /* 0x9a1 */ u8 unk_ce9; - /* 0x9a2 */ u8 unk_cea[RFU_CHILD_MAX]; - /* 0x9a6 */ u8 unk_cee[RFU_CHILD_MAX]; + /* 0x9a0 */ bool8 playerExchangeActive; + /* 0x9a1 */ u8 incomingChild; + /* 0x9a2 */ u8 numChildRecvErrors[RFU_CHILD_MAX]; + /* 0x9a6 */ u8 childRecvIds[RFU_CHILD_MAX]; }; // size: 0x9AC extern struct RfuGameData gHostRfuGameData; extern u8 gHostRfuUsername[]; -extern struct RfuManager Rfu; +extern struct RfuManager gRfu; // GameFreak signatures void AddTextPrinterToWindow1(const u8 *str); @@ -223,14 +257,14 @@ void MEvent_CreateTask_CardOrNewsOverWireless(u32 arg0); void MEvent_CreateTask_Leader(u32 arg0); void Rfu_SendPacket(void *data); u8 CreateTask_ListenToWireless(void); -void LinkRfu_DestroyIdleTask(void); +void DestroyTask_RfuIdle(void); void InitRFUAPI(void); -void sub_80FB128(bool32 a0); +void RfuSetIgnoreError(bool32 enable); bool32 IsSendingKeysToRfu(void); void ClearLinkRfuCallback(void); -u8 GetRfuPlayerCount(void); +u8 Rfu_GetLinkPlayerCount(void); void StartSendingKeysToRfu(void); -u8 LinkRfu_GetMultiplayerId(void); +u8 Rfu_GetMultiplayerId(void); bool32 Rfu_InitBlockSend(const u8 * src, size_t size); bool8 Rfu_SendBlockRequest(u8 blockRequestType); u8 Rfu_GetBlockReceivedStatus(void); @@ -238,15 +272,15 @@ void Rfu_SetBlockReceivedFlag(u8 linkPlayerId); void Rfu_ResetBlockReceivedFlag(u8 linkPlayerId); bool8 Rfu_IsMaster(void); void ResetLinkRfuGFLayer(void); -bool32 LinkRfuMain1(void); -bool32 LinkRfuMain2(void); +bool32 RfuMain1(void); +bool32 RfuMain2(void); bool32 IsRfuRecvQueueEmpty(void); u32 GetRfuRecvQueueLength(void); void LinkRfu_Shutdown(void); -void LinkRfu_CreateIdleTask(void); -bool8 ToggleLMANlinkRecovery(bool32 enable); +void CreateTask_RfuIdle(void); +bool8 Rfu_SetLinkRecovery(bool32 enable); void var_800D_set_xB(void); -struct RfuGameData *GetHostRFUtgtGname(void); +struct RfuGameData *GetHostRfuGameData(void); void UpdateWirelessStatusIndicatorSprite(void); void InitRFU(void); bool32 RfuHasErrored(void); @@ -262,44 +296,44 @@ bool8 RfuBackupQueue_Dequeue(struct RfuBackupQueue *queue, u8 *dest); void RfuBackupQueue_Enqueue(struct RfuBackupQueue *queue, const u8 *dest); bool8 RfuRecvQueue_Dequeue(struct RfuRecvQueue * queue, u8 *dest); void RfuSendQueue_Enqueue(struct RfuSendQueue * queue, u8 *src); -void InitHostRFUtgtGname(struct RfuGameData *data, u8 activity, bool32 started, s32 child_sprite_genders); +void InitHostRFUtgtGname(struct RfuGameData *data, u8 activity, bool32 started, s32 partnerInfo); void UpdateGameData_GroupLockedIn(bool8 started); bool32 IsRfuSerialNumberValid(u32 serialNo); bool8 IsRfuRecoveringFromLinkLoss(void); bool8 LmanAcceptSlotFlagIsNotZero(void); void LinkRfu_StopManagerAndFinalizeSlots(void); -bool32 sub_80FA5D4(void); -bool32 sub_80FC1CC(void); +bool32 RfuTryDisconnectLeavingChildren(void); +bool32 IsRfuCommunicatingWithAllChildren(void); bool32 WaitRfuState(bool32 a0); -bool32 CheckTrainerHasLeftByIdAndName(u16 trainerId, const u8 *trainerName); -void SendByteToPartnerByIdAndName(u8 a0, u16 a1, const u8 *a2); -u32 WaitSendByteToPartnerByIdAndName(u16 a0, const u8 *a1); -void SetHostRFUtgtGname(u8 activity, u32 child_sprite_genders, u32 a2); +bool32 HasTrainerLeftPartnersList(u16 trainerId, const u8 *trainerName); +void SendRfuStatusToPartner(u8 status, u16 trainerId, const u8 *name); +u32 WaitSendRfuStatusToPartner(u16 trainerId, const u8 *name); +void SetHostRfuGameData(u8 activity, u32 partnerInfo, bool32 startedActivity); void InitializeRfuLinkManager_LinkLeader(u32 availSlots); void RequestDisconnectSlotByTrainerNameAndId(const u8 *trainerName, u16 trainerId); void LinkRfu3_SetGnameUnameFromStaticBuffers(struct RfuGameData *gname, u8 *uname); void InitializeRfuLinkManager_JoinGroup(void); void SendLeaveGroupNotice(void); void CreateTask_RfuReconnectWithParent(const u8 *src, u16 trainerId); -void UpdateGameDataWithActivitySpriteGendersFlag(u8 activity, u32 child_sprite_genders, u32 started); +void UpdateGameData_SetActivity(u8 activity, u32 partnerInfo, u32 startedActivity); void RecordMixTrainerNames(void); void LinkRfu_CreateConnectionAsParent(); void LinkRfu_StopManagerBeforeEnteringChat(); -void SetGnameBufferWonderFlags(bool32 hasNews, bool32 hasCard); -void ClearAndInitHostRFUtgtGname(void); -void sub_80F8FA0(void); -void RfuUpdatePlayerGnameStateAndSend(u32 type, u32 species, u32 level); +void SetHostRfuWonderFlags(bool32 hasNews, bool32 hasCard); +void ResetHostRfuGameData(void); +void StopUnionRoomLinkManager(void); +void SetTradeBoardRegisteredMonInfo(u32 type, u32 species, u32 level); bool32 IsUnionRoomListenTaskActive(void); void InitializeRfuLinkManager_EnterUnionRoom(void); -void sub_80FBD6C(u32 a0); -void sub_80FC114(const u8 *name, struct RfuGameData *structPtr, u8 a2); +void Rfu_DisconnectPlayerById(u32 playerIdx); +void TryConnectToUnionRoomParent(const u8 *name, struct RfuGameData *parent, u8 activity); bool32 PlayerHasMetTrainerBefore(u16 id, u8 *name); bool8 LinkRfu_GetNameIfCompatible(struct RfuGameData *gname, u8 *uname, u8 idx); bool8 LinkRfu_GetNameIfSerial7F7D(struct RfuGameData *gname, u8 *uname, u8 idx); -bool32 RfuHasFoundNewLeader(void); -void Rfu_UnionRoomChat_StopLinkManager(void); -void sub_80FB9D0(void); -void sub_80FB030(u32 a0); +bool32 Rfu_IsPlayerExchangeActive(void); +void Rfu_StopPartnerSearch(void); +void RfuSetNormalDisconnectMode(void); +void SetUnionRoomChatPlayerData(u32 numPlayers); void ClearRecvCommands(void); #include "mevent_server.h" diff --git a/include/mystery_gift_menu.h b/include/mystery_gift_menu.h index bd790b36e..a25cc598f 100644 --- a/include/mystery_gift_menu.h +++ b/include/mystery_gift_menu.h @@ -6,7 +6,7 @@ extern bool8 gGiftIsFromEReader; void MainCB_FreeAllBuffersAndReturnToInitTitleScreen(void); void PrintMysteryGiftOrEReaderTopMenu(bool8, bool32); void c2_mystery_gift(void); -void c2_mystery_gift_e_reader_run(void); +void CB2_MysteryGiftEReader(void); s8 mevent_message_print_and_prompt_yes_no(u8 * textState, u16 * windowId, bool8 yesNoBoxPlacement, const u8 * str); void MG_DrawTextBorder(u8 windowId); u16 GetMysteryGiftBaseBlock(void); diff --git a/src/battle_controllers.c b/src/battle_controllers.c index ba56b0db1..e877a1c08 100644 --- a/src/battle_controllers.c +++ b/src/battle_controllers.c @@ -519,7 +519,7 @@ void TryReceiveLinkBattleData(void) if (gReceivedRemoteLinkPlayers != 0 && (gBattleTypeFlags & BATTLE_TYPE_LINK_IN_BATTLE) && (gLinkPlayers[0].linkType == 0x2211)) { - LinkRfu_DestroyIdleTask(); + DestroyTask_RfuIdle(); for (i = 0; i < GetLinkPlayerCount(); i++) { if (GetBlockReceivedStatus() & gBitTable[i]) diff --git a/src/berry_crush.c b/src/berry_crush.c index d116a112f..ec58ece26 100644 --- a/src/berry_crush.c +++ b/src/berry_crush.c @@ -969,9 +969,9 @@ static u32 QuitBerryCrush(MainCallback callback) #define ERROR_EXIT(exitCallback) \ { \ SetMainCallback2(exitCallback); \ - Rfu.linkman_param[0] = 0; \ - Rfu.linkman_param[1] = 0; \ - Rfu.errorState = 1; \ + gRfu.errorParams[0] = 0; \ + gRfu.errorParams[1] = 0; \ + gRfu.errorState = 1; \ } diff --git a/src/link.c b/src/link.c index 6473de242..e60ebed00 100644 --- a/src/link.c +++ b/src/link.c @@ -227,7 +227,7 @@ bool8 IsWirelessAdapterConnected(void) SetWirelessCommType1(); InitRFUAPI(); - sub_80FB128(TRUE); + RfuSetIgnoreError(TRUE); if (rfu_LMAN_REQBN_softReset_and_checkID() == RFU_ID) { rfu_REQ_stopMode(); @@ -748,21 +748,16 @@ void ClearLinkCallback(void) void ClearLinkCallback_2(void) { if (gWirelessCommType) - { ClearLinkRfuCallback(); - } else - { gLinkCallback = NULL; - } } u8 GetLinkPlayerCount(void) { if (gWirelessCommType) - { - return GetRfuPlayerCount(); - } + return Rfu_GetLinkPlayerCount(); + return EXTRACT_PLAYER_COUNT(gLinkStatus); } @@ -977,7 +972,7 @@ u8 GetMultiplayerId(void) { if (gWirelessCommType == 1) { - return LinkRfu_GetMultiplayerId(); + return Rfu_GetMultiplayerId(); } return SIO_MULTI_CNT->id; } @@ -1647,10 +1642,11 @@ void LinkPlayerFromBlock(u32 who) } } +// When this function returns TRUE the callbacks are skipped bool8 HandleLinkConnection(void) { - bool32 r4; - bool32 r5; + bool32 main1Failed; + bool32 main2Failed; if (gWirelessCommType == 0) { @@ -1663,14 +1659,14 @@ bool8 HandleLinkConnection(void) } else { - r4 = LinkRfuMain1(); - r5 = LinkRfuMain2(); + 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; - } } } return FALSE; diff --git a/src/link_rfu_2.c b/src/link_rfu_2.c index 649836276..9257f04b1 100644 --- a/src/link_rfu_2.c +++ b/src/link_rfu_2.c @@ -11,6 +11,40 @@ #include "task.h" #include "constants/union_room.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[sizeof("PokemonSioInfo")]; @@ -42,13 +76,13 @@ static u8 sResendBlock8[CMD_LENGTH * 2]; static u16 sResendBlock16[CMD_LENGTH]; struct RfuGameData gHostRfuGameData; -struct RfuManager Rfu; +struct RfuManager gRfu; u8 gHostRfuUsername[PLAYER_NAME_LENGTH + 1]; -static void sub_80F8AA4(void); -static void sub_80F8AEC(void); -static void MscCallback_Child(u16 a0); -static void MSCCallback_SetUnkCDB(u16 a0); +static void InitChildRecvBuffers(void); +static void InitParentSendData(void); +static void MscCallback_Child(u16 REQ_commandID); +static void MSCCallback_Parent(u16 REQ_commandID); static void UpdateBackupQueue(void); static void RfuHandleReceiveCommand(u8 unused); static void ResetSendDataManager(struct RfuBlockSend *data); @@ -58,28 +92,28 @@ static void SendNextBlock(void); static void SendLastBlock(void); static void CallRfuFunc(void); static void UpdateChildStatuses(void); -static s32 GetRfuRecvStatus(void); -static void sub_80FA834(u8 taskId); +static s32 GetJoinGroupStatus(void); +static void Task_PlayerExchange(u8 taskId); static void ClearSelectedLinkPlayerIds(u16 disconnectMask); -static void ValidateAndReceivePokemonSioInfo(void *a0); -static void Task_ExchangeLinkPlayers(u8 taskId); -static void sub_80FACF0(u8 taskId); -static void GetLinkmanErrorParams(u32 msg); -static void sub_80FB564(s32 bmConnectedFlag); -static void sub_80FBB74(void); +static void ValidateAndReceivePokemonSioInfo(void *recvBuffer); +static void Task_PlayerExchangeUpdate(u8 taskId); +static void Task_PlayerExchangeChat(u8 taskId); +static void RfuSetErrorParams(u32 errorInfo); +static void ParentResetChildRecvMetadata(s32 slot); +static void CB2_RfuIdle(void); static u8 GetPartnerIndexByNameAndTrainerID(const u8 *trainerName, u16 trainerId); static void RfuReqDisconnectSlot(u32 bmDisconnectSlot); -static void sub_80FBE20(u32 a0, u32 a1); -static void sub_80FC028(u8 taskId); +static void SendDisconnectCommand(u32 playersToDisconnect, u32 disconnectMode); +static void Task_TryConnectToUnionRoomParent(u8 taskId); static void Debug_PrintEmpty(void); -static void Task_idle(u8 taskId); +static void Task_Idle(u8 taskId); static const INIT_PARAM sRfuReqConfigTemplate = { .maxMFrame = 4, .MC_TimerCount = 32, .availSlot_flag = 0, .mboot_flag = 0, - .serialNo = 0x0002, + .serialNo = RFU_SERIAL_GAME, .gameName = (void *)&gHostRfuGameData, .userName = gHostRfuUsername, .fastSearchParent_flag = TRUE, @@ -95,76 +129,82 @@ 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 gUnknown_843EC38[] = { +static const u8 sSlotToLinkPlayerTableId[] = { 0, 0, 1, 1, 2, 2, 2, 2, 3 }; -static const u8 sNumSetBits[] = { - [0x0] = 0, - [0x1] = 1, - [0x2] = 1, - [0x3] = 2, - [0x4] = 1, - [0x5] = 2, - [0x6] = 2, - [0x7] = 3, - [0x8] = 1, - [0x9] = 2, - [0xA] = 2, - [0xB] = 3, - [0xC] = 2, - [0xD] = 3, - [0xE] = 3, - [0xF] = 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 sNumTrailingZeroes[] = { - [0x0] = 0, - [0x1] = 0, - [0x2] = 1, - [0x3] = 0, - [0x4] = 2, - [0x5] = 0, - [0x6] = 1, - [0x7] = 0, - [0x8] = 3, - [0x9] = 0, - [0xA] = 1, - [0xB] = 0, - [0xC] = 2, - [0xD] = 0, - [0xE] = 1, - [0xF] = 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[] = { @@ -176,12 +216,12 @@ static const struct BlockRequest sBlockRequests[] = { }; static const u16 sAcceptedSerialNos[] = { - 0x0002, // Pokemon FR/LG/EM - RFU_SERIAL_7F7D, - 0xFFFF + RFU_SERIAL_GAME, + RFU_SERIAL_WONDER_DISTRIBUTOR, + RFU_SERIAL_END }; -static const char sUnref_843EC92[][15] = { +static const char sASCII_RfuCmds[][15] = { "RFU WAIT", "RFU BOOT", "RFU ERROR", @@ -195,7 +235,7 @@ static const char sUnref_843EC92[][15] = { "RFU CP POLL" }; -static const char sUnref_843ED37[][16] = { +static const char sASCII_RecoverCmds[][16] = { " ", "RECOVER START ", "DISSCONECT ", @@ -203,18 +243,19 @@ static const char sUnref_843ED37[][16] = { "RECOVER FAILED" }; -static const TaskFunc gUnknown_843ED88[] = { - sub_80FA834, - Task_ExchangeLinkPlayers, - sub_80FACF0 +// List of additional tasks to destroy (if active) when the RFU shuts down +static const TaskFunc sShutdownTasks[] = { + Task_PlayerExchange, + Task_PlayerExchangeUpdate, + Task_PlayerExchangeChat }; static void Debug_PrintString(const void *string, u8 x, u8 y) { - // debug? + } -static void Debug_PrintNum(u16 num, u8 x, u8 y, u8 ndigits) +static void Debug_PrintNum(u16 num, u8 x, u8 y, u8 numDigits) { } @@ -222,21 +263,17 @@ static void Debug_PrintNum(u16 num, u8 x, u8 y, u8 ndigits) void ResetLinkRfuGFLayer(void) { s32 i; - u8 errorState_bak = Rfu.errorState; - CpuFill16(0, &Rfu, sizeof Rfu); - Rfu.parent_child = MODE_NEUTRAL; - Rfu.errorState = errorState_bak; - if (Rfu.errorState != 4) - { - Rfu.errorState = 0; - } + u8 errorState = gRfu.errorState; + CpuFill16(0, &gRfu, sizeof gRfu); + gRfu.parentChild = MODE_NEUTRAL; + gRfu.errorState = errorState; + 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); @@ -257,149 +294,145 @@ void InitRFU(void) void InitRFUAPI(void) { - if (!rfu_initializeAPI(sRfuAPIBuffer, RFU_API_BUFF_SIZE_RAM, gIntrTable + 1, TRUE)) + if (!rfu_initializeAPI(sRfuAPIBuffer, RFU_API_BUFF_SIZE_RAM, &gIntrTable[1], TRUE)) { gLinkType = 0; // ClearSavedLinkPlayers(); // Em fix - sub_80FB128(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.parent_child, 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(MSCCallback_SetUnkCDB); - sub_80F8AA4(); - sub_80F8AEC(); - 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_80FA834, 5); + CreateTask(Task_PlayerExchange, 5); DestroyTask(taskId); break; } } -static u8 CountTrailingZeroes(u8 acceptSlot) +static u8 Rfu_GetIndexOfNewestChild(u8 bits) { - return sNumTrailingZeroes[acceptSlot]; + return sPlayerBitsToNewChildIdx[bits]; } -static void ReassignPartnerIds(s32 before, s32 after) +static void SetLinkPlayerIdsFromSlots(s32 baseSlots, s32 addSlots) { u8 i; - u8 r4 = 1; - s32 beforeBak = before; - s32 r6 = 0; - if (after == -1) + u8 baseId = 1; + s32 baseSlotsCopy = baseSlots; + s32 newId = 0; + if (addSlots == -1) { - // First Time Init - // UB: linkPlayerIdx may be uninitialized - for (i = 0; i < RFU_CHILD_MAX; before >>= 1, i++) + // Initialize + for (i = 0; i < RFU_CHILD_MAX; baseSlots >>= 1, i++) { - if (before & 1) + if (baseSlots & 1) { - Rfu.linkPlayerIdx[i] = r4; - r4++; + gRfu.linkPlayerIdx[i] = baseId; + baseId++; } } } else { - // Delete before flags - for (i = 0; i < RFU_CHILD_MAX; beforeBak >>= 1, i++) + // Clear id for any empty slot + for (i = 0; i < RFU_CHILD_MAX; baseSlotsCopy >>= 1, i++) { - if (!(beforeBak & 1)) - { - Rfu.linkPlayerIdx[i] = 0; - } + if (!(baseSlotsCopy & 1)) + gRfu.linkPlayerIdx[i] = 0; } - // Get highest retained index - for (r4 = 4; 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++); - if (i == 4) - { - r6 = r4; - } + for (i = 0; i < RFU_CHILD_MAX && gRfu.linkPlayerIdx[i] != baseId; i++) + ; + if (i == RFU_CHILD_MAX) + newId = baseId; } - // Replace with new flags - for (after &= ~before, i = 0; i < RFU_CHILD_MAX; after >>= 1, i++) + + // Set id for new slots + for (addSlots &= ~baseSlots, i = 0; i < RFU_CHILD_MAX; addSlots >>= 1, i++) { - if (after & 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.parent_child, 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 (GetRfuRecvStatus()) + 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.child_slot; - rfu_clearSlot(TYPE_NI_SEND | TYPE_NI_RECV, Rfu.child_slot); - rfu_setRecvBuffer(TYPE_UNI, Rfu.child_slot, Rfu.unk_c3f, sizeof(Rfu.unk_c3f)); - rfu_UNI_setSendData(bmChildSlot, Rfu.lastCmdBeforeCommInterrupt, sizeof(Rfu.lastCmdBeforeCommInterrupt)); + 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.childJoined) @@ -407,13 +440,13 @@ static void Task_JoinGroupSearchForParent(u8 taskId) Debug_PrintEmpty(); sRfuDebug.childJoined++; } - CreateTask(sub_80FA834, 5); + CreateTask(Task_PlayerExchange, 5); break; } } } -static void sub_80F8AA4(void) +static void InitChildRecvBuffers(void) { u8 i; u8 acceptSlot = lman.acceptSlot_flag; @@ -421,79 +454,77 @@ static void sub_80F8AA4(void) { if (acceptSlot & 1) { - rfu_setRecvBuffer(TYPE_UNI, i, Rfu.main_UNI_recvBuffer[i], sizeof(Rfu.main_UNI_recvBuffer[i])); + rfu_setRecvBuffer(TYPE_UNI, i, gRfu.childRecvBuffer[i], sizeof(gRfu.childRecvBuffer[i])); rfu_clearSlot(TYPE_UNI_SEND | TYPE_UNI_RECV, i); } acceptSlot >>= 1; } } -static void sub_80F8AEC(void) +static void InitParentSendData(void) { u8 acceptSlot = lman.acceptSlot_flag; - rfu_UNI_setSendData(acceptSlot, Rfu.recvCmds, sizeof(Rfu.recvCmds)); - Rfu.unk_cda = CountTrailingZeroes(acceptSlot); - Rfu.bm_PartnerFlags = acceptSlot; - ReassignPartnerIds(acceptSlot, -1); - Rfu.parent_child = 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() == 4) + 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: + case RFUSTATE_UR_CONNECT: rfu_LMAN_establishConnection(MODE_P_C_SWITCH, 0, 240, (u16 *)sAcceptedSerialNos); rfu_LMAN_setMSCCallback(MscCallback_Child); - Rfu.state = 18; + gRfu.state = RFUSTATE_UR_CONNECT_END; break; - case 18: + case RFUSTATE_UR_CONNECT_END: break; - case 13: - if (rfu_UNI_setSendData(1 << Rfu.child_slot, Rfu.lastCmdBeforeCommInterrupt, sizeof(Rfu.lastCmdBeforeCommInterrupt)) == 0) + case RFUSTATE_UR_PLAYER_EXCHANGE: + if (rfu_UNI_setSendData(1 << gRfu.childSlot, gRfu.childSendBuffer, sizeof(gRfu.childSendBuffer)) == 0) { - Rfu.parent_child = MODE_CHILD; + gRfu.parentChild = MODE_CHILD; DestroyTask(taskId); - if (gTasks[taskId].data[7]) - { - CreateTask(sub_80FACF0, 1); - } + if (gTasks[taskId].tConnectingForChat) + CreateTask(Task_PlayerExchangeChat, 1); else - { - CreateTask(sub_80FA834, 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(MSCCallback_SetUnkCDB); - UpdateGameData_GroupLockedIn(1); - sub_80F8AA4(); - sub_80F8AEC(); - Rfu.state = 20; + case RFUSTATE_UR_FINALIZE: + gRfu.parentFinished = FALSE; + rfu_LMAN_setMSCCallback(MSCCallback_Parent); + UpdateGameData_GroupLockedIn(TRUE); + InitChildRecvBuffers(); + InitParentSendData(); + gRfu.state = RFUSTATE_FINALIZED; gTasks[taskId].data[1] = 8; - Rfu.parent_child = MODE_PARENT; - CreateTask(sub_80FA834, 5); - Rfu.foundNewLeaderMaybe = TRUE; + gRfu.parentChild = MODE_PARENT; + CreateTask(Task_PlayerExchange, 5); + gRfu.playerExchangeActive = TRUE; DestroyTask(taskId); break; } @@ -509,31 +540,32 @@ void LinkRfu_StopManagerBeforeEnteringChat(void) rfu_LMAN_stopManager(FALSE); } -static void MscCallback_Child(u16 unused) +// Argument is provided by the RFU and is unused. +static void MscCallback_Child(u16 REQ_commandID) { s32 i; - for (i = 0; i < BACKUP_QUEUE_SLOT_LENGTH; i++) - { - Rfu.lastCmdBeforeCommInterrupt[i] = 0; - } + for (i = 0; i < COMM_SLOT_LENGTH; i++) + gRfu.childSendBuffer[i] = 0; + rfu_REQ_recvData(); rfu_waitREQComplete(); - if (gRfuSlotStatusUNI[Rfu.child_slot]->recv.newDataFlag) + if (gRfuSlotStatusUNI[gRfu.childSlot]->recv.newDataFlag) { - Rfu.sem_UNI_SendRecv++; - RfuRecvQueue_Enqueue(&Rfu.recvQueue, Rfu.unk_c3f); + gRfu.childSendCount++; + RfuRecvQueue_Enqueue(&gRfu.recvQueue, gRfu.childRecvQueue); sRfuDebug.recvCount++; UpdateBackupQueue(); - rfu_UNI_readySendData(Rfu.child_slot); - rfu_UNI_clearRecvNewDataFlag(Rfu.child_slot); + rfu_UNI_readySendData(gRfu.childSlot); + rfu_UNI_clearRecvNewDataFlag(gRfu.childSlot); } rfu_LMAN_REQ_sendData(TRUE); } -static void MSCCallback_SetUnkCDB(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) @@ -544,125 +576,125 @@ void LinkRfu_Shutdown(void) return; rfu_LMAN_powerDownRFU(); - if (Rfu.parent_child == 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.parent_child == 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.parent_child == 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 < NELEMS(gUnknown_843ED88); i++) + + // Destroy additional tasks + for (i = 0; i < ARRAY_COUNT(sShutdownTasks); i++) { - if (FuncIsActiveTask(gUnknown_843ED88[i]) == TRUE) - { - DestroyTask(FindTaskIdByFunc(gUnknown_843ED88[i])); - } + if (FuncIsActiveTask(sShutdownTasks[i]) == TRUE) + DestroyTask(FindTaskIdByFunc(sShutdownTasks[i])); } } -static void CreateTask_LinkLeaderSearchForChildren(void) +static void CreateTask_ParentSearchForChildren(void) { if (QL_IS_PLAYBACK_STATE) return; - Rfu.searchTaskId = CreateTask(Task_LinkLeaderSearchForChildren, 1); + gRfu.searchTaskId = CreateTask(Task_ParentSearchForChildren, 1); } -static bool8 ContactedByParentAttemptingToReconnect(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) -{ - if (Rfu.state == 7 && !rfu_LMAN_CHILD_connectParent(gRfuLinkStatus->partner[Rfu.reconnectedParentIdx].id, 240)) - { - Rfu.state = 9; - return TRUE; - } - return FALSE; -} - -static void CreateTask_JoinGroupSearchForParent(void) +static void CreateTask_ChildSearchForParent(void) { if (QL_IS_PLAYBACK_STATE) return; - 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_80F8FA0(void) +void StopUnionRoomLinkManager(void) { - Rfu.state = 14; + gRfu.state = RFUSTATE_UR_STOP_MANAGER; } // Unused -static void sub_80F8FAC(u8 a0) +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 MoveRecvCmdsToRfuBuffer(void) +static void ReadAllPlayerRecvCmds(void) { s32 i, j; for (i = 0; i < MAX_RFU_PLAYERS; i++) { - struct RfuManager *ptr = &Rfu; + struct RfuManager *ptr = &gRfu; for (j = 0; j < CMD_LENGTH - 1; j++) { ptr->recvCmds[i][j][1] = gRecvCmds[i][j] >> 8; @@ -672,37 +704,31 @@ static void MoveRecvCmdsToRfuBuffer(void) CpuFill16(0, gRecvCmds, sizeof gRecvCmds); } -static void MoveSendCmdToFirstRecvCmd(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.lastCmdBeforeCommInterrupt); - if (Rfu.backupQueue.count == 0) - { - Rfu.linkRecovered = FALSE; - } + bool8 backupEmpty = RfuBackupQueue_Dequeue(&gRfu.backupQueue, gRfu.childSendBuffer); + if (gRfu.backupQueue.count == 0) + gRfu.linkRecovered = FALSE; + if (backupEmpty) - { return; - } } - if (!Rfu.linkRecovered) + if (!gRfu.linkRecovered) { - RfuSendQueue_Dequeue(&Rfu.sendQueue, Rfu.lastCmdBeforeCommInterrupt); - RfuBackupQueue_Enqueue(&Rfu.backupQueue, Rfu.lastCmdBeforeCommInterrupt); + RfuSendQueue_Dequeue(&gRfu.sendQueue, gRfu.childSendBuffer); + RfuBackupQueue_Enqueue(&gRfu.backupQueue, gRfu.childSendBuffer); } } @@ -712,25 +738,19 @@ bool32 IsRfuRecvQueueEmpty(void) s32 j; if (gRfuLinkStatus->sendSlotUNIFlag == 0) - { 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_80F911C(void) +static bool32 RfuMain1_Parent(void) { - if (Rfu.state < 20) + if (gRfu.state < RFUSTATE_FINALIZED) { rfu_REQ_recvData(); rfu_waitREQComplete(); @@ -738,19 +758,19 @@ static bool32 sub_80F911C(void) } else { - Rfu.unk_cdb = FALSE; - if ((Rfu.bm_PartnerFlags & gRfuLinkStatus->connSlotFlag) == Rfu.bm_PartnerFlags && (Rfu.bm_PartnerFlags & 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.bm_DisconnectSlot) + if (gRfu.disconnectSlots) { - RfuReqDisconnectSlot(Rfu.bm_DisconnectSlot); - Rfu.bm_DisconnectSlot = 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) @@ -760,67 +780,65 @@ static bool32 sub_80F911C(void) return FALSE; } } - MoveRecvCmdsToRfuBuffer(); - 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_80F9204(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) + while (!gRfu.parentFinished) { - if (Rfu.errorState != 0) - { + if (gRfu.errorState != RFU_ERROR_STATE_NONE) return FALSE; - } } rfu_REQ_recvData(); rfu_waitREQComplete(); - if ((lman.parentAck_flag & Rfu.bm_PartnerFlags) == Rfu.bm_PartnerFlags) + if ((lman.parentAck_flag & gRfu.parentSlots) == gRfu.parentSlots) { - Rfu.unk_cdc = 0; + gRfu.parentMain2Failed = FALSE; sRfuDebug.recvCount++; flags = lman.acceptSlot_flag; for (i = 0; i < RFU_CHILD_MAX; i++) { if (flags & 1) { - if (Rfu.main_UNI_recvBuffer[i][1]) + if (gRfu.childRecvBuffer[i][1]) { - if (Rfu.unk_cee[i] != 0xFF && (Rfu.main_UNI_recvBuffer[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.main_UNI_recvBuffer[i][0] / 32; - Rfu.unk_cea[i] = 0; - Rfu.main_UNI_recvBuffer[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.main_UNI_recvBuffer[i][(j << 1) + 1] << 8) | Rfu.main_UNI_recvBuffer[i][(j << 1) + 0]; - Rfu.main_UNI_recvBuffer[i][(j << 1) + 1] = 0; - Rfu.main_UNI_recvBuffer[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; } } } @@ -828,62 +846,60 @@ static bool32 sub_80F9204(void) } flags >>= 1; } - MoveSendCmdToFirstRecvCmd(); + MoveSendCmdToRecv(); RfuHandleReceiveCommand(0); CallRfuFunc(); - if (Rfu.bmChatLeaderMaybe && !Rfu.linkClosing) + if (gRfu.nextChildBits && !gRfu.stopNewConnections) { sRfuDebug.unkFlag = FALSE; - rfu_clearSlot(TYPE_UNI_SEND | TYPE_UNI_RECV, Rfu.unk_cda); + rfu_clearSlot(TYPE_UNI_SEND | TYPE_UNI_RECV, gRfu.parentSendSlot); for (i = 0; i < RFU_CHILD_MAX; i++) { - if ((Rfu.bmChatLeaderMaybe >> i) & 1) - { - rfu_setRecvBuffer(TYPE_UNI, i, Rfu.main_UNI_recvBuffer[i], sizeof(Rfu.main_UNI_recvBuffer[i])); - } + if ((gRfu.nextChildBits >> i) & 1) + rfu_setRecvBuffer(TYPE_UNI, i, gRfu.childRecvBuffer[i], sizeof(gRfu.childRecvBuffer[i])); } - ReassignPartnerIds(Rfu.bm_PartnerFlags, Rfu.bm_PartnerFlags | Rfu.bmChatLeaderMaybe); - Rfu.unk_ce9 = Rfu.bmChatLeaderMaybe; - Rfu.bm_PartnerFlags |= Rfu.bmChatLeaderMaybe; - Rfu.bmChatLeaderMaybe = 0; - rfu_UNI_setSendData(Rfu.bm_PartnerFlags, Rfu.recvCmds, sizeof(Rfu.recvCmds)); - Rfu.unk_cda = CountTrailingZeroes(Rfu.bm_PartnerFlags); - 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 = 1; - 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 RfuBufferSendCmd(u16 *sendCmd, u8 *rfuSendBuf) +static void ChildBuildSendCmd(u16 *sendCmd, u8 *dst) { s32 i; if (sendCmd[0]) { - sendCmd[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++) { - rfuSendBuf[2 * i + 1] = sendCmd[i] >> 8; - rfuSendBuf[2 * i + 0] = sendCmd[i]; + dst[2 * i + 1] = sendCmd[i] >> 8; + dst[2 * i + 0] = sendCmd[i]; } } else { - for (i = 0; i < 14; i++) - rfuSendBuf[i] = 0; + for (i = 0; i < 2 * (CMD_LENGTH - 1); i++) + dst[i] = 0; } } -static bool32 RfuProcessEnqueuedRecvBlock(void) +static bool32 RfuMain1_Child(void) { u8 i; u8 j; @@ -891,16 +907,17 @@ static bool32 RfuProcessEnqueuedRecvBlock(void) u8 sendBuf[2 * (CMD_LENGTH - 1)]; u8 status; - RfuRecvQueue_Dequeue(&Rfu.recvQueue, recvBuf); + RfuRecvQueue_Dequeue(&gRfu.recvQueue, recvBuf); for (i = 0; i < MAX_RFU_PLAYERS; i++) { for (j = 0; j < CMD_LENGTH - 1; j++) { - gRecvCmds[i][j] = (recvBuf[i * 14 + (j << 1) + 1] << 8) | recvBuf[i * 14 + (j << 1) + 0]; + gRecvCmds[i][j] = (recvBuf[i * COMM_SLOT_LENGTH + (j * 2) + 1] << 8) + | recvBuf[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(); @@ -908,24 +925,24 @@ static bool32 RfuProcessEnqueuedRecvBlock(void) 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.RfuFunc = 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.sem_UNI_SendRecv) + if (gRfu.childSendCount) { - Rfu.sem_UNI_SendRecv--; + gRfu.childSendCount--; CallRfuFunc(); - RfuBufferSendCmd(gSendCmd, sendBuf); - RfuSendQueue_Enqueue(&Rfu.sendQueue, sendBuf); + ChildBuildSendCmd(gSendCmd, sendBuf); + RfuSendQueue_Enqueue(&gRfu.sendQueue, sendBuf); for (i = 0; i < CMD_LENGTH - 1; i++) gSendCmd[i] = 0; } @@ -936,25 +953,26 @@ static void HandleSendFailure(u8 unused, u32 flags) { s32 i, j, temp; - const u8 *payload = 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_SEND_BLOCK_STEP | 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] = (payload[12 * i + temp + 1] << 8) | payload[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; } @@ -962,32 +980,30 @@ static void HandleSendFailure(u8 unused, u32 flags) void Rfu_SetBlockReceivedFlag(u8 linkPlayerId) { - if (Rfu.parent_child == MODE_PARENT && linkPlayerId != 0) - Rfu.numBlocksReceived[linkPlayerId] = 1; + if (gRfu.parentChild == MODE_PARENT && linkPlayerId != 0) + 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 = RFU_RECV_IDLE; + gRfu.blockReceived[linkPlayerId] = FALSE; + gRfu.recvBlock[linkPlayerId].receiving = RECV_STATE_READY; } -static u8 RfuChildSetReceivedPlayerOrder(const u8 *template) +static u8 LoadLinkPlayerIds(const u8 *ids) { u8 i; - if (Rfu.parent_child == MODE_PARENT) + if (gRfu.parentChild == MODE_PARENT) return FALSE; for (i = 0; i < RFU_CHILD_MAX; i++) - { - Rfu.linkPlayerIdx[i] = template[i]; - } - return template[Rfu.child_slot]; + gRfu.linkPlayerIdx[i] = ids[i]; + return ids[gRfu.childSlot]; } -static void RfuFunc_SendKeysToRfu(void) +static void SendKeysToRfu(void) { static u8 heldKeyCount; if (gReceivedRemoteLinkPlayers @@ -1000,27 +1016,49 @@ static void RfuFunc_SendKeysToRfu(void) } } -struct RfuGameData *GetHostRFUtgtGname(void) +struct RfuGameData *GetHostRfuGameData(void) { return &gHostRfuGameData; } bool32 IsSendingKeysToRfu(void) { - return Rfu.RfuFunc == RfuFunc_SendKeysToRfu; + return gRfu.callback == SendKeysToRfu; } void StartSendingKeysToRfu(void) { +// This is the original symbol and field name, which is baked into the assert below +#define Rfu gRfu +#define RfuFunc callback AGB_ASSERT_EX(Rfu.RfuFunc == NULL, ABSPATH("rfu.c"), 1473); - Rfu.RfuFunc = RfuFunc_SendKeysToRfu; +#undef RfuFunc +#undef Rfu + + gRfu.callback = SendKeysToRfu; } void ClearLinkRfuCallback(void) { - Rfu.RfuFunc = NULL; + gRfu.callback = NULL; } +/* +static void Rfu_BerryBlenderSendHeldKeys(void) +{ + RfuPrepareSendBuffer(RFUCMD_BLENDER_SEND_KEYS); + if (GetMultiplayerId() == 0) + gSendCmd[BLENDER_COMM_ARROW_POS] = GetBlenderArrowPosition(); + gBerryBlenderKeySendAttempts++; +} + +void Rfu_SetBerryBlenderLinkCallback(void) +{ + if (gRfu.callback == NULL) + gRfu.callback = Rfu_BerryBlenderSendHeldKeys; +} +*/ + static void RfuHandleReceiveCommand(u8 unused) { u16 i; @@ -1028,42 +1066,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_PLAYERS_LIST_2: - if (Rfu.parent_child == MODE_CHILD && gReceivedRemoteLinkPlayers) + case RFUCMD_SEND_PLAYER_IDS_NEW: + if (gRfu.parentChild == MODE_CHILD && gReceivedRemoteLinkPlayers) return; // fallthrough - case RFUCMD_PLAYERS_LIST: + case RFUCMD_SEND_PLAYER_IDS: if (gRfuLinkStatus->parentChild == MODE_CHILD) { - Rfu.playerCount = gRecvCmds[i][1]; - Rfu.multiplayerId = RfuChildSetReceivedPlayerOrder((u8 *)(gRecvCmds[i] + 2)); + gRfu.playerCount = gRecvCmds[i][1]; + gRfu.multiplayerId = LoadLinkPlayerIds((u8 *)(gRecvCmds[i] + 2)); } break; case RFUCMD_SEND_BLOCK_INIT: - if (Rfu.recvBlock[i].receiving == RFU_RECV_IDLE) + 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 = RFU_RECV_RECEIVING; - 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_SEND_BLOCK_STEP: - if (Rfu.recvBlock[i].receiving == RFU_RECV_RECEIVING) + 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] & ~RFUCMD_MASK; + 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 = RFU_RECV_FINISHED; + gRfu.recvBlock[i].receiving = RECV_STATE_FINISHED; Rfu_SetBlockReceivedFlag(i); - if (GetHostRFUtgtGname()->activity == (ACTIVITY_CHAT | IN_UNION_ROOM) && gReceivedRemoteLinkPlayers && Rfu.parent_child == MODE_CHILD) + if (GetHostRfuGameData()->activity == (ACTIVITY_CHAT | IN_UNION_ROOM) && gReceivedRemoteLinkPlayers && gRfu.parentChild == MODE_CHILD) ValidateAndReceivePokemonSioInfo(gBlockRecvBuffer); } } @@ -1072,67 +1110,70 @@ 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.resendExitStandbyCount == gRecvCmds[i][1]) - Rfu.readyExitStandby[i] = TRUE; + if (gRfu.resendExitStandbyCount == gRecvCmds[i][1]) + gRfu.readyExitStandby[i] = TRUE; break; - case RFUCMD_PARENT_DISCONNECT: - if (Rfu.parent_child == MODE_CHILD) + case RFUCMD_DISCONNECT: + if (gRfu.parentChild == MODE_CHILD) { + // Disconnect child if (gReceivedRemoteLinkPlayers) { if (gRecvCmds[i][1] & gRfuLinkStatus->connSlotFlag) { gReceivedRemoteLinkPlayers = FALSE; 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_CHILD_DISCONNECT); + // Disconnect parent + RfuPrepareSendBuffer(RFUCMD_DISCONNECT_PARENT); gSendCmd[1] = gRecvCmds[i][1]; gSendCmd[2] = gRecvCmds[i][2]; gSendCmd[3] = gRecvCmds[i][3]; } break; - case RFUCMD_CHILD_DISCONNECT: - if (Rfu.parent_child == MODE_PARENT) + case RFUCMD_DISCONNECT_PARENT: + if (gRfu.parentChild == MODE_PARENT) { - Rfu.bm_DisconnectSlot |= gRecvCmds[i][1]; - Rfu.unk_ce4 = gRecvCmds[i][2]; + gRfu.disconnectSlots |= gRecvCmds[i][1]; + gRfu.disconnectMode = gRecvCmds[i][2]; ClearSelectedLinkPlayerIds(gRecvCmds[i][1]); } break; + //case RFUCMD_BLENDER_SEND_KEYS: case RFUCMD_SEND_HELD_KEYS: gLinkPartnersHeldKeys[i] = gRecvCmds[i][1]; break; } - if (Rfu.parent_child == 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 < 5; i++) + for (i = 0; i < MAX_RFU_PLAYERS; i++) { - if (Rfu.recvBlock[i].receiving != RFU_RECV_IDLE) + if (gRfu.recvBlock[i].receiving != RECV_STATE_READY) return FALSE; } return TRUE; @@ -1142,9 +1183,9 @@ 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 != RFU_RECV_FINISHED || Rfu.blockReceived[i] != TRUE) + if (gRfu.recvBlock[i].receiving != RECV_STATE_FINISHED || gRfu.blockReceived[i] != TRUE) return FALSE; } return TRUE; @@ -1156,9 +1197,9 @@ static void ResetSendDataManager(struct RfuBlockSend *data) data->count = 0; data->payload = NULL; data->receivedFlags = 0; - data->sending = 0; + data->sending = FALSE; data->owner = 0; - data->receiving = RFU_RECV_IDLE; + data->receiving = RECV_STATE_READY; } u8 Rfu_GetBlockReceivedStatus(void) @@ -1166,12 +1207,10 @@ u8 Rfu_GetBlockReceivedStatus(void) u8 flags = 0; s32 i; - for (i = 0; i < 5; i++) + for (i = 0; i < MAX_RFU_PLAYERS; i++) { - if (Rfu.recvBlock[i].receiving == RFU_RECV_FINISHED && Rfu.blockReceived[i] == TRUE) - { + if (gRfu.recvBlock[i].receiving == RECV_STATE_FINISHED && gRfu.blockReceived[i] == TRUE) flags |= (1 << i); - } } return flags; } @@ -1186,36 +1225,35 @@ static void RfuPrepareSendBuffer(u16 command) switch (command) { case RFUCMD_SEND_BLOCK_INIT: - gSendCmd[1] = Rfu.sendBlock.count; - gSendCmd[2] = Rfu.sendBlock.owner + 0x80; + gSendCmd[1] = gRfu.sendBlock.count; + gSendCmd[2] = gRfu.sendBlock.owner + 0x80; break; case RFUCMD_SEND_BLOCK_REQ: - if (AreNoPlayersReceiving()) - gSendCmd[1] = Rfu.cmdA100_blockRequestType; + if (AreAllPlayersReadyToReceive()) + gSendCmd[1] = gRfu.blockRequestType; break; - case RFUCMD_PLAYERS_LIST: - case RFUCMD_PLAYERS_LIST_2: - tmp = Rfu.bm_PartnerFlags ^ Rfu.bm_DisconnectSlot; - Rfu.playerCount = sNumSetBits[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.resendExitStandbyCount; + gSendCmd[1] = gRfu.resendExitStandbyCount; break; case RFUCMD_SEND_PACKET: - for (i = 0; i < 6; i++) - gSendCmd[1 + i] = Rfu.packet[i]; + for (i = 0; i < RFU_PACKET_SIZE; i++) + gSendCmd[1 + i] = gRfu.packet[i]; break; case RFUCMD_SEND_HELD_KEYS: gSendCmd[1] = gHeldKeyCodeToSend; break; - case RFUCMD_CHILD_DISCONNECT: - break; - case RFUCMD_PARENT_DISCONNECT: + case RFUCMD_DISCONNECT_PARENT: + case RFUCMD_DISCONNECT: break; } } @@ -1224,40 +1262,41 @@ void Rfu_SendPacket(void *data) { if (IsSendCmdComplete() && !RfuHasErrored()) { - memcpy(Rfu.packet, data, sizeof(Rfu.packet)); + memcpy(gRfu.packet, data, sizeof(gRfu.packet)); RfuPrepareSendBuffer(RFUCMD_SEND_PACKET); } } bool32 Rfu_InitBlockSend(const u8 *src, size_t size) { - bool8 sizeHasModulo; + bool8 round; AGB_ASSERT_EX(size<=252, ABSPATH("rfu.c"), 1793); - if (Rfu.RfuFunc != NULL) + + if (gRfu.callback != NULL) return FALSE; if (gSendCmd[0] != 0) return FALSE; - if (Rfu.sendBlock.sending != 0) + if (gRfu.sendBlock.sending) { sRfuDebug.blockSendTime++; return FALSE; } - sizeHasModulo = (size % 12) != 0; - Rfu.sendBlock.owner = GetMultiplayerId(); - Rfu.sendBlock.sending = 1; - Rfu.sendBlock.count = (size / 12) + sizeHasModulo; - Rfu.sendBlock.next = 0; - if (size > 0x100) // should never be reached - Rfu.sendBlock.payload = src; + round = (size % 12) != 0; + gRfu.sendBlock.owner = GetMultiplayerId(); + gRfu.sendBlock.sending = TRUE; + gRfu.sendBlock.count = (size / 12) + round; + 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_SEND_BLOCK_INIT); - Rfu.RfuFunc = HandleBlockSend; - Rfu.sendBlockInitDelay = 0; + gRfu.callback = HandleBlockSend; + gRfu.sendBlockInitDelay = 0; return TRUE; } @@ -1266,139 +1305,141 @@ static void HandleBlockSend(void) if (IsSendCmdComplete()) { RfuPrepareSendBuffer(RFUCMD_SEND_BLOCK_INIT); - if (Rfu.parent_child == MODE_PARENT) + if (gRfu.parentChild == MODE_PARENT) { - if (++Rfu.sendBlockInitDelay > 2) - Rfu.RfuFunc = SendNextBlock; + if (++gRfu.sendBlockInitDelay > 2) + gRfu.callback = SendNextBlock; } else { - if ((gRecvCmds[GetMultiplayerId()][0] & 0xff00) == RFUCMD_SEND_BLOCK_INIT) - Rfu.RfuFunc = SendNextBlock; + if ((gRecvCmds[GetMultiplayerId()][0] & RFUCMD_MASK) == RFUCMD_SEND_BLOCK_INIT) + gRfu.callback = SendNextBlock; } } } static void SendNextBlock(void) { s32 i; - const u8 *src = Rfu.sendBlock.payload; - gSendCmd[0] = RFUCMD_SEND_BLOCK_STEP | Rfu.sendBlock.next; - for (i = 0; i < 7; 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) + 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) + 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 = 0; - Rfu.RfuFunc = 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.parent_child == MODE_CHILD) + if (gRfu.parentChild == MODE_CHILD) { - gSendCmd[0] = RFUCMD_SEND_BLOCK_STEP | (Rfu.sendBlock.count - 1); - for (i = 0; i < 7; 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[0] = RFUCMD_SEND_BLOCK | (gRfu.sendBlock.count - 1); + for (i = 0; i < CMD_LENGTH - 1; i++) + 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); + HandleSendFailure(mpId, gRfu.recvBlock[mpId].receivedFlags); sRfuDebug.blockSendFailures++; } else - Rfu.RfuFunc = NULL; + gRfu.callback = NULL; } } else - Rfu.RfuFunc = NULL; + gRfu.callback = NULL; } bool8 Rfu_SendBlockRequest(u8 blockRequestType) { - Rfu.cmdA100_blockRequestType = blockRequestType; + gRfu.blockRequestType = blockRequestType; RfuPrepareSendBuffer(RFUCMD_SEND_BLOCK_REQ); return TRUE; } -static void OnDisconnect_PowerDownRfu(void) +static void RfuShutdownAfterDisconnect(void) { rfu_clearAllSlot(); rfu_LMAN_powerDownRFU(); gReceivedRemoteLinkPlayers = FALSE; - Rfu.isShuttingDown = TRUE; - Rfu.RfuFunc = NULL; + gRfu.isShuttingDown = TRUE; + gRfu.callback = NULL; } static void DisconnectRfu(void) { rfu_REQ_disconnect(gRfuLinkStatus->connSlotFlag | gRfuLinkStatus->linkLossSlotFlag); rfu_waitREQComplete(); - OnDisconnect_PowerDownRfu(); + RfuShutdownAfterDisconnect(); } static void TryDisconnectRfu(void) { - if (Rfu.parent_child == MODE_CHILD) + if (gRfu.parentChild == MODE_CHILD) { rfu_LMAN_requestChangeAgbClockMaster(); - Rfu.unk_ce4 = 2; + gRfu.disconnectMode = RFU_DISCONNECT_NORMAL; } else - Rfu.RfuFunc = DisconnectRfu; + gRfu.callback = DisconnectRfu; } void LinkRfu_FatalError(void) { rfu_LMAN_requestChangeAgbClockMaster(); - Rfu.unk_ce4 = 1; - Rfu.bm_DisconnectSlot = 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 | 0xFFFF0000); - if (Rfu.parent_child == MODE_CHILD) + if (gRfu.parentChild == MODE_CHILD) { - Rfu.errorState = 3; + gRfu.errorState = RFU_ERROR_STATE_DISCONNECTING; TryDisconnectRfu(); } else - Rfu.RfuFunc = TryDisconnectRfu; + gRfu.callback = TryDisconnectRfu; } } static void SendReadyCloseLink(void) { - if (IsSendCmdComplete() && !Rfu.foundNewLeaderMaybe) + if (IsSendCmdComplete() && !gRfu.playerExchangeActive) { RfuPrepareSendBuffer(RFUCMD_READY_CLOSE_LINK); - Rfu.RfuFunc = WaitAllReadyToCloseLink; + gRfu.callback = WaitAllReadyToCloseLink; } } static void Task_TryReadyCloseLink(u8 taskId) { - if (Rfu.RfuFunc == NULL) + if (gRfu.callback == NULL) { - Rfu.linkClosing = TRUE; - Rfu.RfuFunc = SendReadyCloseLink; + gRfu.stopNewConnections = TRUE; + gRfu.callback = SendReadyCloseLink; DestroyTask(taskId); } } @@ -1416,34 +1457,34 @@ static void SendReadyExitStandbyUntilAllReady(void) if (GetMultiplayerId() != 0) // child { - 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] == 0) + if (!gRfu.readyExitStandby[i]) break; } if (i == playerCount) { for (i = 0; i < MAX_RFU_PLAYERS; i++) - Rfu.readyExitStandby[i] = 0; - Rfu.resendExitStandbyCount++; - Rfu.RfuFunc = NULL; + gRfu.readyExitStandby[i] = FALSE; + gRfu.resendExitStandbyCount++; + gRfu.callback = NULL; } - Rfu.resendExitStandbyTimer++; + gRfu.resendExitStandbyTimer++; } static void LinkLeaderReadyToExitStandby(void) { - if (Rfu.recvQueue.count == 0 && IsSendCmdComplete()) + if (gRfu.recvQueue.count == 0 && IsSendCmdComplete()) { RfuPrepareSendBuffer(RFUCMD_READY_EXIT_STANDBY); - Rfu.RfuFunc = SendReadyExitStandbyUntilAllReady; + gRfu.callback = SendReadyExitStandbyUntilAllReady; } } @@ -1453,28 +1494,30 @@ static void Rfu_LinkStandby(void) u8 i; u8 playerCount; - if (GetMultiplayerId() != 0) // child + if (GetMultiplayerId() != 0) { - if (Rfu.recvQueue.count == 0 && IsSendCmdComplete()) + // Not link leader, send exit standby when ready + if (gRfu.recvQueue.count == 0 && IsSendCmdComplete()) { RfuPrepareSendBuffer(RFUCMD_READY_EXIT_STANDBY); - Rfu.RfuFunc = SendReadyExitStandbyUntilAllReady; + gRfu.callback = SendReadyExitStandbyUntilAllReady; } } - else // parent + else { + // Link leader, wait for all members to send exit ready playerCount = GetLinkPlayerCount(); for (i = 1; i < playerCount; i++) { - if (Rfu.readyExitStandby[i] == 0) + if (!gRfu.readyExitStandby[i]) break; } if (i == playerCount) { - if (Rfu.recvQueue.count == 0 && IsSendCmdComplete()) + if (gRfu.recvQueue.count == 0 && IsSendCmdComplete()) { RfuPrepareSendBuffer(RFUCMD_READY_EXIT_STANDBY); - Rfu.RfuFunc = LinkLeaderReadyToExitStandby; + gRfu.callback = LinkLeaderReadyToExitStandby; } } } @@ -1482,10 +1525,10 @@ static void Rfu_LinkStandby(void) void Rfu_SetLinkStandbyCallback(void) { - if (Rfu.RfuFunc == NULL) + if (gRfu.callback == NULL) { - Rfu.RfuFunc = Rfu_LinkStandby; - Rfu.resendExitStandbyTimer = 0; + gRfu.callback = Rfu_LinkStandby; + gRfu.resendExitStandbyTimer = 0; } } @@ -1494,13 +1537,13 @@ 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 ToggleLMANlinkRecovery(bool32 enable) +u8 Rfu_SetLinkRecovery(bool32 enable) { if (!enable) return rfu_LMAN_setLinkRecovery(FALSE, 0); @@ -1508,121 +1551,129 @@ u8 ToggleLMANlinkRecovery(bool32 enable) return 0; } -void Rfu_UnionRoomChat_StopLinkManager(void) +void Rfu_StopPartnerSearch(void) { - Rfu.linkClosing = TRUE; + gRfu.stopNewConnections = TRUE; rfu_LMAN_stopManager(FALSE); } -u8 LinkRfu_GetMultiplayerId(void) +u8 Rfu_GetMultiplayerId(void) { - if (Rfu.parent_child == MODE_PARENT) + if (gRfu.parentChild == MODE_PARENT) return 0; - return Rfu.multiplayerId; + return gRfu.multiplayerId; } -u8 GetRfuPlayerCount(void) +u8 Rfu_GetLinkPlayerCount(void) { - return Rfu.playerCount; + return gRfu.playerCount; } bool8 IsLinkRfuTaskFinished(void) { - return Rfu.RfuFunc != NULL ? FALSE : TRUE; + return gRfu.callback != NULL ? FALSE : TRUE; } static void CallRfuFunc(void) { - if (Rfu.RfuFunc != NULL) - Rfu.RfuFunc(); + if (gRfu.callback != NULL) + gRfu.callback(); } static bool8 CheckForLeavingGroupMembers(void) { s32 i; - bool8 retval = FALSE; + 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 (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); - retval = TRUE; + rfu_NI_setSendData(1 << i, 8, &gRfu.partnerSendStatuses[i], 1); + memberLeft = TRUE; } } - else if (gRfuSlotStatusNI[Rfu.child_slot]->recv.state == SLOT_STATE_RECV_FAILED) + else if (gRfuSlotStatusNI[gRfu.childSlot]->recv.state == SLOT_STATE_RECV_FAILED) { rfu_clearSlot(TYPE_NI_RECV, i); } } } - return retval; + return memberLeft; } -bool32 sub_80FA5D4(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; } -bool32 CheckTrainerHasLeftByIdAndName(u16 trainerId, const u8 *trainerName) +bool32 HasTrainerLeftPartnersList(u16 trainerId, const u8 *name) { - u8 r1 = GetPartnerIndexByNameAndTrainerID(trainerName, trainerId); - if (r1 == 0xFF) + u8 idx = GetPartnerIndexByNameAndTrainerID(name, trainerId); + if (idx == 0xFF) return TRUE; - if (Rfu.partnerSendStatuses[r1] == RFU_STATUS_LEAVE_GROUP) + if (gRfu.partnerSendStatuses[idx] == RFU_STATUS_LEAVE_GROUP) return TRUE; return FALSE; } -void SendByteToPartnerByIdAndName(u8 value, u16 trainerId, const u8 *trainerName) +void SendRfuStatusToPartner(u8 status, u16 trainerId, const u8 *name) { - u8 slotNo = GetPartnerIndexByNameAndTrainerID(trainerName, trainerId); - Rfu.partnerSendStatuses[slotNo] = value; - rfu_clearSlot(TYPE_NI_SEND, slotNo); - rfu_NI_setSendData(1 << slotNo, 8, Rfu.partnerSendStatuses + slotNo, 1); + u8 idx = GetPartnerIndexByNameAndTrainerID(name, trainerId); + gRfu.partnerSendStatuses[idx] = status; + rfu_clearSlot(TYPE_NI_SEND, idx); + rfu_NI_setSendData(1 << idx, 8, &gRfu.partnerSendStatuses[idx], 1); } void SendLeaveGroupNotice(void) { - Rfu.sendStatus = RFU_STATUS_LEAVE_GROUP_NOTICE; - rfu_clearSlot(TYPE_NI_SEND, Rfu.child_slot); - rfu_NI_setSendData(1 << Rfu.child_slot, 8, &Rfu.sendStatus, 1); + gRfu.sendStatus = RFU_STATUS_LEAVE_GROUP_NOTICE; + rfu_clearSlot(TYPE_NI_SEND, gRfu.childSlot); + rfu_NI_setSendData(1 << gRfu.childSlot, 8, &gRfu.sendStatus, 1); } -u32 WaitSendByteToPartnerByIdAndName(u16 trainerId, const u8 *trainerName) +u32 WaitSendRfuStatusToPartner(u16 trainerId, const u8 *name) { - u8 r0 = GetPartnerIndexByNameAndTrainerID(trainerName, trainerId); - if (r0 == 0xFF) + u8 idx = GetPartnerIndexByNameAndTrainerID(name, trainerId); + if (idx == 0xFF) return 2; - if (gRfuSlotStatusNI[r0]->send.state == SLOT_STATE_READY) + if (gRfuSlotStatusNI[idx]->send.state == SLOT_STATE_READY) return 1; return 0; } @@ -1634,114 +1685,119 @@ static void UpdateChildStatuses(void) CheckForLeavingGroupMembers(); for (i = 0; i < RFU_CHILD_MAX; i++) { - if (gRfuSlotStatusNI[i]->send.state == SLOT_STATE_SEND_SUCCESS || gRfuSlotStatusNI[i]->send.state == SLOT_STATE_SEND_FAILED) + 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 GetRfuRecvStatus(void) +static s32 GetJoinGroupStatus(void) { - s32 retval = RFU_STATUS_OK; - if (Rfu.sendStatus == RFU_STATUS_LEAVE_GROUP_NOTICE) + s32 status = RFU_STATUS_OK; + if (gRfu.sendStatus == RFU_STATUS_LEAVE_GROUP_NOTICE) { - if (gRfuSlotStatusNI[Rfu.child_slot]->send.state == SLOT_STATE_SEND_SUCCESS || gRfuSlotStatusNI[Rfu.child_slot]->send.state == SLOT_STATE_SEND_FAILED) - rfu_clearSlot(TYPE_NI_SEND, Rfu.child_slot); + 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.child_slot]->recv.state == SLOT_STATE_RECV_SUCCESS || gRfuSlotStatusNI[Rfu.child_slot]->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.child_slot); - RfuSetStatus(Rfu.recvStatus, 0); - retval = Rfu.recvStatus; + rfu_clearSlot(TYPE_NI_RECV, gRfu.childSlot); + RfuSetStatus(gRfu.recvStatus, 0); + status = gRfu.recvStatus; } - else if (gRfuSlotStatusNI[Rfu.child_slot]->recv.state == SLOT_STATE_RECV_FAILED) + else if (gRfuSlotStatusNI[gRfu.childSlot]->recv.state == SLOT_STATE_RECV_FAILED) { - rfu_clearSlot(TYPE_NI_RECV, Rfu.child_slot); - retval = RFU_STATUS_JOIN_GROUP_NO; + rfu_clearSlot(TYPE_NI_RECV, gRfu.childSlot); + status = RFU_STATUS_JOIN_GROUP_NO; } - return retval; + return status; } -static void sub_80FA834(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.foundNewLeaderMaybe = FALSE; + 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.parent_child == MODE_PARENT) + if (gRfu.parentChild == MODE_PARENT) { if (gReceivedRemoteLinkPlayers) - RfuPrepareSendBuffer(RFUCMD_PLAYERS_LIST_2); + RfuPrepareSendBuffer(RFUCMD_SEND_PLAYER_IDS_NEW); else - RfuPrepareSendBuffer(RFUCMD_PLAYERS_LIST); - 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 (IsSendCmdComplete()) - 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.parent_child == MODE_PARENT) + if (gRfu.parentChild == MODE_PARENT) { - if (AreNoPlayersReceiving()) + if (AreAllPlayersReadyToReceive()) { - Rfu.cmdA100_blockRequestType = BLOCK_REQ_SIZE_NONE; + 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 (AreAllPlayersFinishedReceiving()) - gTasks[taskId].data[0]++; + 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.foundNewLeaderMaybe = FALSE; + gRfu.playerExchangeActive = FALSE; rfu_LMAN_setLinkRecovery(1, 600); - if (Rfu.unionRoomChatters) + if (gRfu.newChildQueue) { for (i = 0; i < RFU_CHILD_MAX; i++) { - if ((Rfu.unionRoomChatters >> i) & 1) + if ((gRfu.newChildQueue >> i) & 1) { - Rfu.bmChatLeaderMaybe = 1 << i; - Rfu.unionRoomChatters ^= (1 << i); + gRfu.nextChildBits = 1 << i; + gRfu.newChildQueue ^= (1 << i); } } } @@ -1749,33 +1805,59 @@ static void sub_80FA834(u8 taskId) } } -static void ClearSelectedLinkPlayerIds(u16 disconnectMask) +static void ClearSelectedLinkPlayerIds(u16 selected) { s32 i; for (i = 0; i < RFU_CHILD_MAX; i++) { - if ((disconnectMask >> i) & 1) - Rfu.linkPlayerIdx[i] = 0; + if ((selected >> i) & 1) + gRfu.linkPlayerIdx[i] = 0; } } -static void ReceiveRfuLinkPlayers(const struct SioInfo *chunk) +static void ReceiveRfuLinkPlayers(const struct SioInfo *sioInfo) { s32 i; - Rfu.playerCount = chunk->playerCount; + gRfu.playerCount = sioInfo->playerCount; for (i = 0; i < RFU_CHILD_MAX; i++) - Rfu.linkPlayerIdx[i] = chunk->linkPlayerIdx[i]; + gRfu.linkPlayerIdx[i] = sioInfo->linkPlayerIdx[i]; for (i = 0; i < MAX_RFU_PLAYERS; i++) { - gLinkPlayers[i] = chunk->linkPlayers[i]; + gLinkPlayers[i] = sioInfo->linkPlayers[i]; ConvertLinkPlayerName(gLinkPlayers + i); } } +// Could be relocated to top of file, but would also require relocating assert strings +static const char sASCII_PokemonSioInfo[] = "PokemonSioInfo"; +static const u8 sText_Akito[] = _(" あきと"); // Presumably "Akito Mori", one of Game Freak's programmers +static const char sASCII_LinkLossDisconnect[] = "LINK LOSS DISCONNECT!"; +static const char sASCII_LinkLossRecoveryNow[] = "LINK LOSS RECOVERY NOW"; +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] = { + " ", + "CLOCK DRIFT", + "BUSY SEND ", + "CMD REJECT ", + "CLOCK SLAVE" +}; + +static const char sASCII_ChildParentSearch[][8] = { + "CHILD ", + "PARENT", + "SEARCH" +}; + static void ValidateAndReceivePokemonSioInfo(void *recvBuffer) { - if (strcmp("PokemonSioInfo", recvBuffer) == 0) + if (strcmp(sASCII_PokemonSioInfo, recvBuffer) == 0) { ReceiveRfuLinkPlayers(recvBuffer); CpuFill16(0, recvBuffer, sizeof(struct SioInfo)); @@ -1783,75 +1865,76 @@ 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[gUnknown_843EC38[Rfu.unk_ce9]]; - if (Rfu.status == 1 || Rfu.status == 2) + 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.foundNewLeaderMaybe = FALSE; + gRfu.playerExchangeActive = FALSE; DestroyTask(taskId); } - switch (gTasks[taskId].data[0]) + switch (gTasks[taskId].tState) { case 0: if (IsSendCmdComplete()) { - ResetBlockReceivedFlag(r4); - RfuPrepareSendBuffer(RFUCMD_PLAYERS_LIST_2); - gTasks[taskId].data[0]++; + ResetBlockReceivedFlag(playerId); + RfuPrepareSendBuffer(RFUCMD_SEND_PLAYER_IDS_NEW); + gTasks[taskId].tState++; } break; case 1: if (IsSendCmdComplete()) - 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: // Prepare send block - r5 = (struct SioInfo *)gBlockSendBuffer; - memcpy(r5->magic, "PokemonSioInfo", sizeof("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.foundNewLeaderMaybe = FALSE; - if (Rfu.unionRoomChatters) + gRfu.playerExchangeActive = FALSE; + if (gRfu.newChildQueue) { for (i = 0; i < RFU_CHILD_MAX; i++) { - if ((Rfu.unionRoomChatters >> i) & 1) + if ((gRfu.newChildQueue >> i) & 1) { - Rfu.bmChatLeaderMaybe = 1 << i; - Rfu.unionRoomChatters ^= (1 << i); - Rfu.foundNewLeaderMaybe = TRUE; + gRfu.nextChildBits = 1 << i; + gRfu.newChildQueue ^= (1 << i); + gRfu.playerExchangeActive = TRUE; break; } } @@ -1862,23 +1945,24 @@ static void Task_ExchangeLinkPlayers(u8 taskId) } } -static void sub_80FACF0(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 != 0) + if (gRfu.playerCount != 0) { 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) @@ -1894,31 +1978,31 @@ static void sub_80FACF0(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) + if (gMain.callback2 == CB2_MysteryGiftEReader) gWirelessCommType = 2; SetMainCallback2(CB2_LinkError); gMain.savedCallback = CB2_LinkError; SetLinkErrorFromRfu( - (Rfu.linkman_msg << 16) | (Rfu.linkman_param[0] << 8) | Rfu.linkman_param[1], - Rfu.recvQueue.count, - Rfu.sendQueue.count, + (gRfu.errorInfo << 16) | (gRfu.errorParams[0] << 8) | gRfu.errorParams[1], + gRfu.recvQueue.count, + gRfu.sendQueue.count, RfuGetStatus() == RFU_STATUS_CONNECTION_ERROR ); - Rfu.errorState = 2; + 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 == MODE_PARENT) { @@ -1928,180 +2012,183 @@ static void rfu_REQ_recvData_then_sendData(void) } } -bool32 LinkRfuMain1(void) +// Rfu equivalent of LinkMain1 +bool32 RfuMain1(void) { bool32 retval = FALSE; - Rfu.parentId = 0; + gRfu.parentId = 0; rfu_LMAN_manager_entity(Random()); - if (!Rfu.isShuttingDown) + if (!gRfu.isShuttingDown) { - switch (Rfu.parent_child) + switch (gRfu.parentChild) { case MODE_PARENT: - sub_80F911C(); + RfuMain1_Parent(); break; case MODE_CHILD: - retval = RfuProcessEnqueuedRecvBlock(); + retval = RfuMain1_Child(); break; case MODE_P_C_SWITCH: - rfu_REQ_recvData_then_sendData(); + RfuMain1_UnionRoom(); break; } } return retval; } -bool32 LinkRfuMain2(void) +// Rfu equivalent of LinkMain2 +bool32 RfuMain2(void) { bool32 retval = FALSE; - if (!Rfu.isShuttingDown) + if (!gRfu.isShuttingDown) { - if (Rfu.parent_child == MODE_PARENT) - retval = sub_80F9204(); + if (gRfu.parentChild == MODE_PARENT) + retval = RfuMain2_Parent(); RfuCheckErrorStatus(); } return retval; } -static void CopyPlayerNameToUnameBuffer(void) +static void SetHostRfuUsername(void) { StringCopy(gHostRfuUsername, gSaveBlock2Ptr->playerName); } -void ClearAndInitHostRFUtgtGname(void) +void ResetHostRfuGameData(void) { memset(&gHostRfuGameData, 0, RFU_GAME_NAME_LENGTH); InitHostRFUtgtGname(&gHostRfuGameData, ACTIVITY_NONE, FALSE, 0); } -void SetHostRFUtgtGname(u8 activity, u32 child_sprite_genders, u32 started) +void SetHostRfuGameData(u8 activity, u32 partnerInfo, u32 startedActivity) { - InitHostRFUtgtGname(&gHostRfuGameData, activity, started, child_sprite_genders); + InitHostRFUtgtGname(&gHostRfuGameData, activity, startedActivity, partnerInfo); } -void SetGnameBufferWonderFlags(bool32 hasNews, bool32 hasCard) +void SetHostRfuWonderFlags(bool32 hasNews, bool32 hasCard) { - gHostRfuGameData.unk_00.hasNews = hasNews; - gHostRfuGameData.unk_00.hasCard = hasCard; + gHostRfuGameData.compatibility.hasNews = hasNews; + gHostRfuGameData.compatibility.hasCard = hasCard; } -void RfuUpdatePlayerGnameStateAndSend(u32 type, u32 species, u32 level) +void SetTradeBoardRegisteredMonInfo(u32 type, u32 species, u32 level) { - gHostRfuGameData.type = type; - gHostRfuGameData.species = species; - gHostRfuGameData.level = level; + gHostRfuGameData.tradeType = type; + gHostRfuGameData.tradeSpecies = species; + gHostRfuGameData.tradeLevel = level; } -void UpdateGameData_GroupLockedIn(bool8 started) +void UpdateGameData_GroupLockedIn(bool8 startedActivity) { - gHostRfuGameData.started = started; - rfu_REQ_configGameData(0, 0x0002, (void *)&gHostRfuGameData, gHostRfuUsername); + gHostRfuGameData.startedActivity = startedActivity; + rfu_REQ_configGameData(0, RFU_SERIAL_GAME, (void *)&gHostRfuGameData, gHostRfuUsername); } -void UpdateGameDataWithActivitySpriteGendersFlag(u8 activity, u32 child_sprite_genders, u32 started) +void UpdateGameData_SetActivity(u8 activity, u32 partnerInfo, u32 startedActivity) { - if (activity) - SetHostRFUtgtGname(activity, child_sprite_genders, started); - rfu_REQ_configGameData(0, 0x0002, (void *)&gHostRfuGameData, gHostRfuUsername); + if (activity != ACTIVITY_NONE) + SetHostRfuGameData(activity, partnerInfo, startedActivity); + rfu_REQ_configGameData(0, RFU_SERIAL_GAME, (void *)&gHostRfuGameData, gHostRfuUsername); } -void sub_80FB030(u32 linkPlayerCount) +void SetUnionRoomChatPlayerData(u32 numPlayers) { s32 i; u32 numConnectedChildren; - u32 child_sprite_genders; - s32 bm_child_slots; + 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; - bm_child_slots = Rfu.bm_PartnerFlags ^ Rfu.bm_DisconnectSlot; + partnerInfo = 0; + slots = gRfu.parentSlots ^ gRfu.disconnectSlots; for (i = 0; i < RFU_CHILD_MAX; i++) { - if ((bm_child_slots >> i) & 1) + if ((slots >> i) & 1) { - // The 0x80 prevents this element from being incorrectly read as a 0. - 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 == linkPlayerCount - 1) + if (numConnectedChildren == numPlayers - 1) break; } } - UpdateGameDataWithActivitySpriteGendersFlag(ACTIVITY_CHAT | IN_UNION_ROOM, child_sprite_genders, 0); + UpdateGameData_SetActivity(ACTIVITY_CHAT | IN_UNION_ROOM, partnerInfo, FALSE); } } -static void GetLinkmanErrorParams(u32 msg) +static void RfuSetErrorParams(u32 errorInfo) { - if (Rfu.errorState == 0) + if (gRfu.errorState == RFU_ERROR_STATE_NONE) { - Rfu.linkman_param[0] = lman.param[0]; - Rfu.linkman_param[1] = lman.param[1]; - Rfu.linkman_msg = msg; - Rfu.errorState = 1; + gRfu.errorParams[0] = lman.param[0]; + gRfu.errorParams[1] = 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_80FB128(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_80FB154(void) +static void DisconnectNewChild(void) { - sub_80FBE20(lman.acceptSlot_flag, 1); - Rfu.RfuFunc = NULL; + SendDisconnectCommand(lman.acceptSlot_flag, RFU_DISCONNECT_ERROR); + gRfu.callback = NULL; } -static void sub_80FB174(void) +static void StartDisconnectNewChild(void) { - Rfu.RfuFunc = sub_80FB154; + gRfu.callback = DisconnectNewChild; } -static void LmanCallback_Parent2(u8 msg, u8 param_count) +static void LinkManagerCB_Parent(u8 msg, u8 param_count) { u8 i; - u8 bmDisconnectFlag = 0; + 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_80FB564(lman.param[0]); + ParentResetChildRecvMetadata(lman.param[0]); for (i = 0; i < RFU_CHILD_MAX; i++) { if ((lman.param[0] >> i) & 1) { struct RfuGameData *structPtr = (void *)&gRfuLinkStatus->partner[i].gname; - if (structPtr->activity == GetHostRFUtgtGname()->activity) + if (structPtr->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 { - bmDisconnectFlag |= (1 << i); + disconnectFlag |= (1 << i); } } } - if (bmDisconnectFlag) + if (disconnectFlag) { - rfu_REQ_disconnect(bmDisconnectFlag); + rfu_REQ_disconnect(disconnectFlag); rfu_waitREQComplete(); } break; @@ -2110,106 +2197,103 @@ static void LmanCallback_Parent2(u8 msg, u8 param_count) 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.bm_PartnerFlags &= ~lman.param[0]; + gRfu.linkLossRecoveryState = 4; + gRfu.parentSlots &= ~lman.param[0]; if (gReceivedRemoteLinkPlayers == 1) { - if (Rfu.bm_PartnerFlags == 0) - GetLinkmanErrorParams(msg); + if (gRfu.parentSlots == 0) + RfuSetErrorParams(msg); else - sub_80FB174(); + 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; } } -static const u8 unref_843EDF3[] = _(" あきと"); - -static void LmanCallback_Child(u8 msg, u8 param_count) +static void LinkManagerCB_Child(u8 msg, u8 param_count) { 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.child_slot = 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.sendStatus = RFU_STATUS_OK; - Rfu.recvStatus = RFU_STATUS_OK; - rfu_setRecvBuffer(TYPE_NI, Rfu.child_slot, &Rfu.recvStatus, 1); - rfu_setRecvBuffer(TYPE_UNI, Rfu.child_slot, Rfu.unk_c3f, sizeof(Rfu.unk_c3f)); + gRfu.state = RFUSTATE_CHILD_TRY_JOIN; + gRfu.sendStatus = RFU_STATUS_OK; + gRfu.recvStatus = RFU_STATUS_OK; + rfu_setRecvBuffer(TYPE_NI, gRfu.childSlot, &gRfu.recvStatus, sizeof(gRfu.recvStatus)); + 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.recvStatus == 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.recvStatus != RFU_STATUS_LEAVE_GROUP) RfuSetStatus(RFU_STATUS_CONNECTION_ERROR, msg); - Debug_PrintString("LINK LOSS DISCONNECT!", 5, 5); + 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; - Debug_PrintString("LINK LOSS RECOVERY NOW", 5, 5); + gRfu.linkLossRecoveryState = 1; + Debug_PrintString(sASCII_LinkLossRecoveryNow, 5, 5); break; case LMAN_MSG_LINK_RECOVERY_SUCCESSED: - Rfu.linkLossRecoveryState = 3; - Rfu.linkRecovered = 1; + 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: @@ -2217,45 +2301,45 @@ static void LmanCallback_Child(u8 msg, u8 param_count) 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_80FB564(s32 bmConnectedFlag) +static void ParentResetChildRecvMetadata(s32 slot) { s32 i; for (i = 0; i < RFU_CHILD_MAX; i++) { - if ((bmConnectedFlag >> 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 bmNewChildSlot) +static u8 GetNewChildrenInUnionRoomChat(s32 emptySlotMask) { u8 ret = 0; u8 i; for (i = 0; i < RFU_CHILD_MAX; i++) { - if ((bmNewChildSlot >> i) & 1) + if ((emptySlotMask >> i) & 1) { - struct RfuGameData *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); } } @@ -2263,77 +2347,77 @@ static u8 GetNewChildrenInUnionRoomChat(s32 bmNewChildSlot) return ret; } -static void LmanCallback_Parent(u8 msg, u8 param_count) +static void LinkManagerCB_UnionRoom(u8 msg, u8 param_count) { - 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.linkClosing) + if (GetHostRfuGameData()->activity == (ACTIVITY_CHAT | IN_UNION_ROOM) && !gRfu.stopNewConnections) { - u8 bmAcceptSlot = GetNewChildrenInUnionRoomChat(lman.param[0]); - if (bmAcceptSlot != 0) + u8 newChildren = GetNewChildrenInUnionRoomChat(lman.param[0]); + if (newChildren != 0) { - r1 = 1 << CountTrailingZeroes(bmAcceptSlot); - if (Rfu.unionRoomChatters == 0 && !Rfu.foundNewLeaderMaybe) + acceptSlot = 1 << Rfu_GetIndexOfNewestChild(newChildren); + if (gRfu.newChildQueue == 0 && !gRfu.playerExchangeActive) { - Rfu.bmChatLeaderMaybe = r1; - Rfu.unionRoomChatters |= (r1 ^ bmAcceptSlot); - Rfu.foundNewLeaderMaybe = TRUE; + gRfu.nextChildBits = acceptSlot; + gRfu.newChildQueue |= (acceptSlot ^ newChildren); + gRfu.playerExchangeActive = TRUE; } else { - Rfu.unionRoomChatters |= bmAcceptSlot; + gRfu.newChildQueue |= newChildren; } } - if (bmAcceptSlot != lman.param[0]) + if (newChildren != lman.param[0]) { - Rfu.bm_DisconnectSlot |= (bmAcceptSlot ^ 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_80FB564(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 << CountTrailingZeroes(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; 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.child_slot = 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_80FC028, 2); + gRfu.connectParentFailures++; + CreateTask(Task_TryConnectToUnionRoomParent, 2); } else { @@ -2341,52 +2425,54 @@ static void LmanCallback_Parent(u8 msg, u8 param_count) } 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.child_slot, Rfu.unk_c3f, sizeof(Rfu.unk_c3f)); + 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 = 1; + gRfu.linkRecovered = TRUE; break; case LMAN_MSG_LINK_LOSS_DETECTED_AND_DISCONNECTED: - Rfu.linkLossRecoveryState = 2; + gRfu.linkLossRecoveryState = 2; // fallthrough case LMAN_MSG_LINK_RECOVERY_FAILED_AND_DISCONNECTED: - if (Rfu.linkLossRecoveryState != 2) - Rfu.linkLossRecoveryState = 4; - if (Rfu.parent_child == MODE_PARENT) + if (gRfu.linkLossRecoveryState != 2) + gRfu.linkLossRecoveryState = 4; + if (gRfu.parentChild == MODE_PARENT) { if (gReceivedRemoteLinkPlayers == 1) { - Rfu.bm_PartnerFlags &= ~(lman.param[0]); - if (Rfu.bm_PartnerFlags == 0) - GetLinkmanErrorParams(msg); + gRfu.parentSlots &= ~(lman.param[0]); + if (gRfu.parentSlots == 0) + RfuSetErrorParams(msg); else - sub_80FB174(); + StartDisconnectNewChild(); } } - else if (Rfu.unk_ce4 != 2 && gReceivedRemoteLinkPlayers == 1) + else if (gRfu.disconnectMode != RFU_DISCONNECT_NORMAL && gReceivedRemoteLinkPlayers == 1) { - GetLinkmanErrorParams(msg); + RfuSetErrorParams(msg); rfu_LMAN_stopManager(0); } - 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 == 0 && + FuncIsActiveTask(Task_UnionRoomListen) == TRUE) + gRfu.state = RFUSTATE_UR_CONNECT; RfuSetStatus(RFU_STATUS_CONNECTION_ERROR, msg); break; case LMAN_MSG_LINK_DISCONNECTED_BY_USER: - Rfu.bm_DisconnectSlot = 0; + gRfu.disconnectSlots = 0; break; case LMAN_MSG_RFU_POWER_DOWN: case LMAN_MSG_MANAGER_STOPPED: @@ -2394,34 +2480,34 @@ static void LmanCallback_Parent(u8 msg, u8 param_count) 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_80FB9D0(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.linkman_msg = msg; + gRfu.status = status; + gRfu.errorInfo = errorInfo; } u8 RfuGetStatus(void) { - return Rfu.status; + return gRfu.status; } bool32 RfuHasErrored(void) @@ -2433,17 +2519,17 @@ bool32 RfuHasErrored(void) return FALSE; } -bool32 RfuHasFoundNewLeader(void) +bool32 Rfu_IsPlayerExchangeActive(void) { - return Rfu.foundNewLeaderMaybe; + return gRfu.playerExchangeActive; } bool8 Rfu_IsMaster(void) { - return Rfu.parent_child; + return gRfu.parentChild; } -void RFUVSync(void) +void RfuVSync(void) { rfu_LMAN_syncVBlank(); } @@ -2453,14 +2539,15 @@ void ClearRecvCommands(void) CpuFill32(0, gRecvCmds, sizeof(gRecvCmds)); } -static void sub_80FBA64(void) +static void VBlank_RfuIdle(void) { LoadOam(); ProcessSpriteCopyRequests(); TransferPlttBuffer(); } -static void sub_80FBA78(void) +// Unused +static void Debug_RfuIdle(void) { s32 i; @@ -2468,14 +2555,14 @@ static void sub_80FBA78(void) FreeAllSpritePalettes(); ResetTasks(); ResetPaletteFade(); - SetVBlankCallback(sub_80FBA64); + SetVBlankCallback(VBlank_RfuIdle); if (IsWirelessAdapterConnected()) { gLinkType = LINKTYPE_TRADE; SetWirelessCommType1(); OpenLink(); SeedRng(gMain.vblankCounter2); - for (i = 0; i < RFU_CHILD_MAX; 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); @@ -2483,29 +2570,29 @@ static void sub_80FBA78(void) AnimateSprites(); BuildOamBuffer(); UpdatePaletteFade(); - LinkRfu_CreateIdleTask(); - SetMainCallback2(sub_80FBB74); + CreateTask_RfuIdle(); + SetMainCallback2(CB2_RfuIdle); } } bool32 IsUnionRoomListenTaskActive(void) { - return FuncIsActiveTask(Task_LinkRfu_UnionRoomListen); + return FuncIsActiveTask(Task_UnionRoomListen); } -void LinkRfu_CreateIdleTask(void) +void CreateTask_RfuIdle(void) { - if (!FuncIsActiveTask(Task_idle)) - Rfu.idleTaskId = CreateTask(Task_idle, 0); + if (!FuncIsActiveTask(Task_Idle)) + gRfu.idleTaskId = CreateTask(Task_Idle, 0); } -void LinkRfu_DestroyIdleTask(void) +void DestroyTask_RfuIdle(void) { - if (FuncIsActiveTask(Task_idle) == TRUE) - DestroyTask(Rfu.idleTaskId); + if (FuncIsActiveTask(Task_Idle) == TRUE) + DestroyTask(gRfu.idleTaskId); } -static void sub_80FBB74(void) +static void CB2_RfuIdle(void) { RunTasks(); AnimateSprites(); @@ -2513,35 +2600,35 @@ static void sub_80FBB74(void) UpdatePaletteFade(); } -void InitializeRfuLinkManager_LinkLeader(u32 availSlots) +void InitializeRfuLinkManager_LinkLeader(u32 groupMax) { - Rfu.parent_child = MODE_PARENT; - CopyPlayerNameToUnameBuffer(); - rfu_LMAN_initializeManager(LmanCallback_Parent2, NULL); + gRfu.parentChild = MODE_PARENT; + SetHostRfuUsername(); + rfu_LMAN_initializeManager(LinkManagerCB_Parent, NULL); sRfuReqConfig = sRfuReqConfigTemplate; - sRfuReqConfig.availSlot_flag = sAvailSlots[availSlots - 1]; - CreateTask_LinkLeaderSearchForChildren(); + sRfuReqConfig.availSlot_flag = sAvailSlots[groupMax - 1]; + CreateTask_ParentSearchForChildren(); } void InitializeRfuLinkManager_JoinGroup(void) { - Rfu.parent_child = MODE_CHILD; - CopyPlayerNameToUnameBuffer(); - rfu_LMAN_initializeManager(LmanCallback_Child, MscCallback_Child); - CreateTask_JoinGroupSearchForParent(); + gRfu.parentChild = MODE_CHILD; + SetHostRfuUsername(); + rfu_LMAN_initializeManager(LinkManagerCB_Child, MscCallback_Child); + CreateTask_ChildSearchForParent(); } void InitializeRfuLinkManager_EnterUnionRoom(void) { if (QL_IS_PLAYBACK_STATE) return; - Rfu.parent_child = 2; - CopyPlayerNameToUnameBuffer(); - rfu_LMAN_initializeManager(LmanCallback_Parent, 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) @@ -2557,169 +2644,186 @@ static u16 ReadU16(const void *ptr) * Returns 0xFF if not found. * ================================================================ */ -static u8 GetPartnerIndexByNameAndTrainerID(const u8 *trainerName, u16 trainerId) +static u8 GetPartnerIndexByNameAndTrainerID(const u8 *name, u16 trainerId) { u8 i; - u8 ret = 0xFF; + u8 idx = 0xFF; for (i = 0; i < RFU_CHILD_MAX; i++) { - u16 partnerTrainerId = ReadU16(((struct RfuGameData *)gRfuLinkStatus->partner[i].gname)->unk_00.playerTrainerId); + u16 partnerTrainerId = ReadU16(((struct RfuGameData *)gRfuLinkStatus->partner[i].gname)->compatibility.playerTrainerId); if (IsRfuSerialNumberValid(gRfuLinkStatus->partner[i].serialNo) - && !StringCompare(trainerName, gRfuLinkStatus->partner[i].uname) + && !StringCompare(name, gRfuLinkStatus->partner[i].uname) && trainerId == partnerTrainerId) { - ret = i; + idx = i; if (gRfuLinkStatus->partner[i].slot != 0xFF) break; } } - return ret; + return idx; } -static void RfuReqDisconnectSlot(u32 bmDisconnectSlot) +static void RfuReqDisconnectSlot(u32 slot) { - rfu_REQ_disconnect(bmDisconnectSlot); + rfu_REQ_disconnect(slot); rfu_waitREQComplete(); - Rfu.bm_PartnerFlags &= ~(bmDisconnectSlot); - rfu_clearSlot(TYPE_UNI_SEND, Rfu.unk_cda); - rfu_UNI_setSendData(Rfu.bm_PartnerFlags, Rfu.recvCmds, 70); - Rfu.unk_cda = CountTrailingZeroes(Rfu.bm_PartnerFlags); + gRfu.parentSlots &= ~slot; + rfu_clearSlot(TYPE_UNI_SEND, gRfu.parentSendSlot); + rfu_UNI_setSendData(gRfu.parentSlots, gRfu.recvCmds, sizeof(gRfu.recvCmds)); + gRfu.parentSendSlot = Rfu_GetIndexOfNewestChild(gRfu.parentSlots); } void RequestDisconnectSlotByTrainerNameAndId(const u8 *trainerName, u16 trainerId) { - u8 var = GetPartnerIndexByNameAndTrainerID(trainerName, trainerId); - if (var != 0xFF) - RfuReqDisconnectSlot(1 << var); + u8 index = GetPartnerIndexByNameAndTrainerID(trainerName, trainerId); + if (index != 0xFF) + RfuReqDisconnectSlot(1 << index); } -void sub_80FBD6C(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.bm_PartnerFlags >> i) & 1) - var |= 1 << i; + if (gRfu.linkPlayerIdx[i] == playerIdx && (gRfu.parentSlots >> i) & 1) + toDisconnect |= 1 << i; } - if (var) - sub_80FBE20(var, 2); + if (toDisconnect) + SendDisconnectCommand(toDisconnect, RFU_DISCONNECT_NORMAL); } } -static void sub_80FBDB8(u8 taskId) +#define tDisconnectPlayers data[0] +#define tDisconnectMode data[1] + +static void Task_SendDisconnectCommand(u8 taskId) { - if (IsSendCmdComplete() && !Rfu.foundNewLeaderMaybe) + if (IsSendCmdComplete() && !gRfu.playerExchangeActive) { - RfuPrepareSendBuffer(RFUCMD_PARENT_DISCONNECT); - gSendCmd[1] = gTasks[taskId].data[0]; - gSendCmd[2] = gTasks[taskId].data[1]; - Rfu.playerCount -= sNumSetBits[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_80FBE20(u32 a0, u32 a1) +static void SendDisconnectCommand(u32 playersToDisconnect, u32 disconnectMode) { - u8 taskId = FindTaskIdByFunc(sub_80FBDB8); - if (taskId == 0xFF) + u8 taskId = FindTaskIdByFunc(Task_SendDisconnectCommand); + if (taskId == TASK_NONE) { - taskId = CreateTask(sub_80FBDB8, 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 tDisconnectPlayers +#undef tDisconnectMode + +#define tTime data[15] + static void Task_RfuReconnectWithParent(u8 taskId) { s16 *data = gTasks[taskId].data; - if (ContactedByParentAttemptingToReconnect()) + if (CanTryReconnectParent()) { u8 id = GetPartnerIndexByNameAndTrainerID((u8 *)data, ReadU16(&data[8])); if (id != 0xFF) { if (gRfuLinkStatus->partner[id].slot != 0xFF) { - Rfu.reconnectedParentIdx = id; - if (IsParentSuccessfullyReconnected()) + gRfu.reconnectParentId = id; + if (TryReconnectParent()) DestroyTask(taskId); } - else if (GetHostRFUtgtGname()->activity == ACTIVITY_WCARD2 || GetHostRFUtgtGname()->activity == ACTIVITY_WNEWS2) + else if (GetHostRfuGameData()->activity == ACTIVITY_WCARD2 + || GetHostRfuGameData()->activity == ACTIVITY_WNEWS2) { - 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.reconnectedParentIdx = 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); } } -void CreateTask_RfuReconnectWithParent(const u8 *trainerName, u16 trainerId) +#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), trainerName); + StringCopy((u8 *)(data), name); data[8] = trainerId; } -static bool32 ShouldRejectPartnerConnectionBasedOnActivity(s16 activity, struct RfuGameData *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 RfuGameData *myTradeGname = (struct RfuGameData *)&Rfu.tgtData.gname; - if (myTradeGname->species == SPECIES_EGG) + // Verify that the trade offered hasn't changed + struct RfuGameData *original = (struct RfuGameData *)&gRfu.parent.gname; + if (original->tradeSpecies == SPECIES_EGG) { - if (partnerGname->species == myTradeGname->species) + if (partner->tradeSpecies == original->tradeSpecies) return FALSE; else return TRUE; } - else if (partnerGname->species != myTradeGname->species - || partnerGname->level != myTradeGname->level - || partnerGname->type != myTradeGname->type) + else if (partner->tradeSpecies != original->tradeSpecies + || partner->tradeLevel != original->tradeLevel + || partner->tradeType != original->tradeType) { return TRUE; } @@ -2728,79 +2832,92 @@ static bool32 ShouldRejectPartnerConnectionBasedOnActivity(s16 activity, struct return FALSE; } -static void sub_80FC028(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) { - 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 == MODE_CHILD) + // Check if parent should be searched for + if (gRfu.parentId != 0 && lman.parent_child == MODE_CHILD) { - u16 trainerId = ReadU16(((struct RfuGameData *)&Rfu.tgtData.gname)->unk_00.playerTrainerId); - u8 id = GetPartnerIndexByNameAndTrainerID(Rfu.tgtData.uname, trainerId); + // Search for parent + u16 trainerId = ReadU16(((struct RfuGameData *)&gRfu.parent.gname)->compatibility.playerTrainerId); + u8 id = GetPartnerIndexByNameAndTrainerID(gRfu.parent.uname, trainerId); if (id != 0xFF) { - if (!ShouldRejectPartnerConnectionBasedOnActivity(gTasks[taskId].data[1], (struct RfuGameData *)&gRfuLinkStatus->partner[id].gname)) + // Parent found, try to connect + if (!IsPartnerActivityIncompatible(gTasks[taskId].data[1], (struct RfuGameData *)&gRfuLinkStatus->partner[id].gname)) { if (gRfuLinkStatus->partner[id].slot != 0xFF && !rfu_LMAN_CHILD_connectParent(gRfuLinkStatus->partner[id].id, 90)) { - Rfu.state = 10; + // 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_80FC114(const u8 *name, struct RfuGameData *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.tgtData.uname, name); - memcpy(Rfu.tgtData.gname, structPtr, RFU_GAME_NAME_LENGTH); + gRfu.connectParentFailures = 0; + gRfu.status = RFU_STATUS_OK; + StringCopy(gRfu.parent.uname, name); + memcpy(gRfu.parent.gname, parent, RFU_GAME_NAME_LENGTH); rfu_LMAN_forceChangeSP(); - taskId = CreateTask(sub_80FC028, 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 != 0xFF) - gTasks[taskId2].data[7] = 1; + if (listenTaskId != TASK_NONE) + gTasks[listenTaskId].tConnectingForChat = TRUE; } else { - if (taskId2 != 0xFF) - 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_80FC1CC(void) +bool32 IsRfuCommunicatingWithAllChildren(void) { s32 i; for (i = 0; i < RFU_CHILD_MAX; i++) { - if ((lman.acceptSlot_flag >> i) & 1 && Rfu.partnerSendStatuses[i] == 0) + // 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; } @@ -2812,30 +2929,17 @@ static void Debug_PrintEmpty(void) s32 i; for (i = 0; i < 20; i++) - Debug_PrintString(" ", 0, i); + Debug_PrintString(sASCII_30Spaces, 0, i); } -static const char gUnknown_843EE47[16] = { - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - '\0' -}; - -static const char gUnknown_843EE57[9] = { - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - '\0' -}; - -static const char gUnknown_843EE60[] = {' ', '\0'}; -static const char gUnknown_843EE62[] = {'*', '\0'}; - 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.parent_child == 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++) { @@ -2843,29 +2947,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 < 14; j++) - { - Debug_PrintNum(Rfu.main_UNI_recvBuffer[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("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(gUnknown_843EE47, 6, i + 3); - Debug_PrintString(gUnknown_843EE57, 0x16, i + 3); + Debug_PrintString(sASCII_15Spaces, 6, i + 3); + Debug_PrintString(sASCII_8Spaces, 22, i + 3); } - Debug_PrintNum(gRfuLinkStatus->partner[Rfu.child_slot].serialNo, 1, 3, 4); - Debug_PrintString(gRfuLinkStatus->partner[Rfu.child_slot].gname, 6, 3); - Debug_PrintString(gRfuLinkStatus->partner[Rfu.child_slot].uname, 0x16, 3); + Debug_PrintNum(gRfuLinkStatus->partner[gRfu.childSlot].serialNo, 1, 3, 4); + Debug_PrintString(gRfuLinkStatus->partner[gRfu.childSlot].gname, 6, 3); + Debug_PrintString(gRfuLinkStatus->partner[gRfu.childSlot].uname, 22, 3); } else { @@ -2875,43 +2977,29 @@ 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(gUnknown_843EE47, 6, i + 3); - Debug_PrintString(gUnknown_843EE57, 0x16, i + 3); + Debug_PrintString(sASCII_15Spaces, 6, i + 3); + Debug_PrintString(sASCII_8Spaces, 22, i + 3); } } } -static const char gUnknown_843EE6C[][12] = { - " ", - "CLOCK DRIFT", - "BUSY SEND ", - "CMD REJECT ", - "CLOCK SLAVE" -}; - -static const char gUnknown_843EEA8[][8] = { - "CHILD ", - "PARENT", - "SEARCH" -}; - 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) +static void Task_Idle(u8 taskId) { } diff --git a/src/link_rfu_3.c b/src/link_rfu_3.c index 647658c7e..f47b71829 100644 --- a/src/link_rfu_3.c +++ b/src/link_rfu_3.c @@ -298,10 +298,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->send_slot = 0; queue->recv_slot = 0; @@ -316,10 +314,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->send_slot = 0; queue->recv_slot = 0; @@ -356,26 +352,20 @@ void RfuRecvQueue_Enqueue(struct RfuRecvQueue *queue, u8 *src) 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 (src[i] == 0 && src[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->recv_slot][i] = src[i]; - } queue->recv_slot++; queue->recv_slot %= 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++) src[i] = 0; - } } REG_IME = imeBak; } @@ -394,26 +384,20 @@ void RfuSendQueue_Enqueue(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++) { if (src[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->recv_slot][i] = src[i]; - } queue->recv_slot++; queue->recv_slot %= SEND_QUEUE_NUM_SLOTS; queue->count++; - for (i = 0; i < SEND_QUEUE_SLOT_LENGTH; i++) - { + for (i = 0; i < COMM_SLOT_LENGTH; i++) src[i] = 0; - } } REG_IME = imeBak; } @@ -432,17 +416,13 @@ bool8 RfuRecvQueue_Dequeue(struct RfuRecvQueue *queue, u8 *dest) REG_IME = 0; if (queue->recv_slot == queue->send_slot || queue->full) { - for (i = 0; i < RECV_QUEUE_SLOT_LENGTH; i++) - { + for (i = 0; i < COMM_SLOT_LENGTH * MAX_RFU_PLAYERS; i++) dest[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++) dest[i] = queue->slots[queue->send_slot][i]; - } queue->send_slot++; queue->send_slot %= RECV_QUEUE_NUM_SLOTS; queue->count--; @@ -456,15 +436,11 @@ bool8 RfuSendQueue_Dequeue(struct RfuSendQueue *queue, u8 *dest) u16 imeBak; if (queue->recv_slot == queue->send_slot || queue->full) - { return FALSE; - } imeBak = REG_IME; REG_IME = 0; - for (i = 0; i < SEND_QUEUE_SLOT_LENGTH; i++) - { + for (i = 0; i < COMM_SLOT_LENGTH; i++) dest[i] = queue->slots[queue->send_slot][i]; - } queue->send_slot++; queue->send_slot %= SEND_QUEUE_NUM_SLOTS; queue->count--; @@ -482,10 +458,8 @@ void RfuBackupQueue_Enqueue(struct RfuBackupQueue *queue, const u8 *dest) } else { - for (i = 0; i < BACKUP_QUEUE_SLOT_LENGTH; i++) - { + for (i = 0; i < COMM_SLOT_LENGTH; i++) queue->slots[queue->recv_slot][i] = dest[i]; - } queue->recv_slot++; queue->recv_slot %= BACKUP_QUEUE_NUM_SLOTS; if (queue->count < BACKUP_QUEUE_NUM_SLOTS) @@ -509,10 +483,8 @@ bool8 RfuBackupQueue_Dequeue(struct RfuBackupQueue *queue, u8 *dest) } if (dest != NULL) { - for (i = 0; i < BACKUP_QUEUE_SLOT_LENGTH; i++) - { + for (i = 0; i < COMM_SLOT_LENGTH; i++) dest[i] = queue->slots[queue->send_slot][i]; - } } queue->send_slot++; queue->send_slot %= BACKUP_QUEUE_NUM_SLOTS; @@ -672,30 +644,30 @@ static u8 GetConnectedChildStrength(u8 maxFlags) return 0; } -void InitHostRFUtgtGname(struct RfuGameData *data, u8 activity, bool32 started, s32 child_sprite_genders) +void InitHostRFUtgtGname(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]; + 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; } 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_SYS_CAN_LINK_WITH_RS); - 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_SYS_CAN_LINK_WITH_RS); + data->compatibility.hasNationalDex = IsNationalPokedexEnabled(); + data->compatibility.gameClear = FlagGet(FLAG_SYS_GAME_CLEAR); } /* @@ -749,7 +721,7 @@ bool8 LinkRfu_GetNameIfCompatible(struct RfuGameData *gname, u8 *uname, u8 idx) bool8 LinkRfu_GetNameIfSerial7F7D(struct RfuGameData *gname, u8 *uname, u8 idx) { bool8 retVal = FALSE; - if (gRfuLinkStatus->partner[idx].serialNo == RFU_SERIAL_7F7D) + if (gRfuLinkStatus->partner[idx].serialNo == RFU_SERIAL_WONDER_DISTRIBUTOR) { memcpy(gname, gRfuLinkStatus->partner[idx].gname, RFU_GAME_NAME_LENGTH); memcpy(uname, gRfuLinkStatus->partner[idx].uname, RFU_USER_NAME_LENGTH); diff --git a/src/main.c b/src/main.c index 368638022..5efaaf6d1 100644 --- a/src/main.c +++ b/src/main.c @@ -358,7 +358,7 @@ extern void ProcessDma3Requests(void); static void VBlankIntr(void) { if (gWirelessCommType) - RFUVSync(); + RfuVSync(); else if (!gLinkVSyncDisabled) LinkVSync(); diff --git a/src/mystery_gift_menu.c b/src/mystery_gift_menu.c index 3dfce13a0..380e0b264 100644 --- a/src/mystery_gift_menu.c +++ b/src/mystery_gift_menu.c @@ -354,7 +354,7 @@ void vblankcb_mystery_gift_e_reader_run(void) TransferPlttBuffer(); } -void c2_mystery_gift_e_reader_run(void) +void CB2_MysteryGiftEReader(void) { RunTasks(); RunTextPrinters(); @@ -434,7 +434,7 @@ void c2_mystery_gift(void) { if (HandleMysteryGiftOrEReaderSetup(0)) { - SetMainCallback2(c2_mystery_gift_e_reader_run); + SetMainCallback2(CB2_MysteryGiftEReader); gGiftIsFromEReader = FALSE; task_add_00_mystery_gift(); } @@ -444,7 +444,7 @@ void c2_ereader(void) { if (HandleMysteryGiftOrEReaderSetup(1)) { - SetMainCallback2(c2_mystery_gift_e_reader_run); + SetMainCallback2(CB2_MysteryGiftEReader); gGiftIsFromEReader = TRUE; task_add_00_ereader(); } diff --git a/src/overworld.c b/src/overworld.c index 8c6037ca3..61e1a1db7 100644 --- a/src/overworld.c +++ b/src/overworld.c @@ -3239,7 +3239,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 7725a3c3d..84b9b5807 100644 --- a/src/party_menu.c +++ b/src/party_menu.c @@ -3851,7 +3851,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 RfuGameCompatibilityData *)GetHostRFUtgtGname(), species2, species, isEventLegal)) + switch (CanRegisterMonForTradingBoard(*(struct RfuGameCompatibilityData *)GetHostRfuGameData(), species2, species, isEventLegal)) { case CANT_REGISTER_MON: StringExpandPlaceholders(gStringVar4, gText_PkmnCantBeTradedNow); @@ -3877,7 +3877,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 RfuGameCompatibilityData *)GetHostRFUtgtGname(), gPartnerTgtGnameSub, species2, gUnionRoomOfferedSpecies, gUnionRoomRequestedMonType, species, isEventLegal); + u32 stringId = GetUnionRoomTradeMessageId(*(struct RfuGameCompatibilityData *)GetHostRfuGameData(), gPartnerTgtGnameSub, species2, gUnionRoomOfferedSpecies, gUnionRoomRequestedMonType, species, isEventLegal); if (stringId != UR_TRADE_MSG_NONE) { diff --git a/src/pokemon_jump.c b/src/pokemon_jump.c index 39e13f786..c2e89b8be 100644 --- a/src/pokemon_jump.c +++ b/src/pokemon_jump.c @@ -2540,7 +2540,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) diff --git a/src/rfu_union_tool.c b/src/rfu_union_tool.c index dc9782d47..51b6106d5 100644 --- a/src/rfu_union_tool.c +++ b/src/rfu_union_tool.c @@ -524,17 +524,17 @@ static void AssembleGroup(u32 group, struct RfuGameData * gname) { return; } - SpawnGroupMember(group, 0, GetUnionRoomPlayerGraphicsId(gname->playerGender, gname->unk_00.playerTrainerId[0]), gname); + SpawnGroupMember(group, 0, GetUnionRoomPlayerGraphicsId(gname->playerGender, gname->compatibility.playerTrainerId[0]), gname); } for (i = 1; i < 5; i++) { - if (gname->child_sprite_gender[i - 1] == 0) + if (gname->partnerInfo[i - 1] == 0) { DespawnGroupMember(group, i); } else if (IsUnionRoomPlayerFacingTileAt(group, i, x, y) == FALSE && IsUnionRoomPlayerFacingTileAt(group, i, x2, y2) == FALSE) { - SpawnGroupMember(group, i, GetUnionRoomPlayerGraphicsId((gname->child_sprite_gender[i - 1] >> 3) & 1, gname->child_sprite_gender[i - 1] & 7), gname); + SpawnGroupMember(group, i, GetUnionRoomPlayerGraphicsId((gname->partnerInfo[i - 1] >> 3) & 1, gname->partnerInfo[i - 1] & 7), gname); } } } @@ -546,7 +546,7 @@ static void SpawnGroupLeaderAndMembers(u32 group, struct RfuGameData * gname) { case 0x40: case 0x54: - SpawnGroupLeader(group, gname->playerGender, gname->unk_00.playerTrainerId[0]); + SpawnGroupLeader(group, gname->playerGender, gname->compatibility.playerTrainerId[0]); for (i = 0; i < 5; i++) { DespawnGroupMember(group, i); diff --git a/src/trade.c b/src/trade.c index 9687bc988..e8ada5673 100644 --- a/src/trade.c +++ b/src/trade.c @@ -759,7 +759,7 @@ static void CB2_ReturnFromLinkTrade2(void) { SetWirelessCommType1(); OpenLink(); - LinkRfu_CreateIdleTask(); + CreateTask_RfuIdle(); } else { @@ -802,13 +802,13 @@ static void CB2_ReturnFromLinkTrade2(void) case 4: if (gReceivedRemoteLinkPlayers == TRUE && IsLinkPlayerDataExchangeComplete() == TRUE) { - LinkRfu_DestroyIdleTask(); + DestroyTask_RfuIdle(); CalculatePlayerPartyCount(); gMain.state++; sTradeMenuResourcesPtr->loadUISpritesState = 0; if (gWirelessCommType) { - ToggleLMANlinkRecovery(TRUE); + Rfu_SetLinkRecovery(TRUE); SetLinkStandbyCallback(); } } @@ -2019,7 +2019,7 @@ static void TradeMenuCB_12(void) static void TradeMenuCB_16(void) { - if (!ToggleLMANlinkRecovery(FALSE)) + if (!Rfu_SetLinkRecovery(FALSE)) { SetLinkStandbyCallback(); sTradeMenuResourcesPtr->tradeMenuCBnum = 13; diff --git a/src/union_room.c b/src/union_room.c index 5369225de..c4c7e7a27 100644 --- a/src/union_room.c +++ b/src/union_room.c @@ -646,12 +646,12 @@ static const u8 sUnref_84570D1[] = _("{DYNAMIC 00}·{DYNAMIC 01}"); #define IntlConvPartnerUname7(dest, arg1) ({ \ StringCopy_PlayerName(dest, (arg1).gname_uname.uname); \ - ConvertInternationalString(dest, (arg1).gname_uname.gname.unk_00.language); \ + ConvertInternationalString(dest, (arg1).gname_uname.gname.compatibility.language); \ }) #define IntlConvPartnerUname(dest, arg1) ({ \ StringCopy(dest, (arg1).gname_uname.uname); \ - ConvertInternationalString(dest, (arg1).gname_uname.gname.unk_00.language); \ + ConvertInternationalString(dest, (arg1).gname_uname.gname.compatibility.language); \ }) #define CopyTrainerCardData(dest, src, _version) ({ \ @@ -744,7 +744,7 @@ static void Task_TryBecomeLinkLeader(u8 taskId) case 0: sPlayerCurrActivity = sLinkGroupToActivityAndCapacity[gSpecialVar_0x8004]; sPlayerActivityGroupSize = sLinkGroupToActivityAndCapacity[gSpecialVar_0x8004] >> 8; - SetHostRFUtgtGname(sPlayerCurrActivity, 0, 0); + SetHostRfuGameData(sPlayerCurrActivity, 0, 0); SetWirelessCommType1(); OpenLink(); InitializeRfuLinkManager_LinkLeader(sPlayerActivityGroupSize & 0xF); @@ -819,19 +819,19 @@ static void Task_TryBecomeLinkLeader(u8 taskId) if ((sPlayerActivityGroupSize >> 4) != 0 && data->playerCount > (sPlayerActivityGroupSize >> 4) - 1 && (sPlayerActivityGroupSize & 0xF) != 0 - && sub_80FC1CC() + && IsRfuCommunicatingWithAllChildren() && JOY_NEW(START_BUTTON)) { data->state = 15; LinkRfu_StopManagerAndFinalizeSlots(); } - if (data->state == 6 && sub_80FA5D4()) + if (data->state == 6 && RfuTryDisconnectLeavingChildren()) { data->state = 9; } break; case 9: - if (!sub_80FA5D4()) + if (!RfuTryDisconnectLeavingChildren()) { data->state = 6; data->playerCount = UnionRoomLeaderField0CompactionAndCount(data->field_0); @@ -861,21 +861,21 @@ static void Task_TryBecomeLinkLeader(u8 taskId) } break; case 11: - switch (UnionRoomHandleYesNo(&data->textState, CheckTrainerHasLeftByIdAndName( - ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.unk_00.playerTrainerId), + switch (UnionRoomHandleYesNo(&data->textState, HasTrainerLeftPartnersList( + ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.compatibility.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.uname))) { case 0: LoadWirelessStatusIndicatorSpriteGfx(); CreateWirelessStatusIndicatorSprite(0, 0); data->field_19 = 5; - SendByteToPartnerByIdAndName(5, ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.unk_00.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.uname); + SendRfuStatusToPartner(5, ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.compatibility.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.uname); data->state = 12; break; case 1: case -1: data->field_19 = 6; - SendByteToPartnerByIdAndName(6, ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.unk_00.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.uname); + SendRfuStatusToPartner(6, ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.compatibility.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.uname); data->state = 12; break; case -3: @@ -884,7 +884,7 @@ static void Task_TryBecomeLinkLeader(u8 taskId) } break; case 12: - val = WaitSendByteToPartnerByIdAndName(ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.unk_00.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.uname); + val = WaitSendRfuStatusToPartner(ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.compatibility.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.uname); if (val == 1) { // Xfer complete @@ -918,7 +918,7 @@ static void Task_TryBecomeLinkLeader(u8 taskId) else { // Sent "no" - RequestDisconnectSlotByTrainerNameAndId(data->field_0->arr[data->playerCount].gname_uname.uname, ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.unk_00.playerTrainerId)); + RequestDisconnectSlotByTrainerNameAndId(data->field_0->arr[data->playerCount].gname_uname.uname, ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.compatibility.playerTrainerId)); data->field_0->arr[data->playerCount].groupScheduledAnim = UNION_ROOM_SPAWN_NONE; UnionRoomLeaderField0CompactionAndCount(data->field_0); RedrawListMenu(data->listTaskId); @@ -1287,7 +1287,7 @@ static void Task_TryJoinLinkGroup(u8 taskId) switch (data->state) { case 0: - SetHostRFUtgtGname(sLinkGroupToURoomActivity[gSpecialVar_0x8004], 0, 0); + SetHostRfuGameData(sLinkGroupToURoomActivity[gSpecialVar_0x8004], 0, 0); sPlayerCurrActivity = sLinkGroupToURoomActivity[gSpecialVar_0x8004]; SetWirelessCommType1(); OpenLink(); @@ -1343,7 +1343,7 @@ static void Task_TryJoinLinkGroup(u8 taskId) u32 unusedVar; unusedVar = data->field_0->arr[id].gname_uname.gname.activity; - if (data->field_0->arr[id].groupScheduledAnim == UNION_ROOM_SPAWN_IN && !data->field_0->arr[id].gname_uname.gname.started) + if (data->field_0->arr[id].groupScheduledAnim == UNION_ROOM_SPAWN_IN && !data->field_0->arr[id].gname_uname.gname.startedActivity) { u32 var = IsTryingToTradeWithHoennTooSoon(data, id); if (var == 0) @@ -1536,11 +1536,11 @@ static u32 IsTryingToTradeWithHoennTooSoon(struct UnkStruct_Group * arg0, s32 id { struct UnkStruct_x20 * structPtr = &arg0->field_0->arr[id]; - if (sPlayerCurrActivity == ACTIVITY_TRADE && structPtr->gname_uname.gname.unk_00.version != VERSION_FIRE_RED && structPtr->gname_uname.gname.unk_00.version != VERSION_LEAF_GREEN) + if (sPlayerCurrActivity == ACTIVITY_TRADE && structPtr->gname_uname.gname.compatibility.version != VERSION_FIRE_RED && structPtr->gname_uname.gname.compatibility.version != VERSION_LEAF_GREEN) { if (!(gSaveBlock2Ptr->specialSaveWarpFlags & CHAMPION_SAVEWARP)) return 1; - else if (structPtr->gname_uname.gname.unk_00.isChampion) + else if (structPtr->gname_uname.gname.compatibility.isChampion) return 0; } else @@ -1558,8 +1558,8 @@ static void AskToJoinRfuGroup(struct UnkStruct_Group * data, s32 id) CreateWirelessStatusIndicatorSprite(0, 0); RedrawListMenu(data->listTaskId); IntlConvPartnerUname7(gStringVar1, data->field_0->arr[data->leaderId]); - UpdateGameDataWithActivitySpriteGendersFlag(sLinkGroupToURoomActivity[gSpecialVar_0x8004], 0, TRUE); - CreateTask_RfuReconnectWithParent(data->field_0->arr[data->leaderId].gname_uname.uname, ReadAsU16(data->field_0->arr[data->leaderId].gname_uname.gname.unk_00.playerTrainerId)); + UpdateGameData_SetActivity(sLinkGroupToURoomActivity[gSpecialVar_0x8004], 0, TRUE); + CreateTask_RfuReconnectWithParent(data->field_0->arr[data->leaderId].gname_uname.uname, ReadAsU16(data->field_0->arr[data->leaderId].gname_uname.gname.compatibility.playerTrainerId)); } u8 CreateTask_ListenToWireless(void) @@ -1585,11 +1585,11 @@ static void Task_ListenToWireless(u8 taskId) switch (data->state) { case 0: - SetHostRFUtgtGname(0, 0, 0); + SetHostRfuGameData(0, 0, 0); SetWirelessCommType1(); OpenLink(); InitializeRfuLinkManager_JoinGroup(); - sub_80FB128(TRUE); + RfuSetIgnoreError(TRUE); data->field_4 = AllocZeroed(4 * sizeof(struct UnkStruct_x1C)); data->field_0 = AllocZeroed(16 * sizeof(struct UnkStruct_x20)); data->state = 2; @@ -1649,7 +1649,7 @@ static u8 URoomGroupListGetTextColor(struct UnkStruct_Group * data, u32 id) { if (data->field_0->arr[id].groupScheduledAnim == UNION_ROOM_SPAWN_IN) { - if (data->field_0->arr[id].gname_uname.gname.started) + if (data->field_0->arr[id].gname_uname.gname.startedActivity) return UR_COLOR_WHT_WHT_LTE; else if (data->field_0->arr[id].field_1A_1) return UR_COLOR_RED_WHT_LTR; @@ -1976,7 +1976,7 @@ static void Task_StartActivity(u8 taskId) else { LinkRfu_StopManagerBeforeEnteringChat(); - SetHostRFUtgtGname(ACTIVITY_CHAT | IN_UNION_ROOM, 0, 1); + SetHostRfuGameData(ACTIVITY_CHAT | IN_UNION_ROOM, 0, 1); } EnterUnionRoomChat(); break; @@ -2076,8 +2076,8 @@ static void Task_MEvent_Leader(u8 taskId) case 0: sPlayerCurrActivity = data->activity; sPlayerActivityGroupSize = 2; - SetHostRFUtgtGname(data->activity, 0, 0); - SetGnameBufferWonderFlags(FALSE, FALSE); + SetHostRfuGameData(data->activity, 0, 0); + SetHostRfuWonderFlags(FALSE, FALSE); SetWirelessCommType1(); OpenLink(); InitializeRfuLinkManager_LinkLeader(2); @@ -2145,19 +2145,19 @@ static void Task_MEvent_Leader(u8 taskId) data->field_0->arr[data->playerCount].field_1B = 0; RedrawListMenu(data->listTaskId); data->field_19 = 5; - SendByteToPartnerByIdAndName(5, ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.unk_00.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.uname); + SendRfuStatusToPartner(5, ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.compatibility.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.uname); data->state = 8; break; case 1: case -1: data->field_19 = 6; - SendByteToPartnerByIdAndName(6, ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.unk_00.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.uname); + SendRfuStatusToPartner(6, ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.compatibility.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.uname); data->state = 8; break; } break; case 8: - val = WaitSendByteToPartnerByIdAndName(ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.unk_00.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.uname); + val = WaitSendRfuStatusToPartner(ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.compatibility.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.uname); if (val == 1) { if (data->field_19 == 5) @@ -2172,7 +2172,7 @@ static void Task_MEvent_Leader(u8 taskId) } else { - RequestDisconnectSlotByTrainerNameAndId(data->field_0->arr[data->playerCount].gname_uname.uname, ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.unk_00.playerTrainerId)); + RequestDisconnectSlotByTrainerNameAndId(data->field_0->arr[data->playerCount].gname_uname.uname, ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.compatibility.playerTrainerId)); data->field_0->arr[data->playerCount].groupScheduledAnim = UNION_ROOM_SPAWN_NONE; UnionRoomLeaderField0CompactionAndCount(data->field_0); RedrawListMenu(data->listTaskId); @@ -2283,7 +2283,7 @@ static void Task_CardOrNewsWithFriend(u8 taskId) switch (data->state) { case 0: - SetHostRFUtgtGname(data->cardOrNews + ACTIVITY_WCARD2, 0, 0); + SetHostRfuGameData(data->cardOrNews + ACTIVITY_WCARD2, 0, 0); SetWirelessCommType1(); OpenLink(); InitializeRfuLinkManager_JoinGroup(); @@ -2338,14 +2338,14 @@ static void Task_CardOrNewsWithFriend(u8 taskId) u32 unusedVar; unusedVar = data->field_0->arr[id].gname_uname.gname.activity; - if (data->field_0->arr[id].groupScheduledAnim == UNION_ROOM_SPAWN_IN && !data->field_0->arr[id].gname_uname.gname.started) + if (data->field_0->arr[id].groupScheduledAnim == UNION_ROOM_SPAWN_IN && !data->field_0->arr[id].gname_uname.gname.startedActivity) { data->leaderId = id; LoadWirelessStatusIndicatorSpriteGfx(); CreateWirelessStatusIndicatorSprite(0, 0); RedrawListMenu(data->listTaskId); IntlConvPartnerUname(gStringVar1, data->field_0->arr[data->leaderId]); - CreateTask_RfuReconnectWithParent(data->field_0->arr[data->leaderId].gname_uname.uname, ReadAsU16(data->field_0->arr[data->leaderId].gname_uname.gname.unk_00.playerTrainerId)); + CreateTask_RfuReconnectWithParent(data->field_0->arr[data->leaderId].gname_uname.uname, ReadAsU16(data->field_0->arr[data->leaderId].gname_uname.gname.compatibility.playerTrainerId)); PlaySE(SE_POKENAV_ON); data->state = 4; } @@ -2449,7 +2449,7 @@ static void Task_CardOrNewsOverWireless(u8 taskId) switch (data->state) { case 0: - SetHostRFUtgtGname(0, 0, 0); + SetHostRfuGameData(0, 0, 0); SetWirelessCommType1(); OpenLink(); InitializeRfuLinkManager_JoinGroup(); @@ -2498,7 +2498,7 @@ static void Task_CardOrNewsOverWireless(u8 taskId) 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->field_0->arr[0].groupScheduledAnim == UNION_ROOM_SPAWN_IN && !data->field_0->arr[0].gname_uname.gname.startedActivity) { if (GetGnameWonderFlagByLinkGroup(&data->field_0->arr[0].gname_uname.gname, data->cardOrNews + LINK_GROUP_WONDER_CARD)) { @@ -2506,7 +2506,7 @@ static void Task_CardOrNewsOverWireless(u8 taskId) data->refreshTimer = 0; LoadWirelessStatusIndicatorSpriteGfx(); CreateWirelessStatusIndicatorSprite(0, 0); - CreateTask_RfuReconnectWithParent(data->field_0->arr[0].gname_uname.uname, ReadAsU16(data->field_0->arr[0].gname_uname.gname.unk_00.playerTrainerId)); + CreateTask_RfuReconnectWithParent(data->field_0->arr[0].gname_uname.uname, ReadAsU16(data->field_0->arr[0].gname_uname.gname.compatibility.playerTrainerId)); PlaySE(SE_POKENAV_ON); data->state = 4; } @@ -2608,7 +2608,7 @@ void UnionRoomSpecial(void) { struct UnkStruct_URoom * dataPtr; - ClearAndInitHostRFUtgtGname(); + ResetHostRfuGameData(); CreateTask(Task_RunUnionRoom, 10); // dumb line needed to match @@ -2689,8 +2689,8 @@ static void Task_RunUnionRoom(u8 taskId) data->state = 2; break; case 2: - SetHostRFUtgtGname(IN_UNION_ROOM, 0, 0); - RfuUpdatePlayerGnameStateAndSend(sUnionRoomTrade.type, sUnionRoomTrade.playerSpecies, sUnionRoomTrade.playerLevel); + SetHostRfuGameData(IN_UNION_ROOM, 0, 0); + SetTradeBoardRegisteredMonInfo(sUnionRoomTrade.type, sUnionRoomTrade.playerSpecies, sUnionRoomTrade.playerLevel); SetWirelessCommType1(); OpenLink(); InitializeRfuLinkManager_EnterUnionRoom(); @@ -2709,11 +2709,11 @@ static void Task_RunUnionRoom(u8 taskId) switch (sUnionRoomTrade.field_0) { case 1: - UpdateGameDataWithActivitySpriteGendersFlag(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); + UpdateGameData_SetActivity(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); if (id >= PARTY_SIZE) { ResetUnionRoomTrade(&sUnionRoomTrade); - RfuUpdatePlayerGnameStateAndSend(0, 0, 0); + SetTradeBoardRegisteredMonInfo(0, 0, 0); UnionRoom_ScheduleFieldMessageAndExit(gText_UR_RegistrationCanceled); } else if (!RegisterTradeMonAndGetIsEgg(GetCursorSelectionMonId(), &sUnionRoomTrade)) @@ -2734,7 +2734,7 @@ static void Task_RunUnionRoom(u8 taskId) } else { - UpdateGameDataWithActivitySpriteGendersFlag(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); + UpdateGameData_SetActivity(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); sPlayerCurrActivity = ACTIVITY_TRADE | IN_UNION_ROOM; RegisterTradeMon(GetCursorSelectionMonId(), &sUnionRoomTrade); data->state = 51; @@ -2753,7 +2753,7 @@ static void Task_RunUnionRoom(u8 taskId) { if (gSpecialVar_Result == 9) { - UpdateGameDataWithActivitySpriteGendersFlag(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); + UpdateGameData_SetActivity(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); PlaySE(SE_PC_LOGIN); StringCopy(gStringVar1, gSaveBlock2Ptr->playerName); data->state = 42; @@ -2761,7 +2761,7 @@ static void Task_RunUnionRoom(u8 taskId) } else if (gSpecialVar_Result == 11) { - UpdateGameDataWithActivitySpriteGendersFlag(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); + UpdateGameData_SetActivity(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); data->state = 23; gSpecialVar_Result = 0; } @@ -2786,7 +2786,7 @@ static void Task_RunUnionRoom(u8 taskId) } else if (PlayerIsTalkingToUnionRoomAide()) { - UpdateGameDataWithActivitySpriteGendersFlag(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); + UpdateGameData_SetActivity(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); PlaySE(SE_PC_LOGIN); UR_EnableScriptContext2AndFreezeObjectEvents(); StringCopy(gStringVar1, gSaveBlock2Ptr->playerName); @@ -2805,8 +2805,8 @@ static void Task_RunUnionRoom(u8 taskId) case 4: data->state = 11; UR_EnableScriptContext2AndFreezeObjectEvents(); - RfuUpdatePlayerGnameStateAndSend(0, 0, 0); - UpdateGameDataWithActivitySpriteGendersFlag(ACTIVITY_NPCTALK | IN_UNION_ROOM, GetActivePartnerSpriteGenderParam(data), FALSE); + SetTradeBoardRegisteredMonInfo(0, 0, 0); + UpdateGameData_SetActivity(ACTIVITY_NPCTALK | IN_UNION_ROOM, GetActivePartnerSpriteGenderParam(data), FALSE); break; } HandleUnionRoomPlayerRefresh(data); @@ -2815,21 +2815,21 @@ static void Task_RunUnionRoom(u8 taskId) case 23: if (!FuncIsActiveTask(Task_StartMenuHandleInput)) { - UpdateGameDataWithActivitySpriteGendersFlag(IN_UNION_ROOM, 0, FALSE); + UpdateGameData_SetActivity(IN_UNION_ROOM, 0, FALSE); data->state = 4; } break; case 24: UR_RunTextPrinters_CheckPrinter0Active(); playerGender = GetUnionRoomPlayerGender(taskData[1], data->field_0); - UpdateGameDataWithActivitySpriteGendersFlag(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); + UpdateGameData_SetActivity(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); switch (UnionRoomGetPlayerInteractionResponse(data->field_0, taskData[0], taskData[1], playerGender)) { case 0: data->state = 26; break; case 1: - sub_80FC114(data->field_0->arr[taskData[1]].gname_uname.uname, &data->field_0->arr[taskData[1]].gname_uname.gname, sPlayerCurrActivity); + TryConnectToUnionRoomParent(data->field_0->arr[taskData[1]].gname_uname.uname, &data->field_0->arr[taskData[1]].gname_uname.gname, sPlayerCurrActivity); data->field_12 = id; // Should be just 0, but won't match any other way. data->state = 25; break; @@ -3014,8 +3014,8 @@ static void Task_RunUnionRoom(u8 taskId) case 0: CopyBgTilemapBufferToVram(0); sPlayerCurrActivity = ACTIVITY_CHAT | IN_UNION_ROOM; - UpdateGameDataWithActivitySpriteGendersFlag(ACTIVITY_CHAT | IN_UNION_ROOM, 0, TRUE); - sub_80FC114(data->field_0->arr[taskData[1]].gname_uname.uname, &data->field_0->arr[taskData[1]].gname_uname.gname, sPlayerCurrActivity); + UpdateGameData_SetActivity(ACTIVITY_CHAT | IN_UNION_ROOM, 0, TRUE); + TryConnectToUnionRoomParent(data->field_0->arr[taskData[1]].gname_uname.uname, &data->field_0->arr[taskData[1]].gname_uname.gname, sPlayerCurrActivity); data->field_12 = taskData[1]; data->state = 20; taskData[3] = 0; @@ -3044,7 +3044,7 @@ static void Task_RunUnionRoom(u8 taskId) case 1: case 2: playerGender = GetUnionRoomPlayerGender(taskData[1], data->field_0); - UpdateGameDataWithActivitySpriteGendersFlag(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); + UpdateGameData_SetActivity(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); if (IsUnionRoomListenTaskActive() == TRUE) UnionRoom_ScheduleFieldMessageAndExit(gTexts_UR_ChatDeclined[playerGender]); else @@ -3060,7 +3060,7 @@ static void Task_RunUnionRoom(u8 taskId) if (RfuHasErrored()) { playerGender = GetUnionRoomPlayerGender(taskData[1], data->field_0); - UpdateGameDataWithActivitySpriteGendersFlag(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); + UpdateGameData_SetActivity(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); if (IsUnionRoomListenTaskActive() == TRUE) UnionRoom_ScheduleFieldMessageAndExit(gTexts_UR_ChatDeclined[playerGender]); else @@ -3071,7 +3071,7 @@ static void Task_RunUnionRoom(u8 taskId) break; case 11: PlaySE(SE_DING_DONG); - sub_80F8FA0(); + StopUnionRoomLinkManager(); data->state = 12; data->recvActivityRequest[0] = 0; break; @@ -3107,7 +3107,7 @@ static void Task_RunUnionRoom(u8 taskId) ReceiveUnionRoomActivityPacket(data); if (UnionRoom_HandleContactFromOtherPlayer(data) && JOY_NEW(B_BUTTON)) { - sub_80FBD6C(1); + Rfu_DisconnectPlayerById(1); StringCopy(gStringVar4, gText_UR_ChatEnded); data->state = 36; } @@ -3122,9 +3122,9 @@ static void Task_RunUnionRoom(u8 taskId) case 0: data->playerSendBuffer[0] = ACTIVITY_ACCEPT | IN_UNION_ROOM; if (sPlayerCurrActivity == (ACTIVITY_CHAT | IN_UNION_ROOM)) - UpdateGameDataWithActivitySpriteGendersFlag(sPlayerCurrActivity | IN_UNION_ROOM, GetSinglePartnerSpriteGenderParam(1), FALSE); + UpdateGameData_SetActivity(sPlayerCurrActivity | IN_UNION_ROOM, GetSinglePartnerSpriteGenderParam(1), FALSE); else - UpdateGameDataWithActivitySpriteGendersFlag(sPlayerCurrActivity | IN_UNION_ROOM, GetSinglePartnerSpriteGenderParam(1), TRUE); + UpdateGameData_SetActivity(sPlayerCurrActivity | IN_UNION_ROOM, GetSinglePartnerSpriteGenderParam(1), TRUE); data->field_8->arr[0].field_1B = 0; taskData[3] = 0; @@ -3218,20 +3218,20 @@ static void Task_RunUnionRoom(u8 taskId) } break; case 42: - if (GetHostRFUtgtGname()->species == SPECIES_NONE) + if (GetHostRfuGameData()->tradeSpecies == SPECIES_NONE) { data->state = 43; } else { - if (GetHostRFUtgtGname()->species == SPECIES_EGG) + if (GetHostRfuGameData()->tradeSpecies == SPECIES_EGG) { StringCopy(gStringVar4, gText_UR_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, gText_UR_CancelRegistrationOfMon); } UnionRoom_ScheduleFieldMessageWithFollowupState(44, gStringVar4); @@ -3286,7 +3286,7 @@ static void Task_RunUnionRoom(u8 taskId) case -2: case 18: ResetUnionRoomTrade(&sUnionRoomTrade); - RfuUpdatePlayerGnameStateAndSend(0, 0, 0); + SetTradeBoardRegisteredMonInfo(0, 0, 0); UnionRoom_ScheduleFieldMessageAndExit(gText_UR_RegistrationCanceled); break; default: @@ -3297,7 +3297,7 @@ static void Task_RunUnionRoom(u8 taskId) } break; case 55: - RfuUpdatePlayerGnameStateAndSend(sUnionRoomTrade.type, sUnionRoomTrade.playerSpecies, sUnionRoomTrade.playerLevel); + SetTradeBoardRegisteredMonInfo(sUnionRoomTrade.type, sUnionRoomTrade.playerSpecies, sUnionRoomTrade.playerLevel); UnionRoom_ScheduleFieldMessageAndExit(gText_UR_RegistraionCompleted); break; case 44: @@ -3316,7 +3316,7 @@ static void Task_RunUnionRoom(u8 taskId) case 56: if (PrintOnTextbox(&data->textState, gText_UR_RegistrationCanceled2)) { - RfuUpdatePlayerGnameStateAndSend(0, 0, 0); + SetTradeBoardRegisteredMonInfo(0, 0, 0); ResetUnionRoomTrade(&sUnionRoomTrade); HandleCancelTrade(TRUE); data->state = 4; @@ -3343,7 +3343,7 @@ static void Task_RunUnionRoom(u8 taskId) data->state = 4; break; default: - switch (IsRequestedTypeAndSpeciesInPlayerParty(data->field_0->arr[var5].gname_uname.gname.type, data->field_0->arr[var5].gname_uname.gname.species)) + switch (IsRequestedTypeAndSpeciesInPlayerParty(data->field_0->arr[var5].gname_uname.gname.tradeType, data->field_0->arr[var5].gname_uname.gname.tradeSpecies)) { case UR_TRADE_MATCH: IntlConvPartnerUname(gStringVar1, data->field_0->arr[var5]); @@ -3352,12 +3352,12 @@ static void Task_RunUnionRoom(u8 taskId) break; case UR_TRADE_NOTYPE: IntlConvPartnerUname(gStringVar1, data->field_0->arr[var5]); - StringCopy(gStringVar2, gTypeNames[data->field_0->arr[var5].gname_uname.gname.type]); + StringCopy(gStringVar2, gTypeNames[data->field_0->arr[var5].gname_uname.gname.tradeType]); UnionRoom_ScheduleFieldMessageWithFollowupState(46, gText_UR_DontHaveTypeTrainerWants); break; case UR_TRADE_NOEGG: IntlConvPartnerUname(gStringVar1, data->field_0->arr[var5]); - StringCopy(gStringVar2, gTypeNames[data->field_0->arr[var5].gname_uname.gname.type]); + StringCopy(gStringVar2, gTypeNames[data->field_0->arr[var5].gname_uname.gname.tradeType]); UnionRoom_ScheduleFieldMessageWithFollowupState(46, gText_UR_DontHaveEggTrainerWants); break; } @@ -3382,9 +3382,9 @@ static void Task_RunUnionRoom(u8 taskId) if (PrintOnTextbox(&data->textState, gText_UR_WhichMonWillYouOffer)) { sUnionRoomTrade.field_0 = 2; - memcpy(&gPartnerTgtGnameSub, &data->field_0->arr[taskData[1]].gname_uname.gname.unk_00, sizeof(gPartnerTgtGnameSub)); - gUnionRoomRequestedMonType = data->field_0->arr[taskData[1]].gname_uname.gname.type; - gUnionRoomOfferedSpecies = data->field_0->arr[taskData[1]].gname_uname.gname.species; + memcpy(&gPartnerTgtGnameSub, &data->field_0->arr[taskData[1]].gname_uname.gname.compatibility, sizeof(gPartnerTgtGnameSub)); + gUnionRoomRequestedMonType = data->field_0->arr[taskData[1]].gname_uname.gname.tradeType; + gUnionRoomOfferedSpecies = data->field_0->arr[taskData[1]].gname_uname.gname.tradeSpecies; gFieldCallback = FieldCB_ContinueScriptUnionRoom; ChooseMonForTradingBoard(PARTY_MENU_TYPE_UNION_ROOM_TRADE, CB2_ReturnToField); BackUpURoomField0ToDecompressionBuffer(data); @@ -3393,7 +3393,7 @@ static void Task_RunUnionRoom(u8 taskId) break; case 51: sPlayerCurrActivity = ACTIVITY_TRADE | IN_UNION_ROOM; - sub_80FC114(data->field_0->arr[taskData[1]].gname_uname.uname, &data->field_0->arr[taskData[1]].gname_uname.gname, ACTIVITY_TRADE | IN_UNION_ROOM); + TryConnectToUnionRoomParent(data->field_0->arr[taskData[1]].gname_uname.uname, &data->field_0->arr[taskData[1]].gname_uname.gname, ACTIVITY_TRADE | IN_UNION_ROOM); IntlConvPartnerUname(gStringVar1, data->field_0->arr[taskData[1]]); UR_PrintFieldMessage(gTexts_UR_CommunicatingWait[2]); data->state = 25; @@ -3488,11 +3488,11 @@ static void Task_InitUnionRoom(u8 taskId) structPtr->state = 1; break; case 1: - SetHostRFUtgtGname(ACTIVITY_SEARCH, 0, 0); + SetHostRfuGameData(ACTIVITY_SEARCH, 0, 0); SetWirelessCommType1(); OpenLink(); InitializeRfuLinkManager_EnterUnionRoom(); - sub_80FB128(TRUE); + RfuSetIgnoreError(TRUE); structPtr->state = 2; break; case 2: @@ -3519,7 +3519,7 @@ static void Task_InitUnionRoom(u8 taskId) if (structPtr->field_0->arr[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN) { IntlConvPartnerUname(text, structPtr->field_0->arr[i]); - if (PlayerHasMetTrainerBefore(ReadAsU16(structPtr->field_0->arr[i].gname_uname.gname.unk_00.playerTrainerId), text)) + if (PlayerHasMetTrainerBefore(ReadAsU16(structPtr->field_0->arr[i].gname_uname.gname.compatibility.playerTrainerId), text)) { StringCopy(sUnionRoomPlayerName, text); break; @@ -3659,7 +3659,7 @@ static void Task_SearchForChildOrParent(u8 taskId) { gname_uname = sUnionGnameUnamePair_Dummy; } - if (gname_uname.gname.unk_00.language == LANGUAGE_JAPANESE) + if (gname_uname.gname.compatibility.language == LANGUAGE_JAPANESE) { gname_uname = sUnionGnameUnamePair_Dummy; } @@ -3720,7 +3720,7 @@ static bool32 GetGnameWonderFlagByLinkGroup(struct RfuGameData * gname, s16 link { if (linkGroup == LINK_GROUP_WONDER_CARD) { - if (!gname->unk_00.hasCard) + if (!gname->compatibility.hasCard) { return FALSE; } @@ -3731,7 +3731,7 @@ static bool32 GetGnameWonderFlagByLinkGroup(struct RfuGameData * gname, s16 link } else if (linkGroup == LINK_GROUP_WONDER_NEWS) { - if (!gname->unk_00.hasNews) + if (!gname->compatibility.hasNews) { return FALSE; } @@ -4078,7 +4078,7 @@ static bool8 AreGnameUnameDifferent(struct UnionGnameUnamePair * left, const str for (i = 0; i < 2; i++) { - if (left->gname.unk_00.playerTrainerId[i] != right->gname.unk_00.playerTrainerId[i]) + if (left->gname.compatibility.playerTrainerId[i] != right->gname.compatibility.playerTrainerId[i]) { return TRUE; } @@ -4100,32 +4100,22 @@ static bool32 AreUnionRoomPlayerGnamesDifferent(struct UnionGnameUnamePair * lef s32 i; if (left->gname.activity != right->gname.activity) - { return TRUE; - } - if (left->gname.started != right->gname.started) - { + if (left->gname.startedActivity != right->gname.startedActivity) return TRUE; - } for (i = 0; i < RFU_CHILD_MAX; i++) { - if (left->gname.child_sprite_gender[i] != right->gname.child_sprite_gender[i]) - { + if (left->gname.partnerInfo[i] != right->gname.partnerInfo[i]) return TRUE; - } } - if (left->gname.species != right->gname.species) - { + if (left->gname.tradeSpecies != right->gname.tradeSpecies) return TRUE; - } - if (left->gname.type != right->gname.type) - { + if (left->gname.tradeType != right->gname.tradeType) return TRUE; - } return FALSE; } @@ -4185,7 +4175,7 @@ static void PrintUnionRoomGroupOnWindow(u8 windowId, u8 x, u8 y, struct UnkStruc { IntlConvPartnerUname(uname, *group); UR_AddTextPrinterParameterized(windowId, 2, uname, x, y, colorIdx); - ConvertIntToDecimalStringN(id_str, group->gname_uname.gname.unk_00.playerTrainerId[0] | (group->gname_uname.gname.unk_00.playerTrainerId[1] << 8), STR_CONV_MODE_LEADING_ZEROS, 5); + ConvertIntToDecimalStringN(id_str, group->gname_uname.gname.compatibility.playerTrainerId[0] | (group->gname_uname.gname.compatibility.playerTrainerId[1] << 8), STR_CONV_MODE_LEADING_ZEROS, 5); StringCopy(gStringVar4, gText_UR_ID); StringAppend(gStringVar4, id_str); x += 77; @@ -4202,7 +4192,7 @@ static void PrintGroupMemberCandidateOnWindowWithColor(u8 windowId, u8 x, u8 y, { IntlConvPartnerUname(uname, *group); UR_AddTextPrinterParameterized(windowId, 2, uname, x, y, colorIdx); - ConvertIntToDecimalStringN(id_str, group->gname_uname.gname.unk_00.playerTrainerId[0] | (group->gname_uname.gname.unk_00.playerTrainerId[1] << 8), STR_CONV_MODE_LEADING_ZEROS, 5); + ConvertIntToDecimalStringN(id_str, group->gname_uname.gname.compatibility.playerTrainerId[0] | (group->gname_uname.gname.compatibility.playerTrainerId[1] << 8), STR_CONV_MODE_LEADING_ZEROS, 5); StringCopy(gStringVar4, gText_UR_ID); StringAppend(gStringVar4, id_str); x += 71; @@ -4250,7 +4240,7 @@ static u32 ConvPartnerUnameAndGetWhetherMetAlready(struct UnkStruct_x20 * x20) { u8 sp0[30]; IntlConvPartnerUname(sp0, *x20); - return PlayerHasMetTrainerBefore(ReadAsU16(x20->gname_uname.gname.unk_00.playerTrainerId), sp0); + return PlayerHasMetTrainerBefore(ReadAsU16(x20->gname_uname.gname.compatibility.playerTrainerId), sp0); } static s32 UnionRoomGetPlayerInteractionResponse(struct UnkStruct_Main0 * main0, u8 overrideGender, u8 playerIdx, u32 playerGender) @@ -4259,10 +4249,10 @@ static s32 UnionRoomGetPlayerInteractionResponse(struct UnkStruct_Main0 * main0, struct UnkStruct_x20 * x20 = &main0->arr[playerIdx]; - if (!x20->gname_uname.gname.started && overrideGender == 0) + if (!x20->gname_uname.gname.startedActivity && overrideGender == 0) { IntlConvPartnerUname(gStringVar1, *x20); - metBefore = PlayerHasMetTrainerBefore(ReadAsU16(x20->gname_uname.gname.unk_00.playerTrainerId), gStringVar1); + metBefore = PlayerHasMetTrainerBefore(ReadAsU16(x20->gname_uname.gname.compatibility.playerTrainerId), gStringVar1); if (x20->gname_uname.gname.activity == (ACTIVITY_CHAT | IN_UNION_ROOM)) { StringExpandPlaceholders(gStringVar4, gTexts_UR_JoinChat[metBefore][playerGender]); @@ -4279,7 +4269,7 @@ static s32 UnionRoomGetPlayerInteractionResponse(struct UnkStruct_Main0 * main0, IntlConvPartnerUname(gStringVar1, *x20); if (overrideGender != 0) { - playerGender = (x20->gname_uname.gname.unk_00.playerTrainerId[overrideGender + 1] >> 3) & 1; + playerGender = (x20->gname_uname.gname.compatibility.playerTrainerId[overrideGender + 1] >> 3) & 1; } switch (x20->gname_uname.gname.activity & 0x3F) { @@ -4310,9 +4300,9 @@ static void nullsub_92(u8 windowId, u32 itemId, u8 y) static void TradeBoardPrintItemInfo(u8 windowId, u8 y, struct RfuGameData * gname, const u8 * uname, u8 colorIdx) { u8 level_t[4]; - u16 species = gname->species; - u8 type = gname->type; - u8 level = gname->level; + u16 species = gname->tradeSpecies; + u8 type = gname->tradeType; + u8 level = gname->tradeLevel; UR_AddTextPrinterParameterized(windowId, 2, uname, 8, y, colorIdx); if (species == SPECIES_EGG) @@ -4337,8 +4327,8 @@ static void TradeBoardListMenuItemPrintFunc(u8 windowId, u32 itemId, u8 y) if (itemId == -3 && y == sTradeBoardListMenuTemplate.upText_Y) { - rfu = GetHostRFUtgtGname(); - if (rfu->species != SPECIES_NONE) + rfu = GetHostRfuGameData(); + if (rfu->tradeSpecies != SPECIES_NONE) { TradeBoardPrintItemInfo(windowId, y, rfu, gSaveBlock2Ptr->playerName, 5); } @@ -4348,7 +4338,7 @@ static void TradeBoardListMenuItemPrintFunc(u8 windowId, u32 itemId, u8 y) j = 0; for (i = 0; i < UROOM_MAX_GROUP_COUNT; i++) { - if (leader->field_0->arr[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN && leader->field_0->arr[i].gname_uname.gname.species != SPECIES_NONE) + if (leader->field_0->arr[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN && leader->field_0->arr[i].gname_uname.gname.tradeSpecies != SPECIES_NONE) { j++; } @@ -4369,7 +4359,7 @@ static s32 GetIndexOfNthTradeBoardOffer(struct UnkStruct_x20 * x20, s32 n) for (i = 0; i < UROOM_MAX_GROUP_COUNT; i++) { - if (x20[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN && x20[i].gname_uname.gname.species != SPECIES_NONE) + if (x20[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN && x20[i].gname_uname.gname.tradeSpecies != SPECIES_NONE) { j++; } @@ -4641,8 +4631,8 @@ static void HandleCancelTrade(bool32 unlockObjs) sPlayerCurrActivity = 0; if (unlockObjs) { - RfuUpdatePlayerGnameStateAndSend(sUnionRoomTrade.type, sUnionRoomTrade.playerSpecies, sUnionRoomTrade.playerLevel); - UpdateGameDataWithActivitySpriteGendersFlag(IN_UNION_ROOM, 0, FALSE); + SetTradeBoardRegisteredMonInfo(sUnionRoomTrade.type, sUnionRoomTrade.playerSpecies, sUnionRoomTrade.playerLevel); + UpdateGameData_SetActivity(IN_UNION_ROOM, 0, FALSE); } } @@ -4670,7 +4660,7 @@ static u8 GetActivePartnerSpriteGenderParam(struct UnkStruct_URoom * uroom) if (uroom->field_C->arr[i].active) { retVal |= uroom->field_C->arr[i].gname_uname.gname.playerGender << 3; - retVal |= uroom->field_C->arr[i].gname_uname.gname.unk_00.playerTrainerId[0] & 7; + retVal |= uroom->field_C->arr[i].gname_uname.gname.compatibility.playerTrainerId[0] & 7; break; } } diff --git a/src/union_room_chat.c b/src/union_room_chat.c index 191201ec0..a2436575b 100644 --- a/src/union_room_chat.c +++ b/src/union_room_chat.c @@ -324,7 +324,7 @@ static void ChatEntryRoutine_Join(void) sWork->routineState++; // fall through case 1: - if (IsLinkTaskFinished() && !RfuHasFoundNewLeader()) + if (IsLinkTaskFinished() && !Rfu_IsPlayerExchangeActive()) { if (SendBlock(0, sWork->sendMessageBuffer, sizeof(sWork->sendMessageBuffer))) sWork->routineState++; @@ -527,14 +527,14 @@ static void ChatEntryRoutine_AskQuitChatting(void) sWork->routineState = 3; break; case 0: - Rfu_UnionRoomChat_StopLinkManager(); + Rfu_StopPartnerSearch(); PrepareSendBuffer_Disband(sWork->sendMessageBuffer); sWork->routineState = 4; break; } break; case 4: - if (IsLinkTaskFinished() && !RfuHasFoundNewLeader() && SendBlock(0, sWork->sendMessageBuffer, sizeof(sWork->sendMessageBuffer))) + if (IsLinkTaskFinished() && !Rfu_IsPlayerExchangeActive() && SendBlock(0, sWork->sendMessageBuffer, sizeof(sWork->sendMessageBuffer))) { if (sWork->multiplayerId == 0) sWork->routineState = 6; @@ -577,15 +577,15 @@ static void ChatEntryRoutine_ExitChat(void) } break; case 3: - if (IsLinkTaskFinished() && !RfuHasFoundNewLeader() && SendBlock(0, sWork->sendMessageBuffer, sizeof(sWork->sendMessageBuffer))) + if (IsLinkTaskFinished() && !Rfu_IsPlayerExchangeActive() && SendBlock(0, sWork->sendMessageBuffer, sizeof(sWork->sendMessageBuffer))) sWork->routineState++; break; case 4: - if ((GetBlockReceivedStatus() & 1) && !RfuHasFoundNewLeader()) + if ((GetBlockReceivedStatus() & 1) && !Rfu_IsPlayerExchangeActive()) sWork->routineState++; break; case 5: - if (IsLinkTaskFinished() && !RfuHasFoundNewLeader()) + if (IsLinkTaskFinished() && !Rfu_IsPlayerExchangeActive()) { SetCloseLinkCallback(); sWork->exitDelayTimer = 0; @@ -620,7 +620,7 @@ static void ChatEntryRoutine_Drop(void) } break; case 1: - if (!RunDisplaySubtask(0) && IsLinkTaskFinished() && !RfuHasFoundNewLeader()) + if (!RunDisplaySubtask(0) && IsLinkTaskFinished() && !Rfu_IsPlayerExchangeActive()) { SetCloseLinkCallback(); sWork->exitDelayTimer = 0; @@ -666,7 +666,7 @@ static void ChatEntryRoutine_Disbanded(void) } break; case 2: - if (RunDisplaySubtask(0) != TRUE && IsLinkTaskFinished() && !RfuHasFoundNewLeader()) + if (RunDisplaySubtask(0) != TRUE && IsLinkTaskFinished() && !Rfu_IsPlayerExchangeActive()) { SetCloseLinkCallback(); sWork->exitDelayTimer = 0; @@ -704,7 +704,7 @@ static void ChatEntryRoutine_SendMessage(void) sWork->routineState++; // fall through case 1: - if (IsLinkTaskFinished() == TRUE && !RfuHasFoundNewLeader() && SendBlock(0, sWork->sendMessageBuffer, sizeof(sWork->sendMessageBuffer))) + if (IsLinkTaskFinished() == TRUE && !Rfu_IsPlayerExchangeActive() && SendBlock(0, sWork->sendMessageBuffer, sizeof(sWork->sendMessageBuffer))) sWork->routineState++; break; case 2: @@ -1144,7 +1144,7 @@ static void PrepareSendBuffer_Leave(u8 *arg0) arg0[0] = CHAT_MESSAGE_LEAVE; StringCopy(&arg0[1], gSaveBlock2Ptr->playerName); arg0[1 + (PLAYER_NAME_LENGTH + 1)] = sWork->multiplayerId; - sub_80FB9D0(); + RfuSetNormalDisconnectMode(); } static void PrepareSendBuffer_Drop(u8 *arg0) @@ -1355,7 +1355,7 @@ static void Task_ReceiveChatMessage(u8 taskId) } tBlockReceivedStatus = GetBlockReceivedStatus(); - if (!tBlockReceivedStatus && RfuHasFoundNewLeader()) + if (!tBlockReceivedStatus && Rfu_IsPlayerExchangeActive()) return; tI = 0; @@ -1409,13 +1409,13 @@ static void Task_ReceiveChatMessage(u8 taskId) // You're the leader, and the person who left is not you if (GetLinkPlayerCount() == 2) { - Rfu_UnionRoomChat_StopLinkManager(); + Rfu_StopPartnerSearch(); sWork->exitType = CHATEXIT_LEADER_LAST; DestroyTask(taskId); return; } - sub_80FBD6C(tCurrLinkPlayer); + Rfu_DisconnectPlayerById(tCurrLinkPlayer); } tState = 3; @@ -1433,10 +1433,10 @@ static void Task_ReceiveChatMessage(u8 taskId) DestroyTask(taskId); break; case 2: - if (!RfuHasFoundNewLeader()) + if (!Rfu_IsPlayerExchangeActive()) { if (sWork->multiplayerId == 0) - sub_80FB030(sWork->linkPlayerCount); + SetUnionRoomChatPlayerData(sWork->linkPlayerCount); tState = 1; } diff --git a/src/wireless_communication_status_screen.c b/src/wireless_communication_status_screen.c index c9ebe676d..97131a768 100644 --- a/src/wireless_communication_status_screen.c +++ b/src/wireless_communication_status_screen.c @@ -366,7 +366,7 @@ static u32 CountMembersInGroup(struct UnkStruct_x20 * unk20, u32 * counts) k = 0; for (j = 0; j < RFU_CHILD_MAX; j++) { - if (unk20->gname_uname.gname.child_sprite_gender[j] != 0) k++; + if (unk20->gname_uname.gname.partnerInfo[j] != 0) k++; } k++; counts[sCountParams[i][1]] += k; From 75a53efc904d29b416fd7ba5d0b884819d63ff8a Mon Sep 17 00:00:00 2001 From: GriffinR Date: Mon, 7 Nov 2022 14:22:54 -0500 Subject: [PATCH 3/8] Sync link_rfu_3 --- .../wireless_icon.png} | Bin include/link_rfu.h | 33 +- src/link_rfu_2.c | 4 +- src/link_rfu_3.c | 299 ++++++++---------- src/union_room.c | 12 +- 5 files changed, 155 insertions(+), 193 deletions(-) rename graphics/{interface/wireless_link_icon.png => link/wireless_icon.png} (100%) diff --git a/graphics/interface/wireless_link_icon.png b/graphics/link/wireless_icon.png similarity index 100% rename from graphics/interface/wireless_link_icon.png rename to graphics/link/wireless_icon.png diff --git a/include/link_rfu.h b/include/link_rfu.h index f203d30a3..5fe53cfbe 100644 --- a/include/link_rfu.h +++ b/include/link_rfu.h @@ -29,8 +29,6 @@ #define RECV_QUEUE_NUM_SLOTS 20 #define SEND_QUEUE_NUM_SLOTS 40 #define BACKUP_QUEUE_NUM_SLOTS 2 -#define UNUSED_QUEUE_NUM_SLOTS 2 -#define UNUSED_QUEUE_SLOT_LENGTH 256 #define RFU_PACKET_SIZE 6 @@ -141,8 +139,8 @@ struct RfuBlockSend struct RfuRecvQueue { /* 0x000 */ u8 slots[RECV_QUEUE_NUM_SLOTS][COMM_SLOT_LENGTH * MAX_RFU_PLAYERS]; - /* 0x578 */ vu8 recv_slot; - /* 0x579 */ vu8 send_slot; + /* 0x578 */ vu8 recvSlot; + /* 0x579 */ vu8 sendSlot; /* 0x57a */ vu8 count; /* 0x57b */ vu8 full; }; @@ -150,8 +148,8 @@ struct RfuRecvQueue struct RfuSendQueue { /* 0x000 */ u8 slots[SEND_QUEUE_NUM_SLOTS][COMM_SLOT_LENGTH]; - /* 0x230 */ vu8 recv_slot; - /* 0x231 */ vu8 send_slot; + /* 0x230 */ vu8 recvSlot; + /* 0x231 */ vu8 sendSlot; /* 0x232 */ vu8 count; /* 0x233 */ vu8 full; }; @@ -159,20 +157,11 @@ struct RfuSendQueue struct RfuBackupQueue { /* 0x00 */ u8 slots[BACKUP_QUEUE_NUM_SLOTS][COMM_SLOT_LENGTH]; - /* 0x1c */ vu8 recv_slot; - /* 0x1d */ vu8 send_slot; + /* 0x1c */ vu8 recvSlot; + /* 0x1d */ vu8 sendSlot; /* 0x1e */ vu8 count; }; -struct RfuUnusedQueue -{ - /* 0x000 */ u8 slots[UNUSED_QUEUE_NUM_SLOTS][UNUSED_QUEUE_SLOT_LENGTH]; - /* 0x200 */ vu8 recv_slot; - /* 0x201 */ vu8 send_slot; - /* 0x202 */ vu8 count; - /* 0x203 */ vu8 full; -}; - struct RfuManager { /* 0x000 */ void (*callback)(void); @@ -296,7 +285,7 @@ bool8 RfuBackupQueue_Dequeue(struct RfuBackupQueue *queue, u8 *dest); void RfuBackupQueue_Enqueue(struct RfuBackupQueue *queue, const u8 *dest); bool8 RfuRecvQueue_Dequeue(struct RfuRecvQueue * queue, u8 *dest); void RfuSendQueue_Enqueue(struct RfuSendQueue * queue, u8 *src); -void InitHostRFUtgtGname(struct RfuGameData *data, u8 activity, bool32 started, s32 partnerInfo); +void InitHostRfuGameData(struct RfuGameData *data, u8 activity, bool32 started, s32 partnerInfo); void UpdateGameData_GroupLockedIn(bool8 started); bool32 IsRfuSerialNumberValid(u32 serialNo); bool8 IsRfuRecoveringFromLinkLoss(void); @@ -311,12 +300,12 @@ u32 WaitSendRfuStatusToPartner(u16 trainerId, const u8 *name); void SetHostRfuGameData(u8 activity, u32 partnerInfo, bool32 startedActivity); void InitializeRfuLinkManager_LinkLeader(u32 availSlots); void RequestDisconnectSlotByTrainerNameAndId(const u8 *trainerName, u16 trainerId); -void LinkRfu3_SetGnameUnameFromStaticBuffers(struct RfuGameData *gname, u8 *uname); +void CopyHostRfuGameDataAndUsername(struct RfuGameData *gameData, u8 *username); void InitializeRfuLinkManager_JoinGroup(void); void SendLeaveGroupNotice(void); void CreateTask_RfuReconnectWithParent(const u8 *src, u16 trainerId); void UpdateGameData_SetActivity(u8 activity, u32 partnerInfo, u32 startedActivity); -void RecordMixTrainerNames(void); +void SaveLinkTrainerNames(void); void LinkRfu_CreateConnectionAsParent(); void LinkRfu_StopManagerBeforeEnteringChat(); void SetHostRfuWonderFlags(bool32 hasNews, bool32 hasCard); @@ -328,8 +317,8 @@ void InitializeRfuLinkManager_EnterUnionRoom(void); void Rfu_DisconnectPlayerById(u32 playerIdx); void TryConnectToUnionRoomParent(const u8 *name, struct RfuGameData *parent, u8 activity); bool32 PlayerHasMetTrainerBefore(u16 id, u8 *name); -bool8 LinkRfu_GetNameIfCompatible(struct RfuGameData *gname, u8 *uname, u8 idx); -bool8 LinkRfu_GetNameIfSerial7F7D(struct RfuGameData *gname, u8 *uname, u8 idx); +bool8 Rfu_GetCompatiblePlayerData(struct RfuGameData *gameData, u8 *username, u8 idx); +bool8 Rfu_GetWonderDistributorPlayerData(struct RfuGameData *gameData, u8 *username, u8 idx); bool32 Rfu_IsPlayerExchangeActive(void); void Rfu_StopPartnerSearch(void); void RfuSetNormalDisconnectMode(void); diff --git a/src/link_rfu_2.c b/src/link_rfu_2.c index 9257f04b1..480f1874c 100644 --- a/src/link_rfu_2.c +++ b/src/link_rfu_2.c @@ -2057,12 +2057,12 @@ static void SetHostRfuUsername(void) void ResetHostRfuGameData(void) { memset(&gHostRfuGameData, 0, RFU_GAME_NAME_LENGTH); - InitHostRFUtgtGname(&gHostRfuGameData, ACTIVITY_NONE, FALSE, 0); + InitHostRfuGameData(&gHostRfuGameData, ACTIVITY_NONE, FALSE, 0); } void SetHostRfuGameData(u8 activity, u32 partnerInfo, u32 startedActivity) { - InitHostRFUtgtGname(&gHostRfuGameData, activity, startedActivity, partnerInfo); + InitHostRfuGameData(&gHostRfuGameData, activity, startedActivity, partnerInfo); } void SetHostRfuWonderFlags(bool32 hasNews, bool32 hasCard) diff --git a/src/link_rfu_3.c b/src/link_rfu_3.c index f47b71829..21efcaf22 100644 --- a/src/link_rfu_3.c +++ b/src/link_rfu_3.c @@ -6,12 +6,35 @@ #include "link_rfu.h" #include "random.h" -static EWRAM_DATA u8 gWirelessStatusIndicatorSpriteId = 0; +enum { + WIRELESS_STATUS_ANIM_3_BARS, + WIRELESS_STATUS_ANIM_2_BARS, + WIRELESS_STATUS_ANIM_1_BAR, + WIRELESS_STATUS_ANIM_SEARCHING, + WIRELESS_STATUS_ANIM_ERROR, +}; -static const u16 gWirelessLinkIconPalette[] = INCBIN_U16("graphics/interface/wireless_link_icon.gbapal"); +#define TAG_GFX_STATUS_INDICATOR 0xD431 +#define TAG_PAL_STATUS_INDICATOR 0xD432 -static const u32 gWirelessLinkIconPic[] = INCBIN_U32("graphics/interface/wireless_link_icon.4bpp.lz"); +#define UNUSED_QUEUE_NUM_SLOTS 2 +#define UNUSED_QUEUE_SLOT_LENGTH 256 +struct RfuUnusedQueue +{ + u8 slots[UNUSED_QUEUE_NUM_SLOTS][UNUSED_QUEUE_SLOT_LENGTH]; + vu8 recvSlot; + vu8 sendSlot; + vu8 count; + vu8 full; +}; + +static EWRAM_DATA u8 sWirelessStatusIndicatorSpriteId = 0; + +static const u16 sWirelessLinkIconPalette[] = INCBIN_U16("graphics/link/wireless_icon.gbapal"); +static const u32 sWirelessLinkIconPic[] = INCBIN_U32("graphics/link/wireless_icon.4bpp.lz"); + +// Most of the below two tables won't make sense with ASCII encoding. static const u8 sWireless_ASCIItoRSETable[] = { EOS, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x37, @@ -222,8 +245,7 @@ static const struct OamData sWirelessStatusIndicatorOamData = .paletteNum = 0, }; -static const union AnimCmd sWirelessStatusIndicatorAnim0[] = { - // 3 bars +static const union AnimCmd sWirelessStatusIndicator_3Bars[] = { ANIMCMD_FRAME( 4, 5), ANIMCMD_FRAME( 8, 5), ANIMCMD_FRAME(12, 5), @@ -233,8 +255,7 @@ static const union AnimCmd sWirelessStatusIndicatorAnim0[] = { ANIMCMD_JUMP(0) }; -static const union AnimCmd sWirelessStatusIndicatorAnim1[] = { - // 2 bars +static const union AnimCmd sWirelessStatusIndicator_2Bars[] = { ANIMCMD_FRAME( 4, 5), ANIMCMD_FRAME( 8, 5), ANIMCMD_FRAME(12, 10), @@ -242,46 +263,43 @@ static const union AnimCmd sWirelessStatusIndicatorAnim1[] = { ANIMCMD_JUMP(0) }; -static const union AnimCmd sWirelessStatusIndicatorAnim2[] = { - // 1 bar +static const union AnimCmd sWirelessStatusIndicator_1Bar[] = { ANIMCMD_FRAME(4, 5), ANIMCMD_FRAME(8, 5), ANIMCMD_JUMP(0) }; -static const union AnimCmd sWirelessStatusIndicatorAnim3[] = { - // searching +static const union AnimCmd sWirelessStatusIndicator_Searching[] = { ANIMCMD_FRAME( 4, 10), ANIMCMD_FRAME(20, 10), ANIMCMD_JUMP(0) }; -static const union AnimCmd sWirelessStatusIndicatorAnim4[] = { - // error +static const union AnimCmd sWirelessStatusIndicator_Error[] = { ANIMCMD_FRAME(24, 10), ANIMCMD_FRAME( 4, 10), ANIMCMD_JUMP(0) }; static const union AnimCmd *const sWirelessStatusIndicatorAnims[] = { - sWirelessStatusIndicatorAnim0, - sWirelessStatusIndicatorAnim1, - sWirelessStatusIndicatorAnim2, - sWirelessStatusIndicatorAnim3, - sWirelessStatusIndicatorAnim4 + [WIRELESS_STATUS_ANIM_3_BARS] = sWirelessStatusIndicator_3Bars, + [WIRELESS_STATUS_ANIM_2_BARS] = sWirelessStatusIndicator_2Bars, + [WIRELESS_STATUS_ANIM_1_BAR] = sWirelessStatusIndicator_1Bar, + [WIRELESS_STATUS_ANIM_SEARCHING] = sWirelessStatusIndicator_Searching, + [WIRELESS_STATUS_ANIM_ERROR] = sWirelessStatusIndicator_Error }; static const struct CompressedSpriteSheet sWirelessStatusIndicatorSpriteSheet = { - gWirelessLinkIconPic, 0x0380, 0xD431 + sWirelessLinkIconPic, 0x0380, TAG_GFX_STATUS_INDICATOR }; static const struct SpritePalette sWirelessStatusIndicatorSpritePalette = { - gWirelessLinkIconPalette, 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, @@ -301,8 +319,8 @@ void RfuRecvQueue_Reset(struct RfuRecvQueue *queue) for (j = 0; j < COMM_SLOT_LENGTH * MAX_RFU_PLAYERS; j++) queue->slots[i][j] = 0; } - queue->send_slot = 0; - queue->recv_slot = 0; + queue->sendSlot = 0; + queue->recvSlot = 0; queue->count = 0; queue->full = FALSE; } @@ -317,8 +335,8 @@ void RfuSendQueue_Reset(struct RfuSendQueue *queue) for (j = 0; j < COMM_SLOT_LENGTH; j++) queue->slots[i][j] = 0; } - queue->send_slot = 0; - queue->recv_slot = 0; + queue->sendSlot = 0; + queue->recvSlot = 0; queue->count = 0; queue->full = FALSE; } @@ -331,12 +349,10 @@ 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->send_slot = 0; - queue->recv_slot = 0; + queue->sendSlot = 0; + queue->recvSlot = 0; queue->count = 0; queue->full = FALSE; } @@ -360,9 +376,9 @@ void RfuRecvQueue_Enqueue(struct RfuRecvQueue *queue, u8 *src) if (count != MAX_RFU_PLAYERS) { for (i = 0; i < COMM_SLOT_LENGTH * MAX_RFU_PLAYERS; i++) - queue->slots[queue->recv_slot][i] = src[i]; - queue->recv_slot++; - queue->recv_slot %= RECV_QUEUE_NUM_SLOTS; + queue->slots[queue->recvSlot][i] = src[i]; + queue->recvSlot++; + queue->recvSlot %= RECV_QUEUE_NUM_SLOTS; queue->count++; for (i = 0; i < COMM_SLOT_LENGTH * MAX_RFU_PLAYERS; i++) src[i] = 0; @@ -392,9 +408,9 @@ void RfuSendQueue_Enqueue(struct RfuSendQueue *queue, u8 *src) if (i != COMM_SLOT_LENGTH) { for (i = 0; i < COMM_SLOT_LENGTH; i++) - queue->slots[queue->recv_slot][i] = src[i]; - queue->recv_slot++; - queue->recv_slot %= SEND_QUEUE_NUM_SLOTS; + queue->slots[queue->recvSlot][i] = src[i]; + queue->recvSlot++; + queue->recvSlot %= SEND_QUEUE_NUM_SLOTS; queue->count++; for (i = 0; i < COMM_SLOT_LENGTH; i++) src[i] = 0; @@ -414,7 +430,7 @@ bool8 RfuRecvQueue_Dequeue(struct RfuRecvQueue *queue, u8 *dest) imeBak = REG_IME; REG_IME = 0; - if (queue->recv_slot == queue->send_slot || queue->full) + if (queue->recvSlot == queue->sendSlot || queue->full) { for (i = 0; i < COMM_SLOT_LENGTH * MAX_RFU_PLAYERS; i++) dest[i] = 0; @@ -422,9 +438,9 @@ bool8 RfuRecvQueue_Dequeue(struct RfuRecvQueue *queue, u8 *dest) return FALSE; } for (i = 0; i < COMM_SLOT_LENGTH * MAX_RFU_PLAYERS; i++) - dest[i] = queue->slots[queue->send_slot][i]; - queue->send_slot++; - queue->send_slot %= RECV_QUEUE_NUM_SLOTS; + dest[i] = queue->slots[queue->sendSlot][i]; + queue->sendSlot++; + queue->sendSlot %= RECV_QUEUE_NUM_SLOTS; queue->count--; REG_IME = imeBak; return TRUE; @@ -435,14 +451,14 @@ bool8 RfuSendQueue_Dequeue(struct RfuSendQueue *queue, u8 *dest) s32 i; u16 imeBak; - if (queue->recv_slot == queue->send_slot || queue->full) + if (queue->recvSlot == queue->sendSlot || queue->full) return FALSE; imeBak = REG_IME; REG_IME = 0; for (i = 0; i < COMM_SLOT_LENGTH; i++) - dest[i] = queue->slots[queue->send_slot][i]; - queue->send_slot++; - queue->send_slot %= SEND_QUEUE_NUM_SLOTS; + dest[i] = queue->slots[queue->sendSlot][i]; + queue->sendSlot++; + queue->sendSlot %= SEND_QUEUE_NUM_SLOTS; queue->count--; REG_IME = imeBak; return TRUE; @@ -459,17 +475,13 @@ void RfuBackupQueue_Enqueue(struct RfuBackupQueue *queue, const u8 *dest) else { for (i = 0; i < COMM_SLOT_LENGTH; i++) - queue->slots[queue->recv_slot][i] = dest[i]; - queue->recv_slot++; - queue->recv_slot %= BACKUP_QUEUE_NUM_SLOTS; + queue->slots[queue->recvSlot][i] = dest[i]; + queue->recvSlot++; + queue->recvSlot %= BACKUP_QUEUE_NUM_SLOTS; if (queue->count < BACKUP_QUEUE_NUM_SLOTS) - { queue->count++; - } else - { - queue->send_slot = queue->recv_slot; - } + queue->sendSlot = queue->recvSlot; } } @@ -478,16 +490,15 @@ bool8 RfuBackupQueue_Dequeue(struct RfuBackupQueue *queue, u8 *dest) s32 i; if (queue->count == 0) - { return FALSE; - } + if (dest != NULL) { for (i = 0; i < COMM_SLOT_LENGTH; i++) - dest[i] = queue->slots[queue->send_slot][i]; + dest[i] = queue->slots[queue->sendSlot][i]; } - queue->send_slot++; - queue->send_slot %= BACKUP_QUEUE_NUM_SLOTS; + queue->sendSlot++; + queue->sendSlot %= BACKUP_QUEUE_NUM_SLOTS; queue->count--; return TRUE; } @@ -499,11 +510,9 @@ static void RfuUnusedQueue_Dequeue(struct RfuUnusedQueue *queue, u8 *dest) if (queue->count < UNUSED_QUEUE_NUM_SLOTS) { for (i = 0; i < UNUSED_QUEUE_SLOT_LENGTH; i++) - { - queue->slots[queue->recv_slot][i] = dest[i]; - } - queue->recv_slot++; - queue->recv_slot %= UNUSED_QUEUE_NUM_SLOTS; + queue->slots[queue->recvSlot][i] = dest[i]; + queue->recvSlot++; + queue->recvSlot %= UNUSED_QUEUE_NUM_SLOTS; queue->count++; } else @@ -516,16 +525,14 @@ static bool8 RfuUnusedQueue_Enqueue(struct RfuUnusedQueue *queue, u8 *dest) { s32 i; - if (queue->recv_slot == queue->send_slot || queue->full) - { + if (queue->recvSlot == queue->sendSlot || queue->full) return FALSE; - } + for (i = 0; i < UNUSED_QUEUE_SLOT_LENGTH; i++) - { - dest[i] = queue->slots[queue->send_slot][i]; - } - queue->send_slot++; - queue->send_slot %= UNUSED_QUEUE_NUM_SLOTS; + dest[i] = queue->slots[queue->sendSlot][i]; + + queue->sendSlot++; + queue->sendSlot %= UNUSED_QUEUE_NUM_SLOTS; queue->count--; return TRUE; } @@ -593,9 +600,7 @@ static void PkmnStrToASCII(u8 *dest, const u8 *src) s32 i; for (i = 0; src[i] != EOS; i++) - { dest[i] = sWireless_RSEtoASCIITable[src[i]]; - } dest[i] = 0; } @@ -604,9 +609,7 @@ static void ASCIIToPkmnStr(u8 *dest, const u8 *src) s32 i; for (i = 0; src[i] != 0; i++) - { dest[i] = sWireless_ASCIItoRSETable[src[i]]; - } dest[i] = EOS; } @@ -644,18 +647,17 @@ static u8 GetConnectedChildStrength(u8 maxFlags) return 0; } -void InitHostRFUtgtGname(struct RfuGameData *data, u8 activity, bool32 startedActivity, s32 partnerInfo) +void InitHostRfuGameData(struct RfuGameData *data, u8 activity, bool32 startedActivity, s32 partnerInfo) { s32 i; - for (i = 0; i < 2; 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->partnerInfo[i] = partnerInfo; - partnerInfo >>= 8; + partnerInfo >>= 8; // Each element is 1 byte } data->playerGender = gSaveBlock2Ptr->playerGender; data->activity = activity; @@ -671,13 +673,13 @@ void InitHostRFUtgtGname(struct RfuGameData *data, u8 activity, bool32 startedAc } /* - * ========================================================== + * ================================================================ * Returns 1 if parent, 0 if child or neutral. - * If partner serial number is valid, copies gname and uname. + * If partner serial number is valid, copies gameData and username. * Otherwise, blanks these. - * ========================================================== + * ================================================================ */ -bool8 LinkRfu_GetNameIfCompatible(struct RfuGameData *gname, u8 *uname, u8 idx) +bool8 Rfu_GetCompatiblePlayerData(struct RfuGameData *gameData, u8 *username, u8 idx) { bool8 retVal; @@ -686,13 +688,13 @@ bool8 LinkRfu_GetNameIfCompatible(struct RfuGameData *gname, u8 *uname, u8 idx) retVal = TRUE; if (IsRfuSerialNumberValid(gRfuLinkStatus->partner[idx].serialNo) && ((gRfuLinkStatus->getNameFlag >> idx) & 1)) { - memcpy(gname, &gRfuLinkStatus->partner[idx].gname, RFU_GAME_NAME_LENGTH); - memcpy(uname, gRfuLinkStatus->partner[idx].uname, RFU_USER_NAME_LENGTH); + memcpy(gameData, gRfuLinkStatus->partner[idx].gname, RFU_GAME_NAME_LENGTH); + memcpy(username, gRfuLinkStatus->partner[idx].uname, RFU_USER_NAME_LENGTH); } else { - memset(gname, 0, RFU_GAME_NAME_LENGTH); - memset(uname, 0, RFU_USER_NAME_LENGTH); + memset(gameData, 0, RFU_GAME_NAME_LENGTH); + memset(username, 0, RFU_USER_NAME_LENGTH); } } else @@ -700,45 +702,39 @@ bool8 LinkRfu_GetNameIfCompatible(struct RfuGameData *gname, u8 *uname, u8 idx) retVal = FALSE; if (IsRfuSerialNumberValid(gRfuLinkStatus->partner[idx].serialNo)) { - memcpy(gname, &gRfuLinkStatus->partner[idx].gname, RFU_GAME_NAME_LENGTH); - memcpy(uname, gRfuLinkStatus->partner[idx].uname, RFU_USER_NAME_LENGTH); + memcpy(gameData, gRfuLinkStatus->partner[idx].gname, RFU_GAME_NAME_LENGTH); + memcpy(username, gRfuLinkStatus->partner[idx].uname, RFU_USER_NAME_LENGTH); } else { - memset(gname, 0, RFU_GAME_NAME_LENGTH); - memset(uname, 0, RFU_USER_NAME_LENGTH); + memset(gameData, 0, RFU_GAME_NAME_LENGTH); + memset(username, 0, RFU_USER_NAME_LENGTH); } } return retVal; } -/* - * ========================================================== - * Specific check for serial number 0x7F7D, - * which comes from ??? - * ========================================================== - */ -bool8 LinkRfu_GetNameIfSerial7F7D(struct RfuGameData *gname, u8 *uname, u8 idx) +bool8 Rfu_GetWonderDistributorPlayerData(struct RfuGameData *gameData, u8 *username, u8 idx) { bool8 retVal = FALSE; if (gRfuLinkStatus->partner[idx].serialNo == RFU_SERIAL_WONDER_DISTRIBUTOR) { - memcpy(gname, gRfuLinkStatus->partner[idx].gname, RFU_GAME_NAME_LENGTH); - memcpy(uname, gRfuLinkStatus->partner[idx].uname, RFU_USER_NAME_LENGTH); + memcpy(gameData, gRfuLinkStatus->partner[idx].gname, RFU_GAME_NAME_LENGTH); + memcpy(username, gRfuLinkStatus->partner[idx].uname, RFU_USER_NAME_LENGTH); retVal = TRUE; } else { - memset(gname, 0, RFU_GAME_NAME_LENGTH); - memset(uname, 0, RFU_USER_NAME_LENGTH); + memset(gameData, 0, RFU_GAME_NAME_LENGTH); + memset(username, 0, RFU_USER_NAME_LENGTH); } return retVal; } -void LinkRfu3_SetGnameUnameFromStaticBuffers(struct RfuGameData *gname, u8 *uname) +void CopyHostRfuGameDataAndUsername(struct RfuGameData *gameData, u8 *username) { - memcpy(gname, &gHostRfuGameData, RFU_GAME_NAME_LENGTH); - memcpy(uname, gHostRfuUsername, RFU_USER_NAME_LENGTH); + memcpy(gameData, &gHostRfuGameData, RFU_GAME_NAME_LENGTH); + memcpy(username, gHostRfuUsername, RFU_USER_NAME_LENGTH); } #define sNextAnimNum data[0] @@ -765,23 +761,23 @@ void CreateWirelessStatusIndicatorSprite(u8 x, u8 y) gSprites[sprId].sValidator = STATUS_INDICATOR_ACTIVE; gSprites[sprId].sTileStart = GetSpriteTileStartByTag(sWirelessStatusIndicatorSpriteSheet.tag); gSprites[sprId].invisible = TRUE; - gWirelessStatusIndicatorSpriteId = sprId; + sWirelessStatusIndicatorSpriteId = sprId; } else { - gWirelessStatusIndicatorSpriteId = CreateSprite(&sWirelessStatusIndicatorSpriteTemplate, x, y, 0); - gSprites[gWirelessStatusIndicatorSpriteId].sValidator = STATUS_INDICATOR_ACTIVE; - gSprites[gWirelessStatusIndicatorSpriteId].sTileStart = GetSpriteTileStartByTag(sWirelessStatusIndicatorSpriteSheet.tag); - gSprites[gWirelessStatusIndicatorSpriteId].invisible = TRUE; + sWirelessStatusIndicatorSpriteId = CreateSprite(&sWirelessStatusIndicatorSpriteTemplate, x, y, 0); + gSprites[sWirelessStatusIndicatorSpriteId].sValidator = STATUS_INDICATOR_ACTIVE; + gSprites[sWirelessStatusIndicatorSpriteId].sTileStart = GetSpriteTileStartByTag(sWirelessStatusIndicatorSpriteSheet.tag); + gSprites[sWirelessStatusIndicatorSpriteId].invisible = TRUE; } } void DestroyWirelessStatusIndicatorSprite(void) { - if (gSprites[gWirelessStatusIndicatorSpriteId].sValidator == STATUS_INDICATOR_ACTIVE) + if (gSprites[sWirelessStatusIndicatorSpriteId].sValidator == STATUS_INDICATOR_ACTIVE) { - gSprites[gWirelessStatusIndicatorSpriteId].sValidator = 0; - DestroySprite(&gSprites[gWirelessStatusIndicatorSpriteId]); + gSprites[sWirelessStatusIndicatorSpriteId].sValidator = 0; + DestroySprite(&gSprites[sWirelessStatusIndicatorSpriteId]); gMain.oamBuffer[125] = gDummyOamData; CpuCopy16(&gDummyOamData, (struct OamData *)OAM + 125, sizeof(struct OamData)); } @@ -790,11 +786,9 @@ void DestroyWirelessStatusIndicatorSprite(void) void LoadWirelessStatusIndicatorSpriteGfx(void) { if (GetSpriteTileStartByTag(sWirelessStatusIndicatorSpriteSheet.tag) == 0xFFFF) - { LoadCompressedSpriteSheet(&sWirelessStatusIndicatorSpriteSheet); - } LoadSpritePalette(&sWirelessStatusIndicatorSpritePalette); - gWirelessStatusIndicatorSpriteId = 0xFF; + sWirelessStatusIndicatorSpriteId = SPRITE_NONE; } static u8 GetParentSignalStrength(void) @@ -804,19 +798,17 @@ static u8 GetParentSignalStrength(void) for (i = 0; i < RFU_CHILD_MAX; i++) { if (flags & 1) - { return gRfuLinkStatus->strength[i]; - } flags >>= 1; } return 0; } -static void SetAndRestartWirelessStatusIndicatorAnim(struct Sprite *sprite, s32 signalStrengthAnimNum) +static void SetAndRestartWirelessStatusIndicatorAnim(struct Sprite *sprite, s32 animNum) { - if (sprite->sCurrAnimNum != signalStrengthAnimNum) + if (sprite->sCurrAnimNum != animNum) { - sprite->sCurrAnimNum = signalStrengthAnimNum; + sprite->sCurrAnimNum = animNum; sprite->sFrameDelay = 0; sprite->sFrameIdx = 0; } @@ -824,45 +816,38 @@ static void SetAndRestartWirelessStatusIndicatorAnim(struct Sprite *sprite, s32 void UpdateWirelessStatusIndicatorSprite(void) { - if (gWirelessStatusIndicatorSpriteId != 0xFF && gSprites[gWirelessStatusIndicatorSpriteId].sValidator == STATUS_INDICATOR_ACTIVE) + if (sWirelessStatusIndicatorSpriteId != SPRITE_NONE && gSprites[sWirelessStatusIndicatorSpriteId].sValidator == STATUS_INDICATOR_ACTIVE) { - struct Sprite *sprite = &gSprites[gWirelessStatusIndicatorSpriteId]; + struct Sprite *sprite = &gSprites[sWirelessStatusIndicatorSpriteId]; 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 = 4; - } + sprite->sNextAnimNum = WIRELESS_STATUS_ANIM_ERROR; else if (signalStrength <= RFU_LINK_ICON_LEVEL1_MAX) - { - sprite->sNextAnimNum = 3; - } + sprite->sNextAnimNum = WIRELESS_STATUS_ANIM_SEARCHING; else if (signalStrength >= RFU_LINK_ICON_LEVEL2_MIN && signalStrength <= RFU_LINK_ICON_LEVEL2_MAX) - { - sprite->sNextAnimNum = 2; - } + sprite->sNextAnimNum = WIRELESS_STATUS_ANIM_1_BAR; else if (signalStrength >= RFU_LINK_ICON_LEVEL3_MIN && signalStrength <= RFU_LINK_ICON_LEVEL3_MAX) - { - sprite->sNextAnimNum = 1; - } + sprite->sNextAnimNum = WIRELESS_STATUS_ANIM_2_BARS; else if (signalStrength >= RFU_LINK_ICON_LEVEL4_MIN) - { - sprite->sNextAnimNum = 0; - } + sprite->sNextAnimNum = WIRELESS_STATUS_ANIM_3_BARS; + if (sprite->sNextAnimNum != sprite->sSavedAnimNum) { SetAndRestartWirelessStatusIndicatorAnim(sprite, sprite->sNextAnimNum); @@ -873,9 +858,7 @@ void UpdateWirelessStatusIndicatorSprite(void) sprite->sFrameIdx++; sprite->sFrameDelay = 0; if (sprite->anims[sprite->sCurrAnimNum][sprite->sFrameIdx].type == -2) // ANIMCMD_JUMP - { sprite->sFrameIdx = 0; - } } else { @@ -906,7 +889,7 @@ static void CopyTrainerRecord(struct TrainerNameRecord *dest, u32 trainerId, con { int i; dest->trainerId = trainerId; - for (i = 0; i < 7; i++) + for (i = 0; i < PLAYER_NAME_LENGTH; i++) { if (name[i] == EOS) break; @@ -920,9 +903,7 @@ static void ZeroName(u8 *name) s32 i; for (i = 0; i < PLAYER_NAME_LENGTH + 1; i++) - { *name++ = 0; - } } static bool32 NameIsEmpty(const u8 *name) @@ -932,15 +913,13 @@ static bool32 NameIsEmpty(const u8 *name) for (i = 0; i < PLAYER_NAME_LENGTH + 1; i++) { if (*name++ != 0) - { return FALSE; - } } return TRUE; } // Save the currently connected players into the trainer records, shifting all previous records down. -void RecordMixTrainerNames(void) +void SaveLinkTrainerNames(void) { if (gWirelessCommType != 0) { @@ -948,13 +927,13 @@ void RecordMixTrainerNames(void) s32 j; s32 nextSpace; s32 connectedTrainerRecordIndices[5]; - struct TrainerNameRecord *newRecords = AllocZeroed(20 * sizeof(struct TrainerNameRecord)); + struct TrainerNameRecord *newRecords = AllocZeroed(sizeof(gSaveBlock1Ptr->trainerNameRecords)); // Check if we already have a record saved for connected trainers. for (i = 0; i < GetLinkPlayerCount(); i++) { connectedTrainerRecordIndices[i] = -1; - for (j = 0; j < 20; j++) + 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) { @@ -973,29 +952,25 @@ 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) - { ZeroName(gSaveBlock1Ptr->trainerNameRecords[connectedTrainerRecordIndices[i]].trainerName); - } nextSpace++; } } // Copy all non-empty records to the new list, in the order they appear on the old list. If the list is full, // the last (oldest) records will be dropped. - for (i = 0; i < 20; i++) + for (i = 0; i < (int)ARRAY_COUNT(gSaveBlock1Ptr->trainerNameRecords); i++) { if (!NameIsEmpty(gSaveBlock1Ptr->trainerNameRecords[i].trainerName)) { CopyTrainerRecord(&newRecords[nextSpace], gSaveBlock1Ptr->trainerNameRecords[i].trainerId, gSaveBlock1Ptr->trainerNameRecords[i].trainerName); - if (++nextSpace >= 20) - { + if (++nextSpace >= (int)ARRAY_COUNT(gSaveBlock1Ptr->trainerNameRecords)) break; - } } } // Finalize the new list, and clean up. - memcpy(gSaveBlock1Ptr->trainerNameRecords, newRecords, 20 * sizeof(struct TrainerNameRecord)); + memcpy(gSaveBlock1Ptr->trainerNameRecords, newRecords, sizeof(gSaveBlock1Ptr->trainerNameRecords)); Free(newRecords); } } @@ -1004,16 +979,14 @@ bool32 PlayerHasMetTrainerBefore(u16 id, u8 *name) { s32 i; - for (i = 0; i < 20; i++) + for (i = 0; i < (int)ARRAY_COUNT(gSaveBlock1Ptr->trainerNameRecords); i++) { - if (StringCompareN(gSaveBlock1Ptr->trainerNameRecords[i].trainerName, name, 7) == 0 && gSaveBlock1Ptr->trainerNameRecords[i].trainerId == id) - { + if (StringCompareN(gSaveBlock1Ptr->trainerNameRecords[i].trainerName, name, PLAYER_NAME_LENGTH) == 0 + && gSaveBlock1Ptr->trainerNameRecords[i].trainerId == id) return TRUE; - } + if (NameIsEmpty(gSaveBlock1Ptr->trainerNameRecords[i].trainerName)) - { return FALSE; - } } return FALSE; } diff --git a/src/union_room.c b/src/union_room.c index c4c7e7a27..186d09707 100644 --- a/src/union_room.c +++ b/src/union_room.c @@ -756,7 +756,7 @@ static void Task_TryBecomeLinkLeader(u8 taskId) data->field_8 = AllocZeroed(UROOM_MAX_PARTY_SIZE * sizeof(struct UnkStruct_x20)); BlankUnkStruct_x1CArray(data->field_4->arr, 4); BlankUnkStruct_x20Array(data->field_0->arr, UROOM_MAX_PARTY_SIZE); - LinkRfu3_SetGnameUnameFromStaticBuffers(&data->field_0->arr[0].gname_uname.gname, data->field_0->arr[0].gname_uname.uname); + CopyHostRfuGameDataAndUsername(&data->field_0->arr[0].gname_uname.gname, data->field_0->arr[0].gname_uname.uname); data->field_0->arr[0].field_18 = 0; data->field_0->arr[0].groupScheduledAnim = UNION_ROOM_SPAWN_IN; data->field_0->arr[0].field_1A_1 = 0; @@ -1919,7 +1919,7 @@ static void Task_StartActivity(u8 taskId) case ACTIVITY_BPICK: case ACTIVITY_SPINTRADE: case ACTIVITY_ITEMTRADE: - RecordMixTrainerNames(); + SaveLinkTrainerNames(); break; } @@ -2089,7 +2089,7 @@ static void Task_MEvent_Leader(u8 taskId) data->field_8 = AllocZeroed(UROOM_MAX_PARTY_SIZE * sizeof(struct UnkStruct_x20)); BlankUnkStruct_x1CArray(data->field_4->arr, 4); BlankUnkStruct_x20Array(data->field_0->arr, UROOM_MAX_PARTY_SIZE); - LinkRfu3_SetGnameUnameFromStaticBuffers(&data->field_0->arr[0].gname_uname.gname, data->field_0->arr[0].gname_uname.uname); + CopyHostRfuGameDataAndUsername(&data->field_0->arr[0].gname_uname.gname, data->field_0->arr[0].gname_uname.uname); data->field_0->arr[0].field_18 = 0; data->field_0->arr[0].groupScheduledAnim = UNION_ROOM_SPAWN_IN; data->field_0->arr[0].field_1A_1 = FALSE; @@ -3654,7 +3654,7 @@ static void Task_SearchForChildOrParent(u8 taskId) for (i = 0; i < RFU_CHILD_MAX; i++) { - parent_child = LinkRfu_GetNameIfCompatible(&gname_uname.gname, gname_uname.uname, i); + parent_child = Rfu_GetCompatiblePlayerData(&gname_uname.gname, gname_uname.uname, i); if (!IsPartnerActivityAcceptable(gname_uname.gname.activity, gTasks[taskId].data[4])) { gname_uname = sUnionGnameUnamePair_Dummy; @@ -3700,7 +3700,7 @@ static void Task_ListenForPartnersWithCompatibleSerialNos(u8 taskId) for (i = 0; i < RFU_CHILD_MAX; i++) { - LinkRfu_GetNameIfCompatible(&ptr[0]->arr[i].gname_uname.gname, ptr[0]->arr[i].gname_uname.uname, i); + Rfu_GetCompatiblePlayerData(&ptr[0]->arr[i].gname_uname.gname, ptr[0]->arr[i].gname_uname.uname, i); if (!IsPartnerActivityAcceptable(ptr[0]->arr[i].gname_uname.gname.activity, gTasks[taskId].data[2])) { ptr[0]->arr[i].gname_uname = sUnionGnameUnamePair_Dummy; @@ -3753,7 +3753,7 @@ static void Task_ListenForPartnersWithSerial7F7D(u8 taskId) for (i = 0; i < RFU_CHILD_MAX; i++) { - if (LinkRfu_GetNameIfSerial7F7D(&ptr[0]->arr[i].gname_uname.gname, ptr[0]->arr[i].gname_uname.uname, i)) + if (Rfu_GetWonderDistributorPlayerData(&ptr[0]->arr[i].gname_uname.gname, ptr[0]->arr[i].gname_uname.uname, i)) { GetGnameWonderFlagByLinkGroup(&ptr[0]->arr[i].gname_uname.gname, gTasks[taskId].data[2]); } From 9983b41c1d0688bcac324336161c8da0f9a78013 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Mon, 7 Nov 2022 14:56:34 -0500 Subject: [PATCH 4/8] Sync union room --- data/maps/UnionRoom/scripts.inc | 2 +- data/scripts/cable_club.inc | 2 +- data/specials.inc | 2 +- include/constants/union_room.h | 93 +- include/link_rfu.h | 11 +- include/mevent.h | 4 +- include/mystery_gift_menu.h | 2 +- include/rfu_union_tool.h | 12 +- include/trade.h | 2 +- include/trade_scene.h | 2 +- include/union_room.h | 182 +- src/cable_club.c | 4 +- src/data/union_room.h | 470 +++ src/link_rfu_2.c | 4 +- src/mevent.c | 18 +- src/mystery_gift_menu.c | 69 +- src/party_menu.c | 2 +- src/rfu_union_tool.c | 40 +- src/start_menu.c | 2 +- src/trade.c | 8 +- src/trade_scene.c | 6 +- src/union_room.c | 3456 +++++++++----------- src/wireless_communication_status_screen.c | 56 +- 23 files changed, 2255 insertions(+), 2194 deletions(-) create mode 100644 src/data/union_room.h diff --git a/data/maps/UnionRoom/scripts.inc b/data/maps/UnionRoom/scripts.inc index f75bb1a97..c214b06d3 100644 --- a/data/maps/UnionRoom/scripts.inc +++ b/data/maps/UnionRoom/scripts.inc @@ -29,7 +29,7 @@ UnionRoom_OnResume:: removeobject LOCALID_UNION_ROOM_PLAYER_6 removeobject LOCALID_UNION_ROOM_PLAYER_7 removeobject LOCALID_UNION_ROOM_PLAYER_8 - special UnionRoomSpecial + special RunUnionRoom end UnionRoom_OnTransition:: diff --git a/data/scripts/cable_club.inc b/data/scripts/cable_club.inc index afa923a0a..f725dbaea 100644 --- a/data/scripts/cable_club.inc +++ b/data/scripts/cable_club.inc @@ -796,7 +796,7 @@ CableClub_EventScript_EnterUnionRoom:: special SetCableClubWarp warpspinenter MAP_UNION_ROOM, 7, 11 waitstate - special UnionRoomSpecial + special RunUnionRoom waitstate end diff --git a/data/specials.inc b/data/specials.inc index f16dbb79f..f815d05d6 100644 --- a/data/specials.inc +++ b/data/specials.inc @@ -373,7 +373,7 @@ gSpecials:: def_special IsWirelessAdapterConnected def_special TryBecomeLinkLeader def_special TryJoinLinkGroup - def_special UnionRoomSpecial + def_special RunUnionRoom def_special ShowWirelessCommunicationScreen def_special EnableNationalPokedex def_special SetWalkingIntoSignVars diff --git a/include/constants/union_room.h b/include/constants/union_room.h index b23860645..4016150f0 100644 --- a/include/constants/union_room.h +++ b/include/constants/union_room.h @@ -1,47 +1,51 @@ #ifndef GUARD_CONSTANTS_UNION_ROOM_H #define GUARD_CONSTANTS_UNION_ROOM_H +// 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 #define UNION_ROOM_SPAWN_OUT 2 -#define ACTIVITY_NONE 0 -#define ACTIVITY_BATTLE 1 -#define ACTIVITY_DBLBATTLE 2 -#define ACTIVITY_MLTBATTLE 3 -#define ACTIVITY_TRADE 4 -#define ACTIVITY_CHAT 5 -#define ACTIVITY_WCARD 6 -#define ACTIVITY_WNEWS 7 -#define ACTIVITY_CARD 8 -#define ACTIVITY_PJUMP 9 -#define ACTIVITY_BCRUSH 10 -#define ACTIVITY_BPICK 11 -#define ACTIVITY_SEARCH 12 -#define ACTIVITY_SPINTRADE 13 -#define ACTIVITY_ITEMTRADE 14 +#define UNION_ROOM_MAX_LEVEL 30 + +// The number of possible trainer classes for a trainer of a given gender in the Union Room. +// This value is necessarily a power of 2 because of the way it's treated in GetUnionRoomTrainerPic / GetUnionRoomTrainerClass +#define NUM_UNION_ROOM_CLASSES (1 << 3) // 8 + +#define ACTIVITY_NONE 0 +#define ACTIVITY_BATTLE_SINGLE 1 +#define ACTIVITY_BATTLE_DOUBLE 2 +#define ACTIVITY_BATTLE_MULTI 3 +#define ACTIVITY_TRADE 4 +#define ACTIVITY_CHAT 5 +#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 +#define ACTIVITY_BERRY_PICK 11 +#define ACTIVITY_SEARCH 12 +#define ACTIVITY_SPIN_TRADE 13 +#define ACTIVITY_ITEM_TRADE 14 // Replaced with ACTIVITY_BATTLE_TOWER_OPEN in Emerald +#define ACTIVITY_RECORD_CORNER 15 +#define ACTIVITY_BERRY_BLENDER 16 // Player response -#define ACTIVITY_ACCEPT 17 -#define ACTIVITY_DECLINE 18 +#define ACTIVITY_ACCEPT 17 +#define ACTIVITY_DECLINE 18 -#define ACTIVITY_NPCTALK 19 -#define ACTIVITY_PLYRTALK 20 +#define ACTIVITY_NPCTALK 19 +#define ACTIVITY_PLYRTALK 20 -// Duplicate IDs? -#define ACTIVITY_WCARD2 21 -#define ACTIVITY_WNEWS2 22 +#define ACTIVITY_WONDER_CARD 21 +#define ACTIVITY_WONDER_NEWS 22 -#define IN_UNION_ROOM 0x40 - -// 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 IN_UNION_ROOM (1 << 6) #define LINK_GROUP_SINGLE_BATTLE 0 #define LINK_GROUP_DOUBLE_BATTLE 1 @@ -52,9 +56,30 @@ #define LINK_GROUP_BERRY_PICKING 6 #define LINK_GROUP_WONDER_CARD 7 #define LINK_GROUP_WONDER_NEWS 8 -#define NUM_LINK_GROUP_TYPES 9 - #define LINK_GROUP_UNION_ROOM_RESUME 9 #define LINK_GROUP_UNION_ROOM_INIT 10 +#define LINK_GROUP_UNK_11 11 +#define LINK_GROUP_UNK_12 12 +#define NUM_LINK_GROUP_TYPES 13 + +#define UR_TRADE_MATCH 0 +#define UR_TRADE_NOTYPE 1 +#define UR_TRADE_NOEGG 2 + +#define UR_TRADE_READY 0 +#define UR_TRADE_PLAYER_NOT_READY 1 +#define UR_TRADE_PARTNER_NOT_READY 2 + +#define UR_INTERACT_PLAYER_1 1 +#define UR_INTERACT_PLAYER_2 2 +#define UR_INTERACT_PLAYER_3 3 +#define UR_INTERACT_PLAYER_4 4 +#define UR_INTERACT_PLAYER_5 5 +#define UR_INTERACT_PLAYER_6 6 +#define UR_INTERACT_PLAYER_7 7 +#define UR_INTERACT_PLAYER_8 8 +#define UR_INTERACT_ATTENDANT 9 +#define UR_INTERACT_UNUSED 10 +#define UR_INTERACT_START_MENU 11 #endif //GUARD_CONSTANTS_UNION_ROOM_H diff --git a/include/link_rfu.h b/include/link_rfu.h index 5fe53cfbe..47588004c 100644 --- a/include/link_rfu.h +++ b/include/link_rfu.h @@ -233,17 +233,16 @@ extern struct RfuGameData gHostRfuGameData; extern u8 gHostRfuUsername[]; extern struct RfuManager gRfu; -// GameFreak signatures void AddTextPrinterToWindow1(const u8 *str); -bool32 MG_PrintTextOnWindow1AndWaitButton(u8 * cmdPtr, const u8 * src); +bool32 PrintMysteryGiftMenuMessage(u8 * cmdPtr, const u8 * src); void LinkRfu_FatalError(void); void MG_DrawCheckerboardPattern(void); void Rfu_SetCloseLinkCallback(void); bool8 IsLinkRfuTaskFinished(void); void DestroyWirelessStatusIndicatorSprite(void); -void MEvent_CreateTask_CardOrNewsWithFriend(u32 arg0); -void MEvent_CreateTask_CardOrNewsOverWireless(u32 arg0); -void MEvent_CreateTask_Leader(u32 arg0); +void CreateTask_LinkMysteryGiftWithFriend(u32 arg0); +void CreateTask_LinkMysteryGiftOverWireless(u32 arg0); +void CreateTask_SendMysteryGift(u32 activity); void Rfu_SendPacket(void *data); u8 CreateTask_ListenToWireless(void); void DestroyTask_RfuIdle(void); @@ -268,7 +267,7 @@ u32 GetRfuRecvQueueLength(void); void LinkRfu_Shutdown(void); void CreateTask_RfuIdle(void); bool8 Rfu_SetLinkRecovery(bool32 enable); -void var_800D_set_xB(void); +void SetUsingUnionRoomStartMenu(void); struct RfuGameData *GetHostRfuGameData(void); void UpdateWirelessStatusIndicatorSprite(void); void InitRFU(void); diff --git a/include/mevent.h b/include/mevent.h index 9a273a872..92c664d46 100644 --- a/include/mevent.h +++ b/include/mevent.h @@ -101,8 +101,8 @@ void InitMEventData(void); u16 MEvent_GetBattleCardCount(u32 command); void MysteryGift_TryIncrementStat(u32 eventId, u32 trainerId); u16 *GetMEventProfileECWordsMaybe(void); -void ResetReceivedWonderCardFlag(void); -bool32 MEventHandleReceivedWonderCard(u16 flagId); +void MysteryGift_DisableStats(void); +bool32 MysteryGift_TryEnableStatsByFlagId(u16 flagId); u16 GetWonderCardFlagId(void); #endif //GUARD_MEVENT_H diff --git a/include/mystery_gift_menu.h b/include/mystery_gift_menu.h index a25cc598f..82a47fb5f 100644 --- a/include/mystery_gift_menu.h +++ b/include/mystery_gift_menu.h @@ -7,7 +7,7 @@ void MainCB_FreeAllBuffersAndReturnToInitTitleScreen(void); void PrintMysteryGiftOrEReaderTopMenu(bool8, bool32); void c2_mystery_gift(void); void CB2_MysteryGiftEReader(void); -s8 mevent_message_print_and_prompt_yes_no(u8 * textState, u16 * windowId, bool8 yesNoBoxPlacement, const u8 * str); +s8 DoMysteryGiftYesNo(u8 * textState, u16 * windowId, bool8 yesNoBoxPlacement, const u8 * str); void MG_DrawTextBorder(u8 windowId); u16 GetMysteryGiftBaseBlock(void); diff --git a/include/rfu_union_tool.h b/include/rfu_union_tool.h index 7fc7fd4cb..ffecc3f8d 100644 --- a/include/rfu_union_tool.h +++ b/include/rfu_union_tool.h @@ -3,14 +3,14 @@ #include "union_room.h" -u8 ZeroUnionObjWork(struct UnionObj * ptr); -void DeleteUnionObjWorkAndStopTask(void); +u8 ZeroUnionObjWork(struct UnionRoomObject * ptr); +void DestroyUnionRoomPlayerObjects(void); void CreateGroupMemberObjectsInvisible(u8 *spriteIds, s32 group); void DestroyGroupMemberObjects(u8 *spriteIds); void MakeGroupAssemblyAreasPassable(void); -void ScheduleUnionRoomPlayerRefresh(struct UnkStruct_URoom *uroom_p); -void HandleUnionRoomPlayerRefresh(struct UnkStruct_URoom *uroom_p); -bool32 RfuUnionTool_GetGroupAndMemberInFrontOfPlayer(struct UnkStruct_Main0 *main0_p, s16 *member_p, s16 *group_p, u8 *spriteIds); -void UpdateUnionGroupMemberFacing(u32 member, u32 group, struct UnkStruct_Main0 *main0_p); +void ScheduleUnionRoomPlayerRefresh(struct WirelessLink_URoom *uroom_p); +void HandleUnionRoomPlayerRefresh(struct WirelessLink_URoom *uroom_p); +bool32 TryInteractWithUnionRoomMember(struct RfuPlayerList *main0_p, s16 *member_p, s16 *group_p, u8 *spriteIds); +void UpdateUnionGroupMemberFacing(u32 member, u32 group, struct RfuPlayerList *main0_p); #endif //GUARD_UNION_ROOM_PLAYER_AVATAR_H diff --git a/include/trade.h b/include/trade.h index ede68b05d..2380b2213 100644 --- a/include/trade.h +++ b/include/trade.h @@ -13,7 +13,7 @@ extern const u8 gText_FemaleSymbol4[]; extern const u8 gText_GenderlessSymbol[]; extern const u16 gTradeOrHatchMonShadowTilemap[]; -void CB2_ReturnFromLinkTrade(void); +void CB2_StartCreateTradeMenu(void); s32 Trade_CalcLinkPlayerCompatibilityParam(void); s32 CanRegisterMonForTradingBoard(struct RfuGameCompatibilityData rfuPlayer, u16 species2, u16 species, u8 isEventLegal); s32 GetUnionRoomTradeMessageId(struct RfuGameCompatibilityData rfuPlayer, struct RfuGameCompatibilityData rfuPartner, u16 playerSpecies2, u16 partnerSpecies, u8 requestedType, u16 playerSpecies, u8 isEventLegal); diff --git a/include/trade_scene.h b/include/trade_scene.h index 31679eafe..cbe336859 100644 --- a/include/trade_scene.h +++ b/include/trade_scene.h @@ -1,7 +1,7 @@ #ifndef GUARD_TRADE_SCENE_H #define GUARD_TRADE_SCENE_H -void CB2_InitTradeAnim_LinkTrade(void); +void CB2_LinkTrade(void); void CreateInGameTradePokemon(void); void DoInGameTradeScene(void); void DrawTextOnTradeWindow(u8 windowId, const u8 *str, s8 speed); diff --git a/include/union_room.h b/include/union_room.h index c39513ec2..51390c637 100644 --- a/include/union_room.h +++ b/include/union_room.h @@ -3,58 +3,60 @@ #include "global.h" #include "link_rfu.h" +#include "constants/union_room.h" -// Return value of IsRequestedTypeAndSpeciesInPlayerParty -#define UR_TRADE_MATCH 0 -#define UR_TRADE_NOTYPE 1 -#define UR_TRADE_NOEGG 2 +// 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) -#define UROOM_MAX_GROUP_COUNT 8 -#define UROOM_MAX_PARTY_SIZE 5 +// 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 UnionGnameUnamePair +struct RfuPlayerData { - struct RfuGameData gname; - u8 ALIGNED(4) uname[PLAYER_NAME_LENGTH + 1]; + struct RfuGameData data; + u8 ALIGNED(4) name[RFU_USER_NAME_LENGTH]; }; -struct UnkStruct_x1C +struct RfuPlayer { - struct UnionGnameUnamePair gname_uname; + struct RfuPlayerData rfu; + u16 timeoutCounter; + u8 groupScheduledAnim:2; + bool8 useRedText:1; // Never set + u8 newPlayerCountdown; + u8 unused; +}; + +struct RfuPlayerList +{ + struct RfuPlayer players[0]; // TODO: Should be size MAX_RFU_PLAYER_LIST_SIZE +}; + +struct RfuIncomingPlayer +{ + struct RfuPlayerData rfu; u8 active:1; }; -struct UnkStruct_x20 +struct RfuIncomingPlayerList { - struct UnionGnameUnamePair gname_uname; - u16 field_18; - u8 groupScheduledAnim:2; - bool8 field_1A_1:1; - u8 field_1B; - u32 field_1C; // unused + struct RfuIncomingPlayer players[0]; // TODO: Should be size MAX_RFU_PLAYERS }; -// These arrays are dynamically allocated but must be -// represented as structs to match. -// Don't ask me why. - -// FIXME: Find a way around this. - -struct UnkStruct_Main0 +struct WirelessLink_Leader { - struct UnkStruct_x20 arr[0]; -}; - -struct UnkStruct_Main4 -{ - struct UnkStruct_x1C arr[0]; -}; - -struct UnkStruct_Leader -{ - struct UnkStruct_Main0 * field_0; - struct UnkStruct_Main4 * field_4; - struct UnkStruct_Main0 * field_8; + struct RfuPlayerList * playerList; + struct RfuIncomingPlayerList * incomingPlayerList; + struct RfuPlayerList * playerListBackup; u8 state; u8 textState; u8 delayTimerAfterOk; @@ -63,36 +65,35 @@ struct UnkStruct_Leader u8 nPlayerModeWindowId; u8 listTaskId; u8 playerCount; - u8 messageWindowId; - u8 field_15; - u8 field_16; + u16 yesNoWindowId; + u8 unused; u8 listenTaskId; u8 activity; - u8 field_19; - u16 field_1A; + u8 joinRequestAnswer; + u16 memberConfirmTimeout; }; -struct UnkStruct_Group +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; // unused + u8 delayTimerAfterOk; // unused u8 listWindowId; u8 bButtonCancelWindowId; u8 playerNameAndIdWindowId; u8 listTaskId; u8 leaderId; - u8 field_10; + u8 unused; u8 listenTaskId; - u8 cardOrNews; - u8 field_13; // referenced but never set + bool8 isWonderNews; + bool8 showListMenu; // referenced but never set u8 refreshTimer; u8 delayBeforePrint; }; -struct UnionObj +struct UnionRoomObject { u8 state; u8 gfxId; @@ -100,69 +101,56 @@ struct UnionObj u8 schedAnim; }; -struct UnkStruct_URoom +struct WirelessLink_URoom { - /* 0x000 */ struct UnkStruct_Main0 * field_0; - /* 0x004 */ struct UnkStruct_Main4 * field_4; - /* 0x008 */ struct UnkStruct_Main0 * field_8; - /* 0x00C */ struct UnkStruct_Main4 * field_C; - /* 0x010 */ u16 field_10; - /* 0x012 */ u16 field_12; - /* 0x014 */ u8 state; - /* 0x015 */ u8 stateAfterPrint; - /* 0x016 */ u8 textState; - /* 0x017 */ u8 field_17; - /* 0x018 */ u8 field_18; - /* 0x019 */ u8 field_19; - /* 0x01A */ u8 field_1A; - /* 0x01B */ u8 topListMenuWindowId; - /* 0x01C */ u8 topListMenuListMenuId; - /* 0x01D */ u8 tradeBoardSelectWindowId; - /* 0x01E */ u8 tradeBoardDetailsWindowId; - /* 0x01F */ u8 field_1F; - /* 0x020 */ u8 field_20; - /* 0x021 */ u8 spriteIds[40]; - /* 0x049 */ u8 field_49; - /* 0x04A */ u8 tradeBoardListMenuId; - - // For communication with potential link partners - /* 0x04C */ u16 playerSendBuffer[6]; - /* 0x058 */ u8 activityRequestStrbufs[4][11]; - /* 0x084 */ u16 partnerYesNoResponse; - /* 0x086 */ u16 recvActivityRequest[3]; // activity[, species, level] - /* 0x08C */ struct UnionObj unionObjs[8]; - /* 0x0AC */ u8 trainerCardStrbufs[12][15]; - /* 0x160 */ u8 field_174[48]; - /* 0x190 */ u8 field_1A4[200]; -}; - -union UnkUnion_Main -{ - struct UnkStruct_Leader * leader; - struct UnkStruct_Group * group; - struct UnkStruct_URoom * uRoom; + struct RfuPlayerList * playerList; + struct RfuIncomingPlayerList * incomingChildList; + struct RfuPlayerList * spawnPlayer; + struct RfuIncomingPlayerList * incomingParentList; + u16 unknown; // Never read + u16 unreadPlayerId; + u8 state; + u8 stateAfterPrint; + u8 textState; + u8 filler[4]; + u8 topListMenuWindowId; + u8 topListMenuId; + u8 tradeBoardMainWindowId; + u8 tradeBoardHeaderWindowId; + u8 unused1; + u8 searchTaskId; + u8 spriteIds[NUM_UNION_ROOM_SPRITES]; + u8 unused2; + u8 tradeBoardListMenuId; +// For communication with potential link partners + u16 playerSendBuffer[6]; + u8 activityRequestStrbufs[4][11]; + u16 partnerYesNoResponse; + u16 recvActivityRequest[3]; // activity[, species, level] + struct UnionRoomObject objects[MAX_UNION_ROOM_LEADERS]; + u8 trainerCardStrBuffer[12][15]; + u8 trainerCardColorStrBuffer[48]; + u8 trainerCardMsgStrBuffer[200]; }; struct UnionRoomTrade { - u16 field_0; + u16 state; u16 type; u32 playerPersonality; - u8 field_8; - u8 field_9; + u8 offerPlayerId; u16 playerSpecies; u16 playerLevel; u16 species; u16 level; - u16 field_12; u32 personality; }; -extern struct RfuGameCompatibilityData gPartnerTgtGnameSub; +extern struct RfuGameCompatibilityData gRfuPartnerCompatibilityData; extern u16 gUnionRoomOfferedSpecies; extern u8 gUnionRoomRequestedMonType; void StartUnionRoomBattle(u16 battleFlags); -u8 UnionRoom_CreateTask_CallCB2ReturnFromLinkTrade(void); +u8 CreateTask_CreateTradeMenu(void); #endif //GUARD_UNION_ROOM_H diff --git a/src/cable_club.c b/src/cable_club.c index 1c80945be..b3fbc1f78 100644 --- a/src/cable_club.c +++ b/src/cable_club.c @@ -897,7 +897,7 @@ static void Task_StartWiredTrade(u8 taskId) case 3: if (!gReceivedRemoteLinkPlayers) { - SetMainCallback2(CB2_ReturnFromLinkTrade); + SetMainCallback2(CB2_StartCreateTradeMenu); DestroyTask(taskId); } break; @@ -929,7 +929,7 @@ static void Task_StartWirelessTrade(u8 taskId) case 3: if (IsLinkTaskFinished()) { - UnionRoom_CreateTask_CallCB2ReturnFromLinkTrade(); + CreateTask_CreateTradeMenu(); DestroyTask(taskId); } break; diff --git a/src/data/union_room.h b/src/data/union_room.h new file mode 100644 index 000000000..6c8254d1b --- /dev/null +++ b/src/data/union_room.h @@ -0,0 +1,470 @@ +static const u8 *const sLinkGroupActivityNameTexts[] = { + [ACTIVITY_NONE] = gText_UR_EmptyString, + [ACTIVITY_BATTLE_SINGLE] = gText_UR_SingleBattle, + [ACTIVITY_BATTLE_DOUBLE] = gText_UR_DoubleBattle, + [ACTIVITY_BATTLE_MULTI] = gText_UR_MultiBattle, + [ACTIVITY_TRADE] = gText_UR_PokemonTrades, + [ACTIVITY_CHAT] = gText_UR_Chat, + [ACTIVITY_WONDER_CARD_DUP] = gText_UR_WonderCards, + [ACTIVITY_WONDER_NEWS_DUP] = gText_UR_WonderNews, + [ACTIVITY_CARD] = gText_UR_Cards, + [ACTIVITY_POKEMON_JUMP] = gText_UR_PokemonJump, + [ACTIVITY_BERRY_CRUSH] = gText_UR_BerryCrush, + [ACTIVITY_BERRY_PICK] = gText_UR_BerryPicking, + [ACTIVITY_SEARCH] = gText_UR_Search, + [ACTIVITY_SPIN_TRADE] = gText_UR_SpinTrade, + [ACTIVITY_ITEM_TRADE] = gText_UR_ItemTrade, + [ACTIVITY_RECORD_CORNER] = gText_UR_EmptyString, + [ACTIVITY_BERRY_BLENDER] = gText_UR_EmptyString, + [ACTIVITY_ACCEPT] = gText_UR_EmptyString, + [ACTIVITY_DECLINE] = gText_UR_EmptyString, + [ACTIVITY_NPCTALK] = gText_UR_EmptyString, + [ACTIVITY_PLYRTALK] = gText_UR_EmptyString, + [ACTIVITY_WONDER_CARD] = gText_UR_WonderCards, + [ACTIVITY_WONDER_NEWS] = gText_UR_WonderNews +}; + +static const struct WindowTemplate sWindowTemplate_BButtonCancel = { + .bg = 0, + .tilemapLeft = 0, + .tilemapTop = 0, + .width = 30, + .height = 2, + .paletteNum = 0xF, + .baseBlock = 0x008 +}; + +// Minimum and maximum number of players for a link group +// A minimum of 0 means the min and max are equal +#define LINK_GROUP_CAPACITY(min, max)(((min) << 12) | ((max) << 8)) +#define GROUP_MAX(capacity)(capacity & 0x0F) +#define GROUP_MIN(capacity)(capacity >> 4) +#define GROUP_MIN2(capacity)(capacity & 0xF0) // Unnecessary to have both, but needed to match + +static const u32 sLinkGroupToActivityAndCapacity[] = { + [LINK_GROUP_SINGLE_BATTLE] = ACTIVITY_BATTLE_SINGLE | LINK_GROUP_CAPACITY(0, 2), + [LINK_GROUP_DOUBLE_BATTLE] = ACTIVITY_BATTLE_DOUBLE | LINK_GROUP_CAPACITY(0, 2), + [LINK_GROUP_MULTI_BATTLE] = ACTIVITY_BATTLE_MULTI | LINK_GROUP_CAPACITY(0, 4), + [LINK_GROUP_TRADE] = ACTIVITY_TRADE | LINK_GROUP_CAPACITY(0, 2), + [LINK_GROUP_POKEMON_JUMP] = ACTIVITY_POKEMON_JUMP | LINK_GROUP_CAPACITY(2, 5), + [LINK_GROUP_BERRY_CRUSH] = ACTIVITY_BERRY_CRUSH | LINK_GROUP_CAPACITY(2, 5), + [LINK_GROUP_BERRY_PICKING] = ACTIVITY_BERRY_PICK | LINK_GROUP_CAPACITY(3, 5), + [LINK_GROUP_WONDER_CARD] = ACTIVITY_SPIN_TRADE | LINK_GROUP_CAPACITY(3, 5), + [LINK_GROUP_WONDER_NEWS] = ACTIVITY_ITEM_TRADE | LINK_GROUP_CAPACITY(3, 5) +}; + +static const struct WindowTemplate sWindowTemplate_List_PossibleGroupMembers = { + .bg = 0, + .tilemapLeft = 1, + .tilemapTop = 3, + .width = 13, + .height = 10, + .paletteNum = 15, + .baseBlock = 0x044 +}; + +static const struct WindowTemplate sWindowTemplate_NumPlayerMode = { + .bg = 0, + .tilemapLeft = 16, + .tilemapTop = 3, + .width = 7, + .height = 4, + .paletteNum = 15, + .baseBlock = 0x0C6 +}; + +const struct ListMenuItem sListMenuItems_PossibleGroupMembers[] = { + {gText_UR_EmptyString, 0}, + {gText_UR_EmptyString, 1}, + {gText_UR_EmptyString, 2}, + {gText_UR_EmptyString, 3}, + {gText_UR_EmptyString, 4} +}; + +static const struct ListMenuTemplate sListMenuTemplate_PossibleGroupMembers = { + .items = sListMenuItems_PossibleGroupMembers, + .moveCursorFunc = NULL, + .itemPrintFunc = ItemPrintFunc_PossibleGroupMembers, + .totalItems = ARRAY_COUNT(sListMenuItems_PossibleGroupMembers), + .maxShowed = 5, + .windowId = 0, + .header_X = 0, + .item_X = 1, + .cursor_X = 0, + .upText_Y = 0, + .cursorPal = 2, + .fillValue = 1, + .cursorShadowPal = 3, + .lettersSpacing = 0, + .itemVerticalPadding = 2, + .scrollMultiple = LIST_NO_MULTIPLE_SCROLL, + .fontId = FONT_2, + .cursorKind = 1 +}; + +static const struct WindowTemplate sWindowTemplate_GroupList = { + .bg = 0, + .tilemapLeft = 1, + .tilemapTop = 3, + .width = 17, + .height = 10, + .paletteNum = 15, + .baseBlock = 0x044 +}; + +static const struct WindowTemplate sWindowTemplate_PlayerNameAndId = { + .bg = 0, + .tilemapLeft = 20, + .tilemapTop = 3, + .width = 7, + .height = 4, + .paletteNum = 15, + .baseBlock = 0x0EE +}; + +static const struct ListMenuItem sListMenuItems_UnionRoomGroups[] = { + {gText_UR_EmptyString, 0}, + {gText_UR_EmptyString, 1}, + {gText_UR_EmptyString, 2}, + {gText_UR_EmptyString, 3}, + {gText_UR_EmptyString, 4}, + {gText_UR_EmptyString, 5}, + {gText_UR_EmptyString, 6}, + {gText_UR_EmptyString, 7}, + {gText_UR_EmptyString, 8}, + {gText_UR_EmptyString, 9}, + {gText_UR_EmptyString, 10}, + {gText_UR_EmptyString, 11}, + {gText_UR_EmptyString, 12}, + {gText_UR_EmptyString, 13}, + {gText_UR_EmptyString, 14}, + {gText_UR_EmptyString, 15} +}; + +static const struct ListMenuTemplate sListMenuTemplate_UnionRoomGroups = { + .items = sListMenuItems_UnionRoomGroups, + .moveCursorFunc = ListMenuDefaultCursorMoveFunc, + .itemPrintFunc = ListMenuItemPrintFunc_UnionRoomGroups, + .totalItems = ARRAY_COUNT(sListMenuItems_UnionRoomGroups), + .maxShowed = 5, + .windowId = 0, + .header_X = 0, + .item_X = 8, + .cursor_X = 0, + .upText_Y = 0, + .cursorPal = 2, + .fillValue = 1, + .cursorShadowPal = 3, + .lettersSpacing = 0, + .itemVerticalPadding = 2, + .scrollMultiple = LIST_MULTIPLE_SCROLL_DPAD, + .fontId = FONT_2, + .cursorKind = 0 +}; + +static const struct WindowTemplate sWindowTemplate_InviteToActivity = { + .bg = 0, + .tilemapLeft = 20, + .tilemapTop = 6, + .width = 8, + .height = 7, + .paletteNum = 15, + .baseBlock = 0x001 +}; + +static const struct ListMenuItem sListMenuItems_InviteToActivity[] = { + {gText_UR_Greetings, ACTIVITY_CARD | LINK_GROUP_CAPACITY(0, 2)}, + {gText_UR_Battle, ACTIVITY_BATTLE_SINGLE | IN_UNION_ROOM | LINK_GROUP_CAPACITY(0, 2)}, + {gText_UR_Chat2, ACTIVITY_CHAT | IN_UNION_ROOM | LINK_GROUP_CAPACITY(0, 2)}, + {gText_UR_Exit, ACTIVITY_NONE | IN_UNION_ROOM } +}; + +static const struct ListMenuTemplate sListMenuTemplate_InviteToActivity = { + .items = sListMenuItems_InviteToActivity, + .moveCursorFunc = ListMenuDefaultCursorMoveFunc, + .itemPrintFunc = NULL, + .totalItems = ARRAY_COUNT(sListMenuItems_InviteToActivity), + .maxShowed = 4, + .windowId = 0, + .header_X = 0, + .item_X = 8, + .cursor_X = 0, + .upText_Y = 0, + .cursorPal = 2, + .fillValue = 1, + .cursorShadowPal = 3, + .lettersSpacing = 1, + .itemVerticalPadding = 0, + .scrollMultiple = LIST_NO_MULTIPLE_SCROLL, + .fontId = FONT_2, + .cursorKind = 0 +}; + +static const struct WindowTemplate sWindowTemplate_RegisterForTrade = { + .bg = 0, + .tilemapLeft = 18, + .tilemapTop = 8, + .width = 11, + .height = 5, + .paletteNum = 15, + .baseBlock = 0x001 +}; + +static const struct ListMenuItem sListMenuItems_RegisterForTrade[] = { + {gText_Register, 1}, + {gText_UR_Info, 2}, + {gText_UR_Exit, 3} +}; + +static const struct ListMenuTemplate sListMenuTemplate_RegisterForTrade = { + .items = sListMenuItems_RegisterForTrade, + .moveCursorFunc = ListMenuDefaultCursorMoveFunc, + .itemPrintFunc = NULL, + .totalItems = ARRAY_COUNT(sListMenuItems_RegisterForTrade), + .maxShowed = 3, + .windowId = 0, + .header_X = 0, + .item_X = 8, + .cursor_X = 0, + .upText_Y = 0, + .cursorPal = 2, + .fillValue = 1, + .cursorShadowPal = 3, + .lettersSpacing = 1, + .itemVerticalPadding = 0, + .scrollMultiple = LIST_NO_MULTIPLE_SCROLL, + .fontId = FONT_2, + .cursorKind = 0 +}; + +static const struct WindowTemplate sWindowTemplate_TypeNames = { + .bg = 0, + .tilemapLeft = 20, + .tilemapTop = 2, + .width = 9, + .height = 11, + .paletteNum = 15, + .baseBlock = 0x001 +}; + +static const struct ListMenuItem sListMenuItems_TypeNames[NUMBER_OF_MON_TYPES] = { + { gTypeNames[TYPE_NORMAL], TYPE_NORMAL }, + { gTypeNames[TYPE_FIRE], TYPE_FIRE }, + { gTypeNames[TYPE_WATER], TYPE_WATER }, + { gTypeNames[TYPE_ELECTRIC], TYPE_ELECTRIC }, + { gTypeNames[TYPE_GRASS], TYPE_GRASS }, + { gTypeNames[TYPE_ICE], TYPE_ICE }, + { gTypeNames[TYPE_GROUND], TYPE_GROUND }, + { gTypeNames[TYPE_ROCK], TYPE_ROCK }, + { gTypeNames[TYPE_FLYING], TYPE_FLYING }, + { gTypeNames[TYPE_PSYCHIC], TYPE_PSYCHIC }, + { gTypeNames[TYPE_FIGHTING], TYPE_FIGHTING }, + { gTypeNames[TYPE_POISON], TYPE_POISON }, + { gTypeNames[TYPE_BUG], TYPE_BUG }, + { gTypeNames[TYPE_GHOST], TYPE_GHOST }, + { gTypeNames[TYPE_DRAGON], TYPE_DRAGON }, + { gTypeNames[TYPE_STEEL], TYPE_STEEL }, + { gTypeNames[TYPE_DARK], TYPE_DARK }, + { gText_UR_Exit, NUMBER_OF_MON_TYPES } +}; + +static const struct ListMenuTemplate sListMenuTemplate_TypeNames = { + .items = sListMenuItems_TypeNames, + .moveCursorFunc = ListMenuDefaultCursorMoveFunc, + .itemPrintFunc = NULL, + .totalItems = NUMBER_OF_MON_TYPES, + .maxShowed = 6, + .windowId = 0, + .header_X = 0, + .item_X = 8, + .cursor_X = 0, + .upText_Y = 2, + .cursorPal = 2, + .fillValue = 1, + .cursorShadowPal = 3, + .lettersSpacing = 1, + .itemVerticalPadding = 0, + .scrollMultiple = LIST_NO_MULTIPLE_SCROLL, + .fontId = FONT_2, + .cursorKind = 0 +}; + +static const struct WindowTemplate sWindowTemplate_TradingBoardHeader = { + .bg = 0, + .tilemapLeft = 1, + .tilemapTop = 1, + .width = 28, + .height = 2, + .paletteNum = 13, + .baseBlock = 0x001 +}; + +static const struct WindowTemplate sWindowTemplate_TradingBoardMain = { + .bg = 0, + .tilemapLeft = 1, + .tilemapTop = 5, + .width = 28, + .height = 10, + .paletteNum = 13, + .baseBlock = 0x039 +}; + +static const struct ListMenuItem sListMenuItems_TradeBoard[] = { + {gText_UR_EmptyString, -3}, + {gText_UR_EmptyString, 0}, + {gText_UR_EmptyString, 1}, + {gText_UR_EmptyString, 2}, + {gText_UR_EmptyString, 3}, + {gText_UR_EmptyString, 4}, + {gText_UR_EmptyString, 5}, + {gText_UR_EmptyString, 6}, + {gText_UR_EmptyString, 7}, + {gText_UR_Exit2, 8} +}; + +static const struct ListMenuTemplate sListMenuTemplate_TradeBoard = { + .items = sListMenuItems_TradeBoard, + .moveCursorFunc = ListMenuDefaultCursorMoveFunc, + .itemPrintFunc = TradeBoardListMenuItemPrintFunc, + .totalItems = ARRAY_COUNT(sListMenuItems_TradeBoard), + .maxShowed = 5, + .windowId = 0, + .header_X = 0, + .item_X = 12, + .cursor_X = 0, + .upText_Y = 2, + .cursorPal = 14, + .fillValue = 15, + .cursorShadowPal = 13, + .lettersSpacing = 1, + .itemVerticalPadding = 1, + .scrollMultiple = LIST_NO_MULTIPLE_SCROLL, + .fontId = FONT_2, + .cursorKind = 0 +}; + +static const struct WindowTemplate sWindowTemplate_Unused = { + .bg = 0, + .tilemapLeft = 1, + .tilemapTop = 5, + .width = 28, + .height = 10, + .paletteNum = 13, + .baseBlock = 0x039 +}; + +static const struct ListMenuItem sListMenuItems_Unused[] = { + {gText_UR_EmptyString, 0}, + {gText_UR_EmptyString, 1}, + {gText_UR_EmptyString, 2}, + {gText_UR_EmptyString, 3}, + {gText_UR_EmptyString, 4}, + {gText_UR_EmptyString, 5}, + {gText_UR_EmptyString, 6}, + {gText_UR_EmptyString, 7}, + {gText_UR_EmptyString, 8}, + {gText_UR_EmptyString, 9}, + {gText_UR_EmptyString, 10}, + {gText_UR_EmptyString, 11}, + {gText_UR_EmptyString, 12}, + {gText_UR_EmptyString, 13}, + {gText_UR_EmptyString, 14}, + {gText_UR_EmptyString, 15} +}; + +static const struct ListMenuTemplate sListMenuTemplate_Unused = { + .items = sListMenuItems_Unused, + .moveCursorFunc = ListMenuDefaultCursorMoveFunc, + .itemPrintFunc = ItemPrintFunc_Unused, + .totalItems = ARRAY_COUNT(sListMenuItems_Unused), + .maxShowed = 4, + .windowId = 0, + .header_X = 0, + .item_X = 8, + .cursor_X = 1, + .upText_Y = 0, + .cursorPal = 2, + .fillValue = 1, + .cursorShadowPal = 3, + .lettersSpacing = 1, + .itemVerticalPadding = 0, + .scrollMultiple = LIST_MULTIPLE_SCROLL_DPAD, + .fontId = FONT_2, + .cursorKind = 0 +}; + +static const struct RfuPlayerData sRfuPlayerData_Dummy = {}; + +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, + IN_UNION_ROOM | ACTIVITY_CHAT, + IN_UNION_ROOM | ACTIVITY_CARD, + IN_UNION_ROOM | ACTIVITY_ACCEPT, + IN_UNION_ROOM | ACTIVITY_DECLINE, + IN_UNION_ROOM | ACTIVITY_NPCTALK, + IN_UNION_ROOM | ACTIVITY_PLYRTALK, + 0xFF +}; +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, + ACTIVITY_TRADE, + ACTIVITY_POKEMON_JUMP, + ACTIVITY_BERRY_CRUSH, + ACTIVITY_BERRY_PICK, + ACTIVITY_WONDER_CARD, + ACTIVITY_WONDER_NEWS, + ACTIVITY_SPIN_TRADE, + 0xFF +}; +ALIGNED(4) static const u8 sAcceptedActivityIds_Unk12[] = { + ACTIVITY_BATTLE_SINGLE, + ACTIVITY_BATTLE_DOUBLE, + ACTIVITY_BATTLE_MULTI, + ACTIVITY_TRADE, + ACTIVITY_BERRY_CRUSH, + 0xFF +}; + +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, + [LINK_GROUP_TRADE] = sAcceptedActivityIds_Trade, + [LINK_GROUP_POKEMON_JUMP] = sAcceptedActivityIds_PokemonJump, + [LINK_GROUP_BERRY_CRUSH] = sAcceptedActivityIds_BerryCrush, + [LINK_GROUP_BERRY_PICKING] = sAcceptedActivityIds_BerryPicking, + [LINK_GROUP_WONDER_CARD] = sAcceptedActivityIds_WonderCard, + [LINK_GROUP_WONDER_NEWS] = sAcceptedActivityIds_WonderNews, + [LINK_GROUP_UNION_ROOM_RESUME] = sAcceptedActivityIds_Resume, + [LINK_GROUP_UNION_ROOM_INIT] = sAcceptedActivityIds_Init, + [LINK_GROUP_UNK_11] = sAcceptedActivityIds_Unk11, + [LINK_GROUP_UNK_12] = sAcceptedActivityIds_Unk12, +}; + +static const u8 sLinkGroupToURoomActivity[] = { + [LINK_GROUP_SINGLE_BATTLE] = ACTIVITY_BATTLE_SINGLE, + [LINK_GROUP_DOUBLE_BATTLE] = ACTIVITY_BATTLE_DOUBLE, + [LINK_GROUP_MULTI_BATTLE] = ACTIVITY_BATTLE_MULTI, + [LINK_GROUP_TRADE] = ACTIVITY_TRADE, + [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_CARD, + [LINK_GROUP_WONDER_NEWS] = ACTIVITY_WONDER_NEWS +}; + +static const u8 sUnref_84570D1[] = _("{DYNAMIC 00}·{DYNAMIC 01}"); diff --git a/src/link_rfu_2.c b/src/link_rfu_2.c index 480f1874c..885af4dd3 100644 --- a/src/link_rfu_2.c +++ b/src/link_rfu_2.c @@ -2752,8 +2752,8 @@ static void Task_RfuReconnectWithParent(u8 taskId) if (TryReconnectParent()) DestroyTask(taskId); } - else if (GetHostRfuGameData()->activity == ACTIVITY_WCARD2 - || GetHostRfuGameData()->activity == ACTIVITY_WNEWS2) + else if (GetHostRfuGameData()->activity == ACTIVITY_WONDER_CARD + || GetHostRfuGameData()->activity == ACTIVITY_WONDER_NEWS) { tTime++; } diff --git a/src/mevent.c b/src/mevent.c index 386437259..d16f85ee1 100644 --- a/src/mevent.c +++ b/src/mevent.c @@ -263,7 +263,7 @@ static void Task_EReaderComm(u8 taskId) switch (data->state) { case 0: - if (MG_PrintTextOnWindow1AndWaitButton(&data->textOrReceiveState, gJPText_ReceiveMysteryGiftWithEReader)) + if (PrintMysteryGiftMenuMessage(&data->textOrReceiveState, gJPText_ReceiveMysteryGiftWithEReader)) data->state = 1; break; case 1: @@ -285,7 +285,7 @@ static void Task_EReaderComm(u8 taskId) data->state = 13; break; case 4: - if (MG_PrintTextOnWindow1AndWaitButton(&data->textOrReceiveState, gJPText_SelectConnectFromEReaderMenu)) + if (PrintMysteryGiftMenuMessage(&data->textOrReceiveState, gJPText_SelectConnectFromEReaderMenu)) { AddTextPrinterToWindow1(gJPText_SelectConnectWithGBA); ResetDelayTimer(&data->stateAdvanceDelay); @@ -334,7 +334,7 @@ static void Task_EReaderComm(u8 taskId) } break; case 7: - if (MG_PrintTextOnWindow1AndWaitButton(&data->textOrReceiveState, gJPText_LinkIsIncorrect)) + if (PrintMysteryGiftMenuMessage(&data->textOrReceiveState, gJPText_LinkIsIncorrect)) data->state = 4; break; case 8: @@ -451,19 +451,19 @@ static void Task_EReaderComm(u8 taskId) data->state = 26; break; case 23: - if (MG_PrintTextOnWindow1AndWaitButton(&data->textOrReceiveState, gJPText_CardReadingHasBeenHalted)) + if (PrintMysteryGiftMenuMessage(&data->textOrReceiveState, gJPText_CardReadingHasBeenHalted)) data->state = 26; break; case 20: - if (MG_PrintTextOnWindow1AndWaitButton(&data->textOrReceiveState, gJPText_ConnectionErrorCheckLink)) + if (PrintMysteryGiftMenuMessage(&data->textOrReceiveState, gJPText_ConnectionErrorCheckLink)) data->state = 0; break; case 21: - if (MG_PrintTextOnWindow1AndWaitButton(&data->textOrReceiveState, gJPText_ConnectionErrorTryAgain)) + if (PrintMysteryGiftMenuMessage(&data->textOrReceiveState, gJPText_ConnectionErrorTryAgain)) data->state = 0; break; case 22: - if (MG_PrintTextOnWindow1AndWaitButton(&data->textOrReceiveState, gJPText_WriteErrorUnableToSaveData)) + if (PrintMysteryGiftMenuMessage(&data->textOrReceiveState, gJPText_WriteErrorUnableToSaveData)) data->state = 0; break; case 26: @@ -943,12 +943,12 @@ u16 MEvent_GetBattleCardCount(u32 command) return 0; } -void ResetReceivedWonderCardFlag(void) +void MysteryGift_DisableStats(void) { sReceivedWonderCardIsValid = FALSE; } -bool32 MEventHandleReceivedWonderCard(u16 flagId) +bool32 MysteryGift_TryEnableStatsByFlagId(u16 flagId) { sReceivedWonderCardIsValid = FALSE; if (flagId == 0) diff --git a/src/mystery_gift_menu.c b/src/mystery_gift_menu.c index 380e0b264..b07a57ee0 100644 --- a/src/mystery_gift_menu.c +++ b/src/mystery_gift_menu.c @@ -540,7 +540,7 @@ void ClearTextWindow(void) CopyWindowToVram(1, COPYWIN_MAP); } -bool32 MG_PrintTextOnWindow1AndWaitButton(u8 *textState, const u8 *str) +bool32 PrintMysteryGiftMenuMessage(u8 *textState, const u8 *str) { switch (*textState) { @@ -650,7 +650,7 @@ u32 MysteryGift_HandleThreeOptionMenu(u8 * unused0, u16 * unused1, u8 whichMenu) return response; } -s8 mevent_message_print_and_prompt_yes_no(u8 * textState, u16 * windowId, bool8 yesNoBoxPlacement, const u8 * str) +s8 DoMysteryGiftYesNo(u8 * textState, u16 * windowId, bool8 yesNoBoxPlacement, const u8 * str) { struct WindowTemplate windowTemplate; s8 input; @@ -878,25 +878,17 @@ bool32 TearDownCardOrNews_ReturnToTopMenu(bool32 cardOrNews, bool32 arg1) s32 mevent_message_prompt_discard(u8 * textState, u16 * windowId, bool32 cardOrNews) { if (cardOrNews == 0) - { - return mevent_message_print_and_prompt_yes_no(textState, windowId, TRUE, gText_IfThrowAwayCardEventWontHappen); - } + return DoMysteryGiftYesNo(textState, windowId, TRUE, gText_IfThrowAwayCardEventWontHappen); else - { - return mevent_message_print_and_prompt_yes_no(textState, windowId, TRUE, gText_OkayToDiscardNews); - } + return DoMysteryGiftYesNo(textState, windowId, TRUE, gText_OkayToDiscardNews); } bool32 mevent_message_was_thrown_away(u8 * textState, bool32 cardOrNews) { if (cardOrNews == 0) - { - return MG_PrintTextOnWindow1AndWaitButton(textState, gText_WonderCardThrownAway); - } + return PrintMysteryGiftMenuMessage(textState, gText_WonderCardThrownAway); else - { - return MG_PrintTextOnWindow1AndWaitButton(textState, gText_WonderNewsThrownAway); - } + return PrintMysteryGiftMenuMessage(textState, gText_WonderNewsThrownAway); } bool32 mevent_save_game(u8 * state) @@ -1098,7 +1090,7 @@ static bool32 PrintMGSendStatus(u8 * state, u16 * arg1, u8 arg2, u32 msgId) } else { - return MG_PrintTextOnWindow1AndWaitButton(state, str); + return PrintMysteryGiftMenuMessage(state, str); } } @@ -1165,7 +1157,7 @@ void task00_mystery_gift(u8 taskId) { if (data->IsCardOrNews == 0) { - if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, gText_DontHaveCardNewOneInput)) + if (PrintMysteryGiftMenuMessage(&data->textState, gText_DontHaveCardNewOneInput)) { data->state = 3; PrintMysteryGiftOrEReaderTopMenu(0, 1); @@ -1173,7 +1165,7 @@ void task00_mystery_gift(u8 taskId) } else { - if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, gText_DontHaveNewsNewOneInput)) + if (PrintMysteryGiftMenuMessage(&data->textState, gText_DontHaveNewsNewOneInput)) { data->state = 3; PrintMysteryGiftOrEReaderTopMenu(0, 1); @@ -1228,23 +1220,15 @@ void task00_mystery_gift(u8 taskId) { case 0: if (data->source == 1) - { - MEvent_CreateTask_CardOrNewsWithFriend(ACTIVITY_WCARD2); - } + CreateTask_LinkMysteryGiftWithFriend(ACTIVITY_WONDER_CARD); else if (data->source == 0) - { - MEvent_CreateTask_CardOrNewsOverWireless(ACTIVITY_WCARD2); - } + CreateTask_LinkMysteryGiftOverWireless(ACTIVITY_WONDER_CARD); break; case 1: if (data->source == 1) - { - MEvent_CreateTask_CardOrNewsWithFriend(ACTIVITY_WNEWS2); - } + CreateTask_LinkMysteryGiftWithFriend(ACTIVITY_WONDER_NEWS); else if (data->source == 0) - { - MEvent_CreateTask_CardOrNewsOverWireless(ACTIVITY_WNEWS2); - } + CreateTask_LinkMysteryGiftOverWireless(ACTIVITY_WONDER_NEWS); break; } data->state = 6; @@ -1291,7 +1275,7 @@ void task00_mystery_gift(u8 taskId) } break; case 9: - flag = mevent_message_print_and_prompt_yes_no(&data->textState, &data->curPromptWindowId, FALSE, mevent_client_get_buffer()); + flag = DoMysteryGiftYesNo(&data->textState, &data->curPromptWindowId, FALSE, mevent_client_get_buffer()); switch (flag) { case 0: @@ -1312,14 +1296,14 @@ void task00_mystery_gift(u8 taskId) } break; case 10: - if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, mevent_client_get_buffer())) + if (PrintMysteryGiftMenuMessage(&data->textState, mevent_client_get_buffer())) { mevent_client_inc_flag(); data->state = 7; } break; case 11: - flag = mevent_message_print_and_prompt_yes_no(&data->textState, &data->curPromptWindowId, FALSE, gText_ThrowAwayWonderCard); + flag = DoMysteryGiftYesNo(&data->textState, &data->curPromptWindowId, FALSE, gText_ThrowAwayWonderCard); switch (flag) { case 0: @@ -1347,7 +1331,7 @@ void task00_mystery_gift(u8 taskId) } break; case 12: - flag = mevent_message_print_and_prompt_yes_no(&data->textState, &data->curPromptWindowId, FALSE, gText_HaventReceivedCardsGift); + flag = DoMysteryGiftYesNo(&data->textState, &data->curPromptWindowId, FALSE, gText_HaventReceivedCardsGift); switch (flag) { case 0: @@ -1387,17 +1371,12 @@ void task00_mystery_gift(u8 taskId) case 15: r1 = mevent_message(&sp0, data->IsCardOrNews, data->source, data->prevPromptWindowId); if (r1 == NULL) - { r1 = data->buffer; - } if (sp0) - { flag = PrintMGSuccessMessage(&data->textState, r1, &data->curPromptWindowId); - } else - { - flag = MG_PrintTextOnWindow1AndWaitButton(&data->textState, r1); - } + flag = PrintMysteryGiftMenuMessage(&data->textState, r1); + if (flag) { if (data->prevPromptWindowId == 3) @@ -1423,7 +1402,7 @@ void task00_mystery_gift(u8 taskId) } break; case 16: - if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, gText_CommunicationError)) + if (PrintMysteryGiftMenuMessage(&data->textState, gText_CommunicationError)) { data->state = 0; PrintMysteryGiftOrEReaderTopMenu(0, 0); @@ -1536,7 +1515,7 @@ void task00_mystery_gift(u8 taskId) } break; case 23: - switch ((u32)mevent_message_print_and_prompt_yes_no(&data->textState, &data->curPromptWindowId, TRUE, gText_HaventReceivedGiftOkayToDiscard)) + switch ((u32)DoMysteryGiftYesNo(&data->textState, &data->curPromptWindowId, TRUE, gText_HaventReceivedGiftOkayToDiscard)) { case 0: data->state = 24; @@ -1587,10 +1566,10 @@ void task00_mystery_gift(u8 taskId) switch (data->IsCardOrNews) { case 0: - MEvent_CreateTask_Leader(ACTIVITY_WCARD2); + CreateTask_SendMysteryGift(ACTIVITY_WONDER_CARD); break; case 1: - MEvent_CreateTask_Leader(ACTIVITY_WNEWS2); + CreateTask_SendMysteryGift(ACTIVITY_WONDER_NEWS); break; } data->source = 1; @@ -1660,7 +1639,7 @@ void task00_mystery_gift(u8 taskId) } break; case 36: - if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, gText_CommunicationError)) + if (PrintMysteryGiftMenuMessage(&data->textState, gText_CommunicationError)) { data->state = 0; PrintMysteryGiftOrEReaderTopMenu(0, 0); diff --git a/src/party_menu.c b/src/party_menu.c index 84b9b5807..74a76adc8 100644 --- a/src/party_menu.c +++ b/src/party_menu.c @@ -3877,7 +3877,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 RfuGameCompatibilityData *)GetHostRfuGameData(), 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/rfu_union_tool.c b/src/rfu_union_tool.c index 51b6106d5..d6e77519d 100644 --- a/src/rfu_union_tool.c +++ b/src/rfu_union_tool.c @@ -10,7 +10,7 @@ #include "constants/union_room.h" #include "constants/event_objects.h" -static EWRAM_DATA struct UnionObj * UnionObjWork = NULL; +static EWRAM_DATA struct UnionRoomObject * UnionObjWork = NULL; static EWRAM_DATA u32 sUnionObjRefreshTimer = 0; static u8 StartUnionObjAnimTask(void); @@ -212,7 +212,7 @@ static bool32 TryReleaseUnionRoomPlayerObjectEvent(u32 playerIdx) return TRUE; } -u8 ZeroUnionObjWork(struct UnionObj * ptr) +u8 ZeroUnionObjWork(struct UnionRoomObject * ptr) { s32 i; @@ -234,7 +234,7 @@ static const u8 sMovement_UnionPlayerExit[2] = { MOVEMENT_ACTION_STEP_END }; -static bool32 AnimateUnionRoomPlayerDespawn(s8 * a0, u32 playerIdx, struct UnionObj * ptr) +static bool32 AnimateUnionRoomPlayerDespawn(s8 * a0, u32 playerIdx, struct UnionRoomObject * ptr) { switch (*a0) { @@ -263,7 +263,7 @@ static const u8 sMovement_UnionPlayerEnter[2] = { MOVEMENT_ACTION_STEP_END }; -static bool32 AnimateUnionRoomPlayerSpawn(s8 * state_p, u32 playerIdx, struct UnionObj * ptr) +static bool32 AnimateUnionRoomPlayerSpawn(s8 * state_p, u32 playerIdx, struct UnionRoomObject * ptr) { s16 x, y; @@ -308,7 +308,7 @@ static bool32 AnimateUnionRoomPlayerSpawn(s8 * state_p, u32 playerIdx, struct Un static bool32 SpawnGroupLeader(u32 playerIdx, u32 gender, u32 idMod256) { - struct UnionObj * ptr = &UnionObjWork[playerIdx]; + struct UnionRoomObject * ptr = &UnionObjWork[playerIdx]; AGB_ASSERT_EX(UnionObjWork != NULL, ABSPATH("rfu_union_tool.c"), 561) ptr->schedAnim = UNION_ROOM_SPAWN_IN; ptr->gfxId = GetUnionRoomPlayerGraphicsId(gender, idMod256); @@ -324,7 +324,7 @@ static bool32 SpawnGroupLeader(u32 playerIdx, u32 gender, u32 idMod256) static bool32 DespawnGroupLeader(u32 playerIdx) { - struct UnionObj * ptr = &UnionObjWork[playerIdx]; + struct UnionRoomObject * ptr = &UnionObjWork[playerIdx]; AGB_ASSERT_EX(UnionObjWork != NULL, ABSPATH("rfu_union_tool.c"), 577) ptr->schedAnim = UNION_ROOM_SPAWN_OUT; if (ptr->state == 1) @@ -337,7 +337,7 @@ static bool32 DespawnGroupLeader(u32 playerIdx) } } -static void AnimateUnionObj(u32 playerIdx, struct UnionObj * ptr) +static void AnimateUnionObj(u32 playerIdx, struct UnionRoomObject * ptr) { switch (ptr->state) { @@ -418,7 +418,7 @@ static void DestroyAnimateUnionObjsTask(void) } } -void DeleteUnionObjWorkAndStopTask(void) +void DestroyUnionRoomPlayerObjects(void) { s32 i; for (i = 0; i < 8; i++) @@ -577,30 +577,30 @@ static void DespawnGroupLeaderAndMembers(u32 group, struct RfuGameData * gname) } } -static void UpdateUnionRoomPlayerSprites(struct UnkStruct_URoom * groups) +static void UpdateUnionRoomPlayerSprites(struct WirelessLink_URoom * groups) { s32 i; - struct UnkStruct_x20 * x20_p; + struct RfuPlayer * x20_p; sUnionObjRefreshTimer = 0; - for (i = 0, x20_p = groups->field_0->arr; i < 8; i++) + for (i = 0, x20_p = groups->playerList->players; i < 8; i++) { if (x20_p[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN) { - SpawnGroupLeaderAndMembers(i, &x20_p[i].gname_uname.gname); + SpawnGroupLeaderAndMembers(i, &x20_p[i].rfu.data); } else if (x20_p[i].groupScheduledAnim == UNION_ROOM_SPAWN_OUT) { - DespawnGroupLeaderAndMembers(i, &x20_p[i].gname_uname.gname); + DespawnGroupLeaderAndMembers(i, &x20_p[i].rfu.data); } } } -void ScheduleUnionRoomPlayerRefresh(struct UnkStruct_URoom *uroom_p) +void ScheduleUnionRoomPlayerRefresh(struct WirelessLink_URoom *uroom_p) { sUnionObjRefreshTimer = 300; } -void HandleUnionRoomPlayerRefresh(struct UnkStruct_URoom *uroom_p) +void HandleUnionRoomPlayerRefresh(struct WirelessLink_URoom *uroom_p) { if (++sUnionObjRefreshTimer > 300) { @@ -608,17 +608,17 @@ void HandleUnionRoomPlayerRefresh(struct UnkStruct_URoom *uroom_p) } } -bool32 RfuUnionTool_GetGroupAndMemberInFrontOfPlayer(struct UnkStruct_Main0 *main0_p, s16 *member_p, s16 *group_p, u8 *spriteIds) +bool32 TryInteractWithUnionRoomMember(struct RfuPlayerList *main0_p, s16 *member_p, s16 *group_p, u8 *spriteIds) { s16 x, y; s32 i, j; - struct UnkStruct_x20 * x20_p; + struct RfuPlayer * x20_p; if (!is_walking_or_running()) { return FALSE; } GetXYCoordsOneStepInFrontOfPlayer(&x, &y); - for (i = 0, x20_p = main0_p->arr; i < 8; i++) + for (i = 0, x20_p = main0_p->players; i < 8; i++) { for (j = 0; j < 5; j++) { @@ -657,7 +657,7 @@ static void UnionPartnerObjectSetFacing(s32 member, s32 group, u8 direction) TurnVirtualObject(5 * group - 0x38 + member, direction); } -void UpdateUnionGroupMemberFacing(u32 member, u32 group, struct UnkStruct_Main0 *main0_p) +void UpdateUnionGroupMemberFacing(u32 member, u32 group, struct RfuPlayerList *main0_p) { - return UnionPartnerObjectSetFacing(member, group, UnionPartnerObjectGetFacing(member, group, &main0_p->arr[group].gname_uname.gname)); + return UnionPartnerObjectSetFacing(member, group, UnionPartnerObjectGetFacing(member, group, &main0_p->players[group].rfu.data)); } diff --git a/src/start_menu.c b/src/start_menu.c index ec2616338..76f6cade2 100644 --- a/src/start_menu.c +++ b/src/start_menu.c @@ -374,7 +374,7 @@ void Task_StartMenuHandleInput(u8 taskId) { case 0: if (InUnionRoom() == TRUE) - var_800D_set_xB(); + SetUsingUnionRoomStartMenu(); sStartMenuCallback = StartCB_HandleInput; data[0]++; break; diff --git a/src/trade.c b/src/trade.c index e8ada5673..c302f93b3 100644 --- a/src/trade.c +++ b/src/trade.c @@ -711,7 +711,7 @@ static void InitTradeMenuResources(void) } } -void CB2_ReturnFromLinkTrade(void) +void CB2_StartCreateTradeMenu(void) { SetMainCallback2(CB2_ReturnFromLinkTrade2); } @@ -1208,7 +1208,7 @@ static void TradeMenuCB_10(void) static void TradeMenuCB_13(void) { - gMain.savedCallback = CB2_ReturnFromLinkTrade; + gMain.savedCallback = CB2_StartCreateTradeMenu; if (gWirelessCommType != 0) { if (IsLinkRfuTaskFinished()) @@ -1218,7 +1218,7 @@ static void TradeMenuCB_13(void) Free(sTradeMenuResourcesPtr); gMain.callback1 = NULL; DestroyWirelessStatusIndicatorSprite(); - SetMainCallback2(CB2_InitTradeAnim_LinkTrade); + SetMainCallback2(CB2_LinkTrade); } } else @@ -1229,7 +1229,7 @@ static void TradeMenuCB_13(void) FreeAllWindowBuffers(); Free(sTradeMenuResourcesPtr); gMain.callback1 = NULL; - SetMainCallback2(CB2_InitTradeAnim_LinkTrade); + SetMainCallback2(CB2_LinkTrade); } } } diff --git a/src/trade_scene.c b/src/trade_scene.c index a946299b9..826c45c3b 100644 --- a/src/trade_scene.c +++ b/src/trade_scene.c @@ -773,7 +773,7 @@ static void LoadTradeMonPic(u8 whichParty, u8 action) } } -void CB2_InitTradeAnim_LinkTrade(void) +void CB2_LinkTrade(void) { switch (gMain.state) { @@ -2668,7 +2668,7 @@ static void CB2_HandleTradeEnded(void) case 8: if (IsBGMStopped() == TRUE) { - if (gWirelessCommType && gMain.savedCallback == CB2_ReturnFromLinkTrade) + if (gWirelessCommType && gMain.savedCallback == CB2_StartCreateTradeMenu) { SetLinkStandbyCallback(); } @@ -2680,7 +2680,7 @@ static void CB2_HandleTradeEnded(void) } break; case 9: - if (gWirelessCommType && gMain.savedCallback == CB2_ReturnFromLinkTrade) + if (gWirelessCommType && gMain.savedCallback == CB2_StartCreateTradeMenu) { if (IsLinkRfuTaskFinished()) { diff --git a/src/union_room.c b/src/union_room.c index 186d09707..2458e44ef 100644 --- a/src/union_room.c +++ b/src/union_room.c @@ -10,6 +10,7 @@ #include "easy_chat.h" #include "event_data.h" #include "event_object_lock.h" +#include "fieldmap.h" #include "field_control_avatar.h" #include "field_fadetransition.h" #include "field_player_avatar.h" @@ -48,641 +49,274 @@ #include "constants/trainer_card.h" #include "constants/union_room.h" +// States for Task_RunUnionRoom +enum { + UR_STATE_INIT, + UR_STATE_INIT_OBJECTS, + UR_STATE_INIT_LINK, + UR_STATE_CHECK_SELECTING_MON, + UR_STATE_MAIN, + UR_STATE_DO_SOMETHING_PROMPT, + UR_STATE_HANDLE_DO_SOMETHING_PROMPT_INPUT, + UR_STATE_DO_SOMETHING_PROMPT_2, + UR_STATE_PRINT_MSG, + UR_STATE_HANDLE_ACTIVITY_REQUEST, + UR_STATE_DECLINE_ACTIVITY_REQUEST, + UR_STATE_PLAYER_CONTACTED_YOU, + UR_STATE_RECV_CONTACT_DATA, + UR_STATE_PRINT_START_ACTIVITY_MSG, + UR_STATE_START_ACTIVITY_LINK, + UR_STATE_START_ACTIVITY_WAIT_FOR_LINK, + UR_STATE_START_ACTIVITY_FREE_UROOM, + UR_STATE_START_ACTIVITY_FADE, + UR_STATE_START_ACTIVITY, + UR_STATE_RECV_JOIN_CHAT_REQUEST, + UR_STATE_TRY_ACCEPT_CHAT_REQUEST_DELAY, + UR_STATE_TRY_ACCEPT_CHAT_REQUEST, + UR_STATE_ACCEPT_CHAT_REQUEST, + UR_STATE_WAIT_FOR_START_MENU, + UR_STATE_INTERACT_WITH_PLAYER, + UR_STATE_TRY_COMMUNICATING, + UR_STATE_PRINT_AND_EXIT, + UR_STATE_SEND_ACTIVITY_REQUEST, + UR_STATE_TRAINER_APPEARS_BUSY, + UR_STATE_WAIT_FOR_RESPONSE_TO_REQUEST, + UR_STATE_CANCEL_ACTIVITY_LINK_ERROR, + UR_STATE_SEND_TRADE_REQUST, + UR_STATE_REQUEST_DECLINED, + UR_STATE_PRINT_CONTACT_MSG, + UR_STATE_HANDLE_CONTACT_DATA, + UR_STATE_RECV_ACTIVITY_REQUEST, + UR_STATE_CANCEL_REQUEST_PRINT_MSG, + UR_STATE_CANCEL_REQUEST_RESTART_LINK, + UR_STATE_COMMUNICATING_WAIT_FOR_DATA, + UR_STATE_WAIT_FOR_CONTACT_DATA, + UR_STATE_PRINT_CARD_INFO, + UR_STATE_WAIT_FINISH_READING_CARD, + UR_STATE_INTERACT_WITH_ATTENDANT, + UR_STATE_REGISTER_PROMPT, + UR_STATE_CANCEL_REGISTRATION_PROMPT, + UR_STATE_CHECK_TRADING_BOARD, + UR_STATE_TRADING_BOARD_LOAD, + UR_STATE_REGISTER_PROMPT_HANDLE_INPUT, + UR_STATE_TRADING_BOARD_HANDLE_INPUT, + UR_STATE_TRADE_PROMPT, + UR_STATE_TRADE_SELECT_MON, + UR_STATE_TRADE_OFFER_MON, + UR_STATE_REGISTER_REQUEST_TYPE, + UR_STATE_REGISTER_SELECT_MON_FADE, + UR_STATE_REGISTER_SELECT_MON, + UR_STATE_REGISTER_COMPLETE, + UR_STATE_CANCEL_REGISTRATION, +}; + +// States for sUnionRoomTrade.state +enum { + URTRADE_STATE_NONE, + URTRADE_STATE_REGISTERING, + URTRADE_STATE_OFFERING, +}; + +// States for Task_TryBecomeLinkLeader +enum { + LL_STATE_INIT, + LL_STATE_INIT2 = 3, + LL_STATE_GET_AWAITING_PLAYERS_TEXT, + LL_STATE_PRINT_AWAITING_PLAYERS, + LL_STATE_AWAIT_PLAYERS, + LL_STATE_ACCEPT_NEW_MEMBER_PROMPT, + LL_STATE_WAIT_DISCONNECT_CHILD = 9, + LL_STATE_MEMBER_LEFT, + LL_STATE_ACCEPT_NEW_MEMBER_PROMPT_HANDLE_INPUT, + LL_STATE_UPDATE_AFTER_JOIN_REQUEST, + LL_STATE_ACCEPTED_FINAL_MEMBER, + LL_STATE_WAIT_AND_CONFIRM_MEMBERS, + LL_STATE_MEMBERS_OK_PROMPT, + LL_STATE_MEMBERS_OK_PROMPT_HANDLE_INPUT, + LL_STATE_CONFIRMED_MEMBERS, + LL_STATE_FINAL_MEMBER_CHECK, + LL_STATE_CANCEL_PROMPT, + LL_STATE_CANCEL_PROMPT_HANDLE_INPUT, + LL_STATE_SHUTDOWN_AND_RETRY, + LL_STATE_RETRY, + LL_STATE_SHUTDOWN_AND_FAIL, + LL_STATE_FAILED, + LL_STATE_TRY_START_ACTIVITY = 26, + LL_STATE_MEMBER_DISCONNECTED = 29, + LL_STATE_CANCEL_WITH_MSG +}; + +// States for Task_TryJoinLinkGroup +enum { + LG_STATE_INIT, + LG_STATE_CHOOSE_LEADER_MSG, + LG_STATE_INIT_WINDOWS, + LG_STATE_CHOOSE_LEADER_HANDLE_INPUT, + LG_STATE_ASK_JOIN_GROUP = 5, + LG_STATE_MAIN, + LG_STATE_ASK_LEAVE_GROUP, + LG_STATE_ASK_LEAVE_GROUP_HANDLE_INPUT, + LG_STATE_WAIT_LEAVE_GROUP, + LG_STATE_CANCEL_CHOOSE_LEADER, + LG_STATE_CANCELED, + LG_STATE_RFU_ERROR, + LG_STATE_RFU_ERROR_SHUTDOWN, + LG_STATE_DISCONNECTED, + LG_STATE_RETRY_CONNECTION, + LG_STATE_TRADE_NOT_READY = 18, + LG_STATE_TRADE_NOT_READY_RETRY, + LG_STATE_READY_START_ACTIVITY, + LG_STATE_START_ACTIVITY, + 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] = {}; static EWRAM_DATA u8 sPlayerCurrActivity = 0; static EWRAM_DATA u8 sPlayerActivityGroupSize = 0; -static EWRAM_DATA union UnkUnion_Main sUnionRoomMain = {}; -static EWRAM_DATA u32 sUnref_203B060 = 0; -EWRAM_DATA struct RfuGameCompatibilityData gPartnerTgtGnameSub = {}; +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 RfuGameCompatibilityData gRfuPartnerCompatibilityData = {}; EWRAM_DATA u16 gUnionRoomOfferedSpecies = SPECIES_NONE; EWRAM_DATA u8 gUnionRoomRequestedMonType = TYPE_NORMAL; static EWRAM_DATA struct UnionRoomTrade sUnionRoomTrade = {}; -static struct UnkStruct_Leader * sLeader; -static struct UnkStruct_Group * sGroup; -static struct UnkStruct_URoom * sURoom; +static struct WirelessLink_Leader * sLeader; +static struct WirelessLink_Group * sGroup; +static struct WirelessLink_URoom * sURoom; -static void Task_TryBecomeLinkLeader(u8 taskId); -static void Leader_DestroyResources(struct UnkStruct_Leader * leader); -static bool8 Leader_SetStateIfMemberListChanged(struct UnkStruct_Leader * leader, u32 state1, u32 state2); -static void ItemPrintFunc_PossibleGroupMembers(u8 windowId, u32 itemId, u8 y); -static u8 LeaderUpdateGroupMembership(struct UnkStruct_Main0 * main0); -static u8 UnionRoomLeaderField0CompactionAndCount(struct UnkStruct_Main0 * main0); -static void Task_TryJoinLinkGroup(u8 taskId); -static u32 IsTryingToTradeWithHoennTooSoon(struct UnkStruct_Group * group, s32 id); -static void AskToJoinRfuGroup(struct UnkStruct_Group * group, s32 id); -static void Task_ListenToWireless(u8 taskId); -static void ListMenuItemPrintFunc_UnionRoomGroups(u8 windowId, u32 itemId, u8 y); +static void Task_TryBecomeLinkLeader(u8); +static void Leader_DestroyResources(struct WirelessLink_Leader *); +static bool8 Leader_SetStateIfMemberListChanged(struct WirelessLink_Leader *, u32, u32); +static void ItemPrintFunc_PossibleGroupMembers(u8, u32, u8); +static u8 LeaderUpdateGroupMembership(struct RfuPlayerList *); +static u8 LeaderPrunePlayerList(struct RfuPlayerList *); +static void Task_TryJoinLinkGroup(u8); +static u32 IsTryingToTradeAcrossVersionTooSoon(struct WirelessLink_Group *, s32); +static void AskToJoinRfuGroup(struct WirelessLink_Group *, s32); +static void Task_ListenToWireless(u8); +static void ListMenuItemPrintFunc_UnionRoomGroups(u8, u32, u8); static u8 GetNewLeaderCandidate(void); static void CreateTask_RunScriptAndFadeToActivity(void); static void CreateTask_StartActivity(void); -static void Task_MEvent_Leader(u8 taskId); -static void Task_CardOrNewsWithFriend(u8 taskId); -static void Task_CardOrNewsOverWireless(u8 taskId); -static void Task_RunUnionRoom(u8 taskId); -static u16 ReadAsU16(const u8 *data); -static void ReceiveUnionRoomActivityPacket(struct UnkStruct_URoom * uRoom); -static bool32 UnionRoom_HandleContactFromOtherPlayer(struct UnkStruct_URoom * uRoom); -static void Task_InitUnionRoom(u8 taskId); +static void Task_SendMysteryGift(u8); +static void Task_CardOrNewsWithFriend(u8); +static void Task_CardOrNewsOverWireless(u8); +static void Task_RunUnionRoom(u8); +static u16 ReadAsU16(const u8 *); +static void ReceiveUnionRoomActivityPacket(struct WirelessLink_URoom *); +static bool32 HandleContactFromOtherPlayer(struct WirelessLink_URoom *); +static void Task_InitUnionRoom(u8); static u8 HandlePlayerListUpdate(void); -static u8 CreateTask_SearchForChildOrParent(struct UnkStruct_Main4 * main4, struct UnkStruct_Main4 * arg1, u32 arg2); -static bool32 GetGnameWonderFlagByLinkGroup(struct RfuGameData * gname, s16 linkGroup); -static u8 CreateTask_ListenForPartnersWithCompatibleSerialNos(struct UnkStruct_Main4 * main4, u32 linkGroup); -static u8 CreateTask_ListenForPartnersWithSerial7F7D(struct UnkStruct_Main4 * main4, u32 linkGroup); -static bool32 UR_PrintFieldMessage(const u8 * str); -static bool32 UR_RunTextPrinters_CheckPrinter0Active(void); -static bool8 PrintOnTextbox(u8 *textState, const u8 *str); -static s8 UnionRoomHandleYesNo(u8 *state_p, bool32 no_draw); -static s32 ListMenuHandler_AllItemsAvailable(u8 *state_p, u8 *win_id_p, u8 *list_menu_id_p, const struct WindowTemplate * winTemplate, const struct ListMenuTemplate * menuTemplate); -static s32 TradeBoardMenuHandler(u8 *state_p, u8 *win_id_p, u8 *list_menu_id_p, u8 *trade_board_win_id_p, const struct WindowTemplate * winTemplate, const struct ListMenuTemplate * menuTemplate, struct UnkStruct_Main0 * traders); -static void UR_BlankBg0(void); -static void JoinGroup_BlankBg0AndEnableScriptContexts(void); -static void UR_AddTextPrinterParameterized(u8 windowId, u8 fontId, const u8 *str, u8 x, u8 y, u8 colorIdx); -static void BlankUnkStruct_x20Array(struct UnkStruct_x20 * x20, u8 count); -static void BlankUnkStruct_x1CArray(struct UnkStruct_x1C * x1C, u8 count); -static bool8 AreGnameUnameDifferent(struct UnionGnameUnamePair * arg0, const struct UnionGnameUnamePair * arg1); -static bool32 AreUnionRoomPlayerGnamesDifferent(struct UnionGnameUnamePair * arg0, struct UnionGnameUnamePair * arg1); -static u32 Findx20Inx1CArray(struct UnkStruct_x20 * x20, struct UnkStruct_x1C * x1Carr); -static u8 Appendx1Ctox20(struct UnkStruct_x20 * x20arr, struct UnkStruct_x1C * x1C, u8 count); -static void PrintUnionRoomGroupOnWindow(u8 windowId, u8 x, u8 y, struct UnkStruct_x20 * group, u8 colorIdx, u8 id); -static void PrintGroupMemberCandidateOnWindowWithColor(u8 windowId, u8 x, u8 y, struct UnkStruct_x20 * group, u8 colorIdx, u8 id); -static bool32 PlayerIsTalkingToUnionRoomAide(void); -static u32 GetResponseIdx_InviteToURoomActivity(s32 activity); -static u32 ConvPartnerUnameAndGetWhetherMetAlready(struct UnkStruct_x20 * unkX20); -static s32 UnionRoomGetPlayerInteractionResponse(struct UnkStruct_Main0 * main0, u8 overrideGender, u8 playerIdx, u32 playerGender); -static void nullsub_92(u8 windowId, u32 itemId, u8 y); -static void TradeBoardListMenuItemPrintFunc(u8 windowId, u32 itemId, u8 y); -static s32 GetIndexOfNthTradeBoardOffer(struct UnkStruct_x20 * x20, s32 n); -static s32 GetUnionRoomPlayerGender(s32 playerIdx, struct UnkStruct_Main0 * main0); -static s32 IsRequestedTypeAndSpeciesInPlayerParty(u32 type, u32 species); -static void GetURoomActivityRejectMsg(u8 *dst, s32 activity, u32 playerGender); -static void GetURoomActivityStartMsg(u8 *dst, u8 activity); -static s32 GetChatLeaderActionRequestMessage(u8 *dst, u32 gender, u16 *activity_p, struct UnkStruct_URoom * uroom); -static bool32 PollPartnerYesNoResponse(struct UnkStruct_URoom * uroom); +static u8 CreateTask_SearchForChildOrParent(struct RfuIncomingPlayerList *, struct RfuIncomingPlayerList *, u32); +static bool32 HasWonderCardOrNewsByLinkGroup(struct RfuGameData *, s16); +static u8 CreateTask_ListenForCompatiblePartners(struct RfuIncomingPlayerList *, u32); +static u8 CreateTask_ListenForWonderDistributor(struct RfuIncomingPlayerList *, u32); +static bool32 UR_PrintFieldMessage(const u8 *); +static bool32 UR_RunTextPrinters(void); +static bool8 PrintOnTextbox(u8 *, const u8 *); +static s8 UnionRoomHandleYesNo(u8 *, 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 RfuPlayerList *); +static void UR_ClearBg0(void); +static void JoinGroup_EnableScriptContexts(void); +static void PrintUnionRoomText(u8, u8, const u8 *, u8, u8, u8); +static void ClearRfuPlayerList(struct RfuPlayer *, u8); +static void ClearIncomingPlayerList(struct RfuIncomingPlayer *, u8); +static bool8 ArePlayersDifferent(struct RfuPlayerData *, const struct RfuPlayerData *); +static bool32 ArePlayerDataDifferent(struct RfuPlayerData *, struct RfuPlayerData *); +static u32 GetNewIncomingPlayerId(struct RfuPlayer *, struct RfuIncomingPlayer *); +static u8 TryAddIncomingPlayerToList(struct RfuPlayer *, struct RfuIncomingPlayer *, u8); +static void PrintGroupMemberOnWindow(u8, u8, u8, struct RfuPlayer *, u8, u8); +static void PrintGroupCandidateOnWindow(u8, u8, u8, struct RfuPlayer *, u8, u8); +static bool32 IsPlayerFacingTradingBoard(void); +static u32 GetResponseIdx_InviteToURoomActivity(s32); +static u32 ConvPartnerUnameAndGetWhetherMetAlready(struct RfuPlayer *); +static s32 UnionRoomGetPlayerInteractionResponse(struct RfuPlayerList *, u8, u8, u32); +static void ItemPrintFunc_Unused(u8, u32, u8); +static void TradeBoardListMenuItemPrintFunc(u8, u32, u8); +static s32 GetIndexOfNthTradeBoardOffer(struct RfuPlayer *, s32); +static s32 GetUnionRoomPlayerGender(s32, struct RfuPlayerList *); +static s32 IsRequestedTradeInPlayerParty(u32, u32); +static void GetURoomActivityRejectMsg(u8 *, s32, u32); +static void GetURoomActivityStartMsg(u8 *, u8); +static s32 GetChatLeaderActionRequestMessage(u8 *, u32, u16 *, struct WirelessLink_URoom *); +static bool32 PollPartnerYesNoResponse(struct WirelessLink_URoom *); static bool32 HasAtLeastTwoMonsOfLevel30OrLower(void); -static void ResetUnionRoomTrade(struct UnionRoomTrade * trade); -static bool32 RegisterTradeMonAndGetIsEgg(u32 monId, struct UnionRoomTrade * trade); -static void RegisterTradeMon(u32 monId, struct UnionRoomTrade * trade); -static u32 GetPartyPositionOfRegisteredMon(struct UnionRoomTrade * trade, u8 mpId); -static void HandleCancelTrade(bool32 unlockObjs); -static void UR_EnableScriptContext2AndFreezeObjectEvents(void); -static u8 GetSinglePartnerSpriteGenderParam(s32 linkPlayer); -static u8 GetActivePartnerSpriteGenderParam(struct UnkStruct_URoom * uroom); -static void ViewURoomPartnerTrainerCard(u8 *dest, struct UnkStruct_URoom * uRoom, bool8 parent_child); +static void ResetUnionRoomTrade(struct UnionRoomTrade *); +static bool32 RegisterTradeMonAndGetIsEgg(u32, struct UnionRoomTrade *); +static void RegisterTradeMon(u32, struct UnionRoomTrade *); +static u32 GetPartyPositionOfRegisteredMon(struct UnionRoomTrade *, u8); +static void HandleCancelActivity(bool32); +static void StartScriptInteraction(void); +static u8 GetLinkPlayerInfoFlags(s32); +static u8 GetActivePartnersInfo(struct WirelessLink_URoom *); +static void ViewURoomPartnerTrainerCard(u8 *, struct WirelessLink_URoom *, bool8); -#define _8456CD8(a, b) ((a) | ((b) << 8)) - -static const u8 *const sUnionRoomActivityStringPtrs[] = { - gText_UR_EmptyString, - gText_UR_SingleBattle, - gText_UR_DoubleBattle, - gText_UR_MultiBattle, - gText_UR_PokemonTrades, - gText_UR_Chat, - gText_UR_WonderCards, - gText_UR_WonderNews, - gText_UR_Cards, - gText_UR_PokemonJump, - gText_UR_BerryCrush, - gText_UR_BerryPicking, - gText_UR_Search, - gText_UR_SpinTrade, - gText_UR_ItemTrade, - gText_UR_EmptyString, - gText_UR_EmptyString, - gText_UR_EmptyString, - gText_UR_EmptyString, - gText_UR_EmptyString, - gText_UR_EmptyString, - gText_UR_WonderCards, - gText_UR_WonderNews -}; - -static const struct WindowTemplate sWindowTemplate_BButtonCancel = { - .bg = 0, - .tilemapLeft = 0, - .tilemapTop = 0, - .width = 30, - .height = 2, - .paletteNum = 0xF, - .baseBlock = 0x008 -}; - -static const u32 sLinkGroupToActivityAndCapacity[] = { - [LINK_GROUP_SINGLE_BATTLE] = _8456CD8(ACTIVITY_BATTLE, 2), - [LINK_GROUP_DOUBLE_BATTLE] = _8456CD8(ACTIVITY_DBLBATTLE, 2), - [LINK_GROUP_MULTI_BATTLE] = _8456CD8(ACTIVITY_MLTBATTLE, 4), - [LINK_GROUP_TRADE] = _8456CD8(ACTIVITY_TRADE, 2), - [LINK_GROUP_POKEMON_JUMP] = _8456CD8(ACTIVITY_PJUMP, 5 | 0x20), - [LINK_GROUP_BERRY_CRUSH] = _8456CD8(ACTIVITY_BCRUSH, 5 | 0x20), - [LINK_GROUP_BERRY_PICKING] = _8456CD8(ACTIVITY_BPICK, 5 | 0x30), - [LINK_GROUP_WONDER_CARD] = _8456CD8(ACTIVITY_SPINTRADE, 5 | 0x30), - [LINK_GROUP_WONDER_NEWS] = _8456CD8(ACTIVITY_ITEMTRADE, 5 | 0x30) -}; - -static const struct WindowTemplate sWindowTemplate_List_PossibleGroupMembers = { - .bg = 0, - .tilemapLeft = 1, - .tilemapTop = 3, - .width = 13, - .height = 10, - .paletteNum = 15, - .baseBlock = 0x044 -}; - -static const struct WindowTemplate sWindowTemplate_NumPlayerMode = { - .bg = 0, - .tilemapLeft = 16, - .tilemapTop = 3, - .width = 7, - .height = 4, - .paletteNum = 15, - .baseBlock = 0x0C6 -}; - -const struct ListMenuItem sListMenuItems_PossibleGroupMembers[] = { - {gText_UR_EmptyString, 0}, - {gText_UR_EmptyString, 1}, - {gText_UR_EmptyString, 2}, - {gText_UR_EmptyString, 3}, - {gText_UR_EmptyString, 4} -}; - -static const struct ListMenuTemplate sListMenuTemplate_PossibleGroupMembers = { - .items = sListMenuItems_PossibleGroupMembers, - .moveCursorFunc = NULL, - .itemPrintFunc = ItemPrintFunc_PossibleGroupMembers, - .totalItems = 5, - .maxShowed = 5, - .windowId = 0, - .header_X = 0, - .item_X = 1, - .cursor_X = 0, - .upText_Y = 0, - .cursorPal = 2, - .fillValue = 1, - .cursorShadowPal = 3, - .lettersSpacing = 0, - .itemVerticalPadding = 2, - .scrollMultiple = LIST_NO_MULTIPLE_SCROLL, - .fontId = FONT_2, - .cursorKind = 1 -}; - -static const struct WindowTemplate sWindowTemplate_MysteryGiftList = { - .bg = 0, - .tilemapLeft = 1, - .tilemapTop = 3, - .width = 17, - .height = 10, - .paletteNum = 15, - .baseBlock = 0x044 -}; - -static const struct WindowTemplate sWindowTemplate_MysteryGiftPlayerNameAndId = { - .bg = 0, - .tilemapLeft = 20, - .tilemapTop = 3, - .width = 7, - .height = 4, - .paletteNum = 15, - .baseBlock = 0x0EE -}; - -static const struct ListMenuItem sListMenuItems_UnionRoomGroups[] = { - {gText_UR_EmptyString, 0}, - {gText_UR_EmptyString, 1}, - {gText_UR_EmptyString, 2}, - {gText_UR_EmptyString, 3}, - {gText_UR_EmptyString, 4}, - {gText_UR_EmptyString, 5}, - {gText_UR_EmptyString, 6}, - {gText_UR_EmptyString, 7}, - {gText_UR_EmptyString, 8}, - {gText_UR_EmptyString, 9}, - {gText_UR_EmptyString, 10}, - {gText_UR_EmptyString, 11}, - {gText_UR_EmptyString, 12}, - {gText_UR_EmptyString, 13}, - {gText_UR_EmptyString, 14}, - {gText_UR_EmptyString, 15} -}; - -static const struct ListMenuTemplate sListMenuTemplate_UnionRoomGroups = { - .items = sListMenuItems_UnionRoomGroups, - .moveCursorFunc = ListMenuDefaultCursorMoveFunc, - .itemPrintFunc = ListMenuItemPrintFunc_UnionRoomGroups, - .totalItems = 16, - .maxShowed = 5, - .windowId = 0, - .header_X = 0, - .item_X = 8, - .cursor_X = 0, - .upText_Y = 0, - .cursorPal = 2, - .fillValue = 1, - .cursorShadowPal = 3, - .lettersSpacing = 0, - .itemVerticalPadding = 2, - .scrollMultiple = LIST_MULTIPLE_SCROLL_DPAD, - .fontId = FONT_2, - .cursorKind = 0 -}; - -static const struct WindowTemplate sWindowTemplate_InviteToActivity = { - .bg = 0, - .tilemapLeft = 20, - .tilemapTop = 6, - .width = 8, - .height = 7, - .paletteNum = 15, - .baseBlock = 0x001 -}; - -static const struct ListMenuItem sListMenuItems_InviteToActivity[] = { - {gText_UR_Greetings, _8456CD8( ACTIVITY_CARD, 2)}, - {gText_UR_Battle, _8456CD8(ACTIVITY_BATTLE | IN_UNION_ROOM, 2)}, - {gText_UR_Chat2, _8456CD8(ACTIVITY_CHAT | IN_UNION_ROOM, 2)}, - {gText_UR_Exit, _8456CD8(ACTIVITY_NONE | IN_UNION_ROOM, 0)} -}; - -static const struct ListMenuTemplate sListMenuTemplate_InviteToActivity = { - .items = sListMenuItems_InviteToActivity, - .moveCursorFunc = ListMenuDefaultCursorMoveFunc, - .itemPrintFunc = NULL, - .totalItems = 4, - .maxShowed = 4, - .windowId = 0, - .header_X = 0, - .item_X = 8, - .cursor_X = 0, - .upText_Y = 0, - .cursorPal = 2, - .fillValue = 1, - .cursorShadowPal = 3, - .lettersSpacing = 1, - .itemVerticalPadding = 0, - .scrollMultiple = LIST_NO_MULTIPLE_SCROLL, - .fontId = FONT_2, - .cursorKind = 0 -}; - -static const struct WindowTemplate sWindowTemplate_TradeBoardRegisterInfoExit = { - .bg = 0, - .tilemapLeft = 18, - .tilemapTop = 8, - .width = 11, - .height = 5, - .paletteNum = 15, - .baseBlock = 0x001 -}; - -static const struct ListMenuItem gUnknown_8456E3C[] = { - {gText_Register, 1}, - {gText_UR_Info, 2}, - {gText_UR_Exit, 3} -}; - -static const struct ListMenuTemplate sListMenuTemplate_TradeBoardRegisterInfoExit = { - .items = gUnknown_8456E3C, - .moveCursorFunc = ListMenuDefaultCursorMoveFunc, - .itemPrintFunc = NULL, - .totalItems = 3, - .maxShowed = 3, - .windowId = 0, - .header_X = 0, - .item_X = 8, - .cursor_X = 0, - .upText_Y = 0, - .cursorPal = 2, - .fillValue = 1, - .cursorShadowPal = 3, - .lettersSpacing = 1, - .itemVerticalPadding = 0, - .scrollMultiple = LIST_NO_MULTIPLE_SCROLL, - .fontId = FONT_2, - .cursorKind = 0 -}; - -static const struct WindowTemplate sWindowTemplate_TypeNames = { - .bg = 0, - .tilemapLeft = 20, - .tilemapTop = 2, - .width = 9, - .height = 11, - .paletteNum = 15, - .baseBlock = 0x001 -}; - -static const struct ListMenuItem sListMenuItems_TypeNames[] = { - {gTypeNames[TYPE_NORMAL], TYPE_NORMAL}, - {gTypeNames[TYPE_FIRE], TYPE_FIRE}, - {gTypeNames[TYPE_WATER], TYPE_WATER}, - {gTypeNames[TYPE_ELECTRIC], TYPE_ELECTRIC}, - {gTypeNames[TYPE_GRASS], TYPE_GRASS}, - {gTypeNames[TYPE_ICE], TYPE_ICE}, - {gTypeNames[TYPE_GROUND], TYPE_GROUND}, - {gTypeNames[TYPE_ROCK], TYPE_ROCK}, - {gTypeNames[TYPE_FLYING], TYPE_FLYING}, - {gTypeNames[TYPE_PSYCHIC], TYPE_PSYCHIC}, - {gTypeNames[TYPE_FIGHTING], TYPE_FIGHTING}, - {gTypeNames[TYPE_POISON], TYPE_POISON}, - {gTypeNames[TYPE_BUG], TYPE_BUG}, - {gTypeNames[TYPE_GHOST], TYPE_GHOST}, - {gTypeNames[TYPE_DRAGON], TYPE_DRAGON}, - {gTypeNames[TYPE_STEEL], TYPE_STEEL}, - {gTypeNames[TYPE_DARK], TYPE_DARK}, - {gText_UR_Exit, NUMBER_OF_MON_TYPES} -}; - -static const struct ListMenuTemplate sListMenuTemplate_TypeNames = { - .items = sListMenuItems_TypeNames, - .moveCursorFunc = ListMenuDefaultCursorMoveFunc, - .itemPrintFunc = NULL, - .totalItems = NUMBER_OF_MON_TYPES, - .maxShowed = 6, - .windowId = 0, - .header_X = 0, - .item_X = 8, - .cursor_X = 0, - .upText_Y = 2, - .cursorPal = 2, - .fillValue = 1, - .cursorShadowPal = 3, - .lettersSpacing = 1, - .itemVerticalPadding = 0, - .scrollMultiple = LIST_NO_MULTIPLE_SCROLL, - .fontId = FONT_2, - .cursorKind = 0 -}; - -static const struct WindowTemplate sTradeBoardWindowTemplate = { - .bg = 0, - .tilemapLeft = 1, - .tilemapTop = 1, - .width = 28, - .height = 2, - .paletteNum = 13, - .baseBlock = 0x001 -}; - -static const struct WindowTemplate gUnknown_8456F24 = { - .bg = 0, - .tilemapLeft = 1, - .tilemapTop = 5, - .width = 28, - .height = 10, - .paletteNum = 13, - .baseBlock = 0x039 -}; - -static const struct ListMenuItem sTradeBoardListMenuItems[] = { - {gText_UR_EmptyString, -3}, - {gText_UR_EmptyString, 0}, - {gText_UR_EmptyString, 1}, - {gText_UR_EmptyString, 2}, - {gText_UR_EmptyString, 3}, - {gText_UR_EmptyString, 4}, - {gText_UR_EmptyString, 5}, - {gText_UR_EmptyString, 6}, - {gText_UR_EmptyString, 7}, - {gText_UR_Exit2, 8} -}; - -static const struct ListMenuTemplate sTradeBoardListMenuTemplate = { - .items = sTradeBoardListMenuItems, - .moveCursorFunc = ListMenuDefaultCursorMoveFunc, - .itemPrintFunc = TradeBoardListMenuItemPrintFunc, - .totalItems = 10, - .maxShowed = 5, - .windowId = 0, - .header_X = 0, - .item_X = 12, - .cursor_X = 0, - .upText_Y = 2, - .cursorPal = 14, - .fillValue = 15, - .cursorShadowPal = 13, - .lettersSpacing = 1, - .itemVerticalPadding = 1, - .scrollMultiple = LIST_NO_MULTIPLE_SCROLL, - .fontId = FONT_2, - .cursorKind = 0 -}; - -static const struct WindowTemplate gUnknown_8456F94 = { - .bg = 0, - .tilemapLeft = 1, - .tilemapTop = 5, - .width = 28, - .height = 10, - .paletteNum = 13, - .baseBlock = 0x039 -}; - -static const struct ListMenuItem gUnknown_8456F9C[] = { - {gText_UR_EmptyString, 0}, - {gText_UR_EmptyString, 1}, - {gText_UR_EmptyString, 2}, - {gText_UR_EmptyString, 3}, - {gText_UR_EmptyString, 4}, - {gText_UR_EmptyString, 5}, - {gText_UR_EmptyString, 6}, - {gText_UR_EmptyString, 7}, - {gText_UR_EmptyString, 8}, - {gText_UR_EmptyString, 9}, - {gText_UR_EmptyString, 10}, - {gText_UR_EmptyString, 11}, - {gText_UR_EmptyString, 12}, - {gText_UR_EmptyString, 13}, - {gText_UR_EmptyString, 14}, - {gText_UR_EmptyString, 15} -}; - -static const struct ListMenuTemplate gUnknown_845701C = { - .items = gUnknown_8456F9C, - .moveCursorFunc = ListMenuDefaultCursorMoveFunc, - .itemPrintFunc = nullsub_92, - .totalItems = 16, - .maxShowed = 4, - .windowId = 0, - .header_X = 0, - .item_X = 8, - .cursor_X = 1, - .upText_Y = 0, - .cursorPal = 2, - .fillValue = 1, - .cursorShadowPal = 3, - .lettersSpacing = 1, - .itemVerticalPadding = 0, - .scrollMultiple = LIST_MULTIPLE_SCROLL_DPAD, - .fontId = FONT_2, - .cursorKind = 0 -}; - -static const struct UnionGnameUnamePair sUnionGnameUnamePair_Dummy = {}; - -// starts at gUnknown_082F0474 in pokeemerald, union link groups - -ALIGNED(4) static const u8 gUnknown_845704C[] = { - ACTIVITY_BATTLE, - 0xFF -}; - -ALIGNED(4) static const u8 gUnknown_8457050[] = { - ACTIVITY_DBLBATTLE, - 0xFF -}; - -ALIGNED(4) static const u8 gUnknown_8457054[] = { - ACTIVITY_MLTBATTLE, - 0xFF -}; - -ALIGNED(4) static const u8 gUnknown_8457058[] = { - ACTIVITY_TRADE, - 0xFF -}; - -ALIGNED(4) static const u8 gUnknown_845705C[] = { - ACTIVITY_PJUMP, - 0xFF -}; - -ALIGNED(4) static const u8 gUnknown_8457060[] = { - ACTIVITY_BCRUSH, - 0xFF -}; - -ALIGNED(4) static const u8 gUnknown_8457064[] = { - ACTIVITY_BPICK, - 0xFF -}; - -ALIGNED(4) static const u8 gUnknown_8457068[] = { - ACTIVITY_WCARD2, - 0xFF -}; - -ALIGNED(4) static const u8 gUnknown_845706C[] = { - ACTIVITY_WNEWS2, - 0xFF -}; - -ALIGNED(4) static const u8 gUnknown_8457070[] = { - ACTIVITY_NONE | IN_UNION_ROOM, - ACTIVITY_BATTLE | IN_UNION_ROOM, - ACTIVITY_TRADE | IN_UNION_ROOM, - ACTIVITY_CHAT | IN_UNION_ROOM, - ACTIVITY_CARD | IN_UNION_ROOM, - ACTIVITY_ACCEPT | IN_UNION_ROOM, - ACTIVITY_DECLINE | IN_UNION_ROOM, - ACTIVITY_NPCTALK | IN_UNION_ROOM, - ACTIVITY_PLYRTALK | IN_UNION_ROOM, - 0xFF -}; - -ALIGNED(4) static const u8 gUnknown_845707C[] = { - ACTIVITY_SEARCH, - 0xFF -}; - -ALIGNED(4) static const u8 gUnknown_8457080[] = { - ACTIVITY_BATTLE, - ACTIVITY_DBLBATTLE, - ACTIVITY_MLTBATTLE, - ACTIVITY_TRADE, - ACTIVITY_PJUMP, - ACTIVITY_BCRUSH, - ACTIVITY_BPICK, - ACTIVITY_WCARD2, - ACTIVITY_WNEWS2, - ACTIVITY_SPINTRADE, - 0xFF -}; - -ALIGNED(4) static const u8 gUnknown_845708C[] = { - ACTIVITY_BATTLE, - ACTIVITY_DBLBATTLE, - ACTIVITY_MLTBATTLE, - ACTIVITY_TRADE, - ACTIVITY_BCRUSH, - 0xFF -}; - -static const u8 *const sAcceptedActivityIds[] = { - [LINK_GROUP_SINGLE_BATTLE] = gUnknown_845704C, - [LINK_GROUP_DOUBLE_BATTLE] = gUnknown_8457050, - [LINK_GROUP_MULTI_BATTLE] = gUnknown_8457054, - [LINK_GROUP_TRADE] = gUnknown_8457058, - [LINK_GROUP_POKEMON_JUMP] = gUnknown_845705C, - [LINK_GROUP_BERRY_CRUSH] = gUnknown_8457060, - [LINK_GROUP_BERRY_PICKING] = gUnknown_8457064, - [LINK_GROUP_WONDER_CARD] = gUnknown_8457068, - [LINK_GROUP_WONDER_NEWS] = gUnknown_845706C, - [9] = gUnknown_8457070, - [10] = gUnknown_845707C, - [11] = gUnknown_8457080, - [12] = gUnknown_845708C -}; - -static const u8 sLinkGroupToURoomActivity[] = { - [LINK_GROUP_SINGLE_BATTLE] = ACTIVITY_BATTLE, - [LINK_GROUP_DOUBLE_BATTLE] = ACTIVITY_DBLBATTLE, - [LINK_GROUP_MULTI_BATTLE] = ACTIVITY_MLTBATTLE, - [LINK_GROUP_TRADE] = ACTIVITY_TRADE, - [LINK_GROUP_POKEMON_JUMP] = ACTIVITY_PJUMP, - [LINK_GROUP_BERRY_CRUSH] = ACTIVITY_BCRUSH, - [LINK_GROUP_BERRY_PICKING] = ACTIVITY_BPICK, - [LINK_GROUP_WONDER_CARD] = ACTIVITY_WCARD2, - [LINK_GROUP_WONDER_NEWS] = ACTIVITY_WNEWS2 -}; - -static const u8 sUnref_84570D1[] = _("{DYNAMIC 00}·{DYNAMIC 01}"); - -#undef _8456CD8 +#include "data/union_room.h" // These are functions in Emerald but inlined in FireRed -#define IntlConvPartnerUname7(dest, arg1) ({ \ - StringCopy_PlayerName(dest, (arg1).gname_uname.uname); \ - ConvertInternationalString(dest, (arg1).gname_uname.gname.compatibility.language); \ +#define CopyAndTranslatePlayerName(dest, player) ({ \ + StringCopy_PlayerName(dest, (player).rfu.name); \ + ConvertInternationalString(dest, (player).rfu.data.compatibility.language); \ }) -#define IntlConvPartnerUname(dest, arg1) ({ \ - StringCopy(dest, (arg1).gname_uname.uname); \ - ConvertInternationalString(dest, (arg1).gname_uname.gname.compatibility.language); \ +#define CopyAndTranslatePlayerName2(dest, player) ({ \ + StringCopy(dest, (player).rfu.name); \ + ConvertInternationalString(dest, (player).rfu.data.compatibility.language); \ }) #define CopyTrainerCardData(dest, src, _version) ({ \ - (dest) = *((struct TrainerCard * )(src)); \ - (dest).version = _version; \ + (dest) = *((struct TrainerCard * )(src)); \ + (dest).version = _version; \ }) #define GetStringRightAlignXOffset(_fontId, _string, _maxWidth) ({ \ - u16 strWidth = GetStringWidth(_fontId, _string, 0); \ - _maxWidth - strWidth; \ + u16 strWidth = GetStringWidth(_fontId, _string, 0); \ + _maxWidth - strWidth; \ }) -// capacityCode is a 2-nybble code -// Bits 0-3: Capacity -// Bits 4-7: Min required (if 0, must have exactly Capacity players -static void PrintNumPlayersWaitingForMsg(u8 windowId, u8 capacityCode, u8 count) +static void PrintNumPlayersWaitingForMsg(u8 windowId, u8 capacityCode, u8 stringId) { FillWindowPixelBuffer(windowId, PIXEL_FILL(1)); switch (capacityCode << 8) { - case 0x200: - UR_AddTextPrinterParameterized(windowId, 2, gTexts_UR_PlayersNeededOrMode[0][count - 1], 0, 2, UR_COLOR_DKE_WHT_LTE); + case LINK_GROUP_CAPACITY(0, 2): + PrintUnionRoomText(windowId, FONT_2, gTexts_UR_PlayersNeededOrMode[0][stringId - 1], 0, 2, UR_COLOR_DEFAULT); break; - case 0x400: - UR_AddTextPrinterParameterized(windowId, 2, gTexts_UR_PlayersNeededOrMode[1][count - 1], 0, 2, UR_COLOR_DKE_WHT_LTE); + case LINK_GROUP_CAPACITY(0, 4): + PrintUnionRoomText(windowId, FONT_2, gTexts_UR_PlayersNeededOrMode[1][stringId - 1], 0, 2, UR_COLOR_DEFAULT); break; - case 0x2500: - UR_AddTextPrinterParameterized(windowId, 2, gTexts_UR_PlayersNeededOrMode[2][count - 1], 0, 2, UR_COLOR_DKE_WHT_LTE); + case LINK_GROUP_CAPACITY(2, 5): + PrintUnionRoomText(windowId, FONT_2, gTexts_UR_PlayersNeededOrMode[2][stringId - 1], 0, 2, UR_COLOR_DEFAULT); break; - case 0x3500: - UR_AddTextPrinterParameterized(windowId, 2, gTexts_UR_PlayersNeededOrMode[3][count - 1], 0, 2, UR_COLOR_DKE_WHT_LTE); + case LINK_GROUP_CAPACITY(3, 5): + PrintUnionRoomText(windowId, FONT_2, gTexts_UR_PlayersNeededOrMode[3][stringId - 1], 0, 2, UR_COLOR_DEFAULT); break; } @@ -694,28 +328,33 @@ static void PrintPlayerNameAndIdOnWindow(u8 windowId) u8 text[12]; u8 text2[12]; - UR_AddTextPrinterParameterized(windowId, 2, gSaveBlock2Ptr->playerName, 0, 2, UR_COLOR_DKE_WHT_LTE); + PrintUnionRoomText(windowId, FONT_2, gSaveBlock2Ptr->playerName, 0, 2, UR_COLOR_DEFAULT); StringCopy(text2, gText_UR_ID); ConvertIntToDecimalStringN(text, ReadAsU16(gSaveBlock2Ptr->playerTrainerId), STR_CONV_MODE_LEADING_ZEROS, 5); StringAppend(text2, text); - UR_AddTextPrinterParameterized(windowId, 0, text2, 0, 0x10, UR_COLOR_DKE_WHT_LTE); + PrintUnionRoomText(windowId, FONT_0, text2, 0, 16, UR_COLOR_DEFAULT); } -static void StringExpandPlaceholders_AwaitingCommFromAnother(u8 *dst, u8 caseId) +static void GetAwaitingCommunicationText(u8 *dst, u8 caseId) { switch (caseId) { - case ACTIVITY_BATTLE: - case ACTIVITY_DBLBATTLE: - case ACTIVITY_MLTBATTLE: + case ACTIVITY_BATTLE_SINGLE: + case ACTIVITY_BATTLE_DOUBLE: + case ACTIVITY_BATTLE_MULTI: case ACTIVITY_TRADE: - case ACTIVITY_PJUMP: - case ACTIVITY_BCRUSH: - case ACTIVITY_BPICK: - case ACTIVITY_WCARD2: - case ACTIVITY_WNEWS2: - // UB: argument *dst isn't used, instead it always prints to gStringVar4 + case ACTIVITY_POKEMON_JUMP: + case ACTIVITY_BERRY_CRUSH: + case ACTIVITY_BERRY_PICK: + case ACTIVITY_WONDER_CARD: + case ACTIVITY_WONDER_NEWS: + // BUG: argument *dst isn't used, instead it always prints to gStringVar4 + // not an issue in practice since Gamefreak never used any other arguments here besides gStringVar4 + #ifndef BUGFIX StringExpandPlaceholders(gStringVar4, gText_UR_AwaitingCommunication); + #else + StringExpandPlaceholders(dst, gText_UR_AwaitingCommunication); + #endif break; } } @@ -723,51 +362,51 @@ static void StringExpandPlaceholders_AwaitingCommFromAnother(u8 *dst, u8 caseId) void TryBecomeLinkLeader(void) { u8 taskId; - struct UnkStruct_Leader * dataPtr; + struct WirelessLink_Leader * data; taskId = CreateTask(Task_TryBecomeLinkLeader, 0); - sUnionRoomMain.leader = dataPtr = (void *)(gTasks[taskId].data); - sLeader = dataPtr; + sWirelessLinkMain.leader = data = (void *)(gTasks[taskId].data); + sLeader = data; - dataPtr->state = 0; - dataPtr->textState = 0; - gSpecialVar_Result = 0; + data->state = LL_STATE_INIT; + data->textState = 0; + gSpecialVar_Result = LINKUP_ONGOING; } static void Task_TryBecomeLinkLeader(u8 taskId) { u32 id, val; - struct UnkStruct_Leader * data = sUnionRoomMain.leader; + struct WirelessLink_Leader * data = sWirelessLinkMain.leader; switch (data->state) { - case 0: + case LL_STATE_INIT: sPlayerCurrActivity = sLinkGroupToActivityAndCapacity[gSpecialVar_0x8004]; sPlayerActivityGroupSize = sLinkGroupToActivityAndCapacity[gSpecialVar_0x8004] >> 8; SetHostRfuGameData(sPlayerCurrActivity, 0, 0); SetWirelessCommType1(); OpenLink(); - InitializeRfuLinkManager_LinkLeader(sPlayerActivityGroupSize & 0xF); - data->state = 3; + InitializeRfuLinkManager_LinkLeader(GROUP_MAX(sPlayerActivityGroupSize)); + data->state = LL_STATE_INIT2; break; - case 3: - data->field_4 = AllocZeroed(4 * sizeof(struct UnkStruct_x1C)); - data->field_0 = AllocZeroed(UROOM_MAX_PARTY_SIZE * sizeof(struct UnkStruct_x20)); - data->field_8 = AllocZeroed(UROOM_MAX_PARTY_SIZE * sizeof(struct UnkStruct_x20)); - BlankUnkStruct_x1CArray(data->field_4->arr, 4); - BlankUnkStruct_x20Array(data->field_0->arr, UROOM_MAX_PARTY_SIZE); - CopyHostRfuGameDataAndUsername(&data->field_0->arr[0].gname_uname.gname, data->field_0->arr[0].gname_uname.uname); - data->field_0->arr[0].field_18 = 0; - data->field_0->arr[0].groupScheduledAnim = UNION_ROOM_SPAWN_IN; - data->field_0->arr[0].field_1A_1 = 0; - data->field_0->arr[0].field_1B = 0; - data->listenTaskId = CreateTask_ListenForPartnersWithCompatibleSerialNos(data->field_4, 0xFF); + case LL_STATE_INIT2: + 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->players, 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); data->listWindowId = AddWindow(&sWindowTemplate_List_PossibleGroupMembers); data->nPlayerModeWindowId = AddWindow(&sWindowTemplate_NumPlayerMode); FillWindowPixelBuffer(data->bButtonCancelWindowId, PIXEL_FILL(2)); - UR_AddTextPrinterParameterized(data->bButtonCancelWindowId, 0, gText_UR_BButtonCancel, 8, 2, UR_COLOR_WHT_DKE_LTE); + PrintUnionRoomText(data->bButtonCancelWindowId, FONT_0, gText_UR_BButtonCancel, 8, 2, UR_COLOR_CANCEL); PutWindowTilemap(data->bButtonCancelWindowId); CopyWindowToVram(data->bButtonCancelWindowId, COPYWIN_GFX); @@ -782,129 +421,125 @@ static void Task_TryBecomeLinkLeader(u8 taskId) CopyBgTilemapBufferToVram(0); data->playerCount = 1; - data->state = 4; + data->state = LL_STATE_GET_AWAITING_PLAYERS_TEXT; break; - case 4: - StringCopy(gStringVar1, sUnionRoomActivityStringPtrs[sPlayerCurrActivity]); - if ((sPlayerActivityGroupSize >> 4) != 0) + case LL_STATE_GET_AWAITING_PLAYERS_TEXT: + StringCopy(gStringVar1, sLinkGroupActivityNameTexts[sPlayerCurrActivity]); + if (GROUP_MIN(sPlayerActivityGroupSize) != 0) { - if (data->playerCount > (sPlayerActivityGroupSize >> 4) - 1 && (sPlayerActivityGroupSize & 0xF) != 0) + if (data->playerCount > GROUP_MIN(sPlayerActivityGroupSize) - 1 && GROUP_MAX(sPlayerActivityGroupSize) != 0) StringExpandPlaceholders(gStringVar4, gText_UR_AwaitingLinkPressStart); else StringExpandPlaceholders(gStringVar4, gText_UR_AwaitingCommunication); } else { - StringExpandPlaceholders_AwaitingCommFromAnother(gStringVar4, sPlayerCurrActivity); + GetAwaitingCommunicationText(gStringVar4, sPlayerCurrActivity); } PrintNumPlayersWaitingForMsg(data->nPlayerModeWindowId, sPlayerActivityGroupSize, data->playerCount); - data->state = 5; + data->state = LL_STATE_PRINT_AWAITING_PLAYERS; break; - case 5: + case LL_STATE_PRINT_AWAITING_PLAYERS: if (PrintOnTextbox(&data->textState, gStringVar4)) - data->state = 6; + data->state = LL_STATE_AWAIT_PLAYERS; break; - case 6: - Leader_SetStateIfMemberListChanged(data, 7, 10); + case LL_STATE_AWAIT_PLAYERS: + Leader_SetStateIfMemberListChanged(data, LL_STATE_ACCEPT_NEW_MEMBER_PROMPT, LL_STATE_MEMBER_LEFT); if (JOY_NEW(B_BUTTON)) { if (data->playerCount == 1) - data->state = 23; - else if ((sPlayerActivityGroupSize & 0xF0) != 0) - data->state = 30; + data->state = LL_STATE_SHUTDOWN_AND_FAIL; + else if (GROUP_MIN2(sPlayerActivityGroupSize) != 0) + data->state = LL_STATE_CANCEL_WITH_MSG; else - data->state = 19; + data->state = LL_STATE_CANCEL_PROMPT; } - if ((sPlayerActivityGroupSize >> 4) != 0 - && data->playerCount > (sPlayerActivityGroupSize >> 4) - 1 - && (sPlayerActivityGroupSize & 0xF) != 0 + if (GROUP_MIN(sPlayerActivityGroupSize) != 0 + && data->playerCount > GROUP_MIN(sPlayerActivityGroupSize) - 1 + && GROUP_MAX(sPlayerActivityGroupSize) != 0 && IsRfuCommunicatingWithAllChildren() && JOY_NEW(START_BUTTON)) { - data->state = 15; + data->state = LL_STATE_MEMBERS_OK_PROMPT; LinkRfu_StopManagerAndFinalizeSlots(); } - if (data->state == 6 && RfuTryDisconnectLeavingChildren()) + if (data->state == LL_STATE_AWAIT_PLAYERS && RfuTryDisconnectLeavingChildren()) { - data->state = 9; + // At least 1 group member has left or is trying to leave + data->state = LL_STATE_WAIT_DISCONNECT_CHILD; } break; - case 9: + case LL_STATE_WAIT_DISCONNECT_CHILD: + // Resume after ensuring all members trying to leave have left if (!RfuTryDisconnectLeavingChildren()) { - data->state = 6; - data->playerCount = UnionRoomLeaderField0CompactionAndCount(data->field_0); + data->state = LL_STATE_AWAIT_PLAYERS; + data->playerCount = LeaderPrunePlayerList(data->playerList); } break; - case 10: - id = ((sPlayerCurrActivity & 0xF) == 2) ? 1 : 0; + case LL_STATE_MEMBER_LEFT: + id = (GROUP_MAX(sPlayerCurrActivity) == 2) ? 1 : 0; if (PrintOnTextbox(&data->textState, gTexts_UR_PlayerUnavailable[id])) { - data->playerCount = UnionRoomLeaderField0CompactionAndCount(data->field_0); + data->playerCount = LeaderPrunePlayerList(data->playerList); RedrawListMenu(data->listTaskId); - data->state = 4; + data->state = LL_STATE_GET_AWAITING_PLAYERS_TEXT; } break; - case 29: - // Other player cancelled. - id = ((sPlayerActivityGroupSize & 0xF) == 2) ? 0 : 1; + case LL_STATE_MEMBER_DISCONNECTED: + id = (GROUP_MAX(sPlayerActivityGroupSize) == 2) ? 0 : 1; if (PrintOnTextbox(&data->textState, gTexts_UR_PlayerUnavailable[id])) - { - data->state = 21; - } + data->state = LL_STATE_SHUTDOWN_AND_RETRY; break; - case 7: + case LL_STATE_ACCEPT_NEW_MEMBER_PROMPT: if (PrintOnTextbox(&data->textState, gStringVar4)) - { - data->state = 11; - } + data->state = LL_STATE_ACCEPT_NEW_MEMBER_PROMPT_HANDLE_INPUT; break; - case 11: + case LL_STATE_ACCEPT_NEW_MEMBER_PROMPT_HANDLE_INPUT: switch (UnionRoomHandleYesNo(&data->textState, HasTrainerLeftPartnersList( - ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.compatibility.playerTrainerId), - data->field_0->arr[data->playerCount].gname_uname.uname))) + ReadAsU16(data->playerList->players[data->playerCount].rfu.data.compatibility.playerTrainerId), + data->playerList->players[data->playerCount].rfu.name))) { - case 0: + case 0: // YES LoadWirelessStatusIndicatorSpriteGfx(); CreateWirelessStatusIndicatorSprite(0, 0); - data->field_19 = 5; - SendRfuStatusToPartner(5, ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.compatibility.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.uname); - data->state = 12; + data->joinRequestAnswer = RFU_STATUS_JOIN_GROUP_OK; + 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: - case -1: - data->field_19 = 6; - SendRfuStatusToPartner(6, ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.compatibility.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.uname); - data->state = 12; + case 1: // NO + case MENU_B_PRESSED: + data->joinRequestAnswer = RFU_STATUS_JOIN_GROUP_NO; + 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 = 9; + data->state = LL_STATE_WAIT_DISCONNECT_CHILD; break; } break; - case 12: - val = WaitSendRfuStatusToPartner(ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.compatibility.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.uname); - if (val == 1) + case LL_STATE_UPDATE_AFTER_JOIN_REQUEST: + val = WaitSendRfuStatusToPartner(ReadAsU16(data->playerList->players[data->playerCount].rfu.data.compatibility.playerTrainerId), data->playerList->players[data->playerCount].rfu.name); + if (val == 1) // Send complete { - // Xfer complete - if (data->field_19 == 5) + if (data->joinRequestAnswer == RFU_STATUS_JOIN_GROUP_OK) { // Sent "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 == (sPlayerActivityGroupSize & 0xF)) + if (data->playerCount == GROUP_MAX(sPlayerActivityGroupSize)) { - if ((sPlayerActivityGroupSize & 0xF0) != 0 || data->playerCount == 4) + if (GROUP_MIN2(sPlayerActivityGroupSize) != 0 || data->playerCount == RFU_CHILD_MAX) { - data->state = 15; + 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, gText_UR_AnOKWasSentToPlayer); - data->state = 13; + data->state = LL_STATE_ACCEPTED_FINAL_MEMBER; } LinkRfu_StopManagerAndFinalizeSlots(); @@ -912,124 +547,119 @@ static void Task_TryBecomeLinkLeader(u8 taskId) } else { - data->state = 4; + data->state = LL_STATE_GET_AWAITING_PLAYERS_TEXT; } } - else + else // Member disconnected { - // Sent "no" - RequestDisconnectSlotByTrainerNameAndId(data->field_0->arr[data->playerCount].gname_uname.uname, ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.compatibility.playerTrainerId)); - data->field_0->arr[data->playerCount].groupScheduledAnim = UNION_ROOM_SPAWN_NONE; - UnionRoomLeaderField0CompactionAndCount(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 = 4; + data->state = LL_STATE_GET_AWAITING_PLAYERS_TEXT; } - data->field_19 = 0; + data->joinRequestAnswer = 0; } else if (val == 2) { // Disconnect RfuSetStatus(RFU_STATUS_OK, 0); - data->state = 4; + data->state = LL_STATE_GET_AWAITING_PLAYERS_TEXT; } break; - case 13: + case LL_STATE_ACCEPTED_FINAL_MEMBER: if (PrintOnTextbox(&data->textState, gStringVar4)) - data->state = 14; + data->state = LL_STATE_WAIT_AND_CONFIRM_MEMBERS; break; - case 14: + case LL_STATE_WAIT_AND_CONFIRM_MEMBERS: if (++data->delayTimerAfterOk > 120) - data->state = 17; + data->state = LL_STATE_CONFIRMED_MEMBERS; break; - case 15: + case LL_STATE_MEMBERS_OK_PROMPT: if (PrintOnTextbox(&data->textState, gText_UR_AreTheseMembersOK)) - data->state = 16; + data->state = LL_STATE_MEMBERS_OK_PROMPT_HANDLE_INPUT; break; - case 16: + case LL_STATE_MEMBERS_OK_PROMPT_HANDLE_INPUT: switch (UnionRoomHandleYesNo(&data->textState, FALSE)) { - case 0: - // Yes - data->state = 17; + case 0: // YES + data->state = LL_STATE_CONFIRMED_MEMBERS; break; - case 1: - case -1: - // No - if ((sPlayerActivityGroupSize & 0xF0) != 0) - data->state = 30; + case 1: // NO + case MENU_B_PRESSED: + if (GROUP_MIN2(sPlayerActivityGroupSize) != 0) + data->state = LL_STATE_CANCEL_WITH_MSG; else - data->state = 19; + data->state = LL_STATE_CANCEL_PROMPT; break; } break; - case 19: + case LL_STATE_CANCEL_PROMPT: if (PrintOnTextbox(&data->textState, gText_UR_CancelModeWithTheseMembers)) - data->state = 20; + data->state = LL_STATE_CANCEL_PROMPT_HANDLE_INPUT; break; - case 20: + case LL_STATE_CANCEL_PROMPT_HANDLE_INPUT: switch (UnionRoomHandleYesNo(&data->textState, FALSE)) { - case 0: - data->state = 23; + case 0: // YES + data->state = LL_STATE_SHUTDOWN_AND_FAIL; break; - case 1: - case -1: - if ((sPlayerActivityGroupSize & 0xF0) != 0) - data->state = 15; - else if (data->playerCount == (sPlayerActivityGroupSize & 0xF)) - data->state = 15; + case 1: // NO + case MENU_B_PRESSED: + if (GROUP_MIN2(sPlayerActivityGroupSize) != 0) + data->state = LL_STATE_MEMBERS_OK_PROMPT; + else if (data->playerCount == GROUP_MAX(sPlayerActivityGroupSize)) + data->state = LL_STATE_MEMBERS_OK_PROMPT; else - data->state = 4; + data->state = LL_STATE_GET_AWAITING_PLAYERS_TEXT; break; } break; - case 17: - // Go to start - // Final membership check - if (!Leader_SetStateIfMemberListChanged(data, 7, 23)) - data->state = 18; + case LL_STATE_CONFIRMED_MEMBERS: + if (!Leader_SetStateIfMemberListChanged(data, LL_STATE_ACCEPT_NEW_MEMBER_PROMPT, LL_STATE_SHUTDOWN_AND_FAIL)) + data->state = LL_STATE_FINAL_MEMBER_CHECK; break; - case 18: + case LL_STATE_FINAL_MEMBER_CHECK: if (LmanAcceptSlotFlagIsNotZero()) { if (WaitRfuState(FALSE)) { - data->state = 26; + data->state = LL_STATE_TRY_START_ACTIVITY; } } else { - data->state = 29; + data->state = LL_STATE_MEMBER_DISCONNECTED; data->textState = 0; } break; - case 30: + case LL_STATE_CANCEL_WITH_MSG: if (PrintOnTextbox(&data->textState, gText_UR_ModeWithTheseMembersWillBeCanceled)) - data->state = 23; + data->state = LL_STATE_SHUTDOWN_AND_FAIL; break; - case 21: - case 23: + case LL_STATE_SHUTDOWN_AND_RETRY: + case LL_STATE_SHUTDOWN_AND_FAIL: // An error occurred. Please start over from the beginning. DestroyWirelessStatusIndicatorSprite(); LinkRfu_Shutdown(); Leader_DestroyResources(data); - data->state++; + data->state++; // LL_STATE_RETRY or LL_STATE_FAILED break; - case 24: + case LL_STATE_FAILED: ScriptContext_Enable(); DestroyTask(taskId); - gSpecialVar_Result = 5; + gSpecialVar_Result = LINKUP_FAILED; break; - case 22: + case LL_STATE_RETRY: ScriptContext_Enable(); DestroyTask(taskId); - gSpecialVar_Result = 8; + gSpecialVar_Result = LINKUP_RETRY_ROLE_ASSIGN; break; - case 26: + case LL_STATE_TRY_START_ACTIVITY: if (RfuHasErrored()) { - data->state = 29; + data->state = LL_STATE_MEMBER_DISCONNECTED; } else { @@ -1045,7 +675,7 @@ static void Task_TryBecomeLinkLeader(u8 taskId) } } -static void Leader_DestroyResources(struct UnkStruct_Leader * data) +static void Leader_DestroyResources(struct WirelessLink_Leader * data) { ClearWindowTilemap(data->nPlayerModeWindowId); ClearStdWindowAndFrame(data->nPlayerModeWindowId, FALSE); @@ -1058,28 +688,28 @@ static void Leader_DestroyResources(struct UnkStruct_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 activity) { switch (activity) { - case ACTIVITY_BATTLE: - case ACTIVITY_DBLBATTLE: + case ACTIVITY_BATTLE_SINGLE: + case ACTIVITY_BATTLE_DOUBLE: case ACTIVITY_TRADE: StringExpandPlaceholders(dst, gText_UR_PlayerContactedYouForXAccept); break; - case ACTIVITY_WCARD2: - case ACTIVITY_WNEWS2: + case ACTIVITY_WONDER_CARD: + case ACTIVITY_WONDER_NEWS: StringExpandPlaceholders(dst, gText_UR_PlayerContactedYouShareX); break; - case ACTIVITY_MLTBATTLE: - case ACTIVITY_PJUMP: - case ACTIVITY_BCRUSH: - case ACTIVITY_BPICK: + case ACTIVITY_BATTLE_MULTI: + case ACTIVITY_POKEMON_JUMP: + case ACTIVITY_BERRY_CRUSH: + case ACTIVITY_BERRY_PICK: StringExpandPlaceholders(dst, gText_UR_PlayerContactedYouAddToMembers); break; } @@ -1089,7 +719,7 @@ static void GetYouDeclinedTheOfferMessage(u8 *dst, u8 activity) { switch (activity) { - case ACTIVITY_BATTLE | IN_UNION_ROOM: + case ACTIVITY_BATTLE_SINGLE | IN_UNION_ROOM: case ACTIVITY_TRADE | IN_UNION_ROOM: StringExpandPlaceholders(dst, gText_UR_OfferDeclined1); break; @@ -1104,17 +734,17 @@ static void GetYouAskedToJoinGroupPleaseWaitMessage(u8 *dst, u8 activity) { switch (activity) { - case ACTIVITY_BATTLE: - case ACTIVITY_DBLBATTLE: + case ACTIVITY_BATTLE_SINGLE: + case ACTIVITY_BATTLE_DOUBLE: case ACTIVITY_TRADE: - case ACTIVITY_WCARD2: - case ACTIVITY_WNEWS2: + case ACTIVITY_WONDER_CARD: + case ACTIVITY_WONDER_NEWS: StringExpandPlaceholders(dst, gText_UR_AwaitingPlayersResponse); break; - case ACTIVITY_MLTBATTLE: - case ACTIVITY_PJUMP: - case ACTIVITY_BCRUSH: - case ACTIVITY_BPICK: + case ACTIVITY_BATTLE_MULTI: + case ACTIVITY_POKEMON_JUMP: + case ACTIVITY_BERRY_CRUSH: + case ACTIVITY_BERRY_PICK: StringExpandPlaceholders(dst, gText_UR_PlayerHasBeenAskedToRegisterYouPleaseWait); break; } @@ -1124,96 +754,98 @@ static void GetGroupLeaderSentAnOKMessage(u8 *dst, u8 caseId) { switch (caseId) { - case ACTIVITY_BATTLE: - case ACTIVITY_DBLBATTLE: + case ACTIVITY_BATTLE_SINGLE: + case ACTIVITY_BATTLE_DOUBLE: case ACTIVITY_TRADE: - case ACTIVITY_WCARD2: - case ACTIVITY_WNEWS2: + case ACTIVITY_WONDER_CARD: + case ACTIVITY_WONDER_NEWS: StringExpandPlaceholders(dst, gText_UR_PlayerSentBackOK); break; - case ACTIVITY_MLTBATTLE: - case ACTIVITY_PJUMP: - case ACTIVITY_BCRUSH: - case ACTIVITY_BPICK: + case ACTIVITY_BATTLE_MULTI: + case ACTIVITY_POKEMON_JUMP: + case ACTIVITY_BERRY_CRUSH: + case ACTIVITY_BERRY_PICK: StringExpandPlaceholders(dst, gText_UR_PlayerOKdRegistration); break; } } -static bool8 Leader_SetStateIfMemberListChanged(struct UnkStruct_Leader * data, u32 state1, u32 state2) +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, sPlayerCurrActivity); - data->state = state1; + data->state = joinedState; break; case UNION_ROOM_SPAWN_OUT: RfuSetStatus(RFU_STATUS_OK, 0); RedrawListMenu(data->listTaskId); - data->state = state2; + data->state = droppedState; return TRUE; } return FALSE; } -static void ItemPrintFunc_PossibleGroupMembers(u8 windowId, u32 itemId, u8 y) +static void ItemPrintFunc_PossibleGroupMembers(u8 windowId, u32 id, u8 y) { - struct UnkStruct_Leader * data = sUnionRoomMain.leader; - u8 var = 0; + struct WirelessLink_Leader * data = sWirelessLinkMain.leader; + u8 colorIdx = UR_COLOR_DEFAULT; - switch (data->field_0->arr[itemId].groupScheduledAnim) + switch (data->playerList->players[id].groupScheduledAnim) { case UNION_ROOM_SPAWN_IN: - if (data->field_0->arr[itemId].field_1B != 0) - var = UR_COLOR_GRN_WHT_LTG; + if (data->playerList->players[id].newPlayerCountdown != 0) + colorIdx = UR_COLOR_GREEN; break; case UNION_ROOM_SPAWN_OUT: - var = UR_COLOR_RED_WHT_LTR; + colorIdx = UR_COLOR_RED; break; } - PrintGroupMemberCandidateOnWindowWithColor(windowId, 0, y, &data->field_0->arr[itemId], var, itemId); + PrintGroupCandidateOnWindow(windowId, 0, y, &data->playerList->players[id], colorIdx, id); } -static u8 LeaderUpdateGroupMembership(struct UnkStruct_Main0 * arg0) +static u8 LeaderUpdateGroupMembership(struct RfuPlayerList * list) { - struct UnkStruct_Leader * data = sUnionRoomMain.leader; + struct WirelessLink_Leader * data = sWirelessLinkMain.leader; u8 ret = UNION_ROOM_SPAWN_NONE; u8 i; s32 id; - for (i = 1; i < UROOM_MAX_PARTY_SIZE; i++) + 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].field_18 = 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], UROOM_MAX_PARTY_SIZE); + TryAddIncomingPlayerToList(data->playerList->players, &data->incomingPlayerList->players[id], MAX_RFU_PLAYERS); if (ret != UNION_ROOM_SPAWN_OUT) { - for (id = 0; id < UROOM_MAX_PARTY_SIZE; id++) + 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; } } @@ -1221,95 +853,95 @@ static u8 LeaderUpdateGroupMembership(struct UnkStruct_Main0 * arg0) return ret; } -static u8 UnionRoomLeaderField0CompactionAndCount(struct UnkStruct_Main0 * arg0) +static u8 LeaderPrunePlayerList(struct RfuPlayerList * list) { - struct UnkStruct_Leader * data = sUnionRoomMain.leader; + struct WirelessLink_Leader * data = sWirelessLinkMain.leader; u8 copiedCount; s32 i; - u8 ret; + u8 playerCount; - for (i = 0; i < UROOM_MAX_PARTY_SIZE; i++) - data->field_8->arr[i] = data->field_0->arr[i]; + for (i = 0; i < MAX_RFU_PLAYERS; i++) + data->playerListBackup->players[i] = data->playerList->players[i]; copiedCount = 0; - for (i = 0; i < UROOM_MAX_PARTY_SIZE; i++) + 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++; } } - ret = copiedCount; - for (; copiedCount < UROOM_MAX_PARTY_SIZE; copiedCount++) + playerCount = copiedCount; + for (; copiedCount < MAX_RFU_PLAYERS; copiedCount++) { - data->field_0->arr[copiedCount].gname_uname = sUnionGnameUnamePair_Dummy; - data->field_0->arr[copiedCount].field_18 = 0; - data->field_0->arr[copiedCount].groupScheduledAnim = UNION_ROOM_SPAWN_NONE; - data->field_0->arr[copiedCount].field_1A_1 = FALSE; - data->field_0->arr[copiedCount].field_1B = 0; + data->playerList->players[copiedCount].rfu = sRfuPlayerData_Dummy; + 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 < UROOM_MAX_PARTY_SIZE; i++) + 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 != 0x40) + if (data->playerList->players[i].newPlayerCountdown != 64) continue; - ret = i; + playerCount = i; break; } - return ret; + return playerCount; } void TryJoinLinkGroup(void) { u8 taskId; - struct UnkStruct_Group * dataPtr; + struct WirelessLink_Group * data; taskId = CreateTask(Task_TryJoinLinkGroup, 0); - sUnionRoomMain.group = dataPtr = (void *)(gTasks[taskId].data); - sGroup = dataPtr; + sWirelessLinkMain.group = data = (void *)(gTasks[taskId].data); + sGroup = data; - dataPtr->state = 0; - dataPtr->textState = 0; - gSpecialVar_Result = 0; + data->state = LG_STATE_INIT; + data->textState = 0; + gSpecialVar_Result = LINKUP_ONGOING; } static void Task_TryJoinLinkGroup(u8 taskId) { s32 id; - struct UnkStruct_Group * data = sUnionRoomMain.group; + struct WirelessLink_Group * data = sWirelessLinkMain.group; switch (data->state) { - case 0: + case LG_STATE_INIT: SetHostRfuGameData(sLinkGroupToURoomActivity[gSpecialVar_0x8004], 0, 0); sPlayerCurrActivity = sLinkGroupToURoomActivity[gSpecialVar_0x8004]; SetWirelessCommType1(); OpenLink(); InitializeRfuLinkManager_JoinGroup(); - data->field_4 = AllocZeroed(4 * sizeof(struct UnkStruct_x1C)); - data->field_0 = AllocZeroed(16 * sizeof(struct UnkStruct_x20)); - data->state = 1; + 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 1: + case LG_STATE_CHOOSE_LEADER_MSG: if (PrintOnTextbox(&data->textState, gTexts_UR_ChooseTrainer[gSpecialVar_0x8004])) - data->state = 2; + data->state = LG_STATE_INIT_WINDOWS; break; - case 2: - BlankUnkStruct_x1CArray(data->field_4->arr, 4); - BlankUnkStruct_x20Array(data->field_0->arr, 16); - data->listenTaskId = CreateTask_ListenForPartnersWithCompatibleSerialNos(data->field_4, gSpecialVar_0x8004); + case LG_STATE_INIT_WINDOWS: + ClearIncomingPlayerList(data->incomingPlayerList->players, 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(&sWindowTemplate_MysteryGiftList); - data->playerNameAndIdWindowId = AddWindow(&sWindowTemplate_MysteryGiftPlayerNameAndId); + data->listWindowId = AddWindow(&sWindowTemplate_GroupList); + data->playerNameAndIdWindowId = AddWindow(&sWindowTemplate_PlayerNameAndId); FillWindowPixelBuffer(data->bButtonCancelWindowId, PIXEL_FILL(2)); - UR_AddTextPrinterParameterized(data->bButtonCancelWindowId, 0, gText_UR_ChooseJoinCancel, 8, 2, UR_COLOR_WHT_DKE_LTE); + PrintUnionRoomText(data->bButtonCancelWindowId, FONT_0, gText_UR_ChooseJoinCancel, 8, 2, UR_COLOR_CANCEL); PutWindowTilemap(data->bButtonCancelWindowId); CopyWindowToVram(data->bButtonCancelWindowId, COPYWIN_GFX); @@ -1325,9 +957,9 @@ static void Task_TryJoinLinkGroup(u8 taskId) CopyBgTilemapBufferToVram(0); data->leaderId = 0; - data->state = 3; + data->state = LG_STATE_CHOOSE_LEADER_HANDLE_INPUT; break; - case 3: + case LG_STATE_CHOOSE_LEADER_HANDLE_INPUT: id = GetNewLeaderCandidate(); switch (id) { @@ -1337,26 +969,26 @@ 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 != LIST_NOTHING_CHOSEN) { // this unused variable along with the assignment is needed to match - u32 unusedVar; - unusedVar = 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.startedActivity) + if (data->playerList->players[id].groupScheduledAnim == UNION_ROOM_SPAWN_IN && !data->playerList->players[id].rfu.data.startedActivity) { - u32 var = IsTryingToTradeWithHoennTooSoon(data, id); - if (var == 0) + u32 readyStatus = IsTryingToTradeAcrossVersionTooSoon(data, id); + if (readyStatus == UR_TRADE_READY) { + // Trading is allowed, or not trading at all AskToJoinRfuGroup(data, id); - data->state = 5; + data->state = LG_STATE_ASK_JOIN_GROUP; PlaySE(SE_POKENAV_ON); } else { // Postgame flags not both set - StringCopy(gStringVar4, gTexts_UR_CantTransmitToTrainer[var - 1]); - data->state = 18; + StringCopy(gStringVar4, gTexts_UR_CantTransmitToTrainer[readyStatus - 1]); + data->state = LG_STATE_TRADE_NOT_READY; PlaySE(SE_POKENAV_ON); } } @@ -1367,7 +999,7 @@ static void Task_TryJoinLinkGroup(u8 taskId) } else if (JOY_NEW(B_BUTTON)) { - data->state = 10; + data->state = LG_STATE_CANCEL_CHOOSE_LEADER; } break; default: @@ -1375,59 +1007,58 @@ static void Task_TryJoinLinkGroup(u8 taskId) break; } break; - case 5: + case LG_STATE_ASK_JOIN_GROUP: GetYouAskedToJoinGroupPleaseWaitMessage(gStringVar4, sPlayerCurrActivity); if (PrintOnTextbox(&data->textState, gStringVar4)) { - IntlConvPartnerUname7(gStringVar1, data->field_0->arr[data->leaderId]); - data->state = 6; + CopyAndTranslatePlayerName(gStringVar1, data->playerList->players[data->leaderId]); + data->state = LG_STATE_MAIN; } break; - case 6: + case LG_STATE_MAIN: if (gReceivedRemoteLinkPlayers) { - sPlayerCurrActivity = data->field_0->arr[data->leaderId].gname_uname.gname.activity; + sPlayerCurrActivity = data->playerList->players[data->leaderId].rfu.data.activity; RfuSetStatus(RFU_STATUS_OK, 0); switch (sPlayerCurrActivity) { - case ACTIVITY_BATTLE: - case ACTIVITY_DBLBATTLE: - case ACTIVITY_MLTBATTLE: + case ACTIVITY_BATTLE_SINGLE: + case ACTIVITY_BATTLE_DOUBLE: + case ACTIVITY_BATTLE_MULTI: case ACTIVITY_TRADE: case ACTIVITY_CHAT: - case ACTIVITY_PJUMP: - case ACTIVITY_BCRUSH: - case ACTIVITY_BPICK: - case ACTIVITY_SPINTRADE: - case ACTIVITY_ITEMTRADE: - case ACTIVITY_WCARD2: - case ACTIVITY_WNEWS2: - data->state = 20; + case ACTIVITY_POKEMON_JUMP: + case ACTIVITY_BERRY_CRUSH: + case ACTIVITY_BERRY_PICK: + case ACTIVITY_SPIN_TRADE: + case ACTIVITY_ITEM_TRADE: + case ACTIVITY_WONDER_CARD: + case ACTIVITY_WONDER_NEWS: + data->state = LG_STATE_READY_START_ACTIVITY; break; } } switch (RfuGetStatus()) { - case 1: - data->state = 12; + case RFU_STATUS_FATAL_ERROR: + data->state = LG_STATE_RFU_ERROR; break; - case 2: - case 6: - case 9: - data->state = 14; + case RFU_STATUS_CONNECTION_ERROR: + case RFU_STATUS_JOIN_GROUP_NO: + case RFU_STATUS_LEAVE_GROUP: + data->state = LG_STATE_DISCONNECTED; break; - case 5: + case RFU_STATUS_JOIN_GROUP_OK: GetGroupLeaderSentAnOKMessage(gStringVar4, sPlayerCurrActivity); if (PrintOnTextbox(&data->textState, gStringVar4)) { RfuSetStatus(RFU_STATUS_WAIT_ACK_JOIN_GROUP, 0); - StringCopy(gStringVar1, sUnionRoomActivityStringPtrs[sPlayerCurrActivity]); + StringCopy(gStringVar1, sLinkGroupActivityNameTexts[sPlayerCurrActivity]); StringExpandPlaceholders(gStringVar4, gText_UR_AwaitingOtherMembers); } break; - case 7: - // Wait 4 seconds + case RFU_STATUS_WAIT_ACK_JOIN_GROUP: if (data->delayBeforePrint > 240) { if (PrintOnTextbox(&data->textState, gStringVar4)) @@ -1443,41 +1074,41 @@ static void Task_TryJoinLinkGroup(u8 taskId) break; } - if (!RfuGetStatus() && JOY_NEW(B_BUTTON)) - data->state = 7; + if (RfuGetStatus() == RFU_STATUS_OK && JOY_NEW(B_BUTTON)) + data->state = LG_STATE_ASK_LEAVE_GROUP; break; - case 7: + case LG_STATE_ASK_LEAVE_GROUP: if (PrintOnTextbox(&data->textState, gText_UR_QuitBeingMember)) - data->state = 8; + data->state = LG_STATE_ASK_LEAVE_GROUP_HANDLE_INPUT; break; - case 8: + case LG_STATE_ASK_LEAVE_GROUP_HANDLE_INPUT: switch (UnionRoomHandleYesNo(&data->textState, RfuGetStatus())) { - case 0: + case 0: // YES SendLeaveGroupNotice(); - data->state = 9; + data->state = LG_STATE_WAIT_LEAVE_GROUP; RedrawListMenu(data->listTaskId); break; - case 1: - case -1: - data->state = 5; + case 1: // NO + case MENU_B_PRESSED: + data->state = LG_STATE_ASK_JOIN_GROUP; RedrawListMenu(data->listTaskId); break; case -3: - data->state = 6; + data->state = LG_STATE_MAIN; RedrawListMenu(data->listTaskId); break; } break; - case 9: + case LG_STATE_WAIT_LEAVE_GROUP: if (RfuGetStatus()) - data->state = 6; + data->state = LG_STATE_MAIN; break; - case 10: - case 12: - case 14: - case 18: - case 20: + case LG_STATE_CANCEL_CHOOSE_LEADER: // next: LG_STATE_CANCELED + case LG_STATE_RFU_ERROR: // next: LG_STATE_RFU_ERROR_SHUTDOWN + case LG_STATE_DISCONNECTED: // next: LG_STATE_RETRY_CONNECTION + case LG_STATE_TRADE_NOT_READY: // next: LG_STATE_TRADE_NOT_READY_RETRY + case LG_STATE_READY_START_ACTIVITY: // next: LG_STATE_START_ACTIVITY ClearWindowTilemap(data->playerNameAndIdWindowId); ClearStdWindowAndFrame(data->playerNameAndIdWindowId, FALSE); DestroyListMenuTask(data->listTaskId, 0, 0); @@ -1488,116 +1119,121 @@ 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 13: + case LG_STATE_RFU_ERROR_SHUTDOWN: DestroyWirelessStatusIndicatorSprite(); if (PrintOnTextbox(&data->textState, gTexts_UR_PlayerDisconnected[RfuGetStatus()])) { - gSpecialVar_Result = 6; - data->state = 23; + gSpecialVar_Result = LINKUP_CONNECTION_ERROR; + data->state = LG_STATE_SHUTDOWN; } break; - case 11: + case LG_STATE_CANCELED: DestroyWirelessStatusIndicatorSprite(); - gSpecialVar_Result = 5; - data->state = 23; + gSpecialVar_Result = LINKUP_FAILED; + data->state = LG_STATE_SHUTDOWN; break; - case 15: + case LG_STATE_RETRY_CONNECTION: + // Failure from disconnection + // Happens if player or required member(s) leave group + // or if player is rejected from joining group DestroyWirelessStatusIndicatorSprite(); if (PrintOnTextbox(&data->textState, gTexts_UR_PlayerDisconnected[RfuGetStatus()])) { - gSpecialVar_Result = 8; - data->state = 23; + gSpecialVar_Result = LINKUP_RETRY_ROLE_ASSIGN; + data->state = LG_STATE_SHUTDOWN; } break; - case 19: + case LG_STATE_TRADE_NOT_READY_RETRY: if (PrintOnTextbox(&data->textState, gStringVar4)) { - gSpecialVar_Result = 8; - data->state = 23; + gSpecialVar_Result = LINKUP_RETRY_ROLE_ASSIGN; + data->state = LG_STATE_SHUTDOWN; } break; - case 23: + case LG_STATE_SHUTDOWN: DestroyTask(taskId); - JoinGroup_BlankBg0AndEnableScriptContexts(); + JoinGroup_EnableScriptContexts(); LinkRfu_Shutdown(); break; - case 21: + case LG_STATE_START_ACTIVITY: CreateTask_RunScriptAndFadeToActivity(); DestroyTask(taskId); break; } } -static u32 IsTryingToTradeWithHoennTooSoon(struct UnkStruct_Group * arg0, s32 id) +static u32 IsTryingToTradeAcrossVersionTooSoon(struct WirelessLink_Group * data, s32 id) { - struct UnkStruct_x20 * structPtr = &arg0->field_0->arr[id]; + struct RfuPlayer * partner = &data->playerList->players[id]; - if (sPlayerCurrActivity == ACTIVITY_TRADE && structPtr->gname_uname.gname.compatibility.version != VERSION_FIRE_RED && structPtr->gname_uname.gname.compatibility.version != VERSION_LEAF_GREEN) + if (sPlayerCurrActivity == ACTIVITY_TRADE + && partner->rfu.data.compatibility.version != VERSION_FIRE_RED + && partner->rfu.data.compatibility.version != VERSION_LEAF_GREEN) { if (!(gSaveBlock2Ptr->specialSaveWarpFlags & CHAMPION_SAVEWARP)) - return 1; - else if (structPtr->gname_uname.gname.compatibility.isChampion) - return 0; + return UR_TRADE_PLAYER_NOT_READY; + else if (partner->rfu.data.compatibility.isChampion) + return UR_TRADE_READY; } else { - return 0; + return UR_TRADE_READY; } - return 2; + return UR_TRADE_PARTNER_NOT_READY; } -static void AskToJoinRfuGroup(struct UnkStruct_Group * data, s32 id) +static void AskToJoinRfuGroup(struct WirelessLink_Group * data, s32 id) { data->leaderId = 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.uname, ReadAsU16(data->field_0->arr[data->leaderId].gname_uname.gname.compatibility.playerTrainerId)); + CreateTask_RfuReconnectWithParent(data->playerList->players[data->leaderId].rfu.name, ReadAsU16(data->playerList->players[data->leaderId].rfu.data.compatibility.playerTrainerId)); } u8 CreateTask_ListenToWireless(void) { u8 taskId; - struct UnkStruct_Group * dataPtr; + struct WirelessLink_Group * data; taskId = CreateTask(Task_ListenToWireless, 0); - sUnionRoomMain.group = dataPtr = (void *)(gTasks[taskId].data); + sWirelessLinkMain.group = data = (void *)(gTasks[taskId].data); - dataPtr->state = 0; - dataPtr->textState = 0; + data->state = 0; + data->textState = 0; - sGroup = dataPtr; + sGroup = data; return taskId; } static void Task_ListenToWireless(u8 taskId) { - struct UnkStruct_Group * data = sUnionRoomMain.group; + struct WirelessLink_Group * data = sWirelessLinkMain.group; switch (data->state) { case 0: - SetHostRfuGameData(0, 0, 0); + SetHostRfuGameData(ACTIVITY_NONE, 0, FALSE); SetWirelessCommType1(); OpenLink(); InitializeRfuLinkManager_JoinGroup(); RfuSetIgnoreError(TRUE); - 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 = 2; break; case 2: - BlankUnkStruct_x1CArray(data->field_4->arr, 4); - BlankUnkStruct_x20Array(data->field_0->arr, 16); - data->listenTaskId = CreateTask_ListenForPartnersWithCompatibleSerialNos(data->field_4, 0xFF); + ClearIncomingPlayerList(data->incomingPlayerList->players, 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; @@ -1609,8 +1245,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; @@ -1626,11 +1262,11 @@ static bool32 IsPartnerActivityAcceptable(u32 activity, u32 group) if (group == 0xFF) return TRUE; - #ifndef UBFIX - if (group <= NELEMS(sAcceptedActivityIds)) // UB: <= may access data outside the array - #else - if (group < NELEMS(sAcceptedActivityIds)) - #endif +#ifdef UBFIX + if (group < ARRAY_COUNT(sAcceptedActivityIds)) +#else + if (group <= ARRAY_COUNT(sAcceptedActivityIds)) // UB: <= may access data outside the array +#endif { const u8 *bytes = sAcceptedActivityIds[group]; @@ -1645,78 +1281,78 @@ static bool32 IsPartnerActivityAcceptable(u32 activity, u32 group) return FALSE; } -static u8 URoomGroupListGetTextColor(struct UnkStruct_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.startedActivity) - return UR_COLOR_WHT_WHT_LTE; - else if (data->field_0->arr[id].field_1A_1) - 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 itemId, u8 y) +static void ListMenuItemPrintFunc_UnionRoomGroups(u8 windowId, u32 id, u8 y) { - struct UnkStruct_Group * data = sUnionRoomMain.group; - u8 color_idx = URoomGroupListGetTextColor(data, itemId); + struct WirelessLink_Group * data = sWirelessLinkMain.group; + u8 colorId = GetGroupListTextColor(data, id); - PrintUnionRoomGroupOnWindow(windowId, 8, y, &data->field_0->arr[itemId], color_idx, itemId); + PrintGroupMemberOnWindow(windowId, 8, y, &data->playerList->players[id], colorId, id); } static u8 GetNewLeaderCandidate(void) { - struct UnkStruct_Group * data = sUnionRoomMain.group; + struct WirelessLink_Group * data = sWirelessLinkMain.group; u8 ret = 0; 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].field_18 = 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].field_18++; - if (data->field_0->arr[i].field_18 >= 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; } } @@ -1726,24 +1362,22 @@ 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; } return ret; } -static void Task_CallCB2ReturnFromLinkTrade(u8 taskId) +static void Task_CreateTradeMenu(u8 taskId) { - CB2_ReturnFromLinkTrade(); + CB2_StartCreateTradeMenu(); DestroyTask(taskId); } -u8 UnionRoom_CreateTask_CallCB2ReturnFromLinkTrade(void) +u8 CreateTask_CreateTradeMenu(void) { - u8 taskId = CreateTask(Task_CallCB2ReturnFromLinkTrade, 0); - - return taskId; + return CreateTask(Task_CreateTradeMenu, 0); } static void Task_StartUnionRoomTrade(u8 taskId) @@ -1778,7 +1412,7 @@ static void Task_StartUnionRoomTrade(u8 taskId) gSelectedTradeMonPositions[TRADE_PLAYER] = monId; gSelectedTradeMonPositions[TRADE_PARTNER] = PARTY_SIZE; gMain.savedCallback = CB2_ReturnToField; - SetMainCallback2(CB2_InitTradeAnim_LinkTrade); + SetMainCallback2(CB2_LinkTrade); ResetUnionRoomTrade(&sUnionRoomTrade); DestroyTask(taskId); } @@ -1804,17 +1438,17 @@ static void Task_ExchangeCards(u8 taskId) for (i = 0; i < GetLinkPlayerCount(); i++) { recvBuff = gBlockRecvBuffer[i]; - CopyTrainerCardData(gTrainerCards[i], recvBuff, gLinkPlayers[i].version); + CopyTrainerCardData(gTrainerCards[i], (struct TrainerCard *)recvBuff, gLinkPlayers[i].version); } if (GetLinkPlayerCount() == 2) { recvBuff = gBlockRecvBuffer[GetMultiplayerId() ^ 1]; - MEventHandleReceivedWonderCard(recvBuff[sizeof(struct TrainerCard) / 2]); + MysteryGift_TryEnableStatsByFlagId(recvBuff[sizeof(struct TrainerCard) / 2]); } else { - ResetReceivedWonderCardFlag(); + MysteryGift_DisableStats(); } ResetBlockReceivedFlags(); @@ -1857,22 +1491,22 @@ void StartUnionRoomBattle(u16 battleFlags) PlayBattleBGM(); } -static void SetCableClubStateAndWarpCurrentMap(u16 linkService, u16 x, u16 y) +static void WarpForWirelessMinigame(u16 linkService, u16 x, u16 y) { VarSet(VAR_CABLE_CLUB_STATE, linkService); - SetWarpDestination(gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum, -1, x, y); - SetDynamicWarpWithCoords(0, gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum, -1, x, y); + SetWarpDestination(gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum, WARP_ID_NONE, x, y); + SetDynamicWarpWithCoords(0, gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum, WARP_ID_NONE, x, y); WarpIntoMap(); } -static void SetCableClubStateAndWarpToNewMap(s8 mapGroup, s8 mapNum, s32 x, s32 y, u16 linkService) +static void WarpForCableClubActivity(s8 mapGroup, s8 mapNum, s32 x, s32 y, u16 linkService) { gSpecialVar_0x8004 = linkService; VarSet(VAR_CABLE_CLUB_STATE, linkService); gFieldLinkPlayerCount = GetLinkPlayerCount(); gLocalLinkPlayerId = GetMultiplayerId(); SetCableClubWarp(); - SetWarpDestination(mapGroup, mapNum, -1, x, y); + SetWarpDestination(mapGroup, mapNum, WARP_ID_NONE, x, y); WarpIntoMap(); } @@ -1907,61 +1541,61 @@ static void CreateTrainerCardInBuffer(void *dest, bool32 setWonderCard) static void Task_StartActivity(u8 taskId) { - ResetReceivedWonderCardFlag(); + MysteryGift_DisableStats(); switch (sPlayerCurrActivity) { - case ACTIVITY_BATTLE: - case ACTIVITY_DBLBATTLE: - case ACTIVITY_MLTBATTLE: + case ACTIVITY_BATTLE_SINGLE: + case ACTIVITY_BATTLE_DOUBLE: + case ACTIVITY_BATTLE_MULTI: case ACTIVITY_TRADE: - case ACTIVITY_PJUMP: - case ACTIVITY_BCRUSH: - case ACTIVITY_BPICK: - case ACTIVITY_SPINTRADE: - case ACTIVITY_ITEMTRADE: + case ACTIVITY_POKEMON_JUMP: + case ACTIVITY_BERRY_CRUSH: + case ACTIVITY_BERRY_PICK: + case ACTIVITY_SPIN_TRADE: + case ACTIVITY_ITEM_TRADE: SaveLinkTrainerNames(); break; } switch (sPlayerCurrActivity) { - case ACTIVITY_BATTLE | IN_UNION_ROOM: + case ACTIVITY_BATTLE_SINGLE | IN_UNION_ROOM: case ACTIVITY_ACCEPT | IN_UNION_ROOM: CleanupOverworldWindowsAndTilemaps(); gMain.savedCallback = CB2_UnionRoomBattle; InitChooseMonsForBattle(CHOOSE_MONS_FOR_UNION_ROOM_BATTLE); break; - case ACTIVITY_BATTLE: + case ACTIVITY_BATTLE_SINGLE: CleanupOverworldWindowsAndTilemaps(); CreateTrainerCardInBuffer(gBlockSendBuffer, TRUE); HealPlayerParty(); SavePlayerParty(); LoadPlayerBag(); - SetCableClubStateAndWarpToNewMap(MAP_GROUP(BATTLE_COLOSSEUM_2P), MAP_NUM(BATTLE_COLOSSEUM_2P), 6, 8, USING_SINGLE_BATTLE); + WarpForCableClubActivity(MAP_GROUP(BATTLE_COLOSSEUM_2P), MAP_NUM(BATTLE_COLOSSEUM_2P), 6, 8, USING_SINGLE_BATTLE); SetMainCallback2(CB2_TransitionToCableClub); break; - case ACTIVITY_DBLBATTLE: + case ACTIVITY_BATTLE_DOUBLE: CleanupOverworldWindowsAndTilemaps(); HealPlayerParty(); SavePlayerParty(); LoadPlayerBag(); CreateTrainerCardInBuffer(gBlockSendBuffer, TRUE); - SetCableClubStateAndWarpToNewMap(MAP_GROUP(BATTLE_COLOSSEUM_2P), MAP_NUM(BATTLE_COLOSSEUM_2P), 6, 8, USING_DOUBLE_BATTLE); + WarpForCableClubActivity(MAP_GROUP(BATTLE_COLOSSEUM_2P), MAP_NUM(BATTLE_COLOSSEUM_2P), 6, 8, USING_DOUBLE_BATTLE); SetMainCallback2(CB2_TransitionToCableClub); break; - case ACTIVITY_MLTBATTLE: + case ACTIVITY_BATTLE_MULTI: CleanupOverworldWindowsAndTilemaps(); HealPlayerParty(); SavePlayerParty(); LoadPlayerBag(); CreateTrainerCardInBuffer(gBlockSendBuffer, TRUE); - SetCableClubStateAndWarpToNewMap(MAP_GROUP(BATTLE_COLOSSEUM_4P), MAP_NUM(BATTLE_COLOSSEUM_4P), 5, 8, USING_MULTI_BATTLE); + WarpForCableClubActivity(MAP_GROUP(BATTLE_COLOSSEUM_4P), MAP_NUM(BATTLE_COLOSSEUM_4P), 5, 8, USING_MULTI_BATTLE); SetMainCallback2(CB2_TransitionToCableClub); break; case ACTIVITY_TRADE: CreateTrainerCardInBuffer(gBlockSendBuffer, TRUE); CleanupOverworldWindowsAndTilemaps(); - SetCableClubStateAndWarpToNewMap(MAP_GROUP(TRADE_CENTER), MAP_NUM(TRADE_CENTER), 5, 8, USING_TRADE_CENTER); + WarpForCableClubActivity(MAP_GROUP(TRADE_CENTER), MAP_NUM(TRADE_CENTER), 5, 8, USING_TRADE_CENTER); SetMainCallback2(CB2_TransitionToCableClub); break; case ACTIVITY_TRADE | IN_UNION_ROOM: @@ -1976,7 +1610,7 @@ static void Task_StartActivity(u8 taskId) else { LinkRfu_StopManagerBeforeEnteringChat(); - SetHostRfuGameData(ACTIVITY_CHAT | IN_UNION_ROOM, 0, 1); + SetHostRfuGameData(ACTIVITY_CHAT | IN_UNION_ROOM, 0, TRUE); } EnterUnionRoomChat(); break; @@ -1985,22 +1619,22 @@ static void Task_StartActivity(u8 taskId) CreateTrainerCardInBuffer(gBlockSendBuffer, FALSE); SetMainCallback2(CB2_ShowCard); break; - case ACTIVITY_PJUMP: - SetCableClubStateAndWarpCurrentMap(USING_MINIGAME, 5, 1); + case ACTIVITY_POKEMON_JUMP: + WarpForWirelessMinigame(USING_MINIGAME, 5, 1); StartPokemonJump(GetCursorSelectionMonId(), CB2_LoadMap); break; - case ACTIVITY_BCRUSH: - SetCableClubStateAndWarpCurrentMap(USING_BERRY_CRUSH, 9, 1); + case ACTIVITY_BERRY_CRUSH: + WarpForWirelessMinigame(USING_BERRY_CRUSH, 9, 1); StartBerryCrush(CB2_LoadMap); break; - case ACTIVITY_BPICK: - SetCableClubStateAndWarpCurrentMap(USING_MINIGAME, 5, 1); + case ACTIVITY_BERRY_PICK: + WarpForWirelessMinigame(USING_MINIGAME, 5, 1); StartDodrioBerryPicking(GetCursorSelectionMonId(), CB2_LoadMap); break; } DestroyTask(taskId); - gSpecialVar_Result = 1; + gSpecialVar_Result = LINKUP_SUCCESS; UnlockPlayerFieldControls(); } @@ -2012,7 +1646,7 @@ static void Task_RunScriptAndFadeToActivity(u8 taskId) switch (data[0]) { case 0: - gSpecialVar_Result = 1; + gSpecialVar_Result = LINKUP_SUCCESS; ScriptContext_Enable(); data[0]++; break; @@ -2051,23 +1685,24 @@ static void CreateTask_StartActivity(void) gTasks[taskId].data[0] = 0; } -void MEvent_CreateTask_Leader(u32 activity) +// Sending Wonder Card/News +void CreateTask_SendMysteryGift(u32 activity) { u8 taskId; - struct UnkStruct_Leader * dataPtr; + struct WirelessLink_Leader * data; - taskId = CreateTask(Task_MEvent_Leader, 0); - sUnionRoomMain.leader = dataPtr = (void *)(gTasks[taskId].data); + taskId = CreateTask(Task_SendMysteryGift, 0); + sWirelessLinkMain.leader = data = (void *)(gTasks[taskId].data); - dataPtr->state = 0; - dataPtr->textState = 0; - dataPtr->activity = activity; - gSpecialVar_Result = 0; + data->state = 0; + data->textState = 0; + data->activity = activity; + gSpecialVar_Result = LINKUP_ONGOING; } -static void Task_MEvent_Leader(u8 taskId) +static void Task_SendMysteryGift(u8 taskId) { - struct UnkStruct_Leader * data = sUnionRoomMain.leader; + struct WirelessLink_Leader * data = sWirelessLinkMain.leader; struct WindowTemplate winTemplate; s32 val; @@ -2076,7 +1711,7 @@ static void Task_MEvent_Leader(u8 taskId) case 0: sPlayerCurrActivity = data->activity; sPlayerActivityGroupSize = 2; - SetHostRfuGameData(data->activity, 0, 0); + SetHostRfuGameData(data->activity, 0, FALSE); SetHostRfuWonderFlags(FALSE, FALSE); SetWirelessCommType1(); OpenLink(); @@ -2084,17 +1719,17 @@ static void Task_MEvent_Leader(u8 taskId) data->state = 1; break; case 1: - data->field_4 = AllocZeroed(4 * sizeof(struct UnkStruct_x1C)); - data->field_0 = AllocZeroed(UROOM_MAX_PARTY_SIZE * sizeof(struct UnkStruct_x20)); - data->field_8 = AllocZeroed(UROOM_MAX_PARTY_SIZE * sizeof(struct UnkStruct_x20)); - BlankUnkStruct_x1CArray(data->field_4->arr, 4); - BlankUnkStruct_x20Array(data->field_0->arr, UROOM_MAX_PARTY_SIZE); - CopyHostRfuGameDataAndUsername(&data->field_0->arr[0].gname_uname.gname, data->field_0->arr[0].gname_uname.uname); - data->field_0->arr[0].field_18 = 0; - data->field_0->arr[0].groupScheduledAnim = UNION_ROOM_SPAWN_IN; - data->field_0->arr[0].field_1A_1 = 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->players, 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_List_PossibleGroupMembers; winTemplate.baseBlock = GetMysteryGiftBaseBlock(); @@ -2109,8 +1744,8 @@ static void Task_MEvent_Leader(u8 taskId) data->state = 2; break; case 2: - StringCopy(gStringVar1, sUnionRoomActivityStringPtrs[sPlayerCurrActivity]); - StringExpandPlaceholders_AwaitingCommFromAnother(gStringVar4, sPlayerCurrActivity); + StringCopy(gStringVar1, sLinkGroupActivityNameTexts[sPlayerCurrActivity]); + GetAwaitingCommunicationText(gStringVar4, sPlayerCurrActivity); data->state = 3; break; case 3: @@ -2126,9 +1761,9 @@ static void Task_MEvent_Leader(u8 taskId) } break; case 6: - if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, gText_UR_LinkWithFriendDropped)) + if (PrintMysteryGiftMenuMessage(&data->textState, gText_UR_LinkWithFriendDropped)) { - data->playerCount = UnionRoomLeaderField0CompactionAndCount(data->field_0); + data->playerCount = LeaderPrunePlayerList(data->playerList); RedrawListMenu(data->listTaskId); data->state = 2; } @@ -2137,51 +1772,51 @@ static void Task_MEvent_Leader(u8 taskId) data->state = 7; break; case 7: - switch (mevent_message_print_and_prompt_yes_no(&data->textState, (u16 *)&data->messageWindowId, FALSE, gStringVar4)) + switch (DoMysteryGiftYesNo(&data->textState, &data->yesNoWindowId, FALSE, 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->field_19 = 5; - SendRfuStatusToPartner(5, ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.compatibility.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.uname); + data->joinRequestAnswer = RFU_STATUS_JOIN_GROUP_OK; + 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: - data->field_19 = 6; - SendRfuStatusToPartner(6, ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.compatibility.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.uname); + case MENU_B_PRESSED: + data->joinRequestAnswer = RFU_STATUS_JOIN_GROUP_NO; + 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.compatibility.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.uname); - if (val == 1) + 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->field_19 == 5) + 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, gText_UR_AnOKWasSentToPlayer); data->state = 9; LinkRfu_StopManagerAndFinalizeSlots(); } else { - RequestDisconnectSlotByTrainerNameAndId(data->field_0->arr[data->playerCount].gname_uname.uname, ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.compatibility.playerTrainerId)); - data->field_0->arr[data->playerCount].groupScheduledAnim = UNION_ROOM_SPAWN_NONE; - UnionRoomLeaderField0CompactionAndCount(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; } - data->field_19 = 0; + data->joinRequestAnswer = 0; } - else if (val == 2) + else if (val == 2) // Member disconnected { RfuSetStatus(RFU_STATUS_OK, 0); data->state = 2; @@ -2217,21 +1852,21 @@ 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: // Please start over from the beginning. - if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, gText_UR_PleaseStartOver)) + if (PrintMysteryGiftMenuMessage(&data->textState, gText_UR_PleaseStartOver)) { DestroyTask(taskId); - gSpecialVar_Result = 5; + gSpecialVar_Result = LINKUP_FAILED; } break; case 15: - if (RfuGetStatus() == 1 || RfuGetStatus() == 2) + if (RfuGetStatus() == RFU_STATUS_FATAL_ERROR || RfuGetStatus() == RFU_STATUS_CONNECTION_ERROR) { data->state = 13; } @@ -2246,9 +1881,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; @@ -2259,36 +1894,36 @@ static void Task_MEvent_Leader(u8 taskId) } } -void MEvent_CreateTask_CardOrNewsWithFriend(u32 activity) +void CreateTask_LinkMysteryGiftWithFriend(u32 activity) { u8 taskId; - struct UnkStruct_Group * dataPtr; + struct WirelessLink_Group * data; taskId = CreateTask(Task_CardOrNewsWithFriend, 0); - sUnionRoomMain.group = dataPtr = (void *)(gTasks[taskId].data); - sGroup = dataPtr; + sWirelessLinkMain.group = data = (void *)(gTasks[taskId].data); + sGroup = data; - dataPtr->state = 0; - dataPtr->textState = 0; - dataPtr->cardOrNews = activity - ACTIVITY_WCARD2; // 0: Card; 1: News - gSpecialVar_Result = 0; + data->state = 0; + data->textState = 0; + data->isWonderNews = activity - ACTIVITY_WONDER_CARD; // 0: Card; 1: News + gSpecialVar_Result = LINKUP_ONGOING; } static void Task_CardOrNewsWithFriend(u8 taskId) { s32 id; - struct WindowTemplate winTemplate1, winTemplate2; - struct UnkStruct_Group * data = sUnionRoomMain.group; + struct WindowTemplate listWinTemplate; + struct WirelessLink_Group * data = sWirelessLinkMain.group; switch (data->state) { case 0: - SetHostRfuGameData(data->cardOrNews + ACTIVITY_WCARD2, 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: @@ -2296,15 +1931,15 @@ static void Task_CardOrNewsWithFriend(u8 taskId) data->state = 2; break; case 2: - BlankUnkStruct_x1CArray(data->field_4->arr, 4); - BlankUnkStruct_x20Array(data->field_0->arr, 16); - data->listenTaskId = CreateTask_ListenForPartnersWithCompatibleSerialNos(data->field_4, data->cardOrNews + LINK_GROUP_WONDER_CARD); + ClearIncomingPlayerList(data->incomingPlayerList->players, 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 = sWindowTemplate_MysteryGiftList; - winTemplate1.baseBlock = GetMysteryGiftBaseBlock(); - data->listWindowId = AddWindow(&winTemplate1); + listWinTemplate = sWindowTemplate_GroupList; + listWinTemplate.baseBlock = GetMysteryGiftBaseBlock(); + data->listWindowId = AddWindow(&listWinTemplate); - data->playerNameAndIdWindowId = AddWindow(&sWindowTemplate_MysteryGiftPlayerNameAndId); + data->playerNameAndIdWindowId = AddWindow(&sWindowTemplate_PlayerNameAndId); MG_DrawTextBorder(data->listWindowId); gMultiuseListMenuTemplate = sListMenuTemplate_UnionRoomGroups; @@ -2332,20 +1967,19 @@ static void Task_CardOrNewsWithFriend(u8 taskId) break; case 0: id = ListMenu_ProcessInput(data->listTaskId); - if (JOY_NEW(A_BUTTON) && id != -1) + if (JOY_NEW(A_BUTTON) && id != LIST_NOTHING_CHOSEN) { // this unused variable along with the assignment is needed to match - u32 unusedVar; - unusedVar = 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.startedActivity) + 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); - IntlConvPartnerUname(gStringVar1, data->field_0->arr[data->leaderId]); - CreateTask_RfuReconnectWithParent(data->field_0->arr[data->leaderId].gname_uname.uname, ReadAsU16(data->field_0->arr[data->leaderId].gname_uname.gname.compatibility.playerTrainerId)); + CopyAndTranslatePlayerName2(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; } @@ -2363,24 +1997,24 @@ static void Task_CardOrNewsWithFriend(u8 taskId) break; case 4: AddTextPrinterToWindow1(gText_UR_AwaitingPlayersResponse); - IntlConvPartnerUname(gStringVar1, data->field_0->arr[data->leaderId]); + CopyAndTranslatePlayerName2(gStringVar1, data->playerList->players[data->leaderId]); data->state = 5; break; case 5: if (gReceivedRemoteLinkPlayers) { - sPlayerCurrActivity = data->field_0->arr[data->leaderId].gname_uname.gname.activity; + sPlayerCurrActivity = data->playerList->players[data->leaderId].rfu.data.activity; data->state = 10; } switch (RfuGetStatus()) { - case 1: - case 2: - case 6: + case RFU_STATUS_FATAL_ERROR: + case RFU_STATUS_CONNECTION_ERROR: + case RFU_STATUS_JOIN_GROUP_NO: data->state = 8; break; - case 5: + case RFU_STATUS_JOIN_GROUP_OK: AddTextPrinterToWindow1(gText_UR_PlayerSentBackOK); RfuSetStatus(RFU_STATUS_OK, 0); break; @@ -2394,17 +2028,17 @@ 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: - if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, gTexts_UR_LinkDropped[RfuGetStatus()])) + if (PrintMysteryGiftMenuMessage(&data->textState, gTexts_UR_LinkDropped[RfuGetStatus()])) { DestroyWirelessStatusIndicatorSprite(); DestroyTask(taskId); LinkRfu_Shutdown(); - gSpecialVar_Result = 5; + gSpecialVar_Result = LINKUP_FAILED; } break; case 7: @@ -2412,7 +2046,7 @@ static void Task_CardOrNewsWithFriend(u8 taskId) AddTextPrinterToWindow1(gText_UR_PleaseStartOver); DestroyTask(taskId); LinkRfu_Shutdown(); - gSpecialVar_Result = 5; + gSpecialVar_Result = LINKUP_FAILED; break; case 11: data->state++; @@ -2425,36 +2059,36 @@ static void Task_CardOrNewsWithFriend(u8 taskId) } } -void MEvent_CreateTask_CardOrNewsOverWireless(u32 activity) +void CreateTask_LinkMysteryGiftOverWireless(u32 activity) { u8 taskId; - struct UnkStruct_Group * dataPtr; + struct WirelessLink_Group * data; taskId = CreateTask(Task_CardOrNewsOverWireless, 0); - sUnionRoomMain.group = dataPtr = (void *)(gTasks[taskId].data); - sGroup = dataPtr; + sWirelessLinkMain.group = data = (void *)(gTasks[taskId].data); + sGroup = data; - dataPtr->state = 0; - dataPtr->textState = 0; - dataPtr->cardOrNews = activity - ACTIVITY_WCARD2; // 0: Card; 1: News - gSpecialVar_Result = 0; + data->state = 0; + data->textState = 0; + data->isWonderNews = activity - ACTIVITY_WONDER_CARD; // 0: Card; 1: News + gSpecialVar_Result = LINKUP_ONGOING; } static void Task_CardOrNewsOverWireless(u8 taskId) { s32 id; struct WindowTemplate winTemplate; - struct UnkStruct_Group * data = sUnionRoomMain.group; + struct WirelessLink_Group * data = sWirelessLinkMain.group; switch (data->state) { case 0: - SetHostRfuGameData(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: @@ -2462,13 +2096,13 @@ static void Task_CardOrNewsOverWireless(u8 taskId) data->state = 2; break; case 2: - BlankUnkStruct_x1CArray(data->field_4->arr, 4); - BlankUnkStruct_x20Array(data->field_0->arr, 16); - data->listenTaskId = CreateTask_ListenForPartnersWithSerial7F7D(data->field_4, data->cardOrNews + LINK_GROUP_WONDER_CARD); + ClearIncomingPlayerList(data->incomingPlayerList->players, 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 = sWindowTemplate_MysteryGiftList; + winTemplate = sWindowTemplate_GroupList; winTemplate.baseBlock = GetMysteryGiftBaseBlock(); data->listWindowId = AddWindow(&winTemplate); @@ -2490,23 +2124,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.startedActivity) + if (data->playerList->players[0].groupScheduledAnim == UNION_ROOM_SPAWN_IN && !data->playerList->players[0].rfu.data.startedActivity) { - if (GetGnameWonderFlagByLinkGroup(&data->field_0->arr[0].gname_uname.gname, data->cardOrNews + 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.uname, ReadAsU16(data->field_0->arr[0].gname_uname.gname.compatibility.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; } @@ -2528,24 +2162,24 @@ static void Task_CardOrNewsOverWireless(u8 taskId) break; case 4: AddTextPrinterToWindow1(gText_UR_AwaitingResponseFromWirelessSystem); - IntlConvPartnerUname(gStringVar1, data->field_0->arr[data->leaderId]); + CopyAndTranslatePlayerName2(gStringVar1, data->playerList->players[data->leaderId]); data->state = 5; break; case 5: if (gReceivedRemoteLinkPlayers) { - sPlayerCurrActivity = data->field_0->arr[data->leaderId].gname_uname.gname.activity; + sPlayerCurrActivity = data->playerList->players[data->leaderId].rfu.data.activity; data->state = 12; } switch (RfuGetStatus()) { - case 1: - case 2: - case 6: + case RFU_STATUS_FATAL_ERROR: + case RFU_STATUS_CONNECTION_ERROR: + case RFU_STATUS_JOIN_GROUP_NO: data->state = 8; break; - case 5: + case RFU_STATUS_JOIN_GROUP_OK: AddTextPrinterToWindow1(gText_UR_WirelessLinkEstablished); RfuSetStatus(RFU_STATUS_OK, 0); break; @@ -2555,37 +2189,37 @@ 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: - if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, gText_UR_WirelessLinkDropped)) + if (PrintMysteryGiftMenuMessage(&data->textState, gText_UR_WirelessLinkDropped)) { DestroyWirelessStatusIndicatorSprite(); DestroyTask(taskId); LinkRfu_Shutdown(); - gSpecialVar_Result = 5; + gSpecialVar_Result = LINKUP_FAILED; } break; case 7: - if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, gText_UR_WirelessSearchCanceled)) + if (PrintMysteryGiftMenuMessage(&data->textState, gText_UR_WirelessSearchCanceled)) { DestroyWirelessStatusIndicatorSprite(); DestroyTask(taskId); LinkRfu_Shutdown(); - gSpecialVar_Result = 5; + gSpecialVar_Result = LINKUP_FAILED; } break; case 11: - if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, gTexts_UR_NoWonderShared[data->cardOrNews])) + if (PrintMysteryGiftMenuMessage(&data->textState, gTexts_UR_NoWonderShared[data->isWonderNews])) { DestroyWirelessStatusIndicatorSprite(); DestroyTask(taskId); @@ -2604,24 +2238,24 @@ static void Task_CardOrNewsOverWireless(u8 taskId) } } -void UnionRoomSpecial(void) +void RunUnionRoom(void) { - struct UnkStruct_URoom * dataPtr; + struct WirelessLink_URoom * uroom; ResetHostRfuGameData(); CreateTask(Task_RunUnionRoom, 10); // dumb line needed to match - sUnionRoomMain.uRoom = sUnionRoomMain.uRoom; + sWirelessLinkMain.uRoom = sWirelessLinkMain.uRoom; - dataPtr = AllocZeroed(sizeof(*sUnionRoomMain.uRoom)); - sUnionRoomMain.uRoom = dataPtr; - sURoom = dataPtr; + uroom = AllocZeroed(sizeof(*sWirelessLinkMain.uRoom)); + sWirelessLinkMain.uRoom = uroom; + sURoom = uroom; - dataPtr->state = 0; - dataPtr->textState = 0; - dataPtr->field_10 = 0; - dataPtr->field_12 = 0; + uroom->state = UR_STATE_INIT; + uroom->textState = 0; + uroom->unknown = 0; + uroom->unreadPlayerId = 0; gSpecialVar_Result = 0; ListMenuLoadStdPalAt(0xD0, 1); @@ -2632,144 +2266,148 @@ static u16 ReadAsU16(const u8 *ptr) return (ptr[1] << 8) | (ptr[0]); } -static void UnionRoom_ScheduleFieldMessageWithFollowupState(u32 nextState, const u8 *src) +static void ScheduleFieldMessageWithFollowupState(u32 nextState, const u8 *src) { - struct UnkStruct_URoom * data = sUnionRoomMain.uRoom; + struct WirelessLink_URoom * uroom = sWirelessLinkMain.uRoom; - data->state = 8; - data->stateAfterPrint = nextState; + uroom->state = UR_STATE_PRINT_MSG; + uroom->stateAfterPrint = nextState; if (src != gStringVar4) StringExpandPlaceholders(gStringVar4, src); } -static void UnionRoom_ScheduleFieldMessageAndExit(const u8 *src) +static void ScheduleFieldMessageAndExit(const u8 *src) { - struct UnkStruct_URoom * data = sUnionRoomMain.uRoom; + struct WirelessLink_URoom * uroom = sWirelessLinkMain.uRoom; - data->state = 26; + uroom->state = UR_STATE_PRINT_AND_EXIT; if (src != gStringVar4) StringExpandPlaceholders(gStringVar4, src); } -static void BackUpURoomField0ToDecompressionBuffer(struct UnkStruct_URoom * data) +static void CopyPlayerListToBuffer(struct WirelessLink_URoom * uroom) { - memcpy(&gDecompressionBuffer[0x3F00], data->field_0, UROOM_MAX_GROUP_COUNT * sizeof(struct UnkStruct_x20)); + memcpy(&gDecompressionBuffer[sizeof(gDecompressionBuffer) - (MAX_UNION_ROOM_LEADERS * sizeof(struct RfuPlayer))], + uroom->playerList, + MAX_UNION_ROOM_LEADERS * sizeof(struct RfuPlayer)); } -static void RestoreURoomField0FromDecompressionBuffer(struct UnkStruct_URoom * data) +static void CopyPlayerListFromBuffer(struct WirelessLink_URoom * uroom) { - memcpy(data->field_0, &gDecompressionBuffer[0x3F00], UROOM_MAX_GROUP_COUNT * sizeof(struct UnkStruct_x20)); + 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) { u32 id = 0; - s32 var5 = 0; + s32 input = 0; s32 playerGender = MALE; - struct UnkStruct_URoom * data = sUnionRoomMain.uRoom; + struct WirelessLink_URoom * uroom = sWirelessLinkMain.uRoom; s16 *taskData = gTasks[taskId].data; - switch (data->state) + switch (uroom->state) { - case 0: - data->field_4 = AllocZeroed(RFU_CHILD_MAX * sizeof(struct UnkStruct_x1C)); - data->field_C = AllocZeroed(RFU_CHILD_MAX * sizeof(struct UnkStruct_x1C)); - data->field_0 = AllocZeroed(UROOM_MAX_GROUP_COUNT * sizeof(struct UnkStruct_x20)); - data->field_8 = AllocZeroed(sizeof(struct UnkStruct_x20)); - BlankUnkStruct_x20Array(data->field_0->arr, UROOM_MAX_GROUP_COUNT); + case UR_STATE_INIT: + 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); sPlayerCurrActivity = IN_UNION_ROOM; - data->field_20 = CreateTask_SearchForChildOrParent(data->field_C, data->field_4, LINK_GROUP_UNION_ROOM_RESUME); - ZeroUnionObjWork(data->unionObjs); + uroom->searchTaskId = CreateTask_SearchForChildOrParent(uroom->incomingParentList, uroom->incomingChildList, LINK_GROUP_UNION_ROOM_RESUME); + ZeroUnionObjWork(uroom->objects); MakeGroupAssemblyAreasPassable(); - data->state = 1; + uroom->state = UR_STATE_INIT_OBJECTS; break; - case 1: - CreateGroupMemberObjectsInvisible(data->spriteIds, taskData[0]); + case UR_STATE_INIT_OBJECTS: + CreateGroupMemberObjectsInvisible(uroom->spriteIds, taskData[0]); if (++taskData[0] == 8) - data->state = 2; + uroom->state = UR_STATE_INIT_LINK; break; - case 2: - SetHostRfuGameData(IN_UNION_ROOM, 0, 0); + case UR_STATE_INIT_LINK: + SetHostRfuGameData(IN_UNION_ROOM, 0, FALSE); SetTradeBoardRegisteredMonInfo(sUnionRoomTrade.type, sUnionRoomTrade.playerSpecies, sUnionRoomTrade.playerLevel); SetWirelessCommType1(); OpenLink(); InitializeRfuLinkManager_EnterUnionRoom(); - BlankUnkStruct_x20Array(&data->field_8->arr[0], 1); - BlankUnkStruct_x1CArray(data->field_4->arr, 4); - BlankUnkStruct_x1CArray(data->field_C->arr, 4); + ClearRfuPlayerList(&uroom->spawnPlayer->players[0], 1); + ClearIncomingPlayerList(uroom->incomingChildList->players, RFU_CHILD_MAX); + ClearIncomingPlayerList(uroom->incomingParentList->players, RFU_CHILD_MAX); gSpecialVar_Result = 0; - data->state = 3; + uroom->state = UR_STATE_CHECK_SELECTING_MON; break; - case 3: + case UR_STATE_CHECK_SELECTING_MON: if ((GetPartyMenuType() == PARTY_MENU_TYPE_UNION_ROOM_REGISTER || GetPartyMenuType() == PARTY_MENU_TYPE_UNION_ROOM_TRADE) - && sUnionRoomTrade.field_0 != 0) + && sUnionRoomTrade.state != URTRADE_STATE_NONE) { id = GetCursorSelectionMonId(); - switch (sUnionRoomTrade.field_0) + switch (sUnionRoomTrade.state) { - case 1: + case URTRADE_STATE_REGISTERING: UpdateGameData_SetActivity(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); if (id >= PARTY_SIZE) { ResetUnionRoomTrade(&sUnionRoomTrade); - SetTradeBoardRegisteredMonInfo(0, 0, 0); - UnionRoom_ScheduleFieldMessageAndExit(gText_UR_RegistrationCanceled); + SetTradeBoardRegisteredMonInfo(TYPE_NORMAL, SPECIES_NONE, 0); + ScheduleFieldMessageAndExit(gText_UR_RegistrationCanceled); } else if (!RegisterTradeMonAndGetIsEgg(GetCursorSelectionMonId(), &sUnionRoomTrade)) { - UnionRoom_ScheduleFieldMessageWithFollowupState(52, gText_UR_ChooseRequestedMonType); + ScheduleFieldMessageWithFollowupState(UR_STATE_REGISTER_REQUEST_TYPE, gText_UR_ChooseRequestedMonType); } else { - data->state = 55; + uroom->state = UR_STATE_REGISTER_COMPLETE; } break; - case 2: - RestoreURoomField0FromDecompressionBuffer(data); - taskData[1] = sUnionRoomTrade.field_8; + case URTRADE_STATE_OFFERING: + CopyPlayerListFromBuffer(uroom); + taskData[1] = sUnionRoomTrade.offerPlayerId; if (id >= PARTY_SIZE) { - UnionRoom_ScheduleFieldMessageAndExit(gText_UR_TradeCanceled); + ScheduleFieldMessageAndExit(gText_UR_TradeCanceled); } else { UpdateGameData_SetActivity(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); sPlayerCurrActivity = ACTIVITY_TRADE | IN_UNION_ROOM; RegisterTradeMon(GetCursorSelectionMonId(), &sUnionRoomTrade); - data->state = 51; + uroom->state = UR_STATE_TRADE_OFFER_MON; } break; } - sUnionRoomTrade.field_0 = 0; + sUnionRoomTrade.state = URTRADE_STATE_NONE; } else { - data->state = 4; + uroom->state = UR_STATE_MAIN; } break; - case 4: + case UR_STATE_MAIN: if (gSpecialVar_Result != 0) { - if (gSpecialVar_Result == 9) + if (gSpecialVar_Result == UR_INTERACT_ATTENDANT) { UpdateGameData_SetActivity(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); PlaySE(SE_PC_LOGIN); StringCopy(gStringVar1, gSaveBlock2Ptr->playerName); - data->state = 42; + uroom->state = UR_STATE_INTERACT_WITH_ATTENDANT; gSpecialVar_Result = 0; } - else if (gSpecialVar_Result == 11) + else if (gSpecialVar_Result == UR_INTERACT_START_MENU) { UpdateGameData_SetActivity(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); - data->state = 23; + uroom->state = UR_STATE_WAIT_FOR_START_MENU; gSpecialVar_Result = 0; } - else + else // UR_INTERACT_PLAYER_# (1-8) { taskData[0] = 0; taskData[1] = gSpecialVar_Result - 1; - data->state = 24; + uroom->state = UR_STATE_INTERACT_WITH_PLAYER; gSpecialVar_Result = 0; } } @@ -2777,81 +2415,81 @@ static void Task_RunUnionRoom(u8 taskId) { if (JOY_NEW(A_BUTTON)) { - if (RfuUnionTool_GetGroupAndMemberInFrontOfPlayer(data->field_0, &taskData[0], &taskData[1], data->spriteIds)) + if (TryInteractWithUnionRoomMember(uroom->playerList, &taskData[0], &taskData[1], uroom->spriteIds)) { PlaySE(SE_SELECT); - UR_EnableScriptContext2AndFreezeObjectEvents(); - data->state = 24; + StartScriptInteraction(); + uroom->state = UR_STATE_INTERACT_WITH_PLAYER; break; } - else if (PlayerIsTalkingToUnionRoomAide()) + else if (IsPlayerFacingTradingBoard()) { UpdateGameData_SetActivity(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); PlaySE(SE_PC_LOGIN); - UR_EnableScriptContext2AndFreezeObjectEvents(); + StartScriptInteraction(); StringCopy(gStringVar1, gSaveBlock2Ptr->playerName); - data->state = 45; + uroom->state = UR_STATE_CHECK_TRADING_BOARD; break; } } switch (HandlePlayerListUpdate()) { - case 1: + case PLIST_NEW_PLAYER: PlaySE(SE_NOTE_C); - case 2: - ScheduleUnionRoomPlayerRefresh(data); + case PLIST_RECENT_UPDATE: + ScheduleUnionRoomPlayerRefresh(uroom); break; - case 4: - data->state = 11; - UR_EnableScriptContext2AndFreezeObjectEvents(); - SetTradeBoardRegisteredMonInfo(0, 0, 0); - UpdateGameData_SetActivity(ACTIVITY_NPCTALK | IN_UNION_ROOM, GetActivePartnerSpriteGenderParam(data), FALSE); + case PLIST_CONTACTED: + uroom->state = UR_STATE_PLAYER_CONTACTED_YOU; + StartScriptInteraction(); + SetTradeBoardRegisteredMonInfo(TYPE_NORMAL, SPECIES_NONE, 0); + UpdateGameData_SetActivity(ACTIVITY_NPCTALK | IN_UNION_ROOM, GetActivePartnersInfo(uroom), FALSE); break; } - HandleUnionRoomPlayerRefresh(data); + HandleUnionRoomPlayerRefresh(uroom); } break; - case 23: + case UR_STATE_WAIT_FOR_START_MENU: if (!FuncIsActiveTask(Task_StartMenuHandleInput)) { - UpdateGameData_SetActivity(IN_UNION_ROOM, 0, FALSE); - data->state = 4; + UpdateGameData_SetActivity(ACTIVITY_NONE | IN_UNION_ROOM, 0, FALSE); + uroom->state = UR_STATE_MAIN; } break; - case 24: - UR_RunTextPrinters_CheckPrinter0Active(); - playerGender = GetUnionRoomPlayerGender(taskData[1], data->field_0); + case UR_STATE_INTERACT_WITH_PLAYER: + UR_RunTextPrinters(); + playerGender = GetUnionRoomPlayerGender(taskData[1], uroom->playerList); UpdateGameData_SetActivity(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); - switch (UnionRoomGetPlayerInteractionResponse(data->field_0, taskData[0], taskData[1], playerGender)) + switch (UnionRoomGetPlayerInteractionResponse(uroom->playerList, taskData[0], taskData[1], playerGender)) { - case 0: - data->state = 26; + case 0: // Player is or was just doing an activity + uroom->state = UR_STATE_PRINT_AND_EXIT; break; - case 1: - TryConnectToUnionRoomParent(data->field_0->arr[taskData[1]].gname_uname.uname, &data->field_0->arr[taskData[1]].gname_uname.gname, sPlayerCurrActivity); - data->field_12 = id; // Should be just 0, but won't match any other way. - data->state = 25; + case 1: // Link communicating + TryConnectToUnionRoomParent(uroom->playerList->players[taskData[1]].rfu.name, &uroom->playerList->players[taskData[1]].rfu.data, sPlayerCurrActivity); + uroom->unreadPlayerId = id; // Should be just 0, but won't match any other way. + uroom->state = UR_STATE_TRY_COMMUNICATING; break; - case 2: - UnionRoom_ScheduleFieldMessageWithFollowupState(19, gStringVar4); + case 2: // Ask to join chat + ScheduleFieldMessageWithFollowupState(UR_STATE_RECV_JOIN_CHAT_REQUEST, gStringVar4); break; } break; - case 25: - UR_RunTextPrinters_CheckPrinter0Active(); + case UR_STATE_TRY_COMMUNICATING: + UR_RunTextPrinters(); switch (RfuGetStatus()) { - case 4: - HandleCancelTrade(TRUE); - data->state = 4; + case RFU_STATUS_NEW_CHILD_DETECTED: + HandleCancelActivity(TRUE); + uroom->state = UR_STATE_MAIN; break; - case 1: - case 2: + case RFU_STATUS_FATAL_ERROR: + case RFU_STATUS_CONNECTION_ERROR: if (IsUnionRoomListenTaskActive() == TRUE) - UnionRoom_ScheduleFieldMessageAndExit(gText_UR_TrainerAppearsBusy); + ScheduleFieldMessageAndExit(gText_UR_TrainerAppearsBusy); else - UnionRoom_ScheduleFieldMessageWithFollowupState(30, gText_UR_TrainerAppearsBusy); + ScheduleFieldMessageWithFollowupState(UR_STATE_CANCEL_ACTIVITY_LINK_ERROR, gText_UR_TrainerAppearsBusy); sPlayerCurrActivity = IN_UNION_ROOM; break; @@ -2861,138 +2499,141 @@ static void Task_RunUnionRoom(u8 taskId) { CreateTrainerCardInBuffer(gBlockSendBuffer, TRUE); CreateTask(Task_ExchangeCards, 5); - data->state = 38; + uroom->state = UR_STATE_COMMUNICATING_WAIT_FOR_DATA; } break; - case 38: + case UR_STATE_COMMUNICATING_WAIT_FOR_DATA: if (!FuncIsActiveTask(Task_ExchangeCards)) { if (sPlayerCurrActivity == (ACTIVITY_TRADE | IN_UNION_ROOM)) - UnionRoom_ScheduleFieldMessageWithFollowupState(31, gText_UR_AwaitingPlayersResponseAboutTrade); + ScheduleFieldMessageWithFollowupState(UR_STATE_SEND_TRADE_REQUST, gText_UR_AwaitingPlayersResponseAboutTrade); else - data->state = 5; + uroom->state = UR_STATE_DO_SOMETHING_PROMPT; } break; - case 30: + case UR_STATE_CANCEL_ACTIVITY_LINK_ERROR: if (!gReceivedRemoteLinkPlayers) { - HandleCancelTrade(FALSE); - UpdateUnionGroupMemberFacing(taskData[0], taskData[1], data->field_0); - data->state = 2; + HandleCancelActivity(FALSE); + UpdateUnionGroupMemberFacing(taskData[0], taskData[1], uroom->playerList); + uroom->state = UR_STATE_INIT_LINK; } break; - case 5: - id = ConvPartnerUnameAndGetWhetherMetAlready(&data->field_0->arr[taskData[1]]); - playerGender = GetUnionRoomPlayerGender(taskData[1], data->field_0); - UnionRoom_ScheduleFieldMessageWithFollowupState(6, gTexts_UR_HiDoSomething[id][playerGender]); + case UR_STATE_DO_SOMETHING_PROMPT: + id = ConvPartnerUnameAndGetWhetherMetAlready(&uroom->playerList->players[taskData[1]]); + playerGender = GetUnionRoomPlayerGender(taskData[1], uroom->playerList); + ScheduleFieldMessageWithFollowupState(UR_STATE_HANDLE_DO_SOMETHING_PROMPT_INPUT, gTexts_UR_HiDoSomething[id][playerGender]); break; - case 6: - var5 = ListMenuHandler_AllItemsAvailable(&data->textState, &data->topListMenuWindowId, &data->topListMenuListMenuId, &sWindowTemplate_InviteToActivity, &sListMenuTemplate_InviteToActivity); - if (var5 != -1) + case UR_STATE_HANDLE_DO_SOMETHING_PROMPT_INPUT: + input = ListMenuHandler_AllItemsAvailable(&uroom->textState, + &uroom->topListMenuWindowId, + &uroom->topListMenuId, + &sWindowTemplate_InviteToActivity, + &sListMenuTemplate_InviteToActivity); + if (input != LIST_NOTHING_CHOSEN) { if (!gReceivedRemoteLinkPlayers) { - data->state = 28; + uroom->state = UR_STATE_TRAINER_APPEARS_BUSY; } else { - data->partnerYesNoResponse = 0; - playerGender = GetUnionRoomPlayerGender(taskData[1], data->field_0); - if (var5 == -2 || var5 == IN_UNION_ROOM) + uroom->partnerYesNoResponse = 0; + playerGender = GetUnionRoomPlayerGender(taskData[1], uroom->playerList); + if (input == LIST_CANCEL || input == IN_UNION_ROOM) { - data->playerSendBuffer[0] = IN_UNION_ROOM; - Rfu_SendPacket(data->playerSendBuffer); + uroom->playerSendBuffer[0] = IN_UNION_ROOM; + Rfu_SendPacket(uroom->playerSendBuffer); StringCopy(gStringVar4, gTexts_UR_IfYouWantToDoSomething[gLinkPlayers[0].gender]); - data->state = 32; + uroom->state = UR_STATE_REQUEST_DECLINED; } else { - sPlayerCurrActivity = var5; - sPlayerActivityGroupSize = (u32)(var5) >> 8; - if (sPlayerCurrActivity == (ACTIVITY_BATTLE | IN_UNION_ROOM) && !HasAtLeastTwoMonsOfLevel30OrLower()) + sPlayerCurrActivity = input; + sPlayerActivityGroupSize = (u32)(input) >> 8; // Extract capacity from sInviteToActivityMenuItems + if (sPlayerCurrActivity == (ACTIVITY_BATTLE_SINGLE | IN_UNION_ROOM) && !HasAtLeastTwoMonsOfLevel30OrLower()) { - UnionRoom_ScheduleFieldMessageWithFollowupState(5, gText_UR_NeedTwoMonsOfLevel30OrLower1); + ScheduleFieldMessageWithFollowupState(UR_STATE_DO_SOMETHING_PROMPT, gText_UR_NeedTwoMonsOfLevel30OrLower1); } else { - data->playerSendBuffer[0] = sPlayerCurrActivity | IN_UNION_ROOM; - Rfu_SendPacket(data->playerSendBuffer); - data->state = 27; + uroom->playerSendBuffer[0] = sPlayerCurrActivity | IN_UNION_ROOM; + Rfu_SendPacket(uroom->playerSendBuffer); + uroom->state = UR_STATE_SEND_ACTIVITY_REQUEST; } } } } break; - case 28: + case UR_STATE_TRAINER_APPEARS_BUSY: StringCopy(gStringVar4, gText_UR_TrainerBattleBusy); - data->state = 36; + uroom->state = UR_STATE_CANCEL_REQUEST_PRINT_MSG; break; - case 27: - PollPartnerYesNoResponse(data); - playerGender = GetUnionRoomPlayerGender(taskData[1], data->field_0); - id = GetResponseIdx_InviteToURoomActivity(data->playerSendBuffer[0] & 0x3F); - if (PrintOnTextbox(&data->textState, gTexts_UR_WaitOrShowCard[playerGender][id])) + case UR_STATE_SEND_ACTIVITY_REQUEST: + PollPartnerYesNoResponse(uroom); + playerGender = GetUnionRoomPlayerGender(taskData[1], uroom->playerList); + id = GetResponseIdx_InviteToURoomActivity(uroom->playerSendBuffer[0] & 0x3F); + if (PrintOnTextbox(&uroom->textState, gTexts_UR_WaitOrShowCard[playerGender][id])) { taskData[3] = 0; - data->state = 29; + uroom->state = UR_STATE_WAIT_FOR_RESPONSE_TO_REQUEST; } break; - case 32: + case UR_STATE_REQUEST_DECLINED: SetCloseLinkCallback(); - data->state = 36; + uroom->state = UR_STATE_CANCEL_REQUEST_PRINT_MSG; break; - case 31: - data->playerSendBuffer[0] = ACTIVITY_TRADE | IN_UNION_ROOM; - data->playerSendBuffer[1] = sUnionRoomTrade.species; - data->playerSendBuffer[2] = sUnionRoomTrade.level; - Rfu_SendPacket(data->playerSendBuffer); - data->state = 29; + case UR_STATE_SEND_TRADE_REQUST: + uroom->playerSendBuffer[0] = ACTIVITY_TRADE | IN_UNION_ROOM; + uroom->playerSendBuffer[1] = sUnionRoomTrade.species; + uroom->playerSendBuffer[2] = sUnionRoomTrade.level; + Rfu_SendPacket(uroom->playerSendBuffer); + uroom->state = UR_STATE_WAIT_FOR_RESPONSE_TO_REQUEST; break; - case 29: + case UR_STATE_WAIT_FOR_RESPONSE_TO_REQUEST: if (!gReceivedRemoteLinkPlayers) { StringCopy(gStringVar4, gText_UR_TrainerBattleBusy); - data->state = 28; + uroom->state = UR_STATE_TRAINER_APPEARS_BUSY; } else { - PollPartnerYesNoResponse(data); - if (data->partnerYesNoResponse == (ACTIVITY_ACCEPT | IN_UNION_ROOM)) + PollPartnerYesNoResponse(uroom); + if (uroom->partnerYesNoResponse == (ACTIVITY_ACCEPT | IN_UNION_ROOM)) { if (sPlayerCurrActivity == ACTIVITY_CARD) { - ViewURoomPartnerTrainerCard(gStringVar4, data, MODE_CHILD); - data->state = 40; + ViewURoomPartnerTrainerCard(gStringVar4, uroom, MODE_CHILD); + uroom->state = UR_STATE_PRINT_CARD_INFO; } else { - data->state = 13; + uroom->state = UR_STATE_PRINT_START_ACTIVITY_MSG; } } - else if (data->partnerYesNoResponse == (ACTIVITY_DECLINE | IN_UNION_ROOM)) + else if (uroom->partnerYesNoResponse == (ACTIVITY_DECLINE | IN_UNION_ROOM)) { - data->state = 32; + uroom->state = UR_STATE_REQUEST_DECLINED; GetURoomActivityRejectMsg(gStringVar4, sPlayerCurrActivity | IN_UNION_ROOM, gLinkPlayers[0].gender); - sPlayerCurrActivity = 0; + sPlayerCurrActivity = ACTIVITY_NONE; } } break; - - case 7: - id = ConvPartnerUnameAndGetWhetherMetAlready(&data->field_0->arr[taskData[1]]); - playerGender = GetUnionRoomPlayerGender(taskData[1], data->field_0); - UnionRoom_ScheduleFieldMessageWithFollowupState(6, gTexts_UR_HiDoSomething[id][playerGender]); + case UR_STATE_DO_SOMETHING_PROMPT_2: + id = ConvPartnerUnameAndGetWhetherMetAlready(&uroom->playerList->players[taskData[1]]); + playerGender = GetUnionRoomPlayerGender(taskData[1], uroom->playerList); + ScheduleFieldMessageWithFollowupState(UR_STATE_HANDLE_DO_SOMETHING_PROMPT_INPUT, gTexts_UR_HiDoSomething[id][playerGender]); break; - case 40: - if (PrintOnTextbox(&data->textState, gStringVar4)) + case UR_STATE_PRINT_CARD_INFO: + if (PrintOnTextbox(&uroom->textState, gStringVar4)) { - data->state = 41; + uroom->state = UR_STATE_WAIT_FINISH_READING_CARD; SetLinkStandbyCallback(); - data->partnerYesNoResponse = 0; - data->recvActivityRequest[0] = 0; + uroom->partnerYesNoResponse = 0; + uroom->recvActivityRequest[0] = 0; } break; - case 41: + case UR_STATE_WAIT_FINISH_READING_CARD: if (IsLinkTaskFinished()) { if (GetMultiplayerId() == 0) @@ -3000,227 +2641,225 @@ static void Task_RunUnionRoom(u8 taskId) StringCopy(gStringVar1, gLinkPlayers[GetMultiplayerId() ^ 1].name); id = PlayerHasMetTrainerBefore(gLinkPlayers[1].trainerId, gLinkPlayers[1].name); StringExpandPlaceholders(gStringVar4, gTexts_UR_AwaitingResponse[id]); - data->state = 33; + uroom->state = UR_STATE_PRINT_CONTACT_MSG; } else { - data->state = 7; + uroom->state = UR_STATE_DO_SOMETHING_PROMPT_2; } } break; - case 19: - switch (UnionRoomHandleYesNo(&data->textState, FALSE)) + case UR_STATE_RECV_JOIN_CHAT_REQUEST: + switch (UnionRoomHandleYesNo(&uroom->textState, FALSE)) { - case 0: + case 0: // YES CopyBgTilemapBufferToVram(0); sPlayerCurrActivity = ACTIVITY_CHAT | IN_UNION_ROOM; UpdateGameData_SetActivity(ACTIVITY_CHAT | IN_UNION_ROOM, 0, TRUE); - TryConnectToUnionRoomParent(data->field_0->arr[taskData[1]].gname_uname.uname, &data->field_0->arr[taskData[1]].gname_uname.gname, sPlayerCurrActivity); - data->field_12 = taskData[1]; - data->state = 20; + TryConnectToUnionRoomParent(uroom->playerList->players[taskData[1]].rfu.name, &uroom->playerList->players[taskData[1]].rfu.data, sPlayerCurrActivity); + uroom->unreadPlayerId = taskData[1]; + uroom->state = UR_STATE_TRY_ACCEPT_CHAT_REQUEST_DELAY; taskData[3] = 0; break; - case 1: - case -1: - playerGender = GetUnionRoomPlayerGender(taskData[1], data->field_0); - UnionRoom_ScheduleFieldMessageAndExit(gTexts_UR_DeclineChat[playerGender]); + case 1: // NO + case MENU_B_PRESSED: + playerGender = GetUnionRoomPlayerGender(taskData[1], uroom->playerList); + ScheduleFieldMessageAndExit(gTexts_UR_DeclineChat[playerGender]); break; } break; - case 20: + case UR_STATE_TRY_ACCEPT_CHAT_REQUEST_DELAY: if (++taskData[2] > 60) { - data->state = 21; + uroom->state = UR_STATE_TRY_ACCEPT_CHAT_REQUEST; taskData[2] = 0; } break; - case 21: + case UR_STATE_TRY_ACCEPT_CHAT_REQUEST: switch (RfuGetStatus()) { - case 4: - HandleCancelTrade(TRUE); - data->state = 4; + case RFU_STATUS_NEW_CHILD_DETECTED: + HandleCancelActivity(TRUE); + uroom->state = UR_STATE_MAIN; break; - case 1: - case 2: - playerGender = GetUnionRoomPlayerGender(taskData[1], data->field_0); + case RFU_STATUS_FATAL_ERROR: + case RFU_STATUS_CONNECTION_ERROR: + playerGender = GetUnionRoomPlayerGender(taskData[1], uroom->playerList); UpdateGameData_SetActivity(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); if (IsUnionRoomListenTaskActive() == TRUE) - UnionRoom_ScheduleFieldMessageAndExit(gTexts_UR_ChatDeclined[playerGender]); + ScheduleFieldMessageAndExit(gTexts_UR_ChatDeclined[playerGender]); else - UnionRoom_ScheduleFieldMessageWithFollowupState(30, gTexts_UR_ChatDeclined[playerGender]); + ScheduleFieldMessageWithFollowupState(UR_STATE_CANCEL_ACTIVITY_LINK_ERROR, gTexts_UR_ChatDeclined[playerGender]); break; - case 3: - data->state = 22; + case RFU_STATUS_CHILD_SEND_COMPLETE: + uroom->state = UR_STATE_ACCEPT_CHAT_REQUEST; break; } taskData[3]++; break; - case 22: + case UR_STATE_ACCEPT_CHAT_REQUEST: if (RfuHasErrored()) { - playerGender = GetUnionRoomPlayerGender(taskData[1], data->field_0); + playerGender = GetUnionRoomPlayerGender(taskData[1], uroom->playerList); UpdateGameData_SetActivity(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); if (IsUnionRoomListenTaskActive() == TRUE) - UnionRoom_ScheduleFieldMessageAndExit(gTexts_UR_ChatDeclined[playerGender]); + ScheduleFieldMessageAndExit(gTexts_UR_ChatDeclined[playerGender]); else - UnionRoom_ScheduleFieldMessageWithFollowupState(30, gTexts_UR_ChatDeclined[playerGender]); + ScheduleFieldMessageWithFollowupState(UR_STATE_CANCEL_ACTIVITY_LINK_ERROR, gTexts_UR_ChatDeclined[playerGender]); } if (gReceivedRemoteLinkPlayers) - data->state = 16; + uroom->state = UR_STATE_START_ACTIVITY_FREE_UROOM; break; - case 11: + case UR_STATE_PLAYER_CONTACTED_YOU: PlaySE(SE_DING_DONG); StopUnionRoomLinkManager(); - data->state = 12; - data->recvActivityRequest[0] = 0; + uroom->state = UR_STATE_RECV_CONTACT_DATA; + uroom->recvActivityRequest[0] = 0; break; - case 12: + case UR_STATE_RECV_CONTACT_DATA: if (RfuHasErrored()) { - HandleCancelTrade(FALSE); - data->state = 2; + HandleCancelActivity(FALSE); + uroom->state = UR_STATE_INIT_LINK; } else if (gReceivedRemoteLinkPlayers) { CreateTrainerCardInBuffer(gBlockSendBuffer, TRUE); CreateTask(Task_ExchangeCards, 5); - data->state = 39; + uroom->state = UR_STATE_WAIT_FOR_CONTACT_DATA; } break; - case 39: - ReceiveUnionRoomActivityPacket(data); + case UR_STATE_WAIT_FOR_CONTACT_DATA: + ReceiveUnionRoomActivityPacket(uroom); if (!FuncIsActiveTask(Task_ExchangeCards)) { - data->state = 33; + uroom->state = UR_STATE_PRINT_CONTACT_MSG; StringCopy(gStringVar1, gLinkPlayers[1].name); id = PlayerHasMetTrainerBefore(gLinkPlayers[1].trainerId, gLinkPlayers[1].name); StringExpandPlaceholders(gStringVar4, gTexts_UR_PlayerContactedYou[id]); } break; - case 33: - ReceiveUnionRoomActivityPacket(data); - if (PrintOnTextbox(&data->textState, gStringVar4)) - data->state = 34; + case UR_STATE_PRINT_CONTACT_MSG: + ReceiveUnionRoomActivityPacket(uroom); + if (PrintOnTextbox(&uroom->textState, gStringVar4)) + uroom->state = UR_STATE_HANDLE_CONTACT_DATA; break; - case 34: - ReceiveUnionRoomActivityPacket(data); - if (UnionRoom_HandleContactFromOtherPlayer(data) && JOY_NEW(B_BUTTON)) + case UR_STATE_HANDLE_CONTACT_DATA: + ReceiveUnionRoomActivityPacket(uroom); + if (HandleContactFromOtherPlayer(uroom) && JOY_NEW(B_BUTTON)) { Rfu_DisconnectPlayerById(1); StringCopy(gStringVar4, gText_UR_ChatEnded); - data->state = 36; + uroom->state = UR_STATE_CANCEL_REQUEST_PRINT_MSG; } break; - case 35: - // You said yes - UnionRoom_ScheduleFieldMessageWithFollowupState(9, gStringVar4); + case UR_STATE_RECV_ACTIVITY_REQUEST: + ScheduleFieldMessageWithFollowupState(UR_STATE_HANDLE_ACTIVITY_REQUEST, gStringVar4); break; - case 9: - switch (UnionRoomHandleYesNo(&data->textState, FALSE)) + case UR_STATE_HANDLE_ACTIVITY_REQUEST: + switch (UnionRoomHandleYesNo(&uroom->textState, FALSE)) { - case 0: - data->playerSendBuffer[0] = ACTIVITY_ACCEPT | IN_UNION_ROOM; + case 0: // ACCEPT + uroom->playerSendBuffer[0] = ACTIVITY_ACCEPT | IN_UNION_ROOM; if (sPlayerCurrActivity == (ACTIVITY_CHAT | IN_UNION_ROOM)) - UpdateGameData_SetActivity(sPlayerCurrActivity | IN_UNION_ROOM, GetSinglePartnerSpriteGenderParam(1), FALSE); + UpdateGameData_SetActivity(sPlayerCurrActivity | IN_UNION_ROOM, GetLinkPlayerInfoFlags(1), FALSE); else - UpdateGameData_SetActivity(sPlayerCurrActivity | IN_UNION_ROOM, GetSinglePartnerSpriteGenderParam(1), TRUE); + UpdateGameData_SetActivity(sPlayerCurrActivity | IN_UNION_ROOM, GetLinkPlayerInfoFlags(1), TRUE); - data->field_8->arr[0].field_1B = 0; + uroom->spawnPlayer->players[0].newPlayerCountdown = 0; taskData[3] = 0; - if (sPlayerCurrActivity == (ACTIVITY_BATTLE | IN_UNION_ROOM)) + if (sPlayerCurrActivity == (ACTIVITY_BATTLE_SINGLE | IN_UNION_ROOM)) { if (!HasAtLeastTwoMonsOfLevel30OrLower()) { - data->playerSendBuffer[0] = ACTIVITY_DECLINE | IN_UNION_ROOM; - Rfu_SendPacket(data->playerSendBuffer); - data->state = 10; + uroom->playerSendBuffer[0] = ACTIVITY_DECLINE | IN_UNION_ROOM; + Rfu_SendPacket(uroom->playerSendBuffer); + uroom->state = UR_STATE_DECLINE_ACTIVITY_REQUEST; StringCopy(gStringVar4, gText_UR_NeedTwoMonsOfLevel30OrLower2); } else { - Rfu_SendPacket(data->playerSendBuffer); - data->state = 13; + Rfu_SendPacket(uroom->playerSendBuffer); + uroom->state = UR_STATE_PRINT_START_ACTIVITY_MSG; } } else if (sPlayerCurrActivity == (ACTIVITY_CARD | IN_UNION_ROOM)) { - Rfu_SendPacket(data->playerSendBuffer); - ViewURoomPartnerTrainerCard(gStringVar4, data, MODE_PARENT); - data->state = 40; + Rfu_SendPacket(uroom->playerSendBuffer); + ViewURoomPartnerTrainerCard(gStringVar4, uroom, MODE_PARENT); + uroom->state = UR_STATE_PRINT_CARD_INFO; } else { - Rfu_SendPacket(data->playerSendBuffer); - data->state = 13; + Rfu_SendPacket(uroom->playerSendBuffer); + uroom->state = UR_STATE_PRINT_START_ACTIVITY_MSG; } break; - case 1: - case -1: - data->playerSendBuffer[0] = ACTIVITY_DECLINE | IN_UNION_ROOM; - Rfu_SendPacket(data->playerSendBuffer); - data->state = 10; + case 1: // DECLINE + case MENU_B_PRESSED: + uroom->playerSendBuffer[0] = ACTIVITY_DECLINE | IN_UNION_ROOM; + Rfu_SendPacket(uroom->playerSendBuffer); + uroom->state = UR_STATE_DECLINE_ACTIVITY_REQUEST; GetYouDeclinedTheOfferMessage(gStringVar4, sPlayerCurrActivity); break; } break; - case 10: + case UR_STATE_DECLINE_ACTIVITY_REQUEST: SetCloseLinkCallback(); - data->state = 36; + uroom->state = UR_STATE_CANCEL_REQUEST_PRINT_MSG; break; - case 36: - // You said no + case UR_STATE_CANCEL_REQUEST_PRINT_MSG: if (!gReceivedRemoteLinkPlayers) { sPlayerCurrActivity = IN_UNION_ROOM; - UnionRoom_ScheduleFieldMessageWithFollowupState(37, gStringVar4); - memset(data->playerSendBuffer, 0, sizeof(data->playerSendBuffer)); - data->recvActivityRequest[0] = 0; - data->partnerYesNoResponse = 0; + ScheduleFieldMessageWithFollowupState(UR_STATE_CANCEL_REQUEST_RESTART_LINK, gStringVar4); + memset(uroom->playerSendBuffer, 0, sizeof(uroom->playerSendBuffer)); + uroom->recvActivityRequest[0] = 0; + uroom->partnerYesNoResponse = 0; } break; - case 37: - data->state = 2; - HandleCancelTrade(FALSE); + case UR_STATE_CANCEL_REQUEST_RESTART_LINK: + uroom->state = UR_STATE_INIT_LINK; + HandleCancelActivity(FALSE); break; - case 13: + case UR_STATE_PRINT_START_ACTIVITY_MSG: GetURoomActivityStartMsg(gStringVar4, sPlayerCurrActivity | IN_UNION_ROOM); - UnionRoom_ScheduleFieldMessageWithFollowupState(14, gStringVar4); + ScheduleFieldMessageWithFollowupState(UR_STATE_START_ACTIVITY_LINK, gStringVar4); break; - case 14: + case UR_STATE_START_ACTIVITY_LINK: SetLinkStandbyCallback(); - data->state = 15; + uroom->state = UR_STATE_START_ACTIVITY_WAIT_FOR_LINK; break; - case 15: + case UR_STATE_START_ACTIVITY_WAIT_FOR_LINK: if (IsLinkTaskFinished()) - data->state = 16; + uroom->state = UR_STATE_START_ACTIVITY_FREE_UROOM; break; - case 16: - Free(data->field_8); - Free(data->field_0); - Free(data->field_C); - Free(data->field_4); - DestroyTask(data->field_20); - DestroyGroupMemberObjects(data->spriteIds); - data->state = 17; + case UR_STATE_START_ACTIVITY_FREE_UROOM: + Free(uroom->spawnPlayer); + Free(uroom->playerList); + Free(uroom->incomingParentList); + Free(uroom->incomingChildList); + DestroyTask(uroom->searchTaskId); + DestroyGroupMemberObjects(uroom->spriteIds); + uroom->state = UR_STATE_START_ACTIVITY_FADE; break; - case 17: - BeginNormalPaletteFade(-1, 0, 0, 0x10, RGB_BLACK); - data->state = 18; + case UR_STATE_START_ACTIVITY_FADE: + BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK); + uroom->state = UR_STATE_START_ACTIVITY; break; - case 18: + case UR_STATE_START_ACTIVITY: if (!UpdatePaletteFade()) { - DeleteUnionObjWorkAndStopTask(); + DestroyUnionRoomPlayerObjects(); DestroyTask(taskId); - Free(sUnionRoomMain.uRoom); + Free(sWirelessLinkMain.uRoom); CreateTask_StartActivity(); } break; - case 42: + case UR_STATE_INTERACT_WITH_ATTENDANT: if (GetHostRfuGameData()->tradeSpecies == SPECIES_NONE) { - data->state = 43; + uroom->state = UR_STATE_REGISTER_PROMPT; } else { @@ -3234,194 +2873,204 @@ static void Task_RunUnionRoom(u8 taskId) ConvertIntToDecimalStringN(gStringVar2, GetHostRfuGameData()->tradeLevel, STR_CONV_MODE_LEFT_ALIGN, 3); StringExpandPlaceholders(gStringVar4, gText_UR_CancelRegistrationOfMon); } - UnionRoom_ScheduleFieldMessageWithFollowupState(44, gStringVar4); + ScheduleFieldMessageWithFollowupState(UR_STATE_CANCEL_REGISTRATION_PROMPT, gStringVar4); } break; - case 43: - if (PrintOnTextbox(&data->textState, gText_UR_RegisterMonAtTradingBoard)) - data->state = 47; + case UR_STATE_REGISTER_PROMPT: + if (PrintOnTextbox(&uroom->textState, gText_UR_RegisterMonAtTradingBoard)) + uroom->state = UR_STATE_REGISTER_PROMPT_HANDLE_INPUT; break; - case 47: - var5 = ListMenuHandler_AllItemsAvailable(&data->textState, &data->tradeBoardSelectWindowId, &data->tradeBoardDetailsWindowId, &sWindowTemplate_TradeBoardRegisterInfoExit, &sListMenuTemplate_TradeBoardRegisterInfoExit); - if (var5 != -1) + case UR_STATE_REGISTER_PROMPT_HANDLE_INPUT: + input = ListMenuHandler_AllItemsAvailable(&uroom->textState, + &uroom->tradeBoardMainWindowId, + &uroom->tradeBoardHeaderWindowId, + &sWindowTemplate_RegisterForTrade, + &sListMenuTemplate_RegisterForTrade); + if (input != LIST_NOTHING_CHOSEN) { - if (var5 == -2 || var5 == 3) + if (input == LIST_CANCEL || input == 3) // Exit { - data->state = 4; - HandleCancelTrade(TRUE); + uroom->state = UR_STATE_MAIN; + HandleCancelActivity(TRUE); } else { - switch (var5) + switch (input) { case 1: // REGISTER - UnionRoom_ScheduleFieldMessageWithFollowupState(53, gText_UR_WhichMonWillYouOffer); + ScheduleFieldMessageWithFollowupState(UR_STATE_REGISTER_SELECT_MON_FADE, gText_UR_WhichMonWillYouOffer); break; case 2: // INFO - UnionRoom_ScheduleFieldMessageWithFollowupState(47, gText_UR_TradingBoardInfo); + ScheduleFieldMessageWithFollowupState(UR_STATE_REGISTER_PROMPT_HANDLE_INPUT, gText_UR_TradingBoardInfo); break; } } DestroyHelpMessageWindow_(); } break; - case 53: - BeginNormalPaletteFade(-1, 0, 0, 0x10, RGB_BLACK); - data->state = 54; + case UR_STATE_REGISTER_SELECT_MON_FADE: + BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK); + uroom->state = UR_STATE_REGISTER_SELECT_MON; break; - case 54: + case UR_STATE_REGISTER_SELECT_MON: if (!gPaletteFade.active) { - sUnionRoomTrade.field_0 = 1; + sUnionRoomTrade.state = URTRADE_STATE_REGISTERING; gFieldCallback = FieldCB_ContinueScriptUnionRoom; ChooseMonForTradingBoard(PARTY_MENU_TYPE_UNION_ROOM_REGISTER, CB2_ReturnToField); } break; - case 52: - var5 = ListMenuHandler_AllItemsAvailable(&data->textState, &data->tradeBoardSelectWindowId, &data->tradeBoardDetailsWindowId, &sWindowTemplate_TypeNames, &sListMenuTemplate_TypeNames); - if (var5 != -1) + case UR_STATE_REGISTER_REQUEST_TYPE: + input = ListMenuHandler_AllItemsAvailable(&uroom->textState, &uroom->tradeBoardMainWindowId, &uroom->tradeBoardHeaderWindowId, &sWindowTemplate_TypeNames, &sListMenuTemplate_TypeNames); + if (input != LIST_NOTHING_CHOSEN) { - switch (var5) + switch (input) { - case -2: - case 18: + case LIST_CANCEL: + case NUMBER_OF_MON_TYPES: // Exit ResetUnionRoomTrade(&sUnionRoomTrade); - SetTradeBoardRegisteredMonInfo(0, 0, 0); - UnionRoom_ScheduleFieldMessageAndExit(gText_UR_RegistrationCanceled); + SetTradeBoardRegisteredMonInfo(TYPE_NORMAL, SPECIES_NONE, 0); + ScheduleFieldMessageAndExit(gText_UR_RegistrationCanceled); break; default: - sUnionRoomTrade.type = var5; - data->state = 55; + sUnionRoomTrade.type = input; + uroom->state = UR_STATE_REGISTER_COMPLETE; break; } } break; - case 55: + case UR_STATE_REGISTER_COMPLETE: SetTradeBoardRegisteredMonInfo(sUnionRoomTrade.type, sUnionRoomTrade.playerSpecies, sUnionRoomTrade.playerLevel); - UnionRoom_ScheduleFieldMessageAndExit(gText_UR_RegistraionCompleted); + ScheduleFieldMessageAndExit(gText_UR_RegistraionCompleted); break; - case 44: - switch (UnionRoomHandleYesNo(&data->textState, FALSE)) + case UR_STATE_CANCEL_REGISTRATION_PROMPT: + switch (UnionRoomHandleYesNo(&uroom->textState, FALSE)) { - case 0: - data->state = 56; + case 0: // YES + uroom->state = UR_STATE_CANCEL_REGISTRATION; break; - case 1: - case -1: - HandleCancelTrade(TRUE); - data->state = 4; + case 1: // NO + case MENU_B_PRESSED: + HandleCancelActivity(TRUE); + uroom->state = UR_STATE_MAIN; break; } break; - case 56: - if (PrintOnTextbox(&data->textState, gText_UR_RegistrationCanceled2)) + case UR_STATE_CANCEL_REGISTRATION: + if (PrintOnTextbox(&uroom->textState, gText_UR_RegistrationCanceled2)) { - SetTradeBoardRegisteredMonInfo(0, 0, 0); + SetTradeBoardRegisteredMonInfo(TYPE_NORMAL, SPECIES_NONE, 0); ResetUnionRoomTrade(&sUnionRoomTrade); - HandleCancelTrade(TRUE); - data->state = 4; + HandleCancelActivity(TRUE); + uroom->state = UR_STATE_MAIN; } break; - case 45: - if (PrintOnTextbox(&data->textState, gText_UR_XCheckedTradingBoard)) - data->state = 46; + case UR_STATE_CHECK_TRADING_BOARD: + if (PrintOnTextbox(&uroom->textState, gText_UR_XCheckedTradingBoard)) + uroom->state = UR_STATE_TRADING_BOARD_LOAD; break; - case 46: - UR_BlankBg0(); - data->state = 48; + case UR_STATE_TRADING_BOARD_LOAD: + UR_ClearBg0(); + uroom->state = UR_STATE_TRADING_BOARD_HANDLE_INPUT; break; - case 48: - var5 = TradeBoardMenuHandler(&data->textState, &data->tradeBoardSelectWindowId, &data->tradeBoardListMenuId, &data->tradeBoardDetailsWindowId, &gUnknown_8456F24, &sTradeBoardListMenuTemplate, data->field_0); - if (var5 != -1) + case UR_STATE_TRADING_BOARD_HANDLE_INPUT: + input = TradeBoardMenuHandler(&uroom->textState, + &uroom->tradeBoardMainWindowId, + &uroom->tradeBoardListMenuId, + &uroom->tradeBoardHeaderWindowId, + &sWindowTemplate_TradingBoardMain, + &sListMenuTemplate_TradeBoard, + uroom->playerList); + if (input != LIST_NOTHING_CHOSEN) { - switch (var5) + switch (input) { - case -2: - case 8: - HandleCancelTrade(TRUE); + case LIST_CANCEL: + case 8: // EXIT + HandleCancelActivity(TRUE); DestroyHelpMessageWindow_(); - data->state = 4; + uroom->state = UR_STATE_MAIN; break; default: - switch (IsRequestedTypeAndSpeciesInPlayerParty(data->field_0->arr[var5].gname_uname.gname.tradeType, data->field_0->arr[var5].gname_uname.gname.tradeSpecies)) + switch (IsRequestedTradeInPlayerParty(uroom->playerList->players[input].rfu.data.tradeType, uroom->playerList->players[input].rfu.data.tradeSpecies)) { case UR_TRADE_MATCH: - IntlConvPartnerUname(gStringVar1, data->field_0->arr[var5]); - UnionRoom_ScheduleFieldMessageWithFollowupState(49, gText_UR_AskTrainerToMakeTrade); - taskData[1] = var5; + CopyAndTranslatePlayerName2(gStringVar1, uroom->playerList->players[input]); + ScheduleFieldMessageWithFollowupState(UR_STATE_TRADE_PROMPT, gText_UR_AskTrainerToMakeTrade); + taskData[1] = input; break; case UR_TRADE_NOTYPE: - IntlConvPartnerUname(gStringVar1, data->field_0->arr[var5]); - StringCopy(gStringVar2, gTypeNames[data->field_0->arr[var5].gname_uname.gname.tradeType]); - UnionRoom_ScheduleFieldMessageWithFollowupState(46, gText_UR_DontHaveTypeTrainerWants); + CopyAndTranslatePlayerName2(gStringVar1, uroom->playerList->players[input]); + StringCopy(gStringVar2, gTypeNames[uroom->playerList->players[input].rfu.data.tradeType]); + ScheduleFieldMessageWithFollowupState(UR_STATE_TRADING_BOARD_LOAD, gText_UR_DontHaveTypeTrainerWants); break; case UR_TRADE_NOEGG: - IntlConvPartnerUname(gStringVar1, data->field_0->arr[var5]); - StringCopy(gStringVar2, gTypeNames[data->field_0->arr[var5].gname_uname.gname.tradeType]); - UnionRoom_ScheduleFieldMessageWithFollowupState(46, gText_UR_DontHaveEggTrainerWants); + CopyAndTranslatePlayerName2(gStringVar1, uroom->playerList->players[input]); + StringCopy(gStringVar2, gTypeNames[uroom->playerList->players[input].rfu.data.tradeType]); + ScheduleFieldMessageWithFollowupState(UR_STATE_TRADING_BOARD_LOAD, gText_UR_DontHaveEggTrainerWants); break; } break; } } break; - case 49: - switch (UnionRoomHandleYesNo(&data->textState, FALSE)) + case UR_STATE_TRADE_PROMPT: + switch (UnionRoomHandleYesNo(&uroom->textState, FALSE)) { - case 0: - data->state = 50; + case 0: // YES + uroom->state = UR_STATE_TRADE_SELECT_MON; break; - case -1: - case 1: - HandleCancelTrade(TRUE); - data->state = 4; + case MENU_B_PRESSED: + case 1: // NO + HandleCancelActivity(TRUE); + uroom->state = UR_STATE_MAIN; break; } break; - case 50: - if (PrintOnTextbox(&data->textState, gText_UR_WhichMonWillYouOffer)) + case UR_STATE_TRADE_SELECT_MON: + if (PrintOnTextbox(&uroom->textState, gText_UR_WhichMonWillYouOffer)) { - sUnionRoomTrade.field_0 = 2; - memcpy(&gPartnerTgtGnameSub, &data->field_0->arr[taskData[1]].gname_uname.gname.compatibility, sizeof(gPartnerTgtGnameSub)); - gUnionRoomRequestedMonType = data->field_0->arr[taskData[1]].gname_uname.gname.tradeType; - gUnionRoomOfferedSpecies = data->field_0->arr[taskData[1]].gname_uname.gname.tradeSpecies; + sUnionRoomTrade.state = URTRADE_STATE_OFFERING; + 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); - BackUpURoomField0ToDecompressionBuffer(data); - sUnionRoomTrade.field_8 = taskData[1]; + CopyPlayerListToBuffer(uroom); + sUnionRoomTrade.offerPlayerId = taskData[1]; } break; - case 51: + case UR_STATE_TRADE_OFFER_MON: sPlayerCurrActivity = ACTIVITY_TRADE | IN_UNION_ROOM; - TryConnectToUnionRoomParent(data->field_0->arr[taskData[1]].gname_uname.uname, &data->field_0->arr[taskData[1]].gname_uname.gname, ACTIVITY_TRADE | IN_UNION_ROOM); - IntlConvPartnerUname(gStringVar1, data->field_0->arr[taskData[1]]); + TryConnectToUnionRoomParent(uroom->playerList->players[taskData[1]].rfu.name, &uroom->playerList->players[taskData[1]].rfu.data, ACTIVITY_TRADE | IN_UNION_ROOM); + CopyAndTranslatePlayerName2(gStringVar1, uroom->playerList->players[taskData[1]]); UR_PrintFieldMessage(gTexts_UR_CommunicatingWait[2]); - data->state = 25; + uroom->state = UR_STATE_TRY_COMMUNICATING; break; - case 26: - if (PrintOnTextbox(&data->textState, gStringVar4)) + case UR_STATE_PRINT_AND_EXIT: + if (PrintOnTextbox(&uroom->textState, gStringVar4)) { - HandleCancelTrade(TRUE); - UpdateUnionGroupMemberFacing(taskData[0], taskData[1], data->field_0); - data->state = 4; + HandleCancelActivity(TRUE); + UpdateUnionGroupMemberFacing(taskData[0], taskData[1], uroom->playerList); + uroom->state = UR_STATE_MAIN; } break; - case 8: - if (PrintOnTextbox(&data->textState, gStringVar4)) - data->state = data->stateAfterPrint; + case UR_STATE_PRINT_MSG: + if (PrintOnTextbox(&uroom->textState, gStringVar4)) + uroom->state = uroom->stateAfterPrint; break; } } -void var_800D_set_xB(void) +void SetUsingUnionRoomStartMenu(void) { if (InUnionRoom() == TRUE) - gSpecialVar_Result = 11; + gSpecialVar_Result = UR_INTERACT_START_MENU; } -static void ReceiveUnionRoomActivityPacket(struct UnkStruct_URoom * uroom) +static void ReceiveUnionRoomActivityPacket(struct WirelessLink_URoom * uroom) { - if (gRecvCmds[1][1] != 0 && (gRecvCmds[1][0] & 0xFF00) == RFUCMD_SEND_PACKET) + if (gRecvCmds[1][1] != 0 && (gRecvCmds[1][0] & RFUCMD_MASK) == RFUCMD_SEND_PACKET) { uroom->recvActivityRequest[0] = gRecvCmds[1][1]; if (gRecvCmds[1][1] == (ACTIVITY_TRADE | IN_UNION_ROOM)) @@ -3432,24 +3081,24 @@ static void ReceiveUnionRoomActivityPacket(struct UnkStruct_URoom * uroom) } } -static bool32 UnionRoom_HandleContactFromOtherPlayer(struct UnkStruct_URoom * uroom) +static bool32 HandleContactFromOtherPlayer(struct WirelessLink_URoom * uroom) { if (uroom->recvActivityRequest[0] != 0) { - s32 var = GetChatLeaderActionRequestMessage(gStringVar4, gLinkPlayers[1].gender, &uroom->recvActivityRequest[0], uroom); - if (var == 0) + s32 id = GetChatLeaderActionRequestMessage(gStringVar4, gLinkPlayers[1].gender, &uroom->recvActivityRequest[0], uroom); + if (id == 0) // Error { return TRUE; } - else if (var == 1) + else if (id == 1) // Recieve activity request { - uroom->state = 35; + uroom->state = UR_STATE_RECV_ACTIVITY_REQUEST; sPlayerCurrActivity = uroom->recvActivityRequest[0]; return FALSE; } - else if (var == 2) + else if (id == 2) // No activity { - uroom->state = 36; + uroom->state = UR_STATE_CANCEL_REQUEST_PRINT_MSG; SetCloseLinkCallback(); return FALSE; } @@ -3460,19 +3109,19 @@ static bool32 UnionRoom_HandleContactFromOtherPlayer(struct UnkStruct_URoom * ur void InitUnionRoom(void) { - struct UnkStruct_URoom * ptr; + struct WirelessLink_URoom * data; sUnionRoomPlayerName[0] = EOS; if (QL_IS_PLAYBACK_STATE) return; CreateTask(Task_InitUnionRoom, 0); - sUnionRoomMain.uRoom = sUnionRoomMain.uRoom; // Needed to match. - sUnionRoomMain.uRoom = ptr = AllocZeroed(sizeof(struct UnkStruct_URoom)); - sURoom = sUnionRoomMain.uRoom; - ptr->state = 0; - ptr->textState = 0; - ptr->field_10 = 0; - ptr->field_12 = 0; + sWirelessLinkMain.uRoom = sWirelessLinkMain.uRoom; // Needed to match. + sWirelessLinkMain.uRoom = data = AllocZeroed(sizeof(struct WirelessLink_URoom)); + sURoom = sWirelessLinkMain.uRoom; + data->state = 0; + data->textState = 0; + data->unknown = 0; + data->unreadPlayerId = 0; sUnionRoomPlayerName[0] = EOS; } @@ -3480,46 +3129,46 @@ static void Task_InitUnionRoom(u8 taskId) { s32 i; u8 text[32]; - struct UnkStruct_URoom * structPtr = sUnionRoomMain.uRoom; + struct WirelessLink_URoom * data = sWirelessLinkMain.uRoom; - switch (structPtr->state) + switch (data->state) { case 0: - structPtr->state = 1; + data->state = 1; break; case 1: - SetHostRfuGameData(ACTIVITY_SEARCH, 0, 0); + SetHostRfuGameData(ACTIVITY_SEARCH, 0, FALSE); SetWirelessCommType1(); OpenLink(); InitializeRfuLinkManager_EnterUnionRoom(); RfuSetIgnoreError(TRUE); - structPtr->state = 2; + data->state = 2; break; case 2: - structPtr->field_4 = AllocZeroed(4 * sizeof(struct UnkStruct_x1C)); - BlankUnkStruct_x1CArray(structPtr->field_4->arr, 4); - structPtr->field_C = AllocZeroed(4 * sizeof(struct UnkStruct_x1C)); - BlankUnkStruct_x1CArray(structPtr->field_C->arr, 4); - structPtr->field_0 = AllocZeroed(UROOM_MAX_GROUP_COUNT * sizeof(struct UnkStruct_x20)); - BlankUnkStruct_x20Array(structPtr->field_0->arr, UROOM_MAX_GROUP_COUNT); - structPtr->field_8 = AllocZeroed(sizeof(struct UnkStruct_x20)); - BlankUnkStruct_x20Array(&structPtr->field_8->arr[0], 1); - structPtr->field_20 = CreateTask_SearchForChildOrParent(structPtr->field_C, structPtr->field_4, LINK_GROUP_UNION_ROOM_INIT); - structPtr->state = 3; + data->incomingChildList = AllocZeroed(RFU_CHILD_MAX * sizeof(struct RfuIncomingPlayer)); + ClearIncomingPlayerList(data->incomingChildList->players, RFU_CHILD_MAX); + data->incomingParentList = AllocZeroed(RFU_CHILD_MAX * sizeof(struct RfuIncomingPlayer)); + ClearIncomingPlayerList(data->incomingParentList->players, 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++) { - if (structPtr->field_0->arr[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN) + if (data->playerList->players[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN) { - IntlConvPartnerUname(text, structPtr->field_0->arr[i]); - if (PlayerHasMetTrainerBefore(ReadAsU16(structPtr->field_0->arr[i].gname_uname.gname.compatibility.playerTrainerId), text)) + CopyAndTranslatePlayerName2(text, data->playerList->players[i]); + if (PlayerHasMetTrainerBefore(ReadAsU16(data->playerList->players[i].rfu.data.compatibility.playerTrainerId), text)) { StringCopy(sUnionRoomPlayerName, text); break; @@ -3528,17 +3177,17 @@ static void Task_InitUnionRoom(u8 taskId) } } break; - case 3: + case PLIST_UNUSED: break; } break; case 4: - Free(structPtr->field_8); - Free(structPtr->field_0); - Free(structPtr->field_C); - Free(structPtr->field_4); - DestroyTask(structPtr->field_20); - Free(sUnionRoomMain.uRoom); + Free(data->spawnPlayer); + Free(data->playerList); + Free(data->incomingParentList); + Free(data->incomingChildList); + DestroyTask(data->searchTaskId); + Free(sWirelessLinkMain.uRoom); LinkRfu_Shutdown(); DestroyTask(taskId); break; @@ -3563,73 +3212,73 @@ static u8 HandlePlayerListUpdate(void) { s32 i; u8 j; - struct UnkStruct_URoom * structPtr = sUnionRoomMain.uRoom; - s32 r7 = 0; + struct WirelessLink_URoom * data = sWirelessLinkMain.uRoom; + s32 retVal = PLIST_NONE; - // If someone new joined, register them in field_8 + // If someone new joined, register them in spawnPlayer for (i = 0; i < RFU_CHILD_MAX; i++) { - if (AreGnameUnameDifferent(&structPtr->field_C->arr[i].gname_uname, &sUnionGnameUnamePair_Dummy) == TRUE) + if (ArePlayersDifferent(&data->incomingParentList->players[i].rfu, &sRfuPlayerData_Dummy) == TRUE) { - structPtr->field_8->arr[0].gname_uname = structPtr->field_C->arr[i].gname_uname; - structPtr->field_8->arr[0].field_18 = 0; - structPtr->field_8->arr[0].groupScheduledAnim = UNION_ROOM_SPAWN_IN; - structPtr->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; } } // Handle changes to existing player statuses - for (j = 0; j < UROOM_MAX_GROUP_COUNT; j++) + for (j = 0; j < MAX_UNION_ROOM_LEADERS; j++) { - if (structPtr->field_0->arr[j].groupScheduledAnim != UNION_ROOM_SPAWN_NONE) + if (data->playerList->players[j].groupScheduledAnim != UNION_ROOM_SPAWN_NONE) { - i = Findx20Inx1CArray(&structPtr->field_0->arr[j], &structPtr->field_4->arr[0]); + i = GetNewIncomingPlayerId(&data->playerList->players[j], &data->incomingChildList->players[0]); if (i != 0xFF) { - if (structPtr->field_0->arr[j].groupScheduledAnim == UNION_ROOM_SPAWN_IN) + if (data->playerList->players[j].groupScheduledAnim == UNION_ROOM_SPAWN_IN) { // New join in queue - if (AreUnionRoomPlayerGnamesDifferent(&structPtr->field_0->arr[j].gname_uname, &structPtr->field_4->arr[i].gname_uname)) + if (ArePlayerDataDifferent(&data->playerList->players[j].rfu, &data->incomingChildList->players[i].rfu)) { // Just joined, copy their names - structPtr->field_0->arr[j].gname_uname = structPtr->field_4->arr[i].gname_uname; - structPtr->field_0->arr[j].field_1B = 0x40; - r7 = 1; + data->playerList->players[j].rfu = data->incomingChildList->players[i].rfu; + data->playerList->players[j].newPlayerCountdown = 64; + retVal = PLIST_NEW_PLAYER; } - else if (structPtr->field_0->arr[j].field_1B != 0) + else if (data->playerList->players[j].newPlayerCountdown != 0) { - structPtr->field_0->arr[j].field_1B--; - if (structPtr->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 { // New join, queue them - structPtr->field_0->arr[j].groupScheduledAnim = UNION_ROOM_SPAWN_IN; - structPtr->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 = 2; } - structPtr->field_0->arr[j].field_18 = 0; + data->playerList->players[j].timeoutCounter = 0; } - else if (structPtr->field_0->arr[j].groupScheduledAnim != UNION_ROOM_SPAWN_OUT) + else if (data->playerList->players[j].groupScheduledAnim != UNION_ROOM_SPAWN_OUT) { // Person may have disconnected. Give them 10 seconds. - structPtr->field_0->arr[j].field_18++; - if (structPtr->field_0->arr[j].field_18 >= 600) + data->playerList->players[j].timeoutCounter++; + if (data->playerList->players[j].timeoutCounter >= 600) { - structPtr->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 (structPtr->field_0->arr[j].groupScheduledAnim == UNION_ROOM_SPAWN_OUT) + else if (data->playerList->players[j].groupScheduledAnim == UNION_ROOM_SPAWN_OUT) { // Person dropped. Wait 15 seconds, then remove them. - structPtr->field_0->arr[j].field_18++; - if (structPtr->field_0->arr[j].field_18 >= 900) + data->playerList->players[j].timeoutCounter++; + if (data->playerList->players[j].timeoutCounter >= 900) { - BlankUnkStruct_x20Array(&structPtr->field_0->arr[j], 1); + ClearRfuPlayerList(&data->playerList->players[j], 1); } } } @@ -3638,107 +3287,91 @@ static u8 HandlePlayerListUpdate(void) // Update the players list for (i = 0; i < RFU_CHILD_MAX; i++) { - if (Appendx1Ctox20(&structPtr->field_0->arr[0], &structPtr->field_4->arr[i], UROOM_MAX_GROUP_COUNT) != 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 UnionGnameUnamePair gname_uname; - struct UnkStruct_Main4 ** ptr = (void *) gTasks[taskId].data; - bool8 parent_child; + struct RfuPlayerData rfu; + struct RfuIncomingPlayerList ** list = (void *) gTasks[taskId].data; + bool8 isParent; for (i = 0; i < RFU_CHILD_MAX; i++) { - parent_child = Rfu_GetCompatiblePlayerData(&gname_uname.gname, gname_uname.uname, i); - if (!IsPartnerActivityAcceptable(gname_uname.gname.activity, gTasks[taskId].data[4])) - { - gname_uname = sUnionGnameUnamePair_Dummy; - } - if (gname_uname.gname.compatibility.language == LANGUAGE_JAPANESE) - { - gname_uname = sUnionGnameUnamePair_Dummy; - } - if (parent_child == MODE_CHILD) + isParent = Rfu_GetCompatiblePlayerData(&rfu.data, rfu.name, i); + if (!IsPartnerActivityAcceptable(rfu.data.activity, gTasks[taskId].data[4])) + rfu = sRfuPlayerData_Dummy; + if (rfu.data.compatibility.language == LANGUAGE_JAPANESE) + rfu = sRfuPlayerData_Dummy; + + if (!isParent) { for (j = 0; j < i; j++) { - if (!AreGnameUnameDifferent(&ptr[1]->arr[j].gname_uname, &gname_uname)) - { - gname_uname = sUnionGnameUnamePair_Dummy; - } + if (!ArePlayersDifferent(&list[1]->players[j].rfu, &rfu)) + rfu = sRfuPlayerData_Dummy; } - ptr[1]->arr[i].gname_uname = gname_uname; - ptr[1]->arr[i].active = AreGnameUnameDifferent(&ptr[1]->arr[i].gname_uname, &sUnionGnameUnamePair_Dummy); + list[1]->players[i].rfu = rfu; + list[1]->players[i].active = ArePlayersDifferent(&list[1]->players[i].rfu, &sRfuPlayerData_Dummy); } else { - ptr[0]->arr[i].gname_uname = gname_uname; - ptr[0]->arr[i].active = AreGnameUnameDifferent(&ptr[0]->arr[i].gname_uname, &sUnionGnameUnamePair_Dummy); + list[0]->players[i].rfu = rfu; + list[0]->players[i].active = ArePlayersDifferent(&list[0]->players[i].rfu, &sRfuPlayerData_Dummy); } } } -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++) { - Rfu_GetCompatiblePlayerData(&ptr[0]->arr[i].gname_uname.gname, ptr[0]->arr[i].gname_uname.uname, i); - if (!IsPartnerActivityAcceptable(ptr[0]->arr[i].gname_uname.gname.activity, gTasks[taskId].data[2])) - { - ptr[0]->arr[i].gname_uname = sUnionGnameUnamePair_Dummy; - } + 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])) + list[0]->players[i].rfu = sRfuPlayerData_Dummy; + 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 = sUnionGnameUnamePair_Dummy; - } + if (!ArePlayersDifferent(&list[0]->players[j].rfu, &list[0]->players[i].rfu)) + list[0]->players[i].rfu = sRfuPlayerData_Dummy; } - ptr[0]->arr[i].active = AreGnameUnameDifferent(&ptr[0]->arr[i].gname_uname, &sUnionGnameUnamePair_Dummy); + list[0]->players[i].active = ArePlayersDifferent(&list[0]->players[i].rfu, &sRfuPlayerData_Dummy); } } -static bool32 GetGnameWonderFlagByLinkGroup(struct RfuGameData * gname, s16 linkGroup) +static bool32 HasWonderCardOrNewsByLinkGroup(struct RfuGameData * data, s16 linkGroup) { if (linkGroup == LINK_GROUP_WONDER_CARD) { - if (!gname->compatibility.hasCard) - { + if (!data->compatibility.hasCard) return FALSE; - } else - { return TRUE; - } } else if (linkGroup == LINK_GROUP_WONDER_NEWS) { - if (!gname->compatibility.hasNews) - { + if (!data->compatibility.hasNews) return FALSE; - } else - { return TRUE; - } } else { @@ -3746,35 +3379,34 @@ static bool32 GetGnameWonderFlagByLinkGroup(struct RfuGameData * gname, s16 link } } -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 (Rfu_GetWonderDistributorPlayerData(&ptr[0]->arr[i].gname_uname.gname, ptr[0]->arr[i].gname_uname.uname, i)) - { - GetGnameWonderFlagByLinkGroup(&ptr[0]->arr[i].gname_uname.gname, gTasks[taskId].data[2]); - } - ptr[0]->arr[i].active = AreGnameUnameDifferent(&ptr[0]->arr[i].gname_uname, &sUnionGnameUnamePair_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, &sRfuPlayerData_Dummy); } } -static u8 CreateTask_ListenForPartnersWithCompatibleSerialNos(struct UnkStruct_Main4 * main4, u32 linkGroup) +static u8 CreateTask_ListenForCompatiblePartners(struct RfuIncomingPlayerList * main4, 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 ** list = (void *) gTasks[taskId].data; + list[0] = main4; gTasks[taskId].data[2] = linkGroup; return taskId; } -static u8 CreateTask_ListenForPartnersWithSerial7F7D(struct UnkStruct_Main4 * main4, u32 linkGroup) +static u8 CreateTask_ListenForWonderDistributor(struct RfuIncomingPlayerList * main4, 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 ** list = (void *) gTasks[taskId].data; + list[0] = main4; gTasks[taskId].data[2] = linkGroup; return taskId; } @@ -3788,16 +3420,12 @@ static bool32 UR_PrintFieldMessage(const u8 *src) return FALSE; } -static bool32 UR_RunTextPrinters_CheckPrinter0Active(void) +static bool32 UR_RunTextPrinters(void) { if (!RunTextPrinters_CheckPrinter0Active()) - { return TRUE; - } else - { return FALSE; - } } static bool8 PrintOnTextbox(u8 *textState, const u8 *str) @@ -3822,36 +3450,34 @@ static bool8 PrintOnTextbox(u8 *textState, const u8 *str) return FALSE; } -static s8 UnionRoomHandleYesNo(u8 *state_p, bool32 no_draw) +static s8 UnionRoomHandleYesNo(u8 *state, bool32 noDraw) { - s8 r1; + s8 input; - switch (*state_p) + switch (*state) { case 0: - if (no_draw) - { + if (noDraw) return -3; - } DisplayYesNoMenuDefaultYes(); - (*state_p)++; + (*state)++; break; case 1: - if (no_draw) + if (noDraw) { DestroyYesNoMenu(); - *state_p = 0; + *state = 0; return -3; } - r1 = Menu_ProcessInputNoWrapClearOnChoose(); - if (r1 == -1 || r1 == 0 || r1 == 1) + input = Menu_ProcessInputNoWrapClearOnChoose(); + if (input == MENU_B_PRESSED || input == 0 || input == 1) { - *state_p = 0; - return r1; + *state = 0; + return input; } break; } - return -2; + return MENU_NOTHING_CHOSEN; } static u8 CreateTradeBoardWindow(const struct WindowTemplate * template) @@ -3859,7 +3485,7 @@ static u8 CreateTradeBoardWindow(const struct WindowTemplate * template) u8 windowId = AddWindow(template); DrawStdWindowFrame(windowId, FALSE); FillWindowPixelBuffer(windowId, PIXEL_FILL(15)); - UR_AddTextPrinterParameterized(windowId, 0, gText_UR_NameWantedOfferLv, 8, 1, UR_COLOR_DN5_DN6_LTB); + PrintUnionRoomText(windowId, FONT_0, gText_UR_NameWantedOfferLv, 8, 1, UR_COLOR_TRADE_BOARD_OTHER); PutWindowTilemap(windowId); CopyWindowToVram(windowId, COPYWIN_GFX); return windowId; @@ -3871,86 +3497,90 @@ static void DeleteTradeBoardWindow(u8 windowId) RemoveWindow(windowId); } -static s32 ListMenuHandler_AllItemsAvailable(u8 *state_p, u8 *win_id_p, u8 *list_menu_id_p, const struct WindowTemplate * winTemplate, const struct ListMenuTemplate * menuTemplate) +static s32 ListMenuHandler_AllItemsAvailable(u8 *state, u8 *windowId, u8 *listMenuId, const struct WindowTemplate * winTemplate, const struct ListMenuTemplate * menuTemplate) { s32 input; - switch (*state_p) + switch (*state) { case 0: - *win_id_p = AddWindow(winTemplate); - DrawStdWindowFrame(*win_id_p, FALSE); + *windowId = AddWindow(winTemplate); + DrawStdWindowFrame(*windowId, FALSE); gMultiuseListMenuTemplate = *menuTemplate; - gMultiuseListMenuTemplate.windowId = *win_id_p; - *list_menu_id_p = ListMenuInit(&gMultiuseListMenuTemplate, 0, 0); - CopyWindowToVram(*win_id_p, TRUE); - (*state_p)++; + gMultiuseListMenuTemplate.windowId = *windowId; + *listMenuId = ListMenuInit(&gMultiuseListMenuTemplate, 0, 0); + CopyWindowToVram(*windowId, TRUE); + (*state)++; break; case 1: - input = ListMenu_ProcessInput(*list_menu_id_p); + input = ListMenu_ProcessInput(*listMenuId); if (JOY_NEW(A_BUTTON)) { - DestroyListMenuTask(*list_menu_id_p, NULL, NULL); - ClearStdWindowAndFrame(*win_id_p, TRUE); - RemoveWindow(*win_id_p); - *state_p = 0; + DestroyListMenuTask(*listMenuId, NULL, NULL); + ClearStdWindowAndFrame(*windowId, TRUE); + RemoveWindow(*windowId); + *state = 0; return input; } else if (JOY_NEW(B_BUTTON)) { - DestroyListMenuTask(*list_menu_id_p, NULL, NULL); - ClearStdWindowAndFrame(*win_id_p, TRUE); - RemoveWindow(*win_id_p); - *state_p = 0; - return -2; + DestroyListMenuTask(*listMenuId, NULL, NULL); + ClearStdWindowAndFrame(*windowId, TRUE); + RemoveWindow(*windowId); + *state = 0; + return LIST_CANCEL; } break; } - return -1; + return LIST_NOTHING_CHOSEN; } -static s32 TradeBoardMenuHandler(u8 *state_p, u8 *win_id_p, u8 *list_menu_id_p, u8 *trade_board_win_id_p, 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 r4; + s32 idx; - switch (*state_p) + switch (*state) { case 0: - *trade_board_win_id_p = CreateTradeBoardWindow(&sTradeBoardWindowTemplate); - *win_id_p = AddWindow(winTemplate); - DrawStdWindowFrame(*win_id_p, FALSE); + *headerWindowId = CreateTradeBoardWindow(&sWindowTemplate_TradingBoardHeader); + *mainWindowId = AddWindow(winTemplate); + DrawStdWindowFrame(*mainWindowId, FALSE); gMultiuseListMenuTemplate = *menuTemplate; - gMultiuseListMenuTemplate.windowId = *win_id_p; - *list_menu_id_p = ListMenuInit(&gMultiuseListMenuTemplate, 0, 1); - CopyWindowToVram(*win_id_p, TRUE); - (*state_p)++; + gMultiuseListMenuTemplate.windowId = *mainWindowId; + *listMenuId = ListMenuInit(&gMultiuseListMenuTemplate, 0, 1); + CopyWindowToVram(*mainWindowId, TRUE); + (*state)++; break; case 1: - input = ListMenu_ProcessInput(*list_menu_id_p); + input = ListMenu_ProcessInput(*listMenuId); if (JOY_NEW(A_BUTTON | B_BUTTON)) { - if (input == UROOM_MAX_GROUP_COUNT || JOY_NEW(B_BUTTON)) + // Exit or B button + if (input == 8 || JOY_NEW(B_BUTTON)) { - DestroyListMenuTask(*list_menu_id_p, NULL, NULL); - ClearStdWindowAndFrame(*win_id_p, TRUE); - RemoveWindow(*win_id_p); - DeleteTradeBoardWindow(*trade_board_win_id_p); - *state_p = 0; - return -2; + DestroyListMenuTask(*listMenuId, NULL, NULL); + ClearStdWindowAndFrame(*mainWindowId, TRUE); + RemoveWindow(*mainWindowId); + DeleteTradeBoardWindow(*headerWindowId); + *state = 0; + return LIST_CANCEL; } else { - r4 = GetIndexOfNthTradeBoardOffer(traders->arr, input); - if (r4 >= 0) + idx = GetIndexOfNthTradeBoardOffer(list->players, input); + if (idx >= 0) { - DestroyListMenuTask(*list_menu_id_p, NULL, NULL); - ClearStdWindowAndFrame(*win_id_p, TRUE); - RemoveWindow(*win_id_p); - DeleteTradeBoardWindow(*trade_board_win_id_p); - *state_p = 0; - return r4; + DestroyListMenuTask(*listMenuId, NULL, NULL); + ClearStdWindowAndFrame(*mainWindowId, TRUE); + RemoveWindow(*mainWindowId); + DeleteTradeBoardWindow(*headerWindowId); + *state = 0; + return idx; } else { @@ -3961,23 +3591,23 @@ static s32 TradeBoardMenuHandler(u8 *state_p, u8 *win_id_p, u8 *list_menu_id_p, break; } - return -1; + return LIST_NOTHING_CHOSEN; } -static void UR_BlankBg0(void) +static void UR_ClearBg0(void) { FillBgTilemapBufferRect(0, 0, 0, 0, 32, 32, 0); CopyBgTilemapBufferToVram(0); } -static void JoinGroup_BlankBg0AndEnableScriptContexts(void) +static void JoinGroup_EnableScriptContexts(void) { FillBgTilemapBufferRect(0, 0, 0, 0, 32, 32, 0); CopyBgTilemapBufferToVram(0); ScriptContext_Enable(); } -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; @@ -3993,49 +3623,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; @@ -4044,114 +3674,111 @@ static void UR_AddTextPrinterParameterized(u8 windowId, u8 fontId, const u8 *str break; } - AddTextPrinter(&printerTemplate, 0xFF, NULL); + AddTextPrinter(&printerTemplate, TEXT_SKIP_DRAW, NULL); } -static void BlankUnkStruct_x20Array(struct UnkStruct_x20 * x20arr, u8 count) +static void ClearRfuPlayerList(struct RfuPlayer * x20arr, u8 count) { s32 i; for (i = 0; i < count; i++) { - x20arr[i].gname_uname = sUnionGnameUnamePair_Dummy; - x20arr[i].field_18 = 0xFF; + x20arr[i].rfu = sRfuPlayerData_Dummy; + x20arr[i].timeoutCounter = 0xFF; x20arr[i].groupScheduledAnim = UNION_ROOM_SPAWN_NONE; - x20arr[i].field_1A_1 = FALSE; - x20arr[i].field_1B = 0; + x20arr[i].useRedText = FALSE; + x20arr[i].newPlayerCountdown = 0; } } -static void BlankUnkStruct_x1CArray(struct UnkStruct_x1C * x1Carr, u8 count) +static void ClearIncomingPlayerList(struct RfuIncomingPlayer * x1Carr, u8 count) { s32 i; for (i = 0; i < RFU_CHILD_MAX; i++) { - x1Carr[i].gname_uname = sUnionGnameUnamePair_Dummy; + x1Carr[i].rfu = sRfuPlayerData_Dummy; x1Carr[i].active = FALSE; } } -static bool8 AreGnameUnameDifferent(struct UnionGnameUnamePair * left, const struct UnionGnameUnamePair * right) +// 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 (left->gname.compatibility.playerTrainerId[i] != right->gname.compatibility.playerTrainerId[i]) - { + if (player1->data.compatibility.playerTrainerId[i] != player2->data.compatibility.playerTrainerId[i]) return TRUE; - } } for (i = 0; i < RFU_USER_NAME_LENGTH; i++) { - if (left->uname[i] != right->uname[i]) - { + if (player1->name[i] != player2->name[i]) return TRUE; - } } return FALSE; } -static bool32 AreUnionRoomPlayerGnamesDifferent(struct UnionGnameUnamePair * left, struct UnionGnameUnamePair * right) +static bool32 ArePlayerDataDifferent(struct RfuPlayerData * player1, struct RfuPlayerData * player2) { s32 i; - if (left->gname.activity != right->gname.activity) + if (player1->data.activity != player2->data.activity) return TRUE; - if (left->gname.startedActivity != right->gname.startedActivity) + if (player1->data.startedActivity != player2->data.startedActivity) return TRUE; for (i = 0; i < RFU_CHILD_MAX; i++) { - if (left->gname.partnerInfo[i] != right->gname.partnerInfo[i]) + if (player1->data.partnerInfo[i] != player2->data.partnerInfo[i]) return TRUE; } - if (left->gname.tradeSpecies != right->gname.tradeSpecies) + if (player1->data.tradeSpecies != player2->data.tradeSpecies) return TRUE; - if (left->gname.tradeType != right->gname.tradeType) + if (player1->data.tradeType != player2->data.tradeType) return TRUE; return FALSE; } -static u32 Findx20Inx1CArray(struct UnkStruct_x20 * x20, struct UnkStruct_x1C * x1Carr) +static u32 GetNewIncomingPlayerId(struct RfuPlayer * player, struct RfuIncomingPlayer * incomingPlayer) { u8 result = 0xFF; s32 i; for (i = 0; i < RFU_CHILD_MAX; i++) { - if (x1Carr[i].active && !AreGnameUnameDifferent(&x20->gname_uname, &x1Carr[i].gname_uname)) + if (incomingPlayer[i].active && !ArePlayersDifferent(&player->rfu, &incomingPlayer[i].rfu)) { result = i; - x1Carr[i].active = FALSE; + incomingPlayer[i].active = FALSE; } } return result; } -static u8 Appendx1Ctox20(struct UnkStruct_x20 * x20arr, struct UnkStruct_x1C * x1C, u8 count) +static u8 TryAddIncomingPlayerToList(struct RfuPlayer * players, struct RfuIncomingPlayer * incomingPlayer, u8 count) { s32 i; - if (x1C->active) + if (incomingPlayer->active) { for (i = 0; i < count; i++) { - if (x20arr[i].groupScheduledAnim == UNION_ROOM_SPAWN_NONE) + if (players[i].groupScheduledAnim == UNION_ROOM_SPAWN_NONE) { - x20arr[i].gname_uname = x1C->gname_uname; - x20arr[i].field_18 = 0; - x20arr[i].groupScheduledAnim = UNION_ROOM_SPAWN_IN; - x20arr[i].field_1B = 0x40; - x1C->active = FALSE; + players[i].rfu = incomingPlayer->rfu; + players[i].timeoutCounter = 0; + players[i].groupScheduledAnim = UNION_ROOM_SPAWN_IN; + players[i].newPlayerCountdown = 0x40; + incomingPlayer->active = FALSE; return i; } } @@ -4160,62 +3787,59 @@ static u8 Appendx1Ctox20(struct UnkStruct_x20 * x20arr, struct UnkStruct_x1C * x 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 id_str[6]; + u8 trainerId[6]; u8 uname[30]; ConvertIntToDecimalStringN(gStringVar4, id + 1, STR_CONV_MODE_LEADING_ZEROS, 2); StringAppend(gStringVar4, gText_UR_Colon); - UR_AddTextPrinterParameterized(windowId, 0, gStringVar4, x, y, UR_COLOR_DKE_WHT_LTE); + PrintUnionRoomText(windowId, FONT_0, 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)) { - IntlConvPartnerUname(uname, *group); - UR_AddTextPrinterParameterized(windowId, 2, uname, x, y, colorIdx); - ConvertIntToDecimalStringN(id_str, group->gname_uname.gname.compatibility.playerTrainerId[0] | (group->gname_uname.gname.compatibility.playerTrainerId[1] << 8), STR_CONV_MODE_LEADING_ZEROS, 5); + CopyAndTranslatePlayerName2(uname, *player); + PrintUnionRoomText(windowId, FONT_2, uname, 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, gText_UR_ID); - StringAppend(gStringVar4, id_str); + StringAppend(gStringVar4, trainerId); x += 77; - UR_AddTextPrinterParameterized(windowId, 0, gStringVar4, x, y, colorIdx); + PrintUnionRoomText(windowId, FONT_0, gStringVar4, x, 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 id_str[6]; u8 uname[30]; - if (group->groupScheduledAnim == UNION_ROOM_SPAWN_IN) + if (player->groupScheduledAnim == UNION_ROOM_SPAWN_IN) { - IntlConvPartnerUname(uname, *group); - UR_AddTextPrinterParameterized(windowId, 2, uname, x, y, colorIdx); - ConvertIntToDecimalStringN(id_str, group->gname_uname.gname.compatibility.playerTrainerId[0] | (group->gname_uname.gname.compatibility.playerTrainerId[1] << 8), STR_CONV_MODE_LEADING_ZEROS, 5); + CopyAndTranslatePlayerName2(uname, *player); + PrintUnionRoomText(windowId, FONT_2, uname, x, y, colorIdx); + ConvertIntToDecimalStringN(id_str, player->rfu.data.compatibility.playerTrainerId[0] | (player->rfu.data.compatibility.playerTrainerId[1] << 8), STR_CONV_MODE_LEADING_ZEROS, 5); StringCopy(gStringVar4, gText_UR_ID); StringAppend(gStringVar4, id_str); x += 71; - UR_AddTextPrinterParameterized(windowId, 0, gStringVar4, x, y, colorIdx); + PrintUnionRoomText(windowId, FONT_0, gStringVar4, x, y, colorIdx); } } -static bool32 PlayerIsTalkingToUnionRoomAide(void) +static bool32 IsPlayerFacingTradingBoard(void) { s16 x, y; GetXYCoordsOneStepInFrontOfPlayer(&x, &y); - if (x != 9) - { + + if (x != 2 + MAP_OFFSET) return FALSE; - } - if (y != 8) - { + + if (y != 1 + MAP_OFFSET) return FALSE; - } - if (gPlayerAvatar.tileTransitionState == 2 || gPlayerAvatar.tileTransitionState == 0) - { + + if (gPlayerAvatar.tileTransitionState == T_TILE_CENTER || gPlayerAvatar.tileTransitionState == T_NOT_MOVING) return TRUE; - } return FALSE; } @@ -4230,30 +3854,30 @@ static u32 GetResponseIdx_InviteToURoomActivity(s32 activity) return 2; case ACTIVITY_CARD: return 3; - case ACTIVITY_MLTBATTLE: + case ACTIVITY_BATTLE_MULTI: default: return 0; } } -static u32 ConvPartnerUnameAndGetWhetherMetAlready(struct UnkStruct_x20 * x20) +static u32 ConvPartnerUnameAndGetWhetherMetAlready(struct RfuPlayer * player) { - u8 sp0[30]; - IntlConvPartnerUname(sp0, *x20); - return PlayerHasMetTrainerBefore(ReadAsU16(x20->gname_uname.gname.compatibility.playerTrainerId), sp0); + u8 name[30]; + CopyAndTranslatePlayerName2(name, *player); + return PlayerHasMetTrainerBefore(ReadAsU16(player->rfu.data.compatibility.playerTrainerId), name); } -static s32 UnionRoomGetPlayerInteractionResponse(struct UnkStruct_Main0 * main0, u8 overrideGender, u8 playerIdx, u32 playerGender) +static s32 UnionRoomGetPlayerInteractionResponse(struct RfuPlayerList * list, bool8 overrideGender, u8 playerIdx, u32 playerGender) { bool32 metBefore; - struct UnkStruct_x20 * x20 = &main0->arr[playerIdx]; + struct RfuPlayer * player = &list->players[playerIdx]; - if (!x20->gname_uname.gname.startedActivity && overrideGender == 0) + if (!player->rfu.data.startedActivity && !overrideGender) { - IntlConvPartnerUname(gStringVar1, *x20); - metBefore = PlayerHasMetTrainerBefore(ReadAsU16(x20->gname_uname.gname.compatibility.playerTrainerId), gStringVar1); - if (x20->gname_uname.gname.activity == (ACTIVITY_CHAT | IN_UNION_ROOM)) + CopyAndTranslatePlayerName2(gStringVar1, *player); + metBefore = PlayerHasMetTrainerBefore(ReadAsU16(player->rfu.data.compatibility.playerTrainerId), gStringVar1); + if (player->rfu.data.activity == (ACTIVITY_CHAT | IN_UNION_ROOM)) { StringExpandPlaceholders(gStringVar4, gTexts_UR_JoinChat[metBefore][playerGender]); return 2; @@ -4266,14 +3890,13 @@ static s32 UnionRoomGetPlayerInteractionResponse(struct UnkStruct_Main0 * main0, } else { - IntlConvPartnerUname(gStringVar1, *x20); - if (overrideGender != 0) + CopyAndTranslatePlayerName2(gStringVar1, *player); + if (overrideGender) + playerGender = (player->rfu.data.compatibility.playerTrainerId[overrideGender + 1] >> 3) & 1; + + switch (player->rfu.data.activity & 0x3F) { - playerGender = (x20->gname_uname.gname.compatibility.playerTrainerId[overrideGender + 1] >> 3) & 1; - } - switch (x20->gname_uname.gname.activity & 0x3F) - { - case ACTIVITY_BATTLE: + case ACTIVITY_BATTLE_SINGLE: StringExpandPlaceholders(gStringVar4, gTexts_UR_BattleReaction[playerGender][Random() % 4]); break; case ACTIVITY_TRADE: @@ -4293,91 +3916,85 @@ static s32 UnionRoomGetPlayerInteractionResponse(struct UnkStruct_Main0 * main0, } } -static void nullsub_92(u8 windowId, u32 itemId, u8 y) +static void ItemPrintFunc_Unused(u8 windowId, u32 itemId, u8 y) { } -static void TradeBoardPrintItemInfo(u8 windowId, u8 y, struct RfuGameData * gname, const u8 * uname, u8 colorIdx) +static void TradeBoardPrintItemInfo(u8 windowId, u8 y, struct RfuGameData * data, const u8 * playerName, u8 colorIdx) { - u8 level_t[4]; - u16 species = gname->tradeSpecies; - u8 type = gname->tradeType; - u8 level = gname->tradeLevel; + u8 levelStr[4]; + u16 species = data->tradeSpecies; + u8 type = data->tradeType; + u8 level = data->tradeLevel; - UR_AddTextPrinterParameterized(windowId, 2, uname, 8, y, colorIdx); + PrintUnionRoomText(windowId, FONT_2, playerName, 8, y, colorIdx); if (species == SPECIES_EGG) { - UR_AddTextPrinterParameterized(windowId, 2, gText_UR_EggTrade, 0x44, y, colorIdx); + PrintUnionRoomText(windowId, FONT_2, gText_UR_EggTrade, 68, y, colorIdx); } else { - BlitMoveInfoIcon(windowId, type + 1, 0x44, y); - UR_AddTextPrinterParameterized(windowId, 2, gSpeciesNames[species], 0x76, y, colorIdx); - ConvertIntToDecimalStringN(level_t, level, STR_CONV_MODE_LEFT_ALIGN, 3); - UR_AddTextPrinterParameterized(windowId, 2, level_t, GetStringRightAlignXOffset(2, level_t, 218), y, colorIdx); + BlitMoveInfoIcon(windowId, type + 1, 68, y); + PrintUnionRoomText(windowId, FONT_2, gSpeciesNames[species], 118, y, colorIdx); + ConvertIntToDecimalStringN(levelStr, level, STR_CONV_MODE_LEFT_ALIGN, 3); + PrintUnionRoomText(windowId, FONT_2, levelStr, GetStringRightAlignXOffset(2, levelStr, 218), y, colorIdx); } } static void TradeBoardListMenuItemPrintFunc(u8 windowId, u32 itemId, u8 y) { - struct UnkStruct_Leader * leader = sUnionRoomMain.leader; - struct RfuGameData * rfu; + struct WirelessLink_Leader * leader = sWirelessLinkMain.leader; + struct RfuGameData * gameData; s32 i, j; - u8 uname[RFU_USER_NAME_LENGTH]; + u8 playerName[RFU_USER_NAME_LENGTH]; - if (itemId == -3 && y == sTradeBoardListMenuTemplate.upText_Y) + if (itemId == LIST_HEADER && y == sListMenuTemplate_TradeBoard.upText_Y) { - rfu = GetHostRfuGameData(); - if (rfu->tradeSpecies != SPECIES_NONE) - { - TradeBoardPrintItemInfo(windowId, y, rfu, gSaveBlock2Ptr->playerName, 5); - } + gameData = GetHostRfuGameData(); + if (gameData->tradeSpecies != SPECIES_NONE) + TradeBoardPrintItemInfo(windowId, y, gameData, gSaveBlock2Ptr->playerName, 5); } else { j = 0; - for (i = 0; i < UROOM_MAX_GROUP_COUNT; i++) + for (i = 0; i < MAX_UNION_ROOM_LEADERS; i++) { - if (leader->field_0->arr[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN && leader->field_0->arr[i].gname_uname.gname.tradeSpecies != 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) { - IntlConvPartnerUname(uname, leader->field_0->arr[i]); - TradeBoardPrintItemInfo(windowId, y, &leader->field_0->arr[i].gname_uname.gname, uname, 6); + CopyAndTranslatePlayerName2(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 * x20, s32 n) +static s32 GetIndexOfNthTradeBoardOffer(struct RfuPlayer * players, s32 n) { s32 i; s32 j = 0; - for (i = 0; i < UROOM_MAX_GROUP_COUNT; i++) + for (i = 0; i < MAX_UNION_ROOM_LEADERS; i++) { - if (x20[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN && x20[i].gname_uname.gname.tradeSpecies != 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 IsRequestedTypeAndSpeciesInPlayerParty(u32 type, u32 species) +static s32 IsRequestedTradeInPlayerParty(u32 type, u32 species) { s32 i; @@ -4387,9 +4004,7 @@ static s32 IsRequestedTypeAndSpeciesInPlayerParty(u32 type, u32 species) { species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2); if (species == SPECIES_EGG) - { return UR_TRADE_MATCH; - } } return UR_TRADE_NOEGG; } @@ -4399,9 +4014,7 @@ static s32 IsRequestedTypeAndSpeciesInPlayerParty(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; } @@ -4411,7 +4024,7 @@ static void GetURoomActivityRejectMsg(u8 *dst, s32 activity, u32 playerGender) { switch (activity) { - case ACTIVITY_BATTLE | IN_UNION_ROOM: + case ACTIVITY_BATTLE_SINGLE | IN_UNION_ROOM: StringExpandPlaceholders(dst, gTexts_UR_BattleDeclined[playerGender]); break; case ACTIVITY_CHAT | IN_UNION_ROOM: @@ -4433,7 +4046,7 @@ static void GetURoomActivityStartMsg(u8 *dst, u8 activity) switch (activity) { - case ACTIVITY_BATTLE | IN_UNION_ROOM: + case ACTIVITY_BATTLE_SINGLE | IN_UNION_ROOM: StringCopy(dst, gTexts_UR_StartActivity[mpId][gender][0]); break; case ACTIVITY_TRADE | IN_UNION_ROOM: @@ -4445,15 +4058,15 @@ static void GetURoomActivityStartMsg(u8 *dst, u8 activity) } } -static s32 GetChatLeaderActionRequestMessage(u8 *dst, u32 gender, u16 *activity_p, struct UnkStruct_URoom * arg3) +static s32 GetChatLeaderActionRequestMessage(u8 *dst, u32 gender, u16 *activityData, struct WirelessLink_URoom * uroom) { s32 result = 0; u16 species = SPECIES_NONE; s32 i; - switch (activity_p[0]) + switch (activityData[0]) { - case ACTIVITY_BATTLE | IN_UNION_ROOM: + case ACTIVITY_BATTLE_SINGLE | IN_UNION_ROOM: StringExpandPlaceholders(dst, gText_UR_BattleChallenge); result = 1; break; @@ -4462,15 +4075,15 @@ static s32 GetChatLeaderActionRequestMessage(u8 *dst, u32 gender, u16 *activity_ result = 1; break; case ACTIVITY_TRADE | IN_UNION_ROOM: - ConvertIntToDecimalStringN(arg3->activityRequestStrbufs[0], sUnionRoomTrade.playerLevel, STR_CONV_MODE_LEFT_ALIGN, 3); - StringCopy(arg3->activityRequestStrbufs[1], gSpeciesNames[sUnionRoomTrade.playerSpecies]); + ConvertIntToDecimalStringN(uroom->activityRequestStrbufs[0], sUnionRoomTrade.playerLevel, STR_CONV_MODE_LEFT_ALIGN, 3); + StringCopy(uroom->activityRequestStrbufs[1], gSpeciesNames[sUnionRoomTrade.playerSpecies]); for (i = 0; i < RFU_CHILD_MAX; i++) { - if (gRfuLinkStatus->partner[i].serialNo == 0x0002) + if (gRfuLinkStatus->partner[i].serialNo == RFU_SERIAL_GAME) { - ConvertIntToDecimalStringN(arg3->activityRequestStrbufs[2], activity_p[2], STR_CONV_MODE_LEFT_ALIGN, 3); - StringCopy(arg3->activityRequestStrbufs[3], gSpeciesNames[activity_p[1]]); - species = activity_p[1]; + ConvertIntToDecimalStringN(uroom->activityRequestStrbufs[2], activityData[2], STR_CONV_MODE_LEFT_ALIGN, 3); + StringCopy(uroom->activityRequestStrbufs[3], gSpeciesNames[activityData[1]]); + species = activityData[1]; break; } } @@ -4481,9 +4094,7 @@ static s32 GetChatLeaderActionRequestMessage(u8 *dst, u32 gender, u16 *activity_ else { for (i = 0; i < RFU_CHILD_MAX; i++) - { - DynamicPlaceholderTextUtil_SetPlaceholderPtr(i, arg3->activityRequestStrbufs[i]); - } + DynamicPlaceholderTextUtil_SetPlaceholderPtr(i, uroom->activityRequestStrbufs[i]); DynamicPlaceholderTextUtil_ExpandPlaceholders(dst, gText_UR_OfferToTradeMon); } result = 1; @@ -4492,8 +4103,7 @@ static s32 GetChatLeaderActionRequestMessage(u8 *dst, u32 gender, u16 *activity_ StringExpandPlaceholders(dst, gText_UR_ShowTrainerCard); result = 1; break; - case IN_UNION_ROOM: - // Chat dropped + case ACTIVITY_NONE | IN_UNION_ROOM: StringExpandPlaceholders(dst, gText_UR_ChatDropped); result = 2; break; @@ -4502,7 +4112,7 @@ static s32 GetChatLeaderActionRequestMessage(u8 *dst, u32 gender, u16 *activity_ return result; } -static bool32 PollPartnerYesNoResponse(struct UnkStruct_URoom * uroom) +static bool32 PollPartnerYesNoResponse(struct WirelessLink_URoom * uroom) { if (gRecvCmds[0][1] != 0) { @@ -4534,11 +4144,9 @@ static bool32 HasAtLeastTwoMonsOfLevel30OrLower(void) for (i = 0; i < gPlayerPartyCount; i++) { - if (GetMonData(&gPlayerParty[i], MON_DATA_LEVEL) <= 30 + if (GetMonData(&gPlayerParty[i], MON_DATA_LEVEL) <= UNION_ROOM_MAX_LEVEL && GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2) != SPECIES_EGG) - { count++; - } } if (count > 1) @@ -4549,12 +4157,12 @@ static bool32 HasAtLeastTwoMonsOfLevel30OrLower(void) static void ResetUnionRoomTrade(struct UnionRoomTrade * uroomTrade) { - uroomTrade->field_0 = 0; + uroomTrade->state = URTRADE_STATE_NONE; uroomTrade->type = 0; uroomTrade->playerPersonality = 0; - uroomTrade->playerSpecies = 0; + uroomTrade->playerSpecies = SPECIES_NONE; uroomTrade->playerLevel = 0; - uroomTrade->species = 0; + uroomTrade->species = SPECIES_NONE; uroomTrade->level = 0; uroomTrade->personality = 0; } @@ -4608,14 +4216,10 @@ static u32 GetPartyPositionOfRegisteredMon(struct UnionRoomTrade * trade, u8 mul { 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; } @@ -4623,26 +4227,26 @@ static u32 GetPartyPositionOfRegisteredMon(struct UnionRoomTrade * trade, u8 mul return response; } -static void HandleCancelTrade(bool32 unlockObjs) +static void HandleCancelActivity(bool32 setData) { - UR_BlankBg0(); + UR_ClearBg0(); UnlockPlayerFieldControls(); UnionRoom_UnlockPlayerAndChatPartner(); sPlayerCurrActivity = 0; - if (unlockObjs) + if (setData) { SetTradeBoardRegisteredMonInfo(sUnionRoomTrade.type, sUnionRoomTrade.playerSpecies, sUnionRoomTrade.playerLevel); UpdateGameData_SetActivity(IN_UNION_ROOM, 0, FALSE); } } -static void UR_EnableScriptContext2AndFreezeObjectEvents(void) +static void StartScriptInteraction(void) { LockPlayerFieldControls(); FreezeObjects_WaitForPlayer(); } -static u8 GetSinglePartnerSpriteGenderParam(s32 linkPlayer) +static u8 GetLinkPlayerInfoFlags(s32 linkPlayer) { u8 retval = 0x80; retval |= gLinkPlayers[linkPlayer].gender << 3; @@ -4650,17 +4254,17 @@ static u8 GetSinglePartnerSpriteGenderParam(s32 linkPlayer) return retval; } -static u8 GetActivePartnerSpriteGenderParam(struct UnkStruct_URoom * uroom) +static u8 GetActivePartnersInfo(struct WirelessLink_URoom * uroom) { - u8 retVal = 0x80; + u8 retVal = PINFO_ACTIVE_FLAG; u8 i; for (i = 0; i < RFU_CHILD_MAX; i++) { - if (uroom->field_C->arr[i].active) + if (uroom->incomingParentList->players[i].active) { - retVal |= uroom->field_C->arr[i].gname_uname.gname.playerGender << 3; - retVal |= uroom->field_C->arr[i].gname_uname.gname.compatibility.playerTrainerId[0] & 7; + retVal |= uroom->incomingParentList->players[i].rfu.data.playerGender << PINFO_GENDER_SHIFT; + retVal |= uroom->incomingParentList->players[i].rfu.data.compatibility.playerTrainerId[0] & PINFO_TID_MASK; break; } } @@ -4668,7 +4272,7 @@ static u8 GetActivePartnerSpriteGenderParam(struct UnkStruct_URoom * uroom) return retVal; } -static void ViewURoomPartnerTrainerCard(u8 *unused, struct UnkStruct_URoom * uroom, bool8 parent_child) +static void ViewURoomPartnerTrainerCard(u8 *unused, struct WirelessLink_URoom * uroom, bool8 isParent) { struct TrainerCard * trainerCard = &gTrainerCards[GetMultiplayerId() ^ 1]; s32 i; @@ -4676,61 +4280,57 @@ static void ViewURoomPartnerTrainerCard(u8 *unused, struct UnkStruct_URoom * uro DynamicPlaceholderTextUtil_Reset(); - StringCopy(uroom->trainerCardStrbufs[0], gTrainerClassNames[GetUnionRoomTrainerClass()]); - DynamicPlaceholderTextUtil_SetPlaceholderPtr(0, uroom->trainerCardStrbufs[0]); + StringCopy(uroom->trainerCardStrBuffer[0], gTrainerClassNames[GetUnionRoomTrainerClass()]); + DynamicPlaceholderTextUtil_SetPlaceholderPtr(0, uroom->trainerCardStrBuffer[0]); DynamicPlaceholderTextUtil_SetPlaceholderPtr(1, trainerCard->rse.playerName); - StringCopy(uroom->field_174, gTexts_UR_CardColor[trainerCard->rse.stars]); - DynamicPlaceholderTextUtil_SetPlaceholderPtr(2, uroom->field_174); + StringCopy(uroom->trainerCardColorStrBuffer, gTexts_UR_CardColor[trainerCard->rse.stars]); + DynamicPlaceholderTextUtil_SetPlaceholderPtr(2, uroom->trainerCardColorStrBuffer); - ConvertIntToDecimalStringN(uroom->trainerCardStrbufs[2], trainerCard->rse.caughtMonsCount, STR_CONV_MODE_LEFT_ALIGN, 3); - DynamicPlaceholderTextUtil_SetPlaceholderPtr(3, uroom->trainerCardStrbufs[2]); + ConvertIntToDecimalStringN(uroom->trainerCardStrBuffer[2], trainerCard->rse.caughtMonsCount, STR_CONV_MODE_LEFT_ALIGN, 3); + DynamicPlaceholderTextUtil_SetPlaceholderPtr(3, uroom->trainerCardStrBuffer[2]); - ConvertIntToDecimalStringN(uroom->trainerCardStrbufs[3], trainerCard->rse.playTimeHours, STR_CONV_MODE_LEFT_ALIGN, 3); - ConvertIntToDecimalStringN(uroom->trainerCardStrbufs[4], trainerCard->rse.playTimeMinutes, STR_CONV_MODE_LEADING_ZEROS, 2); - DynamicPlaceholderTextUtil_SetPlaceholderPtr(4, uroom->trainerCardStrbufs[3]); - DynamicPlaceholderTextUtil_SetPlaceholderPtr(5, uroom->trainerCardStrbufs[4]); + ConvertIntToDecimalStringN(uroom->trainerCardStrBuffer[3], trainerCard->rse.playTimeHours, STR_CONV_MODE_LEFT_ALIGN, 3); + ConvertIntToDecimalStringN(uroom->trainerCardStrBuffer[4], trainerCard->rse.playTimeMinutes, STR_CONV_MODE_LEADING_ZEROS, 2); + DynamicPlaceholderTextUtil_SetPlaceholderPtr(4, uroom->trainerCardStrBuffer[3]); + DynamicPlaceholderTextUtil_SetPlaceholderPtr(5, uroom->trainerCardStrBuffer[4]); - DynamicPlaceholderTextUtil_ExpandPlaceholders(uroom->field_1A4, gText_UR_TrainerCardInfoPage1); - StringCopy(gStringVar4, uroom->field_1A4); + DynamicPlaceholderTextUtil_ExpandPlaceholders(uroom->trainerCardMsgStrBuffer, gText_UR_TrainerCardInfoPage1); + StringCopy(gStringVar4, uroom->trainerCardMsgStrBuffer); n = trainerCard->rse.linkBattleWins; if (n > 9999) - { n = 9999; - } - ConvertIntToDecimalStringN(uroom->trainerCardStrbufs[0], n, STR_CONV_MODE_LEFT_ALIGN, 4); - DynamicPlaceholderTextUtil_SetPlaceholderPtr(0, uroom->trainerCardStrbufs[0]); + ConvertIntToDecimalStringN(uroom->trainerCardStrBuffer[0], n, STR_CONV_MODE_LEFT_ALIGN, 4); + DynamicPlaceholderTextUtil_SetPlaceholderPtr(0, uroom->trainerCardStrBuffer[0]); n = trainerCard->rse.linkBattleLosses; if (n > 9999) - { n = 9999; - } - ConvertIntToDecimalStringN(uroom->trainerCardStrbufs[1], n, STR_CONV_MODE_LEFT_ALIGN, 4); - DynamicPlaceholderTextUtil_SetPlaceholderPtr(2, uroom->trainerCardStrbufs[1]); + ConvertIntToDecimalStringN(uroom->trainerCardStrBuffer[1], n, STR_CONV_MODE_LEFT_ALIGN, 4); + DynamicPlaceholderTextUtil_SetPlaceholderPtr(2, uroom->trainerCardStrBuffer[1]); - ConvertIntToDecimalStringN(uroom->trainerCardStrbufs[2], trainerCard->rse.pokemonTrades, STR_CONV_MODE_LEFT_ALIGN, 5); - DynamicPlaceholderTextUtil_SetPlaceholderPtr(3, uroom->trainerCardStrbufs[2]); + ConvertIntToDecimalStringN(uroom->trainerCardStrBuffer[2], trainerCard->rse.pokemonTrades, STR_CONV_MODE_LEFT_ALIGN, 5); + DynamicPlaceholderTextUtil_SetPlaceholderPtr(3, uroom->trainerCardStrBuffer[2]); for (i = 0; i < TRAINER_CARD_PROFILE_LENGTH; i++) { - CopyEasyChatWord(uroom->trainerCardStrbufs[i + 3], trainerCard->rse.easyChatProfile[i]); - DynamicPlaceholderTextUtil_SetPlaceholderPtr(i + 4, uroom->trainerCardStrbufs[i + 3]); + CopyEasyChatWord(uroom->trainerCardStrBuffer[i + 3], trainerCard->rse.easyChatProfile[i]); + DynamicPlaceholderTextUtil_SetPlaceholderPtr(i + 4, uroom->trainerCardStrBuffer[i + 3]); } - DynamicPlaceholderTextUtil_ExpandPlaceholders(uroom->field_1A4, gText_UR_TrainerCardInfoPage2); - StringAppend(gStringVar4, uroom->field_1A4); + DynamicPlaceholderTextUtil_ExpandPlaceholders(uroom->trainerCardMsgStrBuffer, gText_UR_TrainerCardInfoPage2); + StringAppend(gStringVar4, uroom->trainerCardMsgStrBuffer); - if (parent_child == MODE_PARENT) + if (isParent == TRUE) { - DynamicPlaceholderTextUtil_ExpandPlaceholders(uroom->field_1A4, gText_UR_FinishedCheckingPlayersTrainerCard); - StringAppend(gStringVar4, uroom->field_1A4); + DynamicPlaceholderTextUtil_ExpandPlaceholders(uroom->trainerCardMsgStrBuffer, gText_UR_FinishedCheckingPlayersTrainerCard); + StringAppend(gStringVar4, uroom->trainerCardMsgStrBuffer); } - else if (parent_child == MODE_CHILD) + else if (isParent == FALSE) { - DynamicPlaceholderTextUtil_ExpandPlaceholders(uroom->field_1A4, gTexts_UR_GladToMeetYou[trainerCard->rse.gender]); - StringAppend(gStringVar4, uroom->field_1A4); + DynamicPlaceholderTextUtil_ExpandPlaceholders(uroom->trainerCardMsgStrBuffer, gTexts_UR_GladToMeetYou[trainerCard->rse.gender]); + StringAppend(gStringVar4, uroom->trainerCardMsgStrBuffer); } } diff --git a/src/wireless_communication_status_screen.c b/src/wireless_communication_status_screen.c index 97131a768..b6f018a9a 100644 --- a/src/wireless_communication_status_screen.c +++ b/src/wireless_communication_status_screen.c @@ -121,29 +121,29 @@ static const u8 sCountParams[][3] = { // activity, count idx, by // by=0 means count all // UB: no check for count idx == -1 - {ACTIVITY_BATTLE, 1, 2}, - {ACTIVITY_DBLBATTLE, 1, 2}, - {ACTIVITY_MLTBATTLE, 1, 4}, - {ACTIVITY_TRADE, 0, 2}, - {ACTIVITY_WCARD2, 3, 2}, - {ACTIVITY_WNEWS2, 3, 2}, - {ACTIVITY_PJUMP, 4, 0}, - {ACTIVITY_BCRUSH, 4, 0}, - {ACTIVITY_BPICK, 4, 0}, - {ACTIVITY_SEARCH, -1, 0}, - {ACTIVITY_SPINTRADE, 0, 0}, - {ACTIVITY_ITEMTRADE, -1, 0}, - {0x0f, 4, 0}, - {0x10, -1, 0}, - {0x40, 2, 1}, - {ACTIVITY_BATTLE | 0x40, 2, 2}, - {ACTIVITY_TRADE | 0x40, 2, 2}, - {ACTIVITY_CHAT | 0x40, 2, 0}, - {ACTIVITY_CARD | 0x40, 2, 2}, - {20 | 0x40, 2, 1}, - {19 | 0x40, 2, 2}, - {ACTIVITY_ACCEPT | 0x40, 2, 1}, - {ACTIVITY_DECLINE | 0x40, 2, 1} + {ACTIVITY_BATTLE_SINGLE, 1, 2}, + {ACTIVITY_BATTLE_DOUBLE, 1, 2}, + {ACTIVITY_BATTLE_MULTI, 1, 4}, + {ACTIVITY_TRADE, 0, 2}, + {ACTIVITY_WONDER_CARD, 3, 2}, + {ACTIVITY_WONDER_NEWS, 3, 2}, + {ACTIVITY_POKEMON_JUMP, 4, 0}, + {ACTIVITY_BERRY_CRUSH, 4, 0}, + {ACTIVITY_BERRY_PICK, 4, 0}, + {ACTIVITY_SEARCH, -1, 0}, + {ACTIVITY_SPIN_TRADE, 0, 0}, + {ACTIVITY_ITEM_TRADE, -1, 0}, + {ACTIVITY_RECORD_CORNER, 4, 0}, + {ACTIVITY_BERRY_BLENDER, -1, 0}, + {ACTIVITY_NONE | IN_UNION_ROOM, 2, 1}, + {ACTIVITY_BATTLE_SINGLE | IN_UNION_ROOM, 2, 2}, + {ACTIVITY_TRADE | IN_UNION_ROOM, 2, 2}, + {ACTIVITY_CHAT | IN_UNION_ROOM, 2, 0}, + {ACTIVITY_CARD | IN_UNION_ROOM, 2, 2}, + {ACTIVITY_PLYRTALK | IN_UNION_ROOM, 2, 1}, + {ACTIVITY_NPCTALK | IN_UNION_ROOM, 2, 2}, + {ACTIVITY_ACCEPT | IN_UNION_ROOM, 2, 1}, + {ACTIVITY_DECLINE | IN_UNION_ROOM, 2, 1} }; static void CB2_RunWirelessCommunicationScreen(void) @@ -352,9 +352,9 @@ static void WCSS_AddTextPrinterParameterized(u8 windowId, u8 fontId, const u8 * AddTextPrinterParameterized4(windowId, fontId, x, y, fontId == FONT_0 ? 0 : 1, 0, textColor, -1, str); } -static u32 CountMembersInGroup(struct UnkStruct_x20 * unk20, u32 * counts) +static u32 CountMembersInGroup(struct RfuPlayer * unk20, u32 * counts) { - u32 activity = unk20->gname_uname.gname.activity; + u32 activity = unk20->rfu.data.activity; s32 i, j, k; for (i = 0; i < NELEMS(sCountParams); i++) @@ -366,7 +366,7 @@ static u32 CountMembersInGroup(struct UnkStruct_x20 * unk20, u32 * counts) k = 0; for (j = 0; j < RFU_CHILD_MAX; j++) { - if (unk20->gname_uname.gname.partnerInfo[j] != 0) k++; + if (unk20->rfu.data.partnerInfo[j] != 0) k++; } k++; counts[sCountParams[i][1]] += k; @@ -398,12 +398,12 @@ static bool32 UpdateCommunicationCounts(u32 * counts, u32 * lastCounts, u32 * ac { bool32 activitiesUpdated = FALSE; u32 buffer[4] = {0, 0, 0, 0}; - struct UnkStruct_Group * group = (void *)gTasks[taskId].data; + struct WirelessLink_Group * group = (void *)gTasks[taskId].data; s32 i; for (i = 0; i < 16; i++) { - u32 activity = CountMembersInGroup(&group->field_0->arr[i], buffer); + u32 activity = CountMembersInGroup(&group->playerList->players[i], buffer); if (activity != activities[i]) { activities[i] = activity; From 5ce573fca1ce2fa80baff3a6e441716723afe9b4 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Tue, 8 Nov 2022 02:05:33 -0500 Subject: [PATCH 5/8] Sync wireless_communication_status_screen --- graphics/misc/unk_846f4f0.pal | 19 - .../anim_00.pal} | 0 .../anim_01.pal} | 0 .../anim_02.pal} | 0 .../anim_03.pal} | 0 .../anim_04.pal} | 0 .../anim_05.pal} | 0 .../anim_06.pal} | 0 .../anim_07.pal} | 0 .../anim_08.pal} | 0 .../anim_09.pal} | 0 .../anim_10.pal} | 0 .../anim_11.pal} | 0 .../anim_12.pal} | 0 .../anim_13.pal} | 0 .../bg.bin} | Bin .../bg.png} | Bin .../default.pal} | 0 src/wireless_communication_status_screen.c | 357 ++++++++++-------- 19 files changed, 194 insertions(+), 182 deletions(-) delete mode 100644 graphics/misc/unk_846f4f0.pal rename graphics/{misc/unk_846f510.pal => wireless_status_screen/anim_00.pal} (100%) rename graphics/{misc/unk_846f530.pal => wireless_status_screen/anim_01.pal} (100%) rename graphics/{misc/unk_846f550.pal => wireless_status_screen/anim_02.pal} (100%) rename graphics/{misc/unk_846f570.pal => wireless_status_screen/anim_03.pal} (100%) rename graphics/{misc/unk_846f590.pal => wireless_status_screen/anim_04.pal} (100%) rename graphics/{misc/unk_846f5b0.pal => wireless_status_screen/anim_05.pal} (100%) rename graphics/{misc/unk_846f5d0.pal => wireless_status_screen/anim_06.pal} (100%) rename graphics/{misc/unk_846f5f0.pal => wireless_status_screen/anim_07.pal} (100%) rename graphics/{misc/unk_846f610.pal => wireless_status_screen/anim_08.pal} (100%) rename graphics/{misc/unk_846f630.pal => wireless_status_screen/anim_09.pal} (100%) rename graphics/{misc/unk_846f650.pal => wireless_status_screen/anim_10.pal} (100%) rename graphics/{misc/unk_846f670.pal => wireless_status_screen/anim_11.pal} (100%) rename graphics/{misc/unk_846f690.pal => wireless_status_screen/anim_12.pal} (100%) rename graphics/{misc/unk_846f4d0.pal => wireless_status_screen/anim_13.pal} (100%) rename graphics/{misc/unk_846f8e0.bin => wireless_status_screen/bg.bin} (100%) rename graphics/{misc/unk_846f6d0.png => wireless_status_screen/bg.png} (100%) rename graphics/{misc/unk_846f6b0.pal => wireless_status_screen/default.pal} (100%) diff --git a/graphics/misc/unk_846f4f0.pal b/graphics/misc/unk_846f4f0.pal deleted file mode 100644 index 4b0812f09..000000000 --- a/graphics/misc/unk_846f4f0.pal +++ /dev/null @@ -1,19 +0,0 @@ -JASC-PAL -0100 -16 -0 0 0 -0 0 0 -0 0 0 -0 0 0 -0 0 0 -0 0 0 -0 0 0 -0 0 0 -0 0 0 -0 0 0 -0 0 0 -0 0 0 -0 0 0 -0 0 0 -0 0 0 -0 0 0 diff --git a/graphics/misc/unk_846f510.pal b/graphics/wireless_status_screen/anim_00.pal similarity index 100% rename from graphics/misc/unk_846f510.pal rename to graphics/wireless_status_screen/anim_00.pal diff --git a/graphics/misc/unk_846f530.pal b/graphics/wireless_status_screen/anim_01.pal similarity index 100% rename from graphics/misc/unk_846f530.pal rename to graphics/wireless_status_screen/anim_01.pal diff --git a/graphics/misc/unk_846f550.pal b/graphics/wireless_status_screen/anim_02.pal similarity index 100% rename from graphics/misc/unk_846f550.pal rename to graphics/wireless_status_screen/anim_02.pal diff --git a/graphics/misc/unk_846f570.pal b/graphics/wireless_status_screen/anim_03.pal similarity index 100% rename from graphics/misc/unk_846f570.pal rename to graphics/wireless_status_screen/anim_03.pal diff --git a/graphics/misc/unk_846f590.pal b/graphics/wireless_status_screen/anim_04.pal similarity index 100% rename from graphics/misc/unk_846f590.pal rename to graphics/wireless_status_screen/anim_04.pal diff --git a/graphics/misc/unk_846f5b0.pal b/graphics/wireless_status_screen/anim_05.pal similarity index 100% rename from graphics/misc/unk_846f5b0.pal rename to graphics/wireless_status_screen/anim_05.pal diff --git a/graphics/misc/unk_846f5d0.pal b/graphics/wireless_status_screen/anim_06.pal similarity index 100% rename from graphics/misc/unk_846f5d0.pal rename to graphics/wireless_status_screen/anim_06.pal diff --git a/graphics/misc/unk_846f5f0.pal b/graphics/wireless_status_screen/anim_07.pal similarity index 100% rename from graphics/misc/unk_846f5f0.pal rename to graphics/wireless_status_screen/anim_07.pal diff --git a/graphics/misc/unk_846f610.pal b/graphics/wireless_status_screen/anim_08.pal similarity index 100% rename from graphics/misc/unk_846f610.pal rename to graphics/wireless_status_screen/anim_08.pal diff --git a/graphics/misc/unk_846f630.pal b/graphics/wireless_status_screen/anim_09.pal similarity index 100% rename from graphics/misc/unk_846f630.pal rename to graphics/wireless_status_screen/anim_09.pal diff --git a/graphics/misc/unk_846f650.pal b/graphics/wireless_status_screen/anim_10.pal similarity index 100% rename from graphics/misc/unk_846f650.pal rename to graphics/wireless_status_screen/anim_10.pal diff --git a/graphics/misc/unk_846f670.pal b/graphics/wireless_status_screen/anim_11.pal similarity index 100% rename from graphics/misc/unk_846f670.pal rename to graphics/wireless_status_screen/anim_11.pal diff --git a/graphics/misc/unk_846f690.pal b/graphics/wireless_status_screen/anim_12.pal similarity index 100% rename from graphics/misc/unk_846f690.pal rename to graphics/wireless_status_screen/anim_12.pal diff --git a/graphics/misc/unk_846f4d0.pal b/graphics/wireless_status_screen/anim_13.pal similarity index 100% rename from graphics/misc/unk_846f4d0.pal rename to graphics/wireless_status_screen/anim_13.pal diff --git a/graphics/misc/unk_846f8e0.bin b/graphics/wireless_status_screen/bg.bin similarity index 100% rename from graphics/misc/unk_846f8e0.bin rename to graphics/wireless_status_screen/bg.bin diff --git a/graphics/misc/unk_846f6d0.png b/graphics/wireless_status_screen/bg.png similarity index 100% rename from graphics/misc/unk_846f6d0.png rename to graphics/wireless_status_screen/bg.png diff --git a/graphics/misc/unk_846f6b0.pal b/graphics/wireless_status_screen/default.pal similarity index 100% rename from graphics/misc/unk_846f6b0.pal rename to graphics/wireless_status_screen/default.pal diff --git a/src/wireless_communication_status_screen.c b/src/wireless_communication_status_screen.c index b6f018a9a..971db680f 100644 --- a/src/wireless_communication_status_screen.c +++ b/src/wireless_communication_status_screen.c @@ -14,46 +14,60 @@ #include "constants/songs.h" #include "constants/union_room.h" -struct WirelessCommunicationStatusScreenStruct -{ - u32 counts[4]; - u32 lastCounts[4]; - u32 activities[16]; - u8 taskId; - u8 rfuTaskId; - u8 filler_62[0xA]; +enum { + COLOR_NONE, + COLOR_NORMAL, + COLOR_TOTAL, + COLOR_TITLE, + COLOR_UNUSED, }; -static struct WirelessCommunicationStatusScreenStruct * sWCSS; +enum { + GROUPTYPE_NONE = -1, + GROUPTYPE_TRADE, + GROUPTYPE_BATTLE, + GROUPTYPE_UNION, + GROUPTYPE_TOTAL, + NUM_GROUPTYPES +}; + +static struct +{ + u32 groupCounts[NUM_GROUPTYPES]; + u32 prevGroupCounts[NUM_GROUPTYPES]; + u32 activities[NUM_TASK_DATA]; + u8 taskId; + u8 rfuTaskId; + u8 filler[10]; +} * sStatusScreen; static void CB2_InitWirelessCommunicationScreen(void); static void Task_WirelessCommunicationScreen(u8 taskId); static void WCSS_AddTextPrinterParameterized(u8 windowId, u8 fontId, const u8 * str, u8 x, u8 y, u8 palIdx); static bool32 UpdateCommunicationCounts(u32 * counts, u32 * lastCounts, u32 * activities, u8 taskId); -static const u16 sWCSS_Palettes[][16] = { - INCBIN_U16("graphics/misc/unk_846f4d0.gbapal"), - INCBIN_U16("graphics/misc/unk_846f4f0.gbapal"), - INCBIN_U16("graphics/misc/unk_846f510.gbapal"), - INCBIN_U16("graphics/misc/unk_846f530.gbapal"), - INCBIN_U16("graphics/misc/unk_846f550.gbapal"), - INCBIN_U16("graphics/misc/unk_846f570.gbapal"), - INCBIN_U16("graphics/misc/unk_846f590.gbapal"), - INCBIN_U16("graphics/misc/unk_846f5b0.gbapal"), - INCBIN_U16("graphics/misc/unk_846f5d0.gbapal"), - INCBIN_U16("graphics/misc/unk_846f5f0.gbapal"), - INCBIN_U16("graphics/misc/unk_846f610.gbapal"), - INCBIN_U16("graphics/misc/unk_846f630.gbapal"), - INCBIN_U16("graphics/misc/unk_846f650.gbapal"), - INCBIN_U16("graphics/misc/unk_846f670.gbapal"), - INCBIN_U16("graphics/misc/unk_846f690.gbapal"), - INCBIN_U16("graphics/misc/unk_846f6b0.gbapal") +static const u16 sPalettes[][16] = { + INCBIN_U16("graphics/wireless_status_screen/default.gbapal"), + {}, // All black. Never read + INCBIN_U16("graphics/wireless_status_screen/anim_00.gbapal"), + INCBIN_U16("graphics/wireless_status_screen/anim_01.gbapal"), + INCBIN_U16("graphics/wireless_status_screen/anim_02.gbapal"), + INCBIN_U16("graphics/wireless_status_screen/anim_03.gbapal"), + INCBIN_U16("graphics/wireless_status_screen/anim_04.gbapal"), + INCBIN_U16("graphics/wireless_status_screen/anim_05.gbapal"), + INCBIN_U16("graphics/wireless_status_screen/anim_06.gbapal"), + INCBIN_U16("graphics/wireless_status_screen/anim_07.gbapal"), + INCBIN_U16("graphics/wireless_status_screen/anim_08.gbapal"), + INCBIN_U16("graphics/wireless_status_screen/anim_09.gbapal"), + INCBIN_U16("graphics/wireless_status_screen/anim_10.gbapal"), + INCBIN_U16("graphics/wireless_status_screen/anim_11.gbapal"), + INCBIN_U16("graphics/wireless_status_screen/anim_12.gbapal"), + INCBIN_U16("graphics/wireless_status_screen/anim_13.gbapal") }; +static const u32 sBgTiles_Gfx[] = INCBIN_U32("graphics/wireless_status_screen/bg.4bpp.lz"); +static const u16 sBgTiles_Tilemap[] = INCBIN_U16("graphics/wireless_status_screen/bg.bin"); -static const u32 sBgTilesGfx[] = INCBIN_U32("graphics/misc/unk_846f6d0.4bpp.lz"); -static const u16 sBgTilemap[] = INCBIN_U16("graphics/misc/unk_846f8e0.bin"); - -static const struct BgTemplate sBGTemplates[] = { +static const struct BgTemplate sBgTemplates[] = { { .bg = 0, .charBaseIndex = 2, @@ -75,29 +89,29 @@ static const struct BgTemplate sBGTemplates[] = { static const struct WindowTemplate sWindowTemplates[] = { { - .bg = 0x00, - .tilemapLeft = 0x03, - .tilemapTop = 0x00, - .width = 0x18, - .height = 0x03, - .paletteNum = 0x0f, - .baseBlock = 0x0001 + .bg = 0, + .tilemapLeft = 3, + .tilemapTop = 0, + .width = 24, + .height = 3, + .paletteNum = 15, + .baseBlock = 0x001 }, { - .bg = 0x00, - .tilemapLeft = 0x03, - .tilemapTop = 0x04, - .width = 0x16, - .height = 0x0f, - .paletteNum = 0x0f, - .baseBlock = 0x0049 + .bg = 0, + .tilemapLeft = 3, + .tilemapTop = 4, + .width = 22, + .height = 15, + .paletteNum = 15, + .baseBlock = 0x049 }, { - .bg = 0x00, - .tilemapLeft = 0x19, - .tilemapTop = 0x04, - .width = 0x02, - .height = 0x0f, - .paletteNum = 0x0f, - .baseBlock = 0x0193 + .bg = 0, + .tilemapLeft = 25, + .tilemapTop = 4, + .width = 2, + .height = 15, + .paletteNum = 15, + .baseBlock = 0x193 }, DUMMY_WIN_TEMPLATE }; @@ -109,41 +123,43 @@ static const u8 *const sPlayersTextPtrs[] = { gText_Dynamic3Players }; -static const u8 *const sHeaderTextPtrs[] = { - gText_WirelessCommunicationStatus, - gText_PeopleTrading, - gText_PeopleBattling, - gText_PeopleInUnionRoom, - gText_PeopleCommunicating +static const u8 *const sHeaderTexts[NUM_GROUPTYPES + 1] = { + [0] = gText_WirelessCommunicationStatus, + [GROUPTYPE_TRADE + 1] = gText_PeopleTrading, + [GROUPTYPE_BATTLE + 1] = gText_PeopleBattling, + [GROUPTYPE_UNION + 1] = gText_PeopleInUnionRoom, + [GROUPTYPE_TOTAL + 1] = gText_PeopleCommunicating }; -static const u8 sCountParams[][3] = { - // activity, count idx, by - // by=0 means count all - // UB: no check for count idx == -1 - {ACTIVITY_BATTLE_SINGLE, 1, 2}, - {ACTIVITY_BATTLE_DOUBLE, 1, 2}, - {ACTIVITY_BATTLE_MULTI, 1, 4}, - {ACTIVITY_TRADE, 0, 2}, - {ACTIVITY_WONDER_CARD, 3, 2}, - {ACTIVITY_WONDER_NEWS, 3, 2}, - {ACTIVITY_POKEMON_JUMP, 4, 0}, - {ACTIVITY_BERRY_CRUSH, 4, 0}, - {ACTIVITY_BERRY_PICK, 4, 0}, - {ACTIVITY_SEARCH, -1, 0}, - {ACTIVITY_SPIN_TRADE, 0, 0}, - {ACTIVITY_ITEM_TRADE, -1, 0}, - {ACTIVITY_RECORD_CORNER, 4, 0}, - {ACTIVITY_BERRY_BLENDER, -1, 0}, - {ACTIVITY_NONE | IN_UNION_ROOM, 2, 1}, - {ACTIVITY_BATTLE_SINGLE | IN_UNION_ROOM, 2, 2}, - {ACTIVITY_TRADE | IN_UNION_ROOM, 2, 2}, - {ACTIVITY_CHAT | IN_UNION_ROOM, 2, 0}, - {ACTIVITY_CARD | IN_UNION_ROOM, 2, 2}, - {ACTIVITY_PLYRTALK | IN_UNION_ROOM, 2, 1}, - {ACTIVITY_NPCTALK | IN_UNION_ROOM, 2, 2}, - {ACTIVITY_ACCEPT | IN_UNION_ROOM, 2, 1}, - {ACTIVITY_DECLINE | IN_UNION_ROOM, 2, 1} +// Activity, group type, number of players +// 0 players means the number of players can change and should be counted dynamically +// GROUPTYPE_TOTAL have no unique group and are simply counted in the total of "people communicating". +// A handful use NUM_GROUPTYPES, which is invalid, and are changed to GROUPTYPE_TOTAL in Emerald. +// UB: GROUPTYPE_NONE (-1) can potentially be used as an index into a u8[4] in CountPlayersInGroupAndGetActivity. +static const u8 sActivityGroupInfo[][3] = { + {ACTIVITY_BATTLE_SINGLE, GROUPTYPE_BATTLE, 2}, + {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_POKEMON_JUMP, NUM_GROUPTYPES, 0}, + {ACTIVITY_BERRY_CRUSH, NUM_GROUPTYPES, 0}, + {ACTIVITY_BERRY_PICK, NUM_GROUPTYPES, 0}, + {ACTIVITY_SEARCH, GROUPTYPE_NONE, 0}, + {ACTIVITY_SPIN_TRADE, GROUPTYPE_TRADE, 0}, + {ACTIVITY_ITEM_TRADE, GROUPTYPE_NONE, 0}, + {ACTIVITY_RECORD_CORNER, NUM_GROUPTYPES, 0}, + {ACTIVITY_BERRY_BLENDER, GROUPTYPE_NONE, 0}, + {ACTIVITY_NONE | IN_UNION_ROOM, GROUPTYPE_UNION, 1}, + {ACTIVITY_BATTLE_SINGLE | IN_UNION_ROOM, GROUPTYPE_UNION, 2}, + {ACTIVITY_TRADE | IN_UNION_ROOM, GROUPTYPE_UNION, 2}, + {ACTIVITY_CHAT | IN_UNION_ROOM, GROUPTYPE_UNION, 0}, + {ACTIVITY_CARD | IN_UNION_ROOM, GROUPTYPE_UNION, 2}, + {ACTIVITY_PLYRTALK | IN_UNION_ROOM, GROUPTYPE_UNION, 1}, + {ACTIVITY_NPCTALK | IN_UNION_ROOM, GROUPTYPE_UNION, 2}, + {ACTIVITY_ACCEPT | IN_UNION_ROOM, GROUPTYPE_UNION, 1}, + {ACTIVITY_DECLINE | IN_UNION_ROOM, GROUPTYPE_UNION, 1} }; static void CB2_RunWirelessCommunicationScreen(void) @@ -173,14 +189,14 @@ void ShowWirelessCommunicationScreen(void) static void CB2_InitWirelessCommunicationScreen(void) { SetGpuReg(REG_OFFSET_DISPCNT, 0); - sWCSS = AllocZeroed(sizeof(*sWCSS)); + sStatusScreen = AllocZeroed(sizeof(*sStatusScreen)); SetVBlankCallback(NULL); ResetBgsAndClearDma3BusyFlags(FALSE); - InitBgsFromTemplates(0, sBGTemplates, NELEMS(sBGTemplates)); - SetBgTilemapBuffer(1, Alloc(0x800)); - SetBgTilemapBuffer(0, Alloc(0x800)); - DecompressAndLoadBgGfxUsingHeap(1, sBgTilesGfx, 0, 0, 0); - CopyToBgTilemapBuffer(1, sBgTilemap, 0, 0); + InitBgsFromTemplates(0, sBgTemplates, ARRAY_COUNT(sBgTemplates)); + SetBgTilemapBuffer(1, Alloc(BG_SCREEN_SIZE)); + SetBgTilemapBuffer(0, Alloc(BG_SCREEN_SIZE)); + DecompressAndLoadBgGfxUsingHeap(1, sBgTiles_Gfx, 0, 0, 0); + CopyToBgTilemapBuffer(1, sBgTiles_Tilemap, 0, 0); InitWindows(sWindowTemplates); DeactivateAllTextPrinters(); ResetPaletteFade(); @@ -189,14 +205,14 @@ static void CB2_InitWirelessCommunicationScreen(void) ScanlineEffect_Stop(); m4aSoundVSyncOn(); SetVBlankCallback(VBlankCB_WirelessCommunicationScreen); - sWCSS->taskId = CreateTask(Task_WirelessCommunicationScreen, 0); - sWCSS->rfuTaskId = CreateTask_ListenToWireless(); - sWCSS->lastCounts[3] = 1; - ChangeBgX(0, 0, 0); - ChangeBgY(0, 0, 0); - ChangeBgX(1, 0, 0); - ChangeBgY(1, 0, 0); - LoadPalette(sWCSS_Palettes, 0, 0x20); + sStatusScreen->taskId = CreateTask(Task_WirelessCommunicationScreen, 0); + sStatusScreen->rfuTaskId = CreateTask_ListenToWireless(); + sStatusScreen->prevGroupCounts[3] = 1; + ChangeBgX(0, 0, BG_COORD_SET); + ChangeBgY(0, 0, BG_COORD_SET); + ChangeBgX(1, 0, BG_COORD_SET); + ChangeBgY(1, 0, BG_COORD_SET); + LoadPalette(sPalettes, 0, 0x20); Menu_LoadStdPalAt(0xf0); DynamicPlaceholderTextUtil_Reset(); FillBgTilemapBufferRect(0, 0x000, 0, 0, 32, 32, 0xF); @@ -214,29 +230,24 @@ static void ExitWirelessCommunicationStatusScreen(void) s32 i; FreeAllWindowBuffers(); - for (i = 0; i < 2; i++) - { + for (i = 0; i < (int)ARRAY_COUNT(sBgTemplates); i++) Free(GetBgTilemapBuffer(i)); - } - Free(sWCSS); + Free(sStatusScreen); SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic); } -static void WCSS_CyclePalette(s16 * frameCtr_p, s16 * palIdx_p) +// Cycle through palettes that relocate various shades of blue to create the wave effect at the bottom of the screen. +static void CyclePalette(s16 * counter, s16 * palIdx) { s32 idx; - (*frameCtr_p)++; - if (*frameCtr_p > 5) + if (++(*counter) > 5) { - (*palIdx_p)++; - if (*palIdx_p == 14) - { - *palIdx_p = 0; - } - *frameCtr_p = 0; + if (++(*palIdx) == (int)ARRAY_COUNT(sPalettes) - 2) + *palIdx = 0; + *counter = 0; } - idx = *palIdx_p + 2; - LoadPalette(sWCSS_Palettes[idx], 0, 16); + idx = *palIdx + 2; // +2 skips over default.pal and the empty black palette after it + LoadPalette(sPalettes[idx], 0, 16); } static void PrintHeaderTexts(void) @@ -247,50 +258,57 @@ static void PrintHeaderTexts(void) FillWindowPixelBuffer(0, PIXEL_FILL(0)); FillWindowPixelBuffer(1, PIXEL_FILL(0)); FillWindowPixelBuffer(2, PIXEL_FILL(0)); - width = 0xC0 - GetStringWidth(FONT_3, sHeaderTextPtrs[0], 0); - WCSS_AddTextPrinterParameterized(0, FONT_3, sHeaderTextPtrs[0], width / 2, 6, 3); - for (i = 0; i < 3; i++) - { - WCSS_AddTextPrinterParameterized(1, FONT_3, sHeaderTextPtrs[i + 1], 0, 30 * i + 10, 1); - } - WCSS_AddTextPrinterParameterized(1, FONT_3, sHeaderTextPtrs[i + 1], 0, 30 * i + 10, 2); + + // Print title + width = 192 - GetStringWidth(FONT_3, sHeaderTexts[0], 0); + WCSS_AddTextPrinterParameterized(0, FONT_3, sHeaderTexts[0], width / 2, 6, COLOR_TITLE); + + // Print label for each group (excluding total) + for (i = 0; i < NUM_GROUPTYPES - 1; i++) + WCSS_AddTextPrinterParameterized(1, FONT_3, sHeaderTexts[i + 1], 0, 30 * i + 10, COLOR_NORMAL); + + // Print label for total + WCSS_AddTextPrinterParameterized(1, FONT_3, sHeaderTexts[i + 1], 0, 30 * i + 10, COLOR_TOTAL); + PutWindowTilemap(0); CopyWindowToVram(0, COPYWIN_GFX); PutWindowTilemap(1); CopyWindowToVram(1, COPYWIN_GFX); } +#define tState data[0] + static void Task_WirelessCommunicationScreen(u8 taskId) { s32 i; - switch (gTasks[taskId].data[0]) + switch (gTasks[taskId].tState) { case 0: PrintHeaderTexts(); - gTasks[taskId].data[0]++; + gTasks[taskId].tState++; break; case 1: BeginNormalPaletteFade(PALETTES_ALL, 0, 16, 0, RGB_BLACK); ShowBg(1); CopyBgTilemapBufferToVram(0); ShowBg(0); - gTasks[taskId].data[0]++; + gTasks[taskId].tState++; break; case 2: if (!gPaletteFade.active) - gTasks[taskId].data[0]++; + gTasks[taskId].tState++; break; case 3: - if (UpdateCommunicationCounts(sWCSS->counts, sWCSS->lastCounts, sWCSS->activities, sWCSS->rfuTaskId)) + if (UpdateCommunicationCounts(sStatusScreen->groupCounts, sStatusScreen->prevGroupCounts, sStatusScreen->activities, sStatusScreen->rfuTaskId)) { FillWindowPixelBuffer(2, PIXEL_FILL(0)); - for (i = 0; i < 4; i++) + for (i = 0; i < NUM_GROUPTYPES; i++) { - ConvertIntToDecimalStringN(gStringVar4, sWCSS->counts[i], STR_CONV_MODE_RIGHT_ALIGN, 2); - if (i != 3) - WCSS_AddTextPrinterParameterized(2, FONT_3, gStringVar4, 4, 30 * i + 10, 1); + ConvertIntToDecimalStringN(gStringVar4, sStatusScreen->groupCounts[i], STR_CONV_MODE_RIGHT_ALIGN, 2); + if (i != GROUPTYPE_TOTAL) + WCSS_AddTextPrinterParameterized(2, FONT_3, gStringVar4, 4, 30 * i + 10, COLOR_NORMAL); else - WCSS_AddTextPrinterParameterized(2, FONT_3, gStringVar4, 4, 100, 2); + WCSS_AddTextPrinterParameterized(2, FONT_3, gStringVar4, 4, 100, COLOR_TOTAL); } PutWindowTilemap(2); CopyWindowToVram(2, COPYWIN_FULL); @@ -298,14 +316,14 @@ static void Task_WirelessCommunicationScreen(u8 taskId) if (JOY_NEW(A_BUTTON) || JOY_NEW(B_BUTTON)) { PlaySE(SE_SELECT); - gTasks[sWCSS->rfuTaskId].data[15] = 0xFF; - gTasks[taskId].data[0]++; + gTasks[sStatusScreen->rfuTaskId].data[15] = 0xFF; + gTasks[taskId].tState++; } - WCSS_CyclePalette(&gTasks[taskId].data[7], &gTasks[taskId].data[8]); + CyclePalette(&gTasks[taskId].data[7], &gTasks[taskId].data[8]); break; case 4: BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK); - gTasks[taskId].data[0]++; + gTasks[taskId].tState++; break; case 5: if (!gPaletteFade.active) @@ -317,93 +335,99 @@ static void Task_WirelessCommunicationScreen(u8 taskId) } } -static void WCSS_AddTextPrinterParameterized(u8 windowId, u8 fontId, const u8 * str, u8 x, u8 y, u8 palIdx) +static void WCSS_AddTextPrinterParameterized(u8 windowId, u8 fontId, const u8 * str, u8 x, u8 y, u8 mode) { u8 textColor[3]; - switch (palIdx) + switch (mode) { - case 0: + case COLOR_NONE: // Unused. Default to usual text colors textColor[0] = TEXT_COLOR_TRANSPARENT; textColor[1] = TEXT_COLOR_DARK_GRAY; textColor[2] = TEXT_COLOR_LIGHT_GRAY; break; - case 1: + case COLOR_NORMAL: textColor[0] = TEXT_COLOR_TRANSPARENT; textColor[1] = TEXT_COLOR_WHITE; textColor[2] = TEXT_COLOR_LIGHT_GRAY; break; - case 2: + case COLOR_TOTAL: textColor[0] = TEXT_COLOR_TRANSPARENT; textColor[1] = TEXT_COLOR_RED; textColor[2] = TEXT_COLOR_LIGHT_RED; break; - case 3: + case COLOR_TITLE: textColor[0] = TEXT_COLOR_TRANSPARENT; textColor[1] = TEXT_COLOR_LIGHT_GREEN; textColor[2] = TEXT_COLOR_GREEN; break; - case 4: + case COLOR_UNUSED: textColor[0] = TEXT_COLOR_TRANSPARENT; textColor[1] = TEXT_COLOR_WHITE; textColor[2] = TEXT_COLOR_DARK_GRAY; break; // default: UB } - AddTextPrinterParameterized4(windowId, fontId, x, y, fontId == FONT_0 ? 0 : 1, 0, textColor, -1, str); + AddTextPrinterParameterized4(windowId, fontId, x, y, fontId == FONT_0 ? 0 : 1, 0, textColor, TEXT_SKIP_DRAW, str); } -static u32 CountMembersInGroup(struct RfuPlayer * unk20, u32 * counts) +static u32 CountPlayersInGroupAndGetActivity(struct RfuPlayer * player, u32 * groupCounts) { - u32 activity = unk20->rfu.data.activity; + u32 activity = player->rfu.data.activity; s32 i, j, k; - for (i = 0; i < NELEMS(sCountParams); i++) + #define group_activity(i) (sActivityGroupInfo[(i)][0]) + #define group_type(i) (sActivityGroupInfo[(i)][1]) + #define group_players(i) (sActivityGroupInfo[(i)][2]) + + for (i = 0; i < ARRAY_COUNT(sActivityGroupInfo); i++) { - if (activity == sCountParams[i][0] && unk20->groupScheduledAnim == UNION_ROOM_SPAWN_IN) + if (activity == group_activity(i) && player->groupScheduledAnim == UNION_ROOM_SPAWN_IN) { - if (sCountParams[i][2] == 0) + if (group_players(i) == 0) { k = 0; for (j = 0; j < RFU_CHILD_MAX; j++) - { - if (unk20->rfu.data.partnerInfo[j] != 0) k++; - } + if (player->rfu.data.partnerInfo[j] != 0) k++; k++; - counts[sCountParams[i][1]] += k; + groupCounts[group_type(i)] += k; } else { - counts[sCountParams[i][1]] += sCountParams[i][2]; + groupCounts[group_type(i)] += group_players(i); } } } return activity; + + #undef group_activity + #undef group_type + #undef group_players } -static bool32 HaveCountsChanged(const u32 * newCounts, const u32 * prevCounts) +static bool32 HaveCountsChanged(const u32 * curCounts, const u32 * prevCounts) { s32 i; - for (i = 0; i < 4; i++) + for (i = 0; i < NUM_GROUPTYPES; i++) { - if (newCounts[i] != prevCounts[i]) + if (curCounts[i] != prevCounts[i]) return TRUE; } return FALSE; } -static bool32 UpdateCommunicationCounts(u32 * counts, u32 * lastCounts, u32 * activities, u8 taskId) +static bool32 UpdateCommunicationCounts(u32 * groupCounts, u32 * prevGroupCounts, u32 * activities, u8 taskId) { bool32 activitiesUpdated = FALSE; - u32 buffer[4] = {0, 0, 0, 0}; + u32 groupCountBuffer[NUM_GROUPTYPES] = {0, 0, 0, 0}; struct WirelessLink_Group * group = (void *)gTasks[taskId].data; s32 i; - for (i = 0; i < 16; i++) + for (i = 0; i < NUM_TASK_DATA; i++) { - u32 activity = CountMembersInGroup(&group->playerList->players[i], buffer); + u32 activity = CountPlayersInGroupAndGetActivity(&group->playerList->players[i], groupCountBuffer); if (activity != activities[i]) { activities[i] = activity; @@ -411,7 +435,7 @@ static bool32 UpdateCommunicationCounts(u32 * counts, u32 * lastCounts, u32 * ac } } - if (HaveCountsChanged(buffer, lastCounts) == FALSE) + if (!HaveCountsChanged(groupCountBuffer, prevGroupCounts)) { if (activitiesUpdated == TRUE) return TRUE; @@ -419,8 +443,15 @@ static bool32 UpdateCommunicationCounts(u32 * counts, u32 * lastCounts, u32 * ac return FALSE; } - memcpy(counts, buffer, sizeof(buffer)); - memcpy(lastCounts, buffer, sizeof(buffer)); - counts[3] = counts[0] + counts[1] + counts[2]; + memcpy(groupCounts, groupCountBuffer, sizeof(groupCountBuffer)); + memcpy(prevGroupCounts, groupCountBuffer, sizeof(groupCountBuffer)); + + groupCounts[GROUPTYPE_TOTAL] = groupCounts[GROUPTYPE_TRADE] + + groupCounts[GROUPTYPE_BATTLE] + + groupCounts[GROUPTYPE_UNION] + #ifdef BUGFIX + + groupCounts[GROUPTYPE_TOTAL] // Missing count for activities not in above groups + #endif + ; return TRUE; } From a7609df31b8a5756a4d6308fcce89e4886766f2e Mon Sep 17 00:00:00 2001 From: GriffinR Date: Tue, 8 Nov 2022 13:00:51 -0500 Subject: [PATCH 6/8] Sync union_room_player_avatar --- data/maps/UnionRoom/scripts.inc | 9 - include/constants/event_objects.h | 17 +- include/rfu_union_tool.h | 16 - include/union_room_player_avatar.h | 16 + ld_script.txt | 4 +- src/pokemon.c | 17 +- src/rfu_union_tool.c | 663 ----------------------------- src/union_room.c | 14 +- src/union_room_player_avatar.c | 615 ++++++++++++++++++++++++++ sym_ewram.txt | 2 +- 10 files changed, 665 insertions(+), 708 deletions(-) delete mode 100644 include/rfu_union_tool.h create mode 100644 include/union_room_player_avatar.h delete mode 100644 src/rfu_union_tool.c create mode 100644 src/union_room_player_avatar.c diff --git a/data/maps/UnionRoom/scripts.inc b/data/maps/UnionRoom/scripts.inc index c214b06d3..38b5c3dda 100644 --- a/data/maps/UnionRoom/scripts.inc +++ b/data/maps/UnionRoom/scripts.inc @@ -1,12 +1,3 @@ -.set LOCALID_UNION_ROOM_PLAYER_4, 2 -.set LOCALID_UNION_ROOM_PLAYER_8, 3 -.set LOCALID_UNION_ROOM_PLAYER_7, 4 -.set LOCALID_UNION_ROOM_PLAYER_6, 5 -.set LOCALID_UNION_ROOM_PLAYER_5, 6 -.set LOCALID_UNION_ROOM_PLAYER_3, 7 -.set LOCALID_UNION_ROOM_PLAYER_2, 8 -.set LOCALID_UNION_ROOM_PLAYER_1, 9 - UnionRoom_MapScripts:: map_script MAP_SCRIPT_ON_RESUME, UnionRoom_OnResume map_script MAP_SCRIPT_ON_TRANSITION, UnionRoom_OnTransition diff --git a/include/constants/event_objects.h b/include/constants/event_objects.h index 99d3e4209..0eac72a29 100644 --- a/include/constants/event_objects.h +++ b/include/constants/event_objects.h @@ -189,10 +189,21 @@ #define TRACKS_FOOT 1 #define TRACKS_BIKE_TIRE 2 -#define OBJ_EVENT_ID_PLAYER 0xFF -#define OBJ_EVENT_ID_CAMERA 0x7F - #define OBJ_KIND_NORMAL 0 #define OBJ_KIND_CLONE 255 +// Special object event local ids +#define OBJ_EVENT_ID_PLAYER 0xFF +#define OBJ_EVENT_ID_CAMERA 0x7F + +// Object event local ids referenced in C files +#define LOCALID_UNION_ROOM_PLAYER_4 2 +#define LOCALID_UNION_ROOM_PLAYER_8 3 +#define LOCALID_UNION_ROOM_PLAYER_7 4 +#define LOCALID_UNION_ROOM_PLAYER_6 5 +#define LOCALID_UNION_ROOM_PLAYER_5 6 +#define LOCALID_UNION_ROOM_PLAYER_3 7 +#define LOCALID_UNION_ROOM_PLAYER_2 8 +#define LOCALID_UNION_ROOM_PLAYER_1 9 + #endif // GUARD_CONSTANTS_EVENT_OBJECTS_H diff --git a/include/rfu_union_tool.h b/include/rfu_union_tool.h deleted file mode 100644 index ffecc3f8d..000000000 --- a/include/rfu_union_tool.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef GUARD_UNION_ROOM_PLAYER_AVATAR_H -#define GUARD_UNION_ROOM_PLAYER_AVATAR_H - -#include "union_room.h" - -u8 ZeroUnionObjWork(struct UnionRoomObject * ptr); -void DestroyUnionRoomPlayerObjects(void); -void CreateGroupMemberObjectsInvisible(u8 *spriteIds, s32 group); -void DestroyGroupMemberObjects(u8 *spriteIds); -void MakeGroupAssemblyAreasPassable(void); -void ScheduleUnionRoomPlayerRefresh(struct WirelessLink_URoom *uroom_p); -void HandleUnionRoomPlayerRefresh(struct WirelessLink_URoom *uroom_p); -bool32 TryInteractWithUnionRoomMember(struct RfuPlayerList *main0_p, s16 *member_p, s16 *group_p, u8 *spriteIds); -void UpdateUnionGroupMemberFacing(u32 member, u32 group, struct RfuPlayerList *main0_p); - -#endif //GUARD_UNION_ROOM_PLAYER_AVATAR_H diff --git a/include/union_room_player_avatar.h b/include/union_room_player_avatar.h new file mode 100644 index 000000000..17ace17de --- /dev/null +++ b/include/union_room_player_avatar.h @@ -0,0 +1,16 @@ +#ifndef GUARD_UNION_ROOM_PLAYER_AVATAR_H +#define GUARD_UNION_ROOM_PLAYER_AVATAR_H + +#include "union_room.h" + +u8 InitUnionRoomPlayerObjects(struct UnionRoomObject * players); +void DestroyUnionRoomPlayerObjects(void); +void CreateUnionRoomPlayerSprites(u8 *spriteIds, s32 leaderId); +void DestroyUnionRoomPlayerSprites(u8 *spriteIds); +void MakeGroupAssemblyAreasPassable(void); +void ScheduleUnionRoomPlayerRefresh(struct WirelessLink_URoom *uroom); +void HandleUnionRoomPlayerRefresh(struct WirelessLink_URoom *uroom); +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 546f6b5fe..5c7a3751d 100644 --- a/ld_script.txt +++ b/ld_script.txt @@ -249,7 +249,7 @@ SECTIONS { src/trainer_fan_club.o(.text); src/quest_log_events.o(.text); src/union_room.o(.text); - src/rfu_union_tool.o(.text); + src/union_room_player_avatar.o(.text); src/union_room_battle.o(.text); src/pokemon_special_anim.o(.text); src/pokemon_special_anim_scene.o(.text); @@ -542,7 +542,7 @@ SECTIONS { src/trainer_fan_club.o(.rodata); src/quest_log_events.o(.rodata); src/union_room.o(.rodata); - src/rfu_union_tool.o(.rodata); + src/union_room_player_avatar.o(.rodata); src/union_room_battle.o(.rodata); src/union_room_message.o(.rodata); src/pokemon_special_anim.o(.rodata); diff --git a/src/pokemon.c b/src/pokemon.c index 6a164028e..e3cae699c 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -34,6 +34,7 @@ #include "constants/trainers.h" #include "constants/hold_effects.h" #include "constants/battle_move_effects.h" +#include "constants/union_room.h" #define SPECIES_TO_HOENN(name) [SPECIES_##name - 1] = HOENN_DEX_##name #define SPECIES_TO_NATIONAL(name) [SPECIES_##name - 1] = NATIONAL_DEX_##name @@ -1643,7 +1644,9 @@ static const u16 sDeoxysBaseStats[] = }; #endif -const u16 gLinkPlayerFacilityClasses[] = +// The classes used by other players in the Union Room. +// These should correspond with the overworld graphics in sUnionRoomObjGfxIds +const u16 gUnionRoomFacilityClasses[NUM_UNION_ROOM_CLASSES * GENDER_COUNT] = { // Male FACILITY_CLASS_COOLTRAINER_M, @@ -6031,19 +6034,19 @@ void SetDeoxysStats(void) u16 GetUnionRoomTrainerPic(void) { u8 linkId = GetMultiplayerId() ^ 1; - u32 arrId = gLinkPlayers[linkId].trainerId & 7; - arrId |= gLinkPlayers[linkId].gender << 3; - return FacilityClassToPicIndex(gLinkPlayerFacilityClasses[arrId]); + u32 arrId = gLinkPlayers[linkId].trainerId % NUM_UNION_ROOM_CLASSES; + arrId |= gLinkPlayers[linkId].gender * NUM_UNION_ROOM_CLASSES; + return FacilityClassToPicIndex(gUnionRoomFacilityClasses[arrId]); } u16 GetUnionRoomTrainerClass(void) { u8 linkId = GetMultiplayerId() ^ 1; - u32 arrId = gLinkPlayers[linkId].trainerId & 7; - arrId |= gLinkPlayers[linkId].gender << 3; - return gFacilityClassToTrainerClass[gLinkPlayerFacilityClasses[arrId]]; + u32 arrId = gLinkPlayers[linkId].trainerId % NUM_UNION_ROOM_CLASSES; + arrId |= gLinkPlayers[linkId].gender * NUM_UNION_ROOM_CLASSES; + return gFacilityClassToTrainerClass[gUnionRoomFacilityClasses[arrId]]; } void CreateEventLegalEnemyMon(void) diff --git a/src/rfu_union_tool.c b/src/rfu_union_tool.c deleted file mode 100644 index d6e77519d..000000000 --- a/src/rfu_union_tool.c +++ /dev/null @@ -1,663 +0,0 @@ -#include "global.h" -#include "event_data.h" -#include "event_object_movement.h" -#include "field_player_avatar.h" -#include "fieldmap.h" -#include "rfu_union_tool.h" -#include "script.h" -#include "task.h" -#include "constants/event_object_movement.h" -#include "constants/union_room.h" -#include "constants/event_objects.h" - -static EWRAM_DATA struct UnionRoomObject * UnionObjWork = NULL; -static EWRAM_DATA u32 sUnionObjRefreshTimer = 0; - -static u8 StartUnionObjAnimTask(void); -static u32 RfuUnionGroupMemberIsInvisible(u32 group, u32 member); -static void UnionPartnerObjectSetFacing(s32 member, s32 group, u8 direction); - -static const u8 sUnionObjectEventGfxIds[][10] = { - [MALE] = { - OBJ_EVENT_GFX_COOLTRAINER_M, - OBJ_EVENT_GFX_BLACKBELT, - OBJ_EVENT_GFX_CAMPER, - OBJ_EVENT_GFX_YOUNGSTER, - OBJ_EVENT_GFX_BOY, - OBJ_EVENT_GFX_BUG_CATCHER, - OBJ_EVENT_GFX_MAN, - OBJ_EVENT_GFX_ROCKER - }, - [FEMALE] = { - OBJ_EVENT_GFX_COOLTRAINER_F, - OBJ_EVENT_GFX_CHANNELER, - OBJ_EVENT_GFX_PICNICKER, - OBJ_EVENT_GFX_LASS, - OBJ_EVENT_GFX_WOMAN_1, - OBJ_EVENT_GFX_BATTLE_GIRL, - OBJ_EVENT_GFX_WOMAN_2, - OBJ_EVENT_GFX_BEAUTY - } -}; - -static const s16 sUnionPartnerCoords[][2] = { - { 4, 6}, - {13, 8}, - {10, 6}, - { 1, 8}, - {13, 4}, - { 7, 4}, - { 1, 4}, - { 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} -}; - -static const u8 sOppositeFacingDirection[] = { - [DIR_NONE] = DIR_NONE, - [DIR_SOUTH] = DIR_NORTH, - [DIR_NORTH] = DIR_SOUTH, - [DIR_WEST] = DIR_EAST, - [DIR_EAST] = DIR_WEST -}; - -static const u8 sUnionGroupMemberFacings[] = { - DIR_SOUTH, - DIR_WEST, - DIR_SOUTH, - DIR_EAST, - DIR_NORTH -}; - -static const u8 sUnionRoomLocalIds[] = { - 9, - 8, - 7, - 2, - 6, - 5, - 4, - 3 -}; - -// Unused -static const u16 sHidePlayerFlags[] = { - FLAG_HIDE_UNION_ROOM_PLAYER_1, - FLAG_HIDE_UNION_ROOM_PLAYER_2, - FLAG_HIDE_UNION_ROOM_PLAYER_3, - FLAG_HIDE_UNION_ROOM_PLAYER_4, - FLAG_HIDE_UNION_ROOM_PLAYER_5, - FLAG_HIDE_UNION_ROOM_PLAYER_6, - FLAG_HIDE_UNION_ROOM_PLAYER_7, - FLAG_HIDE_UNION_ROOM_PLAYER_8 -}; - -static bool32 is_walking_or_running(void) -{ - if (gPlayerAvatar.tileTransitionState == 2 || gPlayerAvatar.tileTransitionState == 0) - { - return TRUE; - } - else - { - return FALSE; - } -} - -static u8 GetUnionRoomPlayerGraphicsId(u32 gender, u32 id) -{ - return sUnionObjectEventGfxIds[gender][id % 8]; -} - -static void GetUnionRoomPlayerFacingCoords(u32 group, u32 member, s32 * xp, s32 * yp) -{ - *xp = sUnionPartnerCoords[group][0] + sFacingDirectionOffsets[member][0] + 7; - *yp = sUnionPartnerCoords[group][1] + sFacingDirectionOffsets[member][1] + 7; -} - -static bool32 IsUnionRoomPlayerFacingTileAt(u32 group, u32 member, s32 x, s32 y) -{ - if (sUnionPartnerCoords[group][0] + sFacingDirectionOffsets[member][0] + 7 != x) - { - return FALSE; - } - else if (sUnionPartnerCoords[group][1] + sFacingDirectionOffsets[member][1] + 7 != y) - { - return FALSE; - } - else - { - return TRUE; - } -} - -static bool32 IsUnionRoomPlayerHidden(u32 player_idx) -{ - return FlagGet(FLAG_HIDE_UNION_ROOM_PLAYER_1 + player_idx); -} - -static void HideUnionRoomPlayer(u32 player_idx) -{ - FlagSet(FLAG_HIDE_UNION_ROOM_PLAYER_1 + player_idx); -} - -static void ShowUnionRoomPlayer(u32 player_idx) -{ - FlagClear(FLAG_HIDE_UNION_ROOM_PLAYER_1 + player_idx); -} - -static void SetUnionRoomPlayerGfx(u32 playerIdx, u32 gfxId) -{ - VarSet(VAR_OBJ_GFX_ID_0 + playerIdx, gfxId); -} - -static void CreateUnionRoomPlayerObjectEvent(u32 playerIdx) -{ - TrySpawnObjectEvent(sUnionRoomLocalIds[playerIdx], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup); -} - -static void RemoveUnionRoomPlayerObjectEvent(u32 playerIdx) -{ - RemoveObjectEventByLocalIdAndMap(sUnionRoomLocalIds[playerIdx], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup); -} - -static bool32 SetUnionRoomPlayerEnterExitMovement(u32 playerIdx, const u8 * movement) -{ - u8 objectId; - struct ObjectEvent * object; - if (TryGetObjectEventIdByLocalIdAndMap(sUnionRoomLocalIds[playerIdx], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, &objectId)) - { - return FALSE; - } - object = &gObjectEvents[objectId]; - if (ObjectEventIsMovementOverridden(object)) - { - return FALSE; - } - if (ObjectEventSetHeldMovement(object, *movement)) - { - AGB_ASSERT_EX(0, ABSPATH("rfu_union_tool.c"), 387); - return FALSE; - } - return TRUE; -} - -static bool32 TryReleaseUnionRoomPlayerObjectEvent(u32 playerIdx) -{ - u8 objectId; - struct ObjectEvent * object; - if (TryGetObjectEventIdByLocalIdAndMap(sUnionRoomLocalIds[playerIdx], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, &objectId)) - { - return TRUE; - } - object = &gObjectEvents[objectId]; - if (!ObjectEventClearHeldMovementIfFinished(object)) - { - return FALSE; - } - if (!ArePlayerFieldControlsLocked()) - { - UnfreezeObjectEvent(object); - } - else - { - FreezeObjectEvent(object); - } - return TRUE; -} - -u8 ZeroUnionObjWork(struct UnionRoomObject * ptr) -{ - s32 i; - - sUnionObjRefreshTimer = 0; - UnionObjWork = ptr; - AGB_ASSERT_EX(UnionObjWork != NULL, ABSPATH("rfu_union_tool.c"), 442) - for (i = 0; i < 8; i++) - { - ptr[i].state = 0; - ptr[i].gfxId = 0; - ptr[i].animState = 0; - ptr[i].schedAnim = 0; - } - return StartUnionObjAnimTask(); -} - -static const u8 sMovement_UnionPlayerExit[2] = { - MOVEMENT_ACTION_FLY_UP, - MOVEMENT_ACTION_STEP_END -}; - -static bool32 AnimateUnionRoomPlayerDespawn(s8 * a0, u32 playerIdx, struct UnionRoomObject * ptr) -{ - switch (*a0) - { - case 0: - if (SetUnionRoomPlayerEnterExitMovement(playerIdx, sMovement_UnionPlayerExit) == TRUE) - { - HideUnionRoomPlayer(playerIdx); - (*a0)++; - } - break; - case 1: - if (TryReleaseUnionRoomPlayerObjectEvent(playerIdx)) - { - RemoveUnionRoomPlayerObjectEvent(playerIdx); - HideUnionRoomPlayer(playerIdx); - *a0 = 0; - return TRUE; - } - break; - } - return FALSE; -} - -static const u8 sMovement_UnionPlayerEnter[2] = { - MOVEMENT_ACTION_FLY_DOWN, - MOVEMENT_ACTION_STEP_END -}; - -static bool32 AnimateUnionRoomPlayerSpawn(s8 * state_p, u32 playerIdx, struct UnionRoomObject * ptr) -{ - s16 x, y; - - switch (*state_p) - { - case 0: - if (!is_walking_or_running()) - { - break; - } - PlayerGetDestCoords(&x, &y); - if (IsUnionRoomPlayerFacingTileAt(playerIdx, 0, x, y) == TRUE) - { - break; - } - player_get_pos_including_state_based_drift(&x, &y); - if (IsUnionRoomPlayerFacingTileAt(playerIdx, 0, x, y) == TRUE) - { - break; - } - SetUnionRoomPlayerGfx(playerIdx, ptr->gfxId); - CreateUnionRoomPlayerObjectEvent(playerIdx); - ShowUnionRoomPlayer(playerIdx); - (*state_p)++; - // fallthrough - case 3: // incorrect? - if (SetUnionRoomPlayerEnterExitMovement(playerIdx, sMovement_UnionPlayerEnter) == 1) - { - (*state_p)++; - } - break; - case 2: - if (TryReleaseUnionRoomPlayerObjectEvent(playerIdx)) - { - *state_p = 0; - return TRUE; - } - break; - } - return FALSE; -} - -static bool32 SpawnGroupLeader(u32 playerIdx, u32 gender, u32 idMod256) -{ - struct UnionRoomObject * ptr = &UnionObjWork[playerIdx]; - AGB_ASSERT_EX(UnionObjWork != NULL, ABSPATH("rfu_union_tool.c"), 561) - ptr->schedAnim = UNION_ROOM_SPAWN_IN; - ptr->gfxId = GetUnionRoomPlayerGraphicsId(gender, idMod256); - if (ptr->state == 0) - { - return TRUE; - } - else - { - return FALSE; - } -} - -static bool32 DespawnGroupLeader(u32 playerIdx) -{ - struct UnionRoomObject * ptr = &UnionObjWork[playerIdx]; - AGB_ASSERT_EX(UnionObjWork != NULL, ABSPATH("rfu_union_tool.c"), 577) - ptr->schedAnim = UNION_ROOM_SPAWN_OUT; - if (ptr->state == 1) - { - return TRUE; - } - else - { - return FALSE; - } -} - -static void AnimateUnionObj(u32 playerIdx, struct UnionRoomObject * ptr) -{ - switch (ptr->state) - { - case 0: - if (ptr->schedAnim == UNION_ROOM_SPAWN_IN) - { - ptr->state = 2; - ptr->animState = 0; - } - else - { - break; - } - // fallthrough - case 2: - if (!RfuUnionGroupMemberIsInvisible(playerIdx, 0) && ptr->schedAnim == 2) - { - ptr->state = 0; - ptr->animState = 0; - RemoveUnionRoomPlayerObjectEvent(playerIdx); - HideUnionRoomPlayer(playerIdx); - } - else if (AnimateUnionRoomPlayerSpawn(&ptr->animState, playerIdx, ptr) == TRUE) - { - ptr->state = 1; - } - break; - case 1: - if (ptr->schedAnim == UNION_ROOM_SPAWN_OUT) - { - ptr->state = 3; - ptr->animState = 0; - } - else - { - break; - } - // fallthrough - case 3: - if (AnimateUnionRoomPlayerDespawn(&ptr->animState, playerIdx, ptr) == TRUE) - { - ptr->state = 0; - } - break; - } - ptr->schedAnim = UNION_ROOM_SPAWN_NONE; -} - -static void Task_AnimateUnionObjs(u8 taskId) -{ - s32 i; - AGB_ASSERT_EX(UnionObjWork != NULL, ABSPATH("rfu_union_tool.c"), 643) - for (i = 0; i < 8; i++) - { - AnimateUnionObj(i, &UnionObjWork[i]); - } -} - -static u8 StartUnionObjAnimTask(void) -{ - if (FuncIsActiveTask(Task_AnimateUnionObjs) == TRUE) - { - AGB_ASSERT_EX(0, ABSPATH("rfu_union_tool.c"), 655) - return NUM_TASKS; - } - else - { - return CreateTask(Task_AnimateUnionObjs, 5); - } -} - -static void DestroyAnimateUnionObjsTask(void) -{ - u8 taskId = FindTaskIdByFunc(Task_AnimateUnionObjs); - if (taskId < NUM_TASKS) - { - DestroyTask(taskId); - } -} - -void DestroyUnionRoomPlayerObjects(void) -{ - s32 i; - for (i = 0; i < 8; i++) - { - if (!IsUnionRoomPlayerHidden(i)) - { - RemoveUnionRoomPlayerObjectEvent(i); - HideUnionRoomPlayer(i); - } - } - UnionObjWork = NULL; - DestroyAnimateUnionObjsTask(); -} - -void CreateGroupMemberObjectsInvisible(u8 * sprite_ids, s32 group) -{ - s32 i; - - for (i = 0; i < 5; i++) - { - s32 obj_id = 5 * group + i; - sprite_ids[obj_id] = CreateVirtualObject(OBJ_EVENT_GFX_MAN, obj_id - 0x38, sUnionPartnerCoords[group][0] + sFacingDirectionOffsets[i][0], sUnionPartnerCoords[group][1] + sFacingDirectionOffsets[i][1], 3, 1); - SetVirtualObjectInvisibility(obj_id - 0x38, TRUE); - } -} - -void DestroyGroupMemberObjects(u8 *spriteIds) -{ - s32 i; - for (i = 0; i < 40; i++) - { - DestroySprite(&gSprites[spriteIds[i]]); - } -} - -void MakeGroupAssemblyAreasPassable(void) -{ - s32 i, j, x, y; - for (i = 0; i < 8; i++) - { - for (j = 0; j < 5; j++) - { - GetUnionRoomPlayerFacingCoords(i, j, &x, &y); - MapGridSetMetatileImpassabilityAt(x, y, FALSE); - } - } -} - -static u8 UnionPartnerObjectGetFacing(u32 member, u32 group, struct RfuGameData * gname) -{ - if (member != 0) - { - return sUnionGroupMemberFacings[member]; - } - else if (gname->activity == 0x45) - { - return DIR_SOUTH; - } - else - { - return DIR_EAST; - } -} - -static u32 RfuUnionGroupMemberIsInvisible(u32 group, u32 member) -{ - return IsVirtualObjectInvisible(5 * group + member - 0x38); -} - -static void SpawnGroupMember(u32 groupNo, u32 memberNo, u8 direction, struct RfuGameData * gname) -{ - s32 x, y; - s32 objId = 5 * groupNo + memberNo; - if (RfuUnionGroupMemberIsInvisible(groupNo, memberNo) == TRUE) - { - SetVirtualObjectInvisibility(objId - 0x38, FALSE); - SetVirtualObjectSpriteAnim(objId - 0x38, UNION_ROOM_SPAWN_IN); - } - SetVirtualObjectGraphics(objId - 0x38, direction); - UnionPartnerObjectSetFacing(memberNo, groupNo, UnionPartnerObjectGetFacing(memberNo, groupNo, gname)); - GetUnionRoomPlayerFacingCoords(groupNo, memberNo, &x, &y); - MapGridSetMetatileImpassabilityAt(x, y, TRUE); -} - -static void DespawnGroupMember(u32 group, u32 member) -{ - s32 x, y; - SetVirtualObjectSpriteAnim(5 * group + member - 0x38, UNION_ROOM_SPAWN_OUT); - GetUnionRoomPlayerFacingCoords(group, member, &x, &y); - MapGridSetMetatileImpassabilityAt(x, y, FALSE); -} - -static void AssembleGroup(u32 group, struct RfuGameData * gname) -{ - s16 x, y, x2, y2; - s32 i; - - PlayerGetDestCoords(&x, &y); - player_get_pos_including_state_based_drift(&x2, &y2); - if (IsVirtualObjectInvisible(5 * group - 0x38) == TRUE) - { - if (IsUnionRoomPlayerFacingTileAt(group, 0, x, y) == TRUE || IsUnionRoomPlayerFacingTileAt(group, 0, x2, y2) == TRUE) - { - return; - } - SpawnGroupMember(group, 0, GetUnionRoomPlayerGraphicsId(gname->playerGender, gname->compatibility.playerTrainerId[0]), gname); - } - for (i = 1; i < 5; i++) - { - if (gname->partnerInfo[i - 1] == 0) - { - DespawnGroupMember(group, i); - } - else if (IsUnionRoomPlayerFacingTileAt(group, i, x, y) == FALSE && IsUnionRoomPlayerFacingTileAt(group, i, x2, y2) == FALSE) - { - SpawnGroupMember(group, i, GetUnionRoomPlayerGraphicsId((gname->partnerInfo[i - 1] >> 3) & 1, gname->partnerInfo[i - 1] & 7), gname); - } - } -} - -static void SpawnGroupLeaderAndMembers(u32 group, struct RfuGameData * gname) -{ - u32 i; - switch (gname->activity) - { - case 0x40: - case 0x54: - SpawnGroupLeader(group, gname->playerGender, gname->compatibility.playerTrainerId[0]); - for (i = 0; i < 5; i++) - { - DespawnGroupMember(group, i); - } - break; - case 0x41: - case 0x44: - case 0x45: - case 0x48: - case 0x51: - case 0x52: - case 0x53: - DespawnGroupLeader(group); - AssembleGroup(group, gname); - break; - default: - AGB_ASSERT_EX(0, ABSPATH("rfu_union_tool.c"), 979) - } -} - -static void DespawnGroupLeaderAndMembers(u32 group, struct RfuGameData * gname) -{ - s32 i; - DespawnGroupLeader(group); - for (i = 0; i < 5; i++) - { - DespawnGroupMember(group, i); - } -} - -static void UpdateUnionRoomPlayerSprites(struct WirelessLink_URoom * groups) -{ - s32 i; - struct RfuPlayer * x20_p; - sUnionObjRefreshTimer = 0; - for (i = 0, x20_p = groups->playerList->players; i < 8; i++) - { - if (x20_p[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN) - { - SpawnGroupLeaderAndMembers(i, &x20_p[i].rfu.data); - } - else if (x20_p[i].groupScheduledAnim == UNION_ROOM_SPAWN_OUT) - { - DespawnGroupLeaderAndMembers(i, &x20_p[i].rfu.data); - } - } -} - -void ScheduleUnionRoomPlayerRefresh(struct WirelessLink_URoom *uroom_p) -{ - sUnionObjRefreshTimer = 300; -} - -void HandleUnionRoomPlayerRefresh(struct WirelessLink_URoom *uroom_p) -{ - if (++sUnionObjRefreshTimer > 300) - { - UpdateUnionRoomPlayerSprites(uroom_p); - } -} - -bool32 TryInteractWithUnionRoomMember(struct RfuPlayerList *main0_p, s16 *member_p, s16 *group_p, u8 *spriteIds) -{ - s16 x, y; - s32 i, j; - struct RfuPlayer * x20_p; - if (!is_walking_or_running()) - { - return FALSE; - } - GetXYCoordsOneStepInFrontOfPlayer(&x, &y); - for (i = 0, x20_p = main0_p->players; i < 8; i++) - { - for (j = 0; j < 5; j++) - { - s32 objId = 5 * i + j; - if (x != sUnionPartnerCoords[i][0] + sFacingDirectionOffsets[j][0] + 7) - { - continue; - } - if (y != sUnionPartnerCoords[i][1] + sFacingDirectionOffsets[j][1] + 7) - { - continue; - } - if (IsVirtualObjectInvisible(objId - 0x38) != FALSE) - { - continue; - } - if (IsVirtualObjectAnimating(objId - 0x38) != FALSE) - { - continue; - } - if (x20_p[i].groupScheduledAnim != UNION_ROOM_SPAWN_IN) - { - continue; - } - UnionPartnerObjectSetFacing(j, i, sOppositeFacingDirection[GetPlayerFacingDirection()]); - *member_p = j; - *group_p = i; - return TRUE; - } - } - return FALSE; -} - -static void UnionPartnerObjectSetFacing(s32 member, s32 group, u8 direction) -{ - TurnVirtualObject(5 * group - 0x38 + member, direction); -} - -void UpdateUnionGroupMemberFacing(u32 member, u32 group, struct RfuPlayerList *main0_p) -{ - return UnionPartnerObjectSetFacing(member, group, UnionPartnerObjectGetFacing(member, group, &main0_p->players[group].rfu.data)); -} diff --git a/src/union_room.c b/src/union_room.c index 2458e44ef..8b8410e3d 100644 --- a/src/union_room.c +++ b/src/union_room.c @@ -40,7 +40,7 @@ #include "union_room.h" #include "union_room_battle.h" #include "union_room_chat.h" -#include "rfu_union_tool.h" +#include "union_room_player_avatar.h" #include "union_room_message.h" #include "constants/songs.h" #include "constants/maps.h" @@ -2317,13 +2317,13 @@ static void Task_RunUnionRoom(u8 taskId) ClearRfuPlayerList(uroom->playerList->players, MAX_UNION_ROOM_LEADERS); sPlayerCurrActivity = IN_UNION_ROOM; uroom->searchTaskId = CreateTask_SearchForChildOrParent(uroom->incomingParentList, uroom->incomingChildList, LINK_GROUP_UNION_ROOM_RESUME); - ZeroUnionObjWork(uroom->objects); + InitUnionRoomPlayerObjects(uroom->objects); MakeGroupAssemblyAreasPassable(); uroom->state = UR_STATE_INIT_OBJECTS; break; case UR_STATE_INIT_OBJECTS: - CreateGroupMemberObjectsInvisible(uroom->spriteIds, taskData[0]); - if (++taskData[0] == 8) + CreateUnionRoomPlayerSprites(uroom->spriteIds, taskData[0]); + if (++taskData[0] == MAX_UNION_ROOM_LEADERS) uroom->state = UR_STATE_INIT_LINK; break; case UR_STATE_INIT_LINK: @@ -2515,7 +2515,7 @@ static void Task_RunUnionRoom(u8 taskId) if (!gReceivedRemoteLinkPlayers) { HandleCancelActivity(FALSE); - UpdateUnionGroupMemberFacing(taskData[0], taskData[1], uroom->playerList); + UpdateUnionRoomMemberFacing(taskData[0], taskData[1], uroom->playerList); uroom->state = UR_STATE_INIT_LINK; } break; @@ -2840,7 +2840,7 @@ static void Task_RunUnionRoom(u8 taskId) Free(uroom->incomingParentList); Free(uroom->incomingChildList); DestroyTask(uroom->searchTaskId); - DestroyGroupMemberObjects(uroom->spriteIds); + DestroyUnionRoomPlayerSprites(uroom->spriteIds); uroom->state = UR_STATE_START_ACTIVITY_FADE; break; case UR_STATE_START_ACTIVITY_FADE: @@ -3051,7 +3051,7 @@ static void Task_RunUnionRoom(u8 taskId) if (PrintOnTextbox(&uroom->textState, gStringVar4)) { HandleCancelActivity(TRUE); - UpdateUnionGroupMemberFacing(taskData[0], taskData[1], uroom->playerList); + UpdateUnionRoomMemberFacing(taskData[0], taskData[1], uroom->playerList); uroom->state = UR_STATE_MAIN; } break; diff --git a/src/union_room_player_avatar.c b/src/union_room_player_avatar.c new file mode 100644 index 000000000..2cfa38167 --- /dev/null +++ b/src/union_room_player_avatar.c @@ -0,0 +1,615 @@ +#include "global.h" +#include "event_data.h" +#include "event_object_movement.h" +#include "field_player_avatar.h" +#include "fieldmap.h" +#include "union_room_player_avatar.h" +#include "script.h" +#include "task.h" +#include "constants/event_object_movement.h" +#include "constants/union_room.h" +#include "constants/event_objects.h" + +#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) + +// Original symbol name from ASSERT statements +#define UnionObjWork sUnionObjWork + +static EWRAM_DATA struct UnionRoomObject * sUnionObjWork = NULL; +static EWRAM_DATA u32 sUnionObjRefreshTimer = 0; + +static u8 CreateTask_AnimateUnionRoomPlayers(void); +static u32 IsUnionRoomPlayerInvisible(u32 leaderId, u32 member); +static void SetUnionRoomObjectFacingDirection(s32 member, s32 leaderId, u8 direction); + +// + 2 is just to match, those elements are empty and never read +// Graphics ids should correspond with the classes in gUnionRoomFacilityClasses +static const u8 sUnionRoomObjGfxIds[GENDER_COUNT][NUM_UNION_ROOM_CLASSES + 2] = { + [MALE] = { + OBJ_EVENT_GFX_COOLTRAINER_M, + OBJ_EVENT_GFX_BLACKBELT, + OBJ_EVENT_GFX_CAMPER, + OBJ_EVENT_GFX_YOUNGSTER, + OBJ_EVENT_GFX_BOY, + OBJ_EVENT_GFX_BUG_CATCHER, + OBJ_EVENT_GFX_MAN, + OBJ_EVENT_GFX_ROCKER + }, + [FEMALE] = { + OBJ_EVENT_GFX_COOLTRAINER_F, + OBJ_EVENT_GFX_CHANNELER, + OBJ_EVENT_GFX_PICNICKER, + OBJ_EVENT_GFX_LASS, + OBJ_EVENT_GFX_WOMAN_1, + OBJ_EVENT_GFX_BATTLE_GIRL, + OBJ_EVENT_GFX_WOMAN_2, + OBJ_EVENT_GFX_BEAUTY + } +}; + +static const s16 sUnionRoomPlayerCoords[MAX_UNION_ROOM_LEADERS][2] = { + { 4, 6}, + {13, 8}, + {10, 6}, + { 1, 8}, + {13, 4}, + { 7, 4}, + { 1, 4}, + { 7, 8} +}; + +// 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[][2] = { + { 0, 0}, // Center + { 1, 0}, // Left + { 0, -1}, // Top + {-1, 0}, // Right + { 0, 1} // Bottom +}; + +static const u8 sOppositeFacingDirection[] = { + [DIR_NONE] = DIR_NONE, + [DIR_SOUTH] = DIR_NORTH, + [DIR_NORTH] = DIR_SOUTH, + [DIR_WEST] = DIR_EAST, + [DIR_EAST] = DIR_WEST +}; + +// 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[] = { + DIR_SOUTH, // Leader, but never read + DIR_WEST, + DIR_SOUTH, + DIR_EAST, + DIR_NORTH +}; + +static const u8 sUnionRoomLocalIds[] = { + LOCALID_UNION_ROOM_PLAYER_1, + LOCALID_UNION_ROOM_PLAYER_2, + LOCALID_UNION_ROOM_PLAYER_3, + LOCALID_UNION_ROOM_PLAYER_4, + LOCALID_UNION_ROOM_PLAYER_5, + LOCALID_UNION_ROOM_PLAYER_6, + LOCALID_UNION_ROOM_PLAYER_7, + LOCALID_UNION_ROOM_PLAYER_8 +}; + +// Unused +static const u16 sHidePlayerFlags[] = { + FLAG_HIDE_UNION_ROOM_PLAYER_1, + FLAG_HIDE_UNION_ROOM_PLAYER_2, + FLAG_HIDE_UNION_ROOM_PLAYER_3, + FLAG_HIDE_UNION_ROOM_PLAYER_4, + FLAG_HIDE_UNION_ROOM_PLAYER_5, + FLAG_HIDE_UNION_ROOM_PLAYER_6, + FLAG_HIDE_UNION_ROOM_PLAYER_7, + FLAG_HIDE_UNION_ROOM_PLAYER_8 +}; + +static bool32 IsPlayerStandingStill(void) +{ + if (gPlayerAvatar.tileTransitionState == T_TILE_CENTER || gPlayerAvatar.tileTransitionState == T_NOT_MOVING) + return TRUE; + else + 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 % NUM_UNION_ROOM_CLASSES]; +} + +static void GetUnionRoomPlayerCoords(u32 leaderId, u32 memberId, s32 * x, s32 * y) +{ + *x = sUnionRoomPlayerCoords[leaderId][0] + sUnionRoomGroupOffsets[memberId][0] + 7; + *y = sUnionRoomPlayerCoords[leaderId][1] + sUnionRoomGroupOffsets[memberId][1] + 7; +} + +static bool32 IsUnionRoomPlayerAt(u32 leaderId, u32 memberId, s32 x, s32 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; +} + +static bool32 IsUnionRoomPlayerHidden(u32 leaderId) +{ + return FlagGet(FLAG_HIDE_UNION_ROOM_PLAYER_1 + leaderId); +} + +static void HideUnionRoomPlayer(u32 leaderId) +{ + FlagSet(FLAG_HIDE_UNION_ROOM_PLAYER_1 + leaderId); +} + +static void ShowUnionRoomPlayer(u32 leaderId) +{ + FlagClear(FLAG_HIDE_UNION_ROOM_PLAYER_1 + leaderId); +} + +static void SetUnionRoomPlayerGfx(u32 leaderId, u32 gfxId) +{ + VarSet(VAR_OBJ_GFX_ID_0 + leaderId, gfxId); +} + +static void CreateUnionRoomPlayerObjectEvent(u32 leaderId) +{ + TrySpawnObjectEvent(sUnionRoomLocalIds[leaderId], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup); +} + +static void RemoveUnionRoomPlayerObjectEvent(u32 leaderId) +{ + RemoveObjectEventByLocalIdAndMap(sUnionRoomLocalIds[leaderId], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup); +} + +static bool32 SetUnionRoomPlayerEnterExitMovement(u32 leaderId, const u8 * movement) +{ + u8 objectId; + struct ObjectEvent * object; + 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)) + { + AGB_ASSERT_EX(0, ABSPATH("rfu_union_tool.c"), 387); + return FALSE; + } + return TRUE; +} + +static bool32 TryReleaseUnionRoomPlayerObjectEvent(u32 leaderId) +{ + u8 objectId; + struct ObjectEvent * object; + if (TryGetObjectEventIdByLocalIdAndMap(sUnionRoomLocalIds[leaderId], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, &objectId)) + return TRUE; + + object = &gObjectEvents[objectId]; + if (!ObjectEventClearHeldMovementIfFinished(object)) + return FALSE; + + if (!ArePlayerFieldControlsLocked()) + UnfreezeObjectEvent(object); + else + FreezeObjectEvent(object); + return TRUE; +} + +u8 InitUnionRoomPlayerObjects(struct UnionRoomObject * players) +{ + s32 i; + + sUnionObjRefreshTimer = 0; + sUnionObjWork = players; + AGB_ASSERT_EX(UnionObjWork != NULL, ABSPATH("rfu_union_tool.c"), 442) + for (i = 0; i < MAX_UNION_ROOM_LEADERS; i++) + { + players[i].state = 0; + players[i].gfxId = 0; + players[i].animState = 0; + players[i].schedAnim = UNION_ROOM_SPAWN_NONE; + } + return CreateTask_AnimateUnionRoomPlayers(); +} + +static const u8 sMovement_UnionPlayerExit[2] = { + MOVEMENT_ACTION_FLY_UP, + MOVEMENT_ACTION_STEP_END +}; + +static bool32 AnimateUnionRoomPlayerDespawn(s8 * state, u32 leaderId, struct UnionRoomObject * object) +{ + switch (*state) + { + case 0: + if (SetUnionRoomPlayerEnterExitMovement(leaderId, sMovement_UnionPlayerExit) == TRUE) + { + HideUnionRoomPlayer(leaderId); + (*state)++; + } + break; + case 1: + if (TryReleaseUnionRoomPlayerObjectEvent(leaderId)) + { + RemoveUnionRoomPlayerObjectEvent(leaderId); + HideUnionRoomPlayer(leaderId); + *state = 0; + return TRUE; + } + break; + } + return FALSE; +} + +static const u8 sMovement_UnionPlayerEnter[2] = { + MOVEMENT_ACTION_FLY_DOWN, + MOVEMENT_ACTION_STEP_END +}; + +static bool32 AnimateUnionRoomPlayerSpawn(s8 * state, u32 leaderId, struct UnionRoomObject * object) +{ + s16 x, y; + + switch (*state) + { + case 0: + if (!IsPlayerStandingStill()) + break; + PlayerGetDestCoords(&x, &y); + if (IsUnionRoomPlayerAt(leaderId, 0, x, y) == TRUE) + break; + player_get_pos_including_state_based_drift(&x, &y); + if (IsUnionRoomPlayerAt(leaderId, 0, x, y) == TRUE) + break; + SetUnionRoomPlayerGfx(leaderId, object->gfxId); + CreateUnionRoomPlayerObjectEvent(leaderId); + ShowUnionRoomPlayer(leaderId); + (*state)++; + // fallthrough + case 3: // incorrect? + if (SetUnionRoomPlayerEnterExitMovement(leaderId, sMovement_UnionPlayerEnter) == 1) + (*state)++; + break; + case 2: + if (TryReleaseUnionRoomPlayerObjectEvent(leaderId)) + { + *state = 0; + return TRUE; + } + break; + } + return FALSE; +} + +static bool32 SpawnGroupLeader(u32 leaderId, u32 gender, u32 id) +{ + struct UnionRoomObject * object = &sUnionObjWork[leaderId]; + AGB_ASSERT_EX(UnionObjWork != NULL, ABSPATH("rfu_union_tool.c"), 561) + object->schedAnim = UNION_ROOM_SPAWN_IN; + object->gfxId = GetUnionRoomPlayerGraphicsId(gender, id); + + if (object->state == 0) + return TRUE; + else + return FALSE; +} + +static bool32 DespawnGroupLeader(u32 leaderId) +{ + struct UnionRoomObject * object = &sUnionObjWork[leaderId]; + AGB_ASSERT_EX(UnionObjWork != NULL, ABSPATH("rfu_union_tool.c"), 577) + object->schedAnim = UNION_ROOM_SPAWN_OUT; + + if (object->state == 1) + return TRUE; + else + return FALSE; +} + +static void AnimateUnionRoomPlayer(u32 leaderId, struct UnionRoomObject * object) +{ + switch (object->state) + { + case 0: + if (object->schedAnim == UNION_ROOM_SPAWN_IN) + { + object->state = 2; + object->animState = 0; + } + else + { + break; + } + // fallthrough + case 2: + if (!IsUnionRoomPlayerInvisible(leaderId, 0) && object->schedAnim == UNION_ROOM_SPAWN_OUT) + { + object->state = 0; + object->animState = 0; + RemoveUnionRoomPlayerObjectEvent(leaderId); + HideUnionRoomPlayer(leaderId); + } + else if (AnimateUnionRoomPlayerSpawn(&object->animState, leaderId, object) == TRUE) + { + object->state = 1; + } + break; + case 1: + if (object->schedAnim != UNION_ROOM_SPAWN_OUT) + break; + object->state = 3; + object->animState = 0; + // fallthrough + case 3: + if (AnimateUnionRoomPlayerDespawn(&object->animState, leaderId, object) == TRUE) + object->state = 0; + break; + } + object->schedAnim = UNION_ROOM_SPAWN_NONE; +} + +static void Task_AnimateUnionRoomPlayers(u8 taskId) +{ + s32 i; + AGB_ASSERT_EX(UnionObjWork != NULL, ABSPATH("rfu_union_tool.c"), 643) + for (i = 0; i < MAX_UNION_ROOM_LEADERS; i++) + AnimateUnionRoomPlayer(i, &sUnionObjWork[i]); +} + +static u8 CreateTask_AnimateUnionRoomPlayers(void) +{ + if (FuncIsActiveTask(Task_AnimateUnionRoomPlayers) == TRUE) + { + AGB_ASSERT_EX(0, ABSPATH("rfu_union_tool.c"), 655) + return NUM_TASKS; + } + else + { + return CreateTask(Task_AnimateUnionRoomPlayers, 5); + } +} + +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_LEADERS; i++) + { + if (!IsUnionRoomPlayerHidden(i)) + { + RemoveUnionRoomPlayerObjectEvent(i); + HideUnionRoomPlayer(i); + } + } + sUnionObjWork = NULL; + DestroyTask_AnimateUnionRoomPlayers(); +} + +void CreateUnionRoomPlayerSprites(u8 * spriteIds, s32 leaderId) +{ + s32 memberId; + + for (memberId = 0; memberId < MAX_RFU_PLAYERS; memberId++) + { + s32 id = UR_PLAYER_SPRITE_ID(leaderId, memberId); + spriteIds[id] = CreateVirtualObject(OBJ_EVENT_GFX_MAN, + id - UR_SPRITE_START_ID, + sUnionRoomPlayerCoords[leaderId][0] + sUnionRoomGroupOffsets[memberId][0], + sUnionRoomPlayerCoords[leaderId][1] + sUnionRoomGroupOffsets[memberId][1], + 3, 1); + SetVirtualObjectInvisibility(id - UR_SPRITE_START_ID, TRUE); + } +} + +void DestroyUnionRoomPlayerSprites(u8 *spriteIds) +{ + s32 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 MakeGroupAssemblyAreasPassable(void) +{ + s32 leaderId, memberId, x, y; + for (leaderId = 0; leaderId < MAX_UNION_ROOM_LEADERS; leaderId++) + { + for (memberId = 0; memberId < MAX_RFU_PLAYERS; memberId++) + { + GetUnionRoomPlayerCoords(leaderId, memberId, &x, &y); + MapGridSetMetatileImpassabilityAt(x, y, FALSE); + } + } +} + +static u8 GetNewFacingDirectionForUnionRoomPlayer(u32 memberId, u32 leaderId, struct RfuGameData * gameData) +{ + if (memberId != 0) // If not leader + return sMemberFacingDirections[memberId]; + else if (gameData->activity == (ACTIVITY_CHAT | IN_UNION_ROOM)) + return DIR_SOUTH; + else + return DIR_EAST; +} + +static u32 IsUnionRoomPlayerInvisible(u32 leaderId, u32 memberId) +{ + return IsVirtualObjectInvisible(UR_PLAYER_SPRITE_ID(leaderId, memberId) - UR_SPRITE_START_ID); +} + +static void SpawnGroupMember(u32 leaderId, u32 memberId, u8 graphicsId, struct RfuGameData * gameData) +{ + s32 x, y; + s32 id = UR_PLAYER_SPRITE_ID(leaderId, memberId); + if (IsUnionRoomPlayerInvisible(leaderId, memberId) == TRUE) + { + SetVirtualObjectInvisibility(id - UR_SPRITE_START_ID, FALSE); + SetVirtualObjectSpriteAnim(id - UR_SPRITE_START_ID, UNION_ROOM_SPAWN_IN); + } + SetVirtualObjectGraphics(id - UR_SPRITE_START_ID, graphicsId); + SetUnionRoomObjectFacingDirection(memberId, leaderId, GetNewFacingDirectionForUnionRoomPlayer(memberId, leaderId, gameData)); + GetUnionRoomPlayerCoords(leaderId, memberId, &x, &y); + MapGridSetMetatileImpassabilityAt(x, y, TRUE); +} + +static void DespawnGroupMember(u32 leaderId, u32 memberId) +{ + s32 x, y; + SetVirtualObjectSpriteAnim(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 leaderId, struct RfuGameData * gameData) +{ + s16 x, y, x2, y2; + s32 i; + + PlayerGetDestCoords(&x, &y); + player_get_pos_including_state_based_drift(&x2, &y2); + if (IsVirtualObjectInvisible(UR_PLAYER_SPRITE_ID(leaderId, 0) - UR_SPRITE_START_ID) == TRUE) + { + if (IsUnionRoomPlayerAt(leaderId, 0, x, y) == TRUE || IsUnionRoomPlayerAt(leaderId, 0, x2, y2) == TRUE) + return; + SpawnGroupMember(leaderId, 0, GetUnionRoomPlayerGraphicsId(gameData->playerGender, gameData->compatibility.playerTrainerId[0]), gameData); + } + for (i = 1; i < MAX_RFU_PLAYERS; i++) + { + if (gameData->partnerInfo[i - 1] == 0) + DespawnGroupMember(leaderId, i); + else if (IsUnionRoomPlayerAt(leaderId, i, x, y) == FALSE && IsUnionRoomPlayerAt(leaderId, i, x2, y2) == FALSE) + SpawnGroupMember(leaderId, i, GetUnionRoomPlayerGraphicsId((gameData->partnerInfo[i - 1] >> PINFO_GENDER_SHIFT) & 1, + gameData->partnerInfo[i - 1] & PINFO_TID_MASK), + gameData); + } +} + +static void SpawnGroupLeaderAndMembers(u32 leaderId, struct RfuGameData * gameData) +{ + u32 i; + switch (gameData->activity) + { + case ACTIVITY_NONE | IN_UNION_ROOM: + case ACTIVITY_PLYRTALK | IN_UNION_ROOM: + 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: + case ACTIVITY_CHAT | IN_UNION_ROOM: + case ACTIVITY_CARD | IN_UNION_ROOM: + case ACTIVITY_ACCEPT | IN_UNION_ROOM: + case ACTIVITY_DECLINE | IN_UNION_ROOM: + case ACTIVITY_NPCTALK | IN_UNION_ROOM: + DespawnGroupLeader(leaderId); + AssembleGroup(leaderId, gameData); + break; + default: + AGB_ASSERT_EX(0, ABSPATH("rfu_union_tool.c"), 979) + } +} + +static void DespawnGroupLeaderAndMembers(u32 leaderId, struct RfuGameData * gameData) +{ + s32 i; + DespawnGroupLeader(leaderId); + for (i = 0; i < MAX_RFU_PLAYERS; i++) + DespawnGroupMember(leaderId, i); +} + +static void UpdateUnionRoomPlayerSprites(struct WirelessLink_URoom * uroom) +{ + s32 i; + struct RfuPlayer * leaders; + sUnionObjRefreshTimer = 0; + for (i = 0, leaders = uroom->playerList->players; i < MAX_UNION_ROOM_LEADERS; i++) + { + 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); + } +} + +void ScheduleUnionRoomPlayerRefresh(struct WirelessLink_URoom *uroom) +{ + sUnionObjRefreshTimer = 300; +} + +void HandleUnionRoomPlayerRefresh(struct WirelessLink_URoom *uroom) +{ + if (++sUnionObjRefreshTimer > 300) + UpdateUnionRoomPlayerSprites(uroom); +} + +bool32 TryInteractWithUnionRoomMember(struct RfuPlayerList *list, s16 *memberIdPtr, s16 *leaderIdPtr, u8 *spriteIds) +{ + s16 x, y; + s32 leaderId, memberId; + struct RfuPlayer * leaders; + if (!IsPlayerStandingStill()) + return FALSE; + + GetXYCoordsOneStepInFrontOfPlayer(&x, &y); + for (leaderId = 0, leaders = list->players; leaderId < MAX_UNION_ROOM_LEADERS; leaderId++) + { + for (memberId = 0; memberId < MAX_RFU_PLAYERS; memberId++) + { + s32 objId = UR_PLAYER_SPRITE_ID(leaderId, memberId); + + // Is the player in front of a group member position? + if (x != sUnionRoomPlayerCoords[leaderId][0] + sUnionRoomGroupOffsets[memberId][0] + 7) + continue; + if (y != sUnionRoomPlayerCoords[leaderId][1] + sUnionRoomGroupOffsets[memberId][1] + 7) + continue; + + // Has a group member spawned at this position? + if (IsVirtualObjectInvisible(objId - UR_SPRITE_START_ID) != FALSE) + continue; + if (IsVirtualObjectAnimating(objId - UR_SPRITE_START_ID) != FALSE) + continue; + if (leaders[leaderId].groupScheduledAnim != UNION_ROOM_SPAWN_IN) + continue; + + // Interaction attempt successful, face player + SetUnionRoomObjectFacingDirection(memberId, leaderId, sOppositeFacingDirection[GetPlayerFacingDirection()]); + *memberIdPtr = memberId; + *leaderIdPtr = leaderId; + return TRUE; + } + } + return FALSE; +} + +static void SetUnionRoomObjectFacingDirection(s32 memberId, s32 leaderId, u8 direction) +{ + TurnVirtualObject(MAX_RFU_PLAYERS * leaderId - UR_SPRITE_START_ID + memberId, direction); +} + +void UpdateUnionRoomMemberFacing(u32 memberId, u32 leaderId, struct RfuPlayerList *list) +{ + return SetUnionRoomObjectFacingDirection(memberId, leaderId, GetNewFacingDirectionForUnionRoomPlayer(memberId, leaderId, &list->players[leaderId].rfu.data)); +} diff --git a/sym_ewram.txt b/sym_ewram.txt index 0dc0544c1..f957d320b 100644 --- a/sym_ewram.txt +++ b/sym_ewram.txt @@ -102,7 +102,7 @@ .include "src/help_message.o" .include "src/quest_log_events.o" .include "src/union_room.o" - .include "src/rfu_union_tool.o" + .include "src/union_room_player_avatar.o" .include "src/union_room_battle.o" .include "src/pokemon_special_anim.o" .include "src/party_menu.o" From 91915c5662318efcc04e193ee053c737617683c7 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Tue, 8 Nov 2022 13:39:39 -0500 Subject: [PATCH 7/8] Fix player list array sizes --- include/link_rfu.h | 6 +++--- include/union_room.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/link_rfu.h b/include/link_rfu.h index 47588004c..e3b60ccb4 100644 --- a/include/link_rfu.h +++ b/include/link_rfu.h @@ -240,8 +240,8 @@ void MG_DrawCheckerboardPattern(void); void Rfu_SetCloseLinkCallback(void); bool8 IsLinkRfuTaskFinished(void); void DestroyWirelessStatusIndicatorSprite(void); -void CreateTask_LinkMysteryGiftWithFriend(u32 arg0); -void CreateTask_LinkMysteryGiftOverWireless(u32 arg0); +void CreateTask_LinkMysteryGiftWithFriend(u32 activity); +void CreateTask_LinkMysteryGiftOverWireless(u32 activity); void CreateTask_SendMysteryGift(u32 activity); void Rfu_SendPacket(void *data); u8 CreateTask_ListenToWireless(void); @@ -292,7 +292,7 @@ bool8 LmanAcceptSlotFlagIsNotZero(void); void LinkRfu_StopManagerAndFinalizeSlots(void); bool32 RfuTryDisconnectLeavingChildren(void); bool32 IsRfuCommunicatingWithAllChildren(void); -bool32 WaitRfuState(bool32 a0); +bool32 WaitRfuState(bool32 force); bool32 HasTrainerLeftPartnersList(u16 trainerId, const u8 *trainerName); void SendRfuStatusToPartner(u8 status, u16 trainerId, const u8 *name); u32 WaitSendRfuStatusToPartner(u16 trainerId, const u8 *name); diff --git a/include/union_room.h b/include/union_room.h index 51390c637..0e1fd6260 100644 --- a/include/union_room.h +++ b/include/union_room.h @@ -38,7 +38,7 @@ struct RfuPlayer struct RfuPlayerList { - struct RfuPlayer players[0]; // TODO: Should be size MAX_RFU_PLAYER_LIST_SIZE + struct RfuPlayer players[MAX_RFU_PLAYER_LIST_SIZE]; }; struct RfuIncomingPlayer @@ -49,7 +49,7 @@ struct RfuIncomingPlayer struct RfuIncomingPlayerList { - struct RfuIncomingPlayer players[0]; // TODO: Should be size MAX_RFU_PLAYERS + struct RfuIncomingPlayer players[MAX_RFU_PLAYERS]; }; struct WirelessLink_Leader From a0f41da30d0da423d106967c879852d590dd1026 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Mon, 14 Nov 2022 11:33:17 -0500 Subject: [PATCH 8/8] Label missed symbol --- src/data/union_room.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/data/union_room.h b/src/data/union_room.h index 6c8254d1b..557a93297 100644 --- a/src/data/union_room.h +++ b/src/data/union_room.h @@ -467,4 +467,5 @@ static const u8 sLinkGroupToURoomActivity[] = { [LINK_GROUP_WONDER_NEWS] = ACTIVITY_WONDER_NEWS }; -static const u8 sUnref_84570D1[] = _("{DYNAMIC 00}·{DYNAMIC 01}"); +// Unused +static const u8 sDotSeparatedValues[] = _("{DYNAMIC 00}·{DYNAMIC 01}");