Revert "Revert "More level transition synchronization rewrites""

This reverts commit 0667908b86.
This commit is contained in:
MysterD 2020-09-11 18:08:24 -07:00
parent 0667908b86
commit a6b3ddcc69
5 changed files with 135 additions and 75 deletions

View file

@ -49,6 +49,7 @@
u8 gControlledWarp = 0; u8 gControlledWarp = 0;
u8 gReceiveWarp = 0; u8 gReceiveWarp = 0;
struct WarpDest gReceiveWarpDest = { 0 }; struct WarpDest gReceiveWarpDest = { 0 };
extern s8 sReceivedLoadedActNum;
#ifdef VERSION_JP #ifdef VERSION_JP
const char *credits01[] = { "1GAME DIRECTOR", "SHIGERU MIYAMOTO" }; const char *credits01[] = { "1GAME DIRECTOR", "SHIGERU MIYAMOTO" };
@ -986,7 +987,7 @@ void basic_update(UNUSED s16 *arg) {
} }
} }
static void check_for_received_warp(void) { static void check_received_warp(void) {
if (!gReceiveWarp) { return; } if (!gReceiveWarp) { return; }
gReceiveWarp = FALSE; gReceiveWarp = FALSE;
sWarpDest = gReceiveWarpDest; sWarpDest = gReceiveWarpDest;
@ -995,8 +996,7 @@ static void check_for_received_warp(void) {
// force well behaved state // force well behaved state
extern s16 gMenuMode; extern s16 gMenuMode;
reset_dialog_render_state(); reset_dialog_render_state();
level_set_transition(0, 0); level_set_transition(1, 0);
sTransitionUpdate = NULL;
gMenuMode = -1; gMenuMode = -1;
gPauseScreenMode = 1; gPauseScreenMode = 1;
gSaveOptSelectIndex = 0; gSaveOptSelectIndex = 0;
@ -1007,6 +1007,15 @@ static void check_for_received_warp(void) {
set_play_mode((sWarpDest.type == WARP_TYPE_CHANGE_LEVEL) set_play_mode((sWarpDest.type == WARP_TYPE_CHANGE_LEVEL)
? PLAY_MODE_CHANGE_LEVEL ? PLAY_MODE_CHANGE_LEVEL
: PLAY_MODE_CHANGE_AREA); : 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; int gPressedStart = 0;
@ -1044,29 +1053,27 @@ s32 play_mode_normal(void) {
// If either initiate_painting_warp or initiate_delayed_warp initiated a // If either initiate_painting_warp or initiate_delayed_warp initiated a
// warp, change play mode accordingly. // warp, change play mode accordingly.
if (sCurrPlayMode == PLAY_MODE_NORMAL) { if (sCurrPlayMode == PLAY_MODE_NORMAL) {
if (sWarpDest.type == WARP_TYPE_CHANGE_LEVEL) { if (!gReceiveWarp) {
if (sWarpDest.type == WARP_TYPE_NOT_WARPING) { if (sWarpDest.type == WARP_TYPE_CHANGE_LEVEL) {
set_play_mode(PLAY_MODE_CHANGE_LEVEL);
} else {
set_play_mode((gNetworkType != NT_NONE) ? PLAY_MODE_SYNC_LEVEL : PLAY_MODE_CHANGE_LEVEL); set_play_mode((gNetworkType != NT_NONE) ? PLAY_MODE_SYNC_LEVEL : PLAY_MODE_CHANGE_LEVEL);
network_send_level_warp(FALSE); 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);
} }
} 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; return 0;
} }
@ -1088,7 +1095,7 @@ s32 play_mode_paused(void) {
gSavedCourseNum = COURSE_NONE; gSavedCourseNum = COURSE_NONE;
} }
set_play_mode((gNetworkType != NT_NONE) ? PLAY_MODE_SYNC_LEVEL : PLAY_MODE_CHANGE_LEVEL); set_play_mode((gNetworkType != NT_NONE) ? PLAY_MODE_SYNC_LEVEL : PLAY_MODE_CHANGE_LEVEL);
network_send_level_warp(FALSE); network_send_level_warp_begin();
} else if (gPauseScreenMode == 3) { } else if (gPauseScreenMode == 3) {
// We should only be getting "int 3" to here // We should only be getting "int 3" to here
initiate_warp(LEVEL_CASTLE, 1, 0x1F, 0); initiate_warp(LEVEL_CASTLE, 1, 0x1F, 0);
@ -1098,11 +1105,12 @@ s32 play_mode_paused(void) {
gCameraMovementFlags &= ~CAM_MOVE_PAUSE_SCREEN; gCameraMovementFlags &= ~CAM_MOVE_PAUSE_SCREEN;
check_received_warp();
return 0; return 0;
} }
s32 play_mode_sync_level(void) { s32 play_mode_sync_level(void) {
check_for_received_warp(); check_received_warp();
return 0; return 0;
} }
@ -1151,8 +1159,7 @@ s32 play_mode_change_area(void) {
sTransitionTimer -= 1; sTransitionTimer -= 1;
} }
if (sTransitionTimer < 0) { sTransitionTimer = 0; } //! If sTransitionTimer is -1, this will miss.
if (sTransitionTimer == 0) { if (sTransitionTimer == 0) {
sTransitionUpdate = NULL; sTransitionUpdate = NULL;
set_play_mode(PLAY_MODE_NORMAL); set_play_mode(PLAY_MODE_NORMAL);
@ -1210,7 +1217,8 @@ s32 update_level(void) {
changeLevel = play_mode_normal(); changeLevel = play_mode_normal();
break; break;
case PLAY_MODE_PAUSED: case PLAY_MODE_PAUSED:
changeLevel = play_mode_normal() | play_mode_paused(); play_mode_normal();
changeLevel = play_mode_paused();
break; break;
case PLAY_MODE_CHANGE_AREA: case PLAY_MODE_CHANGE_AREA:
changeLevel = play_mode_change_area(); changeLevel = play_mode_change_area();

View file

@ -34,6 +34,7 @@ static struct Object *sStarSelectorModels[8];
// The act the course is loaded as, affects whether some objects spawn. // The act the course is loaded as, affects whether some objects spawn.
s8 sLoadedActNum; s8 sLoadedActNum;
s8 sReceivedLoadedActNum = 0;
// Number of obtained stars, excluding the coin star. // Number of obtained stars, excluding the coin star.
static u8 sObtainedStars; static u8 sObtainedStars;
@ -158,10 +159,6 @@ void bhv_act_selector_init(void) {
} }
render_100_coin_star(stars); render_100_coin_star(stars);
if (gControlledWarp) {
network_send_inside_painting(TRUE, FALSE);
}
} }
/** /**
@ -183,7 +180,7 @@ void bhv_act_selector_loop(void) {
if (gControlledWarp) { if (gControlledWarp) {
s8 oldIndex = sSelectableStarIndex; s8 oldIndex = sSelectableStarIndex;
handle_menu_scrolling(MENU_SCROLL_HORIZONTAL, &sSelectableStarIndex, 0, sObtainedStars); handle_menu_scrolling(MENU_SCROLL_HORIZONTAL, &sSelectableStarIndex, 0, sObtainedStars);
if (oldIndex != sSelectableStarIndex) { network_send_inside_painting(FALSE, FALSE); } if (oldIndex != sSelectableStarIndex) { network_send_inside_painting(); }
} }
starIndexCounter = sSelectableStarIndex; starIndexCounter = sSelectableStarIndex;
for (i = 0; i < sVisibleStars; i++) { for (i = 0; i < sVisibleStars; i++) {
@ -201,7 +198,7 @@ void bhv_act_selector_loop(void) {
if (gControlledWarp) { if (gControlledWarp) {
s8 oldIndex = sSelectableStarIndex; s8 oldIndex = sSelectableStarIndex;
handle_menu_scrolling(MENU_SCROLL_HORIZONTAL, &sSelectableStarIndex, 0, sVisibleStars - 1); handle_menu_scrolling(MENU_SCROLL_HORIZONTAL, &sSelectableStarIndex, 0, sVisibleStars - 1);
if (oldIndex != sSelectableStarIndex) { network_send_inside_painting(FALSE, FALSE); } if (oldIndex != sSelectableStarIndex) { network_send_inside_painting(); }
} }
sSelectedActIndex = sSelectableStarIndex; sSelectedActIndex = sSelectableStarIndex;
} }
@ -452,6 +449,12 @@ 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(); area_update_objects();
sActSelectorMenuTimer++; sActSelectorMenuTimer++;
return sLoadedActNum; return sLoadedActNum;
@ -470,5 +473,5 @@ void star_select_finish_selection(void) {
} }
gDialogCourseActNum = sSelectedActIndex + 1; gDialogCourseActNum = sSelectedActIndex + 1;
if (gControlledWarp) { network_send_inside_painting(FALSE, TRUE); } if (gControlledWarp) { network_send_inside_painting(); }
} }

View file

@ -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); void network_receive_spawn_star(struct Packet* p);
// packet_level_warp.c // packet_level_warp.c
void network_send_level_warp(u8 done); void network_send_level_warp_begin(void);
void network_receive_level_warp(struct Packet* p); void network_receive_level_warp(struct Packet* p);
// packet_inside_painting.c // packet_inside_painting.c
void network_send_inside_painting(u8 startOfEvent, u8 endOfEvent); void network_send_inside_painting(void);
void network_receive_inside_painting(struct Packet* p); void network_receive_inside_painting(struct Packet* p);
// packet_collect_star.c // packet_collect_star.c

View file

@ -10,32 +10,27 @@ extern u8 gControlledWarp;
extern u8 sSelectableStarIndex; extern u8 sSelectableStarIndex;
extern u8 sSelectedActIndex; extern u8 sSelectedActIndex;
extern s8 sLoadedActNum; extern s8 sLoadedActNum;
extern s8 sReceivedLoadedActNum;
#pragma pack(1) #pragma pack(1)
struct PacketInsidePaintingData { struct PacketInsidePaintingData {
u8 seqId; u8 seqId;
u8 eventId;
u8 starIndex; u8 starIndex;
u8 actIndex; u8 actIndex;
u8 loadedActNum; u8 loadedActNum;
}; };
static u8 eventId = 0;
static u8 remoteFinishedEventId = (u8)-1;
static u8 seqId = 0; static u8 seqId = 0;
static u8 remoteLastSeqId = (u8)-1; static u8 remoteLastSeqId = (u8)-1;
static void populate_packet_data(struct PacketInsidePaintingData* data) { static void populate_packet_data(struct PacketInsidePaintingData* data) {
data->seqId = seqId; data->seqId = seqId;
data->eventId = eventId;
data->starIndex = sSelectableStarIndex; data->starIndex = sSelectableStarIndex;
data->actIndex = sSelectedActIndex; data->actIndex = sSelectedActIndex;
data->loadedActNum = sLoadedActNum; data->loadedActNum = sLoadedActNum;
} }
void network_send_inside_painting(u8 startOfEvent, u8 endOfEvent) { void network_send_inside_painting(void) {
if (startOfEvent) { eventId++; }
struct PacketInsidePaintingData data = { 0 }; struct PacketInsidePaintingData data = { 0 };
populate_packet_data(&data); populate_packet_data(&data);
@ -59,10 +54,6 @@ void network_receive_inside_painting(struct Packet* p) {
return; return;
} }
remoteLastSeqId = remote.seqId; 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 // two-player hack: gControlledWarp is a bool instead of an index
if (gControlledWarp) { if (gControlledWarp) {
@ -71,14 +62,15 @@ void network_receive_inside_painting(struct Packet* p) {
} }
LOG_INFO("received update"); LOG_INFO("received update");
eventId = remote.eventId;
sSelectableStarIndex = remote.starIndex; sSelectableStarIndex = remote.starIndex;
sSelectedActIndex = remote.actIndex; sSelectedActIndex = remote.actIndex;
sLoadedActNum = remote.loadedActNum; if (sReceivedLoadedActNum == 0) {
sReceivedLoadedActNum = remote.loadedActNum;
}
if (sLoadedActNum != 0) { if (sReceivedLoadedActNum != 0) {
LOG_INFO("finished with painting"); LOG_INFO("finished with painting");
remoteFinishedEventId = remote.eventId;
} }
} }

View file

@ -8,17 +8,22 @@
#include "pc/debuglog.h" #include "pc/debuglog.h"
static u8 eventId = 0; static u8 eventId = 0;
static u8 remoteFinishedEventId = (u8)-1; static u8 remoteFinishedEventId[2] = { (u8)-1, (u8)-1 };
static u8 seqId = 0; static u8 seqId = 0;
static u8 remoteLastSeqId = (u8)-1; static u8 remoteLastSeqId = (u8)-1;
extern s16 D_80339EE0;
extern u8 gControlledWarp; // two-player hack extern u8 gControlledWarp; // two-player hack
extern u8 gReceiveWarp; extern u8 gReceiveWarp;
extern struct WarpDest gReceiveWarpDest; extern struct WarpDest gReceiveWarpDest;
s16 saved_D_80339EE0 = 0;
struct WarpDest savedWarpNode = { 0 }; struct WarpDest savedWarpNode = { 0 };
static clock_t lastDoneEvent = 0;
static bool isInWarp = FALSE;
#pragma pack(1) #pragma pack(1)
struct PacketLevelWarpData { struct PacketLevelWarpData {
u8 seqId; u8 seqId;
@ -26,26 +31,64 @@ struct PacketLevelWarpData {
u8 done; u8 done;
u8 controlledWarp; u8 controlledWarp;
struct WarpDest warpDest; struct WarpDest warpDest;
s16 D_80339EE0;
}; };
static void populate_packet_data(struct PacketLevelWarpData* data, bool done) { static void populate_packet_data(struct PacketLevelWarpData* data, bool done, u8 packetEventId) {
data->seqId = seqId; data->seqId = seqId;
data->eventId = eventId; data->eventId = packetEventId;
data->done = done; data->done = done;
data->controlledWarp = gControlledWarp; data->controlledWarp = gControlledWarp;
data->warpDest = savedWarpNode; data->warpDest = savedWarpNode;
data->D_80339EE0 = saved_D_80339EE0;
} }
void network_send_level_warp(u8 done) { void network_send_level_warp_begin(void) {
if (!done) { assert(!isInWarp);
savedWarpNode = sWarpDest; isInWarp = TRUE;
gControlledWarp = true; savedWarpNode = sWarpDest;
eventId++; saved_D_80339EE0 = D_80339EE0;
LOG_INFO("new event [%d]!", eventId);
} 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);
struct PacketLevelWarpData data = { 0 }; struct PacketLevelWarpData data = { 0 };
populate_packet_data(&data, done); 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);
struct Packet p; struct Packet p;
packet_init(&p, PACKET_LEVEL_WARP, true); packet_init(&p, PACKET_LEVEL_WARP, true);
@ -57,6 +100,7 @@ void network_send_level_warp(u8 done) {
static void do_warp(void) { static void do_warp(void) {
gReceiveWarpDest = savedWarpNode; gReceiveWarpDest = savedWarpNode;
D_80339EE0 = saved_D_80339EE0;
gReceiveWarp = TRUE; gReceiveWarp = TRUE;
} }
@ -70,32 +114,46 @@ void network_receive_level_warp(struct Packet* p) {
return; return;
} }
remoteLastSeqId = remote.seqId; remoteLastSeqId = remote.seqId;
LOG_INFO("rx event [%d] last [%d]!", remote.eventId, remoteFinishedEventId);
if (remote.eventId == remoteFinishedEventId || (remote.eventId == remoteFinishedEventId - 1)) { LOG_INFO("rx event [%d] last [%d, %d]", remote.eventId, remoteFinishedEventId[0], remoteFinishedEventId[1]);
LOG_INFO("we've finished this event, escape!");
if (remote.done && remote.eventId != eventId) {
LOG_INFO("remote has finished the wrong id!");
return; 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 (gNetworkType == NT_SERVER) {
if (sCurrPlayMode != PLAY_MODE_SYNC_LEVEL) { if (!isInWarp && remote.done) {
LOG_INFO("client is done with warp, but so are we!");
return;
} else if (!isInWarp) {
// client initiated warp // client initiated warp
LOG_INFO("client initiated warp!"); LOG_INFO("client initiated warp!");
gControlledWarp = FALSE; gControlledWarp = !remote.controlledWarp; // two-player hack
savedWarpNode = remote.warpDest; savedWarpNode = remote.warpDest;
eventId = remote.eventId; saved_D_80339EE0 = remote.D_80339EE0;
remoteFinishedEventId = remote.eventId;
LOG_INFO("finished event [%d]!", remote.eventId);
do_warp(); do_warp();
network_send_level_warp(TRUE); network_send_level_warp_done(remote.eventId);
return; return;
} else if (remote.done) { } else if (remote.done && remote.eventId == eventId) {
// client done with warp // client done with warp
LOG_INFO("client is done with warp, lets-a-go!"); LOG_INFO("client is done with warp, lets-a-go!");
remoteFinishedEventId = remote.eventId;
do_warp(); do_warp();
isInWarp = FALSE;
return; return;
} else { } else {
LOG_INFO("client initiated warp, but server is already warping!"); 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; return;
} }
} }
@ -106,9 +164,8 @@ void network_receive_level_warp(struct Packet* p) {
LOG_INFO("server initiated warp!"); LOG_INFO("server initiated warp!");
gControlledWarp = !remote.controlledWarp; // two-player hack gControlledWarp = !remote.controlledWarp; // two-player hack
savedWarpNode = remote.warpDest; savedWarpNode = remote.warpDest;
eventId = remote.eventId; saved_D_80339EE0 = remote.D_80339EE0;
remoteFinishedEventId = remote.eventId;
LOG_INFO("finished event [%d]!", remote.eventId); LOG_INFO("finished event [%d]!", remote.eventId);
do_warp(); do_warp();
network_send_level_warp(TRUE); network_send_level_warp_done(remote.eventId);
} }