From e86efb9e8556060952b1796e446d580d4410b052 Mon Sep 17 00:00:00 2001 From: MysterD Date: Thu, 6 Aug 2020 21:47:03 -0700 Subject: [PATCH] Synchronized checkerboard platforms Created a max update rate Created 'full object syncing' Switched to using clock() instead of ticks for packet_object --- .../behaviors/checkerboard_platform.inc.c | 2 + src/pc/network/network.h | 5 +- src/pc/network/packets/packet_object.c | 72 ++++++++++++------- 3 files changed, 53 insertions(+), 26 deletions(-) diff --git a/src/game/behaviors/checkerboard_platform.inc.c b/src/game/behaviors/checkerboard_platform.inc.c index 30235a03..55ffeac7 100644 --- a/src/game/behaviors/checkerboard_platform.inc.c +++ b/src/game/behaviors/checkerboard_platform.inc.c @@ -45,6 +45,8 @@ void checkerboard_plat_act_rotate(s32 a0, s16 a1) { void bhv_checkerboard_platform_init(void) { o->oCheckerBoardPlatformUnkFC = o->parentObj->oBehParams2ndByte; + network_init_object(o, 1000.0f); + network_object_settings(o, TRUE, 5.0f); } void bhv_checkerboard_platform_loop(void) { diff --git a/src/pc/network/network.h b/src/pc/network/network.h index 315eee2c..0260742d 100644 --- a/src/pc/network/network.h +++ b/src/pc/network/network.h @@ -36,10 +36,12 @@ struct SyncObject { struct Object* o; float maxSyncDistance; bool owned; - unsigned int ticksSinceUpdate; + clock_t clockSinceUpdate; void* behavior; u16 onEventId; u8 extraFieldCount; + bool fullObjectSync; + float maxUpdateRate; void* extraFields[MAX_SYNC_OBJECT_FIELDS]; }; @@ -51,6 +53,7 @@ extern struct SyncObject syncObjects[]; void network_init(enum NetworkType networkType); void network_init_object(struct Object *object, float maxSyncDistance); +void network_object_settings(struct Object *object, bool fullObjectSync, float maxUpdateRate); void network_send(struct Packet* p); void network_update(void); void network_shutdown(void); diff --git a/src/pc/network/packets/packet_object.c b/src/pc/network/packets/packet_object.c index f2678cbc..a694a2d0 100644 --- a/src/pc/network/packets/packet_object.c +++ b/src/pc/network/packets/packet_object.c @@ -22,13 +22,22 @@ void network_init_object(struct Object *o, float maxSyncDistance) { so->o = o; so->maxSyncDistance = maxSyncDistance; so->owned = false; - so->ticksSinceUpdate = -1; + so->clockSinceUpdate = clock(); so->extraFieldCount = 0; so->behavior = o->behavior; so->onEventId = 0; + so->fullObjectSync = false; + so->maxUpdateRate = 0; memset(so->extraFields, 0, sizeof(void*) * MAX_SYNC_OBJECT_FIELDS); } +void network_object_settings(struct Object *o, bool fullObjectSync, float maxUpdateRate) { + assert(o->oSyncID != 0); + struct SyncObject* so = &syncObjects[o->oSyncID]; + so->fullObjectSync = fullObjectSync; + so->maxUpdateRate = maxUpdateRate; +} + void network_init_object_field(struct Object *o, void* field) { assert(o->oSyncID != 0); struct SyncObject* so = &syncObjects[o->oSyncID]; @@ -55,21 +64,26 @@ void network_send_object(struct Object* o) { packet_write(&p, &so->onEventId, 2); packet_write(&p, &so->behavior, sizeof(void*)); packet_write(&p, &o->activeFlags, 2); - packet_write(&p, &o->oPosX, 28); - packet_write(&p, &o->oAction, 4); - packet_write(&p, &o->oSubAction, 4); - packet_write(&p, &o->oInteractStatus, 4); - packet_write(&p, &o->oHeldState, 4); - packet_write(&p, &o->oMoveAngleYaw, 4); - packet_write(&p, &o->oTimer, 4); - packet_write(&p, &so->extraFieldCount, 1); - for (int i = 0; i < so->extraFieldCount; i++) { - assert(so->extraFields[i] != NULL); - packet_write(&p, so->extraFields[i], 4); + if (so->fullObjectSync) { + packet_write(&p, o->rawData.asU32, 320); + } else { + packet_write(&p, &o->oPosX, 28); + packet_write(&p, &o->oAction, 4); + packet_write(&p, &o->oSubAction, 4); + packet_write(&p, &o->oInteractStatus, 4); + packet_write(&p, &o->oHeldState, 4); + packet_write(&p, &o->oMoveAngleYaw, 4); + packet_write(&p, &o->oTimer, 4); + + packet_write(&p, &so->extraFieldCount, 1); + for (int i = 0; i < so->extraFieldCount; i++) { + assert(so->extraFields[i] != NULL); + packet_write(&p, so->extraFields[i], 4); + } } - so->ticksSinceUpdate = 0; + so->clockSinceUpdate = clock(); if (o->activeFlags == ACTIVE_FLAG_DEACTIVATED) { forget_sync_object(so); } @@ -90,7 +104,7 @@ void network_receive_object(struct Packet* p) { // retrieve SyncObject struct SyncObject* so = &syncObjects[syncId]; - so->ticksSinceUpdate = 0; + so->clockSinceUpdate = clock(); // extract Object struct Object* o = syncObjects[syncId].o; @@ -128,13 +142,18 @@ void network_receive_object(struct Packet* p) { // write object flags packet_read(p, &o->activeFlags, 2); - packet_read(p, &o->oPosX, 28); - packet_read(p, &o->oAction, 4); - packet_read(p, &o->oSubAction, 4); - packet_read(p, &o->oInteractStatus, 4); - packet_read(p, &o->oHeldState, 4); - packet_read(p, &o->oMoveAngleYaw, 4); - packet_read(p, &o->oTimer, 4); + + if (so->fullObjectSync) { + packet_read(p, o->rawData.asU32, 320); + } else { + packet_read(p, &o->oPosX, 28); + packet_read(p, &o->oAction, 4); + packet_read(p, &o->oSubAction, 4); + packet_read(p, &o->oInteractStatus, 4); + packet_read(p, &o->oHeldState, 4); + packet_read(p, &o->oMoveAngleYaw, 4); + packet_read(p, &o->oTimer, 4); + } // write extra fields u8 extraFields = 0; @@ -172,7 +191,6 @@ bool should_own_object(struct SyncObject* so) { void forget_sync_object(struct SyncObject* so) { so->o = NULL; so->owned = false; - so->ticksSinceUpdate = -1; } void network_update_objects(void) { @@ -186,7 +204,6 @@ void network_update_objects(void) { forget_sync_object(so); continue; } - so->ticksSinceUpdate++; // check if we should be the one syncing this object so->owned = should_own_object(so); @@ -201,9 +218,14 @@ void network_update_objects(void) { float dist = player_distance(&gMarioStates[0], so->o); if (so->maxSyncDistance != SYNC_DISTANCE_INFINITE && dist > so->maxSyncDistance) { continue; } - int updateRate = dist / 50; + float updateRate = dist / 1000.0f; if (gMarioStates[0].heldObj == so->o) { updateRate = 0; } - if (so->ticksSinceUpdate < updateRate) { continue; } + + if (so->maxUpdateRate > 0 && updateRate < so->maxUpdateRate) { updateRate = so->maxUpdateRate; } + if (updateRate < 0.33f) { updateRate = 0.33f; } + + float timeSinceUpdate = ((float)clock() - (float)so->clockSinceUpdate) / (float)CLOCKS_PER_SEC; + if (timeSinceUpdate < updateRate) { continue; } network_send_object(syncObjects[i].o); }