Synchronize instant warps

This commit is contained in:
MysterD 2020-09-28 19:58:37 -07:00
parent 729103f0fc
commit a480b4c288
7 changed files with 138 additions and 13 deletions

View File

@ -375,6 +375,8 @@ struct MarioState
/*????*/ Vec4s* splineKeyframe;
/*????*/ float splineKeyframeFraction;
/*????*/ int splineState;
/*????*/ Vec3f nonInstantWarpPos;
};
#define PLAY_MODE_NORMAL 0

View File

@ -51,6 +51,7 @@
struct SavedWarpValues gReceiveWarp = { 0 };
u8 gControlledWarp = 0;
extern s8 sReceivedLoadedActNum;
u8 gRejectInstantWarp = 0;
#ifdef VERSION_JP
const char *credits01[] = { "1GAME DIRECTOR", "SHIGERU MIYAMOTO" };
@ -552,29 +553,43 @@ void check_instant_warp(void) {
s16 cameraAngle;
struct Surface *floor;
if (gRejectInstantWarp > 0) {
gRejectInstantWarp--;
}
if (gCurrLevelNum == LEVEL_CASTLE
&& save_file_get_total_star_count(gCurrSaveFileNum - 1, COURSE_MIN - 1, COURSE_MAX - 1) >= 70) {
return;
}
if ((floor = gMarioState->floor) != NULL) {
if ((floor = gMarioStates[0].floor) != NULL) {
s32 index = floor->type - SURFACE_INSTANT_WARP_1B;
if (index >= INSTANT_WARP_INDEX_START && index < INSTANT_WARP_INDEX_STOP
&& gCurrentArea->instantWarps != NULL) {
struct InstantWarp *warp = &gCurrentArea->instantWarps[index];
if (warp->id != 0) {
for (int i = 0; i < MAX_PLAYERS; i++) {
gMarioStates[i].pos[0] += warp->displacement[0];
gMarioStates[i].pos[1] += warp->displacement[1];
gMarioStates[i].pos[2] += warp->displacement[2];
if (gRejectInstantWarp > 0) {
vec3f_copy(gMarioStates[0].pos, gMarioStates[0].nonInstantWarpPos);
//vec3f_mul(gMarioStates[0].vel, -0.8f);
return;
}
u8 changeOfArea = (gCurrAreaIndex != warp->area);
gMarioStates[0].pos[0] += warp->displacement[0];
gMarioStates[0].pos[1] += warp->displacement[1];
gMarioStates[0].pos[2] += warp->displacement[2];
vec3f_copy(gMarioStates[0].nonInstantWarpPos, gMarioStates[0].pos);
gMarioStates[i].marioObj->oPosX = gMarioStates[i].pos[0];
gMarioStates[i].marioObj->oPosY = gMarioStates[i].pos[1];
gMarioStates[i].marioObj->oPosZ = gMarioStates[i].pos[2];
if (changeOfArea) {
for (int i = 0; i < MAX_PLAYERS; i++) {
gMarioStates[i].marioObj->oIntangibleTimer = 30;
}
}
cameraAngle = gMarioState->area->camera->yaw;
gMarioStates[0].marioObj->oPosX = gMarioStates[0].pos[0];
gMarioStates[0].marioObj->oPosY = gMarioStates[0].pos[1];
gMarioStates[0].marioObj->oPosZ = gMarioStates[0].pos[2];
cameraAngle = gMarioStates[0].area->camera->yaw;
change_area(warp->area);
for (int i = 0; i < MAX_PLAYERS; i++) {
@ -582,10 +597,17 @@ void check_instant_warp(void) {
}
warp_camera(warp->displacement[0], warp->displacement[1], warp->displacement[2]);
gMarioState->area->camera->yaw = cameraAngle;
gMarioStates[0].area->camera->yaw = cameraAngle;
if (changeOfArea) {
set_play_mode(PLAY_MODE_SYNC_LEVEL);
network_send_instant_warp();
}
return;
}
}
}
vec3f_copy(gMarioStates[0].nonInstantWarpPos, gMarioStates[0].pos);
}
s16 music_changed_through_warp(s16 arg) {

View File

@ -95,6 +95,7 @@ struct SavedWarpValues {
extern struct WarpDest sWarpDest;
extern s8 gInWarpCheckpoint;
extern u8 gRejectInstantWarp;
extern s16 D_80339EE0;
extern s16 sDelayedWarpOp;

View File

@ -20,8 +20,8 @@ static Gfx *sScreenTransitionVerticesPos[2];
static Vtx *sScreenTransitionVertices;
void reset_screen_transition_timers(void) {
memset(sTransitionColorFadeCount, 0, sizeof(u8) * 4);
memset(sTransitionTextureFadeCount, 0, sizeof(u16) * 2);
for (int i = 0; i < 4; i++) { sTransitionColorFadeCount[i] = 0; }
for (int i = 0; i < 2; i++) { sTransitionTextureFadeCount[i] = 0; }
}
void patch_screen_transition_interpolated(void) {

View File

@ -37,6 +37,7 @@ void packet_receive(struct Packet* p) {
case PACKET_KEEP_ALIVE: network_receive_keep_alive(p); break;
case PACKET_LEAVING: network_receive_leaving(p); break;
case PACKET_SAVE_FILE: network_receive_save_file(p); break;
case PACKET_INSTANT_WARP: network_receive_instant_warp(p); break;
///
case PACKET_CUSTOM: network_receive_custom(p); break;
default: LOG_ERROR("received unknown packet: %d", p->buffer[0]);

View File

@ -29,6 +29,7 @@ enum PacketType {
PACKET_KEEP_ALIVE,
PACKET_LEAVING,
PACKET_SAVE_FILE,
PACKET_INSTANT_WARP,
///
PACKET_CUSTOM = 255,
};
@ -150,4 +151,8 @@ void network_receive_leaving(struct Packet* p);
void network_send_save_file(s32 fileIndex);
void network_receive_save_file(struct Packet* p);
// packet_instant_warp.c
void network_send_instant_warp(void);
void network_receive_instant_warp(struct Packet* p);
#endif

View File

@ -0,0 +1,94 @@
#include <stdio.h>
#include "sm64.h"
#include "../network.h"
#include "engine/math_util.h"
#include "game/level_update.h"
#include "game/area.h"
#include "game/ingame_menu.h"
#define DISABLE_MODULE_LOG
#include "pc/debuglog.h"
extern u8 gRejectInstantWarp;
static u8 seqId = 0;
static u8 remoteLastSeqId = (u8)-1;
#pragma pack(1)
struct PacketInstantWarpData {
u8 seqId;
Vec3f pos;
s16 areaIndex;
s16 yaw;
};
static void populate_packet_data(struct PacketInstantWarpData* data) {
data->seqId = seqId;
data->pos[0] = gMarioStates[0].pos[0];
data->pos[1] = gMarioStates[0].pos[1];
data->pos[2] = gMarioStates[0].pos[2];
data->yaw = gMarioStates[0].faceAngle[1];
data->areaIndex = gCurrAreaIndex;
}
void network_send_instant_warp(void) {
struct PacketInstantWarpData data = { 0 };
populate_packet_data(&data);
struct Packet p;
packet_init(&p, PACKET_INSTANT_WARP, true, false);
packet_write(&p, &data, sizeof(struct PacketInstantWarpData));
network_send(&p);
LOG_INFO("tx %d", data.areaIndex);
gRejectInstantWarp = 120;
seqId++;
}
void network_receive_instant_warp(struct Packet* p) {
struct PacketInstantWarpData remote = { 0 };
packet_read(p, &remote, sizeof(struct PacketInstantWarpData));
// de-dup
if (remote.seqId == remoteLastSeqId) {
LOG_INFO("we've seen this packet, escape!");
return;
}
remoteLastSeqId = remote.seqId;
LOG_INFO("rx instant warp");
if (gCurrAreaIndex == remote.areaIndex) {
if (sCurrPlayMode == PLAY_MODE_SYNC_LEVEL) { sCurrPlayMode = PLAY_MODE_NORMAL; }
LOG_INFO("instant warp done %d", remote.areaIndex);
return;
}
gMarioStates[0].pos[0] = remote.pos[0];
gMarioStates[0].pos[1] = remote.pos[1];
gMarioStates[0].pos[2] = remote.pos[2];
vec3f_copy(gMarioStates[0].nonInstantWarpPos, gMarioStates[0].pos);
gMarioStates[0].marioObj->oPosX = gMarioStates[0].pos[0];
gMarioStates[0].marioObj->oPosY = gMarioStates[0].pos[1];
gMarioStates[0].marioObj->oPosZ = gMarioStates[0].pos[2];
/*gMarioStates[0].faceAngle[1] = remote.yaw;
gMarioStates[0].intendedYaw = remote.yaw;
gMarioStates[0].marioObj->oMoveAngleYaw = remote.yaw;
gMarioStates[0].marioObj->oFaceAngleYaw = remote.yaw;*/
for (int i = 0; i < MAX_PLAYERS; i++) {
gMarioStates[i].marioObj->oIntangibleTimer = 30;
}
//s16 cameraAngle = gMarioStates[0].area->camera->yaw;
change_area(remote.areaIndex);
for (int i = 0; i < MAX_PLAYERS; i++) { gMarioStates[i].area = gCurrentArea; }
//warp_camera(warp->displacement[0], warp->displacement[1], warp->displacement[2]);
//gMarioStates[0].area->camera->yaw = cameraAngle;
LOG_INFO("instant warp applied %d", remote.areaIndex);
network_send_instant_warp();
}