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:
parent
e0b86b7d59
commit
e86efb9e85
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue