diff --git a/port/include/net/net.h b/port/include/net/net.h index a67a35c3f..d4c848a5f 100644 --- a/port/include/net/net.h +++ b/port/include/net/net.h @@ -62,9 +62,10 @@ struct netplayermove { u32 ucmd; // player commands (UCMD_) f32 leanofs; // analog lean value (-1 .. 1; equal to player->swaytarget / 75.f) f32 crouchofs; // analog crouch value (-90 for SQUAT, 0 for STAND; player->crouchofs) + f32 zoomfov; // manual zoom fov for the current gun; synced only if UCMD_AIMING is set f32 movespeed[2]; // move inputs, [0] is forward, [1] is sideways; used mostly for animation f32 angles[2]; // view angles, [0] is theta, [1] is verta - f32 crosspos[2]; // crosshair position in aiming mode + f32 crosspos[2]; // crosshair position in aiming mode; normalized to default aspect ratio s8 weaponnum; // switch to this weapon if UCMD_SELECT is set struct coord pos; // player position at g_NetTick == tick }; @@ -80,6 +81,8 @@ struct netclient { u8 headnum; u8 bodynum; u8 team; + f32 fovy; + f32 fovzoommult; } settings; struct mpplayerconfig *config; diff --git a/port/src/net/net.c b/port/src/net/net.c index 5506a8851..07a1ee0c7 100644 --- a/port/src/net/net.c +++ b/port/src/net/net.c @@ -15,6 +15,7 @@ #include "game/playermgr.h" #include "game/bondgun.h" #include "game/game_1531a0.h" +#include "game/game_0b0fd0.h" #include "lib/main.h" #include "lib/vi.h" #include "config.h" @@ -191,14 +192,23 @@ static inline void netClientRecordMove(struct netclient *cl, const struct player move->angles[0] = pl->vv_theta; move->angles[1] = pl->vv_verta; move->pos = (pl->prop) ? pl->prop->pos : pl->cam_pos; + move->crosspos[0] = pl->crosspos[0]; move->crosspos[1] = pl->crosspos[1]; + if (!pl->isremote) { + // normalize crosspos x + move->crosspos[0] -= (f32)(SCREEN_WIDTH_LO / 2); + move->crosspos[0] = (f32)(SCREEN_WIDTH_LO / 2) + move->crosspos[0] * pl->aspect / SCREEN_ASPECT; + } + move->ucmd = pl->ucmd; if (g_NetMode == NETMODE_SERVER && pl->isremote && cl->inmove[0].tick) { // carry some of the client inputs over to the outmove move->ucmd |= (cl->inmove[0].ucmd & (UCMD_FIRE | UCMD_RELOAD | UCMD_AIMMODE | UCMD_EYESSHUT | UCMD_SELECT | UCMD_SELECT_DUAL)); + move->crosspos[0] = cl->inmove[0].crosspos[0]; + move->crosspos[1] = cl->inmove[0].crosspos[1]; } if (pl->crouchpos == CROUCHPOS_DUCK) { @@ -228,6 +238,13 @@ static inline void netClientRecordMove(struct netclient *cl, const struct player move->ucmd |= UCMD_SECONDARY; } + if (pl->insightaimmode) { + move->ucmd |= UCMD_AIMMODE; + move->zoomfov = currentPlayerGetGunZoomFov(); + } else { + move->zoomfov = 0.f; + } + setCurrentPlayerNum(oldnum); if (cl != g_NetLocalClient && !cl->forcetick && (move->ucmd & UCMD_FL_FORCEMASK)) { @@ -328,6 +345,8 @@ s32 netStartServer(u16 port, s32 maxclients) g_NetLocalClient->state = CLSTATE_LOBBY; // local client doesn't need auth g_NetLocalClient->settings.bodynum = g_PlayerConfigsArray[0].base.mpbodynum; g_NetLocalClient->settings.headnum = g_PlayerConfigsArray[0].base.mpheadnum; + g_NetLocalClient->settings.fovy = g_PlayerExtCfg[0].fovy; + g_NetLocalClient->settings.fovzoommult = g_PlayerExtCfg[0].fovzoommult; memcpy(g_NetLocalClient->settings.name, g_PlayerConfigsArray[0].base.name, sizeof(g_NetLocalClient->settings.name)); // the \n will be readded in the playerconfig char *newline = strrchr(g_NetLocalClient->settings.name, '\n'); @@ -432,6 +451,8 @@ s32 netStartClient(const char *addr) g_NetLocalClient->state = CLSTATE_CONNECTING; g_NetLocalClient->settings.bodynum = g_PlayerConfigsArray[0].base.mpbodynum; g_NetLocalClient->settings.headnum = g_PlayerConfigsArray[0].base.mpheadnum; + g_NetLocalClient->settings.fovy = g_PlayerExtCfg[0].fovy; + g_NetLocalClient->settings.fovzoommult = g_PlayerExtCfg[0].fovzoommult; memcpy(g_NetLocalClient->settings.name, g_PlayerConfigsArray[0].base.name, sizeof(g_NetLocalClient->settings.name)); // the \n will be readded in the playerconfig char *newline = strrchr(g_NetLocalClient->settings.name, '\n'); diff --git a/port/src/net/netmsg.c b/port/src/net/netmsg.c index 42cfd155f..56c98a67d 100644 --- a/port/src/net/netmsg.c +++ b/port/src/net/netmsg.c @@ -79,6 +79,9 @@ static inline u32 netbufWritePlayerMove(struct netbuf *buf, const struct netplay netbufWriteF32(buf, in->crosspos[1]); netbufWriteS8(buf, in->weaponnum); netbufWriteCoord(buf, &in->pos); + if (in->ucmd & UCMD_AIMMODE) { + netbufWriteF32(buf, in->zoomfov); + } return buf->error; } @@ -96,6 +99,11 @@ static inline u32 netbufReadPlayerMove(struct netbuf *buf, struct netplayermove in->crosspos[1] = netbufReadF32(buf); in->weaponnum = netbufReadS8(buf); netbufReadCoord(buf, &in->pos); + if (in->ucmd & UCMD_AIMMODE) { + in->zoomfov = netbufReadF32(buf); + } else { + in->zoomfov = 0.f; + } return buf->error; } @@ -151,6 +159,8 @@ u32 netmsgClcAuthWrite(struct netbuf *dst) netbufWriteU8(dst, 1); // TODO: number of local players netbufWriteU8(dst, g_NetLocalClient->settings.bodynum); netbufWriteU8(dst, g_NetLocalClient->settings.headnum); + netbufWriteF32(dst, g_NetLocalClient->settings.fovy); + netbufWriteF32(dst, g_NetLocalClient->settings.fovzoommult); netbufWriteStr(dst, g_NetLocalClient->settings.name); return dst->error; @@ -168,6 +178,8 @@ u32 netmsgClcAuthRead(struct netbuf *src, struct netclient *srccl) const u8 players = netbufReadU8(src); const u8 bodynum = netbufReadU8(src); const u8 headnum = netbufReadU8(src); + const f32 fovy = netbufReadF32(src); + const f32 fovzoommult = netbufReadF32(src); char *name = netbufReadStr(src); if (src->error) { @@ -196,6 +208,8 @@ u32 netmsgClcAuthRead(struct netbuf *src, struct netclient *srccl) strncpy(srccl->settings.name, name, sizeof(srccl->settings.name) - 1); srccl->settings.bodynum = bodynum; srccl->settings.headnum = headnum; + srccl->settings.fovy = fovy; + srccl->settings.fovzoommult = fovzoommult; srccl->state = CLSTATE_LOBBY; sysLogPrintf(LOG_NOTE, "NET: CLC_AUTH from %s (%s), responding", netFormatClientAddr(srccl), srccl->settings.name); @@ -382,6 +396,8 @@ u32 netmsgSvcStageStartWrite(struct netbuf *dst) netbufWriteU8(dst, ncl->settings.team); netbufWriteU8(dst, ncl->settings.bodynum); netbufWriteU8(dst, ncl->settings.headnum); + netbufWriteF32(dst, ncl->settings.fovy); + netbufWriteF32(dst, ncl->settings.fovzoommult); netbufWriteStr(dst, ncl->settings.name); memset(ncl->inmove, 0, sizeof(ncl->inmove)); memset(ncl->outmove, 0, sizeof(ncl->outmove)); @@ -445,6 +461,8 @@ u32 netmsgSvcStageStartRead(struct netbuf *src, struct netclient *srccl) ncl->id = id; ncl->settings.bodynum = netbufReadU8(src); ncl->settings.headnum = netbufReadU8(src); + ncl->settings.fovy = netbufReadF32(src); + ncl->settings.fovzoommult = netbufReadF32(src); char *name = netbufReadStr(src); if (name) { strncpy(ncl->settings.name, name, sizeof(ncl->settings.name) - 1); @@ -456,6 +474,8 @@ u32 netmsgSvcStageStartRead(struct netbuf *src, struct netclient *srccl) // skip our own settings except for the team netbufReadU8(src); netbufReadU8(src); + netbufReadF32(src); + netbufReadF32(src); netbufReadStr(src); } ncl->state = CLSTATE_GAME; diff --git a/src/game/bondmove.c b/src/game/bondmove.c index 73c0752c3..b5f45cf47 100644 --- a/src/game/bondmove.c +++ b/src/game/bondmove.c @@ -148,6 +148,36 @@ static inline void bmoveProcessRemoteInput(const bool allowc1buttons) pl->crosspos[0] = inmove->crosspos[0]; pl->crosspos[1] = inmove->crosspos[1]; + // denormalize crosspos x + pl->crosspos[0] -= (f32)(SCREEN_WIDTH_LO / 2); + pl->crosspos[0] = (f32)(SCREEN_WIDTH_LO / 2) + pl->crosspos[0] / pl->aspect * SCREEN_ASPECT; + + pl->crosspos2[0] = pl->crosspos[0]; + pl->crosspos2[1] = pl->crosspos[1]; + + pl->insightaimmode = (inmove->ucmd & UCMD_AIMMODE) != 0; + if (pl->insightaimmode) { + pl->gunzoomfovs[0] = pl->gunzoomfovs[1] = pl->gunzoomfovs[2] = inmove->zoomfov; + } + + f32 zoomfov = 0.f; + if (pl->insightaimmode) { + zoomfov = currentPlayerGetGunZoomFov(); + } + if (bgunGetWeaponNum(HAND_RIGHT) == WEAPON_AR34 && pl->hands[HAND_RIGHT].gset.weaponfunc == FUNC_SECONDARY) { + zoomfov = currentPlayerGetGunZoomFov(); + } + if (zoomfov <= 0.f) { + zoomfov = pl->client->settings.fovy; + } + playerTweenFovY(zoomfov); + playerUpdateZoom(); + + for (s32 h = 0; h < 2; ++h) { + pl->hands[h].crosspos[0] = pl->crosspos[0]; + pl->hands[h].crosspos[1] = pl->crosspos[1]; + } + if (inmove->ucmd & UCMD_SELECT) { pl->gunctrl.dualwielding = (inmove->ucmd & UCMD_SELECT_DUAL) != 0; if (inmove->weaponnum >= 0) { @@ -155,9 +185,6 @@ static inline void bmoveProcessRemoteInput(const bool allowc1buttons) } } - const bool fireguns = (inmove->ucmd & UCMD_FIRE) && - !g_Vars.currentplayer->waitforzrelease && allowc1buttons; - if ((inmove->ucmd & UCMD_SECONDARY) && !bgunIsUsingSecondaryFunction()) { bgunConsiderToggleGunFunction(0, false, false, true); } else if (!(inmove->ucmd & UCMD_SECONDARY) && bgunIsUsingSecondaryFunction()) { @@ -167,6 +194,8 @@ static inline void bmoveProcessRemoteInput(const bool allowc1buttons) } } + const bool fireguns = (inmove->ucmd & UCMD_FIRE) && !pl->waitforzrelease && allowc1buttons; + bgunTickGameplay(fireguns); if (fireguns && g_NetMode == NETMODE_SERVER) { @@ -194,7 +223,7 @@ static inline void bmoveProcessRemoteInput(const bool allowc1buttons) } } - bgunSetSightVisible(GUNSIGHTREASON_NOTAIMING, (inmove->ucmd & UCMD_AIMMODE) != 0); + bgunSetSightVisible(GUNSIGHTREASON_NOTAIMING, pl->insightaimmode); const bool forcepos = !inmoveprev->tick || !moveticks || (inmove->ucmd & UCMD_FL_FORCEANGLE); diff --git a/src/game/game_0b0fd0.c b/src/game/game_0b0fd0.c index 8c7953ccf..5293e8500 100644 --- a/src/game/game_0b0fd0.c +++ b/src/game/game_0b0fd0.c @@ -167,7 +167,7 @@ f32 func0f0b131c(s32 hand) weapon = weaponFindById(bgunGetWeaponNum2(0)); x = weapon->posx; - if (PLAYERCOUNT() == 2 && optionsGetScreenSplit() == SCREENSPLIT_VERTICAL) { + if (LOCALPLAYERCOUNT() == 2 && optionsGetScreenSplit() == SCREENSPLIT_VERTICAL) { x -= 3.5f; if (g_Vars.currentplayernum == 0) { @@ -178,7 +178,7 @@ f32 func0f0b131c(s32 hand) weapon = weaponFindById(bgunGetWeaponNum2(1)); x = -weapon->posx; - if (PLAYERCOUNT() == 2 && optionsGetScreenSplit() == SCREENSPLIT_VERTICAL) { + if (LOCALPLAYERCOUNT() == 2 && optionsGetScreenSplit() == SCREENSPLIT_VERTICAL) { x += 3.5f; if (g_Vars.currentplayernum == 0) { diff --git a/src/game/player.c b/src/game/player.c index 0c1352b57..3f63da803 100644 --- a/src/game/player.c +++ b/src/game/player.c @@ -5862,6 +5862,32 @@ struct sndstate *playerSndStart(s32 arg0, s16 sound, struct sndstate **handle, s return sndStart(arg0, sound, handle, vol, pan, pitch, fxbus, fxmix); } +#ifndef PLATFORM_N64 + +f32 playerGetDefaultFovY(s32 playernum) +{ + if (g_NetMode) { + const struct player *pl = g_Vars.players[playernum % MAX_PLAYERS]; + if (pl && pl->client) { + return pl->client->settings.fovy; + } + } + return g_PlayerExtCfg[playernum % MAX_LOCAL_PLAYERS].fovy; +} + +f32 playerGetZoomFovMult(s32 playernum) +{ + if (g_NetMode) { + const struct player *pl = g_Vars.players[playernum % MAX_PLAYERS]; + if (pl && pl->client) { + return pl->client->settings.fovzoommult; + } + } + return g_PlayerExtCfg[playernum % MAX_LOCAL_PLAYERS].fovzoommult; +} + +#endif + #if MAX_PLAYERS > 4 s32 playerGetCount(void) diff --git a/src/include/data.h b/src/include/data.h index 0ccf08cbe..535d3773c 100644 --- a/src/include/data.h +++ b/src/include/data.h @@ -556,10 +556,10 @@ extern s32 g_BgunGeMuzzleFlashes; extern s32 g_NetMode; #define PLAYER_EXTCFG() g_PlayerExtCfg[g_Vars.currentplayerstats->mpindex & 3] -#define PLAYER_DEFAULT_FOV (PLAYER_EXTCFG().fovy) +#define PLAYER_DEFAULT_FOV playerGetDefaultFovY(g_Vars.currentplayerstats->mpindex) +#define ADJUST_ZOOM_FOV(x) ((x) * playerGetZoomFovMult(g_Vars.currentplayerstats->mpindex)) #define TEX_FILTER_2D g_TexFilter2D -#define ADJUST_ZOOM_FOV(x) ((x) * PLAYER_EXTCFG().fovzoommult) s32 playerGetCount(void); diff --git a/src/include/game/player.h b/src/include/game/player.h index 6c84f2e56..21f12d0cf 100644 --- a/src/include/game/player.h +++ b/src/include/game/player.h @@ -106,7 +106,15 @@ void playerSetCamPropertiesWithRoom(struct coord *pos, struct coord *up, struct void playerSetCamPropertiesWithoutRoom(struct coord *pos, struct coord *up, struct coord *look, s32 room); void playerSetCamProperties(struct coord *pos, struct coord *up, struct coord *look, s32 room); void playerClearMemCamRoom(void); -s32 playerGetCount(void); struct sndstate *playerSndStart(s32 arg0, s16 sound, struct sndstate **handle, s32 playernum, f32 pitch, s32 fxbus, s32 fxmix); +#if MAX_PLAYERS > 4 +s32 playerGetCount(void); +#endif + +#ifndef PLATFORM_N64 +f32 playerGetDefaultFovY(s32 playernum); +f32 playerGetZoomFovMult(s32 playernum); +#endif + #endif