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) {
o->oCheckerBoardPlatformUnkFC = o->parentObj->oBehParams2ndByte;
network_init_object(o, 1000.0f);
network_object_settings(o, TRUE, 5.0f);
}
void bhv_checkerboard_platform_loop(void) {

View File

@ -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);

View File

@ -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);
}