diff --git a/src/am_map.cpp b/src/am_map.cpp index e71177860..172f31bde 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -1953,13 +1953,13 @@ void AM_drawSubsectors() double secx; double secy; double seczb, seczt; - double cmpz = FIXED2DBL(viewz); + double cmpz = ViewPos.Z; if (players[consoleplayer].camera && sec == players[consoleplayer].camera->Sector) { // For the actual camera sector use the current viewpoint as reference. - secx = FIXED2DBL(viewx); - secy = FIXED2DBL(viewy); + secx = ViewPos.X; + secy = ViewPos.Y; } else { diff --git a/src/m_fixed.h b/src/m_fixed.h index 1a2e8b780..506b9702c 100644 --- a/src/m_fixed.h +++ b/src/m_fixed.h @@ -156,6 +156,11 @@ inline double AngleToFloat(unsigned f) return f * (90. / 0x40000000); } +inline double AngleToFloat(int f) +{ + return f * (90. / 0x40000000); +} + #define FLOAT2FIXED(f) FloatToFixed(f) #define FIXED2FLOAT(f) float(FixedToFloat(f)) #define FIXED2DBL(f) FixedToFloat(f) diff --git a/src/p_effect.cpp b/src/p_effect.cpp index e84cf8e3c..f71a822f3 100644 --- a/src/p_effect.cpp +++ b/src/p_effect.cpp @@ -692,7 +692,7 @@ void P_DrawRailTrail(AActor *source, const DVector3 &start, const DVector3 &end, point = start + r * dir; dir.Z = dirz; - S_Sound (DVector3(point.X, point.Y, viewz), CHAN_WEAPON, sound, 1, ATTN_NORM); + S_Sound (DVector3(point.X, point.Y, ViewPos.Z), CHAN_WEAPON, sound, 1, ATTN_NORM); } } } diff --git a/src/p_maputl.h b/src/p_maputl.h index d53ab49a7..e075f5f6d 100644 --- a/src/p_maputl.h +++ b/src/p_maputl.h @@ -38,12 +38,12 @@ struct intercept_t inline int P_PointOnLineSidePrecise(double x, double y, const line_t *line) { - return (y - line->v1->fY()) * line->Delta().X + (line->v1->fX() - x) * line->Delta().Y > -EQUAL_EPSILON; + return (y - line->v1->fY()) * line->Delta().X + (line->v1->fX() - x) * line->Delta().Y > EQUAL_EPSILON; } inline int P_PointOnLineSidePrecise(const DVector2 &pt, const line_t *line) { - return (pt.Y - line->v1->fY()) * line->Delta().X + (line->v1->fX() - pt.X) * line->Delta().Y > -EQUAL_EPSILON; + return (pt.Y - line->v1->fY()) * line->Delta().X + (line->v1->fX() - pt.X) * line->Delta().Y > EQUAL_EPSILON; } inline int P_PointOnLineSide (double x, double y, const line_t *line) @@ -73,12 +73,12 @@ inline int P_PointOnLineSide(const DVector2 & p, const line_t *line) inline int P_PointOnDivlineSide(double x, double y, const divline_t *line) { - return (y - line->y) * line->dx + (line->x - x) * line->dy > -EQUAL_EPSILON; + return (y - line->y) * line->dx + (line->x - x) * line->dy > EQUAL_EPSILON; } inline int P_PointOnDivlineSide(const DVector2 &pos, const divline_t *line) { - return (pos.Y - line->y) * line->dx + (line->x - pos.X) * line->dy > -EQUAL_EPSILON; + return (pos.Y - line->y) * line->dx + (line->x - pos.X) * line->dy > EQUAL_EPSILON; } //========================================================================== diff --git a/src/posix/sdl/i_main.cpp b/src/posix/sdl/i_main.cpp index 7c08dacdb..54d2c2705 100644 --- a/src/posix/sdl/i_main.cpp +++ b/src/posix/sdl/i_main.cpp @@ -180,10 +180,10 @@ static int DoomSpecificInfo (char *buffer, char *end) } else { - p += snprintf (buffer+p, size-p, "\n\nviewx = %d", (int)viewx); - p += snprintf (buffer+p, size-p, "\nviewy = %d", (int)viewy); - p += snprintf (buffer+p, size-p, "\nviewz = %d", (int)viewz); - p += snprintf (buffer+p, size-p, "\nviewangle = %x", (unsigned int)viewangle); + p += snprintf (buffer+p, size-p, "\n\nviewx = %f", ViewPos.X); + p += snprintf (buffer+p, size-p, "\nviewy = %f", ViewPos.Y); + p += snprintf (buffer+p, size-p, "\nviewz = %f", ViewPos.Z); + p += snprintf (buffer+p, size-p, "\nviewangle = %f", ViewAngle.Degrees); } } buffer[p++] = '\n'; diff --git a/src/r_bsp.cpp b/src/r_bsp.cpp index e50642347..d0ca0a2f4 100644 --- a/src/r_bsp.cpp +++ b/src/r_bsp.cpp @@ -38,6 +38,7 @@ #include "p_lnspec.h" #include "p_setup.h" +#include "r_local.h" #include "r_main.h" #include "r_plane.h" #include "r_draw.h" diff --git a/src/r_defs.h b/src/r_defs.h index 4aa0f9d53..f6ff54387 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -352,6 +352,12 @@ public: return TMulScale16(a,x, b,y, c,z) + d; } + int PointOnSide(const DVector3 &pos) const + { + double v = a * pos.X + b * pos.Y + c * pos.Z; + return v < -EQUAL_EPSILON ? -1 : v > EQUAL_EPSILON ? 1 : 0; + } + // Returns the value of z at (0,0) This is used by the 3D floor code which does not handle slopes fixed_t Zat0 () const { @@ -375,6 +381,13 @@ public: return (d + a*pos.X + b*pos.Y) * ic / (-65536.0 * 65536.0); } + // This is for the software renderer + fixed_t ZatPointFixed(const DVector2 &pos) const + { + return xs_CRoundToInt((d + a*pos.X + b*pos.Y) * ic / (-65536.0)); + } + + double ZatPoint(const vertex_t *v) const { return FIXED2DBL(FixedMul(ic, -d - DMulScale16(a, v->fixX(), b, v->fixY()))); diff --git a/src/r_local.h b/src/r_local.h index 7977e6923..17f413572 100644 --- a/src/r_local.h +++ b/src/r_local.h @@ -38,4 +38,8 @@ #include "r_things.h" #include "r_draw.h" +extern fixed_t viewx, viewy, viewz; +extern angle_t viewangle; +extern int viewpitch; + #endif // __R_LOCAL_H__ diff --git a/src/r_main.cpp b/src/r_main.cpp index 80e2eb859..599b682d5 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -68,6 +68,10 @@ #define TEST_ANGLE 2468347904 #endif +fixed_t viewx, viewy, viewz; +angle_t viewangle; +int viewpitch; + // TYPES ------------------------------------------------------------------- // EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- @@ -550,6 +554,12 @@ void R_SetupColormap(player_t *player) void R_SetupFreelook() { + viewx = FLOAT2FIXED(ViewPos.X); + viewy = FLOAT2FIXED(ViewPos.Y); + viewz = FLOAT2FIXED(ViewPos.Z); + viewangle = ViewAngle.BAMs(); + viewpitch = ViewPitch.BAMs(); + { fixed_t dy; @@ -727,6 +737,7 @@ void R_EnterPortal (PortalDrawseg* pds, int depth) viewx = FLOAT2FIXED((x1 + r * dx)*2 - x); viewy = FLOAT2FIXED((y1 + r * dy)*2 - y); } + ViewAngle = pds->src->Delta().Angle(); viewangle = 2*R_PointToAngle2 (pds->src->v1->fixX(), pds->src->v1->fixY(), pds->src->v2->fixX(), pds->src->v2->fixY()) - startang; @@ -743,6 +754,7 @@ void R_EnterPortal (PortalDrawseg* pds, int depth) viewz = FLOAT2FIXED(view.Z); viewangle = va.BAMs(); } + ViewAngle = AngleToFloat(viewangle); viewsin = finesine[viewangle>>ANGLETOFINESHIFT]; viewcos = finecosine[viewangle>>ANGLETOFINESHIFT]; @@ -821,6 +833,7 @@ void R_EnterPortal (PortalDrawseg* pds, int depth) viewx = startx; viewy = starty; viewz = startz; + ViewAngle = AngleToFloat(viewangle); } //========================================================================== diff --git a/src/r_plane.cpp b/src/r_plane.cpp index fe387509f..61b969a4e 100644 --- a/src/r_plane.cpp +++ b/src/r_plane.cpp @@ -1082,6 +1082,7 @@ void R_DrawHeightPlanes(fixed_t height) viewy = pl->viewy; viewz = pl->viewz; viewangle = pl->viewangle; + ViewAngle = AngleToFloat(viewangle); MirrorFlags = pl->MirrorFlags; R_DrawSinglePlane (pl, pl->sky & 0x7FFFFFFF, pl->Additive, true); } @@ -1092,6 +1093,7 @@ void R_DrawHeightPlanes(fixed_t height) viewy = oViewY; viewz = oViewZ; viewangle = oViewAngle; + ViewAngle = AngleToFloat(viewangle); } @@ -1248,11 +1250,12 @@ void R_DrawSkyBoxes () { extralight = pl->extralight; R_SetVisibility (pl->visibility); - viewx = pl->viewx - FLOAT2FIXED(sky->Mate->X() + sky->X()); - viewy = pl->viewy - FLOAT2FIXED(sky->Mate->Y() + sky->Y()); + viewx = pl->viewx + FLOAT2FIXED(-sky->Mate->X() + sky->X()); + viewy = pl->viewy + FLOAT2FIXED(-sky->Mate->Y() + sky->Y()); viewz = pl->viewz; viewangle = pl->viewangle; } + ViewAngle = AngleToFloat(viewangle); sky->bInSkybox = true; if (mate != NULL) mate->bInSkybox = true; @@ -1367,6 +1370,7 @@ void R_DrawSkyBoxes () R_SetVisibility (savedvisibility); extralight = savedextralight; viewangle = savedangle; + ViewAngle = AngleToFloat(viewangle); R_SetViewAngle (); CurrentPortalInSkybox = false; diff --git a/src/r_things.cpp b/src/r_things.cpp index 0e4e717f6..e6b4a68c6 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -802,7 +802,7 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor { // choose a different rotation based on player view spriteframe_t *sprframe = &SpriteFrames[tex->Rotations]; - angle_t ang = R_PointToAngle (fx, fy); + angle_t ang = R_PointToAngle2 (viewx, viewy, fx, fy); angle_t rot; if (sprframe->Texture[0] == sprframe->Texture[1]) { @@ -841,7 +841,7 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor //picnum = SpriteFrames[sprdef->spriteframes + thing->frame].Texture[0]; // choose a different rotation based on player view spriteframe_t *sprframe = &SpriteFrames[sprdef->spriteframes + thing->frame]; - angle_t ang = R_PointToAngle (fx, fy); + angle_t ang = R_PointToAngle2 (viewx, viewy, fx, fy); angle_t rot; if (sprframe->Texture[0] == sprframe->Texture[1]) { diff --git a/src/r_utility.cpp b/src/r_utility.cpp index 148ee9d52..eaf1ef2a7 100644 --- a/src/r_utility.cpp +++ b/src/r_utility.cpp @@ -70,12 +70,15 @@ EXTERN_CVAR (Bool, cl_capfps) struct InterpolationViewer { + struct instance + { + DVector3 Pos; + DRotator Angles; + }; + AActor *ViewActor; int otic; - fixed_t oviewx, oviewy, oviewz; - fixed_t nviewx, nviewy, nviewz; - int oviewpitch, nviewpitch; - angle_t oviewangle, nviewangle; + instance Old, New; }; // PRIVATE DATA DECLARATIONS ----------------------------------------------- @@ -102,11 +105,9 @@ DCanvas *RenderTarget; // [RH] canvas to render to int viewwindowx; int viewwindowy; -fixed_t viewx; -fixed_t viewy; -fixed_t viewz; -int viewpitch; -angle_t viewangle; +DVector3 ViewPos; +DAngle ViewAngle; +DAngle ViewPitch; extern "C" { @@ -574,27 +575,20 @@ EXTERN_CVAR (Bool, cl_noprediction) void R_InterpolateView (player_t *player, double Frac, InterpolationViewer *iview) { - fixed_t frac = FLOAT2FIXED(Frac); if (NoInterpolateView) { InterpolationPath.Clear(); NoInterpolateView = false; - iview->oviewx = iview->nviewx; - iview->oviewy = iview->nviewy; - iview->oviewz = iview->nviewz; - iview->oviewpitch = iview->nviewpitch; - iview->oviewangle = iview->nviewangle; + iview->Old = iview->New; } - int oldgroup = R_PointInSubsector(iview->oviewx, iview->oviewy)->sector->PortalGroup; - int newgroup = R_PointInSubsector(iview->nviewx, iview->nviewy)->sector->PortalGroup; + int oldgroup = R_PointInSubsector(iview->Old.Pos)->sector->PortalGroup; + int newgroup = R_PointInSubsector(iview->New.Pos)->sector->PortalGroup; - fixed_t oviewangle = iview->oviewangle; - fixed_t nviewangle = iview->nviewangle; - if ((iview->oviewx != iview->nviewx || iview->oviewy != iview->nviewy) && InterpolationPath.Size() > 0) + DAngle oviewangle = iview->Old.Angles.Yaw; + DAngle nviewangle = iview->New.Angles.Yaw; + if ((iview->Old.Pos.X != iview->New.Pos.X || iview->Old.Pos.Y != iview->New.Pos.Y) && InterpolationPath.Size() > 0) { - viewx = iview->nviewx; - viewy = iview->nviewy; - viewz = iview->nviewz; + DVector3 view = iview->New.Pos; // Interpolating through line portals is a messy affair. // What needs be done is to store the portal transitions of the camera actor as waypoints @@ -602,49 +596,47 @@ void R_InterpolateView (player_t *player, double Frac, InterpolationViewer *ivie // Needless to say, this doesn't work for chasecam mode. if (!r_showviewer) { - fixed_t pathlen = 0; - fixed_t zdiff = 0; - fixed_t totalzdiff = 0; - angle_t adiff = 0; - angle_t totaladiff = 0; - fixed_t oviewz = iview->oviewz; - fixed_t nviewz = iview->nviewz; - DVector3a oldpos = { {FIXED2DBL(iview->oviewx), FIXED2DBL(iview->oviewy), 0.}, 0. }; - DVector3a newpos = { {FIXED2DBL(iview->nviewx), FIXED2DBL(iview->nviewy), 0. }, 0. }; + double pathlen = 0; + double zdiff = 0; + double totalzdiff = 0; + DAngle adiff = 0.; + DAngle totaladiff = 0.; + double oviewz = iview->Old.Pos.Z; + double nviewz = iview->New.Pos.Z; + DVector3a oldpos = { { iview->Old.Pos.X, iview->Old.Pos.Y, 0 }, 0. }; + DVector3a newpos = { { iview->New.Pos.X, iview->New.Pos.Y, 0 }, 0. }; InterpolationPath.Push(newpos); // add this to the array to simplify the loops below for (unsigned i = 0; i < InterpolationPath.Size(); i += 2) { DVector3a &start = i == 0 ? oldpos : InterpolationPath[i - 1]; DVector3a &end = InterpolationPath[i]; - pathlen += FLOAT2FIXED((end.pos-start.pos).Length()); - totalzdiff += FLOAT2FIXED(start.pos.Z); - totaladiff += start.angle.BAMs(); + pathlen += (end.pos-start.pos).Length(); + totalzdiff += start.pos.Z; + totaladiff += start.angle; } - fixed_t interpolatedlen = FixedMul(frac, pathlen); + double interpolatedlen = Frac * pathlen; for (unsigned i = 0; i < InterpolationPath.Size(); i += 2) { DVector3a &start = i == 0 ? oldpos : InterpolationPath[i - 1]; DVector3a &end = InterpolationPath[i]; - fixed_t fraglen = FLOAT2FIXED((end.pos - start.pos).Length()); - zdiff += FLOAT2FIXED(start.pos.Z); - adiff += start.angle.BAMs(); + double fraglen = (end.pos - start.pos).Length(); + zdiff += start.pos.Z; + adiff += start.angle; if (fraglen <= interpolatedlen) { interpolatedlen -= fraglen; } else { - double fragfrac = FIXED2DBL(FixedDiv(interpolatedlen, fraglen)); + double fragfrac = interpolatedlen / fraglen; oviewz += zdiff; nviewz -= totalzdiff - zdiff; oviewangle += adiff; nviewangle -= totaladiff - adiff; DVector2 viewpos = start.pos + (fragfrac * (end.pos - start.pos)); - viewx = FLOAT2FIXED(viewpos.X); - viewy = FLOAT2FIXED(viewpos.Y); - viewz = oviewz + FixedMul(frac, nviewz - oviewz); + ViewPos = { viewpos, oviewz + Frac * (nviewz - oviewz) }; break; } } @@ -654,17 +646,15 @@ void R_InterpolateView (player_t *player, double Frac, InterpolationViewer *ivie else { DVector2 disp = Displacements.getOffset(oldgroup, newgroup); - viewx = iview->oviewx + FixedMul(frac, iview->nviewx - iview->oviewx - FLOAT2FIXED(disp.X)); - viewy = iview->oviewy + FixedMul(frac, iview->nviewy - iview->oviewy - FLOAT2FIXED(disp.Y)); - viewz = iview->oviewz + FixedMul(frac, iview->nviewz - iview->oviewz); + ViewPos = iview->Old.Pos + (iview->New.Pos - iview->Old.Pos - disp) * Frac; } if (player != NULL && !(player->cheats & CF_INTERPVIEW) && player - players == consoleplayer && camera == player->mo && !demoplayback && - iview->nviewx == camera->_f_X() && - iview->nviewy == camera->_f_Y() && + iview->New.Pos.X == camera->X() && + iview->New.Pos.Y == camera->Y() && !(player->cheats & (CF_TOTALLYFROZEN|CF_FROZEN)) && player->playerstate == PST_LIVE && player->mo->reactiontime == 0 && @@ -673,53 +663,26 @@ void R_InterpolateView (player_t *player, double Frac, InterpolationViewer *ivie (!netgame || !cl_noprediction) && !LocalKeyboardTurner) { - viewangle = nviewangle + (LocalViewAngle & 0xFFFF0000); - - fixed_t delta = player->centering ? 0 : -(signed)(LocalViewPitch & 0xFFFF0000); - - viewpitch = iview->nviewpitch; - if (delta > 0) - { - // Avoid overflowing viewpitch (can happen when a netgame is stalled) - if (viewpitch > INT_MAX - delta) - { - viewpitch = player->MaxPitch.BAMs(); - } - else - { - viewpitch = MIN(viewpitch + delta, player->MaxPitch.BAMs()); - } - } - else if (delta < 0) - { - // Avoid overflowing viewpitch (can happen when a netgame is stalled) - if (viewpitch < INT_MIN - delta) - { - viewpitch = player->MinPitch.BAMs(); - } - else - { - viewpitch = MAX(viewpitch + delta, player->MinPitch.BAMs()); - } - } + ViewAngle = (nviewangle + AngleToFloat(LocalViewAngle & 0xFFFF0000)).Normalized180(); + DAngle delta = player->centering ? DAngle(0.) : AngleToFloat(int(LocalViewPitch & 0xFFFF0000)); + ViewPitch = clamp((iview->New.Angles.Pitch - delta).Normalized180(), player->MinPitch, player->MaxPitch); } else { - viewpitch = iview->oviewpitch + FixedMul (frac, iview->nviewpitch - iview->oviewpitch); - viewangle = oviewangle + FixedMul (frac, nviewangle - oviewangle); + ViewPitch = (iview->Old.Angles.Pitch + (iview->New.Angles.Pitch - iview->Old.Angles.Pitch) * Frac).Normalized180(); + ViewAngle = (oviewangle + (nviewangle - oviewangle) * Frac).Normalized180(); } // Due to interpolation this is not necessarily the same as the sector the camera is in. - viewsector = R_PointInSubsector(viewx, viewy)->sector; + viewsector = R_PointInSubsector(ViewPos)->sector; bool moved = false; while (!viewsector->PortalBlocksMovement(sector_t::ceiling)) { AActor *point = viewsector->SkyBoxes[sector_t::ceiling]; - if (viewz > FLOAT2FIXED(point->specialf1)) + if (ViewPos.Z > point->specialf1) { - viewx += FLOAT2FIXED(point->Scale.X); - viewy += FLOAT2FIXED(point->Scale.Y); - viewsector = R_PointInSubsector(viewx, viewy)->sector; + ViewPos += point->Scale; + viewsector = R_PointInSubsector(ViewPos)->sector; moved = true; } else break; @@ -729,11 +692,10 @@ void R_InterpolateView (player_t *player, double Frac, InterpolationViewer *ivie while (!viewsector->PortalBlocksMovement(sector_t::floor)) { AActor *point = viewsector->SkyBoxes[sector_t::floor]; - if (viewz < FLOAT2FIXED(point->specialf1)) + if (ViewPos.Z < point->specialf1) { - viewx += FLOAT2FIXED(point->Scale.X); - viewy += FLOAT2FIXED(point->Scale.Y); - viewsector = R_PointInSubsector(viewx, viewy)->sector; + ViewPos += point->Scale; + viewsector = R_PointInSubsector(ViewPos)->sector; moved = true; } else break; @@ -761,10 +723,8 @@ void R_ResetViewInterpolation () void R_SetViewAngle () { - angle_t ang = viewangle >> ANGLETOFINESHIFT; - - viewsin = finesine[ang]; - viewcos = finecosine[ang]; + viewsin = FLOAT2FIXED(ViewAngle.Sin()); + viewcos = FLOAT2FIXED(ViewAngle.Cos()); viewtansin = FixedMul (FocalTangent, viewsin); viewtancos = FixedMul (FocalTangent, viewcos); @@ -787,7 +747,8 @@ static InterpolationViewer *FindPastViewer (AActor *actor) } // Not found, so make a new one - InterpolationViewer iview = { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + InterpolationViewer iview; + memset(&iview, 0, sizeof(iview)); iview.ViewActor = actor; iview.otic = -1; InterpolationPath.Clear(); @@ -851,11 +812,7 @@ void R_RebuildViewInterpolation(player_t *player) InterpolationViewer *iview = FindPastViewer(player->camera); - iview->oviewx = iview->nviewx; - iview->oviewy = iview->nviewy; - iview->oviewz = iview->nviewz; - iview->oviewpitch = iview->nviewpitch; - iview->oviewangle = iview->nviewangle; + iview->Old = iview->New; InterpolationPath.Clear(); } @@ -955,52 +912,39 @@ void R_SetupFrame (AActor *actor) if (iview->otic != -1 && nowtic > iview->otic) { iview->otic = nowtic; - iview->oviewx = iview->nviewx; - iview->oviewy = iview->nviewy; - iview->oviewz = iview->nviewz; - iview->oviewpitch = iview->nviewpitch; - iview->oviewangle = iview->nviewangle; + iview->Old = iview->New; } if (player != NULL && gamestate != GS_TITLELEVEL && ((player->cheats & CF_CHASECAM) || (r_deathcamera && camera->health <= 0))) { - sector_t *oldsector = R_PointInSubsector(iview->oviewx, iview->oviewy)->sector; + sector_t *oldsector = R_PointInSubsector(iview->Old.Pos)->sector; // [RH] Use chasecam view DVector3 campos; - P_AimCamera (camera, campos, viewsector, unlinked); - iview->nviewx = FLOAT2FIXED(campos.X); - iview->nviewy = FLOAT2FIXED(campos.Y); - iview->nviewz = FLOAT2FIXED(campos.Z); + P_AimCamera (camera, campos, viewsector, unlinked); // fixme: This needs to translate the angle, too. + iview->New.Pos = campos; r_showviewer = true; // Interpolating this is a very complicated thing because nothing keeps track of the aim camera's movement, so whenever we detect a portal transition // it's probably best to just reset the interpolation for this move. // Note that this can still cause problems with unusually linked portals - if (viewsector->PortalGroup != oldsector->PortalGroup || (unlinked && P_AproxDistance(iview->oviewx - iview->nviewx, iview->oviewy - iview->nviewy) > 256 * FRACUNIT)) + if (viewsector->PortalGroup != oldsector->PortalGroup || (unlinked && ((iview->New.Pos.XY() - iview->Old.Pos.XY()).LengthSquared()) > 256*256)) { iview->otic = nowtic; - iview->oviewx = iview->nviewx; - iview->oviewy = iview->nviewy; - iview->oviewz = iview->nviewz; - iview->oviewpitch = iview->nviewpitch; - iview->oviewangle = iview->nviewangle; + iview->Old = iview->New; } } else { - iview->nviewx = camera->_f_X(); - iview->nviewy = camera->_f_Y(); - iview->nviewz = FLOAT2FIXED(camera->player ? camera->player->viewz : camera->Z() + camera->GetCameraHeight()); + iview->New.Pos = { camera->Pos().XY(), camera->player ? camera->player->viewz : camera->Z() + camera->GetCameraHeight() }; viewsector = camera->Sector; r_showviewer = false; } - iview->nviewpitch = camera->Angles.Pitch.BAMs(); + iview->New.Angles = camera->Angles; if (camera->player != 0) { player = camera->player; } - iview->nviewangle = camera->Angles.Yaw.BAMs(); if (iview->otic == -1 || r_NoInterpolate) { R_ResetViewInterpolation (); @@ -1014,13 +958,6 @@ void R_SetupFrame (AActor *actor) } R_InterpolateView (player, r_TicFracF, iview); -#ifdef TEST_X - viewx = TEST_X; - viewy = TEST_Y; - viewz = TEST_Z; - viewangle = TEST_ANGLE; -#endif - R_SetViewAngle (); interpolator.DoInterpolations (r_TicFracF); @@ -1028,19 +965,19 @@ void R_SetupFrame (AActor *actor) // Keep the view within the sector's floor and ceiling if (viewsector->PortalBlocksMovement(sector_t::ceiling)) { - fixed_t theZ = viewsector->ceilingplane.ZatPoint(viewx, viewy) - 4 * FRACUNIT; - if (viewz > theZ) + double theZ = viewsector->ceilingplane.ZatPoint(ViewPos) - 4; + if (ViewPos.Z > theZ) { - viewz = theZ; + ViewPos.Z = theZ; } } if (viewsector->PortalBlocksMovement(sector_t::floor)) { - fixed_t theZ = viewsector->floorplane.ZatPoint(viewx, viewy) + 4 * FRACUNIT; - if (viewz < theZ) + double theZ = viewsector->floorplane.ZatPoint(ViewPos) + 4; + if (ViewPos.Z < theZ) { - viewz = theZ; + ViewPos.Z = theZ; } } @@ -1058,32 +995,30 @@ void R_SetupFrame (AActor *actor) { an = camera->Angles.Yaw; double power = QuakePower(quakefactor, jiggers.RelIntensity.X, jiggers.RelOffset.X, jiggers.Falloff, jiggers.WFalloff); - viewx += FLOAT2FIXED(an.Cos() * power); - viewy += FLOAT2FIXED(an.Sin() * power); + ViewPos += an.ToVector(power); } if (jiggers.RelIntensity.Y != 0 || jiggers.RelOffset.Y != 0) { an = camera->Angles.Yaw + 90; double power = QuakePower(quakefactor, jiggers.RelIntensity.Y, jiggers.RelOffset.Y, jiggers.Falloff, jiggers.WFalloff); - viewx += FLOAT2FIXED(an.Cos() * power); - viewy += FLOAT2FIXED(an.Sin() * power); + ViewPos += an.ToVector(power); } // FIXME: Relative Z is not relative if (jiggers.RelIntensity.Z != 0 || jiggers.RelOffset.Z != 0) { - viewz += FLOAT2FIXED(QuakePower(quakefactor, jiggers.RelIntensity.Z, jiggers.RelOffset.Z, jiggers.Falloff, jiggers.WFalloff)); + ViewPos.Z += QuakePower(quakefactor, jiggers.RelIntensity.Z, jiggers.RelOffset.Z, jiggers.Falloff, jiggers.WFalloff); } if (jiggers.Intensity.X != 0 || jiggers.Offset.X != 0) { - viewx += FLOAT2FIXED(QuakePower(quakefactor, jiggers.Intensity.X, jiggers.Offset.X, jiggers.Falloff, jiggers.WFalloff)); + ViewPos.Z += QuakePower(quakefactor, jiggers.Intensity.X, jiggers.Offset.X, jiggers.Falloff, jiggers.WFalloff); } if (jiggers.Intensity.Y != 0 || jiggers.Offset.Y != 0) { - viewy += FLOAT2FIXED(QuakePower(quakefactor, jiggers.Intensity.Y, jiggers.Offset.Y, jiggers.Falloff, jiggers.WFalloff)); + ViewPos.Z += QuakePower(quakefactor, jiggers.Intensity.Y, jiggers.Offset.Y, jiggers.Falloff, jiggers.WFalloff); } if (jiggers.Intensity.Z != 0 || jiggers.Offset.Z != 0) { - viewz += FLOAT2FIXED(QuakePower(quakefactor, jiggers.Intensity.Z, jiggers.Offset.Z, jiggers.Falloff, jiggers.WFalloff)); + ViewPos.Z += QuakePower(quakefactor, jiggers.Intensity.Z, jiggers.Offset.Z, jiggers.Falloff, jiggers.WFalloff); } } } @@ -1102,7 +1037,7 @@ void R_SetupFrame (AActor *actor) secplane_t *plane; int viewside; plane = (i < lightlist.Size()-1) ? &lightlist[i+1].plane : &viewsector->floorplane; - viewside = plane->PointOnSide(viewx, viewy, viewz); + viewside = plane->PointOnSide(ViewPos); // Reverse the direction of the test if the plane was downward facing. // We want to know if the view is above it, whatever its orientation may be. if (plane->fC() < 0) @@ -1124,9 +1059,9 @@ void R_SetupFrame (AActor *actor) const sector_t *s = viewsector->GetHeightSec(); if (s != NULL) { - newblend = s->floorplane.PointOnSide(viewx, viewy, viewz) < 0 + newblend = s->floorplane.PointOnSide(ViewPos) < 0 ? s->bottommap - : s->ceilingplane.PointOnSide(viewx, viewy, viewz) < 0 + : s->ceilingplane.PointOnSide(ViewPos) < 0 ? s->topmap : s->midmap; if (APART(newblend) == 0 && newblend >= numfakecmaps) diff --git a/src/r_utility.h b/src/r_utility.h index f37fc01ee..0a63b3f66 100644 --- a/src/r_utility.h +++ b/src/r_utility.h @@ -2,6 +2,7 @@ #define __R_UTIL_H #include "r_state.h" +#include "vectors.h" // // Stuff from r_main.h that's needed outside the rendering code. @@ -11,10 +12,9 @@ extern DCanvas *RenderTarget; -extern fixed_t viewx; -extern fixed_t viewy; -extern fixed_t viewz; -extern int viewpitch; +extern DVector3 ViewPos; +extern DAngle ViewAngle; +extern DAngle ViewPitch; extern "C" int centerx, centerxwide; extern "C" int centery; @@ -65,7 +65,6 @@ inline int R_PointOnSide(const DVector2 &pos, const node_t *node) } angle_t R_PointToAngle2 (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2); -inline angle_t R_PointToAngle (fixed_t x, fixed_t y) { return R_PointToAngle2 (viewx, viewy, x, y); } inline angle_t R_PointToAnglePrecise (fixed_t viewx, fixed_t viewy, fixed_t x, fixed_t y) { return xs_RoundToUInt(g_atan2(double(y-viewy), double(x-viewx)) * (ANGLE_180/M_PI)); diff --git a/src/win32/i_main.cpp b/src/win32/i_main.cpp index 4e6868a7b..241e9dae2 100644 --- a/src/win32/i_main.cpp +++ b/src/win32/i_main.cpp @@ -1080,10 +1080,10 @@ void DoomSpecificInfo (char *buffer, size_t bufflen) } else { - buffer += mysnprintf (buffer, buffend - buffer, "\r\n\r\nviewx = %d", viewx); - buffer += mysnprintf (buffer, buffend - buffer, "\r\nviewy = %d", viewy); - buffer += mysnprintf (buffer, buffend - buffer, "\r\nviewz = %d", viewz); - buffer += mysnprintf (buffer, buffend - buffer, "\r\nviewangle = %x", viewangle); + buffer += mysnprintf (buffer, buffend - buffer, "\r\n\r\nviewx = %f", ViewPos.X); + buffer += mysnprintf (buffer, buffend - buffer, "\r\nviewy = %f", ViewPos.Y); + buffer += mysnprintf (buffer, buffend - buffer, "\r\nviewz = %f", ViewPos.Z); + buffer += mysnprintf (buffer, buffend - buffer, "\r\nviewangle = %f", ViewAngle); } } *buffer++ = '\r';