Synchronized checkerboard platforms

Created a max update rate
Created 'full object syncing'
Switched to using clock() instead of ticks for packet_object
This commit is contained in:
MysterD 2020-08-06 21:47:03 -07:00
parent e0b86b7d59
commit e86efb9e85
3 changed files with 53 additions and 26 deletions

View File

@ -45,6 +45,8 @@ void checkerboard_plat_act_rotate(s32 a0, s16 a1) {
void bhv_checkerboard_platform_init(void) { void bhv_checkerboard_platform_init(void) {
o->oCheckerBoardPlatformUnkFC = o->parentObj->oBehParams2ndByte; o->oCheckerBoardPlatformUnkFC = o->parentObj->oBehParams2ndByte;
network_init_object(o, 1000.0f);
network_object_settings(o, TRUE, 5.0f);
} }
void bhv_checkerboard_platform_loop(void) { void bhv_checkerboard_platform_loop(void) {

View File

@ -36,10 +36,12 @@ struct SyncObject {
struct Object* o; struct Object* o;
float maxSyncDistance; float maxSyncDistance;
bool owned; bool owned;
unsigned int ticksSinceUpdate; clock_t clockSinceUpdate;
void* behavior; void* behavior;
u16 onEventId; u16 onEventId;
u8 extraFieldCount; u8 extraFieldCount;
bool fullObjectSync;
float maxUpdateRate;
void* extraFields[MAX_SYNC_OBJECT_FIELDS]; void* extraFields[MAX_SYNC_OBJECT_FIELDS];
}; };
@ -51,6 +53,7 @@ extern struct SyncObject syncObjects[];
void network_init(enum NetworkType networkType); void network_init(enum NetworkType networkType);
void network_init_object(struct Object *object, float maxSyncDistance); 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_send(struct Packet* p);
void network_update(void); void network_update(void);
void network_shutdown(void); void network_shutdown(void);

View File

@ -22,13 +22,22 @@ void network_init_object(struct Object *o, float maxSyncDistance) {
so->o = o; so->o = o;
so->maxSyncDistance = maxSyncDistance; so->maxSyncDistance = maxSyncDistance;
so->owned = false; so->owned = false;
so->ticksSinceUpdate = -1; so->clockSinceUpdate = clock();
so->extraFieldCount = 0; so->extraFieldCount = 0;
so->behavior = o->behavior; so->behavior = o->behavior;
so->onEventId = 0; so->onEventId = 0;
so->fullObjectSync = false;
so->maxUpdateRate = 0;
memset(so->extraFields, 0, sizeof(void*) * MAX_SYNC_OBJECT_FIELDS); 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) { void network_init_object_field(struct Object *o, void* field) {
assert(o->oSyncID != 0); assert(o->oSyncID != 0);
struct SyncObject* so = &syncObjects[o->oSyncID]; struct SyncObject* so = &syncObjects[o->oSyncID];
@ -55,6 +64,10 @@ void network_send_object(struct Object* o) {
packet_write(&p, &so->onEventId, 2); packet_write(&p, &so->onEventId, 2);
packet_write(&p, &so->behavior, sizeof(void*)); packet_write(&p, &so->behavior, sizeof(void*));
packet_write(&p, &o->activeFlags, 2); packet_write(&p, &o->activeFlags, 2);
if (so->fullObjectSync) {
packet_write(&p, o->rawData.asU32, 320);
} else {
packet_write(&p, &o->oPosX, 28); packet_write(&p, &o->oPosX, 28);
packet_write(&p, &o->oAction, 4); packet_write(&p, &o->oAction, 4);
packet_write(&p, &o->oSubAction, 4); packet_write(&p, &o->oSubAction, 4);
@ -68,8 +81,9 @@ void network_send_object(struct Object* o) {
assert(so->extraFields[i] != NULL); assert(so->extraFields[i] != NULL);
packet_write(&p, so->extraFields[i], 4); packet_write(&p, so->extraFields[i], 4);
} }
}
so->ticksSinceUpdate = 0; so->clockSinceUpdate = clock();
if (o->activeFlags == ACTIVE_FLAG_DEACTIVATED) { forget_sync_object(so); } if (o->activeFlags == ACTIVE_FLAG_DEACTIVATED) { forget_sync_object(so); }
@ -90,7 +104,7 @@ void network_receive_object(struct Packet* p) {
// retrieve SyncObject // retrieve SyncObject
struct SyncObject* so = &syncObjects[syncId]; struct SyncObject* so = &syncObjects[syncId];
so->ticksSinceUpdate = 0; so->clockSinceUpdate = clock();
// extract Object // extract Object
struct Object* o = syncObjects[syncId].o; struct Object* o = syncObjects[syncId].o;
@ -128,6 +142,10 @@ void network_receive_object(struct Packet* p) {
// write object flags // write object flags
packet_read(p, &o->activeFlags, 2); packet_read(p, &o->activeFlags, 2);
if (so->fullObjectSync) {
packet_read(p, o->rawData.asU32, 320);
} else {
packet_read(p, &o->oPosX, 28); packet_read(p, &o->oPosX, 28);
packet_read(p, &o->oAction, 4); packet_read(p, &o->oAction, 4);
packet_read(p, &o->oSubAction, 4); packet_read(p, &o->oSubAction, 4);
@ -135,6 +153,7 @@ void network_receive_object(struct Packet* p) {
packet_read(p, &o->oHeldState, 4); packet_read(p, &o->oHeldState, 4);
packet_read(p, &o->oMoveAngleYaw, 4); packet_read(p, &o->oMoveAngleYaw, 4);
packet_read(p, &o->oTimer, 4); packet_read(p, &o->oTimer, 4);
}
// write extra fields // write extra fields
u8 extraFields = 0; u8 extraFields = 0;
@ -172,7 +191,6 @@ bool should_own_object(struct SyncObject* so) {
void forget_sync_object(struct SyncObject* so) { void forget_sync_object(struct SyncObject* so) {
so->o = NULL; so->o = NULL;
so->owned = false; so->owned = false;
so->ticksSinceUpdate = -1;
} }
void network_update_objects(void) { void network_update_objects(void) {
@ -186,7 +204,6 @@ void network_update_objects(void) {
forget_sync_object(so); forget_sync_object(so);
continue; continue;
} }
so->ticksSinceUpdate++;
// check if we should be the one syncing this object // check if we should be the one syncing this object
so->owned = should_own_object(so); so->owned = should_own_object(so);
@ -201,9 +218,14 @@ void network_update_objects(void) {
float dist = player_distance(&gMarioStates[0], so->o); float dist = player_distance(&gMarioStates[0], so->o);
if (so->maxSyncDistance != SYNC_DISTANCE_INFINITE && dist > so->maxSyncDistance) { continue; } 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 (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); network_send_object(syncObjects[i].o);
} }