diff --git a/src/game/level_update.c b/src/game/level_update.c index 3dbc5568b..66d9b3a1b 100644 --- a/src/game/level_update.c +++ b/src/game/level_update.c @@ -49,7 +49,6 @@ u8 gControlledWarp = 0; u8 gReceiveWarp = 0; struct WarpDest gReceiveWarpDest = { 0 }; -extern s8 sReceivedLoadedActNum; #ifdef VERSION_JP const char *credits01[] = { "1GAME DIRECTOR", "SHIGERU MIYAMOTO" }; @@ -987,7 +986,7 @@ void basic_update(UNUSED s16 *arg) { } } -static void check_received_warp(void) { +static void check_for_received_warp(void) { if (!gReceiveWarp) { return; } gReceiveWarp = FALSE; sWarpDest = gReceiveWarpDest; @@ -996,7 +995,8 @@ static void check_received_warp(void) { // force well behaved state extern s16 gMenuMode; reset_dialog_render_state(); - level_set_transition(1, 0); + level_set_transition(0, 0); + sTransitionUpdate = NULL; gMenuMode = -1; gPauseScreenMode = 1; gSaveOptSelectIndex = 0; @@ -1007,15 +1007,6 @@ static void check_received_warp(void) { set_play_mode((sWarpDest.type == WARP_TYPE_CHANGE_LEVEL) ? PLAY_MODE_CHANGE_LEVEL : PLAY_MODE_CHANGE_AREA); - - s8 warpCourse = gLevelToCourseNumTable[sWarpDest.levelNum - 1]; - if (sWarpDest.type == WARP_TYPE_CHANGE_LEVEL && warpCourse == COURSE_NONE) { - sReceivedLoadedActNum = 0; - } - - /*return (sWarpDest.type == WARP_TYPE_CHANGE_LEVEL) - ? sWarpDest.levelNum - : 0;*/ } int gPressedStart = 0; @@ -1053,27 +1044,29 @@ s32 play_mode_normal(void) { // If either initiate_painting_warp or initiate_delayed_warp initiated a // warp, change play mode accordingly. if (sCurrPlayMode == PLAY_MODE_NORMAL) { - if (!gReceiveWarp) { - if (sWarpDest.type == WARP_TYPE_CHANGE_LEVEL) { + if (sWarpDest.type == WARP_TYPE_CHANGE_LEVEL) { + if (sWarpDest.type == WARP_TYPE_NOT_WARPING) { + set_play_mode(PLAY_MODE_CHANGE_LEVEL); + } else { set_play_mode((gNetworkType != NT_NONE) ? PLAY_MODE_SYNC_LEVEL : PLAY_MODE_CHANGE_LEVEL); - network_send_level_warp_begin(); - } else if (sTransitionTimer != 0) { - if (sWarpDest.type == WARP_TYPE_CHANGE_AREA) { - set_play_mode((gNetworkType != NT_NONE) ? PLAY_MODE_SYNC_LEVEL : PLAY_MODE_CHANGE_AREA); - network_send_level_warp_begin(); - } else { - set_play_mode(PLAY_MODE_CHANGE_AREA); - } - } else if (pressed_pause()) { - lower_background_noise(1); - cancel_rumble(); - gCameraMovementFlags |= CAM_MOVE_PAUSE_SCREEN; - set_play_mode(PLAY_MODE_PAUSED); + network_send_level_warp(FALSE); } + } else if (sTransitionTimer != 0) { + if (sWarpDest.type == WARP_TYPE_NOT_WARPING || gCurrentArea->index == sWarpDest.areaIdx) { + set_play_mode(PLAY_MODE_CHANGE_AREA); + } else { + set_play_mode((gNetworkType != NT_NONE) ? PLAY_MODE_SYNC_LEVEL : PLAY_MODE_CHANGE_AREA); + network_send_level_warp(FALSE); + } + } else if (pressed_pause()) { + lower_background_noise(1); + cancel_rumble(); + gCameraMovementFlags |= CAM_MOVE_PAUSE_SCREEN; + set_play_mode(PLAY_MODE_PAUSED); } - check_received_warp(); } + check_for_received_warp(); return 0; } @@ -1095,7 +1088,7 @@ s32 play_mode_paused(void) { gSavedCourseNum = COURSE_NONE; } set_play_mode((gNetworkType != NT_NONE) ? PLAY_MODE_SYNC_LEVEL : PLAY_MODE_CHANGE_LEVEL); - network_send_level_warp_begin(); + network_send_level_warp(FALSE); } else if (gPauseScreenMode == 3) { // We should only be getting "int 3" to here initiate_warp(LEVEL_CASTLE, 1, 0x1F, 0); @@ -1105,12 +1098,11 @@ s32 play_mode_paused(void) { gCameraMovementFlags &= ~CAM_MOVE_PAUSE_SCREEN; - check_received_warp(); return 0; } s32 play_mode_sync_level(void) { - check_received_warp(); + check_for_received_warp(); return 0; } @@ -1159,7 +1151,8 @@ s32 play_mode_change_area(void) { sTransitionTimer -= 1; } - //! If sTransitionTimer is -1, this will miss. + if (sTransitionTimer < 0) { sTransitionTimer = 0; } + if (sTransitionTimer == 0) { sTransitionUpdate = NULL; set_play_mode(PLAY_MODE_NORMAL); @@ -1217,8 +1210,7 @@ s32 update_level(void) { changeLevel = play_mode_normal(); break; case PLAY_MODE_PAUSED: - play_mode_normal(); - changeLevel = play_mode_paused(); + changeLevel = play_mode_normal() | play_mode_paused(); break; case PLAY_MODE_CHANGE_AREA: changeLevel = play_mode_change_area(); diff --git a/src/menu/star_select.c b/src/menu/star_select.c index 0774f36e7..6aa8ae62c 100644 --- a/src/menu/star_select.c +++ b/src/menu/star_select.c @@ -34,7 +34,6 @@ static struct Object *sStarSelectorModels[8]; // The act the course is loaded as, affects whether some objects spawn. s8 sLoadedActNum; -s8 sReceivedLoadedActNum = 0; // Number of obtained stars, excluding the coin star. static u8 sObtainedStars; @@ -159,6 +158,10 @@ void bhv_act_selector_init(void) { } render_100_coin_star(stars); + + if (gControlledWarp) { + network_send_inside_painting(TRUE, FALSE); + } } /** @@ -180,7 +183,7 @@ void bhv_act_selector_loop(void) { if (gControlledWarp) { s8 oldIndex = sSelectableStarIndex; handle_menu_scrolling(MENU_SCROLL_HORIZONTAL, &sSelectableStarIndex, 0, sObtainedStars); - if (oldIndex != sSelectableStarIndex) { network_send_inside_painting(); } + if (oldIndex != sSelectableStarIndex) { network_send_inside_painting(FALSE, FALSE); } } starIndexCounter = sSelectableStarIndex; for (i = 0; i < sVisibleStars; i++) { @@ -198,7 +201,7 @@ void bhv_act_selector_loop(void) { if (gControlledWarp) { s8 oldIndex = sSelectableStarIndex; handle_menu_scrolling(MENU_SCROLL_HORIZONTAL, &sSelectableStarIndex, 0, sVisibleStars - 1); - if (oldIndex != sSelectableStarIndex) { network_send_inside_painting(); } + if (oldIndex != sSelectableStarIndex) { network_send_inside_painting(FALSE, FALSE); } } sSelectedActIndex = sSelectableStarIndex; } @@ -449,12 +452,6 @@ s32 lvl_update_obj_and_load_act_button_actions(UNUSED s32 arg, UNUSED s32 unused } } - // apply the received act num - if (sReceivedLoadedActNum != 0) { - sLoadedActNum = sReceivedLoadedActNum; - sReceivedLoadedActNum = 0; - } - area_update_objects(); sActSelectorMenuTimer++; return sLoadedActNum; @@ -473,5 +470,5 @@ void star_select_finish_selection(void) { } gDialogCourseActNum = sSelectedActIndex + 1; - if (gControlledWarp) { network_send_inside_painting(); } + if (gControlledWarp) { network_send_inside_painting(FALSE, TRUE); } } diff --git a/src/pc/network/network.h b/src/pc/network/network.h index 634c4dc29..3e32e3866 100644 --- a/src/pc/network/network.h +++ b/src/pc/network/network.h @@ -131,11 +131,11 @@ void network_send_spawn_star(struct Object* o, u8 starType, f32 x, f32 y, f32 z, void network_receive_spawn_star(struct Packet* p); // packet_level_warp.c -void network_send_level_warp_begin(void); +void network_send_level_warp(u8 done); void network_receive_level_warp(struct Packet* p); // packet_inside_painting.c -void network_send_inside_painting(void); +void network_send_inside_painting(u8 startOfEvent, u8 endOfEvent); void network_receive_inside_painting(struct Packet* p); // packet_collect_star.c diff --git a/src/pc/network/packets/packet_inside_painting.c b/src/pc/network/packets/packet_inside_painting.c index 2e44b3e6e..2862873f9 100644 --- a/src/pc/network/packets/packet_inside_painting.c +++ b/src/pc/network/packets/packet_inside_painting.c @@ -10,27 +10,32 @@ extern u8 gControlledWarp; extern u8 sSelectableStarIndex; extern u8 sSelectedActIndex; extern s8 sLoadedActNum; -extern s8 sReceivedLoadedActNum; #pragma pack(1) struct PacketInsidePaintingData { u8 seqId; + u8 eventId; u8 starIndex; u8 actIndex; u8 loadedActNum; }; +static u8 eventId = 0; +static u8 remoteFinishedEventId = (u8)-1; + static u8 seqId = 0; static u8 remoteLastSeqId = (u8)-1; static void populate_packet_data(struct PacketInsidePaintingData* data) { data->seqId = seqId; + data->eventId = eventId; data->starIndex = sSelectableStarIndex; data->actIndex = sSelectedActIndex; data->loadedActNum = sLoadedActNum; } -void network_send_inside_painting(void) { +void network_send_inside_painting(u8 startOfEvent, u8 endOfEvent) { + if (startOfEvent) { eventId++; } struct PacketInsidePaintingData data = { 0 }; populate_packet_data(&data); @@ -54,6 +59,10 @@ void network_receive_inside_painting(struct Packet* p) { return; } remoteLastSeqId = remote.seqId; + if (remote.eventId == remoteFinishedEventId || (remote.eventId == remoteFinishedEventId - 1)) { + LOG_INFO("we've finished this event, escape!"); + return; + } // two-player hack: gControlledWarp is a bool instead of an index if (gControlledWarp) { @@ -62,15 +71,14 @@ void network_receive_inside_painting(struct Packet* p) { } LOG_INFO("received update"); - + eventId = remote.eventId; sSelectableStarIndex = remote.starIndex; sSelectedActIndex = remote.actIndex; - if (sReceivedLoadedActNum == 0) { - sReceivedLoadedActNum = remote.loadedActNum; - } + sLoadedActNum = remote.loadedActNum; - if (sReceivedLoadedActNum != 0) { + if (sLoadedActNum != 0) { LOG_INFO("finished with painting"); + remoteFinishedEventId = remote.eventId; } } diff --git a/src/pc/network/packets/packet_level_warp.c b/src/pc/network/packets/packet_level_warp.c index 45d7df58b..0560cabe2 100644 --- a/src/pc/network/packets/packet_level_warp.c +++ b/src/pc/network/packets/packet_level_warp.c @@ -8,22 +8,17 @@ #include "pc/debuglog.h" static u8 eventId = 0; -static u8 remoteFinishedEventId[2] = { (u8)-1, (u8)-1 }; +static u8 remoteFinishedEventId = (u8)-1; static u8 seqId = 0; static u8 remoteLastSeqId = (u8)-1; -extern s16 D_80339EE0; extern u8 gControlledWarp; // two-player hack extern u8 gReceiveWarp; extern struct WarpDest gReceiveWarpDest; -s16 saved_D_80339EE0 = 0; struct WarpDest savedWarpNode = { 0 }; -static clock_t lastDoneEvent = 0; -static bool isInWarp = FALSE; - #pragma pack(1) struct PacketLevelWarpData { u8 seqId; @@ -31,64 +26,26 @@ struct PacketLevelWarpData { u8 done; u8 controlledWarp; struct WarpDest warpDest; - s16 D_80339EE0; }; -static void populate_packet_data(struct PacketLevelWarpData* data, bool done, u8 packetEventId) { +static void populate_packet_data(struct PacketLevelWarpData* data, bool done) { data->seqId = seqId; - data->eventId = packetEventId; + data->eventId = eventId; data->done = done; data->controlledWarp = gControlledWarp; data->warpDest = savedWarpNode; - data->D_80339EE0 = saved_D_80339EE0; } -void network_send_level_warp_begin(void) { - assert(!isInWarp); - isInWarp = TRUE; - savedWarpNode = sWarpDest; - saved_D_80339EE0 = D_80339EE0; - - float elapsedSinceDone = (clock() - lastDoneEvent) / CLOCKS_PER_SEC; - gControlledWarp = (elapsedSinceDone < 1.0f) - ? (gNetworkType == NT_SERVER) // two-player hack - : true; - - eventId++; - if (eventId == (u8)-1) { eventId++; } - LOG_INFO("new event [%d]!", eventId); +void network_send_level_warp(u8 done) { + if (!done) { + savedWarpNode = sWarpDest; + gControlledWarp = true; + eventId++; + LOG_INFO("new event [%d]!", eventId); + } struct PacketLevelWarpData data = { 0 }; - populate_packet_data(&data, false, eventId); - - struct Packet p; - packet_init(&p, PACKET_LEVEL_WARP, true); - packet_write(&p, &data, sizeof(struct PacketLevelWarpData)); - network_send(&p); - - seqId++; -} - -static void network_send_level_warp_repeat(void) { - assert(isInWarp); - - struct PacketLevelWarpData data = { 0 }; - populate_packet_data(&data, false, eventId); - - struct Packet p; - packet_init(&p, PACKET_LEVEL_WARP, false); - packet_write(&p, &data, sizeof(struct PacketLevelWarpData)); - network_send(&p); - - seqId++; -} - -static void network_send_level_warp_done(u8 remoteEventId) { - lastDoneEvent = clock(); - isInWarp = FALSE; - - struct PacketLevelWarpData data = { 0 }; - populate_packet_data(&data, true, remoteEventId); + populate_packet_data(&data, done); struct Packet p; packet_init(&p, PACKET_LEVEL_WARP, true); @@ -100,7 +57,6 @@ static void network_send_level_warp_done(u8 remoteEventId) { static void do_warp(void) { gReceiveWarpDest = savedWarpNode; - D_80339EE0 = saved_D_80339EE0; gReceiveWarp = TRUE; } @@ -114,46 +70,32 @@ void network_receive_level_warp(struct Packet* p) { return; } remoteLastSeqId = remote.seqId; - - LOG_INFO("rx event [%d] last [%d, %d]", remote.eventId, remoteFinishedEventId[0], remoteFinishedEventId[1]); - - if (remote.done && remote.eventId != eventId) { - LOG_INFO("remote has finished the wrong id!"); + LOG_INFO("rx event [%d] last [%d]!", remote.eventId, remoteFinishedEventId); + if (remote.eventId == remoteFinishedEventId || (remote.eventId == remoteFinishedEventId - 1)) { + LOG_INFO("we've finished this event, escape!"); return; } - if (!remote.done) { - if (remote.eventId == remoteFinishedEventId[0] || remote.eventId == remoteFinishedEventId[1]) { - LOG_INFO("we've finished this event, escape!"); - return; - } - remoteFinishedEventId[1] = remoteFinishedEventId[0]; - remoteFinishedEventId[0] = remote.eventId; - } - if (gNetworkType == NT_SERVER) { - if (!isInWarp && remote.done) { - LOG_INFO("client is done with warp, but so are we!"); - return; - } else if (!isInWarp) { + if (sCurrPlayMode != PLAY_MODE_SYNC_LEVEL) { // client initiated warp LOG_INFO("client initiated warp!"); - gControlledWarp = !remote.controlledWarp; // two-player hack + gControlledWarp = FALSE; savedWarpNode = remote.warpDest; - saved_D_80339EE0 = remote.D_80339EE0; + eventId = remote.eventId; + remoteFinishedEventId = remote.eventId; + LOG_INFO("finished event [%d]!", remote.eventId); do_warp(); - network_send_level_warp_done(remote.eventId); + network_send_level_warp(TRUE); return; - } else if (remote.done && remote.eventId == eventId) { + } else if (remote.done) { // client done with warp LOG_INFO("client is done with warp, lets-a-go!"); + remoteFinishedEventId = remote.eventId; do_warp(); - isInWarp = FALSE; return; } else { LOG_INFO("client initiated warp, but server is already warping!"); - LOG_INFO("remote.done: %d, remote.eventId: %d!", remote.done, remote.eventId); - network_send_level_warp_repeat(); return; } } @@ -164,8 +106,9 @@ void network_receive_level_warp(struct Packet* p) { LOG_INFO("server initiated warp!"); gControlledWarp = !remote.controlledWarp; // two-player hack savedWarpNode = remote.warpDest; - saved_D_80339EE0 = remote.D_80339EE0; + eventId = remote.eventId; + remoteFinishedEventId = remote.eventId; LOG_INFO("finished event [%d]!", remote.eventId); do_warp(); - network_send_level_warp_done(remote.eventId); + network_send_level_warp(TRUE); }