mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2025-12-02 14:12:39 +00:00
Cached network IDs for each area to prevent area swapping from assigning a different set of sync IDs
This commit is contained in:
parent
7c9b9a60d5
commit
9363de073f
4 changed files with 84 additions and 9 deletions
|
|
@ -227,6 +227,8 @@ void clear_areas(void) {
|
||||||
gAreaData[i].dialog[1] = 255;
|
gAreaData[i].dialog[1] = 255;
|
||||||
gAreaData[i].musicParam = 0;
|
gAreaData[i].musicParam = 0;
|
||||||
gAreaData[i].musicParam2 = 0;
|
gAreaData[i].musicParam2 = 0;
|
||||||
|
memset(gAreaData[i].cachedBehaviors, 0, sizeof(u8) * 256);
|
||||||
|
memset(gAreaData[i].cachedPositions, 0, sizeof(Vec3f) * 256);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,8 @@ struct Area
|
||||||
/*0x34*/ u8 dialog[2]; // Level start dialog number (set by level script cmd 0x30)
|
/*0x34*/ u8 dialog[2]; // Level start dialog number (set by level script cmd 0x30)
|
||||||
/*0x36*/ u16 musicParam;
|
/*0x36*/ u16 musicParam;
|
||||||
/*0x38*/ u16 musicParam2;
|
/*0x38*/ u16 musicParam2;
|
||||||
|
/*????*/ u8 cachedBehaviors[256];
|
||||||
|
/*????*/ Vec3f cachedPositions[256];
|
||||||
};
|
};
|
||||||
|
|
||||||
// All the transition data to be used in screen_transition.c
|
// All the transition data to be used in screen_transition.c
|
||||||
|
|
|
||||||
|
|
@ -39,8 +39,9 @@ void network_send_chat(char* message, u8 globalIndex) {
|
||||||
network_send(&p);
|
network_send(&p);
|
||||||
|
|
||||||
#ifdef DEVELOPMENT
|
#ifdef DEVELOPMENT
|
||||||
print_network_player_table();
|
//print_network_player_table();
|
||||||
reservation_area_debug();
|
//reservation_area_debug();
|
||||||
|
print_sync_object_table();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,42 @@ void forget_ent_reliable_packet(struct Object* o) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct DelayedPacketObject {
|
||||||
|
struct Packet p;
|
||||||
|
struct DelayedPacketObject* next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DelayedPacketObject* delayedPacketObjectHead = NULL;
|
||||||
|
struct DelayedPacketObject* delayedPacketObjectTail = NULL;
|
||||||
|
|
||||||
|
void network_delayed_packet_object_remember(struct Packet* p) {
|
||||||
|
struct DelayedPacketObject* node = malloc(sizeof(struct DelayedPacketObject));
|
||||||
|
packet_duplicate(p, &node->p);
|
||||||
|
node->next = NULL;
|
||||||
|
LOG_INFO("saving delayed object");
|
||||||
|
|
||||||
|
if (delayedPacketObjectHead == NULL) {
|
||||||
|
delayedPacketObjectHead = node;
|
||||||
|
delayedPacketObjectTail = node;
|
||||||
|
} else {
|
||||||
|
delayedPacketObjectTail->next = node;
|
||||||
|
delayedPacketObjectTail = node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void network_delayed_packet_object_execute(void) {
|
||||||
|
struct DelayedPacketObject* node = delayedPacketObjectHead;
|
||||||
|
while (node != NULL) {
|
||||||
|
struct DelayedPacketObject* next = node->next;
|
||||||
|
LOG_INFO("executing delayed object");
|
||||||
|
network_receive_object(&node->p);
|
||||||
|
free(node);
|
||||||
|
node = next;
|
||||||
|
}
|
||||||
|
delayedPacketObjectHead = NULL;
|
||||||
|
delayedPacketObjectTail = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// todo: move this to somewhere more general
|
// todo: move this to somewhere more general
|
||||||
static 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; }
|
if (marioState->marioObj == NULL) { return 0; }
|
||||||
|
|
@ -149,18 +185,42 @@ void network_clear_sync_objects(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u8 network_find_cached_sync_id(struct Object* o) {
|
||||||
|
u8 behaviorId = get_id_from_behavior(o->behavior);
|
||||||
|
for (int i = 1; i < 256; i++) {
|
||||||
|
if (gSyncObjects[i].o != NULL) { continue; }
|
||||||
|
u8 cachedBehaviorId = gCurrentArea->cachedBehaviors[i];
|
||||||
|
if (cachedBehaviorId != behaviorId) { continue; }
|
||||||
|
|
||||||
|
f32 dist = dist_between_object_and_point(o, gCurrentArea->cachedPositions[i][0], gCurrentArea->cachedPositions[i][1], gCurrentArea->cachedPositions[i][2]);
|
||||||
|
if (dist > 1) { continue; }
|
||||||
|
//LOG_INFO("get cached sync id for %02X: %d", behaviorId, i);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void network_set_sync_id(struct Object* o) {
|
void network_set_sync_id(struct Object* o) {
|
||||||
if (o->oSyncID != 0) { return; }
|
if (o->oSyncID != 0) { return; }
|
||||||
|
|
||||||
u8 syncId = 0;
|
u8 syncId = 0;
|
||||||
if (!gNetworkAreaLoaded) {
|
if (!gNetworkAreaLoaded) {
|
||||||
// while loading, just fill in sync ids from 1 to MAX_SYNC_OBJECTS
|
syncId = network_find_cached_sync_id(o);
|
||||||
for (int i = 1; i < MAX_SYNC_OBJECTS; i++) {
|
if (syncId == 0) {
|
||||||
sNextSyncId++;
|
// while loading, just fill in sync ids from 1 to MAX_SYNC_OBJECTS
|
||||||
sNextSyncId = sNextSyncId % RESERVED_IDS_SYNC_OBJECT_OFFSET;
|
for (int i = 1; i < MAX_SYNC_OBJECTS; i++) {
|
||||||
if (gSyncObjects[sNextSyncId].o != NULL) { continue; }
|
sNextSyncId++;
|
||||||
syncId = sNextSyncId;
|
sNextSyncId = sNextSyncId % RESERVED_IDS_SYNC_OBJECT_OFFSET;
|
||||||
break;
|
if (gSyncObjects[sNextSyncId].o != NULL) { continue; }
|
||||||
|
syncId = sNextSyncId;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// cache this object's id
|
||||||
|
gCurrentArea->cachedBehaviors[syncId] = get_id_from_behavior(o->behavior);
|
||||||
|
gCurrentArea->cachedPositions[syncId][0] = o->oPosX;
|
||||||
|
gCurrentArea->cachedPositions[syncId][1] = o->oPosY;
|
||||||
|
gCurrentArea->cachedPositions[syncId][2] = o->oPosZ;
|
||||||
|
//LOG_INFO("set cached sync id for %02X: %d", gCurrentArea->cachedBehaviors[syncId], syncId);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// no longer loading, require reserved id
|
// no longer loading, require reserved id
|
||||||
|
|
@ -480,6 +540,12 @@ void network_receive_object(struct Packet* p) {
|
||||||
// prevent receiving objects during credits sequence
|
// prevent receiving objects during credits sequence
|
||||||
if (gCurrActStarNum == 99) { return; }
|
if (gCurrActStarNum == 99) { return; }
|
||||||
|
|
||||||
|
// delay any objects received while we're loading the area
|
||||||
|
if (!gNetworkAreaLoaded) {
|
||||||
|
network_delayed_packet_object_remember(p);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// read the header and sanity check the packet
|
// read the header and sanity check the packet
|
||||||
u8 fromLocalIndex = 0;
|
u8 fromLocalIndex = 0;
|
||||||
struct SyncObject* so = packet_read_object_header(p, &fromLocalIndex);
|
struct SyncObject* so = packet_read_object_header(p, &fromLocalIndex);
|
||||||
|
|
@ -560,6 +626,10 @@ void network_forget_sync_object(struct SyncObject* so) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void network_update_objects(void) {
|
void network_update_objects(void) {
|
||||||
|
if (gNetworkAreaLoaded && delayedPacketObjectHead != NULL) {
|
||||||
|
network_delayed_packet_object_execute();
|
||||||
|
}
|
||||||
|
|
||||||
for (u32 i = 1; i < MAX_SYNC_OBJECTS; i++) {
|
for (u32 i = 1; i < MAX_SYNC_OBJECTS; i++) {
|
||||||
struct SyncObject* so = &gSyncObjects[i];
|
struct SyncObject* so = &gSyncObjects[i];
|
||||||
if (so->o == NULL) { continue; }
|
if (so->o == NULL) { continue; }
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue