diff --git a/asm/rom_81D1C44.s b/asm/rom_81D1C44.s index 13664a4b2..a9ef8e4f2 100644 --- a/asm/rom_81D1C44.s +++ b/asm/rom_81D1C44.s @@ -6500,7 +6500,7 @@ _081D4F6C: bne _081D4F88 movs r0, 0x49 bl PlaySE - bl sub_800A620 + bl CheckShouldAdvanceLinkState movs r0, 0 strh r0, [r5] b _081D4FE6 diff --git a/common_syms/overworld.txt b/common_syms/overworld.txt index b92da84ec..e136f5444 100644 --- a/common_syms/overworld.txt +++ b/common_syms/overworld.txt @@ -1,8 +1,8 @@ gBGTilemapBuffers1 gBGTilemapBuffers2 gBGTilemapBuffers3 -gUnknown_03005DA8 +gHeldKeyCodeToSend gFieldCallback gFieldCallback2 -gUnknown_03005DB4 +gLocalLinkPlayerId gFieldLinkPlayerCount diff --git a/data/event_scripts.s b/data/event_scripts.s index 1453175b5..fd6cc10cf 100644 --- a/data/event_scripts.s +++ b/data/event_scripts.s @@ -1146,19 +1146,19 @@ EverGrandeCity_HallOfFame_EventScript_271851:: @ 8271851 EventScript_WhiteOut:: @ 8271857 call EverGrandeCity_HallOfFame_EventScript_2718CC - goto EventScript_271862 + goto EventScript_ResetMrBriney end -EventScript_271862:: @ 8271862 +EventScript_ResetMrBriney:: @ 8271862 compare VAR_BRINEY_LOCATION, 1 - goto_if_eq EverGrandeCity_HallOfFame_EventScript_271884 + goto_if_eq EventScript_MoveMrBrineyToHouse compare VAR_BRINEY_LOCATION, 2 - goto_if_eq EverGrandeCity_HallOfFame_EventScript_27189A + goto_if_eq EventScript_MoveMrBrineyToDewford compare VAR_BRINEY_LOCATION, 3 - goto_if_eq EverGrandeCity_HallOfFame_EventScript_2718B3 + goto_if_eq EventScript_MoveMrBrineyToRoute108 end -EverGrandeCity_HallOfFame_EventScript_271884:: @ 8271884 +EventScript_MoveMrBrineyToHouse:: @ 8271884 setflag FLAG_HIDE_MR_BRINEY_DEWFORD_TOWN setflag FLAG_HIDE_MR_BRINEY_BOAT_DEWFORD_TOWN setflag FLAG_HIDE_ROUTE_108_MR_BRINEY @@ -1168,7 +1168,7 @@ EverGrandeCity_HallOfFame_EventScript_271884:: @ 8271884 clearflag FLAG_HIDE_BRINEYS_HOUSE_PEEKO end -EverGrandeCity_HallOfFame_EventScript_27189A:: @ 827189A +EventScript_MoveMrBrineyToDewford:: @ 827189A setflag FLAG_HIDE_ROUTE_108_MR_BRINEY setflag FLAG_HIDE_ROUTE_109_MR_BRINEY_BOAT setflag FLAG_HIDE_ROUTE_104_MR_BRINEY @@ -1179,7 +1179,7 @@ EverGrandeCity_HallOfFame_EventScript_27189A:: @ 827189A clearflag FLAG_HIDE_MR_BRINEY_BOAT_DEWFORD_TOWN end -EverGrandeCity_HallOfFame_EventScript_2718B3:: @ 82718B3 +EventScript_MoveMrBrineyToRoute108:: @ 82718B3 setflag FLAG_HIDE_ROUTE_104_MR_BRINEY setflag FLAG_HIDE_ROUTE_104_MR_BRINEY_BOAT setflag FLAG_HIDE_BRINEYS_HOUSE_MR_BRINEY @@ -1597,7 +1597,7 @@ EventScript_271D5E:: @ 8271D5E goto EventScript_271D89 EventScript_271D83:: @ 8271D83 - special sub_80E6BE8 + special RecordMixingPlayerSpotTriggered waitstate lock faceplayer diff --git a/data/io_reg.s b/data/io_reg.s index e6315cd89..9c5f64f58 100644 --- a/data/io_reg.s +++ b/data/io_reg.s @@ -24,11 +24,11 @@ gUnref_82EC784:: @ 82EC784 .4byte 0x02000100 .4byte 0x08000400 -gUnknown_82EC7C4:: @ 82EC7C4 - .2byte 0x0100 - .2byte 0x0200 - .2byte 0x0400 - .2byte 0x0800 +gOverworldBackgroundLayerFlags:: @ 82EC7C4 + .2byte 0x0100 /* BLDCNT_TGT2_BG0 */ + .2byte 0x0200 /* BLDCNT_TGT2_BG1 */ + .2byte 0x0400 /* BLDCNT_TGT2_BG2 */ + .2byte 0x0800 /* BLDCNT_TGT2_BG3 */ gUnknown_82EC7CC:: @ 82EC7CC .2byte 0x0001 diff --git a/data/maps/DoubleBattleColosseum/map.json b/data/maps/DoubleBattleColosseum/map.json index 7480e36c1..172bb3fdc 100644 --- a/data/maps/DoubleBattleColosseum/map.json +++ b/data/maps/DoubleBattleColosseum/map.json @@ -52,7 +52,7 @@ "elevation": 3, "var": "VAR_TEMP_0", "var_value": "0", - "script": "gUnknown_08277388" + "script": "EventScript_DoubleBattleColosseum_PlayerSpot0" }, { "type": "trigger", @@ -61,7 +61,7 @@ "elevation": 3, "var": "VAR_TEMP_0", "var_value": "0", - "script": "gUnknown_082773BE" + "script": "EventScript_DoubleBattleColosseum_PlayerSpot2" }, { "type": "trigger", @@ -70,7 +70,7 @@ "elevation": 3, "var": "VAR_TEMP_0", "var_value": "0", - "script": "gUnknown_082773A3" + "script": "EventScript_DoubleBattleColosseum_PlayerSpot1" }, { "type": "trigger", @@ -79,7 +79,7 @@ "elevation": 3, "var": "VAR_TEMP_0", "var_value": "0", - "script": "gUnknown_082773D9" + "script": "EventScript_DoubleBattleColosseum_PlayerSpot3" } ], "bg_events": [] diff --git a/data/maps/MossdeepCity_SpaceCenter_2F/scripts.inc b/data/maps/MossdeepCity_SpaceCenter_2F/scripts.inc index d9727235f..797e553c6 100644 --- a/data/maps/MossdeepCity_SpaceCenter_2F/scripts.inc +++ b/data/maps/MossdeepCity_SpaceCenter_2F/scripts.inc @@ -248,7 +248,7 @@ MossdeepCity_SpaceCenter_2F_EventScript_22400C:: @ 822400C waitmovement 0 special SavePlayerParty fadescreen 1 - special sub_80F9438 + special ChooseHalfPartyForBattle waitstate compare VAR_RESULT, 0 goto_if_ne MossdeepCity_SpaceCenter_2F_EventScript_224032 diff --git a/data/maps/RecordCorner/map.json b/data/maps/RecordCorner/map.json index 4777472d2..d34ad4903 100644 --- a/data/maps/RecordCorner/map.json +++ b/data/maps/RecordCorner/map.json @@ -66,7 +66,7 @@ "elevation": 3, "var": "VAR_TEMP_0", "var_value": "0", - "script": "gUnknown_0827741D" + "script": "EventScript_RecordCenter_Spot0" }, { "type": "trigger", @@ -75,7 +75,7 @@ "elevation": 3, "var": "VAR_TEMP_0", "var_value": "0", - "script": "gUnknown_08277447" + "script": "EventScript_RecordCenter_Spot2" }, { "type": "trigger", @@ -84,7 +84,7 @@ "elevation": 3, "var": "VAR_TEMP_0", "var_value": "0", - "script": "gUnknown_08277432" + "script": "EventScript_RecordCenter_Spot1" }, { "type": "trigger", @@ -93,7 +93,7 @@ "elevation": 3, "var": "VAR_TEMP_0", "var_value": "0", - "script": "gUnknown_0827745C" + "script": "EventScript_RecordCenter_Spot3" } ], "bg_events": [] diff --git a/data/maps/SingleBattleColosseum/map.json b/data/maps/SingleBattleColosseum/map.json index 167344e61..a7ad50f1b 100644 --- a/data/maps/SingleBattleColosseum/map.json +++ b/data/maps/SingleBattleColosseum/map.json @@ -52,7 +52,7 @@ "elevation": 3, "var": "VAR_TEMP_0", "var_value": "0", - "script": "gUnknown_08277374" + "script": "EventScript_SingleBattleColosseum_PlayerSpot0" }, { "type": "trigger", @@ -61,7 +61,7 @@ "elevation": 3, "var": "VAR_TEMP_0", "var_value": "0", - "script": "gUnknown_0827737E" + "script": "EventScript_SingleBattleColosseum_PlayerSpot1" } ], "bg_events": [] diff --git a/data/maps/SootopolisCity_MysteryEventsHouse_1F/scripts.inc b/data/maps/SootopolisCity_MysteryEventsHouse_1F/scripts.inc index d107037d4..c7ceb0a4f 100644 --- a/data/maps/SootopolisCity_MysteryEventsHouse_1F/scripts.inc +++ b/data/maps/SootopolisCity_MysteryEventsHouse_1F/scripts.inc @@ -129,7 +129,7 @@ SootopolisCity_MysteryEventsHouse_1F_EventScript_227AE2:: @ 8227AE2 SootopolisCity_MysteryEventsHouse_1F_EventScript_227AEF:: @ 8227AEF msgbox SootopolisCity_MysteryEventsHouse_1F_Text_227C84, MSGBOX_DEFAULT fadescreen 1 - special sub_80F9438 + special ChooseHalfPartyForBattle waitstate return diff --git a/data/maps/TradeCenter/map.json b/data/maps/TradeCenter/map.json index 257c7d1c8..1c409132d 100644 --- a/data/maps/TradeCenter/map.json +++ b/data/maps/TradeCenter/map.json @@ -52,7 +52,7 @@ "elevation": 3, "var": "VAR_TEMP_0", "var_value": "0", - "script": "gUnknown_082773F5" + "script": "EventScript_TradeCenter_Chair0" }, { "type": "trigger", @@ -61,7 +61,7 @@ "elevation": 3, "var": "VAR_TEMP_0", "var_value": "0", - "script": "gUnknown_082773FF" + "script": "EventScript_TradeCenter_Chair1" } ], "bg_events": [] diff --git a/data/scripts/cable_club.inc b/data/scripts/cable_club.inc index 0858dfabb..645ba92b0 100644 --- a/data/scripts/cable_club.inc +++ b/data/scripts/cable_club.inc @@ -791,116 +791,118 @@ EventScript_CableBoxResults:: @ 8277365 releaseall end -gUnknown_08277374:: @ 8277374 +EventScript_SingleBattleColosseum_PlayerSpot0:: @ 8277374 setvar VAR_0x8005, 0 - special sub_80B3968 + special ColosseumPlayerSpotTriggered waitstate end -gUnknown_0827737E:: @ 827737E +EventScript_SingleBattleColosseum_PlayerSpot1:: @ 827737E setvar VAR_0x8005, 1 - special sub_80B3968 + special ColosseumPlayerSpotTriggered waitstate end -gUnknown_08277388:: @ 8277388 +EventScript_DoubleBattleColosseum_PlayerSpot0:: @ 8277388 fadescreen 1 - special sub_80F9438 + special ChooseHalfPartyForBattle waitstate compare VAR_RESULT, 0 - goto_if_eq DoubleBattleColosseum_EventScript_2773F4 + goto_if_eq EventScript_DoubleBattleColosseum_CancelSpotTrigger setvar VAR_0x8005, 0 - special sub_80B3968 + special ColosseumPlayerSpotTriggered waitstate end -gUnknown_082773A3:: @ 82773A3 +EventScript_DoubleBattleColosseum_PlayerSpot1:: @ 82773A3 fadescreen 1 - special sub_80F9438 + special ChooseHalfPartyForBattle waitstate compare VAR_RESULT, 0 - goto_if_eq DoubleBattleColosseum_EventScript_2773F4 + goto_if_eq EventScript_DoubleBattleColosseum_CancelSpotTrigger setvar VAR_0x8005, 1 - special sub_80B3968 + special ColosseumPlayerSpotTriggered waitstate end -gUnknown_082773BE:: @ 82773BE +EventScript_DoubleBattleColosseum_PlayerSpot2:: @ 82773BE fadescreen 1 - special sub_80F9438 + special ChooseHalfPartyForBattle waitstate compare VAR_RESULT, 0 - goto_if_eq DoubleBattleColosseum_EventScript_2773F4 + goto_if_eq EventScript_DoubleBattleColosseum_CancelSpotTrigger setvar VAR_0x8005, 2 - special sub_80B3968 + special ColosseumPlayerSpotTriggered waitstate end -gUnknown_082773D9:: @ 82773D9 +EventScript_DoubleBattleColosseum_PlayerSpot3:: @ 82773D9 fadescreen 1 - special sub_80F9438 + special ChooseHalfPartyForBattle waitstate compare VAR_RESULT, 0 - goto_if_eq DoubleBattleColosseum_EventScript_2773F4 + goto_if_eq EventScript_DoubleBattleColosseum_CancelSpotTrigger setvar VAR_0x8005, 3 - special sub_80B3968 + special ColosseumPlayerSpotTriggered waitstate end -DoubleBattleColosseum_EventScript_2773F4:: @ 82773F4 +EventScript_DoubleBattleColosseum_CancelSpotTrigger:: @ 82773F4 end -gUnknown_082773F5:: @ 82773F5 +EventScript_TradeCenter_Chair0:: @ 82773F5 setvar VAR_0x8005, 0 - special sub_80B3924 + special PlayerEnteredTradeSeat waitstate end -gUnknown_082773FF:: @ 82773FF +EventScript_TradeCenter_Chair1:: @ 82773FF setvar VAR_0x8005, 1 - special sub_80B3924 + special PlayerEnteredTradeSeat waitstate end -gUnknown_08277409:: @ 8277409 +/* Never used */ +EventScript_TradeCenter_Chair2:: @ 8277409 setvar VAR_0x8005, 2 - special sub_80B3924 + special PlayerEnteredTradeSeat waitstate end -gUnknown_08277413:: @ 8277413 +/* Never used */ +EventScript_TradeCenter_Chair3:: @ 8277413 setvar VAR_0x8005, 3 - special sub_80B3924 + special PlayerEnteredTradeSeat waitstate end -gUnknown_0827741D:: @ 827741D +EventScript_RecordCenter_Spot0:: @ 827741D setvar VAR_0x8005, 0 - special sub_80E6BE8 + special RecordMixingPlayerSpotTriggered waitstate compare VAR_TEMP_1, 0 goto_if_ne RecordCorner_EventScript_277471 end -gUnknown_08277432:: @ 8277432 +EventScript_RecordCenter_Spot1:: @ 8277432 setvar VAR_0x8005, 1 - special sub_80E6BE8 + special RecordMixingPlayerSpotTriggered waitstate compare VAR_TEMP_1, 0 goto_if_ne RecordCorner_EventScript_277471 end -gUnknown_08277447:: @ 8277447 +EventScript_RecordCenter_Spot2:: @ 8277447 setvar VAR_0x8005, 2 - special sub_80E6BE8 + special RecordMixingPlayerSpotTriggered waitstate compare VAR_TEMP_1, 0 goto_if_ne RecordCorner_EventScript_277471 end -gUnknown_0827745C:: @ 827745C +EventScript_RecordCenter_Spot3:: @ 827745C setvar VAR_0x8005, 3 - special sub_80E6BE8 + special RecordMixingPlayerSpotTriggered waitstate compare VAR_TEMP_1, 0 goto_if_ne RecordCorner_EventScript_277471 @@ -914,21 +916,21 @@ RecordCorner_EventScript_277471:: @ 8277471 releaseall end -EventScript_TradeRoom_ReadTrainerCard1:: @ 827747E +gEventScript_TradeRoom_ReadTrainerCard_NoColor:: @ 827747E msgbox Text_278452, MSGBOX_DEFAULT fadescreen 1 special sp02A_crash_sound waitstate end -EventScript_TradeRoom_ReadTrainerCard2:: @ 827748D +gEventScript_TradeRoom_ReadTrainerCard_Normal:: @ 827748D msgbox Text_27847B, MSGBOX_DEFAULT fadescreen 1 special sp02A_crash_sound waitstate end -EventScript_TradeRoom_TooBusyToNotice:: @ 827749C +gEventScript_TradeRoom_TooBusyToNotice:: @ 827749C msgbox Text_27842E, MSGBOX_DEFAULT closemessage end @@ -967,22 +969,22 @@ RecordCorner_EventScript_2774E0:: @ 82774E0 closemessage end -gUnknown_082774EF:: @ 82774EF - msgbox Text_2783A8, MSGBOX_YESNO +EventScript_ConfirmLeaveTradeRoom:: @ 82774EF + msgbox Text_TerminateLinkConfirmation, MSGBOX_YESNO compare VAR_RESULT, 1 - goto_if_eq gUnknown_08277509 + goto_if_eq EventScript_TerminateLink erasebox 0, 0, 29, 19 releaseall end -gUnknown_08277509:: @ 8277509 - messageautoscroll Text_2783E9 +EventScript_TerminateLink:: @ 8277509 + messageautoscroll Text_TerminateLinkPleaseWait waitmessage - special sub_80B371C + special ExitLinkRoom end -EventScript_277513:: @ 8277513 - special sub_80B36EC +EventScript_DoLinkRoomExit:: @ 8277513 + special CleanupLinkRoomState special sub_80AF9F8 waitstate end @@ -1736,11 +1738,11 @@ OldaleTown_PokemonCenter_2F_Text_278372: @ 8278372 .string "Please confirm the number of\n" .string "players and start again.$" -Text_2783A8: @ 82783A8 +Text_TerminateLinkConfirmation: @ 82783A8 .string "The link will be terminated if you\n" .string "leave the room. Is that okay?$" -Text_2783E9: @ 82783E9 +Text_TerminateLinkPleaseWait: @ 82783E9 .string "Terminating linkā€¦\n" .string "You will be escorted out of\l" .string "the room. Please wait.$" diff --git a/data/specials.inc b/data/specials.inc index e7f5e6072..32640ccfa 100644 --- a/data/specials.inc +++ b/data/specials.inc @@ -12,8 +12,8 @@ gSpecials:: @ 81DBA64 def_special SetCableClubWarp def_special sub_80AF948 def_special sub_80AF9F8 - def_special sub_80B36EC - def_special sub_80B371C + def_special CleanupLinkRoomState + def_special ExitLinkRoom def_special sub_80E8E18 def_special sub_80E8BC8 def_special sub_80E9068 @@ -35,14 +35,14 @@ gSpecials:: @ 81DBA64 def_special sub_80E91F8 def_special sub_80EA30C def_special DoSecretBasePCTurnOffEffect - def_special sub_80E6BE8 + def_special RecordMixingPlayerSpotTriggered def_special sub_80B2DA4 def_special sub_80B2E4C def_special sub_80B2E74 def_special sub_80B2EA8 def_special CloseLink - def_special sub_80B3968 - def_special sub_80B3924 + def_special ColosseumPlayerSpotTriggered + def_special PlayerEnteredTradeSeat def_special nullsub_37 def_special sub_80B3254 def_special sub_80B2FD8 @@ -50,7 +50,7 @@ gSpecials:: @ 81DBA64 def_special SpawnLinkPartnerEventObject def_special SavePlayerParty def_special LoadPlayerParty - def_special sub_80F9438 + def_special ChooseHalfPartyForBattle def_special sp02A_crash_sound def_special EventObjectInteractionGetBerryTreeData def_special EventObjectInteractionGetBerryName diff --git a/include/cable_club.h b/include/cable_club.h index 60d56460d..c2849ca3e 100644 --- a/include/cable_club.h +++ b/include/cable_club.h @@ -15,6 +15,6 @@ void sub_80B360C(void); bool32 sub_80B2AF4(u16 *arg0, u16 *arg1); void sub_80B3AF8(u8 taskId); void task00_08081A90(u8 taskId); -bool32 sub_80B39D4(u8 linkPlayerIndex); +bool32 GetLinkTrainerCardColor(u8 linkPlayerIndex); #endif //GUARD_CABLE_CLUB_H diff --git a/include/constants/battle_frontier.h b/include/constants/battle_frontier.h index ca9e3bc9f..1224c0f31 100644 --- a/include/constants/battle_frontier.h +++ b/include/constants/battle_frontier.h @@ -10,6 +10,8 @@ #define FRONTIER_FACILITY_PIKE 5 #define FRONTIER_FACILITY_PYRAMID 6 #define NUM_FRONTIER_FACILITIES 7 +// The multiplayer battle colosseum rooms re-use VAR_FRONTIER_FACILITY. +#define FRONTIER_FACILITY_DOUBLE_COLOSSEUM 9 #define TENT_VERDANTURF 2 #define TENT_FALLARBOR 3 diff --git a/include/global.h b/include/global.h index cc026f36a..8737c6388 100644 --- a/include/global.h +++ b/include/global.h @@ -906,13 +906,13 @@ struct MapPosition s8 height; }; -struct UnkStruct_8054FF8 +struct TradeRoomPlayer { - u8 a; - u8 b; + u8 playerId; + u8 isLocalPlayer; u8 c; - u8 d; - struct MapPosition sub; + u8 facing; + struct MapPosition pos; u16 field_C; }; diff --git a/include/link.h b/include/link.h index 11eff5c28..83deab88f 100644 --- a/include/link.h +++ b/include/link.h @@ -244,7 +244,7 @@ bool8 IsLinkTaskFinished(void); void CreateWirelessStatusIndicatorSprite(u8, u8); void sub_800ADF8(void); void sub_800B488(void); -void sub_800A620(void); +void CheckShouldAdvanceLinkState(void); void sub_8011BD0(void); u8 IsLinkMaster(void); void sub_800AC34(void); @@ -299,8 +299,8 @@ extern struct LinkPlayer gLocalLinkPlayer; bool32 Link_AnyPartnersPlayingRubyOrSapphire(void); bool32 sub_800A03C(void); -void sub_8009628(u8); -u8 sub_800AA48(void); +void SetLocalLinkPlayerId(u8); +u8 GetSavedPlayerCount(void); void sub_8009FAC(void); bool8 sub_800A4D8(u8 a0); u8 sub_800A9D8(void); @@ -312,7 +312,7 @@ void sub_800AB18(void); void sub_8009F18(void); bool8 sub_800AA60(void); void sub_800ABF4(u16 a0); -bool32 sub_8009F3C(void); -u32 sub_800B4DC(void); +bool32 IsSendingKeysToLink(void); +u32 GetLinkRecvQueueLength(void); #endif // GUARD_LINK_H diff --git a/include/link_rfu.h b/include/link_rfu.h index c91f9f1d3..5b8ccd9fb 100644 --- a/include/link_rfu.h +++ b/include/link_rfu.h @@ -219,7 +219,7 @@ void sub_800E700(void); void sub_800EDD4(void); void sub_800F6FC(u8 who); void sub_800F728(u8 who); -bool32 sub_800F7E4(void); +bool32 IsSendingKeysToRfu(void); void sub_800F804(void); void sub_800F850(void); u8 sub_800FCD8(void); @@ -238,8 +238,8 @@ void sub_800E6D0(void); bool32 sub_8010EC0(void); bool32 sub_8010F1C(void); bool32 sub_8011A80(void); -bool32 sub_800F0B8(void); -u32 sub_80124D4(void); +bool32 IsRfuRecvQueueEmpty(void); +u32 GetRfuRecvQueueLength(void); void RfuVSync(void); void sub_80111B0(bool32 a0); u8 sub_8011A74(void); diff --git a/include/overworld.h b/include/overworld.h index 8caba0673..203084ae3 100644 --- a/include/overworld.h +++ b/include/overworld.h @@ -1,6 +1,29 @@ #ifndef GUARD_OVERWORLD_H #define GUARD_OVERWORLD_H +#define LINK_KEY_CODE_NULL 0x00 +#define LINK_KEY_CODE_EMPTY 0x11 +#define LINK_KEY_CODE_DPAD_DOWN 0x12 +#define LINK_KEY_CODE_DPAD_UP 0x13 +#define LINK_KEY_CODE_DPAD_LEFT 0x14 +#define LINK_KEY_CODE_DPAD_RIGHT 0x15 +#define LINK_KEY_CODE_UNK_2 0x16 +#define LINK_KEY_CODE_EXIT_ROOM 0x17 +#define LINK_KEY_CODE_START_BUTTON 0x18 +#define LINK_KEY_CODE_A_BUTTON 0x19 +#define LINK_KEY_CODE_UNK_4 0x1A // I'd guess this is the B button? + +// These two are a hack to stop user input until link stuff can be +// resolved. +#define LINK_KEY_CODE_HANDLE_RECV_QUEUE 0x1B +#define LINK_KEY_CODE_HANDLE_SEND_QUEUE 0x1C +#define LINK_KEY_CODE_UNK_7 0x1D +#define LINK_KEY_CODE_UNK_8 0x1E + +#define MOVEMENT_MODE_FREE 0 +#define MOVEMENT_MODE_FROZEN 1 +#define MOVEMENT_MODE_SCRIPTED 2 + struct InitialPlayerAvatarState { u8 transitionFlags; @@ -12,7 +35,7 @@ struct LinkPlayerEventObject u8 active; u8 linkPlayerId; u8 eventObjId; - u8 mode; + u8 movementMode; }; // Exported RAM declarations @@ -22,10 +45,10 @@ extern struct LinkPlayerEventObject gLinkPlayerEventObjects[4]; extern u16 *gBGTilemapBuffers1; extern u16 *gBGTilemapBuffers2; extern u16 *gBGTilemapBuffers3; -extern u16 gUnknown_03005DA8; +extern u16 gHeldKeyCodeToSend; extern void (*gFieldCallback)(void); extern bool8 (*gFieldCallback2)(void); -extern u8 gUnknown_03005DB4; +extern u8 gLocalLinkPlayerId; extern u8 gFieldLinkPlayerCount; // Exported ROM declarations @@ -103,12 +126,12 @@ u8 GetSavedWarpRegionMapSectionId(void); u8 GetCurrentRegionMapSectionId(void); u8 GetCurrentMapBattleScene(void); void CleanupOverworldWindowsAndTilemaps(void); -bool32 is_c1_link_related_active(void); +bool32 IsUpdateLinkStateCBActive(void); void CB1_Overworld(void); void CB2_OverworldBasic(void); void CB2_Overworld(void); void SetMainCallback1(void (*cb)(void)); -void sub_8085E94(void *a0); +void SetUnusedCallback(void *a0); void CB2_NewGame(void); void CB2_WhiteOut(void); void CB2_LoadMap(void); @@ -117,18 +140,18 @@ void sub_8086074(void); void CB2_ReturnToField(void); void CB2_ReturnToFieldLocal(void); void CB2_ReturnToFieldLink(void); -void c2_8056854(void); +void CB2_ReturnToFieldFromMultiplayer(void); void CB2_ReturnToFieldWithOpenMenu(void); void CB2_ReturnToFieldContinueScript(void); void CB2_ReturnToFieldContinueScriptPlayMapMusic(void); void sub_80861E8(void); void CB2_ContinueSavedGame(void); -void sub_8086C2C(void); +void ResetAllMultiplayerState(void); u32 sub_8087214(void); bool32 sub_808727C(void); u16 sub_8087288(void); u16 sub_808729C(void); -u16 sub_80872B0(void); +u16 QueueExitLinkRoomKey(void); u16 sub_80872C4(void); bool32 sub_8087598(void); bool32 sub_80875C8(void); diff --git a/include/party_menu.h b/include/party_menu.h index 702b4fde1..e67dd56f2 100644 --- a/include/party_menu.h +++ b/include/party_menu.h @@ -85,7 +85,7 @@ u8 GetItemEffectType(u16 item); void CB2_PartyMenuFromStartMenu(void); void sub_81B7F60(void); void sub_81B8448(void); -void sub_81B8518(u8 unused); +void InitChooseHalfPartyForBattle(u8 unused); void sub_81B8558(void); void sub_81B8904(u8 initArg, MainCallback callback); void sub_81B892C(void); diff --git a/include/record_mixing.h b/include/record_mixing.h index 0d50f46f9..4cd231e8a 100644 --- a/include/record_mixing.h +++ b/include/record_mixing.h @@ -7,7 +7,7 @@ struct PlayerHallRecords struct RankingHall2P twoPlayers[2]; }; -void sub_80E6BE8(void); +void RecordMixingPlayerSpotTriggered(void); void GetPlayerHallRecords(struct PlayerHallRecords *dst); #endif //GUARD_RECORD_MIXING_H diff --git a/include/save.h b/include/save.h index 42ce8b3f3..7ce86de70 100644 --- a/include/save.h +++ b/include/save.h @@ -83,13 +83,11 @@ bool8 sub_8153380(void); bool8 sub_81533AC(void); u8 sub_81533E0(void); u8 sub_8153408(void); -u8 sub_8153430(void); -bool8 sub_8153474(void); +u8 FullSaveGame(void); +bool8 CheckSaveFile(void); u8 Save_LoadGameData(u8 a1); u16 sub_815355C(void); u8 sub_81534D0(u8); -u8 sub_8153430(void); -bool8 sub_8153474(void); u32 TryCopySpecialSaveSection(u8 sector, u8* dst); u32 sub_8153634(u8 sector, u8* src); void sub_8153688(u8 taskId); diff --git a/include/trainer_card.h b/include/trainer_card.h index 1cadbd8fc..173d23baa 100644 --- a/include/trainer_card.h +++ b/include/trainer_card.h @@ -43,7 +43,7 @@ struct TrainerCard extern struct TrainerCard gTrainerCards[4]; u32 CountPlayerTrainerStars(void); -u8 sub_80C4904(u8 cardId); +u8 GetTrainerCardStars(u8 cardId); void CopyTrainerCardData(struct TrainerCard *dst, u16 *src, u8 gameVersion); void ShowPlayerTrainerCard(void (*callback)(void)); void ShowTrainerCardInLink(u8 arg0, void (*callback)(void)); diff --git a/src/battle_controllers.c b/src/battle_controllers.c index 70a53f332..29272c19a 100644 --- a/src/battle_controllers.c +++ b/src/battle_controllers.c @@ -767,7 +767,7 @@ static void Task_HandleSendLinkBuffersData(u8 taskId) { if (IsLinkMaster()) { - sub_800A620(); + CheckShouldAdvanceLinkState(); gTasks[taskId].data[11]++; } else diff --git a/src/berry_blender.c b/src/berry_blender.c index c85d0e827..87d24e717 100644 --- a/src/berry_blender.c +++ b/src/berry_blender.c @@ -34,6 +34,8 @@ #include "battle_records.h" #include "graphics.h" #include "new_game.h" +#include "save.h" +#include "link.h" #define BLENDER_SCORE_BEST 0 #define BLENDER_SCORE_GOOD 1 @@ -140,15 +142,8 @@ extern const u8 gText_Space[]; extern const u8 gText_BlenderMaxSpeedRecord[]; extern const u8 gText_234Players[]; -extern void sub_800A418(void); -extern u8 sub_800A9D8(void); extern void sub_81AABF0(void (*callback)(void)); extern void sub_800B4C0(void); -extern void ClearLinkCallback(void); -extern void sub_8009F8C(void); -extern void sub_8153430(void); -extern bool8 sub_8153474(void); -extern void sub_80EECEC(void); // this file's functions static void BerryBlender_SetBackgroundsPos(void); @@ -2600,7 +2595,7 @@ static bool8 LinkPlayAgainHandleSaving(void) } break; case 2: - sub_8153430(); + FullSaveGame(); sBerryBlenderData->field_1A0++; sBerryBlenderData->framesToWait = 0; break; @@ -2614,7 +2609,7 @@ static bool8 LinkPlayAgainHandleSaving(void) case 4: if (IsLinkTaskFinished()) { - if (sub_8153474()) + if (CheckSaveFile()) { sBerryBlenderData->field_1A0 = 5; } diff --git a/src/cable_club.c b/src/cable_club.c index 303b0d016..d83508504 100644 --- a/src/cable_club.c +++ b/src/cable_club.c @@ -282,7 +282,7 @@ static void sub_80B2804(u8 taskId) if (GetFieldMessageBoxMode() == FIELD_MESSAGE_BOX_HIDDEN) { - if (sub_800AA48() != GetLinkPlayerCount_2()) + if (GetSavedPlayerCount() != GetLinkPlayerCount_2()) { ShowFieldAutoScrollMessage(gText_ConfirmLinkWhenPlayersReady); gTasks[taskId].func = sub_80B270C; @@ -295,7 +295,7 @@ static void sub_80B2804(u8 taskId) else if (gMain.heldKeys & A_BUTTON) { PlaySE(SE_SELECT); - sub_800A620(); + CheckShouldAdvanceLinkState(); gTasks[taskId].func = sub_80B28A8; } } @@ -310,7 +310,7 @@ static void sub_80B28A8(u8 taskId) || sub_80B2D6C(taskId) == TRUE) return; - if (GetLinkPlayerCount_2() != sub_800AA48()) + if (GetLinkPlayerCount_2() != GetSavedPlayerCount()) { gTasks[taskId].func = sub_80B2D2C; } @@ -352,7 +352,7 @@ static void sub_80B2918(u8 taskId) else { gFieldLinkPlayerCount = GetLinkPlayerCount_2(); - gUnknown_03005DB4 = GetMultiplayerId(); + gLocalLinkPlayerId = GetMultiplayerId(); sub_800AA04(gFieldLinkPlayerCount); card = (struct TrainerCard *)gBlockSendBuffer; TrainerCard_GenerateCardForPlayer(card); @@ -399,7 +399,7 @@ static void sub_80B2A08(u8 taskId) else { gFieldLinkPlayerCount = GetLinkPlayerCount_2(); - gUnknown_03005DB4 = GetMultiplayerId(); + gLocalLinkPlayerId = GetMultiplayerId(); sub_800AA04(gFieldLinkPlayerCount); card = (struct TrainerCard *)gBlockSendBuffer; TrainerCard_GenerateCardForPlayer(card); @@ -764,9 +764,9 @@ static void sub_80B3194(u8 taskId) static void sub_80B31E8(u8 taskId) { - if (sub_800AA48() == GetLinkPlayerCount_2()) + if (GetSavedPlayerCount() == GetLinkPlayerCount_2()) { - sub_800A620(); + CheckShouldAdvanceLinkState(); gTasks[taskId].func = sub_80B3220; } } @@ -972,7 +972,7 @@ void sub_80B360C(void) if (gSpecialVar_0x8004 == 1 || gSpecialVar_0x8004 == 2) { - UpdatePlayerLinkBattleRecords(gUnknown_03005DB4 ^ 1); + UpdatePlayerLinkBattleRecords(gLocalLinkPlayerId ^ 1); if (gWirelessCommType) { switch (gBattleOutcome) @@ -993,13 +993,13 @@ void sub_80B360C(void) } else { - gMain.savedCallback = c2_8056854; + gMain.savedCallback = CB2_ReturnToFieldFromMultiplayer; } SetMainCallback2(sub_80A0514); } -void sub_80B36EC(void) +void CleanupLinkRoomState(void) { if (gSpecialVar_0x8004 == 1 || gSpecialVar_0x8004 == 2 || gSpecialVar_0x8004 == 5 || gSpecialVar_0x8004 == 9) { @@ -1009,9 +1009,9 @@ void sub_80B36EC(void) SetWarpDestinationToDynamicWarp(0x7F); } -void sub_80B371C(void) +void ExitLinkRoom(void) { - sub_80872B0(); + QueueExitLinkRoomKey(); } static void sub_80B3728(u8 taskId) @@ -1028,7 +1028,7 @@ static void sub_80B3728(u8 taskId) if (IsFieldMessageBoxHidden()) { sub_8087288(); - sub_8009628(gSpecialVar_0x8005); + SetLocalLinkPlayerId(gSpecialVar_0x8005); task->data[0] = 2; } break; @@ -1130,7 +1130,8 @@ static void sub_80B3894(u8 taskId) } } -void sub_80B3924(void) +// Note: VAR_0x8005 is set to the ID of the trade seat. +void PlayerEnteredTradeSeat(void) { if (gWirelessCommType != 0) { @@ -1152,7 +1153,8 @@ void nullsub_37(void) } -void sub_80B3968(void) +// Note: VAR_0x8005 is set to the ID of the player spot. +void ColosseumPlayerSpotTriggered(void) { gLinkType = 0x2211; @@ -1166,6 +1168,7 @@ void sub_80B3968(void) } } +// This function is never called. static void sub_80B39A4(void) { u8 taskId = CreateTask(sub_80B3728, 80); @@ -1177,14 +1180,16 @@ void sp02A_crash_sound(void) ShowTrainerCardInLink(gSpecialVar_0x8006, CB2_ReturnToFieldContinueScriptPlayMapMusic); } -bool32 sub_80B39D4(u8 linkPlayerIndex) +// Returns FALSE if the player has no stars. Returns TRUE otherwise, and puts the name of the +// color into gStringVar2. +bool32 GetLinkTrainerCardColor(u8 linkPlayerIndex) { u32 trainerCardColorIndex; gSpecialVar_0x8006 = linkPlayerIndex; StringCopy(gStringVar1, gLinkPlayers[linkPlayerIndex].name); - trainerCardColorIndex = sub_80C4904(linkPlayerIndex); + trainerCardColorIndex = GetTrainerCardStars(linkPlayerIndex); if (trainerCardColorIndex == 0) return FALSE; @@ -1263,13 +1268,13 @@ void sub_80B3AF8(u8 taskId) } break; case 2: - if (GetLinkPlayerCount_2() >= sub_800AA48()) + if (GetLinkPlayerCount_2() >= GetSavedPlayerCount()) { if (IsLinkMaster()) { if (++data[1] > 30) { - sub_800A620(); + CheckShouldAdvanceLinkState(); data[0]++; } } diff --git a/src/easy_chat.c b/src/easy_chat.c index aa681eeba..a8fb12eb5 100644 --- a/src/easy_chat.c +++ b/src/easy_chat.c @@ -1114,7 +1114,7 @@ static void sub_811A2A4(u8 taskId, TaskFunc taskFunc) static void sub_811A2C0(u8 taskId) { - if (!is_c1_link_related_active()) + if (!IsUpdateLinkStateCBActive()) { while (sub_811A428(taskId)); } diff --git a/src/field_screen_effect.c b/src/field_screen_effect.c index 0a4f3212b..e7476dea3 100644 --- a/src/field_screen_effect.c +++ b/src/field_screen_effect.c @@ -255,7 +255,7 @@ void sub_80AF2B4(u8 taskId) break; case 2: sub_8009F18(); - sub_8086C2C(); + ResetAllMultiplayerState(); ScriptContext2_Disable(); DestroyTask(taskId); break; @@ -621,7 +621,7 @@ void sub_80AF948(void) CreateTask(sub_80AF8E0, 10); } -static void sub_80AF96C(u8 taskId) +static void Task_ReturnToWorldFromLinkRoom(u8 taskId) { s16 *data = gTasks[taskId].data; @@ -654,7 +654,7 @@ static void sub_80AF96C(u8 taskId) void sub_80AF9F8(void) { - CreateTask(sub_80AF96C, 10); + CreateTask(Task_ReturnToWorldFromLinkRoom, 10); } static void sub_80AFA0C(u8 taskId) diff --git a/src/link.c b/src/link.c index bec9dddc6..72ac3e878 100644 --- a/src/link.c +++ b/src/link.c @@ -28,7 +28,7 @@ #include "link.h" #include "link_rfu.h" -extern u16 gUnknown_03005DA8; +extern u16 gHeldKeyCodeToSend; // Static type declarations @@ -302,9 +302,9 @@ void LinkTestScreen(void) SetMainCallback2(CB2_LinkTest); } -void sub_8009628(u8 a0) +void SetLocalLinkPlayerId(u8 playerId) { - gLocalLinkPlayer.id = a0; + gLocalLinkPlayer.id = playerId; } static void InitLocalLinkPlayer(void) @@ -695,12 +695,12 @@ static void BuildSendCmd(u16 command) gSendCmd[0] = LINKCMD_0x5566; break; case LINKCMD_SEND_HELD_KEYS_2: - if (gUnknown_03005DA8 == 0 || gLinkTransferringData) + if (gHeldKeyCodeToSend == 0 || gLinkTransferringData) { break; } gSendCmd[0] = LINKCMD_SEND_HELD_KEYS_2; - gSendCmd[1] = gUnknown_03005DA8; + gSendCmd[1] = gHeldKeyCodeToSend; break; } } @@ -714,11 +714,11 @@ void sub_8009F18(void) gLinkCallback = sub_8009F70; } -bool32 sub_8009F3C(void) +bool32 IsSendingKeysToLink(void) { if (gWirelessCommType) { - return sub_800F7E4(); + return IsSendingKeysToRfu(); } if (gLinkCallback == sub_8009F70) { @@ -1142,7 +1142,7 @@ void ResetBlockReceivedFlag(u8 who) } } -void sub_800A620(void) +void CheckShouldAdvanceLinkState(void) { if ((gLinkStatus & LINK_STAT_MASTER) && EXTRACT_PLAYER_COUNT(gLinkStatus) > 1) { @@ -1327,7 +1327,9 @@ void sub_800AA04(u8 a0) } } -u8 sub_800AA48(void) +// The number of players when trading began. This is frequently compared against the +// current number of connected players to check if anyone dropped out. +u8 GetSavedPlayerCount(void) { return gSavedLinkPlayerCount; } @@ -1849,7 +1851,7 @@ bool8 HandleLinkConnection(void) r5 = sub_8010F1C(); if (sub_808766C() == TRUE) { - if (r4 == TRUE || sub_800F0B8() || r5) + if (r4 == TRUE || IsRfuRecvQueueEmpty() || r5) { return TRUE; } @@ -1882,18 +1884,18 @@ void sub_800B4C0(void) } } -u32 sub_800B4DC(void) +u32 GetLinkRecvQueueLength(void) { if (gWirelessCommType != 0) { - return sub_80124D4(); + return GetRfuRecvQueueLength(); } return gLink.recvQueue.count; } bool8 sub_800B504(void) { - if (sub_800B4DC() > 2) + if (GetLinkRecvQueueLength() > 2) { return TRUE; } diff --git a/src/link_rfu.c b/src/link_rfu.c index 4ad2a5169..8da6b166a 100644 --- a/src/link_rfu.c +++ b/src/link_rfu.c @@ -18,7 +18,7 @@ #include "constants/species.h" #include "save.h" -extern u16 gUnknown_03005DA8; +extern u16 gHeldKeyCodeToSend; extern void nullsub_89(u8 taskId); struct UnkRfuStruct_1 gUnknown_03004140; @@ -2991,7 +2991,7 @@ static void sub_800F048(void) } } -bool32 sub_800F0B8(void) +bool32 IsRfuRecvQueueEmpty(void) { s32 i; s32 j; @@ -3212,7 +3212,7 @@ bool32 sub_800F4F0(void) for (i = 0; i < CMD_LENGTH - 1; i++) gSendCmd[i] = 0; } - return sub_800F0B8(); + return IsRfuRecvQueueEmpty(); } void sub_800F638(u8 unused, u32 flags) @@ -3272,10 +3272,12 @@ u8 sub_800F74C(const u8 *a0) void rfu_func_080F97B8(void) { - if (gReceivedRemoteLinkPlayers && gUnknown_03005DA8 && gLinkTransferringData != 1) + if (gReceivedRemoteLinkPlayers + && gHeldKeyCodeToSend != LINK_KEY_CODE_NULL + && gLinkTransferringData != TRUE) { gUnknown_03000D78[0]++; - gUnknown_03005DA8 |= (gUnknown_03000D78[0] << 8); + gHeldKeyCodeToSend |= (gUnknown_03000D78[0] << 8); sub_800FD14(0xbe00); } } @@ -3285,7 +3287,7 @@ struct UnkLinkRfuStruct_02022B14 *sub_800F7DC(void) return &gUnknown_02022B14; } -bool32 sub_800F7E4(void) +bool32 IsSendingKeysToRfu(void) { return gUnknown_03005000.unk_00 == rfu_func_080F97B8; } @@ -3509,7 +3511,7 @@ void sub_800FD14(u16 command) gSendCmd[1 + i] = gUnknown_03005000.unk_f2[i]; break; case 0xbe00: - gSendCmd[1] = gUnknown_03005DA8; + gSendCmd[1] = gHeldKeyCodeToSend; break; case 0xee00: break; @@ -3799,10 +3801,10 @@ bool32 sub_8010454(u32 a0) u8 sub_801048C(bool32 a0) { - if (a0 == 0) + if (a0 == FALSE) return sub_800D550(0, 0); sub_800D550(1, 0x258); - return FALSE; + return 0; } void sub_80104B0(void) @@ -5163,7 +5165,7 @@ u32 sub_80124C0(void) return gUnknown_03005000.unk_9e8.unk_232; } -u32 sub_80124D4(void) +u32 GetRfuRecvQueueLength(void) { return gUnknown_03005000.unk_124.unk_8c2; } diff --git a/src/menu_helpers.c b/src/menu_helpers.c index e6547b300..846c23b6b 100644 --- a/src/menu_helpers.c +++ b/src/menu_helpers.c @@ -293,7 +293,7 @@ bool8 sub_8122148(u16 itemId) bool8 itemid_80BF6D8_mail_related(u16 itemId) { - if (is_c1_link_related_active() != TRUE && InUnionRoom() != TRUE) + if (IsUpdateLinkStateCBActive() != TRUE && InUnionRoom() != TRUE) return TRUE; else if (ItemIsMail(itemId) != TRUE) return TRUE; @@ -303,7 +303,7 @@ bool8 itemid_80BF6D8_mail_related(u16 itemId) bool8 sub_81221AC(void) { - if (is_c1_link_related_active() == TRUE || gReceivedRemoteLinkPlayers == 1) + if (IsUpdateLinkStateCBActive() == TRUE || gReceivedRemoteLinkPlayers == 1) return TRUE; else return FALSE; diff --git a/src/mystery_event_menu.c b/src/mystery_event_menu.c index 0de4675d9..2058bb81f 100644 --- a/src/mystery_event_menu.c +++ b/src/mystery_event_menu.c @@ -179,7 +179,7 @@ static void CB2_MysteryEventMenu(void) if (gMain.newKeys & A_BUTTON) { PlaySE(SE_SELECT); - sub_800A620(); + CheckShouldAdvanceLinkState(); SetWindowBorderStyle(1, 1, 1, 0xD); PrintMysteryMenuText(1, gText_LoadingEvent, 1, 2, 0); PutWindowTilemap(1); diff --git a/src/overworld.c b/src/overworld.c index a10d1e17a..be94a694b 100644 --- a/src/overworld.c +++ b/src/overworld.c @@ -66,32 +66,47 @@ #include "constants/species.h" #include "constants/weather.h" +#define PLAYER_TRADING_STATE_IDLE 0x80 +#define PLAYER_TRADING_STATE_BUSY 0x81 +#define PLAYER_TRADING_STATE_UNK_2 0x82 +#define PLAYER_TRADING_STATE_EXITING_ROOM 0x83 + +#define FACING_NONE 0 +#define FACING_UP 1 +#define FACING_DOWN 2 +#define FACING_LEFT 3 +#define FACING_RIGHT 4 +#define FACING_FORCED_UP 7 +#define FACING_FORCED_DOWN 8 +#define FACING_FORCED_LEFT 9 +#define FACING_FORCED_RIGHT 10 + // event scripts extern const u8 EventScript_WhiteOut[]; -extern const u8 EventScript_271862[]; -extern const u8 EventScript_277513[]; -extern const u8 EventScript_TradeRoom_TooBusyToNotice[]; -extern const u8 EventScript_TradeRoom_ReadTrainerCard1[]; -extern const u8 EventScript_TradeRoom_ReadTrainerCard2[]; -extern const u8 gUnknown_08277388[]; -extern const u8 gUnknown_082773A3[]; -extern const u8 gUnknown_082773BE[]; -extern const u8 gUnknown_082773D9[]; -extern const u8 gUnknown_0827741D[]; -extern const u8 gUnknown_08277432[]; -extern const u8 gUnknown_08277447[]; -extern const u8 gUnknown_0827745C[]; -extern const u8 gUnknown_08277374[]; -extern const u8 gUnknown_0827737E[]; -extern const u8 gUnknown_082773FF[]; -extern const u8 gUnknown_082773F5[]; -extern const u8 gUnknown_082774EF[]; -extern const u8 gUnknown_08277509[]; +extern const u8 EventScript_ResetMrBriney[]; +extern const u8 EventScript_DoLinkRoomExit[]; +extern const u8 gEventScript_TradeRoom_TooBusyToNotice[]; +extern const u8 gEventScript_TradeRoom_ReadTrainerCard_NoColor[]; +extern const u8 gEventScript_TradeRoom_ReadTrainerCard_Normal[]; +extern const u8 EventScript_DoubleBattleColosseum_PlayerSpot0[]; +extern const u8 EventScript_DoubleBattleColosseum_PlayerSpot1[]; +extern const u8 EventScript_DoubleBattleColosseum_PlayerSpot2[]; +extern const u8 EventScript_DoubleBattleColosseum_PlayerSpot3[]; +extern const u8 EventScript_RecordCenter_Spot0[]; +extern const u8 EventScript_RecordCenter_Spot1[]; +extern const u8 EventScript_RecordCenter_Spot2[]; +extern const u8 EventScript_RecordCenter_Spot3[]; +extern const u8 EventScript_SingleBattleColosseum_PlayerSpot0[]; +extern const u8 EventScript_SingleBattleColosseum_PlayerSpot1[]; +extern const u8 EventScript_TradeCenter_Chair1[]; +extern const u8 EventScript_TradeCenter_Chair0[]; +extern const u8 EventScript_ConfirmLeaveTradeRoom[]; +extern const u8 EventScript_TerminateLink[]; extern const struct MapLayout *const gMapLayouts[]; extern const struct MapHeader *const *const gMapGroups[]; extern const int gMaxFlashLevel; -extern const u16 gUnknown_82EC7C4[]; +extern const u16 gOverworldBackgroundLayerFlags[]; static void Overworld_ResetStateAfterWhiteOut(void); static void c2_80567AC(void); @@ -106,63 +121,63 @@ static bool32 load_map_stuff(u8 *state, u32); static bool32 map_loading_iteration_2_link(u8 *state); static void mli4_mapscripts_and_other(void); static void InitOverworldGraphicsRegisters(void); -static u8 sub_8087858(u8); -static u16 sub_80871C0(u32 a1); +static u8 GetSpriteForLinkedPlayer(u8); +static u16 KeyInterCB_SendNothing(u32 a1); static void sub_80867C8(void); static void sub_80867D8(void); static void sub_8086AE4(void); static void sub_80869DC(void); static void sub_8086B14(void); -static void sub_8086AAC(void); +static void SetCameraToTrackGuestPlayer(void); static void sub_8086988(bool32 arg0); static void sub_8086A80(void); static void sub_8086A68(void); static void sub_8086860(void); -static void sub_8086AC8(void); -static void sub_8086B9C(void); -static void sub_8086C40(void); -static void sub_8086C90(void); -static void sub_8086FA0(u16); -static void sub_8086F38(u16*, s32); -static u8 npc_something3(u8 a1, u8 a2); +static void SetCameraToTrackGuestPlayer_2(void); +static void CreateLinkPlayerSprites(void); +static void ClearAllPlayerKeys(void); +static void ResetAllTradingStates(void); +static void UpdateHeldKeyCode(u16); +static void UpdateAllLinkPlayers(u16*, s32); +static u8 FlipVerticalAndClearForced(u8 a1, u8 a2); static u8 LinkPlayerDetectCollision(u8 selfEventObjId, u8 a2, s16 x, s16 y); static void CreateLinkPlayerSprite(u8 linkPlayerId, u8 gameVersion); -static void sub_8087878(u8 linkPlayerId, u16 *x, u16 *y); -static u8 sub_80878A0(u8 linkPlayerId); -static u8 sub_80878C0(u8 linkPlayerId); +static void GetLinkPlayerCoords(u8 linkPlayerId, u16 *x, u16 *y); +static u8 GetLinkPlayerFacingDirection(u8 linkPlayerId); +static u8 GetLinkPlayerElevation(u8 linkPlayerId); static s32 sub_80878E4(u8 linkPlayerId); static u8 GetLinkPlayerIdAt(s16 x, s16 y); -static void sub_808796C(u8 linkPlayerId, u8 a2); +static void SetPlayerFacingDirection(u8 linkPlayerId, u8 a2); static void ZeroEventObject(struct EventObject *eventObj); static void SpawnLinkPlayerEventObject(u8 linkPlayerId, s16 x, s16 y, u8 a4); static void InitLinkPlayerEventObjectPos(struct EventObject *eventObj, s16 x, s16 y); static void sub_80877DC(u8 linkPlayerId, u8 a2); static void sub_808780C(u8 linkPlayerId); -static u8 sub_8087858(u8 linkPlayerId); +static u8 GetSpriteForLinkedPlayer(u8 linkPlayerId); static void sub_8087584(void); -static u32 sub_8087690(void); +static u32 GetLinkSendQueueLength(void); static void ZeroLinkPlayerEventObject(struct LinkPlayerEventObject *linkPlayerEventObj); -static const u8 *sub_80873B4(struct UnkStruct_8054FF8 *a1); -static u16 sub_8087480(const u8 *script); +static const u8 *TryInteractWithPlayer(struct TradeRoomPlayer *a1); +static u16 GetDirectionForEventScript(const u8 *script); static void sub_8087510(void); -static void sub_808751C(void); +static void InitLinkRoomStartMenuScript(void); static void sub_8087530(const u8 *script); -static void sub_808754C(void); -static void sub_8087568(const u8 *script); -static void sub_80872D8(s32 linkPlayerId, s32 a2, struct UnkStruct_8054FF8 *a3); -static bool32 sub_8087340(struct UnkStruct_8054FF8 *a1); -static bool32 sub_8087358(struct UnkStruct_8054FF8 *a1); -static u8 *sub_8087370(struct UnkStruct_8054FF8 *a1); -static bool32 sub_8087388(struct UnkStruct_8054FF8 *a1); -static const u8 *sub_80873B4(struct UnkStruct_8054FF8 *a1); -static u16 sub_808711C(u32); -static u16 sub_8087140(u32); -static void sub_808709C(u16 *a1); -static u16 sub_80870B0(u32 a1); -static u16 sub_80870F8(u32 a1); -static u16 sub_8087068(u16 a1); -static void c1_link_related(void); -static void c1_link_related_func_set(u16 (*func)(u32)); +static void CreateConfirmLeaveTradeRoomPrompt(void); +static void InitMenuBasedScript(const u8 *script); +static void LoadTradeRoomPlayer(s32 linkPlayerId, s32 a2, struct TradeRoomPlayer *a3); +static bool32 sub_8087340(struct TradeRoomPlayer *a1); +static bool32 sub_8087340_2(struct TradeRoomPlayer *a1); +static u8 *TryGetTileEventScript(struct TradeRoomPlayer *a1); +static bool32 PlayerIsAtSouthExit(struct TradeRoomPlayer *a1); +static const u8 *TryInteractWithPlayer(struct TradeRoomPlayer *a1); +static u16 KeyInterCB_DeferToRecvQueue(u32); +static u16 KeyInterCB_DeferToSendQueue(u32); +static void ResetPlayerHeldKeys(u16 *a1); +static u16 KeyInterCB_SelfIdle(u32 a1); +static u16 KeyInterCB_DeferToEventScript(u32 a1); +static u16 GetDirectionForDpadKey(u16 a1); +static void CB1_UpdateLinkState(void); +static void SetKeyInterceptCallback(u16 (*func)(u32)); static void SetFieldVBlankCallback(void); static void FieldClearVBlankHBlankCallbacks(void); static void sub_8085810(void); @@ -171,21 +186,24 @@ static u8 GetAdjustedInitialDirection(struct InitialPlayerAvatarState *playerStr static u16 GetCenterScreenMetatileBehavior(void); // IWRAM bss vars -IWRAM_DATA static void *sUnknown_03000E0C; -IWRAM_DATA static u8 sUnknown_03000E10[4]; -IWRAM_DATA static u16 (*sUnknown_03000E14)(u32); -IWRAM_DATA static u8 sUnknown_03000E18; -IWRAM_DATA static u8 sUnknown_03000E19; +IWRAM_DATA static void *sUnusedOverworldCallback; +IWRAM_DATA static u8 sPlayerTradingStates[4]; +// This callback is called with a player's key code. It then returns an +// adjusted key code, effectively intercepting the input before anything +// can process it. +IWRAM_DATA static u16 (*sPlayerKeyInterceptCallback)(u32); +IWRAM_DATA static bool8 sUnknown_03000E18; +IWRAM_DATA static u8 sRfuKeepAliveTimer; IWRAM_DATA static u32 sUnusedVar; // IWRAM common u16 *gBGTilemapBuffers1; u16 *gBGTilemapBuffers2; u16 *gBGTilemapBuffers3; -u16 gUnknown_03005DA8; +u16 gHeldKeyCodeToSend; void (*gFieldCallback)(void); bool8 (*gFieldCallback2)(void); -u8 gUnknown_03005DB4; +u8 gLocalLinkPlayerId; // This is our player id in a multiplayer mode. u8 gFieldLinkPlayerCount; // EWRAM vars @@ -319,43 +337,47 @@ static const struct ScanlineEffectParams sFlashEffectParams = 0, }; -static u8 sub_80879D8(struct LinkPlayerEventObject *, struct EventObject *, u8); -static u8 sub_80879F8(struct LinkPlayerEventObject *, struct EventObject *, u8); -static u8 sub_80879FC(struct LinkPlayerEventObject *, struct EventObject *, u8); +static u8 MovementEventModeCB_Normal(struct LinkPlayerEventObject *, struct EventObject *, u8); +static u8 MovementEventModeCB_Ignored(struct LinkPlayerEventObject *, struct EventObject *, u8); +static u8 MovementEventModeCB_Normal_2(struct LinkPlayerEventObject *, struct EventObject *, u8); -static u8 (*const gUnknown_08339DC8[])(struct LinkPlayerEventObject *, struct EventObject *, u8) = +static u8 (*const gLinkPlayerMovementModes[])(struct LinkPlayerEventObject *, struct EventObject *, u8) = { - sub_80879D8, - sub_80879F8, - sub_80879FC, + MovementEventModeCB_Normal, // MOVEMENT_MODE_FREE + MovementEventModeCB_Ignored, // MOVEMENT_MODE_FROZEN + MovementEventModeCB_Normal_2, // MOVEMENT_MODE_SCRIPTED }; -static u8 sub_8087A1C(struct LinkPlayerEventObject *, struct EventObject *, u8); -static u8 sub_8087A20(struct LinkPlayerEventObject *, struct EventObject *, u8); -static u8 sub_8087A88(struct LinkPlayerEventObject *, struct EventObject *, u8); +static u8 FacingHandler_DoNothing(struct LinkPlayerEventObject *, struct EventObject *, u8); +static u8 FacingHandler_DpadMovement(struct LinkPlayerEventObject *, struct EventObject *, u8); +static u8 FacingHandler_ForcedFacingChange(struct LinkPlayerEventObject *, struct EventObject *, u8); -static u8 (*const gUnknown_08339DD4[])(struct LinkPlayerEventObject *, struct EventObject *, u8) = +// These handlers return TRUE if the movement was scripted and successful, and FALSE otherwise. +static bool8 (*const gLinkPlayerFacingHandlers[])(struct LinkPlayerEventObject *, struct EventObject *, u8) = { - sub_8087A1C, - sub_8087A20, - sub_8087A20, - sub_8087A20, - sub_8087A20, - sub_8087A1C, - sub_8087A1C, - sub_8087A88, - sub_8087A88, - sub_8087A88, - sub_8087A88, + FacingHandler_DoNothing, + FacingHandler_DpadMovement, + FacingHandler_DpadMovement, + FacingHandler_DpadMovement, + FacingHandler_DpadMovement, + FacingHandler_DoNothing, + FacingHandler_DoNothing, + FacingHandler_ForcedFacingChange, + FacingHandler_ForcedFacingChange, + FacingHandler_ForcedFacingChange, + FacingHandler_ForcedFacingChange, }; -static void sub_8087AA0(struct LinkPlayerEventObject *, struct EventObject *); -static void sub_8087AA8(struct LinkPlayerEventObject *, struct EventObject *); +static void MovementStatusHandler_EnterFreeMode(struct LinkPlayerEventObject *, struct EventObject *); +static void MovementStatusHandler_TryAdvanceScript(struct LinkPlayerEventObject *, struct EventObject *); -static void (*const gUnknown_08339E00[])(struct LinkPlayerEventObject *, struct EventObject *) = +// These handlers are run after an attempted movement. +static void (*const gMovementStatusHandler[])(struct LinkPlayerEventObject *, struct EventObject *) = { - sub_8087AA0, - sub_8087AA8, + // FALSE: + MovementStatusHandler_EnterFreeMode, + // TRUE: + MovementStatusHandler_TryAdvanceScript, }; // code @@ -387,7 +409,7 @@ void Overworld_ResetStateAfterTeleport(void) FlagClear(FLAG_SYS_SAFARI_MODE); FlagClear(FLAG_SYS_USE_STRENGTH); FlagClear(FLAG_SYS_USE_FLASH); - ScriptContext2_RunNewScript(EventScript_271862); + ScriptContext2_RunNewScript(EventScript_ResetMrBriney); } void Overworld_ResetStateAfterDigEscRope(void) @@ -1407,9 +1429,9 @@ static void ResetSafariZoneFlag_(void) ResetSafariZoneFlag(); } -bool32 is_c1_link_related_active(void) +bool32 IsUpdateLinkStateCBActive(void) { - if (gMain.callback1 == c1_link_related) + if (gMain.callback1 == CB1_UpdateLinkState) return TRUE; else return FALSE; @@ -1476,9 +1498,10 @@ void SetMainCallback1(MainCallback cb) gMain.callback1 = cb; } -void sub_8085E94(void *a0) +// This function is never called. +void SetUnusedCallback(void *func) { - sUnknown_03000E0C = a0; + sUnusedOverworldCallback = func; } static bool8 map_post_load_hook_exec(void) @@ -1595,15 +1618,15 @@ static void c2_80567AC(void) if (map_loading_iteration_3(&gMain.state)) { SetFieldVBlankCallback(); - SetMainCallback1(c1_link_related); - sub_8086C2C(); + SetMainCallback1(CB1_UpdateLinkState); + ResetAllMultiplayerState(); SetMainCallback2(CB2_Overworld); } } void CB2_ReturnToField(void) { - if (is_c1_link_related_active() == TRUE) + if (IsUpdateLinkStateCBActive() == TRUE) { SetMainCallback2(CB2_ReturnToFieldLink); } @@ -1629,12 +1652,12 @@ void CB2_ReturnToFieldLink(void) SetMainCallback2(CB2_Overworld); } -void c2_8056854(void) +void CB2_ReturnToFieldFromMultiplayer(void) { FieldClearVBlankHBlankCallbacks(); StopMapMusic(); - SetMainCallback1(c1_link_related); - sub_8086C2C(); + SetMainCallback1(CB1_UpdateLinkState); + ResetAllMultiplayerState(); if (gWirelessCommType != 0) gFieldCallback = sub_80AF314; @@ -1810,7 +1833,7 @@ static bool32 map_loading_iteration_3(u8 *state) sub_8086AE4(); sub_80869DC(); sub_8086B14(); - sub_8086AAC(); + SetCameraToTrackGuestPlayer(); (*state)++; break; case 4: @@ -1980,9 +2003,9 @@ static bool32 map_loading_iteration_2_link(u8 *state) (*state)++; break; case 2: - sub_8086B9C(); + CreateLinkPlayerSprites(); sub_8086A68(); - sub_8086AC8(); + SetCameraToTrackGuestPlayer_2(); (*state)++; break; case 3: @@ -2083,7 +2106,7 @@ static void InitOverworldGraphicsRegisters(void) SetGpuReg(REG_OFFSET_WIN0V, 0xFF); SetGpuReg(REG_OFFSET_WIN1H, 0xFFFF); SetGpuReg(REG_OFFSET_WIN1V, 0xFFFF); - SetGpuReg(REG_OFFSET_BLDCNT, gUnknown_82EC7C4[1] | gUnknown_82EC7C4[2] | gUnknown_82EC7C4[3] + SetGpuReg(REG_OFFSET_BLDCNT, gOverworldBackgroundLayerFlags[1] | gOverworldBackgroundLayerFlags[2] | gOverworldBackgroundLayerFlags[3] | BLDCNT_TGT2_OBJ | BLDCNT_EFFECT_BLEND); SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(13, 7)); InitOverworldBgs(); @@ -2169,21 +2192,25 @@ static void sub_8086A80(void) InitCameraUpdateCallback(gPlayerAvatar.spriteId); } -static void sub_8086AAC(void) +static void SetCameraToTrackGuestPlayer(void) { - InitCameraUpdateCallback(sub_8087858(gUnknown_03005DB4)); + InitCameraUpdateCallback(GetSpriteForLinkedPlayer(gLocalLinkPlayerId)); } -static void sub_8086AC8(void) +// Duplicate function. +static void SetCameraToTrackGuestPlayer_2(void) { - InitCameraUpdateCallback(sub_8087858(gUnknown_03005DB4)); + InitCameraUpdateCallback(GetSpriteForLinkedPlayer(gLocalLinkPlayerId)); } static void sub_8086AE4(void) { u16 x, y; GetCameraFocusCoords(&x, &y); - sub_8088B3C(x + gUnknown_03005DB4, y); + + // This is a hack of some kind; it's undone in sub_8086B14, which is called + // soon after this function. + sub_8088B3C(x + gLocalLinkPlayerId, y); } static void sub_8086B14(void) @@ -2192,7 +2219,7 @@ static void sub_8086B14(void) u16 x, y; GetCameraFocusCoords(&x, &y); - x -= gUnknown_03005DB4; + x -= gLocalLinkPlayerId; for (i = 0; i < gFieldLinkPlayerCount; i++) { @@ -2200,161 +2227,180 @@ static void sub_8086B14(void) CreateLinkPlayerSprite(i, gLinkPlayers[i].version); } - sub_8086C40(); + ClearAllPlayerKeys(); } -static void sub_8086B9C(void) +static void CreateLinkPlayerSprites(void) { u16 i; for (i = 0; i < gFieldLinkPlayerCount; i++) CreateLinkPlayerSprite(i, gLinkPlayers[i].version); } -static void c1_link_related(void) + +static void CB1_UpdateLinkState(void) { - if (gWirelessCommType == 0 || !sub_800F0B8() || !sub_8009F3C()) + if (gWirelessCommType == 0 || !IsRfuRecvQueueEmpty() || !IsSendingKeysToLink()) { - u8 var = gUnknown_03005DB4; - sub_8086F38(gLinkPartnersHeldKeys, var); - sub_8086FA0(sUnknown_03000E14(var)); - sub_8086C40(); + u8 selfId = gLocalLinkPlayerId; + UpdateAllLinkPlayers(gLinkPartnersHeldKeys, selfId); + + // Note: Because guestId is between 0 and 4, while the smallest key code is + // LINK_KEY_CODE_EMPTY, this is functionally equivalent to `sPlayerKeyInterceptCallback(0)`. + // It is expecting the callback to be KeyInterCB_SelfIdle, and that will + // completely ignore any input parameters. + // + // UpdateHeldKeyCode performs a sanity check on its input; if + // sPlayerKeyInterceptCallback echoes back the argument, which is selfId, then + // it'll use LINK_KEY_CODE_EMPTY instead. + // + // Note 2: There are some key intercept callbacks that treat the key as a player + // ID. It's so hacky. + UpdateHeldKeyCode(sPlayerKeyInterceptCallback(selfId)); + ClearAllPlayerKeys(); } } -void sub_8086C2C(void) +void ResetAllMultiplayerState(void) { - sub_8086C90(); - c1_link_related_func_set(sub_80870B0); + ResetAllTradingStates(); + SetKeyInterceptCallback(KeyInterCB_SelfIdle); } -static void sub_8086C40(void) +static void ClearAllPlayerKeys(void) { - sub_808709C(gLinkPartnersHeldKeys); + ResetPlayerHeldKeys(gLinkPartnersHeldKeys); } -static void c1_link_related_func_set(u16 (*func)(u32)) +static void SetKeyInterceptCallback(u16 (*func)(u32)) { - sUnknown_03000E19 = 0; - sUnknown_03000E14 = func; + sRfuKeepAliveTimer = 0; + sPlayerKeyInterceptCallback = func; } -static void sub_8086C64(void) +// Once every ~60 frames, if the link state hasn't changed (timer reset by calls +// to SetKeyInterceptCallback), it does a bunch of sanity checks on the connection. +// I'm not sure if sRfuKeepAliveTimer is reset in the process, though; rfu stuff is +// still undocumented. +static void CheckRfuKeepAliveTimer(void) { - if (gWirelessCommType != 0 && ++sUnknown_03000E19 > 60) + if (gWirelessCommType != 0 && ++sRfuKeepAliveTimer > 60) sub_8010198(); } -static void sub_8086C90(void) +static void ResetAllTradingStates(void) { s32 i; for (i = 0; i < 4; i++) - sUnknown_03000E10[i] = 0x80; + sPlayerTradingStates[i] = PLAYER_TRADING_STATE_IDLE; } -static bool32 sub_8086CA8(u16 a1) +// Returns true if all connected players are in tradingState. +static bool32 AreAllPlayersInTradingState(u16 tradingState) { s32 i; s32 count = gFieldLinkPlayerCount; for (i = 0; i < count; i++) - if (sUnknown_03000E10[i] != a1) + if (sPlayerTradingStates[i] != tradingState) return FALSE; return TRUE; } -static bool32 sub_8086CE0(u16 a1) +static bool32 IsAnyPlayerInTradingState(u16 tradingState) { s32 i; s32 count = gFieldLinkPlayerCount; for (i = 0; i < count; i++) - if (sUnknown_03000E10[i] == a1) + if (sPlayerTradingStates[i] == tradingState) return TRUE; return FALSE; } -static void sub_8086D18(u32 a1, u16 a2, struct UnkStruct_8054FF8 *a3, u16 *a4) +static void HandleLinkPlayerKeyInput(u32 playerId, u16 key, struct TradeRoomPlayer *trainer, u16 *forceFacing) { const u8 *script; - if (sUnknown_03000E10[a1] == 0x80) + if (sPlayerTradingStates[playerId] == PLAYER_TRADING_STATE_IDLE) { - script = sub_8087370(a3); + script = TryGetTileEventScript(trainer); if (script) { - *a4 = sub_8087480(script); - sUnknown_03000E10[a1] = 0x81; - if (a3->b) + *forceFacing = GetDirectionForEventScript(script); + sPlayerTradingStates[playerId] = PLAYER_TRADING_STATE_BUSY; + if (trainer->isLocalPlayer) { - c1_link_related_func_set(sub_80870F8); + SetKeyInterceptCallback(KeyInterCB_DeferToEventScript); sub_8087530(script); } return; } - if (sub_8086CE0(0x83) == 1) + if (IsAnyPlayerInTradingState(PLAYER_TRADING_STATE_EXITING_ROOM) == TRUE) { - sUnknown_03000E10[a1] = 0x81; - if (a3->b) + sPlayerTradingStates[playerId] = PLAYER_TRADING_STATE_BUSY; + if (trainer->isLocalPlayer) { - c1_link_related_func_set(sub_80870F8); + SetKeyInterceptCallback(KeyInterCB_DeferToEventScript); sub_8087584(); } return; } - switch (a2) + + switch (key) { - case 24: - if (sub_8087358(a3)) + case LINK_KEY_CODE_START_BUTTON: + if (sub_8087340_2(trainer)) { - sUnknown_03000E10[a1] = 0x81; - if (a3->b) + sPlayerTradingStates[playerId] = PLAYER_TRADING_STATE_BUSY; + if (trainer->isLocalPlayer) { - c1_link_related_func_set(sub_80870F8); - sub_808751C(); + SetKeyInterceptCallback(KeyInterCB_DeferToEventScript); + InitLinkRoomStartMenuScript(); } } break; - case 18: - if (sub_8087388(a3) == TRUE) + case LINK_KEY_CODE_DPAD_DOWN: + if (PlayerIsAtSouthExit(trainer) == TRUE) { - sUnknown_03000E10[a1] = 0x81; - if (a3->b) + sPlayerTradingStates[playerId] = PLAYER_TRADING_STATE_BUSY; + if (trainer->isLocalPlayer) { - c1_link_related_func_set(sub_80870F8); - sub_808754C(); + SetKeyInterceptCallback(KeyInterCB_DeferToEventScript); + CreateConfirmLeaveTradeRoomPrompt(); } } break; - case 25: - script = sub_80873B4(a3); + case LINK_KEY_CODE_A_BUTTON: + script = TryInteractWithPlayer(trainer); if (script) { - sUnknown_03000E10[a1] = 0x81; - if (a3->b) + sPlayerTradingStates[playerId] = PLAYER_TRADING_STATE_BUSY; + if (trainer->isLocalPlayer) { - c1_link_related_func_set(sub_80870F8); - sub_8087568(script); + SetKeyInterceptCallback(KeyInterCB_DeferToEventScript); + InitMenuBasedScript(script); } } break; - case 27: - if (sub_8087340(a3)) + case LINK_KEY_CODE_HANDLE_RECV_QUEUE: + if (sub_8087340(trainer)) { - sUnknown_03000E10[a1] = 0x81; - if (a3->b) + sPlayerTradingStates[playerId] = PLAYER_TRADING_STATE_BUSY; + if (trainer->isLocalPlayer) { - c1_link_related_func_set(sub_808711C); + SetKeyInterceptCallback(KeyInterCB_DeferToRecvQueue); sub_8087510(); } } break; - case 28: - if (sub_8087340(a3)) + case LINK_KEY_CODE_HANDLE_SEND_QUEUE: + if (sub_8087340(trainer)) { - sUnknown_03000E10[a1] = 0x81; - if (a3->b) + sPlayerTradingStates[playerId] = PLAYER_TRADING_STATE_BUSY; + if (trainer->isLocalPlayer) { - c1_link_related_func_set(sub_8087140); + SetKeyInterceptCallback(KeyInterCB_DeferToSendQueue); sub_8087510(); } } @@ -2362,388 +2408,403 @@ static void sub_8086D18(u32 a1, u16 a2, struct UnkStruct_8054FF8 *a3, u16 *a4) } } - switch (a2) + switch (key) { - case 23: - sUnknown_03000E10[a1] = 0x83; + case LINK_KEY_CODE_EXIT_ROOM: + sPlayerTradingStates[playerId] = PLAYER_TRADING_STATE_EXITING_ROOM; break; - case 22: - sUnknown_03000E10[a1] = 0x82; + case LINK_KEY_CODE_UNK_2: + sPlayerTradingStates[playerId] = PLAYER_TRADING_STATE_UNK_2; break; - case 26: - sUnknown_03000E10[a1] = 0x80; - if (a3->b) - c1_link_related_func_set(sub_80870B0); + case LINK_KEY_CODE_UNK_4: + sPlayerTradingStates[playerId] = PLAYER_TRADING_STATE_IDLE; + if (trainer->isLocalPlayer) + SetKeyInterceptCallback(KeyInterCB_SelfIdle); break; - case 29: - if (sUnknown_03000E10[a1] == 0x82) - sUnknown_03000E10[a1] = 0x81; + case LINK_KEY_CODE_UNK_7: + if (sPlayerTradingStates[playerId] == PLAYER_TRADING_STATE_UNK_2) + sPlayerTradingStates[playerId] = PLAYER_TRADING_STATE_BUSY; break; } } -static void sub_8086F38(u16 *a1, s32 a2) +static void UpdateAllLinkPlayers(u16 *keys, s32 selfId) { - struct UnkStruct_8054FF8 st; + struct TradeRoomPlayer trainer; s32 i; for (i = 0; i < 4; i++) { - u8 v5 = a1[i]; - u16 v8 = 0; - sub_80872D8(i, a2, &st); - sub_8086D18(i, v5, &st, &v8); - if (sUnknown_03000E10[i] == 0x80) - v8 = sub_8087068(v5); - sub_808796C(i, v8); + u8 key = keys[i]; + u16 setFacing = FACING_NONE; + LoadTradeRoomPlayer(i, selfId, &trainer); + HandleLinkPlayerKeyInput(i, key, &trainer, &setFacing); + if (sPlayerTradingStates[i] == PLAYER_TRADING_STATE_IDLE) + setFacing = GetDirectionForDpadKey(key); + SetPlayerFacingDirection(i, setFacing); } } -static void sub_8086FA0(u16 a1) +static void UpdateHeldKeyCode(u16 key) { - if (a1 >= 17 && a1 < 30) - gUnknown_03005DA8 = a1; + if (key >= LINK_KEY_CODE_EMPTY && key < LINK_KEY_CODE_UNK_8) + gHeldKeyCodeToSend = key; else - gUnknown_03005DA8 = 17; + gHeldKeyCodeToSend = LINK_KEY_CODE_EMPTY; if (gWirelessCommType != 0 - && sub_8087690() > 1 - && is_c1_link_related_active() == TRUE - && sub_8009F3C() == TRUE) + && GetLinkSendQueueLength() > 1 + && IsUpdateLinkStateCBActive() == TRUE + && IsSendingKeysToLink() == TRUE) { - switch (a1) + switch (key) { - case 17: - case 18: - case 19: - case 20: - case 21: - case 24: - case 25: - gUnknown_03005DA8 = 0; + case LINK_KEY_CODE_EMPTY: + case LINK_KEY_CODE_DPAD_DOWN: + case LINK_KEY_CODE_DPAD_UP: + case LINK_KEY_CODE_DPAD_LEFT: + case LINK_KEY_CODE_DPAD_RIGHT: + case LINK_KEY_CODE_START_BUTTON: + case LINK_KEY_CODE_A_BUTTON: + gHeldKeyCodeToSend = LINK_KEY_CODE_NULL; break; } } } -static u16 sub_808700C(u32 a1) +static u16 KeyInterCB_ReadButtons(u32 key) { if (gMain.heldKeys & DPAD_UP) - return 19; + return LINK_KEY_CODE_DPAD_UP; else if (gMain.heldKeys & DPAD_DOWN) - return 18; + return LINK_KEY_CODE_DPAD_DOWN; else if (gMain.heldKeys & DPAD_LEFT) - return 20; + return LINK_KEY_CODE_DPAD_LEFT; else if (gMain.heldKeys & DPAD_RIGHT) - return 21; + return LINK_KEY_CODE_DPAD_RIGHT; else if (gMain.newKeys & START_BUTTON) - return 24; + return LINK_KEY_CODE_START_BUTTON; else if (gMain.newKeys & A_BUTTON) - return 25; + return LINK_KEY_CODE_A_BUTTON; else - return 17; + return LINK_KEY_CODE_EMPTY; } -static u16 sub_8087068(u16 a1) +static u16 GetDirectionForDpadKey(u16 a1) { switch (a1) { - case 21: - return 4; - case 20: - return 3; - case 19: - return 1; - case 18: - return 2; + case LINK_KEY_CODE_DPAD_RIGHT: + return FACING_RIGHT; + case LINK_KEY_CODE_DPAD_LEFT: + return FACING_LEFT; + case LINK_KEY_CODE_DPAD_UP: + return FACING_UP; + case LINK_KEY_CODE_DPAD_DOWN: + return FACING_DOWN; default: - return 0; + return FACING_NONE; } } -static void sub_808709C(u16 *a1) +// Overwrites the keys with 0x11 +static void ResetPlayerHeldKeys(u16 *keys) { s32 i; for (i = 0; i < 4; i++) - a1[i] = 17; + keys[i] = LINK_KEY_CODE_EMPTY; } -static u16 sub_80870B0(u32 a1) + +static u16 KeyInterCB_SelfIdle(u32 key) { - if (ScriptContext2_IsEnabled() == 1) - return 17; - if (sub_800B4DC() > 4) - return 27; - if (sub_8087690() <= 4) - return sub_808700C(a1); - return 28; + if (ScriptContext2_IsEnabled() == TRUE) + return LINK_KEY_CODE_EMPTY; + if (GetLinkRecvQueueLength() > 4) + return LINK_KEY_CODE_HANDLE_RECV_QUEUE; + if (GetLinkSendQueueLength() <= 4) + return KeyInterCB_ReadButtons(key); + return LINK_KEY_CODE_HANDLE_SEND_QUEUE; } -static u16 sub_80870EC(u32 a1) +static u16 sub_80870EC(u32 key) { - sub_8086C64(); - return 17; + CheckRfuKeepAliveTimer(); + return LINK_KEY_CODE_EMPTY; } -static u16 sub_80870F8(u32 a1) +// Ignore the player's inputs as long as there is an event script +// in ScriptContext2. +static u16 KeyInterCB_DeferToEventScript(u32 key) { u16 retVal; if (ScriptContext2_IsEnabled() == TRUE) { - retVal = 17; + retVal = LINK_KEY_CODE_EMPTY; } else { - retVal = 26; - c1_link_related_func_set(sub_80870EC); + retVal = LINK_KEY_CODE_UNK_4; + SetKeyInterceptCallback(sub_80870EC); } return retVal; } -static u16 sub_808711C(u32 a1) +// Ignore the player's inputs as long as there are events being recived. +static u16 KeyInterCB_DeferToRecvQueue(u32 key) { u16 retVal; - if (sub_800B4DC() > 2) + if (GetLinkRecvQueueLength() > 2) { - retVal = 17; + retVal = LINK_KEY_CODE_EMPTY; } else { - retVal = 26; + retVal = LINK_KEY_CODE_UNK_4; ScriptContext2_Disable(); - c1_link_related_func_set(sub_80870EC); + SetKeyInterceptCallback(sub_80870EC); } return retVal; } -static u16 sub_8087140(u32 a1) +// Ignore the player's inputs as long as there are events being sent. +static u16 KeyInterCB_DeferToSendQueue(u32 key) { u16 retVal; - if (sub_8087690() > 2) + if (GetLinkSendQueueLength() > 2) { - retVal = 17; + retVal = LINK_KEY_CODE_EMPTY; } else { - retVal = 26; + retVal = LINK_KEY_CODE_UNK_4; ScriptContext2_Disable(); - c1_link_related_func_set(sub_80870EC); + SetKeyInterceptCallback(sub_80870EC); } return retVal; } -static u16 sub_8087164(u32 a1) +static u16 KeyInterCB_DoNothingAndKeepAlive(u32 key) { - sub_8086C64(); - return 17; + CheckRfuKeepAliveTimer(); + return LINK_KEY_CODE_EMPTY; } -static u16 sub_8087170(u32 linkPlayerId) +static u16 sub_8087170(u32 keyOrPlayerId) { - if (sUnknown_03000E10[linkPlayerId] == 0x82) + if (sPlayerTradingStates[keyOrPlayerId] == PLAYER_TRADING_STATE_UNK_2) { if (gMain.newKeys & B_BUTTON) { - c1_link_related_func_set(sub_8087164); - return 29; + SetKeyInterceptCallback(KeyInterCB_DoNothingAndKeepAlive); + return LINK_KEY_CODE_UNK_7; } else { - return 17; + return LINK_KEY_CODE_EMPTY; } } else { - sub_8086C64(); - return 17; + CheckRfuKeepAliveTimer(); + return LINK_KEY_CODE_EMPTY; } } static u16 sub_80871AC(u32 a1) { - c1_link_related_func_set(sub_8087170); - return 22; + SetKeyInterceptCallback(sub_8087170); + return LINK_KEY_CODE_UNK_2; } -static u16 sub_80871C0(u32 a1) +static u16 KeyInterCB_SendNothing(u32 key) { - return 17; + return LINK_KEY_CODE_EMPTY; } -static u16 sub_80871C4(u32 a1) +static u16 KeyInterCB_WaitForPlayersToExit(u32 keyOrPlayerId) { - if (sUnknown_03000E10[a1] != 0x83) - sub_8086C64(); - if (sub_8086CA8(0x83) == TRUE) + // keyOrPlayerId could be any keycode. This callback does no sanity checking + // on the size of the key. It's assuming that it is being called from + // CB1_UpdateLinkState. + if (sPlayerTradingStates[keyOrPlayerId] != PLAYER_TRADING_STATE_EXITING_ROOM) + CheckRfuKeepAliveTimer(); + if (AreAllPlayersInTradingState(PLAYER_TRADING_STATE_EXITING_ROOM) == TRUE) { - ScriptContext1_SetupScript(EventScript_277513); - c1_link_related_func_set(sub_80871C0); + ScriptContext1_SetupScript(EventScript_DoLinkRoomExit); + SetKeyInterceptCallback(KeyInterCB_SendNothing); } - return 17; + return LINK_KEY_CODE_EMPTY; } -static u16 sub_80871FC(u32 a1) +static u16 KeyInterCB_SendExitRoomKey(u32 key) { - c1_link_related_func_set(sub_80871C4); - return 23; + SetKeyInterceptCallback(KeyInterCB_WaitForPlayersToExit); + return LINK_KEY_CODE_EXIT_ROOM; } -static u16 sub_8087210(u32 a1) +// Duplicate function. +static u16 KeyInterCB_SendNothing_2(u32 key) { - return 17; + return LINK_KEY_CODE_EMPTY; } u32 sub_8087214(void) { - if (sub_8086CE0(0x83) == TRUE) + if (IsAnyPlayerInTradingState(PLAYER_TRADING_STATE_EXITING_ROOM) == TRUE) return 2; - if (sUnknown_03000E14 == sub_8087170 && sUnknown_03000E10[gUnknown_03005DB4] != 0x82) + if (sPlayerKeyInterceptCallback == sub_8087170 && sPlayerTradingStates[gLocalLinkPlayerId] != PLAYER_TRADING_STATE_UNK_2) return 0; - if (sUnknown_03000E14 == sub_8087164 && sUnknown_03000E10[gUnknown_03005DB4] == 0x81) + if (sPlayerKeyInterceptCallback == KeyInterCB_DoNothingAndKeepAlive && sPlayerTradingStates[gLocalLinkPlayerId] == PLAYER_TRADING_STATE_BUSY) return 2; - if (sub_8086CA8(0x82) != 0) + if (AreAllPlayersInTradingState(PLAYER_TRADING_STATE_UNK_2) != FALSE) return 1; return 0; } bool32 sub_808727C(void) { - return sub_8086CE0(0x83); + return IsAnyPlayerInTradingState(PLAYER_TRADING_STATE_EXITING_ROOM); } u16 sub_8087288(void) { - c1_link_related_func_set(sub_80871AC); + SetKeyInterceptCallback(sub_80871AC); return 0; } u16 sub_808729C(void) { - c1_link_related_func_set(sub_80870F8); + SetKeyInterceptCallback(KeyInterCB_DeferToEventScript); return 0; } -u16 sub_80872B0(void) +// The exit room key will be sent at the next opportunity. +// The return value is meaningless. +u16 QueueExitLinkRoomKey(void) { - c1_link_related_func_set(sub_80871FC); + SetKeyInterceptCallback(KeyInterCB_SendExitRoomKey); return 0; } u16 sub_80872C4(void) { - c1_link_related_func_set(sub_8087210); + SetKeyInterceptCallback(KeyInterCB_SendNothing_2); return 0; } -static void sub_80872D8(s32 linkPlayerId, s32 a2, struct UnkStruct_8054FF8 *a3) +static void LoadTradeRoomPlayer(s32 linkPlayerId, s32 myPlayerId, struct TradeRoomPlayer *trainer) { s16 x, y; - a3->a = linkPlayerId; - a3->b = (linkPlayerId == a2) ? 1 : 0; - a3->c = gLinkPlayerEventObjects[linkPlayerId].mode; - a3->d = sub_80878A0(linkPlayerId); - sub_8087878(linkPlayerId, &x, &y); - a3->sub.x = x; - a3->sub.y = y; - a3->sub.height = sub_80878C0(linkPlayerId); - a3->field_C = MapGridGetMetatileBehaviorAt(x, y); + trainer->playerId = linkPlayerId; + trainer->isLocalPlayer = (linkPlayerId == myPlayerId) ? 1 : 0; + trainer->c = gLinkPlayerEventObjects[linkPlayerId].movementMode; + trainer->facing = GetLinkPlayerFacingDirection(linkPlayerId); + GetLinkPlayerCoords(linkPlayerId, &x, &y); + trainer->pos.x = x; + trainer->pos.y = y; + trainer->pos.height = GetLinkPlayerElevation(linkPlayerId); + trainer->field_C = MapGridGetMetatileBehaviorAt(x, y); } -static bool32 sub_8087340(struct UnkStruct_8054FF8 *a1) +static bool32 sub_8087340(struct TradeRoomPlayer *player) { - u8 v1 = a1->c; - if (v1 == 2 || v1 == 0) + u8 v1 = player->c; + if (v1 == MOVEMENT_MODE_SCRIPTED || v1 == MOVEMENT_MODE_FREE) return TRUE; else return FALSE; } -static bool32 sub_8087358(struct UnkStruct_8054FF8 *a1) +// Duplicate function. +static bool32 sub_8087340_2(struct TradeRoomPlayer *player) { - u8 v1 = a1->c; - if (v1 == 2 || v1 == 0) + u8 v1 = player->c; + if (v1 == MOVEMENT_MODE_SCRIPTED || v1 == MOVEMENT_MODE_FREE) return TRUE; else return FALSE; } -static u8 *sub_8087370(struct UnkStruct_8054FF8 *a1) +static u8 *TryGetTileEventScript(struct TradeRoomPlayer *player) { - if (a1->c != 2) - return 0; - return GetCoordEventScriptAtMapPosition(&a1->sub); + if (player->c != MOVEMENT_MODE_SCRIPTED) + return FACING_NONE; + return GetCoordEventScriptAtMapPosition(&player->pos); } -static bool32 sub_8087388(struct UnkStruct_8054FF8 *a1) +static bool32 PlayerIsAtSouthExit(struct TradeRoomPlayer *player) { - if (a1->c != 2 && a1->c != 0) + if (player->c != MOVEMENT_MODE_SCRIPTED && player->c != MOVEMENT_MODE_FREE) return FALSE; - else if (!MetatileBehavior_IsSouthArrowWarp(a1->field_C)) + else if (!MetatileBehavior_IsSouthArrowWarp(player->field_C)) return FALSE; - else if (a1->d != 1) + else if (player->facing != 1) return FALSE; else return TRUE; } -static const u8 *sub_80873B4(struct UnkStruct_8054FF8 *a1) +static const u8 *TryInteractWithPlayer(struct TradeRoomPlayer *player) { - struct MapPosition unkStruct; + struct MapPosition otherPlayerPos; u8 linkPlayerId; - if (a1->c && a1->c != 2) - return 0; + if (player->c != MOVEMENT_MODE_FREE && player->c != MOVEMENT_MODE_SCRIPTED) + return FACING_NONE; - unkStruct = a1->sub; - unkStruct.x += gDirectionToVectors[a1->d].x; - unkStruct.y += gDirectionToVectors[a1->d].y; - unkStruct.height = 0; - linkPlayerId = GetLinkPlayerIdAt(unkStruct.x, unkStruct.y); + otherPlayerPos = player->pos; + otherPlayerPos.x += gDirectionToVectors[player->facing].x; + otherPlayerPos.y += gDirectionToVectors[player->facing].y; + otherPlayerPos.height = 0; + linkPlayerId = GetLinkPlayerIdAt(otherPlayerPos.x, otherPlayerPos.y); if (linkPlayerId != 4) { - if (!a1->b) - return EventScript_TradeRoom_TooBusyToNotice; - else if (sUnknown_03000E10[linkPlayerId] != 0x80) - return EventScript_TradeRoom_TooBusyToNotice; - else if (!sub_80B39D4(linkPlayerId)) - return EventScript_TradeRoom_ReadTrainerCard1; + if (!player->isLocalPlayer) + return gEventScript_TradeRoom_TooBusyToNotice; + else if (sPlayerTradingStates[linkPlayerId] != PLAYER_TRADING_STATE_IDLE) + return gEventScript_TradeRoom_TooBusyToNotice; + else if (!GetLinkTrainerCardColor(linkPlayerId)) + return gEventScript_TradeRoom_ReadTrainerCard_NoColor; else - return EventScript_TradeRoom_ReadTrainerCard2; + return gEventScript_TradeRoom_ReadTrainerCard_Normal; } - return GetInteractedLinkPlayerScript(&unkStruct, a1->field_C, a1->d); + return GetInteractedLinkPlayerScript(&otherPlayerPos, player->field_C, player->facing); } -static u16 sub_8087480(const u8 *script) +// This returns which direction to force the player to look when one of +// these event scripts runs. +static u16 GetDirectionForEventScript(const u8 *script) { - if (script == gUnknown_08277388) - return 10; - else if (script == gUnknown_082773A3) - return 9; - else if (script == gUnknown_082773BE) - return 10; - else if (script == gUnknown_082773D9) - return 9; - else if (script == gUnknown_0827741D) - return 10; - else if (script == gUnknown_08277432) - return 9; - else if (script == gUnknown_08277447) - return 10; - else if (script == gUnknown_0827745C) - return 9; - else if (script == gUnknown_08277374) - return 10; - else if (script == gUnknown_0827737E) - return 9; - else if (script == gUnknown_082773F5) - return 10; - else if (script == gUnknown_082773FF) - return 9; + if (script == EventScript_DoubleBattleColosseum_PlayerSpot0) + return FACING_FORCED_RIGHT; + else if (script == EventScript_DoubleBattleColosseum_PlayerSpot1) + return FACING_FORCED_LEFT; + else if (script == EventScript_DoubleBattleColosseum_PlayerSpot2) + return FACING_FORCED_RIGHT; + else if (script == EventScript_DoubleBattleColosseum_PlayerSpot3) + return FACING_FORCED_LEFT; + else if (script == EventScript_RecordCenter_Spot0) + return FACING_FORCED_RIGHT; + else if (script == EventScript_RecordCenter_Spot1) + return FACING_FORCED_LEFT; + else if (script == EventScript_RecordCenter_Spot2) + return FACING_FORCED_RIGHT; + else if (script == EventScript_RecordCenter_Spot3) + return FACING_FORCED_LEFT; + else if (script == EventScript_SingleBattleColosseum_PlayerSpot0) + return FACING_FORCED_RIGHT; + else if (script == EventScript_SingleBattleColosseum_PlayerSpot1) + return FACING_FORCED_LEFT; + else if (script == EventScript_TradeCenter_Chair0) + return FACING_FORCED_RIGHT; + else if (script == EventScript_TradeCenter_Chair1) + return FACING_FORCED_LEFT; else - return 0; + return FACING_NONE; } static void sub_8087510(void) @@ -2751,7 +2812,7 @@ static void sub_8087510(void) ScriptContext2_Enable(); } -static void sub_808751C(void) +static void InitLinkRoomStartMenuScript(void) { PlaySE(SE_WIN_OPEN); ShowStartMenu(); @@ -2765,14 +2826,14 @@ static void sub_8087530(const u8 *script) ScriptContext2_Enable(); } -static void sub_808754C(void) +static void CreateConfirmLeaveTradeRoomPrompt(void) { PlaySE(SE_WIN_OPEN); - ScriptContext1_SetupScript(gUnknown_082774EF); + ScriptContext1_SetupScript(EventScript_ConfirmLeaveTradeRoom); ScriptContext2_Enable(); } -static void sub_8087568(const u8 *script) +static void InitMenuBasedScript(const u8 *script) { PlaySE(SE_SELECT); ScriptContext1_SetupScript(script); @@ -2781,18 +2842,18 @@ static void sub_8087568(const u8 *script) static void sub_8087584(void) { - ScriptContext1_SetupScript(gUnknown_08277509); + ScriptContext1_SetupScript(EventScript_TerminateLink); ScriptContext2_Enable(); } bool32 sub_8087598(void) { - if (!is_c1_link_related_active()) - return 0; - if (sub_800B4DC() >= 3) - sUnknown_03000E18 = 1; + if (!IsUpdateLinkStateCBActive()) + return FALSE; + if (GetLinkRecvQueueLength() >= 3) + sUnknown_03000E18 = TRUE; else - sUnknown_03000E18 = 0; + sUnknown_03000E18 = FALSE; return sUnknown_03000E18; } @@ -2800,19 +2861,19 @@ bool32 sub_80875C8(void) { u8 temp; - if (sub_800B4DC() < 2) + if (GetLinkRecvQueueLength() < 2) return FALSE; - else if (is_c1_link_related_active() != TRUE) + else if (IsUpdateLinkStateCBActive() != TRUE) return FALSE; - else if (sub_8009F3C() != TRUE) + else if (IsSendingKeysToLink() != TRUE) return FALSE; - else if (sUnknown_03000E14 == sub_808711C) + else if (sPlayerKeyInterceptCallback == KeyInterCB_DeferToRecvQueue) return TRUE; - else if (sUnknown_03000E14 != sub_80870F8) + else if (sPlayerKeyInterceptCallback != KeyInterCB_DeferToEventScript) return FALSE; temp = sUnknown_03000E18; - sUnknown_03000E18 = 0; + sUnknown_03000E18 = FALSE; if (temp == TRUE) return TRUE; @@ -2824,13 +2885,13 @@ bool32 sub_80875C8(void) bool32 sub_8087634(void) { - if (sub_8087690() < 2) + if (GetLinkSendQueueLength() < 2) return FALSE; - else if (is_c1_link_related_active() != TRUE) + else if (IsUpdateLinkStateCBActive() != TRUE) return FALSE; - else if (sub_8009F3C() != TRUE) + else if (IsSendingKeysToLink() != TRUE) return FALSE; - else if (sUnknown_03000E14 == sub_8087140) + else if (sPlayerKeyInterceptCallback == KeyInterCB_DeferToSendQueue) return TRUE; else return FALSE; @@ -2840,13 +2901,13 @@ bool32 sub_808766C(void) { if (gWirelessCommType != 0) return FALSE; - else if (!sub_8009F3C()) + else if (!IsSendingKeysToLink()) return FALSE; else return TRUE; } -static u32 sub_8087690(void) +static u32 GetLinkSendQueueLength(void) { if (gWirelessCommType != 0) return gUnknown_03005000.unk_9e8.unk_232; @@ -2881,7 +2942,7 @@ static void SpawnLinkPlayerEventObject(u8 linkPlayerId, s16 x, s16 y, u8 a4) linkPlayerEventObj->active = 1; linkPlayerEventObj->linkPlayerId = linkPlayerId; linkPlayerEventObj->eventObjId = eventObjId; - linkPlayerEventObj->mode = 0; + linkPlayerEventObj->movementMode = MOVEMENT_MODE_FREE; eventObj->active = 1; eventObj->singleMovementActive = a4; @@ -2923,14 +2984,15 @@ static void sub_808780C(u8 linkPlayerId) eventObj->active = 0; } -static u8 sub_8087858(u8 linkPlayerId) +// Returns the spriteId corresponding to this player. +static u8 GetSpriteForLinkedPlayer(u8 linkPlayerId) { u8 eventObjId = gLinkPlayerEventObjects[linkPlayerId].eventObjId; struct EventObject *eventObj = &gEventObjects[eventObjId]; return eventObj->spriteId; } -static void sub_8087878(u8 linkPlayerId, u16 *x, u16 *y) +static void GetLinkPlayerCoords(u8 linkPlayerId, u16 *x, u16 *y) { u8 eventObjId = gLinkPlayerEventObjects[linkPlayerId].eventObjId; struct EventObject *eventObj = &gEventObjects[eventObjId]; @@ -2938,14 +3000,14 @@ static void sub_8087878(u8 linkPlayerId, u16 *x, u16 *y) *y = eventObj->currentCoords.y; } -static u8 sub_80878A0(u8 linkPlayerId) +static u8 GetLinkPlayerFacingDirection(u8 linkPlayerId) { u8 eventObjId = gLinkPlayerEventObjects[linkPlayerId].eventObjId; struct EventObject *eventObj = &gEventObjects[eventObjId]; return eventObj->range.as_byte; } -static u8 sub_80878C0(u8 linkPlayerId) +static u8 GetLinkPlayerElevation(u8 linkPlayerId) { u8 eventObjId = gLinkPlayerEventObjects[linkPlayerId].eventObjId; struct EventObject *eventObj = &gEventObjects[eventObjId]; @@ -2965,7 +3027,7 @@ static u8 GetLinkPlayerIdAt(s16 x, s16 y) for (i = 0; i < 4; i++) { if (gLinkPlayerEventObjects[i].active - && (gLinkPlayerEventObjects[i].mode == 0 || gLinkPlayerEventObjects[i].mode == 2)) + && (gLinkPlayerEventObjects[i].movementMode == 0 || gLinkPlayerEventObjects[i].movementMode == 2)) { struct EventObject *eventObj = &gEventObjects[gLinkPlayerEventObjects[i].eventObjId]; if (eventObj->currentCoords.x == x && eventObj->currentCoords.y == y) @@ -2975,7 +3037,7 @@ static u8 GetLinkPlayerIdAt(s16 x, s16 y) return 4; } -static void sub_808796C(u8 linkPlayerId, u8 a2) +static void SetPlayerFacingDirection(u8 linkPlayerId, u8 facing) { struct LinkPlayerEventObject *linkPlayerEventObj = &gLinkPlayerEventObjects[linkPlayerId]; u8 eventObjId = linkPlayerEventObj->eventObjId; @@ -2983,94 +3045,111 @@ static void sub_808796C(u8 linkPlayerId, u8 a2) if (linkPlayerEventObj->active) { - if (a2 > 10) + if (facing > FACING_FORCED_RIGHT) + { eventObj->triggerGroundEffectsOnMove = 1; + } else - gUnknown_08339E00[gUnknown_08339DC8[linkPlayerEventObj->mode](linkPlayerEventObj, eventObj, a2)](linkPlayerEventObj, eventObj); + { + // This is a hack to split this code onto two separate lines, without declaring a local variable. + // C++ style inline variables would be nice here. + #define TEMP gLinkPlayerMovementModes[linkPlayerEventObj->movementMode](linkPlayerEventObj, eventObj, facing) + + gMovementStatusHandler[TEMP](linkPlayerEventObj, eventObj); + + // Clean up the hack. + #undef TEMP + } } } -static u8 sub_80879D8(struct LinkPlayerEventObject *linkPlayerEventObj, struct EventObject *eventObj, u8 a3) + +static u8 MovementEventModeCB_Normal(struct LinkPlayerEventObject *linkPlayerEventObj, struct EventObject *eventObj, u8 a3) { - return gUnknown_08339DD4[a3](linkPlayerEventObj, eventObj, a3); + return gLinkPlayerFacingHandlers[a3](linkPlayerEventObj, eventObj, a3); } -static u8 sub_80879F8(struct LinkPlayerEventObject *linkPlayerEventObj, struct EventObject *eventObj, u8 a3) +static u8 MovementEventModeCB_Ignored(struct LinkPlayerEventObject *linkPlayerEventObj, struct EventObject *eventObj, u8 a3) { - return 1; + return FACING_UP; } -static u8 sub_80879FC(struct LinkPlayerEventObject *linkPlayerEventObj, struct EventObject *eventObj, u8 a3) +// Duplicate Function +static u8 MovementEventModeCB_Normal_2(struct LinkPlayerEventObject *linkPlayerEventObj, struct EventObject *eventObj, u8 a3) { - return gUnknown_08339DD4[a3](linkPlayerEventObj, eventObj, a3); + return gLinkPlayerFacingHandlers[a3](linkPlayerEventObj, eventObj, a3); } -static u8 sub_8087A1C(struct LinkPlayerEventObject *linkPlayerEventObj, struct EventObject *eventObj, u8 a3) +static bool8 FacingHandler_DoNothing(struct LinkPlayerEventObject *linkPlayerEventObj, struct EventObject *eventObj, u8 a3) { - return 0; + return FALSE; } -static u8 sub_8087A20(struct LinkPlayerEventObject *linkPlayerEventObj, struct EventObject *eventObj, u8 a3) +static bool8 FacingHandler_DpadMovement(struct LinkPlayerEventObject *linkPlayerEventObj, struct EventObject *eventObj, u8 a3) { s16 x, y; - eventObj->range.as_byte = npc_something3(a3, eventObj->range.as_byte); + eventObj->range.as_byte = FlipVerticalAndClearForced(a3, eventObj->range.as_byte); EventObjectMoveDestCoords(eventObj, eventObj->range.as_byte, &x, &y); if (LinkPlayerDetectCollision(linkPlayerEventObj->eventObjId, eventObj->range.as_byte, x, y)) { - return 0; + return FALSE; } else { eventObj->directionSequenceIndex = 16; ShiftEventObjectCoords(eventObj, x, y); EventObjectUpdateZCoord(eventObj); - return 1; + return TRUE; } } -static u8 sub_8087A88(struct LinkPlayerEventObject *linkPlayerEventObj, struct EventObject *eventObj, u8 a3) +static bool8 FacingHandler_ForcedFacingChange(struct LinkPlayerEventObject *linkPlayerEventObj, struct EventObject *eventObj, u8 a3) { - eventObj->range.as_byte = npc_something3(a3, eventObj->range.as_byte); - return 0; + eventObj->range.as_byte = FlipVerticalAndClearForced(a3, eventObj->range.as_byte); + return FALSE; } -static void sub_8087AA0(struct LinkPlayerEventObject *linkPlayerEventObj, struct EventObject *eventObj) +// This is called every time a free movement happens. Most of the time it's a No-Op. +static void MovementStatusHandler_EnterFreeMode(struct LinkPlayerEventObject *linkPlayerEventObj, struct EventObject *eventObj) { - linkPlayerEventObj->mode = 0; + linkPlayerEventObj->movementMode = MOVEMENT_MODE_FREE; } -static void sub_8087AA8(struct LinkPlayerEventObject *linkPlayerEventObj, struct EventObject *eventObj) +static void MovementStatusHandler_TryAdvanceScript(struct LinkPlayerEventObject *linkPlayerEventObj, struct EventObject *eventObj) { eventObj->directionSequenceIndex--; - linkPlayerEventObj->mode = 1; + linkPlayerEventObj->movementMode = MOVEMENT_MODE_FROZEN; MoveCoords(eventObj->range.as_byte, &eventObj->initialCoords.x, &eventObj->initialCoords.y); if (!eventObj->directionSequenceIndex) { ShiftStillEventObjectCoords(eventObj); - linkPlayerEventObj->mode = 2; + linkPlayerEventObj->movementMode = MOVEMENT_MODE_SCRIPTED; } } -static u8 npc_something3(u8 a1, u8 a2) +// Flip Up/Down facing codes. If newFacing doesn't specify a direction, default +// to oldFacing. Note that this clears also the "FORCED" part of the facing code, +// even for Left/Right codes. +static u8 FlipVerticalAndClearForced(u8 newFacing, u8 oldFacing) { - switch (a1 - 1) + switch (newFacing) { - case 0: - case 6: - return 2; - case 1: - case 7: - return 1; - case 2: - case 8: - return 3; - case 3: - case 9: - return 4; + case FACING_UP: + case FACING_FORCED_UP: + return DIR_NORTH; + case FACING_DOWN: + case FACING_FORCED_DOWN: + return DIR_SOUTH; + case FACING_LEFT: + case FACING_FORCED_LEFT: + return DIR_WEST; + case FACING_RIGHT: + case FACING_FORCED_RIGHT: + return DIR_EAST; } - return a2; + return oldFacing; } static u8 LinkPlayerDetectCollision(u8 selfEventObjId, u8 a2, s16 x, s16 y) @@ -3130,7 +3209,7 @@ static void SpriteCB_LinkPlayer(struct Sprite *sprite) SetObjectSubpriorityByZCoord(eventObj->previousElevation, sprite, 1); sprite->oam.priority = ZCoordToPriority(eventObj->previousElevation); - if (!linkPlayerEventObj->mode) + if (!linkPlayerEventObj->movementMode != MOVEMENT_MODE_FREE) StartSpriteAnim(sprite, GetFaceDirectionAnimNum(eventObj->range.as_byte)); else StartSpriteAnimIfDifferent(sprite, GetMoveDirectionAnimNum(eventObj->range.as_byte)); diff --git a/src/party_menu.c b/src/party_menu.c index 4103c212c..10665ad9e 100755 --- a/src/party_menu.c +++ b/src/party_menu.c @@ -6522,7 +6522,7 @@ static void sub_81B8474(u8 taskId) gTasks[taskId].func = sub_81B8104; } -void sub_81B8518(u8 unused) +void InitChooseHalfPartyForBattle(u8 unused) { sub_81B8558(); InitPartyMenu(4, 0, 0, 0, 0, sub_81B1370, gMain.savedCallback); diff --git a/src/pokenav.c b/src/pokenav.c index d09c3da94..41434606c 100644 --- a/src/pokenav.c +++ b/src/pokenav.c @@ -388,7 +388,7 @@ u32 sub_81C7078(u32 (*func)(s32), u32 priority) { u16 taskId; - if (!is_c1_link_related_active()) + if (!IsUpdateLinkStateCBActive()) taskId = CreateTask(sub_81C7170, priority); else taskId = CreateTask(sub_81C71E4, priority); diff --git a/src/record_mixing.c b/src/record_mixing.c index c0ca5f19c..aafd7284b 100644 --- a/src/record_mixing.c +++ b/src/record_mixing.c @@ -106,7 +106,7 @@ static EWRAM_DATA union PlayerRecords *sSentRecord = NULL; // Static ROM declarations static void Task_RecordMixing_Main(u8 taskId); -static void sub_80E7324(u8 taskId); +static void Task_MixingRecordsRecv(u8 taskId); static void Task_SendPacket(u8 taskId); static void Task_CopyReceiveBuffer(u8 taskId); static void Task_SendPacket_SwitchToReceive(u8 taskId); @@ -120,7 +120,7 @@ static void ReceiveLilycoveLadyData(LilycoveLady *, size_t, u8); static void sub_80E7B2C(const u8 *); static void ReceiveDaycareMailData(struct RecordMixingDayCareMail *, size_t, u8, TVShow *); static void ReceiveGiftItem(u16 *item, u8 which); -static void sub_80E7FF8(u8 taskId); +static void Task_DoRecordMixing(u8 taskId); static void sub_80E8110(struct Apprentice *arg0, struct Apprentice *arg1); static void ReceiveApprenticeData(struct Apprentice *arg0, size_t arg1, u32 arg2); static void ReceiveRankingHallRecords(struct PlayerHallRecords *hallRecords, size_t arg1, u32 arg2); @@ -170,7 +170,8 @@ static const u8 gUnknown_0858CFBE[3][4] = #define BUFFER_CHUNK_SIZE 200 -void sub_80E6BE8(void) +// Note: VAR_0x8005 contains the spotId. +void RecordMixingPlayerSpotTriggered(void) { sub_80B37D4(Task_RecordMixing_Main); } @@ -313,6 +314,7 @@ static void Task_RecordMixing_SoundEffect(u8 taskId) #define tState data[0] #define tSndEffTaskId data[15] +// Note: Currently, special var 8005 contains the player's spot id. static void Task_RecordMixing_Main(u8 taskId) { s16 *data = gTasks[taskId].data; @@ -322,16 +324,16 @@ static void Task_RecordMixing_Main(u8 taskId) case 0: // init sSentRecord = malloc(sizeof(union PlayerRecords)); sReceivedRecords = malloc(sizeof(union PlayerRecords) * 4); - sub_8009628(gSpecialVar_0x8005); + SetLocalLinkPlayerId(gSpecialVar_0x8005); VarSet(VAR_TEMP_0, 1); gUnknown_03001130 = FALSE; PrepareExchangePacket(); CreateRecordMixingSprite(); tState = 1; - data[10] = CreateTask(sub_80E7324, 80); + data[10] = CreateTask(Task_MixingRecordsRecv, 80); tSndEffTaskId = CreateTask(Task_RecordMixing_SoundEffect, 81); break; - case 1: // wait for sub_80E7324 + case 1: // wait for Task_MixingRecordsRecv if (!gTasks[data[10]].isActive) { tState = 2; @@ -341,11 +343,11 @@ static void Task_RecordMixing_Main(u8 taskId) } break; case 2: - data[10] = CreateTask(sub_80E7FF8, 10); + data[10] = CreateTask(Task_DoRecordMixing, 10); tState = 3; PlaySE(SE_W226); break; - case 3: // wait for sub_80E7FF8 + case 3: // wait for Task_DoRecordMixing if (!gTasks[data[10]].isActive) { tState = 4; @@ -381,7 +383,7 @@ static void Task_RecordMixing_Main(u8 taskId) #undef tState #undef tSndEffTaskId -static void sub_80E7324(u8 taskId) +static void Task_MixingRecordsRecv(u8 taskId) { struct Task *task = &gTasks[taskId]; @@ -405,7 +407,7 @@ static void sub_80E7324(u8 taskId) u8 players = GetLinkPlayerCount_2(); if (IsLinkMaster() == TRUE) { - if (players == sub_800AA48()) + if (players == GetSavedPlayerCount()) { PlaySE(SE_PIN); task->data[0] = 201; @@ -420,14 +422,15 @@ static void sub_80E7324(u8 taskId) } break; case 201: - if (sub_800AA48() == GetLinkPlayerCount_2() && ++task->data[12] > (GetLinkPlayerCount_2() * 30)) + // We're the link master. Delay for 30 frames per connected player. + if (GetSavedPlayerCount() == GetLinkPlayerCount_2() && ++task->data[12] > (GetLinkPlayerCount_2() * 30)) { - sub_800A620(); + CheckShouldAdvanceLinkState(); task->data[0] = 1; } break; case 301: - if (sub_800AA48() == GetLinkPlayerCount_2()) + if (GetSavedPlayerCount() == GetLinkPlayerCount_2()) task->data[0] = 1; break; case 400: // wait 20 frames @@ -470,6 +473,7 @@ static void sub_80E7324(u8 taskId) StorePtrInTaskData(sReceivedRecords, (u16 *)&gTasks[subTaskId].data[5]); sRecordStructSize = sizeof(struct PlayerRecordsEmerald); } + // Note: This task is destroyed by Task_CopyReceiveBuffer when it's done. } break; case 5: // wait 60 frames @@ -938,7 +942,7 @@ static void ReceiveGiftItem(u16 *item, u8 which) } } -static void sub_80E7FF8(u8 taskId) +static void Task_DoRecordMixing(u8 taskId) { struct Task *task = &gTasks[taskId]; @@ -953,20 +957,22 @@ static void sub_80E7FF8(u8 taskId) else task->data[0] = 6; break; + + // Mixing Ruby/Sapphire records. case 2: SetContinueGameWarpStatusToDynamicWarp(); - sub_8153430(); + FullSaveGame(); task->data[0] ++; break; case 3: - if (sub_8153474()) + if (CheckSaveFile()) { ClearContinueGameWarpStatus2(); task->data[0] = 4; task->data[1] = 0; } break; - case 4: + case 4: // Wait 10 frames if (++task->data[1] > 10) { sub_800AC34(); @@ -974,22 +980,24 @@ static void sub_80E7FF8(u8 taskId) } break; case 5: - if (gReceivedRemoteLinkPlayers == 0) + if (gReceivedRemoteLinkPlayers == FALSE) DestroyTask(taskId); break; + + // Mixing Emerald records. case 6: - if (!sub_801048C(0)) + if (!sub_801048C(FALSE)) { CreateTask(sub_8153688, 5); task->data[0] ++; } break; - case 7: + case 7: // wait for sub_8153688 to finish. if (!FuncIsActiveTask(sub_8153688)) { if (gWirelessCommType) { - sub_801048C(1); + sub_801048C(TRUE); task->data[0] = 8; } else diff --git a/src/rom_8011DC0.c b/src/rom_8011DC0.c index c8adfbe0b..27472b6e3 100644 --- a/src/rom_8011DC0.c +++ b/src/rom_8011DC0.c @@ -188,7 +188,7 @@ extern u8 gUnknown_02022C3E; extern u16 gUnknown_02022C3C; extern u8 gUnknown_02022C20[]; extern u8 gFieldLinkPlayerCount; -extern u8 gUnknown_03005DB4; +extern u8 gLocalLinkPlayerId; // IWRAM vars IWRAM_DATA struct UnkStruct_Leader *gUnknown_03000DA0; @@ -1641,7 +1641,7 @@ void sub_8014304(s8 mapGroup, s8 mapNum, s32 x, s32 y, u16 arg4) gSpecialVar_0x8004 = arg4; VarSet(VAR_CABLE_CLUB_STATE, arg4); gFieldLinkPlayerCount = GetLinkPlayerCount(); - gUnknown_03005DB4 = GetMultiplayerId(); + gLocalLinkPlayerId = GetMultiplayerId(); SetCableClubWarp(); SetWarpDestination(mapGroup, mapNum, -1, x, y); WarpIntoMap(); @@ -1697,7 +1697,7 @@ void sub_801440C(u8 taskId) case 81: CleanupOverworldWindowsAndTilemaps(); gMain.savedCallback = sub_801AC54; - sub_81B8518(3); + InitChooseHalfPartyForBattle(3); break; case 1: CleanupOverworldWindowsAndTilemaps(); diff --git a/src/save.c b/src/save.c index a22e20f0b..d07e59766 100644 --- a/src/save.c +++ b/src/save.c @@ -768,7 +768,7 @@ u8 sub_8153408(void) // trade.s save return 0; } -u8 sub_8153430(void) +u8 FullSaveGame(void) { if (gFlashMemoryPresent != TRUE) return 1; @@ -780,7 +780,7 @@ u8 sub_8153430(void) return 0; } -bool8 sub_8153474(void) +bool8 CheckSaveFile(void) { u8 retVal = FALSE; u16 val = ++gUnknown_03006208; diff --git a/src/scrcmd.c b/src/scrcmd.c index b80b2baed..6df835bad 100644 --- a/src/scrcmd.c +++ b/src/scrcmd.c @@ -1203,7 +1203,7 @@ bool8 ScrCmd_turnvobject(struct ScriptContext *ctx) bool8 ScrCmd_lockall(struct ScriptContext *ctx) { - if (is_c1_link_related_active()) + if (IsUpdateLinkStateCBActive()) { return FALSE; } @@ -1217,7 +1217,7 @@ bool8 ScrCmd_lockall(struct ScriptContext *ctx) bool8 ScrCmd_lock(struct ScriptContext *ctx) { - if (is_c1_link_related_active()) + if (IsUpdateLinkStateCBActive()) { return FALSE; } @@ -2182,7 +2182,7 @@ bool8 ScrCmd_cmdD8(struct ScriptContext *ctx) bool8 ScrCmd_cmdD9(struct ScriptContext *ctx) { - if (is_c1_link_related_active()) + if (IsUpdateLinkStateCBActive()) { return FALSE; } diff --git a/src/script_pokemon_util_80F87D8.c b/src/script_pokemon_util_80F87D8.c index cade00b50..7d6020c7a 100755 --- a/src/script_pokemon_util_80F87D8.c +++ b/src/script_pokemon_util_80F87D8.c @@ -29,6 +29,7 @@ #include "constants/items.h" #include "constants/species.h" #include "constants/vars.h" +#include "constants/battle_frontier.h" extern const u16 gEventObjectPalette8[]; extern const u16 gEventObjectPalette17[]; @@ -40,7 +41,7 @@ static const u8 gUnknown_0858D8EC[] = { 3, 4, 5, 14 }; static void sub_80F8EE8(u8 taskId); static void sub_80F9088(u8 taskId); -static void sub_80F9460(void); +static void CB2_ReturnFromChooseHalfParty(void); static void sub_80F94B8(void); void SetContestTrainerGfxIds(void) @@ -640,22 +641,24 @@ void ScriptSetMonMoveSlot(u8 monIndex, u16 move, u8 slot) SetMonMoveSlot(&gPlayerParty[monIndex], move, slot); } -void sub_80F9438(void) +// Note: When control returns to the event script, gSpecialVar_Result will be +// TRUE if the party selection was successful. +void ChooseHalfPartyForBattle(void) { - gMain.savedCallback = sub_80F9460; - VarSet(VAR_FRONTIER_FACILITY, 9); // this isn't a valid frontier facility id (??) - sub_81B8518(0); + gMain.savedCallback = CB2_ReturnFromChooseHalfParty; + VarSet(VAR_FRONTIER_FACILITY, FRONTIER_FACILITY_DOUBLE_COLOSSEUM); + InitChooseHalfPartyForBattle(0); } -static void sub_80F9460(void) +static void CB2_ReturnFromChooseHalfParty(void) { switch (gSelectedOrderFromParty[0]) { case 0: - gSpecialVar_Result = 0; + gSpecialVar_Result = FALSE; break; default: - gSpecialVar_Result = 1; + gSpecialVar_Result = TRUE; break; } @@ -665,7 +668,7 @@ static void sub_80F9460(void) void sub_80F9490(void) { gMain.savedCallback = sub_80F94B8; - sub_81B8518(gSpecialVar_0x8004 + 1); + InitChooseHalfPartyForBattle(gSpecialVar_0x8004 + 1); } static void sub_80F94B8(void) diff --git a/src/start_menu.c b/src/start_menu.c index 6efd7a04a..4b71f6147 100644 --- a/src/start_menu.c +++ b/src/start_menu.c @@ -84,7 +84,7 @@ EWRAM_DATA static bool8 sSavingComplete = FALSE; EWRAM_DATA static u8 sSaveInfoWindowId = 0; // Extern variables. -extern u8 gUnknown_03005DB4; +extern u8 gLocalLinkPlayerId; // Extern functions in not decompiled files. extern void sub_80AF688(void); @@ -244,7 +244,7 @@ static void BuildStartMenuActions(void) { sNumStartMenuActions = 0; - if (is_c1_link_related_active() == TRUE) + if (IsUpdateLinkStateCBActive() == TRUE) { BuildLinkModeStartMenu(); } @@ -547,7 +547,7 @@ void sub_809FA34(u8 taskId) // Referenced in field_screen.s and rom_8011DC0.s void ShowStartMenu(void) // Called from overworld.c and field_control_avatar.s { - if (!is_c1_link_related_active()) + if (!IsUpdateLinkStateCBActive()) { FreezeEventObjects(); sub_808B864(); @@ -672,7 +672,7 @@ static bool8 StartMenuPlayerNameCallback(void) RemoveExtraStartMenuWindows(); CleanupOverworldWindowsAndTilemaps(); - if (is_c1_link_related_active() || InUnionRoom()) + if (IsUpdateLinkStateCBActive() || InUnionRoom()) ShowPlayerTrainerCard(CB2_ReturnToFieldWithOpenMenu); // Display trainer card else if (FlagGet(FLAG_SYS_FRONTIER_PASS)) ShowFrontierPass(CB2_ReturnToFieldWithOpenMenu); // Display frontier pass @@ -734,7 +734,7 @@ static bool8 StartMenuLinkModePlayerNameCallback(void) { PlayRainStoppingSoundEffect(); CleanupOverworldWindowsAndTilemaps(); - ShowTrainerCardInLink(gUnknown_03005DB4, CB2_ReturnToFieldWithOpenMenu); + ShowTrainerCardInLink(gLocalLinkPlayerId, CB2_ReturnToFieldWithOpenMenu); return TRUE; } @@ -1265,11 +1265,11 @@ static void sub_80A0550(u8 taskId) break; case 1: SetContinueGameWarpStatusToDynamicWarp(); - sub_8153430(); + FullSaveGame(); *step = 2; break; case 2: - if (sub_8153474()) + if (CheckSaveFile()) { ClearContinueGameWarpStatus2(); *step = 3; diff --git a/src/trade.c b/src/trade.c index 6dfb6e2c4..849442ae0 100644 --- a/src/trade.c +++ b/src/trade.c @@ -1507,13 +1507,13 @@ static void sub_80773D0(void) } break; case 3: - if (GetLinkPlayerCount_2() >= sub_800AA48()) + if (GetLinkPlayerCount_2() >= GetSavedPlayerCount()) { if (IsLinkMaster()) { if (++gUnknown_0203229C->unk_A8 > 30) { - sub_800A620(); + CheckShouldAdvanceLinkState(); gMain.state++; } } @@ -2762,7 +2762,7 @@ static void sub_80794CC(void) Free(gUnknown_0203229C); FreeAllWindowBuffers(); sub_800E084(); - SetMainCallback2(c2_8056854); + SetMainCallback2(CB2_ReturnToFieldFromMultiplayer); } } else @@ -2772,7 +2772,7 @@ static void sub_80794CC(void) Free(gUnknown_02032184); Free(gUnknown_0203229C); FreeAllWindowBuffers(); - SetMainCallback2(c2_8056854); + SetMainCallback2(CB2_ReturnToFieldFromMultiplayer); } } } @@ -4099,11 +4099,11 @@ void sub_807AE50(void) case 3: if (IsLinkMaster()) { - if (GetLinkPlayerCount_2() >= sub_800AA48()) + if (GetLinkPlayerCount_2() >= GetSavedPlayerCount()) { if (++gUnknown_020322A0->timer > 30) { - sub_800A620(); + CheckShouldAdvanceLinkState(); gMain.state++; } } diff --git a/src/trainer_card.c b/src/trainer_card.c index 4019ef0bd..4fb30f616 100755 --- a/src/trainer_card.c +++ b/src/trainer_card.c @@ -1536,7 +1536,7 @@ static void sub_80C48C8(void) } } -u8 sub_80C4904(u8 cardId) +u8 GetTrainerCardStars(u8 cardId) { struct TrainerCard* trainerCards = gTrainerCards; return trainerCards[cardId].stars;