From b9750057d58bad77bc91ab6555cccd910a57852f Mon Sep 17 00:00:00 2001 From: MysterD Date: Sun, 6 Sep 2020 11:02:41 -0700 Subject: [PATCH] General network code clean up Marked globals, rearranged functions, added comments --- src/engine/behavior_script.c | 2 +- src/game/behaviors/boo.inc.c | 8 +- src/game/behaviors/breakable_wall.inc.c | 2 +- src/game/behaviors/cannon_door.inc.c | 4 +- .../behaviors/flying_bookend_switch.inc.c | 28 ++--- src/game/hud.c | 2 +- src/game/level_update.c | 8 +- src/game/mario.c | 8 +- src/game/object_helpers.c | 4 +- src/game/save_file.c | 2 +- src/game/spawn_object.c | 2 +- src/menu/file_select.c | 12 +- src/pc/network/network.c | 54 +++++---- src/pc/network/network.h | 48 +++++--- .../network/packets/packet_inside_painting.c | 2 +- src/pc/network/packets/packet_level_warp.c | 2 +- src/pc/network/packets/packet_object.c | 110 +++++++++--------- src/pc/network/packets/packet_player.c | 8 +- src/pc/network/packets/packet_reservation.c | 20 ++-- src/pc/network/packets/packet_save_file.c | 8 +- src/pc/network/packets/packet_spawn_objects.c | 12 +- 21 files changed, 186 insertions(+), 160 deletions(-) diff --git a/src/engine/behavior_script.c b/src/engine/behavior_script.c index 3faa8faa8..3226789be 100644 --- a/src/engine/behavior_script.c +++ b/src/engine/behavior_script.c @@ -72,7 +72,7 @@ u16 random_u16(void) { // override this function for synchronized entities if (gCurrentObject->oSyncID != 0) { - struct SyncObject* so = &syncObjects[gCurrentObject->oSyncID]; + struct SyncObject* so = &gSyncObjects[gCurrentObject->oSyncID]; if (so->o != NULL && !so->keepRandomSeed) { gSavedSeed16 = gRandomSeed16; force_replicable_seed(FALSE); diff --git a/src/game/behaviors/boo.inc.c b/src/game/behaviors/boo.inc.c index 1e552aaf3..d697c8d67 100644 --- a/src/game/behaviors/boo.inc.c +++ b/src/game/behaviors/boo.inc.c @@ -537,7 +537,7 @@ void bhv_boo_loop(void) { else { if (network_sync_object_initialized(o)) { network_send_object_reliability(o, TRUE); - network_forget_sync_object(&syncObjects[o->oSyncID]); + network_forget_sync_object(&gSyncObjects[o->oSyncID]); } } @@ -752,7 +752,7 @@ void bhv_big_boo_loop(void) { } else if (o->oHealth <= 0) { if (network_sync_object_initialized(o)) { network_send_object_reliability(o, TRUE); - network_forget_sync_object(&syncObjects[o->oSyncID]); + network_forget_sync_object(&gSyncObjects[o->oSyncID]); } } @@ -858,7 +858,7 @@ void bhv_merry_go_round_boo_manager_loop(void) { switch (o->oAction) { case 0: if (distanceToPlayer < 1000.0f) { - if (networkType == NT_SERVER && o->oMerryGoRoundBooManagerNumBoosKilled < 5) { + if (gNetworkType == NT_SERVER && o->oMerryGoRoundBooManagerNumBoosKilled < 5) { if (o->oMerryGoRoundBooManagerNumBoosSpawned < 5) { if (o->oMerryGoRoundBooManagerNumBoosSpawned - o->oMerryGoRoundBooManagerNumBoosKilled < 2) { struct Object* boo = spawn_object(o, MODEL_BOO, bhvMerryGoRoundBoo); @@ -877,7 +877,7 @@ void bhv_merry_go_round_boo_manager_loop(void) { } if (o->oMerryGoRoundBooManagerNumBoosKilled > 4) { - if (networkType == NT_SERVER) { + if (gNetworkType == NT_SERVER) { struct Object* boo = spawn_object(o, MODEL_BOO, bhvMerryGoRoundBigBoo); obj_copy_behavior_params(boo, o); diff --git a/src/game/behaviors/breakable_wall.inc.c b/src/game/behaviors/breakable_wall.inc.c index fcf88117d..76fddd11c 100644 --- a/src/game/behaviors/breakable_wall.inc.c +++ b/src/game/behaviors/breakable_wall.inc.c @@ -12,7 +12,7 @@ void bhv_wf_breakable_wall_loop(void) { if (!o->oBreakableWallForce) { o->oBreakableWallForce = TRUE; network_send_object(o); - syncObjects[o->oSyncID].syncDeathEvent = FALSE; + gSyncObjects[o->oSyncID].syncDeathEvent = FALSE; } if (cur_obj_has_behavior(bhvWfBreakableWallRight)) play_puzzle_jingle(); diff --git a/src/game/behaviors/cannon_door.inc.c b/src/game/behaviors/cannon_door.inc.c index 8fa3a21c6..b761ea00a 100644 --- a/src/game/behaviors/cannon_door.inc.c +++ b/src/game/behaviors/cannon_door.inc.c @@ -4,7 +4,7 @@ void bhv_cannon_closed_init(void) { struct Object *cannon; if (save_file_is_cannon_unlocked() == 1) { - if (!networkLevelLoaded || networkType == NT_SERVER) { + if (!gNetworkLevelLoaded || gNetworkType == NT_SERVER) { // If the cannon is open, spawn a cannon and despawn the object. cannon = spawn_object(o, MODEL_CANNON_BASE, bhvCannon); cannon->parentObj = cannon; @@ -12,7 +12,7 @@ void bhv_cannon_closed_init(void) { cannon->oPosX = o->oHomeX; cannon->oPosY = o->oHomeY; cannon->oPosZ = o->oHomeZ; - if (networkLevelLoaded) { + if (gNetworkLevelLoaded) { network_set_sync_id(cannon); struct Object* spawn_objects[] = { cannon }; u32 models[] = { MODEL_CANNON_BASE }; diff --git a/src/game/behaviors/flying_bookend_switch.inc.c b/src/game/behaviors/flying_bookend_switch.inc.c index 09198b6e3..b29d2ea9b 100644 --- a/src/game/behaviors/flying_bookend_switch.inc.c +++ b/src/game/behaviors/flying_bookend_switch.inc.c @@ -173,11 +173,11 @@ void bookshelf_manager_act_0(void) { void bookshelf_manager_act_1(void) { struct MarioState* marioState = nearest_mario_state_to_object(o); if (o->oBookSwitchManagerUnkF8 == 0) { - if (networkType == NT_SERVER && obj_is_near_to_and_facing_mario(marioState, 500.0f, 0x3000)) { + if (gNetworkType == NT_SERVER && obj_is_near_to_and_facing_mario(marioState, 500.0f, 0x3000)) { o->oBookSwitchManagerUnkF8 = 1; network_send_object(o); } - } else if (o->oTimer > 60 && networkType == NT_SERVER) { + } else if (o->oTimer > 60 && gNetworkType == NT_SERVER) { o->oAction = 2; o->oBookSwitchManagerUnkF8 = 0; network_send_object(o); @@ -188,12 +188,12 @@ void bookshelf_manager_act_2(void) { if (!(o->activeFlags & ACTIVE_FLAG_IN_DIFFERENT_ROOM)) { if (o->oBookSwitchManagerUnkF4 < 0) { if (o->oTimer > 30) { - if (networkType == NT_SERVER) { + if (gNetworkType == NT_SERVER) { o->oBookSwitchManagerUnkF4 = o->oBookSwitchManagerUnkF8 = 0; network_send_object(o); } } else if (o->oTimer > 10) { - if (networkType == NT_SERVER) { + if (gNetworkType == NT_SERVER) { o->oBookSwitchManagerUnkF8 = 1; network_send_object(o); } @@ -201,7 +201,7 @@ void bookshelf_manager_act_2(void) { } else { if (o->oBookSwitchManagerUnkF4 >= 3) { if (o->oTimer > 100) { - if (networkType == NT_SERVER) { + if (gNetworkType == NT_SERVER) { o->parentObj = cur_obj_nearest_object_with_behavior(bhvHauntedBookshelf); o->parentObj->oAction = 1; o->oPosX = o->parentObj->oPosX; @@ -216,7 +216,7 @@ void bookshelf_manager_act_2(void) { o->oTimer = 0; } } - } else if (networkType == NT_SERVER) { + } else if (gNetworkType == NT_SERVER) { o->oAction = 4; network_send_object(o); } @@ -224,7 +224,7 @@ void bookshelf_manager_act_2(void) { void bookshelf_manager_act_3(void) { if (o->oTimer > 85) { - if (networkType == NT_SERVER) { + if (gNetworkType == NT_SERVER) { o->oAction = 4; network_send_object(o); } @@ -237,7 +237,7 @@ void bookshelf_manager_act_3(void) { void bookshelf_manager_act_4(void) { if (o->oBookSwitchManagerUnkF4 >= 3) { obj_mark_for_deletion(o); - } else if (networkType == NT_SERVER) { + } else if (gNetworkType == NT_SERVER) { o->oAction = 0; network_send_object(o); } @@ -308,7 +308,7 @@ void bhv_book_switch_loop(void) { cur_obj_become_intangible(); } - if (networkType == NT_SERVER && o->oAction != 1) { + if (gNetworkType == NT_SERVER && o->oAction != 1) { o->oAction = 1; network_send_object(o); } @@ -320,7 +320,7 @@ void bhv_book_switch_loop(void) { if (approach_f32_ptr(&o->oBookSwitchUnkF4, 50.0f, 20.0f)) { if (o->parentObj->oBookSwitchManagerUnkF4 >= 0 && o->oTimer > 60) { if (sp3C == 1 || sp3C == 2 || sp3C == 6) { - if (networkType == NT_SERVER && o->oAction != 2) { + if (gNetworkType == NT_SERVER && o->oAction != 2) { o->oAction = 2; network_send_object(o); } @@ -335,7 +335,7 @@ void bhv_book_switch_loop(void) { if (o->oAction != 0) { if (o->parentObj->oBookSwitchManagerUnkF4 == o->oBehParams2ndByte) { play_sound(SOUND_GENERAL2_RIGHT_ANSWER, gDefaultSoundArgs); - if (networkType == NT_SERVER) { + if (gNetworkType == NT_SERVER) { o->parentObj->oBookSwitchManagerUnkF4 += 1; network_send_object(o->parentObj); } @@ -348,7 +348,7 @@ void bhv_book_switch_loop(void) { sp34 = 0; } - if (networkType == NT_SERVER) { + if (gNetworkType == NT_SERVER) { book = spawn_object_abs_with_rot(o, 0, MODEL_BOOKEND, bhvFlyingBookend, 0x1FC * sp36 - 0x8CA, 890, sp34, 0, 0x8000 * sp36 + 0x4000, 0); @@ -361,13 +361,13 @@ void bhv_book_switch_loop(void) { } } - if (networkType == NT_SERVER) { + if (gNetworkType == NT_SERVER) { o->parentObj->oBookSwitchManagerUnkF4 = -1; network_send_object(o->parentObj); } } - if (networkType == NT_SERVER && o->oAction != 0) { + if (gNetworkType == NT_SERVER && o->oAction != 0) { o->oAction = 0; network_send_object(o); } diff --git a/src/game/hud.c b/src/game/hud.c index b9796e622..b4242f4ff 100644 --- a/src/game/hud.c +++ b/src/game/hud.c @@ -296,7 +296,7 @@ void render_hud_mario_lives(void) { #ifdef VERSION_JP char* displayHead = ","; #else - char* displayHead = (networkType == NT_SERVER) ? "," : "."; + char* displayHead = (gNetworkType == NT_SERVER) ? "," : "."; #endif print_text(GFX_DIMENSIONS_RECT_FROM_LEFT_EDGE(22), HUD_TOP_Y, displayHead); // 'Mario Head' glyph if (gHudDisplay.lives == -1) { return; } diff --git a/src/game/level_update.c b/src/game/level_update.c index b754e53bc..4a9860465 100644 --- a/src/game/level_update.c +++ b/src/game/level_update.c @@ -681,7 +681,7 @@ void initiate_painting_warp(void) { } else if (pWarpNode->id != 0) { initiate_painting_warp_node(pWarpNode, false); gControlPainting = true; - gWaitingForRemotePainting = (networkType != NT_NONE); + gWaitingForRemotePainting = (gNetworkType != NT_NONE); set_mario_action(gMarioState, ACT_DISAPPEARED, 0); gMarioState->marioObj->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE; } @@ -1028,14 +1028,14 @@ s32 play_mode_normal(void) { if (sWarpDest.type == WARP_TYPE_NOT_WARPING) { set_play_mode(PLAY_MODE_CHANGE_LEVEL); } else { - set_play_mode((networkType != 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(); } } 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((networkType != NT_NONE) ? PLAY_MODE_SYNC_LEVEL : PLAY_MODE_CHANGE_AREA); + set_play_mode((gNetworkType != NT_NONE) ? PLAY_MODE_SYNC_LEVEL : PLAY_MODE_CHANGE_AREA); network_send_level_warp(); } } else if (pressed_pause()) { @@ -1065,7 +1065,7 @@ s32 play_mode_paused(void) { fade_into_special_warp(0, 0); gSavedCourseNum = COURSE_NONE; } - set_play_mode((networkType != 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(); } else if (gPauseScreenMode == 3) { // We should only be getting "int 3" to here diff --git a/src/game/mario.c b/src/game/mario.c index 2a756a039..ce811bc40 100644 --- a/src/game/mario.c +++ b/src/game/mario.c @@ -1877,7 +1877,7 @@ s32 execute_mario_action(UNUSED struct Object *o) { } // two-player hack: drop held object if server is holding it - if (networkType == NT_CLIENT && gMarioState->playerIndex == 0 && gMarioState->heldObj != NULL) { + if (gNetworkType == NT_CLIENT && gMarioState->playerIndex == 0 && gMarioState->heldObj != NULL) { u8 inCutscene = ((gMarioState->action & ACT_GROUP_MASK) != ACT_GROUP_CUTSCENE); if (!inCutscene && gMarioState->heldObj == gMarioStates[0].heldObj) { drop_and_set_mario_action(gMarioState, ACT_IDLE, 0); @@ -2027,7 +2027,7 @@ void init_mario(void) { vec3f_set(gMarioState->vel, 0, 0, 0); // two-player hack - if ((networkType == NT_CLIENT && isLocal) || (networkType == NT_SERVER && !isLocal)) { + if ((gNetworkType == NT_CLIENT && isLocal) || (gNetworkType == NT_SERVER && !isLocal)) { gMarioState->pos[0] += 50.0f * coss(gMarioState->faceAngle[1]); gMarioState->pos[2] += 50.0f * sins(gMarioState->faceAngle[1]); } else { @@ -2076,9 +2076,9 @@ void init_mario(void) { // set mario/luigi model if (isLocal) { - gMarioState->marioObj->header.gfx.sharedChild = gLoadedGraphNodes[(networkType == NT_SERVER) ? MODEL_MARIO : MODEL_LUIGI]; + gMarioState->marioObj->header.gfx.sharedChild = gLoadedGraphNodes[(gNetworkType == NT_SERVER) ? MODEL_MARIO : MODEL_LUIGI]; } else { - gMarioState->marioObj->header.gfx.sharedChild = gLoadedGraphNodes[(networkType == NT_SERVER) ? MODEL_LUIGI2 : MODEL_MARIO2]; + gMarioState->marioObj->header.gfx.sharedChild = gLoadedGraphNodes[(gNetworkType == NT_SERVER) ? MODEL_LUIGI2 : MODEL_MARIO2]; } skippy: diff --git a/src/game/object_helpers.c b/src/game/object_helpers.c index ed02ed68c..dc411414c 100644 --- a/src/game/object_helpers.c +++ b/src/game/object_helpers.c @@ -1166,7 +1166,7 @@ void cur_obj_get_thrown_or_placed(f32 forwardVel, f32 velY, s32 thrownAction) { cur_obj_move_after_thrown_or_dropped(forwardVel, velY); } - if (o->oSyncID != 0 && syncObjects[o->oSyncID].owned) { + if (o->oSyncID != 0 && gSyncObjects[o->oSyncID].owned) { network_send_object(o); } } @@ -1178,7 +1178,7 @@ void cur_obj_get_dropped(void) { o->oHeldState = HELD_FREE; cur_obj_move_after_thrown_or_dropped(0.0f, 0.0f); - if (o->oSyncID != 0 && syncObjects[o->oSyncID].owned) { + if (o->oSyncID != 0 && gSyncObjects[o->oSyncID].owned) { network_send_object(o); } } diff --git a/src/game/save_file.c b/src/game/save_file.c index 269d77a67..e5e96b0c2 100644 --- a/src/game/save_file.c +++ b/src/game/save_file.c @@ -347,7 +347,7 @@ void save_file_do_save(s32 fileIndex) { return; #ifdef TEXTSAVES - if (gSaveFileModified && networkType != NT_CLIENT) { + if (gSaveFileModified && gNetworkType != NT_CLIENT) { // Write to text file write_text_save(fileIndex); gSaveFileModified = FALSE; diff --git a/src/game/spawn_object.c b/src/game/spawn_object.c index 26ee2e6f5..0ea548846 100644 --- a/src/game/spawn_object.c +++ b/src/game/spawn_object.c @@ -198,7 +198,7 @@ void unload_object(struct Object *obj) { obj->header.gfx.node.flags &= ~GRAPH_RENDER_CYLBOARD; obj->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE; - if (obj->oSyncID != 0 && syncObjects[obj->oSyncID].syncDeathEvent) { + if (obj->oSyncID != 0 && gSyncObjects[obj->oSyncID].syncDeathEvent) { network_send_object(obj); } diff --git a/src/menu/file_select.c b/src/menu/file_select.c index 3c947331a..9ab108f05 100644 --- a/src/menu/file_select.c +++ b/src/menu/file_select.c @@ -403,7 +403,7 @@ void keyboard_exit_join_to_network_menu(void) { } void join_server_as_client(void) { - if (networkType != NT_NONE) { return; } + if (gNetworkType != NT_NONE) { return; } char delims[] = { ' ' }; @@ -441,7 +441,7 @@ void join_server_as_client(void) { } void joined_server_as_client(s16 fileIndex) { - if (networkType != NT_CLIENT) { return; } + if (gNetworkType != NT_CLIENT) { return; } sSelectedFileNum = fileIndex; } @@ -561,7 +561,7 @@ void print_join_mode_menu_strings(void) { print_generic_ascii_string(JOIN_LEVEL_NAME_X, 191 - (12 * 2), gTextInput); // Print status - if (networkType == NT_CLIENT) { + if (gNetworkType == NT_CLIENT) { print_generic_ascii_string(JOIN_LEVEL_NAME_X, 191 - (12 * 14), "Connecting..."); } else if (strlen(gTextInput) > 0) { print_generic_ascii_string(JOIN_LEVEL_NAME_X, 191 - (12 * 14), "Press (ENTER) to join."); @@ -1856,7 +1856,7 @@ void handle_cursor_button_input(void) { sClickPos[1] = sCursorPos[1]; sCursorClickingTimer = 1; } - if (networkType == NT_SERVER) { + if (gNetworkType == NT_SERVER) { sClickPos[0] = sCursorPos[0]; sClickPos[1] = sCursorPos[1]; sCursorClickingTimer = 1; @@ -3092,7 +3092,7 @@ s32 lvl_init_menu_values_and_cursor_pos(UNUSED s32 arg, UNUSED s32 unused) { sClickPos[0] = -10000; sClickPos[1] = -10000; sCursorClickingTimer = 0; - if (networkType != NT_CLIENT) { sSelectedFileNum = 0; } + if (gNetworkType != NT_CLIENT) { sSelectedFileNum = 0; } sSelectedFileIndex = MENU_BUTTON_NONE; sFadeOutText = FALSE; sStatusMessageID = 0; @@ -3118,7 +3118,7 @@ s32 lvl_init_menu_values_and_cursor_pos(UNUSED s32 arg, UNUSED s32 unused) { sCursorPos[1] = -24.0f; // immediately jump in - if (networkType == NT_SERVER) { + if (gNetworkType == NT_SERVER) { sSelectedFileNum = configHostSaveSlot; } diff --git a/src/pc/network/network.c b/src/pc/network/network.c index 1086c14f6..443023152 100644 --- a/src/pc/network/network.c +++ b/src/pc/network/network.c @@ -5,67 +5,76 @@ #include "socket/socket.h" #include "pc/configfile.h" -enum NetworkType networkType; +// Mario 64 specific externs +extern u8 gInsidePainting; +extern s16 sCurrPlayMode; + +enum NetworkType gNetworkType; static SOCKET gSocket; struct sockaddr_in txAddr; #define LOADING_LEVEL_THRESHOLD 10 u8 networkLoadingLevel = 0; -bool networkLevelLoaded = false; +bool gNetworkLevelLoaded = false; struct ServerSettings gServerSettings = { .playerInteractions = PLAYER_INTERACTIONS_SOLID, }; void network_init(enum NetworkType inNetworkType, char* ip, unsigned int port) { - networkType = inNetworkType; - - if (networkType == NT_NONE) { return; } + // set network type + gNetworkType = inNetworkType; + if (gNetworkType == NT_NONE) { return; } // sanity check port if (port == 0) { - port = (networkType == NT_CLIENT) ? configJoinPort : configHostPort; + port = (gNetworkType == NT_CLIENT) ? configJoinPort : configHostPort; if (port == 0) { port = DEFAULT_PORT; } } - if (networkType == NT_SERVER) { + // set server settings + if (gNetworkType == NT_SERVER) { gServerSettings.playerInteractions = configPlayerInteraction; } - // Create a receiver socket to receive datagrams + // create a receiver socket to receive datagrams gSocket = socket_initialize(); if (gSocket == INVALID_SOCKET) { return; } - // Bind the socket to any address and the specified port. - if (networkType == NT_SERVER) { + // connect + if (gNetworkType == NT_SERVER) { + // bind the socket to any address and the specified port. int rc = socket_bind(gSocket, port); if (rc != NO_ERROR) { return; } } else { - // Save the port to send to + // save the port to send to txAddr.sin_family = AF_INET; txAddr.sin_port = htons(port); txAddr.sin_addr.s_addr = inet_addr(ip); } - if (networkType == NT_CLIENT) { + // send connection request + if (gNetworkType == NT_CLIENT) { network_send_save_file_request(); } } void network_on_init_level(void) { + // reset loading timer networkLoadingLevel = 0; - networkLevelLoaded = false; + gNetworkLevelLoaded = false; } void network_on_loaded_level(void) { - if (networkType == NT_CLIENT) { + // request my chunk of reserved sync ids + if (gNetworkType == NT_CLIENT) { network_send_reservation_request(); } } void network_send(struct Packet* p) { // sanity checks - if (networkType == NT_NONE) { return; } + if (gNetworkType == NT_NONE) { return; } if (p->error) { printf("%s packet error!\n", NETWORKTYPESTR); return; } // remember reliable packets @@ -82,14 +91,17 @@ void network_send(struct Packet* p) { } void network_update(void) { - if (networkType == NT_NONE) { return; } - if (!networkLevelLoaded) { + if (gNetworkType == NT_NONE) { return; } + + // check for level loaded event + if (!gNetworkLevelLoaded) { if (networkLoadingLevel++ >= LOADING_LEVEL_THRESHOLD) { - networkLevelLoaded = true; + gNetworkLevelLoaded = true; network_on_loaded_level(); } } + // figure out which update loop to run if (gInsidePainting && sCurrPlayMode == PLAY_MODE_CHANGE_LEVEL) { network_update_inside_painting(); } else if (sCurrPlayMode == PLAY_MODE_NORMAL) { @@ -97,6 +109,7 @@ void network_update(void) { network_update_objects(); } + // receive packets do { // receive packet struct Packet p = { .cursor = 3 }; @@ -139,7 +152,8 @@ void network_update(void) { } void network_shutdown(void) { - if (networkType == NT_NONE) { return; } + if (gNetworkType == NT_NONE) { return; } + // close down socket socket_close(gSocket); - networkType = NT_NONE; + gNetworkType = NT_NONE; } diff --git a/src/pc/network/network.h b/src/pc/network/network.h index ec2f0a693..14b1d529b 100644 --- a/src/pc/network/network.h +++ b/src/pc/network/network.h @@ -7,13 +7,16 @@ #include #include "../cliopts.h" +// Mario 64 specific externs +extern struct MarioState gMarioStates[]; + #define SYNC_DISTANCE_ONLY_DEATH -1.0f #define SYNC_DISTANCE_ONLY_EVENTS -2.0f #define SYNC_DISTANCE_INFINITE 0 -#define MAX_SYNC_OBJECTS 256 +#define MAX_SYNC_OBJECTS 256 // note: increasing this requires code to be rewritten #define MAX_SYNC_OBJECT_FIELDS 64 #define PACKET_LENGTH 1024 -#define NETWORKTYPESTR (networkType == NT_CLIENT ? "Client" : "Server") +#define NETWORKTYPESTR (gNetworkType == NT_CLIENT ? "Client" : "Server") enum PacketType { PACKET_ACK, @@ -72,83 +75,92 @@ struct ServerSettings { enum PlayerInteractions playerInteractions; }; -extern struct MarioState gMarioStates[]; -extern u8 gInsidePainting; -extern s16 sCurrPlayMode; -extern enum NetworkType networkType; -extern struct SyncObject syncObjects[]; -extern bool networkLevelLoaded; +// Networking-specific externs +extern bool gNetworkLevelLoaded; +extern enum NetworkType gNetworkType; +extern struct SyncObject gSyncObjects[]; extern struct ServerSettings gServerSettings; - +// network.c void network_init(enum NetworkType inNetworkType, char* ip, unsigned int port); void network_on_init_level(void); void network_on_loaded_level(void); - -void network_clear_sync_objects(void); -struct SyncObject* network_init_object(struct Object *object, float maxSyncDistance); -void network_init_object_field(struct Object* o, void* field); void network_send(struct Packet* p); void network_update(void); void network_shutdown(void); -// packet read / write +// packet_read_write.c void packet_init(struct Packet* packet, enum PacketType packetType, bool reliable); void packet_write(struct Packet* packet, void* data, u16 length); void packet_read(struct Packet* packet, void* data, u16 length); u32 packet_hash(struct Packet* packet); bool packet_check_hash(struct Packet* packet); -// packet headers +// packet_reliable.c void network_send_ack(struct Packet* p); void network_receive_ack(struct Packet* p); void network_remember_reliable(struct Packet* p); void network_update_reliable(void); +// packet_player.c void network_update_player(void); void network_receive_player(struct Packet* p); -void network_forget_sync_object(struct SyncObject* so); +// packet_object.c +struct SyncObject* network_init_object(struct Object* object, float maxSyncDistance); +void network_init_object_field(struct Object* o, void* field); bool network_owns_object(struct Object* o); -void network_set_sync_id(struct Object* o); bool network_sync_object_initialized(struct Object* o); -void network_update_objects(void); +void network_clear_sync_objects(void); +void network_set_sync_id(struct Object* o); void network_send_object(struct Object* o); void network_send_object_reliability(struct Object* o, bool reliable); void network_receive_object(struct Packet* p); +void network_forget_sync_object(struct SyncObject* so); +void network_update_objects(void); +// packet_spawn_object.c void network_send_spawn_objects(struct Object* objects[], u32 models[], u8 objectCount); void network_receive_spawn_objects(struct Packet* p); +// packet_spawn_star.c void network_send_spawn_star(struct Object* o, u8 starType, f32 x, f32 y, f32 z, u32 behParams); void network_receive_spawn_star(struct Packet* p); +// packet_level_warp.c void network_send_level_warp(void); void network_receive_level_warp(struct Packet* p); +// packet_inside_painting.c void network_update_inside_painting(void); void network_send_inside_painting(void); void network_receive_inside_painting(struct Packet* p); +// packet_collect_star.c void network_send_collect_star(struct Object* o, s16 coinScore, s16 starIndex); void network_receive_collect_star(struct Packet* p); +// packet_collect_coin.c void network_send_collect_coin(struct Object* o); void network_receive_collect_coin(struct Packet* p); +// packet_collect_item.c void network_send_collect_item(struct Object* o); void network_receive_collect_item(struct Packet* p); +// packet_reservation.c void network_send_reservation_request(void); void network_receive_reservation_request(UNUSED struct Packet* p); void network_send_reservation(void); void network_receive_reservation(struct Packet* p); +// packet_save_file.c void network_send_save_file_request(void); void network_receive_save_file_request(UNUSED struct Packet* p); void network_send_save_file(void); void network_receive_save_file(struct Packet* p); +// packet_custom.c u8 network_register_custom_packet(void (*send_callback)(struct Packet* p, void* params), void (*receive_callback)(struct Packet* p)); void network_send_custom(u8 customId, bool reliable, void* params); void network_receive_custom(struct Packet* p); diff --git a/src/pc/network/packets/packet_inside_painting.c b/src/pc/network/packets/packet_inside_painting.c index 993207002..0e8fb7d52 100644 --- a/src/pc/network/packets/packet_inside_painting.c +++ b/src/pc/network/packets/packet_inside_painting.c @@ -42,7 +42,7 @@ void network_receive_inside_painting(struct Packet* p) { struct PacketDataInsidePainting remote = { 0 }; packet_read(p, &remote, sizeof(struct PacketDataInsidePainting)); - if (networkType == NT_CLIENT && gControlPainting && remote.controlPainting) { + if (gNetworkType == NT_CLIENT && gControlPainting && remote.controlPainting) { // we both think we should control the painting, host wins the tie gControlPainting = false; } diff --git a/src/pc/network/packets/packet_level_warp.c b/src/pc/network/packets/packet_level_warp.c index 67d908c39..3cc07bae0 100644 --- a/src/pc/network/packets/packet_level_warp.c +++ b/src/pc/network/packets/packet_level_warp.c @@ -53,7 +53,7 @@ void network_receive_level_warp(struct Packet* p) { case WARP_TYPE_CHANGE_LEVEL: sCurrPlayMode = PLAY_MODE_CHANGE_LEVEL; break; } } else { - if (networkType == NT_CLIENT) { + if (gNetworkType == NT_CLIENT) { if (remoteWarpDest.type == WARP_TYPE_NOT_WARPING) { return; } // two-player hack: would need to use player index as priority sWarpDest = remoteWarpDest; diff --git a/src/pc/network/packets/packet_object.c b/src/pc/network/packets/packet_object.c index 8a564501c..6c9048b29 100644 --- a/src/pc/network/packets/packet_object.c +++ b/src/pc/network/packets/packet_object.c @@ -9,10 +9,10 @@ #include "src/game/object_helpers.h" static u8 nextSyncID = 1; -struct SyncObject syncObjects[MAX_SYNC_OBJECTS] = { 0 }; +struct SyncObject gSyncObjects[MAX_SYNC_OBJECTS] = { 0 }; // todo: move this to somewhere more general -float player_distance(struct MarioState* marioState, struct Object* o) { +static float player_distance(struct MarioState* marioState, struct Object* o) { if (marioState->marioObj == NULL) { return 0; } f32 mx = marioState->marioObj->header.gfx.pos[0] - o->oPosX; f32 my = marioState->marioObj->header.gfx.pos[1] - o->oPosY; @@ -23,29 +23,16 @@ float player_distance(struct MarioState* marioState, struct Object* o) { return sqrt(mx + my + mz); } -void network_clear_sync_objects(void) { - for (u16 i = 0; i < MAX_SYNC_OBJECTS; i++) { - network_forget_sync_object(&syncObjects[i]); +static bool should_own_object(struct SyncObject* so) { + if (gMarioStates[0].heldByObj == so->o) { return true; } + for (int i = 0; i < MAX_PLAYERS; i++) { + if (gMarioStates[i].heldByObj == so->o) { return false; } } - nextSyncID = 1; -} -void network_set_sync_id(struct Object* o) { - if (o->oSyncID != 0) { return; } - - // two-player hack - u8 reserveId = (networkLevelLoaded && networkType == NT_CLIENT) ? 1 : 0; - - for (u16 i = 0; i < MAX_SYNC_OBJECTS; i++) { - if (syncObjects[nextSyncID].reserved == reserveId && syncObjects[nextSyncID].o == NULL) { break; } - nextSyncID = (nextSyncID + 1) % MAX_SYNC_OBJECTS; - } - assert(syncObjects[nextSyncID].o == NULL); - assert(syncObjects[nextSyncID].reserved == reserveId); - o->oSyncID = nextSyncID; - nextSyncID = (nextSyncID + 1) % MAX_SYNC_OBJECTS; - - assert(o->oSyncID < MAX_SYNC_OBJECTS); + if (so->o->oHeldState == HELD_HELD && so->o->heldByPlayerIndex == 0) { return true; } + if (player_distance(&gMarioStates[0], so->o) > player_distance(&gMarioStates[1], so->o)) { return false; } + if (so->o->oHeldState == HELD_HELD && so->o->heldByPlayerIndex != 0) { return false; } + return true; } struct SyncObject* network_init_object(struct Object *o, float maxSyncDistance) { @@ -53,7 +40,7 @@ struct SyncObject* network_init_object(struct Object *o, float maxSyncDistance) network_set_sync_id(o); // set default values for sync object - struct SyncObject* so = &syncObjects[o->oSyncID]; + struct SyncObject* so = &gSyncObjects[o->oSyncID]; so->o = o; so->reserved = 0; so->maxSyncDistance = maxSyncDistance; @@ -77,27 +64,52 @@ struct SyncObject* network_init_object(struct Object *o, float maxSyncDistance) void network_init_object_field(struct Object *o, void* field) { assert(o->oSyncID != 0); // remember to synchronize this extra field - struct SyncObject* so = &syncObjects[o->oSyncID]; + struct SyncObject* so = &gSyncObjects[o->oSyncID]; u8 index = so->extraFieldCount++; so->extraFields[index] = field; } bool network_owns_object(struct Object* o) { - struct SyncObject* so = &syncObjects[o->oSyncID]; + struct SyncObject* so = &gSyncObjects[o->oSyncID]; if (so == NULL) { return false; } return so->owned; } bool network_sync_object_initialized(struct Object* o) { if (o->oSyncID == 0) { return false; } - if (syncObjects[o->oSyncID].behavior == NULL) { return false; } + if (gSyncObjects[o->oSyncID].behavior == NULL) { return false; } return true; } +void network_clear_sync_objects(void) { + for (u16 i = 0; i < MAX_SYNC_OBJECTS; i++) { + network_forget_sync_object(&gSyncObjects[i]); + } + nextSyncID = 1; +} + +void network_set_sync_id(struct Object* o) { + if (o->oSyncID != 0) { return; } + + // two-player hack + u8 reserveId = (gNetworkLevelLoaded && gNetworkType == NT_CLIENT) ? 1 : 0; + + for (u16 i = 0; i < MAX_SYNC_OBJECTS; i++) { + if (gSyncObjects[nextSyncID].reserved == reserveId && gSyncObjects[nextSyncID].o == NULL) { break; } + nextSyncID = (nextSyncID + 1) % MAX_SYNC_OBJECTS; + } + assert(gSyncObjects[nextSyncID].o == NULL); + assert(gSyncObjects[nextSyncID].reserved == reserveId); + o->oSyncID = nextSyncID; + nextSyncID = (nextSyncID + 1) % MAX_SYNC_OBJECTS; + + assert(o->oSyncID < MAX_SYNC_OBJECTS); +} + // ----- header ----- // static void packet_write_object_header(struct Packet* p, struct Object* o) { - struct SyncObject* so = &syncObjects[o->oSyncID]; + struct SyncObject* so = &gSyncObjects[o->oSyncID]; enum BehaviorId behaviorId = get_id_from_behavior(o->behavior); packet_write(p, &o->oSyncID, sizeof(u32)); @@ -130,14 +142,14 @@ static struct SyncObject* packet_read_object_header(struct Packet* p) { } // extract object, sanity check - struct Object* o = syncObjects[syncId].o; + struct Object* o = gSyncObjects[syncId].o; if (o == NULL) { printf("%s invalid SyncObject!\n", NETWORKTYPESTR); return NULL; } // retrieve SyncObject, check if we should update using callback - struct SyncObject* so = &syncObjects[syncId]; + struct SyncObject* so = &gSyncObjects[syncId]; if (so->ignore_if_true != NULL && (*so->ignore_if_true)(so->o)) { return NULL; } @@ -167,7 +179,7 @@ static struct SyncObject* packet_read_object_header(struct Packet* p) { // ----- full sync ----- // static void packet_write_object_full_sync(struct Packet* p, struct Object* o) { - struct SyncObject* so = &syncObjects[o->oSyncID]; + struct SyncObject* so = &gSyncObjects[o->oSyncID]; if (!so->fullObjectSync) { return; } // write all of raw data @@ -175,7 +187,7 @@ static void packet_write_object_full_sync(struct Packet* p, struct Object* o) { } static void packet_read_object_full_sync(struct Packet* p, struct Object* o) { - struct SyncObject* so = &syncObjects[o->oSyncID]; + struct SyncObject* so = &gSyncObjects[o->oSyncID]; if (!so->fullObjectSync) { return; } // read all of raw data @@ -185,7 +197,7 @@ static void packet_read_object_full_sync(struct Packet* p, struct Object* o) { // ----- standard fields ----- // static void packet_write_object_standard_fields(struct Packet* p, struct Object* o) { - struct SyncObject* so = &syncObjects[o->oSyncID]; + struct SyncObject* so = &gSyncObjects[o->oSyncID]; if (so->fullObjectSync) { return; } if (so->maxSyncDistance == SYNC_DISTANCE_ONLY_DEATH) { return; } if (so->maxSyncDistance == SYNC_DISTANCE_ONLY_EVENTS) { return; } @@ -205,7 +217,7 @@ static void packet_write_object_standard_fields(struct Packet* p, struct Object* } static void packet_read_object_standard_fields(struct Packet* p, struct Object* o) { - struct SyncObject* so = &syncObjects[o->oSyncID]; + struct SyncObject* so = &gSyncObjects[o->oSyncID]; if (so->fullObjectSync) { return; } if (so->maxSyncDistance == SYNC_DISTANCE_ONLY_DEATH) { return; } if (so->maxSyncDistance == SYNC_DISTANCE_ONLY_EVENTS) { return; } @@ -227,7 +239,7 @@ static void packet_read_object_standard_fields(struct Packet* p, struct Object* // ----- extra fields ----- // static void packet_write_object_extra_fields(struct Packet* p, struct Object* o) { - struct SyncObject* so = &syncObjects[o->oSyncID]; + struct SyncObject* so = &gSyncObjects[o->oSyncID]; if (so->maxSyncDistance == SYNC_DISTANCE_ONLY_DEATH) { return; } // write the count @@ -241,7 +253,7 @@ static void packet_write_object_extra_fields(struct Packet* p, struct Object* o) } static void packet_read_object_extra_fields(struct Packet* p, struct Object* o) { - struct SyncObject* so = &syncObjects[o->oSyncID]; + struct SyncObject* so = &gSyncObjects[o->oSyncID]; if (so->maxSyncDistance == SYNC_DISTANCE_ONLY_DEATH) { return; } // read the count and sanity check @@ -261,13 +273,13 @@ static void packet_read_object_extra_fields(struct Packet* p, struct Object* o) // ----- only death ----- // static void packet_write_object_only_death(struct Packet* p, struct Object* o) { - struct SyncObject* so = &syncObjects[o->oSyncID]; + struct SyncObject* so = &gSyncObjects[o->oSyncID]; if (so->maxSyncDistance != SYNC_DISTANCE_ONLY_DEATH) { return; } packet_write(p, &o->activeFlags, sizeof(s16)); } static void packet_read_object_only_death(struct Packet* p, struct Object* o) { - struct SyncObject* so = &syncObjects[o->oSyncID]; + struct SyncObject* so = &gSyncObjects[o->oSyncID]; if (so->maxSyncDistance != SYNC_DISTANCE_ONLY_DEATH) { return; } s16 activeFlags; packet_read(p, &activeFlags, sizeof(u16)); @@ -283,7 +295,7 @@ static void packet_read_object_only_death(struct Packet* p, struct Object* o) { void network_send_object(struct Object* o) { // sanity check SyncObject if (!network_sync_object_initialized(o)) { return; } - struct SyncObject* so = &syncObjects[o->oSyncID]; + struct SyncObject* so = &gSyncObjects[o->oSyncID]; if (so == NULL) { return; } if (o->behavior != so->behavior && !allowable_behavior_change(so, so->behavior)) { printf("network_send_object() BEHAVIOR MISMATCH!\n"); @@ -303,7 +315,7 @@ void network_send_object(struct Object* o) { void network_send_object_reliability(struct Object* o, bool reliable) { // sanity check SyncObject if (!network_sync_object_initialized(o)) { return; } - struct SyncObject* so = &syncObjects[o->oSyncID]; + struct SyncObject* so = &gSyncObjects[o->oSyncID]; if (so == NULL) { return; } if (o->behavior != so->behavior && !allowable_behavior_change(so, so->behavior)) { @@ -362,18 +374,6 @@ void network_receive_object(struct Packet* p) { } } -bool should_own_object(struct SyncObject* so) { - if (gMarioStates[0].heldByObj == so->o) { return true; } - for (int i = 0; i < MAX_PLAYERS; i++) { - if (gMarioStates[i].heldByObj == so->o) { return false; } - } - - if (so->o->oHeldState == HELD_HELD && so->o->heldByPlayerIndex == 0) { return true; } - if (player_distance(&gMarioStates[0], so->o) > player_distance(&gMarioStates[1], so->o)) { return false; } - if (so->o->oHeldState == HELD_HELD && so->o->heldByPlayerIndex != 0) { return false; } - return true; -} - void network_forget_sync_object(struct SyncObject* so) { so->o = NULL; so->behavior = NULL; @@ -383,7 +383,7 @@ void network_forget_sync_object(struct SyncObject* so) { void network_update_objects(void) { for (u32 i = 1; i < nextSyncID; i++) { - struct SyncObject* so = &syncObjects[i]; + struct SyncObject* so = &gSyncObjects[i]; if (so->o == NULL) { continue; } // check for stale sync object @@ -400,7 +400,7 @@ void network_update_objects(void) { // check for 'only death' event if (so->maxSyncDistance == SYNC_DISTANCE_ONLY_DEATH) { if (so->o->activeFlags != ACTIVE_FLAG_DEACTIVATED) { continue; } - network_send_object(syncObjects[i].o); + network_send_object(gSyncObjects[i].o); continue; } @@ -419,7 +419,7 @@ void network_update_objects(void) { if (timeSinceUpdate < updateRate) { continue; } // update! - network_send_object(syncObjects[i].o); + network_send_object(gSyncObjects[i].o); } } diff --git a/src/pc/network/packets/packet_player.c b/src/pc/network/packets/packet_player.c index edcaf0f1d..9fa07e40f 100644 --- a/src/pc/network/packets/packet_player.c +++ b/src/pc/network/packets/packet_player.c @@ -66,9 +66,9 @@ void network_receive_player(struct Packet* p) { } // find and set their held object - if (heldSyncID != 0 && syncObjects[heldSyncID].o != NULL) { + if (heldSyncID != 0 && gSyncObjects[heldSyncID].o != NULL) { // TODO: do we have to move graphics nodes around to make this visible? - struct Object* heldObj = syncObjects[heldSyncID].o; + struct Object* heldObj = gSyncObjects[heldSyncID].o; gMarioStates[1].heldObj = heldObj; heldObj->oHeldState = HELD_HELD; heldObj->heldByPlayerIndex = 1; @@ -77,9 +77,9 @@ void network_receive_player(struct Packet* p) { } // find and set their held-by object - if (heldBySyncID != 0 && syncObjects[heldBySyncID].o != NULL) { + if (heldBySyncID != 0 && gSyncObjects[heldBySyncID].o != NULL) { // TODO: do we have to move graphics nodes around to make this visible? - gMarioStates[1].heldByObj = syncObjects[heldBySyncID].o; + gMarioStates[1].heldByObj = gSyncObjects[heldBySyncID].o; } else { gMarioStates[1].heldByObj = NULL; } diff --git a/src/pc/network/packets/packet_reservation.c b/src/pc/network/packets/packet_reservation.c index 879ac91b1..4193ec56d 100644 --- a/src/pc/network/packets/packet_reservation.c +++ b/src/pc/network/packets/packet_reservation.c @@ -10,7 +10,7 @@ #define RESERVATION_COUNT 10 void network_send_reservation_request(void) { - assert(networkType == NT_CLIENT); + assert(gNetworkType == NT_CLIENT); struct Packet p; packet_init(&p, PACKET_RESERVATION_REQUEST, true); @@ -18,19 +18,19 @@ void network_send_reservation_request(void) { } void network_receive_reservation_request(UNUSED struct Packet* p) { - assert(networkType == NT_SERVER); + assert(gNetworkType == NT_SERVER); network_send_reservation(); } void network_send_reservation(void) { - assert(networkType == NT_SERVER); + assert(gNetworkType == NT_SERVER); u8 clientPlayerIndex = 1; // two-player hack // find all reserved objects u8 reservedObjs[RESERVATION_COUNT] = { 0 }; u16 reservedIndex = 0; for (u16 i = 1; i < MAX_SYNC_OBJECTS; i++) { - if (syncObjects[i].reserved == clientPlayerIndex) { + if (gSyncObjects[i].reserved == clientPlayerIndex) { reservedObjs[reservedIndex++] = i; if (reservedIndex >= RESERVATION_COUNT) { break; } } @@ -39,9 +39,9 @@ void network_send_reservation(void) { if (reservedIndex < RESERVATION_COUNT) { // reserve the rest for (u16 i = MAX_SYNC_OBJECTS - 1; i > 0; i--) { - if (syncObjects[i].o != NULL) { continue; } - if (syncObjects[i].reserved != 0) { continue; } - syncObjects[i].reserved = clientPlayerIndex; + if (gSyncObjects[i].o != NULL) { continue; } + if (gSyncObjects[i].reserved != 0) { continue; } + gSyncObjects[i].reserved = clientPlayerIndex; reservedObjs[reservedIndex++] = i; if (reservedIndex >= RESERVATION_COUNT) { break; } } @@ -54,7 +54,7 @@ void network_send_reservation(void) { } void network_receive_reservation(struct Packet* p) { - assert(networkType == NT_CLIENT); + assert(gNetworkType == NT_CLIENT); u8 clientPlayerIndex = 1; // two-player hack // find all reserved objects @@ -64,7 +64,7 @@ void network_receive_reservation(struct Packet* p) { for (u16 i = 0; i < RESERVATION_COUNT; i++) { u16 index = reservedObjs[i]; if (index == 0) { continue; } - if (syncObjects[index].o != NULL) { continue; } - syncObjects[index].reserved = clientPlayerIndex; + if (gSyncObjects[index].o != NULL) { continue; } + gSyncObjects[index].reserved = clientPlayerIndex; } } diff --git a/src/pc/network/packets/packet_save_file.c b/src/pc/network/packets/packet_save_file.c index 622790c82..843a40f7a 100644 --- a/src/pc/network/packets/packet_save_file.c +++ b/src/pc/network/packets/packet_save_file.c @@ -15,7 +15,7 @@ extern u8* gOverrideEeprom; static u8 eeprom[512] = { 0 }; void network_send_save_file_request(void) { - assert(networkType == NT_CLIENT); + assert(gNetworkType == NT_CLIENT); gOverrideEeprom = eeprom; @@ -25,12 +25,12 @@ void network_send_save_file_request(void) { } void network_receive_save_file_request(UNUSED struct Packet* p) { - assert(networkType == NT_SERVER); + assert(gNetworkType == NT_SERVER); network_send_save_file(); } void network_send_save_file(void) { - assert(networkType == NT_SERVER); + assert(gNetworkType == NT_SERVER); fs_file_t* fp = fs_open(SAVE_FILENAME); if (fp != NULL) { @@ -47,7 +47,7 @@ void network_send_save_file(void) { } void network_receive_save_file(struct Packet* p) { - assert(networkType == NT_CLIENT); + assert(gNetworkType == NT_CLIENT); gOverrideEeprom = eeprom; diff --git a/src/pc/network/packets/packet_spawn_objects.c b/src/pc/network/packets/packet_spawn_objects.c index 49cb5a9b8..ceb200503 100644 --- a/src/pc/network/packets/packet_spawn_objects.c +++ b/src/pc/network/packets/packet_spawn_objects.c @@ -87,7 +87,7 @@ void network_receive_spawn_objects(struct Packet* p) { onRemoteSpawnId = (onRemoteSpawnId + 1) % MAX_REMOTE_SPAWN_IDS; // two-player hack - u8 reserveId = (networkLevelLoaded && networkType == NT_SERVER) ? 1 : 0; + u8 reserveId = (gNetworkLevelLoaded && gNetworkType == NT_SERVER) ? 1 : 0; bool receivedReservedSyncObject = false; struct Object* spawned[MAX_SPAWN_OBJECTS_PER_PACKET] = { 0 }; @@ -106,7 +106,7 @@ void network_receive_spawn_objects(struct Packet* p) { } else { // this object has a known parent parentObj = (i == 0) - ? syncObjects[data.parentId].o + ? gSyncObjects[data.parentId].o : spawned[data.parentId]; if (parentObj == NULL) { continue; } } @@ -119,9 +119,9 @@ void network_receive_spawn_objects(struct Packet* p) { if (data.parentId == (u8)-1) { o->parentObj = o; } // they've allocated one of their reserved sync objects - if (o->oSyncID != 0 && syncObjects[o->oSyncID].reserved == reserveId) { - syncObjects[o->oSyncID].o = o; - syncObjects[o->oSyncID].reserved = 0; + if (o->oSyncID != 0 && gSyncObjects[o->oSyncID].reserved == reserveId) { + gSyncObjects[o->oSyncID].o = o; + gSyncObjects[o->oSyncID].reserved = 0; receivedReservedSyncObject = true; } @@ -129,7 +129,7 @@ void network_receive_spawn_objects(struct Packet* p) { } // update their block of reserved ids - if (networkType == NT_SERVER && receivedReservedSyncObject) { + if (gNetworkType == NT_SERVER && receivedReservedSyncObject) { network_send_reservation(); } }