diff --git a/doomsday/engine/api/dd_share.h b/doomsday/engine/api/dd_share.h index 8528aa0a9b..05e0111d0c 100644 --- a/doomsday/engine/api/dd_share.h +++ b/doomsday/engine/api/dd_share.h @@ -282,14 +282,11 @@ enum { DD_OPENTOP, DD_OPENBOTTOM, DD_LOWFLOOR, - DD_VIEWX, - DD_VIEWY, - DD_VIEWZ, - DD_VIEWX_OFFSET, - DD_VIEWY_OFFSET, - DD_VIEWZ_OFFSET, - DD_VIEWANGLE, - DD_VIEWANGLE_OFFSET, + DD_VIEW_X, + DD_VIEW_Y, + DD_VIEW_Z, + DD_VIEW_ANGLE, + DD_VIEW_PITCH, DD_CPLAYER_THRUST_MUL, DD_GRAVITY, DD_PSPRITE_OFFSET_X, // 10x @@ -1331,9 +1328,6 @@ typedef struct ticcmd_s { typedef struct ddplayer_s { ticcmd_t cmd; struct mobj_s* mo; // Pointer to a (game specific) mobj. - float viewZ; // Focal origin above r.z. - float viewHeight; // Base height above floor for viewZ. - float viewHeightDelta; float lookDir; // For mouse look. int fixedColorMap; // Can be set to REDCOLORMAP, etc. int extraLight; // So gun flashes light up areas. diff --git a/doomsday/engine/portable/include/r_main.h b/doomsday/engine/portable/include/r_main.h index 02a7ee666c..0f2303178e 100644 --- a/doomsday/engine/portable/include/r_main.h +++ b/doomsday/engine/portable/include/r_main.h @@ -34,27 +34,37 @@ typedef struct viewport_s { int x, y, width, height; } viewport_t; -extern float viewX, viewY, viewZ; -extern float viewFrontVec[3], viewUpVec[3], viewSideVec[3]; -extern float viewXOffset, viewYOffset, viewZOffset; -extern angle_t viewAngle; -extern float viewPitch; -extern angle_t clipAngle; -extern fixed_t fineTangent[FINEANGLES / 2]; +typedef struct viewer_s { + float pos[3]; + angle_t angle; + float pitch; +} viewer_t; + +typedef struct viewdata_s { + viewer_t current; // Current view paramaters. + viewer_t lastSharp[2]; // For smoothing. + float frontVec[3], upVec[3], sideVec[3]; + float viewCos, viewSin; + + // These are used when camera smoothing is disabled. + angle_t frozenAngle; + float frozenPitch; +} viewdata_t; + +extern float viewX, viewY, viewZ, viewPitch; +extern int viewAngle; extern float frameTimePos; // 0...1: fractional part for sharp game tics -extern boolean resyncFrameTimePos; extern int loadInStartupMode; extern int validCount; extern int viewwidth, viewheight, viewwindowx, viewwindowy; -extern boolean setSizeNeeded; extern int frameCount; -extern int viewAngleOffset; extern int extraLight; extern float extraLightDelta; -extern float viewCos, viewSin; extern int rendInfoTris; +extern fixed_t fineTangent[FINEANGLES / 2]; + void R_Register(void); void R_Init(void); void R_Update(void); @@ -64,7 +74,10 @@ void R_EndWorldFrame(void); void R_RenderPlayerView(int num); void R_RenderPlayerViewBorder(void); void R_RenderViewPorts(void); + +const viewdata_t* R_ViewData(int localPlayerNum); void R_ResetViewer(void); + void R_SetViewWindow(int x, int y, int w, int h); void R_NewSharpWorld(void); diff --git a/doomsday/engine/portable/include/r_util.h b/doomsday/engine/portable/include/r_util.h index 9bee2e6df9..fc2eebe75d 100644 --- a/doomsday/engine/portable/include/r_util.h +++ b/doomsday/engine/portable/include/r_util.h @@ -32,8 +32,8 @@ int R_PointOnSide(const float x, const float y, const partition_t* par); angle_t R_PointToAngle(float x, float y); -angle_t R_PointToAngle2(const float x1, const float y1, - const float x2, const float y2); +angle_t R_PointToAngle2(float x1, float y1, + float x2, float y2); float R_PointToDist(const float x, const float y); linedef_t* R_GetLineForSide(const uint sideIDX); subsector_t* R_PointInSubsector(const float x, const float y); diff --git a/doomsday/engine/portable/src/cl_player.c b/doomsday/engine/portable/src/cl_player.c index b333799d81..a60018d8aa 100644 --- a/doomsday/engine/portable/src/cl_player.c +++ b/doomsday/engine/portable/src/cl_player.c @@ -582,12 +582,10 @@ void Cl_MoveLocalPlayer(float dx, float dy, float z, boolean onground) if(onground) { mo->pos[VZ] = z - 1; - ddpl->viewHeight = 1; } else { mo->pos[VZ] = z; - ddpl->viewHeight = 0; } Cl_UpdatePlayerPos(consolePlayer); diff --git a/doomsday/engine/portable/src/dd_main.c b/doomsday/engine/portable/src/dd_main.c index 29f022e33c..9df3548853 100644 --- a/doomsday/engine/portable/src/dd_main.c +++ b/doomsday/engine/portable/src/dd_main.c @@ -960,29 +960,20 @@ void* DD_GetVariable(int ddvalue) case DD_GAME_EXPORTS: return &gx; - case DD_VIEWX: + case DD_VIEW_X: return &viewX; - case DD_VIEWY: + case DD_VIEW_Y: return &viewY; - case DD_VIEWZ: + case DD_VIEW_Z: return &viewZ; - case DD_VIEWX_OFFSET: - return &viewXOffset; - - case DD_VIEWY_OFFSET: - return &viewYOffset; - - case DD_VIEWZ_OFFSET: - return &viewZOffset; - - case DD_VIEWANGLE: + case DD_VIEW_ANGLE: return &viewAngle; - case DD_VIEWANGLE_OFFSET: - return &viewAngleOffset; + case DD_VIEW_PITCH: + return &viewPitch; case DD_SECTOR_COUNT: return &numSectors; @@ -1149,36 +1140,24 @@ void DD_SetVariable(int ddvalue, void *parm) { switch(ddvalue) { - case DD_VIEWX: + case DD_VIEW_X: viewX = *(float*) parm; return; - case DD_VIEWY: + case DD_VIEW_Y: viewY = *(float*) parm; return; - case DD_VIEWZ: + case DD_VIEW_Z: viewZ = *(float*) parm; return; - case DD_VIEWX_OFFSET: - viewXOffset = *(float*) parm; - return; - - case DD_VIEWY_OFFSET: - viewYOffset = *(float*) parm; - return; - - case DD_VIEWZ_OFFSET: - viewZOffset = *(float*) parm; - return; - - case DD_VIEWANGLE: + case DD_VIEW_ANGLE: viewAngle = *(angle_t*) parm; return; - case DD_VIEWANGLE_OFFSET: - viewAngleOffset = *(int*) parm; + case DD_VIEW_PITCH: + viewPitch = *(float*) parm; return; case DD_CPLAYER_THRUST_MUL: diff --git a/doomsday/engine/portable/src/edit_bias.c b/doomsday/engine/portable/src/edit_bias.c index b65e071806..5427b97c39 100644 --- a/doomsday/engine/portable/src/edit_bias.c +++ b/doomsday/engine/portable/src/edit_bias.c @@ -145,9 +145,10 @@ void SBE_Register(void) static void SBE_GetHand(float pos[3]) { - pos[0] = vx + viewFrontVec[VX] * editDistance; - pos[1] = vz + viewFrontVec[VZ] * editDistance; - pos[2] = vy + viewFrontVec[VY] * editDistance; + const viewdata_t* viewData = R_ViewData(viewPlayer - ddPlayers); + pos[0] = vx + viewData->frontVec[VX] * editDistance; + pos[1] = vz + viewData->frontVec[VZ] * editDistance; + pos[2] = vy + viewData->frontVec[VY] * editDistance; } static source_t *SBE_GrabSource(int index) @@ -200,13 +201,14 @@ static source_t *SBE_GetNearest(void) static void SBE_GetHueColor(float *color, float *angle, float *sat) { - int i; - float dot; - float saturation, hue, scale; - float minAngle = 0.1f, range = 0.19f; - vec3_t h, proj; - - dot = M_DotProduct(viewFrontVec, hueOrigin); + int i; + float dot; + float saturation, hue, scale; + float minAngle = 0.1f, range = 0.19f; + vec3_t h, proj; + const viewdata_t* viewData = R_ViewData(viewPlayer - ddPlayers); + + dot = M_DotProduct(viewData->frontVec, hueOrigin); saturation = (acos(dot) - minAngle) / range; if(saturation < 0) @@ -229,12 +231,12 @@ static void SBE_GetHueColor(float *color, float *angle, float *sat) // Calculate hue angle by projecting the current viewfront to the // hue circle plane. Project onto the normal and subtract. - scale = M_DotProduct(viewFrontVec, hueOrigin) / + scale = M_DotProduct(viewData->frontVec, hueOrigin) / M_DotProduct(hueOrigin, hueOrigin); M_Scale(h, hueOrigin, scale); for(i = 0; i < 3; ++i) - proj[i] = viewFrontVec[i] - h[i]; + proj[i] = viewData->frontVec[i] - h[i]; // Now we have the projected view vector on the circle's plane. // Normalize the projected vector. @@ -439,7 +441,7 @@ void SBE_MenuSave(ui_object_t *ob) void SBE_SetHueCircle(boolean activate) { - int i; + int i; if((signed) activate == editHueCircle) return; // No change in state. @@ -451,12 +453,14 @@ void SBE_SetHueCircle(boolean activate) if(activate) { + const viewdata_t* viewData = R_ViewData(viewPlayer - ddPlayers); + // Determine the orientation of the hue circle. for(i = 0; i < 3; ++i) { - hueOrigin[i] = viewFrontVec[i]; - hueSide[i] = viewSideVec[i]; - hueUp[i] = viewUpVec[i]; + hueOrigin[i] = viewData->frontVec[i]; + hueSide[i] = viewData->sideVec[i]; + hueUp[i] = viewData->upVec[i]; } } } diff --git a/doomsday/engine/portable/src/m_misc.c b/doomsday/engine/portable/src/m_misc.c index 31c15f8ab8..395332e18d 100644 --- a/doomsday/engine/portable/src/m_misc.c +++ b/doomsday/engine/portable/src/m_misc.c @@ -54,6 +54,8 @@ #include "de_graphics.h" #include "de_refresh.h" #include "de_misc.h" +#include "de_play.h" + #include "lzss.h" // MACROS ------------------------------------------------------------------ @@ -709,20 +711,21 @@ void M_ProjectViewRelativeLine2D(const float center[2], float width, float offset, float start[2], float end[2]) { - float sinrv, cosrv; + const viewdata_t* viewData = R_ViewData(viewPlayer - ddPlayers); + float sinrv, cosrv; if(alignToViewPlane) { // Should be fully aligned to view plane. - sinrv = -viewCos; - cosrv = viewSin; + sinrv = -viewData->viewCos; + cosrv = viewData->viewSin; } else { - float trx, try, thangle; + float trx, try, thangle; // Transform the origin point. - trx = center[VX] - viewX; - try = center[VY] - viewY; + trx = center[VX] - viewData->current.pos[VX]; + try = center[VY] - viewData->current.pos[VY]; thangle = BANG2RAD(bamsAtan2(try * 10, trx * 10)) - PI / 2; sinrv = sin(thangle); diff --git a/doomsday/engine/portable/src/net_demo.c b/doomsday/engine/portable/src/net_demo.c index 1c7e1b1d20..29b109febb 100644 --- a/doomsday/engine/portable/src/net_demo.c +++ b/doomsday/engine/portable/src/net_demo.c @@ -445,12 +445,13 @@ Con_Printf("RDP: pt=%i ang=%i ld=%i len=%i type=%i\n", ptime, */ void Demo_WriteLocalCamera(int plrNum) { - player_t *plr = &ddPlayers[plrNum]; - ddplayer_t *ddpl = &plr->shared; - mobj_t *mo = ddpl->mo; - fixed_t x, y, z; - byte flags; - boolean incfov = (writeInfo[plrNum].fov != fieldOfView); + player_t* plr = &ddPlayers[plrNum]; + ddplayer_t* ddpl = &plr->shared; + mobj_t* mo = ddpl->mo; + fixed_t x, y, z; + byte flags; + boolean incfov = (writeInfo[plrNum].fov != fieldOfView); + const viewdata_t* viewData = R_ViewData(plrNum); if(!mo) return; @@ -474,8 +475,7 @@ void Demo_WriteLocalCamera(int plrNum) Msg_WriteShort(y >> 16); Msg_WriteByte(y >> 8); - //z = mo->pos[VZ] + ddpl->viewheight; - z = FLT2FIX(ddpl->viewZ); + z = FLT2FIX(mo->pos[VZ] + viewData->current.pos[VZ]); Msg_WriteShort(z >> 16); Msg_WriteByte(z >> 8); @@ -577,7 +577,6 @@ void Demo_ReadLocalCamera(void) R_ResetViewer(); demoFrameZ = z; Cl_MoveLocalPlayer(posDelta[VX], posDelta[VY], z, demoOnGround); - pl->viewZ = z; // Might get an unsynced frame is not set right now. posDelta[VX] = posDelta[VY] = posDelta[VZ] = 0; } } diff --git a/doomsday/engine/portable/src/p_mobj.c b/doomsday/engine/portable/src/p_mobj.c index d71d9f33e1..4d2e57bed9 100644 --- a/doomsday/engine/portable/src/p_mobj.c +++ b/doomsday/engine/portable/src/p_mobj.c @@ -924,14 +924,6 @@ void P_MobjZMovement(mobj_t *mo) { float gravity = FIX2FLT(mapGravity); - // check for smooth step up - if(mo->dPlayer && mo->pos[VZ] < mo->floorZ) - { - mo->dPlayer->viewHeight -= mo->floorZ - mo->pos[VZ]; - mo->dPlayer->viewHeightDelta = - (41 - mo->dPlayer->viewHeight) / 8; - } - // Adjust height. mo->pos[VZ] += mo->mom[MZ]; @@ -940,15 +932,6 @@ void P_MobjZMovement(mobj_t *mo) { if(mo->mom[MZ] < 0) { - if(mo->dPlayer && mo->mom[MZ] < -gravity * 8) - { - /** - * Decrease viewheight for a moment after hitting the ground - * (hard), and utter appropriate sound. - */ - mo->dPlayer->viewHeightDelta = mo->mom[MZ] / 8; - } - mo->mom[MZ] = 0; } @@ -962,15 +945,6 @@ void P_MobjZMovement(mobj_t *mo) // Hit the floor. if(mo->mom[MZ] < 0) { - if(mo->dPlayer && mo->mom[MZ] < -gravity * 8) - { - /** - * Decrease viewheight for a moment after hitting the ground - * (hard), and utter appropriate sound. - */ - mo->dPlayer->viewHeightDelta = mo->mom[MZ] / 8; - } - mo->mom[MZ] = 0; } diff --git a/doomsday/engine/portable/src/r_lumobjs.c b/doomsday/engine/portable/src/r_lumobjs.c index 77df629ccc..b0215855c8 100644 --- a/doomsday/engine/portable/src/r_lumobjs.c +++ b/doomsday/engine/portable/src/r_lumobjs.c @@ -575,7 +575,8 @@ static int C_DECL lumobjSorter(const void* e1, const void* e2) */ void LO_BeginFrame(void) { - uint i; + const viewdata_t* viewData = R_ViewData(viewPlayer - ddPlayers); + uint i; if(!(numLuminous > 0)) return; @@ -585,18 +586,19 @@ BEGIN_PROF( PROF_LUMOBJ_FRAME_SORT ); // Update lumobj distances ready for linking and sorting. for(i = 0; i < numLuminous; ++i) { - lumobj_t* lum = luminousList[i]; + lumobj_t* lum = luminousList[i]; + float pos[3]; + + V3_Subtract(pos, lum->pos, viewData->current.pos); // Approximate the distance in 3D. - luminousDist[i] = P_ApproxDistance3(lum->pos[VX] - viewX, - lum->pos[VY] - viewY, - lum->pos[VZ] - viewZ); + luminousDist[i] = P_ApproxDistance3(pos[VX], pos[VY], pos[VZ]); } if(loMaxLumobjs > 0 && numLuminous > loMaxLumobjs) { // Sort lumobjs by distance from the viewer. Then clip all lumobjs // so that only the closest are visible (max loMaxLumobjs). - uint n; + uint n; // Init the lumobj indices, sort array. for(i = 0; i < numLuminous; ++i) diff --git a/doomsday/engine/portable/src/r_main.c b/doomsday/engine/portable/src/r_main.c index 3681495e54..ce7ec8a100 100644 --- a/doomsday/engine/portable/src/r_main.c +++ b/doomsday/engine/portable/src/r_main.c @@ -54,20 +54,6 @@ END_PROF_TIMERS() // TYPES ------------------------------------------------------------------- -typedef struct viewer_s { - float pos[3]; - angle_t angle; - float pitch; -} viewer_t; - -typedef struct viewdata_s { - // These are used when camera smoothing is disabled. - angle_t frozenAngle; - float frozenPitch; - - viewer_t lastSharpView[2]; -} viewdata_t; - // EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- // PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- @@ -84,17 +70,12 @@ extern boolean firstFrameAfterLoad; // PUBLIC DATA DEFINITIONS ------------------------------------------------- -int viewAngleOffset = 0; int validCount = 1; // Increment every time a check is made. int frameCount; // Just for profiling purposes. int rendInfoTris = 0; int useVSync = 0; -float viewX, viewY, viewZ; -float viewFrontVec[3], viewUpVec[3], viewSideVec[3]; -float viewXOffset = 0, viewYOffset = 0, viewZOffset = 0; -angle_t viewAngle; -float viewPitch; // Player->lookDir, global version. -float viewCos, viewSin; +float viewX = 0, viewY = 0, viewZ = 0, viewPitch = 0; +int viewAngle = 0; boolean setSizeNeeded; // Precalculated math tables. @@ -376,13 +357,20 @@ void R_InterpolateViewer(viewer_t* start, viewer_t* end, float pos, out->pitch = inv * start->pitch + pos * end->pitch; } -void R_SetViewPos(viewer_t* v) +void R_CopyViewer(viewer_t* dst, const viewer_t* src) +{ + dst->pos[VX] = src->pos[VX]; + dst->pos[VY] = src->pos[VY]; + dst->pos[VZ] = src->pos[VZ]; + dst->angle = src->angle; + dst->pitch = src->pitch; +} + +const viewdata_t* R_ViewData(int localPlayerNum) { - viewX = v->pos[VX]; - viewY = v->pos[VY]; - viewZ = v->pos[VZ]; - viewAngle = v->angle; - viewPitch = v->pitch; + assert(localPlayerNum >= 0 && localPlayerNum < DDMAXPLAYERS); + + return &viewData[localPlayerNum]; } /** @@ -411,7 +399,7 @@ void R_CheckViewerLimits(viewer_t* src, viewer_t* dst) */ void R_GetSharpView(viewer_t* view, player_t* player) { - ddplayer_t* ddpl; + ddplayer_t* ddpl; if(!player || !player->shared.mo) { @@ -420,12 +408,13 @@ void R_GetSharpView(viewer_t* view, player_t* player) ddpl = &player->shared; + view->pos[VX] = viewX; + view->pos[VY] = viewY; + view->pos[VZ] = viewZ; /* $unifiedangles */ - view->angle = ddpl->mo->angle + viewAngleOffset; - view->pitch = ddpl->lookDir; - view->pos[VX] = ddpl->mo->pos[VX] + viewXOffset; - view->pos[VY] = ddpl->mo->pos[VY] + viewYOffset; - view->pos[VZ] = ddpl->viewZ + viewZOffset; + view->angle = viewAngle; + view->pitch = viewPitch; + if((ddpl->flags & DDPF_CHASECAM) && !(ddpl->flags & DDPF_CAMERA)) { /* STUB @@ -433,9 +422,9 @@ void R_GetSharpView(viewer_t* view, player_t* player) * camera control setup. Currently we simply project the viewer's * position a set distance behind the ddpl. */ - angle_t pitch = LOOKDIR2DEG(view->pitch) / 360 * ANGLE_MAX; - angle_t angle = view->angle; - float distance = 90; + angle_t pitch = LOOKDIR2DEG(view->pitch) / 360 * ANGLE_MAX; + angle_t angle = view->angle; + float distance = 90; angle = view->angle >> ANGLETOFINESHIFT; pitch >>= ANGLETOFINESHIFT; @@ -487,9 +476,9 @@ void R_NewSharpWorld(void) for(i = 0; i < DDMAXPLAYERS; ++i) { - viewer_t sharpView; - viewdata_t* vd = &viewData[i]; - player_t* plr = &ddPlayers[i]; + viewer_t sharpView; + viewdata_t* vd = &viewData[i]; + player_t* plr = &ddPlayers[i]; if(!(/*(plr->shared.flags & DDPF_LOCAL) &&*/ plr->shared.inGame)) continue; @@ -508,10 +497,10 @@ void R_NewSharpWorld(void) // buffer. The effect of this is that [0] is the previous sharp // position and [1] is the current one. - memcpy(&vd->lastSharpView[0], &vd->lastSharpView[1], sizeof(viewer_t)); - memcpy(&vd->lastSharpView[1], &sharpView, sizeof(sharpView)); + memcpy(&vd->lastSharp[0], &vd->lastSharp[1], sizeof(viewer_t)); + memcpy(&vd->lastSharp[1], &sharpView, sizeof(sharpView)); - R_CheckViewerLimits(vd->lastSharpView, &sharpView); + R_CheckViewerLimits(vd->lastSharp, &sharpView); } R_UpdateWatchedPlanes(watchedPlaneList); @@ -604,6 +593,7 @@ void R_EndWorldFrame(void) */ void R_SetupFrame(player_t* player) { +#define VIEWPOS_MAX_SMOOTHDISTANCE 172 #define MINEXTRALIGHTFRAMES 2 int tableAngle; @@ -619,17 +609,18 @@ void R_SetupFrame(player_t* player) R_GetSharpView(&sharpView, viewPlayer); - if(resetNextViewer) + if(resetNextViewer || + V3_Distance(vd->current.pos, sharpView.pos) > VIEWPOS_MAX_SMOOTHDISTANCE) { // Keep reseting until a new sharp world has arrived. if(resetNextViewer > 1) resetNextViewer = 0; // Just view from the sharp position. - R_SetViewPos(&sharpView); + R_CopyViewer(&vd->current, &sharpView); - memcpy(&vd->lastSharpView[0], &sharpView, sizeof(sharpView)); - memcpy(&vd->lastSharpView[1], &sharpView, sizeof(sharpView)); + memcpy(&vd->lastSharp[0], &sharpView, sizeof(sharpView)); + memcpy(&vd->lastSharp[1], &sharpView, sizeof(sharpView)); } // While the game is paused there is no need to calculate any // time offsets or interpolated camera positions. @@ -639,7 +630,7 @@ void R_SetupFrame(player_t* player) // between the previous and current sharp positions. This // introduces a slight delay (max. 1/35 sec) to the movement // of the smoothed camera. - R_InterpolateViewer(vd->lastSharpView, vd->lastSharpView + 1, frameTimePos, + R_InterpolateViewer(vd->lastSharp, vd->lastSharp + 1, frameTimePos, &smoothView); // Use the latest view angles known to us, if the interpolation flags @@ -650,7 +641,8 @@ void R_SetupFrame(player_t* player) smoothView.angle = sharpView.angle; if(!(player->shared.flags & DDPF_INTERPITCH)) smoothView.pitch = sharpView.pitch; - R_SetViewPos(&smoothView); + + R_CopyViewer(&vd->current, &smoothView); // Monitor smoothness of yaw/pitch changes. if(showViewAngleDeltas) @@ -707,6 +699,33 @@ void R_SetupFrame(player_t* player) } } + // Update viewer. + tableAngle = viewData->current.angle >> ANGLETOFINESHIFT; + viewData->viewSin = FIX2FLT(finesine[tableAngle]); + viewData->viewCos = FIX2FLT(fineCosine[tableAngle]); + + // Calculate the front, up and side unit vectors. + // The vectors are in the DGL coordinate system, which is a left-handed + // one (same as in the game, but Y and Z have been swapped). Anyone + // who uses these must note that it might be necessary to fix the aspect + // ratio of the Y axis by dividing the Y coordinate by 1.2. + yawRad = ((viewData->current.angle / (float) ANGLE_MAX) *2) * PI; + + pitchRad = viewData->current.pitch * 85 / 110.f / 180 * PI; + + // The front vector. + viewData->frontVec[VX] = cos(yawRad) * cos(pitchRad); + viewData->frontVec[VZ] = sin(yawRad) * cos(pitchRad); + viewData->frontVec[VY] = sin(pitchRad); + + // The up vector. + viewData->upVec[VX] = -cos(yawRad) * sin(pitchRad); + viewData->upVec[VZ] = -sin(yawRad) * sin(pitchRad); + viewData->upVec[VY] = cos(pitchRad); + + // The side vector is the cross product of the front and up vectors. + M_CrossProduct(viewData->frontVec, viewData->upVec, viewData->sideVec); + if(showFrameTimePos) { Con_Printf("frametime = %f\n", frameTimePos); @@ -730,32 +749,11 @@ void R_SetupFrame(player_t* player) extraLight = player->extraLight; extraLightDelta = extraLight / 16.0f; - tableAngle = viewAngle >> ANGLETOFINESHIFT; - viewSin = FIX2FLT(finesine[tableAngle]); - viewCos = FIX2FLT(fineCosine[tableAngle]); + // Why? validCount++; - // Calculate the front, up and side unit vectors. - // The vectors are in the DGL coordinate system, which is a left-handed - // one (same as in the game, but Y and Z have been swapped). Anyone - // who uses these must note that it might be necessary to fix the aspect - // ratio of the Y axis by dividing the Y coordinate by 1.2. - yawRad = ((viewAngle / (float) ANGLE_MAX) *2) * PI; - - pitchRad = viewPitch * 85 / 110.f / 180 * PI; - - // The front vector. - viewFrontVec[VX] = cos(yawRad) * cos(pitchRad); - viewFrontVec[VZ] = sin(yawRad) * cos(pitchRad); - viewFrontVec[VY] = sin(pitchRad); - - // The up vector. - viewUpVec[VX] = -cos(yawRad) * sin(pitchRad); - viewUpVec[VZ] = -sin(yawRad) * sin(pitchRad); - viewUpVec[VY] = cos(pitchRad); - - // The side vector is the cross product of the front and up vectors. - M_CrossProduct(viewFrontVec, viewUpVec, viewSideVec); +#undef MINEXTRALIGHTFRAMES +#undef VIEWPOS_MAX_SMOOTHDISTANCE } /** diff --git a/doomsday/engine/portable/src/r_things.c b/doomsday/engine/portable/src/r_things.c index 062fca71cd..26d69fdc03 100644 --- a/doomsday/engine/portable/src/r_things.c +++ b/doomsday/engine/portable/src/r_things.c @@ -807,13 +807,14 @@ vissprite_t* R_NewVisSprite(void) */ void R_ProjectPlayerSprites(void) { - int i; - float inter; - modeldef_t* mf, *nextmf; - ddpsprite_t* psp; - boolean isFullBright = (levelFullBright != 0); - boolean isModel; - ddplayer_t* ddpl = &viewPlayer->shared; + int i; + float inter; + modeldef_t* mf, *nextmf; + ddpsprite_t* psp; + boolean isFullBright = (levelFullBright != 0); + boolean isModel; + ddplayer_t* ddpl = &viewPlayer->shared; + const viewdata_t* viewData = R_ViewData(viewPlayer - ddPlayers); psp3d = false; @@ -837,7 +838,7 @@ void R_ProjectPlayerSprites(void) for(i = 0, psp = ddpl->pSprites; i < DDMAXPSPRITES; ++i, psp++) { - vispsprite_t* spr = &visPSprites[i]; + vispsprite_t* spr = &visPSprites[i]; spr->type = VPSPR_SPRITE; spr->psp = psp; @@ -849,7 +850,7 @@ void R_ProjectPlayerSprites(void) isModel = false; if(useModels) { // Is there a model for this frame? - mobj_t dummy; + mobj_t dummy; // Setup a dummy for the call to R_CheckModelFor. dummy.state = psp->statePtr; @@ -870,7 +871,7 @@ void R_ProjectPlayerSprites(void) spr->data.model.subsector = ddpl->mo->subsector; spr->data.model.flags = 0; // 32 is the raised weapon height. - spr->data.model.gzt = viewZ; + spr->data.model.gzt = viewData->current.pos[VZ]; spr->data.model.secFloor = ddpl->mo->subsector->sector->SP_floorvisheight; spr->data.model.secCeil = ddpl->mo->subsector->sector->SP_ceilvisheight; spr->data.model.pClass = 0; @@ -880,9 +881,9 @@ void R_ProjectPlayerSprites(void) spr->data.model.nextMF = nextmf; spr->data.model.inter = inter; spr->data.model.viewAligned = true; - spr->center[VX] = viewX; - spr->center[VY] = viewY; - spr->center[VZ] = viewZ; + spr->center[VX] = viewData->current.pos[VX]; + spr->center[VY] = viewData->current.pos[VY]; + spr->center[VZ] = viewData->current.pos[VZ]; // Offsets to rotation angles. spr->data.model.yawAngleOffset = psp->pos[VX] * weaponOffsetScale - 90; @@ -893,8 +894,8 @@ void R_ProjectPlayerSprites(void) spr->data.model.pitchAngleOffset -= weaponFOVShift * (fieldOfView - 90) / 90; // Real rotation angles. spr->data.model.yaw = - viewAngle / (float) ANGLE_MAX *-360 + spr->data.model.yawAngleOffset + 90; - spr->data.model.pitch = viewPitch * 85 / 110 + spr->data.model.yawAngleOffset; + viewData->current.angle / (float) ANGLE_MAX *-360 + spr->data.model.yawAngleOffset + 90; + spr->data.model.pitch = viewData->current.pitch * 85 / 110 + spr->data.model.yawAngleOffset; memset(spr->data.model.visOff, 0, sizeof(spr->data.model.visOff)); spr->data.model.alpha = psp->alpha; @@ -905,9 +906,9 @@ void R_ProjectPlayerSprites(void) spr->type = VPSPR_SPRITE; // Adjust the center slightly so an angle can be calculated. - spr->center[VX] = viewX; - spr->center[VY] = viewY; - spr->center[VZ] = viewZ; + spr->center[VX] = viewData->current.pos[VX]; + spr->center[VY] = viewData->current.pos[VY]; + spr->center[VZ] = viewData->current.pos[VZ]; spr->data.sprite.subsector = ddpl->mo->subsector; spr->data.sprite.alpha = psp->alpha; @@ -1137,28 +1138,29 @@ void getLightingParams(float x, float y, float z, subsector_t* ssec, */ void R_ProjectSprite(mobj_t* mo) { - sector_t* sect = mo->subsector->sector; - float thangle = 0, alpha, floorClip, secFloor, secCeil; - float pos[2], yaw, pitch; - vec3_t visOff; - spritedef_t* sprDef; - spriteframe_t* sprFrame = NULL; - int i, tmap = 0, tclass = 0; - unsigned rot; - boolean matFlipS, matFlipT; - vissprite_t* vis; - angle_t ang; - boolean align, fullBright, viewAlign, floorAdjust; - modeldef_t* mf = NULL, *nextmf = NULL; - float interp = 0, distance, gzt; - spritetex_t* sprTex; - vismobjzparams_t params; - visspritetype_t visType = VSPR_SPRITE; - float ambientColor[3]; - uint vLightListIdx = 0; - material_t* mat; + sector_t* sect = mo->subsector->sector; + float thangle = 0, alpha, floorClip, secFloor, secCeil; + float pos[2], yaw, pitch; + vec3_t visOff; + spritedef_t* sprDef; + spriteframe_t* sprFrame = NULL; + int i, tmap = 0, tclass = 0; + unsigned rot; + boolean matFlipS, matFlipT; + vissprite_t* vis; + angle_t ang; + boolean align, fullBright, viewAlign, floorAdjust; + modeldef_t* mf = NULL, *nextmf = NULL; + float interp = 0, distance, gzt; + spritetex_t* sprTex; + vismobjzparams_t params; + visspritetype_t visType = VSPR_SPRITE; + float ambientColor[3]; + uint vLightListIdx = 0; + material_t* mat; material_snapshot_t ms; material_load_params_t mparams; + const viewdata_t* viewData = R_ViewData(viewPlayer - ddPlayers); if(mo->ddFlags & DDMF_DONTDRAW || mo->translucency == 0xff || mo->state == NULL || mo->state == states) @@ -1170,8 +1172,8 @@ void R_ProjectSprite(mobj_t* mo) } // Transform the origin point. - pos[VX] = mo->pos[VX] - viewX; - pos[VY] = mo->pos[VY] - viewY; + pos[VX] = mo->pos[VX] - viewData->current.pos[VX]; + pos[VY] = mo->pos[VY] - viewData->current.pos[VY]; // Decide which patch to use for sprite relative to player. @@ -1264,7 +1266,7 @@ void R_ProjectSprite(mobj_t* mo) // draw it. Otherwise large models are likely to disappear // too early. if(P_ApproxDistance - (distance, mo->pos[VZ] + (mo->height / 2) - viewZ) > + (distance, mo->pos[VZ] + (mo->height / 2) - viewData->current.pos[VZ]) > MAX_OBJECT_RADIUS) { return; // Can't be visible. @@ -1363,7 +1365,7 @@ void R_ProjectSprite(mobj_t* mo) if(mf->sub[0].flags & MFF_ALIGN_PITCH) { pitch = -BANG2DEG(bamsAtan2 - (((vis->center[VZ] + gzt) / 2 - viewZ) * 10, + (((vis->center[VZ] + gzt) / 2 - viewData->current.pos[VZ]) * 10, distance * 10)); } else if(mf->sub[0].flags & MFF_MOVEMENT_PITCH) diff --git a/doomsday/engine/portable/src/r_util.c b/doomsday/engine/portable/src/r_util.c index c00ec93309..49b11a5faa 100644 --- a/doomsday/engine/portable/src/r_util.c +++ b/doomsday/engine/portable/src/r_util.c @@ -32,6 +32,7 @@ #include "de_base.h" #include "de_refresh.h" +#include "de_play.h" #include "p_dmu.h" @@ -156,24 +157,9 @@ int R_SlopeDiv(unsigned num, unsigned den) return ans <= SLOPERANGE ? ans : SLOPERANGE; } -/** - * To get a global angle from cartesian coordinates, the coordinates are - * flipped until they are in the first octant of the coordinate system, then - * the y (<=x) is scaled and divided by x to get a tangent (slope) value - * which is looked up in the tantoangle[] table. The +1 size is to handle - * the case when x==y without additional checking. - * - * @param x X coordinate to test. - * @param y Y coordinate to test. - * - * @return angle_t Angle between the test point and viewX,y. - */ -angle_t R_PointToAngle(float x, float y) +static angle_t pointToAngle(float x, float y) { - fixed_t pos[2]; - - x -= viewX; - y -= viewY; + fixed_t pos[2]; if(x == 0 && y == 0) return 0; @@ -186,56 +172,75 @@ angle_t R_PointToAngle(float x, float y) if(pos[VY] >= 0) { // y>= 0 if(pos[VX] > pos[VY]) - return tantoangle[R_SlopeDiv(pos[VY], pos[VX])]; // octant 0 - else - return ANG90 - 1 - tantoangle[R_SlopeDiv(pos[VX], pos[VY])]; // octant 1 - } - else - { // y<0 - pos[VY] = -pos[VY]; - if(pos[VX] > pos[VY]) - return -tantoangle[R_SlopeDiv(pos[VY], pos[VX])]; // octant 8 - else - return ANG270 + tantoangle[R_SlopeDiv(pos[VX], pos[VY])]; // octant 7 + return tantoangle[R_SlopeDiv(pos[VY], pos[VX])]; // octant 0 + + return ANG90 - 1 - tantoangle[R_SlopeDiv(pos[VX], pos[VY])]; // octant 1 } + + // y<0 + pos[VY] = -pos[VY]; + if(pos[VX] > pos[VY]) + return -tantoangle[R_SlopeDiv(pos[VY], pos[VX])]; // octant 8 + + return ANG270 + tantoangle[R_SlopeDiv(pos[VX], pos[VY])]; // octant 7 } - else - { // x<0 - pos[VX] = -pos[VX]; - if(pos[VY] >= 0) - { // y>= 0 - if(pos[VX] > pos[VY]) - return ANG180 - 1 - tantoangle[R_SlopeDiv(pos[VY], pos[VX])]; // octant 3 - else - return ANG90 + tantoangle[R_SlopeDiv(pos[VX], pos[VY])]; // octant 2 - } - else - { // y<0 - pos[VY] = -pos[VY]; - if(pos[VX] > pos[VY]) - return ANG180 + tantoangle[R_SlopeDiv(pos[VY], pos[VX])]; // octant 4 - else - return ANG270 - 1 - tantoangle[R_SlopeDiv(pos[VX], pos[VY])]; // octant 5 - } + + // x<0 + pos[VX] = -pos[VX]; + if(pos[VY] >= 0) + { // y>= 0 + if(pos[VX] > pos[VY]) + return ANG180 - 1 - tantoangle[R_SlopeDiv(pos[VY], pos[VX])]; // octant 3 + + return ANG90 + tantoangle[R_SlopeDiv(pos[VX], pos[VY])]; // octant 2 } + + // y<0 + pos[VY] = -pos[VY]; + if(pos[VX] > pos[VY]) + return ANG180 + tantoangle[R_SlopeDiv(pos[VY], pos[VX])]; // octant 4 + + return ANG270 - 1 - tantoangle[R_SlopeDiv(pos[VX], pos[VY])]; // octant 5 } -angle_t R_PointToAngle2(const float x1, const float y1, - const float x2, const float y2) +/** + * To get a global angle from cartesian coordinates, the coordinates are + * flipped until they are in the first octant of the coordinate system, then + * the y (<=x) is scaled and divided by x to get a tangent (slope) value + * which is looked up in the tantoangle[] table. The +1 size is to handle + * the case when x==y without additional checking. + * + * @param x X coordinate to test. + * @param y Y coordinate to test. + * + * @return angle_t Angle between the test point and viewX,y. + */ +angle_t R_PointToAngle(float x, float y) { - viewX = x1; - viewY = y1; - return R_PointToAngle(x2, y2); + const viewdata_t* viewData = R_ViewData(viewPlayer - ddPlayers); + + x -= viewData->current.pos[VX]; + y -= viewData->current.pos[VY]; + + return pointToAngle(x, y); +} + +angle_t R_PointToAngle2(float x1, float y1, float x2, float y2) +{ + x2 -= x1; + y2 -= y1; + + return pointToAngle(x2, y2); } float R_PointToDist(const float x, const float y) { - uint angle; - float dx, dy, temp; - float dist; + const viewdata_t* viewData = R_ViewData(viewPlayer - ddPlayers); + float dx, dy, temp, dist; + uint angle; - dx = fabs(x - viewX); - dy = fabs(y - viewY); + dx = fabs(x - viewData->current.pos[VX]); + dy = fabs(y - viewData->current.pos[VY]); if(dy > dx) { diff --git a/doomsday/engine/portable/src/rend_fakeradio.c b/doomsday/engine/portable/src/rend_fakeradio.c index f89daa0354..3bdb5b6577 100644 --- a/doomsday/engine/portable/src/rend_fakeradio.c +++ b/doomsday/engine/portable/src/rend_fakeradio.c @@ -47,6 +47,7 @@ #include "de_render.h" #include "de_graphics.h" #include "de_misc.h" +#include "de_play.h" #include "m_vector.h" @@ -1642,9 +1643,10 @@ void Rend_RadioSubsectorEdges(subsector_t* subsector) #if _DEBUG static void drawPoint(float pos[3], float radius, const float color[4]) { - int i; - float viewPos[3], viewToCenter[3], finalPos[3], scale, - leftOff[3], rightOff[3], radX, radY; + const viewdata_t* viewData = R_ViewData(viewPlayer - ddPlayers); + float viewPos[3], viewToCenter[3], finalPos[3], scale, leftOff[3], + rightOff[3], radX, radY; + int i; viewPos[VX] = vx; viewPos[VY] = vy; @@ -1653,14 +1655,14 @@ static void drawPoint(float pos[3], float radius, const float color[4]) // viewSideVec is to the left. for(i = 0; i < 3; ++i) { - leftOff[i] = viewUpVec[i] + viewSideVec[i]; - rightOff[i] = viewUpVec[i] - viewSideVec[i]; + leftOff[i] = viewData->upVec[i] + viewData->sideVec[i]; + rightOff[i] = viewData->upVec[i] - viewData->sideVec[i]; viewToCenter[i] = pos[i] - viewPos[i]; } - scale = M_DotProduct(viewToCenter, viewFrontVec) / - M_DotProduct(viewFrontVec, viewFrontVec); + scale = M_DotProduct(viewToCenter, viewData->frontVec) / + M_DotProduct(viewData->frontVec, viewData->frontVec); finalPos[VX] = pos[VX]; finalPos[VY] = pos[VZ]; diff --git a/doomsday/engine/portable/src/rend_halo.c b/doomsday/engine/portable/src/rend_halo.c index 27a644a1ee..8441831077 100644 --- a/doomsday/engine/portable/src/rend_halo.c +++ b/doomsday/engine/portable/src/rend_halo.c @@ -145,15 +145,16 @@ boolean H_RenderHalo(float x, float y, float z, float size, DGLuint tex, float viewXOffset, boolean primary, boolean viewRelativeRotate) { - int i, k; - float viewPos[3]; - float viewToCenter[3], mirror[3], normalViewToCenter[3]; - float leftOff[3], rightOff[3], center[3], radius; - float haloPos[3]; - float rgba[4], radX, radY, scale, turnAngle = 0; - float fadeFactor = 1, secBold, secDimFactor; - float colorAverage, f, distanceDim; - flare_t* fl; + int i, k; + float viewPos[3]; + float viewToCenter[3], mirror[3], normalViewToCenter[3]; + float leftOff[3], rightOff[3], center[3], radius; + float haloPos[3]; + float rgba[4], radX, radY, scale, turnAngle = 0; + float fadeFactor = 1, secBold, secDimFactor; + float colorAverage, f, distanceDim; + flare_t* fl; + const viewdata_t* viewData = R_ViewData(viewPlayer - ddPlayers); // In realistic mode we don't render secondary halos. if(!primary && haloRealistic) @@ -175,8 +176,8 @@ boolean H_RenderHalo(float x, float y, float z, float size, DGLuint tex, // viewSideVec is to the left. for(i = 0; i < 3; ++i) { - leftOff[i] = viewUpVec[i] + viewSideVec[i]; - rightOff[i] = viewUpVec[i] - viewSideVec[i]; + leftOff[i] = viewData->upVec[i] + viewData->sideVec[i]; + rightOff[i] = viewData->upVec[i] - viewData->sideVec[i]; } rgba[CR] = color[CR]; @@ -194,7 +195,7 @@ boolean H_RenderHalo(float x, float y, float z, float size, DGLuint tex, // Apply the flare's X offset. (Positive is to the right.) for(i = 0; i < 3; i++) - center[i] -= viewXOffset * viewSideVec[i]; + center[i] -= viewXOffset * viewData->sideVec[i]; // Calculate the mirrored position. // Project viewtocenter vector onto viewSideVec. @@ -206,14 +207,14 @@ boolean H_RenderHalo(float x, float y, float z, float size, DGLuint tex, // Calculate the dimming factor for secondary flares. M_Normalize(normalViewToCenter); - secDimFactor = M_DotProduct(normalViewToCenter, viewFrontVec); + secDimFactor = M_DotProduct(normalViewToCenter, viewData->frontVec); - scale = M_DotProduct(viewToCenter, viewFrontVec) / - M_DotProduct(viewFrontVec, viewFrontVec); + scale = M_DotProduct(viewToCenter, viewData->frontVec) / + M_DotProduct(viewData->frontVec, viewData->frontVec); for(i = 0; i < 3; i++) haloPos[i] = mirror[i] = - (viewFrontVec[i] * scale - viewToCenter[i]) * 2; + (viewData->frontVec[i] * scale - viewToCenter[i]) * 2; // Now adding 'mirror' to a position will mirror it. // Calculate texture turn angle. @@ -223,7 +224,7 @@ boolean H_RenderHalo(float x, float y, float z, float size, DGLuint tex, // Both vectors are on the view plane. if(viewRelativeRotate) { - turnAngle = M_DotProduct(haloPos, viewUpVec); + turnAngle = M_DotProduct(haloPos, viewData->upVec); if(turnAngle > 1) turnAngle = 1; else if(turnAngle < -1) @@ -237,7 +238,7 @@ boolean H_RenderHalo(float x, float y, float z, float size, DGLuint tex, turnAngle = acos(turnAngle); // On which side of the up vector (left or right)? - if(M_DotProduct(haloPos, viewSideVec) < 0) + if(M_DotProduct(haloPos, viewData->sideVec) < 0) turnAngle = -turnAngle; } else diff --git a/doomsday/engine/portable/src/rend_main.c b/doomsday/engine/portable/src/rend_main.c index 8c6a460bdb..35bb0c9cbd 100644 --- a/doomsday/engine/portable/src/rend_main.c +++ b/doomsday/engine/portable/src/rend_main.c @@ -203,11 +203,13 @@ void Rend_Reset(void) void Rend_ModelViewMatrix(boolean useAngles) { - vx = viewX; - vy = viewZ; - vz = viewY; - vang = viewAngle / (float) ANGLE_MAX *360 - 90; - vpitch = viewPitch * 85.0 / 110.0; + const viewdata_t* viewData = R_ViewData(viewPlayer - ddPlayers); + + vx = viewData->current.pos[VX]; + vy = viewData->current.pos[VZ]; + vz = viewData->current.pos[VY]; + vang = viewData->current.angle / (float) ANGLE_MAX *360 - 90; + vpitch = viewData->current.pitch * 85.0 / 110.0; glMatrixMode(GL_MODELVIEW); glLoadIdentity(); @@ -2149,7 +2151,8 @@ static boolean rendSegSection(subsector_t* ssec, seg_t* seg, if(section == SEG_MIDDLE && softSurface) { - mobj_t* mo = viewPlayer->shared.mo; + mobj_t* mo = viewPlayer->shared.mo; + const viewdata_t* viewData = R_ViewData(viewPlayer - ddPlayers); /** * Can the player walk through this surface? @@ -2159,10 +2162,11 @@ static boolean rendSegSection(subsector_t* ssec, seg_t* seg, * opaque waterfall). */ - if(viewZ > bottom && viewZ < top) + if(viewData->current.pos[VZ] > bottom && + viewData->current.pos[VZ] < top) { - float delta[2], pos, result[2]; - linedef_t* lineDef = seg->lineDef; + float delta[2], pos, result[2]; + linedef_t* lineDef = seg->lineDef; delta[0] = lineDef->dX; delta[1] = lineDef->dY; @@ -3314,17 +3318,19 @@ static void Rend_RenderNode(uint bspnum) } else { - node_t *bsp; - byte side; + const viewdata_t* viewData = R_ViewData(viewPlayer - ddPlayers); + node_t* bsp; + byte side; // Descend deeper into the nodes. bsp = NODE_PTR(bspnum); // Decide which side the view point is on. - side = R_PointOnSide(viewX, viewY, &bsp->partition); + side = R_PointOnSide(viewData->current.pos[VX], viewData->current.pos[VY], + &bsp->partition); - Rend_RenderNode(bsp->children[side]); // Recursively divide front space. - Rend_RenderNode(bsp->children[side ^ 1]); // ...and back space. + Rend_RenderNode(bsp->children[side]); // Recursively divide front space. + Rend_RenderNode(bsp->children[side ^ 1]); // ...and back space. } } @@ -3740,9 +3746,8 @@ void Rend_Vertexes(void) void Rend_RenderMap(void) { - binangle_t viewside; - boolean doLums = - (useDynLights || haloMode || spriteLight || useDecorations); + binangle_t viewside; + boolean doLums = (useDynLights || haloMode || spriteLight || useDecorations); // Set to true if dynlights are inited for this frame. loInited = false; @@ -3754,6 +3759,8 @@ void Rend_RenderMap(void) if(!freezeRLs) { + const viewdata_t* viewData = R_ViewData(viewPlayer - ddPlayers); + // Prepare for rendering. RL_ClearLists(); // Clear the lists for new quads. C_ClearRanges(); // Clear the clipper. @@ -3782,19 +3789,20 @@ void Rend_RenderMap(void) // Add the backside clipping range (if vpitch allows). if(vpitch <= 90 - yfov / 2 && vpitch >= -90 + yfov / 2) { - float a = fabs(vpitch) / (90 - yfov / 2); + + float a = fabs(vpitch) / (90 - yfov / 2); binangle_t startAngle = (binangle_t) (BANG_45 * fieldOfView / 90) * (1 + a); binangle_t angLen = BANG_180 - startAngle; - viewside = (viewAngle >> (32 - BAMS_BITS)) + startAngle; + viewside = (viewData->current.angle >> (32 - BAMS_BITS)) + startAngle; C_SafeAddRange(viewside, viewside + angLen); C_SafeAddRange(viewside + angLen, viewside + 2 * angLen); } // The viewside line for the depth cue. - viewsidex = -viewSin; - viewsidey = viewCos; + viewsidex = -viewData->viewSin; + viewsidey = viewData->viewCos; // We don't want subsector clipchecking for the first subsector. firstsubsector = true; diff --git a/doomsday/engine/portable/src/rend_particle.c b/doomsday/engine/portable/src/rend_particle.c index 3666cfdaf1..a30a3687df 100644 --- a/doomsday/engine/portable/src/rend_particle.c +++ b/doomsday/engine/portable/src/rend_particle.c @@ -109,8 +109,9 @@ static boolean isPtcGenVisible(const ptcgen_t* gen) static float pointDist(fixed_t c[3]) { - float dist = ((viewY - FIX2FLT(c[VY])) * -viewSin) - - ((viewX - FIX2FLT(c[VX])) * viewCos); + const viewdata_t* viewData = R_ViewData(viewPlayer - ddPlayers); + float dist = ((viewData->current.pos[VY] - FIX2FLT(c[VY])) * -viewData->viewSin) - + ((viewData->current.pos[VX] - FIX2FLT(c[VX])) * viewData->viewCos); if(dist < 0) return -dist; // Always return positive. @@ -496,18 +497,21 @@ static void setupModelParamsForParticle(rendmodelparams_t* params, static void renderParticles(int rtype, boolean withBlend) { - size_t i; - int c; - DGLuint tex = 0; - float leftoff[3], rightoff[3]; - ushort primType = GL_QUADS; - blendmode_t mode = BM_NORMAL, newMode; + size_t i; + int c; + DGLuint tex = 0; + float leftoff[3], rightoff[3]; + ushort primType = GL_QUADS; + blendmode_t mode = BM_NORMAL, newMode; + { + const viewdata_t* viewData = R_ViewData(viewPlayer - ddPlayers); // viewSideVec points to the left. for(c = 0; c < 3; ++c) { - leftoff[c] = viewUpVec[c] + viewSideVec[c]; - rightoff[c] = viewUpVec[c] - viewSideVec[c]; + leftoff[c] = viewData->upVec[c] + viewData->sideVec[c]; + rightoff[c] = viewData->upVec[c] - viewData->sideVec[c]; + } } // Should we use a texture? diff --git a/doomsday/engine/portable/src/rend_sprite.c b/doomsday/engine/portable/src/rend_sprite.c index c0d82f94d0..bcd784fbb9 100644 --- a/doomsday/engine/portable/src/rend_sprite.c +++ b/doomsday/engine/portable/src/rend_sprite.c @@ -385,11 +385,14 @@ void Rend_DrawPSprite(const rendpspriteparams_t *params) // All psprite vertices are co-plannar, so just copy the view front vector. // \fixme: Can we do something better here? + { + const float* frontVec = R_ViewData(viewPlayer - ddPlayers)->frontVec; for(i = 0; i < 4; ++i) { - quadNormals[i].xyz[VX] = viewFrontVec[VX]; - quadNormals[i].xyz[VY] = viewFrontVec[VZ]; - quadNormals[i].xyz[VZ] = viewFrontVec[VY]; + quadNormals[i].xyz[VX] = frontVec[VX]; + quadNormals[i].xyz[VY] = frontVec[VZ]; + quadNormals[i].xyz[VZ] = frontVec[VY]; + } } if(!params->vLightListIdx) diff --git a/doomsday/plugins/common/include/p_mapsetup.h b/doomsday/plugins/common/include/p_mapsetup.h index 47d8b358b5..4692d2bff9 100644 --- a/doomsday/plugins/common/include/p_mapsetup.h +++ b/doomsday/plugins/common/include/p_mapsetup.h @@ -42,6 +42,9 @@ #define numpolyobjs (*(uint*) DD_GetVariable(DD_POLYOBJ_COUNT)) #endif +// If true we are in the process of setting up a map. +extern boolean mapSetup; + void P_SetupForMapData(int type, uint num); void P_SetupMap(int episode, int map, int playermask, skillmode_t skill); diff --git a/doomsday/plugins/common/src/d_netcl.c b/doomsday/plugins/common/src/d_netcl.c index 27f8b73ebf..3b778620c0 100644 --- a/doomsday/plugins/common/src/d_netcl.c +++ b/doomsday/plugins/common/src/d_netcl.c @@ -228,7 +228,6 @@ void NetCl_UpdateGameState(byte *data) mo->pos[VZ] = (float) NetCl_ReadShort(); P_MobjSetPosition(mo); mo->angle = NetCl_ReadShort() << 16; /* $unifiedangles */ - pl->plr->viewZ = mo->pos[VZ]; // Update floorz and ceilingz. #if __JDOOM__ || __JDOOM64__ P_CheckPosition3fv(mo, mo->pos); @@ -564,7 +563,7 @@ void NetCl_UpdatePlayerState(byte *data, int plrNum) if(flags & PSF_VIEW_HEIGHT) { - pl->plr->viewHeight = (float) NetCl_ReadByte(); + pl->viewHeight = (float) NetCl_ReadByte(); } #if __JHERETIC || __JHEXEN__ || __JSTRIFE__ diff --git a/doomsday/plugins/common/src/d_netsv.c b/doomsday/plugins/common/src/d_netsv.c index 8d608566ca..4a9fb1892f 100644 --- a/doomsday/plugins/common/src/d_netsv.c +++ b/doomsday/plugins/common/src/d_netsv.c @@ -1174,7 +1174,8 @@ void NetSv_SendPlayerState(int srcPlrNum, int destPlrNum, int flags, if(flags & PSF_VIEW_HEIGHT) { - *ptr++ = (byte) pl->plr->viewHeight; + // @todo Do clients really need to know this? + *ptr++ = (byte) pl->viewHeight; } #if __JHERETIC__ || __JHEXEN__ || __JSTRIFE__ diff --git a/doomsday/plugins/common/src/p_mapsetup.c b/doomsday/plugins/common/src/p_mapsetup.c index 2dccf8eaeb..f894bd3217 100644 --- a/doomsday/plugins/common/src/p_mapsetup.c +++ b/doomsday/plugins/common/src/p_mapsetup.c @@ -972,7 +972,7 @@ static void P_ResetWorldState(void) plr->killCount = plr->secretCount = plr->itemCount = 0; // Initial height of PointOfView; will be set by player think. - plr->plr->viewZ = 1; + plr->viewZ = 1; AM_SetCheatLevel(map, 0); AM_RevealMap(map, false); diff --git a/doomsday/plugins/common/src/p_player.c b/doomsday/plugins/common/src/p_player.c index ea256960fe..5207136321 100644 --- a/doomsday/plugins/common/src/p_player.c +++ b/doomsday/plugins/common/src/p_player.c @@ -947,12 +947,12 @@ DEFCC(CCmdSetCamera) if(player->plr->flags & DDPF_CAMERA) { // Is now a camera. if(player->plr->mo) - player->plr->mo->pos[VZ] += player->plr->viewHeight; + player->plr->mo->pos[VZ] += player->viewHeight; } else { // Is now a "real" player. if(player->plr->mo) - player->plr->mo->pos[VZ] -= player->plr->viewHeight; + player->plr->mo->pos[VZ] -= player->viewHeight; } } return true; diff --git a/doomsday/plugins/common/src/p_saveg.c b/doomsday/plugins/common/src/p_saveg.c index fee2ec1727..5084741d13 100644 --- a/doomsday/plugins/common/src/p_saveg.c +++ b/doomsday/plugins/common/src/p_saveg.c @@ -1021,9 +1021,9 @@ static void SV_WritePlayer(int playernum) #if __JHEXEN__ SV_WriteLong(p->class); // 2nd class...? #endif - SV_WriteLong(FLT2FIX(dp->viewZ)); - SV_WriteLong(FLT2FIX(dp->viewHeight)); - SV_WriteLong(FLT2FIX(dp->viewHeightDelta)); + SV_WriteLong(FLT2FIX(p->viewZ)); + SV_WriteLong(FLT2FIX(p->viewHeight)); + SV_WriteLong(FLT2FIX(p->viewHeightDelta)); #if !__JHEXEN__ SV_WriteFloat(dp->lookDir); #endif @@ -1187,9 +1187,10 @@ static void SV_ReadPlayer(player_t* p) #if __JHEXEN__ p->class = SV_ReadLong(); // 2nd class...? #endif - dp->viewZ = FIX2FLT(SV_ReadLong()); - dp->viewHeight = FIX2FLT(SV_ReadLong()); - dp->viewHeightDelta = FIX2FLT(SV_ReadLong()); + + p->viewZ = FIX2FLT(SV_ReadLong()); + p->viewHeight = FIX2FLT(SV_ReadLong()); + p->viewHeightDelta = FIX2FLT(SV_ReadLong()); #if !__JHEXEN__ dp->lookDir = SV_ReadFloat(); #endif diff --git a/doomsday/plugins/common/src/p_start.c b/doomsday/plugins/common/src/p_start.c index 2a3bf9f323..c9d60db0a4 100644 --- a/doomsday/plugins/common/src/p_start.c +++ b/doomsday/plugins/common/src/p_start.c @@ -476,10 +476,10 @@ void P_SpawnPlayer(int plrNum, playerclass_t pClass, float x, float y, if(p->plr->flags & DDPF_CAMERA) { p->plr->mo->pos[VZ] += (float) cfg.plrViewHeight; - p->plr->viewHeight = 0; + p->viewHeight = p->viewZ = 0; } else - p->plr->viewHeight = (float) cfg.plrViewHeight; + p->viewHeight = p->viewZ = (float) cfg.plrViewHeight; // Give all cards in death match mode. if(deathmatch) diff --git a/doomsday/plugins/common/src/p_user.c b/doomsday/plugins/common/src/p_user.c index c78ccc8cc2..5d389bf47d 100644 --- a/doomsday/plugins/common/src/p_user.c +++ b/doomsday/plugins/common/src/p_user.c @@ -501,8 +501,8 @@ void P_DeathThink(player_t* player) player->plr->mo->type == MT_ICECHUNK) #endif { // Flying bloody skull - player->plr->viewHeight = 6; - player->plr->viewHeightDelta = 0; + player->viewHeight = 6; + player->viewHeightDelta = 0; if(onground) { @@ -528,13 +528,13 @@ void P_DeathThink(player_t* player) else // fall to the ground #endif { - if(player->plr->viewHeight > 6) - player->plr->viewHeight -= 1; + if(player->viewHeight > 6) + player->viewHeight -= 1; - if(player->plr->viewHeight < 6) - player->plr->viewHeight = 6; + if(player->viewHeight < 6) + player->viewHeight = 6; - player->plr->viewHeightDelta = 0; + player->viewHeightDelta = 0; #if __JHERETIC__ || __JHEXEN__ if(player->plr->lookDir > 0) diff --git a/doomsday/plugins/common/src/p_view.c b/doomsday/plugins/common/src/p_view.c index a9610ce43f..8f44eae113 100644 --- a/doomsday/plugins/common/src/p_view.c +++ b/doomsday/plugins/common/src/p_view.c @@ -101,7 +101,7 @@ void P_CalcHeight(player_t* plr) // During demo playback the view is thought to be airborne if viewheight // is zero (Cl_MoveLocalPlayer). if(Get(DD_PLAYBACK)) - airborne = !ddplr->viewHeight; + airborne = !plr->viewHeight; else airborne = pmo->pos[VZ] > pmo->floorZ; // Truly in the air? @@ -152,31 +152,31 @@ void P_CalcHeight(player_t* plr) // Move viewheight. if(plr->playerState == PST_LIVE) { - ddplr->viewHeight += ddplr->viewHeightDelta; + plr->viewHeight += plr->viewHeightDelta; - if(ddplr->viewHeight > VIEW_HEIGHT) + if(plr->viewHeight > VIEW_HEIGHT) { - ddplr->viewHeight = VIEW_HEIGHT; - ddplr->viewHeightDelta = 0; + plr->viewHeight = VIEW_HEIGHT; + plr->viewHeightDelta = 0; } - else if(ddplr->viewHeight < VIEW_HEIGHT / 2.0f) + else if(plr->viewHeight < VIEW_HEIGHT / 2.0f) { - ddplr->viewHeight = VIEW_HEIGHT / 2.0f; - if(ddplr->viewHeightDelta <= 0) - ddplr->viewHeightDelta = 1; + plr->viewHeight = VIEW_HEIGHT / 2.0f; + if(plr->viewHeightDelta <= 0) + plr->viewHeightDelta = 1; } - if(ddplr->viewHeightDelta) + if(plr->viewHeightDelta) { - ddplr->viewHeightDelta += 0.25f; - if(!ddplr->viewHeightDelta) - ddplr->viewHeightDelta = 1; + plr->viewHeightDelta += 0.25f; + if(!plr->viewHeightDelta) + plr->viewHeightDelta = 1; } } } // Set the plr's eye-level Z coordinate. - ddplr->viewZ = pmo->pos[VZ] + (P_MobjIsCamera(pmo)? 0 : ddplr->viewHeight); + plr->viewZ = pmo->pos[VZ] + (P_MobjIsCamera(pmo)? 0 : plr->viewHeight); // During demo playback (or camera mode) the viewz will not be modified // any further. @@ -185,7 +185,7 @@ void P_CalcHeight(player_t* plr) { if(morphed) { // Chicken or pig. - ddplr->viewZ -= 20; + plr->viewZ -= 20; } // Foot clipping is done for living players. @@ -193,7 +193,7 @@ void P_CalcHeight(player_t* plr) { if(pmo->floorClip && pmo->pos[VZ] <= pmo->floorZ) { - ddplr->viewZ -= pmo->floorClip; + plr->viewZ -= pmo->floorClip; } } } diff --git a/doomsday/plugins/common/src/p_xgline.c b/doomsday/plugins/common/src/p_xgline.c index 0a9a080c4d..eaf147c456 100644 --- a/doomsday/plugins/common/src/p_xgline.c +++ b/doomsday/plugins/common/src/p_xgline.c @@ -1758,7 +1758,7 @@ int C_DECL XLTrav_LineTeleport(linedef_t* newLine, boolean dummy, // Adjust the player's view, incase there has been a height change if(mobj->player) { - mobj->dPlayer->viewZ = mobj->pos[VZ] + mobj->dPlayer->viewHeight; + mobj->player->viewZ = mobj->pos[VZ] + mobj->player->viewHeight; mobj->dPlayer->flags |= DDPF_FIXANGLES | DDPF_FIXPOS | DDPF_FIXMOM; } diff --git a/doomsday/plugins/common/src/p_xgsec.c b/doomsday/plugins/common/src/p_xgsec.c index 26c404c6b8..767149fdb9 100644 --- a/doomsday/plugins/common/src/p_xgsec.c +++ b/doomsday/plugins/common/src/p_xgsec.c @@ -2203,14 +2203,14 @@ int C_DECL XSTrav_Teleport(sector_t* sector, boolean ceiling, void* context, { thing->pos[VZ] = thceilz - thing->height; } - thing->dPlayer->viewZ = - thing->pos[VZ] + thing->dPlayer->viewHeight; + thing->player->viewZ = + thing->pos[VZ] + thing->player->viewHeight; } else { thing->pos[VZ] = thfloorz; - thing->dPlayer->viewZ = - thing->pos[VZ] + thing->dPlayer->viewHeight; + thing->player->viewZ = + thing->pos[VZ] + thing->player->viewHeight; thing->dPlayer->lookDir = 0; /* $unifiedangles */ } #if __JHERETIC__ diff --git a/doomsday/plugins/jdoom/include/d_player.h b/doomsday/plugins/jdoom/include/d_player.h index a7e21b16b8..ac986fc7ff 100644 --- a/doomsday/plugins/jdoom/include/d_player.h +++ b/doomsday/plugins/jdoom/include/d_player.h @@ -62,8 +62,6 @@ typedef struct player_s { playerclass_t class; // Player class type. playerbrain_t brain; - float viewOffset[3]; - float bob; // Bounded/scaled total momentum. int health; // This is only used between levels, mo->health is used during levels. int armorPoints; int armorType; // Armor type is 0-2. @@ -100,15 +98,20 @@ typedef struct player_s { int colorMap; // Player skin colorshift, 0-3 for which color to draw player. pspdef_t pSprites[NUMPSPRITES]; // Overlay view sprites (gun, etc). boolean didSecret; // True if secret level has been done. - boolean centering; // The player's view pitch is centering back to zero. - // The player can jump if this counter is zero. - int jumpTics; + int jumpTics; // The player can jump if this counter is zero. int airCounter; int flyHeight; int rebornWait; // The player can be reborn if this counter is zero. + boolean centering; // The player's view pitch is centering back to zero. int update, startSpot; + float viewOffset[3]; // Relative to position of the player mobj. + float viewZ; // Focal origin above r.z. + float viewHeight; // Base height above floor for viewZ. + float viewHeightDelta; + float bob; // Bounded/scaled total momentum. + // Target view to a mobj (NULL=disabled): mobj_t* viewLock; // $democam int lockFull; diff --git a/doomsday/plugins/jdoom/src/d_console.c b/doomsday/plugins/jdoom/src/d_console.c index 5544fb9af4..4bec324559 100644 --- a/doomsday/plugins/jdoom/src/d_console.c +++ b/doomsday/plugins/jdoom/src/d_console.c @@ -278,10 +278,10 @@ void D_ConsoleBg(int *width, int *height) */ void G_UpdateEyeHeight(cvar_t* unused) { - player_t* plr = &players[CONSOLEPLAYER]; + player_t* plr = &players[CONSOLEPLAYER]; if(!(plr->plr->flags & DDPF_CAMERA)) - plr->plr->viewHeight = (float) cfg.plrViewHeight; + plr->viewHeight = (float) cfg.plrViewHeight; } /** diff --git a/doomsday/plugins/jdoom/src/d_refresh.c b/doomsday/plugins/jdoom/src/d_refresh.c index db8b04b8a8..7d4df10375 100644 --- a/doomsday/plugins/jdoom/src/d_refresh.c +++ b/doomsday/plugins/jdoom/src/d_refresh.c @@ -220,13 +220,12 @@ void R_SetViewSize(int blocks) static void rendPlayerView(int player) { - player_t* plr = &players[player]; - int viewAngleOffset = - ANGLE_MAX * -G_GetLookOffset(player); - int isFullBright = - ((plr->powers[PT_INFRARED] > 4 * 32) || - (plr->powers[PT_INFRARED] & 8) || - plr->powers[PT_INVULNERABILITY] > 30); + player_t* plr = &players[player]; + float viewPos[3], viewPitch; + angle_t viewAngle; + int isFullBright = ((plr->powers[PT_INFRARED] > 4 * 32) || + (plr->powers[PT_INFRARED] & 8) || + plr->powers[PT_INVULNERABILITY] > 30); if(IS_CLIENT) { @@ -234,17 +233,23 @@ static void rendPlayerView(int player) R_SetAllDoomsdayFlags(); } - DD_SetVariable(DD_VIEWX_OFFSET, &plr->viewOffset[VX]); - DD_SetVariable(DD_VIEWY_OFFSET, &plr->viewOffset[VY]); - DD_SetVariable(DD_VIEWZ_OFFSET, &plr->viewOffset[VZ]); - // The view angle offset. - DD_SetVariable(DD_VIEWANGLE_OFFSET, &viewAngleOffset); + viewPos[VX] = plr->plr->mo->pos[VX] + plr->viewOffset[VX]; + viewPos[VY] = plr->plr->mo->pos[VY] + plr->viewOffset[VY]; + viewPos[VZ] = plr->viewZ + plr->viewOffset[VZ]; + viewAngle = plr->plr->mo->angle + (int) (ANGLE_MAX * -G_GetLookOffset(player)); + viewPitch = plr->plr->lookDir; + + DD_SetVariable(DD_VIEW_X, &viewPos[VX]); + DD_SetVariable(DD_VIEW_Y, &viewPos[VY]); + DD_SetVariable(DD_VIEW_Z, &viewPos[VZ]); + DD_SetVariable(DD_VIEW_ANGLE, &viewAngle); + DD_SetVariable(DD_VIEW_PITCH, &viewPitch); // $democam GL_SetFilter((plr->plr->flags & DDPF_VIEW_FILTER)? true : false); if(plr->plr->flags & DDPF_VIEW_FILTER) { - const float* color = plr->plr->filterColor; + const float* color = plr->plr->filterColor; GL_SetFilterColor(color[CR], color[CG], color[CB], color[CA]); } @@ -351,14 +356,6 @@ void D_Display(int layer) if(IS_CLIENT && (!Get(DD_GAME_READY) || !Get(DD_GOTFRAME))) return; - if(!IS_CLIENT && mapTime < 2) - { - // Don't render too early; the first couple of frames - // might be a bit unstable -- this should be considered - // a bug, but since there's an easy fix... - return; - } - rendPlayerView(player); R_DrawSpecialFilter(player); diff --git a/doomsday/plugins/jdoom/src/p_mobj.c b/doomsday/plugins/jdoom/src/p_mobj.c index 520986a8d9..ffc3ab8268 100644 --- a/doomsday/plugins/jdoom/src/p_mobj.c +++ b/doomsday/plugins/jdoom/src/p_mobj.c @@ -483,7 +483,7 @@ void P_MobjMoveZ(mobj_t* mo) // Squat down. // Decrease viewheight for a moment after hitting the ground // (hard), and utter appropriate sound. - mo->dPlayer->viewHeightDelta = mo->mom[MZ] / 8; + mo->player->viewHeightDelta = mo->mom[MZ] / 8; mo->player->jumpTics = 10; /** @@ -533,9 +533,9 @@ void P_MobjMoveZ(mobj_t* mo) if(mo->player && mo->player->plr->mo == mo && mo->pos[VZ] < mo->floorZ) { - mo->dPlayer->viewHeight -= mo->floorZ - mo->pos[VZ]; - mo->dPlayer->viewHeightDelta = - (cfg.plrViewHeight - mo->dPlayer->viewHeight) / 8; + mo->player->viewHeight -= (mo->floorZ - mo->pos[VZ]); + mo->player->viewHeightDelta = + (cfg.plrViewHeight - mo->player->viewHeight) / 8; } mo->pos[VZ] = floorZ; diff --git a/doomsday/plugins/jdoom/src/p_oldsvg.c b/doomsday/plugins/jdoom/src/p_oldsvg.c index 0d31953b4b..55b872fe85 100644 --- a/doomsday/plugins/jdoom/src/p_oldsvg.c +++ b/doomsday/plugins/jdoom/src/p_oldsvg.c @@ -109,9 +109,9 @@ static void SV_ReadPlayer(player_t* pl) SV_ReadLong(); pl->playerState = SV_ReadLong(); SV_Read(NULL, 8); - pl->plr->viewZ = FIX2FLT(SV_ReadLong()); - pl->plr->viewHeight = FIX2FLT(SV_ReadLong()); - pl->plr->viewHeightDelta = FIX2FLT(SV_ReadLong()); + pl->viewZ = FIX2FLT(SV_ReadLong()); + pl->viewHeight = FIX2FLT(SV_ReadLong()); + pl->viewHeightDelta = FIX2FLT(SV_ReadLong()); pl->bob = FLT2FIX(SV_ReadLong()); pl->flyHeight = 0; pl->health = SV_ReadLong(); diff --git a/doomsday/plugins/jdoom/src/p_telept.c b/doomsday/plugins/jdoom/src/p_telept.c index fd6704cc12..3652ddb9ce 100644 --- a/doomsday/plugins/jdoom/src/p_telept.c +++ b/doomsday/plugins/jdoom/src/p_telept.c @@ -196,8 +196,7 @@ int EV_Teleport(linedef_t* line, int side, mobj_t* mo, boolean spawnFog) //mo->dPlayer->clLookDir = 0; /* $unifiedangles */ mo->dPlayer->lookDir = 0; } - mo->dPlayer->viewZ = - mo->pos[VZ] + mo->dPlayer->viewHeight; + mo->player->viewZ = mo->pos[VZ] + mo->player->viewHeight; //mo->dPlayer->clAngle = mo->angle; /* $unifiedangles */ mo->dPlayer->flags |= diff --git a/doomsday/plugins/jdoom/src/st_stuff.c b/doomsday/plugins/jdoom/src/st_stuff.c index cc6539278a..24d2097a71 100644 --- a/doomsday/plugins/jdoom/src/st_stuff.c +++ b/doomsday/plugins/jdoom/src/st_stuff.c @@ -1406,7 +1406,7 @@ static void initData(hudstate_t* hud) hud->lastAttackDown = -1; hud->blended = false; hud->showBar = 0.f; - hud->statusbarCounterAlpha = 0.f; + hud->statusbarCounterAlpha = 1.f; for(i = 0; i < 3; ++i) { diff --git a/doomsday/plugins/jdoom64/include/d_player.h b/doomsday/plugins/jdoom64/include/d_player.h index c66608d1b0..dbbfed4b98 100644 --- a/doomsday/plugins/jdoom64/include/d_player.h +++ b/doomsday/plugins/jdoom64/include/d_player.h @@ -71,9 +71,6 @@ typedef struct player_s { playerclass_t class; // player class type playerbrain_t brain; - float viewOffset[3]; - float bob; // Bounded/scaled total momentum. - // This is only used between maps, mo->health is used during maps. int health; int armorPoints; @@ -130,15 +127,18 @@ typedef struct player_s { // True if secret map has been done. boolean didSecret; - // The player's view pitch is centering back to zero. - boolean centering; - - // The player can jump if this counter is zero. - int jumpTics; + int jumpTics; // The player can jump if this counter is zero. int airCounter; int rebornWait; // The player can be reborn if this counter is zero. + boolean centering; // The player's view pitch is centering back to zero. int update, startSpot; + float viewOffset[3]; // Relative to position of the player mobj. + float viewZ; // Focal origin above r.z. + float viewHeight; // Base height above floor for viewZ. + float viewHeightDelta; + float bob; // Bounded/scaled total momentum. + // Target view to a mobj (NULL=disabled). mobj_t* viewLock; // $democam int lockFull; diff --git a/doomsday/plugins/jdoom64/src/d_console.c b/doomsday/plugins/jdoom64/src/d_console.c index f4a6239eff..f6b2e90460 100644 --- a/doomsday/plugins/jdoom64/src/d_console.c +++ b/doomsday/plugins/jdoom64/src/d_console.c @@ -280,7 +280,7 @@ void G_UpdateEyeHeight(cvar_t* unused) player_t* plr = &players[CONSOLEPLAYER]; if(!(plr->plr->flags & DDPF_CAMERA)) - plr->plr->viewHeight = (float) cfg.plrViewHeight; + plr->viewHeight = (float) cfg.plrViewHeight; } /** diff --git a/doomsday/plugins/jdoom64/src/d_refresh.c b/doomsday/plugins/jdoom64/src/d_refresh.c index c27ddaceae..3f02a3c492 100644 --- a/doomsday/plugins/jdoom64/src/d_refresh.c +++ b/doomsday/plugins/jdoom64/src/d_refresh.c @@ -221,14 +221,12 @@ void R_SetViewSize(int blocks) static void rendPlayerView(int player) { - player_t* plr = &players[player]; - - int viewAngleOffset = - ANGLE_MAX * -G_GetLookOffset(player); - int isFullBright = - ((plr->powers[PT_INFRARED] > 4 * 32) || - (plr->powers[PT_INFRARED] & 8) || - plr->powers[PT_INVULNERABILITY] > 30); + player_t* plr = &players[player]; + float viewPos[3], viewPitch; + angle_t viewAngle; + int isFullBright = ((plr->powers[PT_INFRARED] > 4 * 32) || + (plr->powers[PT_INFRARED] & 8) || + plr->powers[PT_INVULNERABILITY] > 30); if(IS_CLIENT) { @@ -236,17 +234,23 @@ static void rendPlayerView(int player) R_SetAllDoomsdayFlags(); } - DD_SetVariable(DD_VIEWX_OFFSET, &plr->viewOffset[VX]); - DD_SetVariable(DD_VIEWY_OFFSET, &plr->viewOffset[VY]); - DD_SetVariable(DD_VIEWZ_OFFSET, &plr->viewOffset[VZ]); - // The view angle offset. - DD_SetVariable(DD_VIEWANGLE_OFFSET, &viewAngleOffset); + viewPos[VX] = plr->plr->mo->pos[VX] + plr->viewOffset[VX]; + viewPos[VY] = plr->plr->mo->pos[VY] + plr->viewOffset[VY]; + viewPos[VZ] = plr->viewZ + plr->viewOffset[VZ]; + viewAngle = plr->plr->mo->angle + (int) (ANGLE_MAX * -G_GetLookOffset(player)); + viewPitch = plr->plr->lookDir; + + DD_SetVariable(DD_VIEW_X, &viewPos[VX]); + DD_SetVariable(DD_VIEW_Y, &viewPos[VY]); + DD_SetVariable(DD_VIEW_Z, &viewPos[VZ]); + DD_SetVariable(DD_VIEW_ANGLE, &viewAngle); + DD_SetVariable(DD_VIEW_PITCH, &viewPitch); // $democam GL_SetFilter((plr->plr->flags & DDPF_VIEW_FILTER)? true : false); if(plr->plr->flags & DDPF_VIEW_FILTER) { - const float* color = plr->plr->filterColor; + const float* color = plr->plr->filterColor; GL_SetFilterColor(color[CR], color[CG], color[CB], color[CA]); } @@ -350,14 +354,6 @@ void D_Display(int layer) if(IS_CLIENT && (!Get(DD_GAME_READY) || !Get(DD_GOTFRAME))) return; - if(!IS_CLIENT && mapTime < 2) - { - // Don't render too early; the first couple of frames - // might be a bit unstable -- this should be considered - // a bug, but since there's an easy fix... - return; - } - rendPlayerView(player); R_DrawSpecialFilter(player); diff --git a/doomsday/plugins/jdoom64/src/p_mobj.c b/doomsday/plugins/jdoom64/src/p_mobj.c index 16a7df412f..44a74e2cd3 100644 --- a/doomsday/plugins/jdoom64/src/p_mobj.c +++ b/doomsday/plugins/jdoom64/src/p_mobj.c @@ -400,9 +400,9 @@ void P_MobjMoveZ(mobj_t* mo) if(mo->player && mo->player->plr->mo == mo && mo->pos[VZ] < mo->floorZ) { - mo->dPlayer->viewHeight -= mo->floorZ - mo->pos[VZ]; - mo->dPlayer->viewHeightDelta = - (cfg.plrViewHeight - mo->dPlayer->viewHeight) / 8; + mo->player->viewHeight -= mo->floorZ - mo->pos[VZ]; + mo->player->viewHeightDelta = + (cfg.plrViewHeight - mo->player->viewHeight) / 8; } // Adjust height. @@ -470,7 +470,7 @@ void P_MobjMoveZ(mobj_t* mo) // Squat down. // Decrease viewheight for a moment after hitting the ground // (hard), and utter appropriate sound. - mo->dPlayer->viewHeightDelta = mo->mom[MZ] / 8; + mo->player->viewHeightDelta = mo->mom[MZ] / 8; if(mo->player->health > 0) S_StartSound(SFX_OOF, mo); @@ -553,7 +553,7 @@ void P_MobjMoveZ(mobj_t* mo) // Squat down. // Decrease viewheight for a moment after hitting the ground // (hard), and utter appropriate sound. - mo->dPlayer->viewHeightDelta = mo->mom[MZ] / 8; + mo->player->viewHeightDelta = mo->mom[MZ] / 8; mo->player->jumpTics = 10; /** diff --git a/doomsday/plugins/jdoom64/src/p_telept.c b/doomsday/plugins/jdoom64/src/p_telept.c index 45f1ca4313..c535dbddbf 100644 --- a/doomsday/plugins/jdoom64/src/p_telept.c +++ b/doomsday/plugins/jdoom64/src/p_telept.c @@ -198,8 +198,7 @@ int EV_Teleport(linedef_t* line, int side, mobj_t* mo, boolean spawnFog) //mo->dPlayer->clLookDir = 0; /* $unifiedangles */ mo->dPlayer->lookDir = 0; } - mo->dPlayer->viewZ = - mo->pos[VZ] + mo->dPlayer->viewHeight; + mo->player->viewZ = mo->pos[VZ] + mo->player->viewHeight; //mo->dPlayer->clAngle = mo->angle; /* $unifiedangles */ mo->dPlayer->flags |= diff --git a/doomsday/plugins/jheretic/include/h_player.h b/doomsday/plugins/jheretic/include/h_player.h index 2a55121340..9e45de4b53 100644 --- a/doomsday/plugins/jheretic/include/h_player.h +++ b/doomsday/plugins/jheretic/include/h_player.h @@ -80,9 +80,6 @@ typedef struct player_s { playerclass_t class; // Player class. playerbrain_t brain; - float viewOffset[3]; - float bob; // bounded/scaled total momentum - // This is only used between levels, // mo->health is used during levels. int health; @@ -139,15 +136,18 @@ typedef struct player_s { // True if secret level has been done. boolean didSecret; - // The player's view pitch is centering back to zero. - boolean centering; - - // The player can jump if this counter is zero. - int jumpTics; + int jumpTics; // The player can jump if this counter is zero. int airCounter; int rebornWait; // The player can be reborn if this counter is zero. + boolean centering; // The player's view pitch is centering back to zero. int update, startSpot; + float viewOffset[3]; // Relative to position of the player mobj. + float viewZ; // Focal origin above r.z. + float viewHeight; // Base height above floor for viewZ. + float viewHeightDelta; + float bob; // Bounded/scaled total momentum. + // Target view to a mobj (NULL=disabled). mobj_t* viewLock; // $democam int lockFull; diff --git a/doomsday/plugins/jheretic/src/h_console.c b/doomsday/plugins/jheretic/src/h_console.c index da6205aa4f..f8efba5fbc 100644 --- a/doomsday/plugins/jheretic/src/h_console.c +++ b/doomsday/plugins/jheretic/src/h_console.c @@ -271,7 +271,7 @@ void G_UpdateEyeHeight(cvar_t* unused) player_t* plr = &players[CONSOLEPLAYER]; if(!(plr->plr->flags & DDPF_CAMERA)) - plr->plr->viewHeight = (float) cfg.plrViewHeight; + plr->viewHeight = (float) cfg.plrViewHeight; } /** diff --git a/doomsday/plugins/jheretic/src/h_refresh.c b/doomsday/plugins/jheretic/src/h_refresh.c index b51bb49556..4d688e71d5 100644 --- a/doomsday/plugins/jheretic/src/h_refresh.c +++ b/doomsday/plugins/jheretic/src/h_refresh.c @@ -176,12 +176,11 @@ void R_SetViewSize(int blocks) static void rendPlayerView(int player) { - player_t* plr = &players[player]; - int viewAngleOffset = - ANGLE_MAX * -G_GetLookOffset(player); - boolean isFullBright = - (plr->powers[PT_INVULNERABILITY] > BLINKTHRESHOLD) || - (plr->powers[PT_INVULNERABILITY] & 8); + player_t* plr = &players[player]; + float viewPos[3], viewPitch; + angle_t viewAngle; + boolean isFullBright = (plr->powers[PT_INVULNERABILITY] > BLINKTHRESHOLD) || + (plr->powers[PT_INVULNERABILITY] & 8); if(IS_CLIENT) { @@ -189,17 +188,23 @@ static void rendPlayerView(int player) R_SetAllDoomsdayFlags(); } - DD_SetVariable(DD_VIEWX_OFFSET, &plr->viewOffset[VX]); - DD_SetVariable(DD_VIEWY_OFFSET, &plr->viewOffset[VY]); - DD_SetVariable(DD_VIEWZ_OFFSET, &plr->viewOffset[VZ]); - // The view angle offset. - DD_SetVariable(DD_VIEWANGLE_OFFSET, &viewAngleOffset); + viewPos[VX] = plr->plr->mo->pos[VX] + plr->viewOffset[VX]; + viewPos[VY] = plr->plr->mo->pos[VY] + plr->viewOffset[VY]; + viewPos[VZ] = plr->viewZ + plr->viewOffset[VZ]; + viewAngle = plr->plr->mo->angle + (int) (ANGLE_MAX * -G_GetLookOffset(player)); + viewPitch = plr->plr->lookDir; + + DD_SetVariable(DD_VIEW_X, &viewPos[VX]); + DD_SetVariable(DD_VIEW_Y, &viewPos[VY]); + DD_SetVariable(DD_VIEW_Z, &viewPos[VZ]); + DD_SetVariable(DD_VIEW_ANGLE, &viewAngle); + DD_SetVariable(DD_VIEW_PITCH, &viewPitch); // $democam GL_SetFilter((plr->plr->flags & DDPF_VIEW_FILTER)? true : false); if(plr->plr->flags & DDPF_VIEW_FILTER) { - const float* color = plr->plr->filterColor; + const float* color = plr->plr->filterColor; GL_SetFilterColor(color[CR], color[CG], color[CB], color[CA]); } @@ -306,14 +311,6 @@ void H_Display(int layer) if(IS_CLIENT && (!Get(DD_GAME_READY) || !Get(DD_GOTFRAME))) return; - if(!IS_CLIENT && mapTime < 2) - { - // Don't render too early; the first couple of frames - // might be a bit unstable -- this should be considered - // a bug, but since there's an easy fix... - return; - } - rendPlayerView(player); R_DrawSpecialFilter(player); diff --git a/doomsday/plugins/jheretic/src/p_enemy.c b/doomsday/plugins/jheretic/src/p_enemy.c index be3bf32b56..396b074c0d 100644 --- a/doomsday/plugins/jheretic/src/p_enemy.c +++ b/doomsday/plugins/jheretic/src/p_enemy.c @@ -1411,7 +1411,7 @@ void C_DECL A_MinotaurAtk1(mobj_t* actor) if((player = actor->target->player) != NULL) { // Squish the player. - player->plr->viewHeightDelta = -16; + player->viewHeightDelta = -16; } } } @@ -1536,7 +1536,7 @@ void C_DECL A_MinotaurAtk3(mobj_t* actor) if((player = actor->target->player) != NULL) { // Squish the player. - player->plr->viewHeightDelta = -16; + player->viewHeightDelta = -16; } } else diff --git a/doomsday/plugins/jheretic/src/p_mobj.c b/doomsday/plugins/jheretic/src/p_mobj.c index ed476eae91..d8906d6007 100644 --- a/doomsday/plugins/jheretic/src/p_mobj.c +++ b/doomsday/plugins/jheretic/src/p_mobj.c @@ -567,10 +567,9 @@ void P_MobjMoveZ(mobj_t *mo) // Check for smooth step up. if(mo->player && mo->pos[VZ] < mo->floorZ) { - mo->dPlayer->viewHeight -= mo->floorZ - mo->pos[VZ]; - - mo->dPlayer->viewHeightDelta = - (cfg.plrViewHeight - mo->dPlayer->viewHeight) / 8; + mo->player->viewHeight -= mo->floorZ - mo->pos[VZ]; + mo->player->viewHeightDelta = + (cfg.plrViewHeight - mo->player->viewHeight) / 8; } // Adjust height. @@ -625,7 +624,7 @@ void P_MobjMoveZ(mobj_t *mo) { // Squat down. Decrease viewheight for a moment after // hitting the ground (hard), and utter appropriate sound. - mo->dPlayer->viewHeightDelta = mo->mom[MZ] / 8; + mo->player->viewHeightDelta = mo->mom[MZ] / 8; if(mo->player->health > 0) S_StartSound(SFX_PLROOF, mo); @@ -684,7 +683,7 @@ void P_MobjMoveZ(mobj_t *mo) { // Squat down. Decrease viewheight for a moment after // hitting the ground hard and utter appropriate sound. - mo->player->plr->viewHeightDelta = mo->mom[MZ] / 8; + mo->player->viewHeightDelta = mo->mom[MZ] / 8; #if __JHERETIC__ mo->player->jumpTics = 12; // Can't jump in a while. #endif diff --git a/doomsday/plugins/jheretic/src/p_oldsvg.c b/doomsday/plugins/jheretic/src/p_oldsvg.c index bbaf0d600d..7f1f55d9c7 100644 --- a/doomsday/plugins/jheretic/src/p_oldsvg.c +++ b/doomsday/plugins/jheretic/src/p_oldsvg.c @@ -110,9 +110,9 @@ static void SV_v13_ReadPlayer(player_t* pl) SV_v13_ReadLong(); // mo pl->playerState = SV_v13_ReadLong(); SV_v13_Read(temp, 10); // ticcmd_t - ddpl->viewZ = FIX2FLT(SV_v13_ReadLong()); - ddpl->viewHeight = FIX2FLT(SV_v13_ReadLong()); - ddpl->viewHeightDelta = FIX2FLT(SV_v13_ReadLong()); + pl->viewZ = FIX2FLT(SV_v13_ReadLong()); + pl->viewHeight = FIX2FLT(SV_v13_ReadLong()); + pl->viewHeightDelta = FIX2FLT(SV_v13_ReadLong()); pl->bob = FIX2FLT(SV_v13_ReadLong()); pl->flyHeight = SV_v13_ReadLong(); ddpl->lookDir = SV_v13_ReadLong(); diff --git a/doomsday/plugins/jheretic/src/p_telept.c b/doomsday/plugins/jheretic/src/p_telept.c index e023c815c3..81474d5f68 100644 --- a/doomsday/plugins/jheretic/src/p_telept.c +++ b/doomsday/plugins/jheretic/src/p_telept.c @@ -89,12 +89,12 @@ boolean P_Teleport(mobj_t* thing, float x, float y, angle_t angle, { thing->pos[VZ] = thing->ceilingZ - thing->height; } - player->plr->viewZ = thing->pos[VZ] + player->plr->viewHeight; + player->viewZ = thing->pos[VZ] + player->viewHeight; } else { thing->pos[VZ] = thing->floorZ; - player->plr->viewZ = thing->pos[VZ] + player->plr->viewHeight; + player->viewZ = thing->pos[VZ] + player->viewHeight; //player->plr->clLookDir = 0; /* $unifiedangles */ player->plr->lookDir = 0; } diff --git a/doomsday/plugins/jhexen/include/x_player.h b/doomsday/plugins/jhexen/include/x_player.h index fe0613cacb..601691913d 100644 --- a/doomsday/plugins/jhexen/include/x_player.h +++ b/doomsday/plugins/jhexen/include/x_player.h @@ -75,11 +75,7 @@ typedef struct player_s { playerclass_t class; // Player class type. playerbrain_t brain; - float viewOffset[3]; - float bob; // Bounded/scaled total momentum. - int flyHeight; - boolean centering; int health; // Only used between maps, mo->health is used during. int armorPoints[NUMARMOR]; @@ -112,8 +108,16 @@ typedef struct player_s { int jumpTics; // Delay the next jump for a moment. int airCounter; int rebornWait; // The player can be reborn if this counter is zero. + boolean centering; unsigned int worldTimer; // Total time the player's been playing. int update, startSpot; + + float viewOffset[3]; // Relative to position of the player mobj. + float viewZ; // Focal origin above r.z. + float viewHeight; // Base height above floor for viewZ. + float viewHeightDelta; + float bob; // Bounded/scaled total momentum. + // Target view to a mobj (NULL=disabled). mobj_t* viewLock; // $democam int lockFull; diff --git a/doomsday/plugins/jhexen/src/hconsole.c b/doomsday/plugins/jhexen/src/hconsole.c index 3907cbe095..18ea062813 100644 --- a/doomsday/plugins/jhexen/src/hconsole.c +++ b/doomsday/plugins/jhexen/src/hconsole.c @@ -259,7 +259,7 @@ void G_UpdateEyeHeight(cvar_t* unused) player_t* plr = &players[CONSOLEPLAYER]; if(!(plr->plr->flags & DDPF_CAMERA)) - plr->plr->viewHeight = (float) cfg.plrViewHeight; + plr->viewHeight = (float) cfg.plrViewHeight; } /** diff --git a/doomsday/plugins/jhexen/src/hrefresh.c b/doomsday/plugins/jhexen/src/hrefresh.c index eaad9033e1..9f714bc9e0 100644 --- a/doomsday/plugins/jhexen/src/hrefresh.c +++ b/doomsday/plugins/jhexen/src/hrefresh.c @@ -142,10 +142,10 @@ void R_DrawMapTitle(void) static void rendPlayerView(int player) { - player_t* plr = &players[player]; - boolean special200 = false; - int viewAngleOffset = - ANGLE_MAX * -G_GetLookOffset(player); + player_t* plr = &players[player]; + boolean special200 = false; + float viewPos[3], viewPitch; + angle_t viewAngle; if(IS_CLIENT) { @@ -165,8 +165,7 @@ static void rendPlayerView(int player) // How about a bit of quake? if(localQuakeHappening[player] && !P_IsPaused()) { - int intensity = - localQuakeHappening[player]; + int intensity = localQuakeHappening[player]; plr->viewOffset[VX] = (float) ((M_Random() % (intensity << 2)) - (intensity << 1)); @@ -178,17 +177,23 @@ static void rendPlayerView(int player) plr->viewOffset[VX] = plr->viewOffset[VY] = 0; } - DD_SetVariable(DD_VIEWX_OFFSET, &plr->viewOffset[VX]); - DD_SetVariable(DD_VIEWY_OFFSET, &plr->viewOffset[VY]); - DD_SetVariable(DD_VIEWZ_OFFSET, &plr->viewOffset[VZ]); - // The view angle offset. - DD_SetVariable(DD_VIEWANGLE_OFFSET, &viewAngleOffset); + viewPos[VX] = plr->plr->mo->pos[VX] + plr->viewOffset[VX]; + viewPos[VY] = plr->plr->mo->pos[VY] + plr->viewOffset[VY]; + viewPos[VZ] = plr->viewZ + plr->viewOffset[VZ]; + viewAngle = plr->plr->mo->angle + (int) (ANGLE_MAX * -G_GetLookOffset(player)); + viewPitch = plr->plr->lookDir; + + DD_SetVariable(DD_VIEW_X, &viewPos[VX]); + DD_SetVariable(DD_VIEW_Y, &viewPos[VY]); + DD_SetVariable(DD_VIEW_Z, &viewPos[VZ]); + DD_SetVariable(DD_VIEW_ANGLE, &viewAngle); + DD_SetVariable(DD_VIEW_PITCH, &viewPitch); // $democam GL_SetFilter((plr->plr->flags & DDPF_VIEW_FILTER)? true : false); if(plr->plr->flags & DDPF_VIEW_FILTER) { - const float* color = plr->plr->filterColor; + const float* color = plr->plr->filterColor; GL_SetFilterColor(color[CR], color[CG], color[CB], color[CA]); } @@ -299,14 +304,6 @@ void G_Display(int layer) if(IS_CLIENT && (!Get(DD_GAME_READY) || !Get(DD_GOTFRAME))) return; - if(!IS_CLIENT && mapTime < 2) - { - // Don't render too early; the first couple of frames - // might be a bit unstable -- this should be considered - // a bug, but since there's an easy fix... - return; - } - rendPlayerView(player); // Crosshair. diff --git a/doomsday/plugins/jhexen/src/p_enemy.c b/doomsday/plugins/jhexen/src/p_enemy.c index 87c79e9bac..e78ea510a4 100644 --- a/doomsday/plugins/jhexen/src/p_enemy.c +++ b/doomsday/plugins/jhexen/src/p_enemy.c @@ -1316,7 +1316,7 @@ void C_DECL A_MinotaurAtk3(mobj_t *actor) P_DamageMobj(actor->target, actor, actor, HITDICE(3), false); if((player = actor->target->player) != NULL) { // Squish the player. - player->plr->viewHeightDelta = -16; + player->viewHeightDelta = -16; } } else diff --git a/doomsday/plugins/jhexen/src/p_mobj.c b/doomsday/plugins/jhexen/src/p_mobj.c index 1bcf82840b..9bf695df9e 100644 --- a/doomsday/plugins/jhexen/src/p_mobj.c +++ b/doomsday/plugins/jhexen/src/p_mobj.c @@ -738,9 +738,9 @@ void P_MobjMoveZ(mobj_t *mo) // Check for smooth step up. if(mo->player && mo->pos[VZ] < mo->floorZ) { - mo->player->plr->viewHeight -= mo->floorZ - mo->pos[VZ]; - mo->player->plr->viewHeightDelta = - (cfg.plrViewHeight - mo->player->plr->viewHeight) / 8; + mo->player->viewHeight -= mo->floorZ - mo->pos[VZ]; + mo->player->viewHeightDelta = + (cfg.plrViewHeight - mo->player->viewHeight) / 8; } // Adjust height. @@ -834,7 +834,7 @@ void P_MobjMoveZ(mobj_t *mo) mo->player->jumpTics = 7; // delay any jumping for a short time if(mo->mom[MZ] < -gravity * 8 && !(mo->flags2 & MF2_FLY)) { // Squat down. - mo->player->plr->viewHeightDelta = mo->mom[MZ] / 8; + mo->player->viewHeightDelta = mo->mom[MZ] / 8; if(mo->mom[MZ] < -23) { P_FallingDamage(mo->player); @@ -977,7 +977,7 @@ static void landedOnThing(mobj_t* mo) if(mo->player) return; // We are only interested in players. - mo->player->plr->viewHeightDelta = mo->mom[MZ] / 8; + mo->player->viewHeightDelta = mo->mom[MZ] / 8; if(mo->mom[MZ] < -23) { P_FallingDamage(mo->player); @@ -1157,10 +1157,10 @@ void P_MobjThinker(mobj_t* mobj) { if(mobj->player) { - mobj->player->plr->viewHeight -= + mobj->player->viewHeight -= mobj->onMobj->pos[VZ] + mobj->onMobj->height - mobj->pos[VZ]; - mobj->player->plr->viewHeightDelta = - (cfg.plrViewHeight - mobj->player->plr->viewHeight) / 8; + mobj->player->viewHeightDelta = + (cfg.plrViewHeight - mobj->player->viewHeight) / 8; } mobj->pos[VZ] = mobj->onMobj->pos[VZ] + mobj->onMobj->height; diff --git a/doomsday/plugins/jhexen/src/p_telept.c b/doomsday/plugins/jhexen/src/p_telept.c index 7ac2864ebc..b2000787c0 100644 --- a/doomsday/plugins/jhexen/src/p_telept.c +++ b/doomsday/plugins/jhexen/src/p_telept.c @@ -131,12 +131,12 @@ boolean P_Teleport(mobj_t* mo, float x, float y, angle_t angle, { mo->pos[VZ] = mo->ceilingZ - mo->height; } - player->plr->viewZ = mo->pos[VZ] + player->plr->viewHeight; + player->viewZ = mo->pos[VZ] + player->viewHeight; } else { mo->pos[VZ] = mo->floorZ; - player->plr->viewZ = mo->pos[VZ] + player->plr->viewHeight; + player->viewZ = mo->pos[VZ] + player->viewHeight; if(useFog) { player->plr->lookDir = 0;