From 54f0d0c1104a2f51dced0d58a7a432d9f3c76afb Mon Sep 17 00:00:00 2001 From: Ronald Kinard Date: Tue, 18 Nov 2014 18:45:57 -0600 Subject: [PATCH 01/91] IN PROGRESS: porting eternity slopes from srb2cb --- src/Makefile | 2 + src/doomdef.h | 8 + src/m_fixed.h | 23 + src/m_vector.c | 1160 ++++++++++++++++++++++++++++++++++++++++++++++ src/m_vector.h | 123 +++++ src/p_enemy.c | 13 + src/p_floor.c | 11 +- src/p_local.h | 15 + src/p_map.c | 371 ++++++++++++--- src/p_maputl.c | 205 ++++++-- src/p_mobj.c | 103 +++- src/p_mobj.h | 10 + src/p_slopes.c | 1211 ++++++++++++++++++++++++++++++++++++++++++++++++ src/p_slopes.h | 84 ++++ src/p_spec.c | 90 +++- src/p_spec.h | 5 + src/p_user.c | 81 ++++ src/r_defs.h | 54 +++ src/tables.c | 5 +- src/tables.h | 5 +- 20 files changed, 3450 insertions(+), 129 deletions(-) create mode 100644 src/m_vector.c create mode 100644 src/m_vector.h create mode 100644 src/p_slopes.c create mode 100644 src/p_slopes.h diff --git a/src/Makefile b/src/Makefile index f5d58af3a..3e0ab2f76 100644 --- a/src/Makefile +++ b/src/Makefile @@ -432,6 +432,7 @@ OBJS:=$(i_main_o) \ $(OBJDIR)/m_misc.o \ $(OBJDIR)/m_random.o \ $(OBJDIR)/m_queue.o \ + $(OBJDIR)/m_vector.o \ $(OBJDIR)/info.o \ $(OBJDIR)/p_ceilng.o \ $(OBJDIR)/p_enemy.o \ @@ -450,6 +451,7 @@ OBJS:=$(i_main_o) \ $(OBJDIR)/p_telept.o \ $(OBJDIR)/p_tick.o \ $(OBJDIR)/p_user.o \ + $(OBJDIR)/p_slopes.o \ $(OBJDIR)/tables.o \ $(OBJDIR)/r_bsp.o \ $(OBJDIR)/r_data.o \ diff --git a/src/doomdef.h b/src/doomdef.h index c4896a764..924d09685 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -436,6 +436,14 @@ extern const char *compdate, *comptime, *comprevision; /// Fun experimental slope stuff! //#define SLOPENESS +/// Kalaron/Eternity Engine slope code (SRB2CB ported) +/// Depends on NEED_FIXED_VECTORS? for a few functions. +/// However, uses own vector types for math. +#define ESLOPE + +/// Fixed and float point types +//#define NEED_FIXED_VECTOR + /// Delete file while the game is running. /// \note EXTREMELY buggy, tends to crash game. //#define DELFILE diff --git a/src/m_fixed.h b/src/m_fixed.h index e68de0308..8bf160204 100644 --- a/src/m_fixed.h +++ b/src/m_fixed.h @@ -357,6 +357,29 @@ FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedRound(fixed_t x) return INT32_MAX; } +/*! + \brief convert a fixed_t number into double floating number + */ +#define FIXED_TO_DOUBLE(f) ((double)((f) / FRACUNIT)) + +/*! + \brief convert a double floating number into fixed_t number + */ +#define DOUBLE_TO_FIXED(f) ((fixed_t)((f) * FRACUNIT)) + +/*! + \brief convert a integer into fixed_t number + */ +#define INT_TO_FIXED(x) ((int)((x) * FRACUNIT)) + +/*! + \brief convert a fixed_t number into integer + */ +#define FIXED_TO_INT(x) (((int)(x)) / (FRACUNIT)) + +static inline int DivScale32 (fixed_t a, fixed_t b) { return (fixed_t)(((INT64)a << 32) / b); } + + #ifdef NEED_FIXED_VECTOR typedef struct diff --git a/src/m_vector.c b/src/m_vector.c new file mode 100644 index 000000000..af5189853 --- /dev/null +++ b/src/m_vector.c @@ -0,0 +1,1160 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// Copyright(C) 2004 Stephen McGranahan +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//-------------------------------------------------------------------------- +// +// DESCRIPTION: +// Vectors +// SoM created 05/18/09 +// +//----------------------------------------------------------------------------- + +#include "doomdef.h" +#include "m_vector.h" +#include "r_main.h" +#include "m_fixed.h" +#include "m_misc.h" +#include "tables.h" + +#ifdef ESLOPE + +v3fixed_t *M_LoadVec(v3fixed_t *vec, fixed_t x, fixed_t y, fixed_t z) +{ + vec->x = x; + vec->y = y; + vec->z = z; + return vec; +} + +v3fixed_t *M_CopyVec(v3fixed_t *a_o, const v3fixed_t *a_i) +{ + return M_Memcpy(a_o, a_i, sizeof(v3fixed_t)); +} + +v3float_t *M_LoadVecf(v3float_t *vec, float x, float y, float z) +{ + vec->x = x; + vec->y = y; + vec->z = z; + return vec; +} + +v3float_t *M_CopyVecf(v3float_t *a_o, const v3float_t *a_i) +{ + return M_Memcpy(a_o, a_i, sizeof(v3float_t)); +} + +// +// M_MakeVec3 +// +// Given two points, create a vector between them. +// +v3fixed_t *M_MakeVec3(const v3fixed_t *point1, const v3fixed_t *point2, v3fixed_t *a_o) +{ + a_o->x = point1->x - point2->x; + a_o->y = point1->y - point2->y; + a_o->z = point1->z - point2->z; + return a_o; +} + + +// +// M_MakeVec3f +// +// Given two points, create a vector between them. +// +v3float_t *M_MakeVec3f(const v3float_t *point1, const v3float_t *point2, v3float_t *a_o) +{ + a_o->x = point1->x - point2->x; + a_o->y = point1->y - point2->y; + a_o->z = point1->z - point2->z; + return a_o; +} + +// +// M_TranslateVec3 +// +// Translates the given vector (in the game's coordinate system) to the camera +// space (in right-handed coordinate system) This function is used for slopes. +// +void M_TranslateVec3(v3fixed_t *vec) +{ + fixed_t tx, ty, tz; + + tx = vec->x - viewx; + ty = viewz - vec->y; + tz = vec->z - viewy; + + // Just like wall projection. + vec->x = (tx * viewcos) - (tz * viewsin); + vec->z = (tz * viewcos) + (tx * viewsin); + vec->y = ty; +} + +// +// M_TranslateVec3f +// +// Translates the given vector (in the game's coordinate system) to the camera +// space (in right-handed coordinate system) This function is used for slopes. +// +void M_TranslateVec3f(v3float_t *vec) +{ + float tx, ty, tz; + + tx = vec->x - viewx; // SRB2CBTODO: This may need float viewxyz + ty = viewz - vec->y; + tz = vec->z - viewy; + + // Just like wall projection. + vec->x = (tx * viewcos) - (tz * viewsin); + vec->z = (tz * viewcos) + (tx * viewsin); + vec->y = ty; +} + +#ifdef SESLOPE +// +// M_TranslateVec3d +// +// Translates the given vector (in the game's coordinate system) to the camera +// space (in right-handed coordinate system) This function is used for slopes. +// +void M_TranslateVec3d(v3double_t *vec) +{ + double tx, ty, tz; + + tx = vec->x - viewx; // SRB2CBTODO: This may need float viewxyz + ty = viewz - vec->y; + tz = vec->z - viewy; + + // Just like wall projection. + vec->x = (tx * viewcos) - (tz * viewsin); + vec->z = (tz * viewcos) + (tx * viewsin); + vec->y = ty; +} +#endif + +// +// M_AddVec3 +// +// Adds v2 to v1 stores in dest +// +void M_AddVec3(v3fixed_t *dest, const v3fixed_t *v1, const v3fixed_t *v2) +{ + dest->x = v1->x + v2->x; + dest->y = v1->y + v2->y; + dest->z = v1->z + v2->z; +} + +// +// M_AddVec3f +// +// Adds v2 to v1 stores in dest +// +void M_AddVec3f(v3float_t *dest, const v3float_t *v1, const v3float_t *v2) +{ + dest->x = v1->x + v2->x; + dest->y = v1->y + v2->y; + dest->z = v1->z + v2->z; +} + +// +// M_SubVec3 +// +// Adds v2 to v1 stores in dest +// +void M_SubVec3(v3fixed_t *dest, const v3fixed_t *v1, const v3fixed_t *v2) // SRB2CBTODO: Make a function that allows the destxyz to equal the change of 2 args +{ + dest->x = v1->x - v2->x; + dest->y = v1->y - v2->y; + dest->z = v1->z - v2->z; +} + +// +// M_SubVec3f +// +// Subtracts v2 from v1 stores in dest +// +void M_SubVec3f(v3float_t *dest, const v3float_t *v1, const v3float_t *v2) +{ + dest->x = v1->x - v2->x; + dest->y = v1->y - v2->y; + dest->z = v1->z - v2->z; +} + +// +// M_DotVec3 +// +// Returns the dot product of v1 and v2 +// +fixed_t M_DotVec3(const v3fixed_t *v1, const v3fixed_t *v2) +{ + return FixedMul(v1->x, v2->x) + FixedMul(v1->y, v2->y) + FixedMul(v1->z, v2->z); +} + +// +// M_DotVec3f +// +// Returns the dot product of v1 and v2 +// +float M_DotVec3f(const v3float_t *v1, const v3float_t *v2) +{ + if (!v1 || !v2) + I_Error("M_DotVec3f: No vertexes!"); + if (!(v1 || v2 || v1->x || v1->y || v1->z || v2->x || v2->y || v2->z)) + I_Error("M_DotVec3f: No vertexes!"); + return (v1->x * v2->x) + (v1->y * v2->y) + (v1->z * v2->z); +} + +#ifdef SESLOPE +// +// M_DotVec3d +// +// Returns the dot product of v1 and v2 +// +double M_DotVec3d(const v3double_t *v1, const v3double_t *v2) +{ + return (v1->x * v2->x) + (v1->y * v2->y) + (v1->z * v2->z); +} +#endif + +// +// M_CrossProduct3 +// +// Gets the cross product of v1 and v2 and stores in dest +// +void M_CrossProduct3(v3fixed_t *dest, const v3fixed_t *v1, const v3fixed_t *v2) +{ + v3fixed_t tmp; + tmp.x = (v1->y * v2->z) - (v1->z * v2->y); + tmp.y = (v1->z * v2->x) - (v1->x * v2->z); + tmp.z = (v1->x * v2->y) - (v1->y * v2->x); + memcpy(dest, &tmp, sizeof(v3fixed_t)); +} + +// +// M_CrossProduct3f +// +// Gets the cross product of v1 and v2 and stores in dest +// +void M_CrossProduct3f(v3float_t *dest, const v3float_t *v1, const v3float_t *v2) +{ + v3float_t tmp; + tmp.x = (v1->y * v2->z) - (v1->z * v2->y); + tmp.y = (v1->z * v2->x) - (v1->x * v2->z); + tmp.z = (v1->x * v2->y) - (v1->y * v2->x); + memcpy(dest, &tmp, sizeof(v3float_t)); +} + +fixed_t FV_Magnitude(const v3fixed_t *a_normal) +{ + fixed_t xs = FixedMul(a_normal->x,a_normal->x); + fixed_t ys = FixedMul(a_normal->y,a_normal->y); + fixed_t zs = FixedMul(a_normal->z,a_normal->z); + return FixedSqrt(xs+ys+zs); +} + +float FV_Magnitudef(const v3float_t *a_normal) +{ + float xs = (a_normal->x * a_normal->x); + float ys = (a_normal->y * a_normal->y); + float zs = (a_normal->z * a_normal->z); + return (float)sqrt(xs+ys+zs); +} + +// Vector Complex Math +v3fixed_t *FV_Midpoint(const v3fixed_t *a_1, const v3fixed_t *a_2, v3fixed_t *a_o) +{ + a_o->x = FixedDiv(a_2->x - a_1->x, 2*FRACUNIT); + a_o->y = FixedDiv(a_2->y - a_1->y, 2*FRACUNIT); + a_o->z = FixedDiv(a_2->z - a_1->z, 2*FRACUNIT); + a_o->x = a_1->x + a_o->x; + a_o->y = a_1->y + a_o->y; + a_o->z = a_1->z + a_o->z; + return a_o; +} + +fixed_t FV_Distance(const v3fixed_t *p1, const v3fixed_t *p2) +{ + fixed_t xs = FixedMul(p2->x-p1->x,p2->x-p1->x); + fixed_t ys = FixedMul(p2->y-p1->y,p2->y-p1->y); + fixed_t zs = FixedMul(p2->z-p1->z,p2->z-p1->z); + return FixedSqrt(xs+ys+zs); +} + +v3float_t *FV_Midpointf(const v3float_t *a_1, const v3float_t *a_2, v3float_t *a_o) +{ + a_o->x = (a_2->x - a_1->x / 2.0f); + a_o->y = (a_2->y - a_1->y / 2.0f); + a_o->z = (a_2->z - a_1->z / 2.0f); + a_o->x = a_1->x + a_o->x; + a_o->y = a_1->y + a_o->y; + a_o->z = a_1->z + a_o->z; + return a_o; +} + + + +// +// AngleBetweenVectors +// +// This checks to see if a point is inside the ranges of a polygon +// +angle_t FV_AngleBetweenVectors(const v3fixed_t *Vector1, const v3fixed_t *Vector2) +{ + // Remember, above we said that the Dot Product of returns the cosine of the angle + // between 2 vectors? Well, that is assuming they are unit vectors (normalize vectors). + // So, if we don't have a unit vector, then instead of just saying arcCos(DotProduct(A, B)) + // We need to divide the dot product by the magnitude of the 2 vectors multiplied by each other. + // Here is the equation: arc cosine of (V . W / || V || * || W || ) + // the || V || means the magnitude of V. This then cancels out the magnitudes dot product magnitudes. + // But basically, if you have normalize vectors already, you can forget about the magnitude part. + + // Get the dot product of the vectors + fixed_t dotProduct = M_DotVec3(Vector1, Vector2); + + // Get the product of both of the vectors magnitudes + fixed_t vectorsMagnitude = FixedMul(FV_Magnitude(Vector1), FV_Magnitude(Vector2)); + + // Return the arc cosine of the (dotProduct / vectorsMagnitude) which is the angle in RADIANS. + return FixedAcos(FixedDiv(dotProduct, vectorsMagnitude)); +} + +float FV_AngleBetweenVectorsf(const v3float_t *Vector1, const v3float_t *Vector2) +{ + // Remember, above we said that the Dot Product of returns the cosine of the angle + // between 2 vectors? Well, that is assuming they are unit vectors (normalize vectors). + // So, if we don't have a unit vector, then instead of just saying arcCos(DotProduct(A, B)) + // We need to divide the dot product by the magnitude of the 2 vectors multiplied by each other. + // Here is the equation: arc cosine of (V . W / || V || * || W || ) + // the || V || means the magnitude of V. This then cancels out the magnitudes dot product magnitudes. + // But basically, if you have normalize vectors already, you can forget about the magnitude part. + + // Get the dot product of the vectors + float dotProduct = M_DotVec3f(Vector1, Vector2); + + // Get the product of both of the vectors magnitudes + float vectorsMagnitude = FV_Magnitudef(Vector1)*FV_Magnitudef(Vector2); + + // Return the arc cosine of the (dotProduct / vectorsMagnitude) which is the angle in RADIANS. + return acos(dotProduct/vectorsMagnitude); +} + + + +// Crazy physics code + +float M_VectorYaw(v3float_t v) +{ + return atan2(v.x, v.z); +} +float M_VectorPitch(v3float_t v) +{ + return -atan2(v.y, sqrt(v.x*v.x+v.z*v.z)); +} + +#include "z_zone.h" + +// Returns pitch roll and yaw values, allows objects to align to a slope +angles3d_t *M_VectorAlignTo(float Pitch, float Yaw, float Roll, v3float_t v, byte AngleAxis, float Rate) +{ + CONS_Printf("P %f\n", Pitch); + CONS_Printf("R %f\n", Roll); + CONS_Printf("Y %f\n", Yaw); + if (AngleAxis == 1) + { + float DestYaw = (atan2(v.z,v.x)* 180 / M_PI); + float DestRoll = (atan2(v.y,v.x)* 180 / M_PI); + + Yaw = Yaw+(DestYaw-Yaw)*Rate; + Roll = Roll+(DestRoll-Roll)*Rate; + } + else if (AngleAxis == 2) + { + float DestPitch = (atan2(v.z,v.y)* 180 / M_PI); + float DestRoll = (-atan2(v.x,v.y)* 180 / M_PI); + + Pitch = Pitch+(DestPitch-Pitch)*Rate; + Roll = Roll+(DestRoll-Roll)*Rate; + } + else if (AngleAxis == 3) + { + float DestPitch = (-atan2(v.y,v.z)* 180 / M_PI); + float DestYaw = (-atan2(v.x,v.z)* 180 / M_PI); + + Pitch = Pitch+(DestPitch-Pitch)*Rate; + Yaw = Yaw+(DestYaw-Yaw)*Rate; + } + + angles3d_t *returnangles = Z_Malloc(sizeof(angles3d_t), PU_LEVEL, NULL); + memset(returnangles, 0, sizeof(*returnangles)); + returnangles->yaw = Yaw; + returnangles->pitch = Pitch; + returnangles->roll = Roll; + + return returnangles; + +} + + + + + +#if 0 // Backport +v3fixed_t *FV_SubO(const v3fixed_t *a_i, const v3fixed_t *a_c, v3fixed_t *a_o) +{ + a_o->x = a_i->x - a_c->x; + a_o->y = a_i->y - a_c->y; + a_o->z = a_i->z - a_c->z; + return a_o; +} + +boolean FV_Equal(const v3fixed_t *a_1, const v3fixed_t *a_2) +{ + fixed_t Epsilon = FRACUNIT/FRACUNIT; + + if ((abs(a_2->x - a_1->x) > Epsilon) || + (abs(a_2->y - a_1->y) > Epsilon) || + (abs(a_2->z - a_1->z) > Epsilon)) + { + return true; + } + + return false; +} + +boolean FV_Equalf(const v3float_t *a_1, const v3float_t *a_2) +{ + float Epsilon = 1.0f/1.0f; + + if ((abs(a_2->x - a_1->x) > Epsilon) || + (abs(a_2->y - a_1->y) > Epsilon) || + (abs(a_2->z - a_1->z) > Epsilon)) + { + return true; + } + + return false; +} + +// +// Normal +// +// Calculates the normal of a polygon. +// +void FV_Normal (const v3fixed_t *a_triangle, v3fixed_t *a_normal) +{ + v3fixed_t a_1; + v3fixed_t a_2; + + FV_Point2Vec(&a_triangle[2], &a_triangle[0], &a_1); + FV_Point2Vec(&a_triangle[1], &a_triangle[0], &a_2); + + FV_Cross(&a_1, &a_2, a_normal); + + FV_NormalizeO(a_normal, a_normal); +} + +// +// PlaneDistance +// +// Calculates distance between a plane and the origin. +// +fixed_t FV_PlaneDistance(const v3fixed_t *a_normal, const v3fixed_t *a_point) +{ + return -(FixedMul(a_normal->x, a_point->x) + FixedMul(a_normal->y, a_point->y) + FixedMul(a_normal->z, a_point->z)); +} + +boolean FV_IntersectedPlane(const v3fixed_t *a_triangle, const v3fixed_t *a_line, v3fixed_t *a_normal, fixed_t *originDistance) +{ + fixed_t distance1 = 0, distance2 = 0; + + FV_Normal(a_triangle, a_normal); + + *originDistance = FV_PlaneDistance(a_normal, &a_triangle[0]); + + distance1 = (FixedMul(a_normal->x, a_line[0].x) + FixedMul(a_normal->y, a_line[0].y) + + FixedMul(a_normal->z, a_line[0].z)) + *originDistance; + + distance2 = (FixedMul(a_normal->x, a_line[1].x) + FixedMul(a_normal->y, a_line[1].y) + + FixedMul(a_normal->z, a_line[1].z)) + *originDistance; + + // Positive or zero number means no intersection + if (FixedMul(distance1, distance2) >= 0) + return false; + + return true; +} + +// +// PlaneIntersection +// +// Returns the distance from +// rOrigin to where the ray +// intersects the plane. Assumes +// you already know it intersects +// the plane. +// +fixed_t FV_PlaneIntersection(const v3fixed_t *pOrigin, const v3fixed_t *pNormal, const v3fixed_t *rOrigin, const v3fixed_t *rVector) +{ + fixed_t d = -(FV_Dot(pNormal, pOrigin)); + fixed_t number = FV_Dot(pNormal,rOrigin) + d; + fixed_t denom = FV_Dot(pNormal,rVector); + return -FixedDiv(number, denom); +} + +// +// IntersectRaySphere +// Input : rO - origin of ray in world space +// rV - vector describing direction of ray in world space +// sO - Origin of sphere +// sR - radius of sphere +// Notes : Normalized directional vectors expected +// Return: distance to sphere in world units, -1 if no intersection. +// +fixed_t FV_IntersectRaySphere(const v3fixed_t *rO, const v3fixed_t *rV, const v3fixed_t *sO, fixed_t sR) +{ + v3fixed_t Q; + fixed_t c, v, d; + FV_SubO(sO, rO, &Q); + + c = FV_Magnitude(&Q); + v = FV_Dot(&Q, rV); + d = FixedMul(sR, sR) - (FixedMul(c,c) - FixedMul(v,v)); + + // If there was no intersection, return -1 + if (d < 0*FRACUNIT) + return (-1*FRACUNIT); + + // Return the distance to the [first] intersecting point + return (v - FixedSqrt(d)); +} + +// +// IntersectionPoint +// +// This returns the intersection point of the line that intersects the plane +// +v3fixed_t *FV_IntersectionPoint(const v3fixed_t *vNormal, const v3fixed_t *vLine, fixed_t distance, v3fixed_t *ReturnVec) +{ + v3fixed_t vLineDir; // Variables to hold the point and the line's direction + fixed_t Numerator = 0, Denominator = 0, dist = 0; + + // Here comes the confusing part. We need to find the 3D point that is actually + // on the plane. Here are some steps to do that: + + // 1) First we need to get the vector of our line, Then normalize it so it's a length of 1 + FV_Point2Vec(&vLine[1], &vLine[0], &vLineDir); // Get the Vector of the line + FV_NormalizeO(&vLineDir, &vLineDir); // Normalize the lines vector + + + // 2) Use the plane equation (distance = Ax + By + Cz + D) to find the distance from one of our points to the plane. + // Here I just chose a arbitrary point as the point to find that distance. You notice we negate that + // distance. We negate the distance because we want to eventually go BACKWARDS from our point to the plane. + // By doing this is will basically bring us back to the plane to find our intersection point. + Numerator = - (FixedMul(vNormal->x, vLine[0].x) + // Use the plane equation with the normal and the line + FixedMul(vNormal->y, vLine[0].y) + + FixedMul(vNormal->z, vLine[0].z) + distance); + + // 3) If we take the dot product between our line vector and the normal of the polygon, + // this will give us the cosine of the angle between the 2 (since they are both normalized - length 1). + // We will then divide our Numerator by this value to find the offset towards the plane from our arbitrary point. + Denominator = FV_Dot(vNormal, &vLineDir); // Get the dot product of the line's vector and the normal of the plane + + // Since we are using division, we need to make sure we don't get a divide by zero error + // If we do get a 0, that means that there are INFINITE points because the the line is + // on the plane (the normal is perpendicular to the line - (Normal.Vector = 0)). + // In this case, we should just return any point on the line. + + if( Denominator == 0*FRACUNIT) // Check so we don't divide by zero + { + ReturnVec->x = vLine[0].x; + ReturnVec->y = vLine[0].y; + ReturnVec->z = vLine[0].z; + return ReturnVec; // Return an arbitrary point on the line + } + + // We divide the (distance from the point to the plane) by (the dot product) + // to get the distance (dist) that we need to move from our arbitrary point. We need + // to then times this distance (dist) by our line's vector (direction). When you times + // a scalar (single number) by a vector you move along that vector. That is what we are + // doing. We are moving from our arbitrary point we chose from the line BACK to the plane + // along the lines vector. It seems logical to just get the numerator, which is the distance + // from the point to the line, and then just move back that much along the line's vector. + // Well, the distance from the plane means the SHORTEST distance. What about in the case that + // the line is almost parallel with the polygon, but doesn't actually intersect it until half + // way down the line's length. The distance from the plane is short, but the distance from + // the actual intersection point is pretty long. If we divide the distance by the dot product + // of our line vector and the normal of the plane, we get the correct length. Cool huh? + + dist = FixedDiv(Numerator, Denominator); // Divide to get the multiplying (percentage) factor + + // Now, like we said above, we times the dist by the vector, then add our arbitrary point. + // This essentially moves the point along the vector to a certain distance. This now gives + // us the intersection point. Yay! + + // Return the intersection point + ReturnVec->x = vLine[0].x + FixedMul(vLineDir.x, dist); + ReturnVec->y = vLine[0].y + FixedMul(vLineDir.y, dist); + ReturnVec->z = vLine[0].z + FixedMul(vLineDir.z, dist); + return ReturnVec; +} + +// +// PointOnLineSide +// +// If on the front side of the line, returns 1. +// If on the back side of the line, returns 0. +// 2D only. +// +unsigned int FV_PointOnLineSide(const v3fixed_t *point, const v3fixed_t *line) +{ + fixed_t s1 = FixedMul((point->y - line[0].y),(line[1].x - line[0].x)); + fixed_t s2 = FixedMul((point->x - line[0].x),(line[1].y - line[0].y)); + return s1 - s2 < 0; +} + +// +// PointInsideBox +// +// Given four points of a box, +// determines if the supplied point is +// inside the box or not. +// +boolean FV_PointInsideBox(const v3fixed_t *point, const v3fixed_t *box) +{ + v3fixed_t lastLine[2]; + + FV_Load(&lastLine[0], box[3].x, box[3].y, box[3].z); + FV_Load(&lastLine[1], box[0].x, box[0].y, box[0].z); + + if (FV_PointOnLineSide(point, &box[0]) + || FV_PointOnLineSide(point, &box[1]) + || FV_PointOnLineSide(point, &box[2]) + || FV_PointOnLineSide(point, lastLine)) + return false; + + return true; +} +// +// LoadIdentity +// +// Loads the identity matrix into a matrix +// +void FM_LoadIdentity(fmatrix_t* matrix) +{ +#define M(row,col) matrix->m[col * 4 + row] + memset(matrix, 0x00, sizeof(fmatrix_t)); + + M(0, 0) = FRACUNIT; + M(1, 1) = FRACUNIT; + M(2, 2) = FRACUNIT; + M(3, 3) = FRACUNIT; +#undef M +} + +// +// CreateObjectMatrix +// +// Creates a matrix that can be used for +// adjusting the position of an object +// +void FM_CreateObjectMatrix(fmatrix_t *matrix, fixed_t x, fixed_t y, fixed_t z, fixed_t anglex, fixed_t angley, fixed_t anglez, fixed_t upx, fixed_t upy, fixed_t upz, fixed_t radius) +{ + v3fixed_t upcross; + v3fixed_t upvec; + v3fixed_t basevec; + + FV_Load(&upvec, upx, upy, upz); + FV_Load(&basevec, anglex, angley, anglez); + FV_Cross(&upvec, &basevec, &upcross); + FV_Normalize(&upcross); + + FM_LoadIdentity(matrix); + + matrix->m[0] = upcross.x; + matrix->m[1] = upcross.y; + matrix->m[2] = upcross.z; + matrix->m[3] = 0*FRACUNIT; + + matrix->m[4] = upx; + matrix->m[5] = upy; + matrix->m[6] = upz; + matrix->m[7] = 0; + + matrix->m[8] = anglex; + matrix->m[9] = angley; + matrix->m[10] = anglez; + matrix->m[11] = 0; + + matrix->m[12] = x - FixedMul(upx,radius); + matrix->m[13] = y - FixedMul(upy,radius); + matrix->m[14] = z - FixedMul(upz,radius); + matrix->m[15] = FRACUNIT; +} + +// +// MultMatrixVec +// +// Multiplies a vector by the specified matrix +// +void FM_MultMatrixVec(const fmatrix_t *matrix, const v3fixed_t *vec, v3fixed_t *out) +{ +#define M(row,col) matrix->m[col * 4 + row] + out->x = FixedMul(vec->x,M(0, 0)) + + FixedMul(vec->y,M(0, 1)) + + FixedMul(vec->z,M(0, 2)) + + M(0, 3); + + out->y = FixedMul(vec->x,M(1, 0)) + + FixedMul(vec->y,M(1, 1)) + + FixedMul(vec->z,M(1, 2)) + + M(1, 3); + + out->z = FixedMul(vec->x,M(2, 0)) + + FixedMul(vec->y,M(2, 1)) + + FixedMul(vec->z,M(2, 2)) + + M(2, 3); +#undef M +} + +// +// MultMatrix +// +// Multiples one matrix into another +// +void FM_MultMatrix(fmatrix_t *dest, const fmatrix_t *multme) +{ + fmatrix_t result; + unsigned int i, j; +#define M(row,col) multme->m[col * 4 + row] +#define D(row,col) dest->m[col * 4 + row] +#define R(row,col) result.m[col * 4 + row] + + for (i = 0; i < 4; i++) + { + for (j = 0; j < 4; j++) + R(i, j) = FixedMul(D(i, 0),M(0, j)) + FixedMul(D(i, 1),M(1, j)) + FixedMul(D(i, 2),M(2, j)) + FixedMul(D(i, 3),M(3, j)); + } + + M_Memcpy(dest, &result, sizeof(fmatrix_t)); + +#undef R +#undef D +#undef M +} + +// +// Translate +// +// Translates a matrix +// +void FM_Translate(fmatrix_t *dest, fixed_t x, fixed_t y, fixed_t z) +{ + fmatrix_t trans; +#define M(row,col) trans.m[col * 4 + row] + + memset(&trans, 0x00, sizeof(fmatrix_t)); + + M(0, 0) = M(1, 1) = M(2, 2) = M(3, 3) = FRACUNIT; + M(0, 3) = x; + M(1, 3) = y; + M(2, 3) = z; + + FM_MultMatrix(dest, &trans); +#undef M +} + +// +// Scale +// +// Scales a matrix +// +void FM_Scale(fmatrix_t *dest, fixed_t x, fixed_t y, fixed_t z) +{ + fmatrix_t scale; +#define M(row,col) scale.m[col * 4 + row] + + memset(&scale, 0x00, sizeof(fmatrix_t)); + + M(3, 3) = FRACUNIT; + M(0, 0) = x; + M(1, 1) = y; + M(2, 2) = z; + + FM_MultMatrix(dest, &scale); +#undef M +} + + +v3fixed_t *FV_Cross(const v3fixed_t *a_1, const v3fixed_t *a_2, v3fixed_t *a_o) +{ + a_o->x = FixedMul(a_1->y, a_2->z) - FixedMul(a_1->z, a_2->y); + a_o->y = FixedMul(a_1->z, a_2->x) - FixedMul(a_1->x, a_2->z); + a_o->z = FixedMul(a_1->x, a_2->y) - FixedMul(a_1->y, a_2->x); + return a_o; +} + +// +// ClosestPointOnLine +// +// Finds the point on a line closest +// to the specified point. +// +v3fixed_t *FV_ClosestPointOnLine(const v3fixed_t *Line, const v3fixed_t *p, v3fixed_t *out) +{ + // Determine t (the length of the vector from √´Line[0]√≠ to √´p√≠) + v3fixed_t c, V; + fixed_t t, d = 0; + FV_SubO(p, &Line[0], &c); + FV_SubO(&Line[1], &Line[0], &V); + FV_NormalizeO(&V, &V); + + d = FV_Distance(&Line[0], &Line[1]); + t = FV_Dot(&V, &c); + + // Check to see if √´t√≠ is beyond the extents of the line segment + if (t < 0) + { + return FV_Copy(out, &Line[0]); + } + if (t > d) + { + return FV_Copy(out, &Line[1]); + } + + // Return the point between √´Line[0]√≠ and √´Line[1]√≠ + FV_Mul(&V, t); + + return FV_AddO(&Line[0], &V, out); +} + +// +// ClosestPointOnTriangle +// +// Given a triangle and a point, +// the closest point on the edge of +// the triangle is returned. +// +void FV_ClosestPointOnTriangle (const v3fixed_t *tri, const v3fixed_t *point, v3fixed_t *result) +{ + unsigned int i; + fixed_t dist, closestdist; + v3fixed_t EdgePoints[3]; + v3fixed_t Line[2]; + + FV_Copy(&Line[0], (v3fixed_t*)&tri[0]); + FV_Copy(&Line[1], (v3fixed_t*)&tri[1]); + FV_ClosestPointOnLine(Line, point, &EdgePoints[0]); + + FV_Copy(&Line[0], (v3fixed_t*)&tri[1]); + FV_Copy(&Line[1], (v3fixed_t*)&tri[2]); + FV_ClosestPointOnLine(Line, point, &EdgePoints[1]); + + FV_Copy(&Line[0], (v3fixed_t*)&tri[2]); + FV_Copy(&Line[1], (v3fixed_t*)&tri[0]); + FV_ClosestPointOnLine(Line, point, &EdgePoints[2]); + + // Find the closest one of the three + FV_Copy(result, &EdgePoints[0]); + closestdist = FV_Distance(point, &EdgePoints[0]); + for (i = 1; i < 3; i++) + { + dist = FV_Distance(point, &EdgePoints[i]); + + if (dist < closestdist) + { + closestdist = dist; + FV_Copy(result, &EdgePoints[i]); + } + } + + // We now have the closest point! Whee! +} + +// +// InsidePolygon +// +// This checks to see if a point is inside the ranges of a polygon +// +boolean FV_InsidePolygon(const fvector_t *vIntersection, const fvector_t *Poly, const int vertexCount) +{ + int i; + UINT64 Angle = 0; // Initialize the angle + fvector_t vA, vB; // Create temp vectors + + // Just because we intersected the plane, doesn't mean we were anywhere near the polygon. + // This functions checks our intersection point to make sure it is inside of the polygon. + // This is another tough function to grasp at first, but let me try and explain. + // It's a brilliant method really, what it does is create triangles within the polygon + // from the intersection point. It then adds up the inner angle of each of those triangles. + // If the angles together add up to 360 degrees (or 2 * PI in radians) then we are inside! + // If the angle is under that value, we must be outside of polygon. To further + // understand why this works, take a pencil and draw a perfect triangle. Draw a dot in + // the middle of the triangle. Now, from that dot, draw a line to each of the vertices. + // Now, we have 3 triangles within that triangle right? Now, we know that if we add up + // all of the angles in a triangle we get 360 right? Well, that is kinda what we are doing, + // but the inverse of that. Say your triangle is an isosceles triangle, so add up the angles + // and you will get 360 degree angles. 90 + 90 + 90 is 360. + + for (i = 0; i < vertexCount; i++) // Go in a circle to each vertex and get the angle between + { + FV_Point2Vec(&Poly[i], vIntersection, &vA); // Subtract the intersection point from the current vertex + // Subtract the point from the next vertex + FV_Point2Vec(&Poly[(i + 1) % vertexCount], vIntersection, &vB); + + Angle += FV_AngleBetweenVectors(&vA, &vB); // Find the angle between the 2 vectors and add them all up as we go along + } + + // Now that we have the total angles added up, we need to check if they add up to 360 degrees. + // Since we are using the dot product, we are working in radians, so we check if the angles + // equals 2*PI. We defined PI in 3DMath.h. You will notice that we use a MATCH_FACTOR + // in conjunction with our desired degree. This is because of the inaccuracy when working + // with floating point numbers. It usually won't always be perfectly 2 * PI, so we need + // to use a little twiddling. I use .9999, but you can change this to fit your own desired accuracy. + + if(Angle >= ANGLE_MAX) // If the angle is greater than 2 PI, (360 degrees) + return 1; // The point is inside of the polygon + + return 0; // If you get here, it obviously wasn't inside the polygon. +} + +// +// IntersectedPolygon +// +// This checks if a line is intersecting a polygon +// +boolean FV_IntersectedPolygon(const fvector_t *vPoly, const fvector_t *vLine, const int vertexCount, fvector_t *collisionPoint) +{ + fvector_t vNormal, vIntersection; + fixed_t originDistance = 0*FRACUNIT; + + + // First we check to see if our line intersected the plane. If this isn't true + // there is no need to go on, so return false immediately. + // We pass in address of vNormal and originDistance so we only calculate it once + + if(!FV_IntersectedPlane(vPoly, vLine, &vNormal, &originDistance)) + return false; + + // Now that we have our normal and distance passed back from IntersectedPlane(), + // we can use it to calculate the intersection point. The intersection point + // is the point that actually is ON the plane. It is between the line. We need + // this point test next, if we are inside the polygon. To get the I-Point, we + // give our function the normal of the plane, the points of the line, and the originDistance. + + FV_IntersectionPoint(&vNormal, vLine, originDistance, &vIntersection); + + // Now that we have the intersection point, we need to test if it's inside the polygon. + // To do this, we pass in : + // (our intersection point, the polygon, and the number of vertices our polygon has) + + if(FV_InsidePolygon(&vIntersection, vPoly, vertexCount)) + { + if (collisionPoint != NULL) // Optional - load the collision point. + { + collisionPoint->x = vIntersection.x; + collisionPoint->y = vIntersection.y; + collisionPoint->z = vIntersection.z; + } + return true; // We collided! + } + + // If we get here, we must have NOT collided + return false; +} + +// +// RotateVector +// +// Rotates a vector around another vector +// +void FV_Rotate(fvector_t *rotVec, const fvector_t *axisVec, const angle_t angle) +{ + // Rotate the point (x,y,z) around the vector (u,v,w) + fixed_t ux = FixedMul(axisVec->x, rotVec->x); + fixed_t uy = FixedMul(axisVec->x, rotVec->y); + fixed_t uz = FixedMul(axisVec->x, rotVec->z); + fixed_t vx = FixedMul(axisVec->y, rotVec->x); + fixed_t vy = FixedMul(axisVec->y, rotVec->y); + fixed_t vz = FixedMul(axisVec->y, rotVec->z); + fixed_t wx = FixedMul(axisVec->z, rotVec->x); + fixed_t wy = FixedMul(axisVec->z, rotVec->y); + fixed_t wz = FixedMul(axisVec->z, rotVec->z); + fixed_t sa = FINESINE(angle); + fixed_t ca = FINECOSINE(angle); + fixed_t ua = ux+vy+wz; + fixed_t ax = FixedMul(axisVec->x,ua); + fixed_t ay = FixedMul(axisVec->y,ua); + fixed_t az = FixedMul(axisVec->z,ua); + fixed_t xs = FixedMul(axisVec->x,axisVec->x); + fixed_t ys = FixedMul(axisVec->y,axisVec->y); + fixed_t zs = FixedMul(axisVec->z,axisVec->z); + fixed_t bx = FixedMul(rotVec->x,ys+zs); + fixed_t by = FixedMul(rotVec->y,xs+zs); + fixed_t bz = FixedMul(rotVec->z,xs+ys); + fixed_t cx = FixedMul(axisVec->x,vy+wz); + fixed_t cy = FixedMul(axisVec->y,ux+wz); + fixed_t cz = FixedMul(axisVec->z,ux+vy); + fixed_t dx = FixedMul(bx-cx, ca); + fixed_t dy = FixedMul(by-cy, ca); + fixed_t dz = FixedMul(bz-cz, ca); + fixed_t ex = FixedMul(vz-wy, sa); + fixed_t ey = FixedMul(wx-uz, sa); + fixed_t ez = FixedMul(uy-vx, sa); + + rotVec->x = ax+dx+ex; + rotVec->y = ay+dy+ey; + rotVec->z = az+dz+ez; +} + +void FM_Rotate(fmatrix_t *dest, angle_t angle, fixed_t x, fixed_t y, fixed_t z) +{ +#define M(row,col) dest->m[row * 4 + col] + const fixed_t sinA = FINESINE(angle>>ANGLETOFINESHIFT); + const fixed_t cosA = FINECOSINE(angle>>ANGLETOFINESHIFT); + const fixed_t invCosA = FRACUNIT - cosA; + fvector_t nrm = {x, y, z}; + fixed_t xSq, ySq, zSq; + fixed_t sx, sy, sz; + fixed_t sxy, sxz, syz; + + FV_Normalize(&nrm); + + x = nrm.x; + y = nrm.y; + z = nrm.z; + + xSq = FixedMul(x, FixedMul(invCosA,x)); + ySq = FixedMul(y, FixedMul(invCosA,y)); + zSq = FixedMul(z, FixedMul(invCosA,z)); + + sx = FixedMul(sinA, x); + sy = FixedMul(sinA, y); + sz = FixedMul(sinA, z); + + sxy = FixedMul(x, FixedMul(invCosA,y)); + sxz = FixedMul(x, FixedMul(invCosA,z)); + syz = FixedMul(y, FixedMul(invCosA,z)); + + + M(0, 0) = xSq + cosA; + M(1, 0) = sxy - sz; + M(2, 0) = sxz + sy; + M(3, 0) = 0; + + M(0, 1) = sxy + sz; + M(1, 1) = ySq + cosA; + M(2, 1) = syz - sx; + M(3, 1) = 0; + + M(0, 2) = sxz - sy; + M(1, 2) = syz + sx; + M(2, 2) = zSq + cosA; + M(3, 2) = 0; + + M(0, 3) = 0; + M(1, 3) = 0; + M(2, 3) = 0; + M(3, 3) = FRACUNIT; +#undef M +} + +#endif + + + + +float FV_Distancef(const v3float_t *p1, const v3float_t *p2) +{ + float xs = (p2->x-p1->x * p2->x-p1->x); + float ys = (p2->y-p1->y * p2->y-p1->y); + float zs = (p2->z-p1->z * p2->z-p1->z); + return sqrt(xs+ys+zs); +} + +// Also returns the magnitude +fixed_t FV_NormalizeO(const v3fixed_t *a_normal, v3fixed_t *a_o) +{ + fixed_t magnitude = FV_Magnitude(a_normal); + a_o->x = FixedDiv(a_normal->x, magnitude); + a_o->y = FixedDiv(a_normal->y, magnitude); + a_o->z = FixedDiv(a_normal->z, magnitude); + return magnitude; +} + +// Also returns the magnitude +float FV_NormalizeOf(const v3float_t *a_normal, v3float_t *a_o) +{ + float magnitude = FV_Magnitudef(a_normal); + a_o->x = (a_normal->x/magnitude); + a_o->y = (a_normal->y/magnitude); + a_o->z = (a_normal->z/magnitude); + return magnitude; +} + +fixed_t FV_Normalize(v3fixed_t *a_normal) +{ + return FV_NormalizeO(a_normal, a_normal); +} + +fixed_t FV_Normalizef(v3float_t *a_normal) +{ + return FV_NormalizeOf(a_normal, a_normal); +} + +// +// FV_Normalf +// +// Calculates the normal of a polygon. +// +void FV_Normal(const v3fixed_t *a_triangle, v3fixed_t *a_normal) +{ + v3fixed_t a_1; + v3fixed_t a_2; + + M_MakeVec3(&a_triangle[2], &a_triangle[0], &a_1); + M_MakeVec3(&a_triangle[1], &a_triangle[0], &a_2); + + M_CrossProduct3(&a_1, &a_2, a_normal); + + FV_NormalizeO(a_normal, a_normal); +} + +// +// FV_Normalf +// +// Calculates the normal of a polygon. +// +void FV_Normalf(const v3float_t *a_triangle, v3float_t *a_normal) +{ + v3float_t a_1; + v3float_t a_2; + + M_MakeVec3f(&a_triangle[2], &a_triangle[0], &a_1); + M_MakeVec3f(&a_triangle[1], &a_triangle[0], &a_2); + + M_CrossProduct3f(&a_1, &a_2, a_normal); + + FV_NormalizeOf(a_normal, a_normal); +} + + +// EOF +#endif // #ifdef ESLOPE + diff --git a/src/m_vector.h b/src/m_vector.h new file mode 100644 index 000000000..743a26023 --- /dev/null +++ b/src/m_vector.h @@ -0,0 +1,123 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// Copyright(C) 2004 Stephen McGranahan +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//-------------------------------------------------------------------------- +// +// DESCRIPTION: +// Vectors +// SoM created 05/18/09 +// +//----------------------------------------------------------------------------- + +#ifndef M_VECTOR_H__ +#define M_VECTOR_H__ + +#ifdef ESLOPE + +#include "m_fixed.h" +#include "tables.h" + +#define TWOPI M_PI*2.0 +#define HALFPI M_PI*0.5 +#define QUARTERPI M_PI*0.25 +#define EPSILON 0.000001f +#define OMEGA 10000000.0f + +typedef struct +{ + fixed_t x, y, z; +} v3fixed_t; + +typedef struct +{ + fixed_t x, y; +} v2fixed_t; + +typedef struct +{ + float x, y, z; +} v3float_t; + +typedef struct +{ + float yaw, pitch, roll; +} angles3d_t; + +typedef struct +{ + double x, y, z; +} v3double_t; + +typedef struct +{ + float x, y; +} v2float_t; + + +v3fixed_t *M_MakeVec3(const v3fixed_t *point1, const v3fixed_t *point2, v3fixed_t *a_o); +v3float_t *M_MakeVec3f(const v3float_t *point1, const v3float_t *point2, v3float_t *a_o); +void M_TranslateVec3(v3fixed_t *vec); +void M_TranslateVec3f(v3float_t *vec); +void M_AddVec3(v3fixed_t *dest, const v3fixed_t *v1, const v3fixed_t *v2); +void M_AddVec3f(v3float_t *dest, const v3float_t *v1, const v3float_t *v2); +void M_SubVec3(v3fixed_t *dest, const v3fixed_t *v1, const v3fixed_t *v2); +void M_SubVec3f(v3float_t *dest, const v3float_t *v1, const v3float_t *v2); +fixed_t M_DotVec3(const v3fixed_t *v1, const v3fixed_t *v2); +float M_DotVec3f(const v3float_t *v1, const v3float_t *v2); + +#ifdef SESLOPE +v3double_t *M_MakeVec3d(const v3double_t *point1, const v3double_t *point2, v3double_t *a_o); +double M_DotVec3d(const v3double_t *v1, const v3double_t *v2); +void M_TranslateVec3d(v3double_t *vec); +#endif + +void M_CrossProduct3(v3fixed_t *dest, const v3fixed_t *v1, const v3fixed_t *v2); +void M_CrossProduct3f(v3float_t *dest, const v3float_t *v1, const v3float_t *v2); +fixed_t FV_Magnitude(const v3fixed_t *a_normal); +float FV_Magnitudef(const v3float_t *a_normal); +fixed_t FV_NormalizeO(const v3fixed_t *a_normal, v3fixed_t *a_o); +float FV_NormalizeOf(const v3float_t *a_normal, v3float_t *a_o); +fixed_t FV_Normalize(v3fixed_t *a_normal); +fixed_t FV_Normalizef(v3float_t *a_normal); +void FV_Normal(const v3fixed_t *a_triangle, v3fixed_t *a_normal); +void FV_Normalf(const v3float_t *a_triangle, v3float_t *a_normal); +v3fixed_t *M_LoadVec(v3fixed_t *vec, fixed_t x, fixed_t y, fixed_t z); +v3fixed_t *M_CopyVec(v3fixed_t *a_o, const v3fixed_t *a_i); +v3float_t *M_LoadVecf(v3float_t *vec, float x, float y, float z); +v3float_t *M_CopyVecf(v3float_t *a_o, const v3float_t *a_i); +v3fixed_t *FV_Midpoint(const v3fixed_t *a_1, const v3fixed_t *a_2, v3fixed_t *a_o); +fixed_t FV_Distance(const v3fixed_t *p1, const v3fixed_t *p2); +v3float_t *FV_Midpointf(const v3float_t *a_1, const v3float_t *a_2, v3float_t *a_o); +angle_t FV_AngleBetweenVectors(const v3fixed_t *Vector1, const v3fixed_t *Vector2); +float FV_AngleBetweenVectorsf(const v3float_t *Vector1, const v3float_t *Vector2); +float FV_Distancef(const v3float_t *p1, const v3float_t *p2); + + +// Kalaron: something crazy, vector physics +float M_VectorYaw(v3float_t v); +float M_VectorPitch(v3float_t v); +angles3d_t *M_VectorAlignTo(float Pitch, float Yaw, float Roll, v3float_t v, byte AngleAxis, float Rate); + + + +#endif + +// EOF +#endif // #ifdef ESLOPE + diff --git a/src/p_enemy.c b/src/p_enemy.c index 54e151123..61c943d02 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -28,6 +28,10 @@ #include "hardware/hw3sound.h" #endif +#ifdef ESLOPE +#include "p_slopes.h" +#endif + #ifdef HAVE_BLUA boolean LUA_CallAction(const char *action, mobj_t *actor); #endif @@ -5614,8 +5618,17 @@ void A_MixUp(mobj_t *actor) P_SetThingPosition(players[i].mo); +#ifdef ESLOPE + players[i].mo->floorz = (players[i].mo->subsector->sector->f_slope ? + P_GetZAt(players[i].mo->subsector->sector->f_slope, players[i].mo->x, players[i].mo->y) : + players[i].mo->subsector->sector->floorheight); + players[i].mo->ceilingz = (players[i].mo->subsector->sector->c_slope ? + P_GetZAt(players[i].mo->subsector->sector->c_slope, players[i].mo->x, players[i].mo->y) : + players[i].mo->subsector->sector->ceilingheight); +#else players[i].mo->floorz = players[i].mo->subsector->sector->floorheight; players[i].mo->ceilingz = players[i].mo->subsector->sector->ceilingheight; +#endif P_CheckPosition(players[i].mo, players[i].mo->x, players[i].mo->y); } diff --git a/src/p_floor.c b/src/p_floor.c index f798174ad..65c4821ca 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -19,6 +19,9 @@ #include "z_zone.h" #include "g_game.h" #include "r_main.h" +#ifdef ESLOPE +#include "p_slopes.h" +#endif // ========================================================================== // FLOORS @@ -1174,12 +1177,18 @@ void T_SpikeSector(levelspecthink_t *spikes) if (affectsec == spikes->sector) // Applied to an actual sector { + fixed_t affectpoint = affectsec->floorheight; + +#ifdef ESLOPE + if (affectsec->f_slope) + affectpoint = P_GetZAt(affectsec->f_slope, thing->x, thing->y); +#endif if (affectsec->flags & SF_FLIPSPECIAL_FLOOR) { if (!(thing->eflags & MFE_VERTICALFLIP) && thing->momz > 0) continue; - if (thing->z == affectsec->floorheight) + if (thing->z == affectpoint) dothepain = true; } diff --git a/src/p_local.h b/src/p_local.h index 9f8918cd8..9fbab1d85 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -50,6 +50,15 @@ // above this, a height difference is considered as a 'dropoff' #define MAXSTEPMOVE (24*FRACUNIT) +#ifdef ESLOPE +// [RH] Minimum floorplane.c value for walking +// The lower the value, the steeper the slope is +#define SECPLANESTEEPSLOPE 46000 +// ESLOPE stuff - a slope of 4 or lower is so level, treat it as flat +#define LEVELSLOPE 4 +#define STEEPSLOPE 65 +#endif + #define USERANGE (64*FRACUNIT) #define MELEERANGE (64*FRACUNIT) #define MISSILERANGE (32*64*FRACUNIT) @@ -135,6 +144,12 @@ boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec); boolean P_InSpaceSector(mobj_t *mo); boolean P_InQuicksand(mobj_t *mo); +#ifdef ESLOPE +boolean P_IsObjectOnSlope(mobj_t *mo, boolean ceiling); +boolean P_SlopeGreaterThan(mobj_t *mo, boolean ceiling, int value); +boolean P_SlopeLessThan(mobj_t *mo, boolean ceiling, int value); +#endif + void P_SetObjectMomZ(mobj_t *mo, fixed_t value, boolean relative); void P_RestoreMusic(player_t *player); void P_SpawnShieldOrb(player_t *player); diff --git a/src/p_map.c b/src/p_map.c index 62cbf7b77..f484b6a2e 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -27,6 +27,10 @@ #include "r_splats.h" +#ifdef ESLOPE +#include "p_slopes.h" +#endif + #include "z_zone.h" #include "lua_hook.h" @@ -1213,8 +1217,21 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) // that contains the point. // Any contacted lines the step closer together // will adjust them. +#ifdef ESLOPE + if (newsubsec->sector->f_slope) + { + tmfloorz = tmdropoffz = P_GetZAt(newsubsec->sector->f_slope, thing->x, thing->y); + } + else +#endif tmfloorz = tmdropoffz = newsubsec->sector->floorheight; - tmceilingz = tmdrpoffceilz = newsubsec->sector->ceilingheight; + +#ifdef ESLOPE + if (newsubsec->sector->c_slope) + tmceilingz = P_GetZAt(newsubsec->sector->c_slope, thing->x, thing->y); + else +#endif + tmceilingz = newsubsec->sector->ceilingheight; // Check list of fake floors and see if tmfloorz/tmceilingz need to be altered. if (newsubsec->sector->ffloors) @@ -1228,32 +1245,42 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) if (!(rover->flags & FF_EXISTS)) continue; + fixed_t topheight = *rover->topheight; + fixed_t bottomheight = *rover->bottomheight; + +/*#ifdef ESLOPE + if (rover->t_slope) + topheight = P_GetZAt(rover->t_slope, thing->x, thing->y); + if (rover->b_slope) + bottomheight = P_GetZAt(rover->b_slope, thing->x, thing->y); +#endif*/ + if (rover->flags & FF_GOOWATER && !(thing->flags & MF_NOGRAVITY)) { // If you're inside goowater and slowing down fixed_t sinklevel = FixedMul(thing->info->height/6, thing->scale); fixed_t minspeed = FixedMul(thing->info->height/12, thing->scale); - if (thing->z < *rover->topheight && *rover->bottomheight < thingtop + if (thing->z < topheight && bottomheight < thingtop && abs(thing->momz) < minspeed) { // Oh no! The object is stick in between the surface of the goo and sinklevel! help them out! - if (!(thing->eflags & MFE_VERTICALFLIP) && thing->z > *rover->topheight - sinklevel + if (!(thing->eflags & MFE_VERTICALFLIP) && thing->z > topheight - sinklevel && thing->momz >= 0 && thing->momz < (minspeed>>2)) thing->momz += minspeed>>2; - else if (thing->eflags & MFE_VERTICALFLIP && thingtop < *rover->bottomheight + sinklevel + else if (thing->eflags & MFE_VERTICALFLIP && thingtop < bottomheight + sinklevel && thing->momz <= 0 && thing->momz > -(minspeed>>2)) thing->momz -= minspeed>>2; // Land on the top or the bottom, depending on gravity flip. - if (!(thing->eflags & MFE_VERTICALFLIP) && thing->z >= *rover->topheight - sinklevel && thing->momz <= 0) + if (!(thing->eflags & MFE_VERTICALFLIP) && thing->z >= topheight - sinklevel && thing->momz <= 0) { - if (tmfloorz < *rover->topheight - sinklevel) - tmfloorz = *rover->topheight - sinklevel; + if (tmfloorz < topheight - sinklevel) + tmfloorz = topheight - sinklevel; } - else if (thing->eflags & MFE_VERTICALFLIP && thingtop <= *rover->bottomheight + sinklevel && thing->momz >= 0) + else if (thing->eflags & MFE_VERTICALFLIP && thingtop <= bottomheight + sinklevel && thing->momz >= 0) { - if (tmceilingz > *rover->bottomheight + sinklevel) - tmceilingz = *rover->bottomheight + sinklevel; + if (tmceilingz > bottomheight + sinklevel) + tmceilingz = bottomheight + sinklevel; } } continue; @@ -1270,7 +1297,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) if (rover->flags & FF_QUICKSAND) { - if (thing->z < *rover->topheight && *rover->bottomheight < thingtop) + if (thing->z < topheight && bottomheight < thingtop) { if (tmfloorz < thing->z) tmfloorz = thing->z; @@ -1279,21 +1306,21 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) continue; } - delta1 = thing->z - (*rover->bottomheight - + ((*rover->topheight - *rover->bottomheight)/2)); - delta2 = thingtop - (*rover->bottomheight - + ((*rover->topheight - *rover->bottomheight)/2)); + delta1 = thing->z - (bottomheight + + ((topheight - bottomheight)/2)); + delta2 = thingtop - (bottomheight + + ((topheight - bottomheight)/2)); - if (*rover->topheight > tmfloorz && abs(delta1) < abs(delta2) + if (topheight > tmfloorz && abs(delta1) < abs(delta2) && !(rover->flags & FF_REVERSEPLATFORM)) { - tmfloorz = tmdropoffz = *rover->topheight; + tmfloorz = tmdropoffz = topheight; } - if (*rover->bottomheight < tmceilingz && abs(delta1) >= abs(delta2) + if (bottomheight < tmceilingz && abs(delta1) >= abs(delta2) && !(rover->flags & FF_PLATFORM) && !(thing->type == MT_SKIM && (rover->flags & FF_SWIMMABLE))) { - tmceilingz = tmdrpoffceilz = *rover->bottomheight; + tmceilingz = tmdrpoffceilz = bottomheight; } } } @@ -1470,8 +1497,21 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam) // that contains the point. // Any contacted lines the step closer together // will adjust them. +#ifdef ESLOPE + if (newsubsec->sector->f_slope) + { + tmfloorz = tmdropoffz = P_GetZAt(newsubsec->sector->f_slope, thiscam->x, thiscam->y); + } + else +#endif tmfloorz = tmdropoffz = newsubsec->sector->floorheight; - tmceilingz = tmdrpoffceilz = newsubsec->sector->ceilingheight; + +#ifdef ESLOPE + if (newsubsec->sector->c_slope) + tmceilingz = P_GetZAt(newsubsec->sector->c_slope, thiscam->x, thiscam->y); + else +#endif + tmceilingz = newsubsec->sector->ceilingheight; // Cameras use the heightsec's heights rather then the actual sector heights. // If you can see through it, why not move the camera through it too? @@ -1500,17 +1540,27 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam) if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERALL) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12) continue; - delta1 = thiscam->z - (*rover->bottomheight - + ((*rover->topheight - *rover->bottomheight)/2)); - delta2 = thingtop - (*rover->bottomheight - + ((*rover->topheight - *rover->bottomheight)/2)); - if (*rover->topheight > tmfloorz && abs(delta1) < abs(delta2)) + fixed_t topheight = *rover->topheight; + fixed_t bottomheight = *rover->bottomheight; + +/*#ifdef ESLOPE + if (rover->t_slope) + topheight = P_GetZAt(rover->t_slope, thiscam->x, thiscam->y); + if (rover->b_slope) + bottomheight = P_GetZAt(rover->b_slope, thiscam->x, thiscam->y); +#endif*/ + + delta1 = thiscam->z - (bottomheight + + ((topheight - bottomheight)/2)); + delta2 = thingtop - (bottomheight + + ((topheight - bottomheight)/2)); + if (topheight > tmfloorz && abs(delta1) < abs(delta2)) { - tmfloorz = tmdropoffz = *rover->topheight; + tmfloorz = tmdropoffz = topheight; } - if (*rover->bottomheight < tmceilingz && abs(delta1) >= abs(delta2)) + if (bottomheight < tmceilingz && abs(delta1) >= abs(delta2)) { - tmceilingz = tmdrpoffceilz = *rover->bottomheight; + tmceilingz = tmdrpoffceilz = bottomheight; } } } @@ -1703,8 +1753,30 @@ boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam) } else { - tmfloorz = thiscam->subsector->sector->floorheight; - tmceilingz = thiscam->subsector->sector->ceilingheight; +#ifdef ESLOPE // SRB2CBTODO: Checking the things momx/y help with collision issues, but makes going done slopes not as smooth + if (thiscam->subsector->sector && thiscam->subsector->sector->f_slope) + { + // SRB2CBTODO: Support a mobj's gravity for this too + if (P_GetZAt(thiscam->subsector->sector->f_slope, thiscam->x+thiscam->momx, thiscam->y+thiscam->momy) > P_GetZAt(thiscam->subsector->sector->f_slope, thiscam->x, thiscam->y)) + thiscam->floorz = P_GetZAt(thiscam->subsector->sector->f_slope, thiscam->x+thiscam->momx, thiscam->y+thiscam->momy); + else + thiscam->floorz = P_GetZAt(thiscam->subsector->sector->f_slope, thiscam->x, thiscam->y); + } + else +#endif + tmfloorz = thiscam->subsector->sector->floorheight; +#ifdef ESLOPE + if (thiscam->subsector->sector && thiscam->subsector->sector->c_slope) + { + // SRB2CBTODO: Support a mobj's gravity for this too + if (P_GetZAt(thiscam->subsector->sector->c_slope, thiscam->x+thiscam->momx, thiscam->y+thiscam->momy) < P_GetZAt(thiscam->subsector->sector->c_slope, thiscam->x, thiscam->y)) + thiscam->ceilingz = P_GetZAt(thiscam->subsector->sector->c_slope, thiscam->x, thiscam->y); + else + thiscam->ceilingz = P_GetZAt(thiscam->subsector->sector->c_slope, thiscam->x+thiscam->momx, thiscam->y+thiscam->momy); + } + else +#endif + tmceilingz = thiscam->subsector->sector->ceilingheight; } // the move is ok, @@ -1966,8 +2038,111 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) // Link the thing into its new position P_UnsetThingPosition(thing); - thing->floorz = tmfloorz; - thing->ceilingz = tmceilingz; +#ifdef ESLOPE + // By virtue of being derived from SRB2 code, Kalaron's physics are GPL. + if (P_IsObjectOnSlope(thing, false)) + { + fixed_t thingspeed = P_AproxDistance(thing->momx, thing->momy); + fixed_t predictmomx = x+(thing->momx/2); + fixed_t predictmomy = y+(thing->momy/2); + sector_t *nextsector = R_PointInSubsector(predictmomx, predictmomy)->sector; + sector_t *currentsector = R_PointInSubsector(thing->x, thing->y)->sector; + fixed_t zthrust = 0; + fixed_t slopeang = currentsector->f_slope->zangle; + fixed_t nextz = nextsector->floorheight; + if (nextsector->f_slope) + nextz = P_GetZAt(nextsector->f_slope, thing->x+predictmomx+thing->momx, thing->y+predictmomy+thing->momy); + + if (nextsector != currentsector) + { + // Give a boost up from the slope you came if the next sector is lower than the first + // If your next sector does not have a slope and you're comming off of one + if (currentsector->f_slope) + if (P_GetZAt(currentsector->f_slope, thing->x, thing->y)/FRACUNIT > (nextz/FRACUNIT)+(slopeang*3)) + //&& !nextsector->f_slope // TODO: VPHYSICS height check, not this hacky check? Or is this good enough? + if (currentsector->f_slope->zangle > 9) + { + fixed_t currentz = P_GetZAt(currentsector->f_slope, thing->x, thing->y); + fixed_t predictz = P_GetZAt(currentsector->f_slope, thing->x+thing->momx, thing->y+thing->momy); + + predictz += (((thing->pitchangle/(ANGLE_45/45))+90)/70.0f)+thingspeed/9; + + // Make sure that the z doesn't go too high for steep slopes + + predictz -= ((currentsector->f_slope->zangle)/4)*FRACUNIT; + if (currentsector->f_slope->zangle > 60) // really steep + { + predictz -= ((currentsector->f_slope->zangle)/2)*FRACUNIT; + } + + zthrust = (predictz - currentz)/2; + + if (zthrust > (30*thing->scale/100)*FRACUNIT) + zthrust = (30*thing->scale/100)*FRACUNIT; + + if (zthrust < -(30*thing->scale/100)*FRACUNIT) + zthrust = -(30*thing->scale/100)*FRACUNIT; + + if (currentz/FRACUNIT > (nextz/FRACUNIT)+(slopeang*3)) + { + // Now even out the momx/momy when catapulting off a steep slope + if (currentsector->f_slope->zangle > 65) + { + thing->momx /= 4.0f; + thing->momy /= 4.0f; + } + else if (currentsector->f_slope->zangle > 60) + { + thing->momx /= 3.5f; + thing->momy /= 3.5f; + } + else if (currentsector->f_slope->zangle > 50) + { + thing->momx /= 3.4f; + thing->momy /= 3.4f; + } + else if (currentsector->f_slope->zangle > 40) + { + thing->momx /= 3.3f; + thing->momy /= 3.3f; + } + } + + thing->momz += zthrust; // VPHYSICS TODO: Make a real formula for z trajectory going off a slope + /*CONS_Printf("CurZ %i, PredictZ %i\n", currentz/FRACUNIT, predictz/FRACUNIT); + CONS_Printf("Pitch: %i\n", thing->pitchangle/(ANG45/45)+90); + CONS_Printf("ZThrust: %i\n", zthrust/FRACUNIT);*/ + } + } + } +#endif + + // P_CheckPosition sets the tmfloorz with slopes, but after P_UnsetThingPosition, recheck the function here + // TODO: Make a function for floor/ceilingz auto check with slopes? +#ifdef ESLOPE + if (thing->subsector->sector->f_slope) + { + // TODO: Support a mobj's gravity for this too + if (P_GetZAt(thing->subsector->sector->f_slope, thing->x+thing->momx, thing->y+thing->momy) > P_GetZAt(thing->subsector->sector->f_slope, thing->x, thing->y)) + thing->floorz = P_GetZAt(thing->subsector->sector->f_slope, thing->x+thing->momx, thing->y+thing->momy); + else + thing->floorz = P_GetZAt(thing->subsector->sector->f_slope, thing->x, thing->y); + } + else +#endif + thing->floorz = tmfloorz; +#ifdef ESLOPE + if (thing->subsector->sector->c_slope) + { + // SRB2CBTODO: Support a mobj's gravity for this too + if (P_GetZAt(thing->subsector->sector->c_slope, thing->x+thing->momx, thing->y+thing->momy) < P_GetZAt(thing->subsector->sector->c_slope, thing->x, thing->y)) + thing->ceilingz = P_GetZAt(thing->subsector->sector->c_slope, thing->x, thing->y); + else + thing->ceilingz = P_GetZAt(thing->subsector->sector->c_slope, thing->x+thing->momx, thing->y+thing->momy); + } + else +#endif + thing->ceilingz = tmceilingz; thing->x = x; thing->y = y; @@ -1983,6 +2158,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y) { fixed_t tryx, tryy; + tryx = thing->x; tryy = thing->y; do { @@ -2004,7 +2180,15 @@ boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y) if (!(thing->flags & MF_NOCLIP)) { - const fixed_t maxstep = MAXSTEPMOVE; + fixed_t maxstep = MAXSTEPMOVE; + +#ifdef ESLOPE // TODO: Make this collosion better + // Maxstepmove = 0 means the object bounces like a nut while going down a slope + if (thing->subsector->sector->f_slope) + { + maxstep *= thing->subsector->sector->f_slope->zangle; + } +#endif if (tmceilingz - tmfloorz < thing->height) return false; // doesn't fit @@ -2308,12 +2492,24 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle) { fixed_t platx, platy; subsector_t *glidesector; + fixed_t floorz, ceilingz; platx = P_ReturnThrustX(player->mo, angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale)); platy = P_ReturnThrustY(player->mo, angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale)); glidesector = R_PointInSubsector(player->mo->x + platx, player->mo->y + platy); + floorz = glidesector->sector->floorheight; +#ifdef ESLOPE + if (glidesector->sector->f_slope) + floorz = P_GetZAt(glidesector->sector->f_slope, player->mo->x + platx, player->mo->y + platy); +#endif + ceilingz = glidesector->sector->ceilingheight; +#ifdef ESLOPE + if (glidesector->sector->c_slope) + ceilingz = P_GetZAt(glidesector->sector->c_slope, player->mo->x + platx, player->mo->y + platy); +#endif + if (glidesector->sector != player->mo->subsector->sector) { boolean floorclimb = false; @@ -2326,34 +2522,44 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER)) continue; + fixed_t topheight = *rover->topheight; + fixed_t bottomheight = *rover->bottomheight; + +/*#ifdef ESLOPE + if (rover->t_slope) + topheight = P_GetZAt(rover->t_slope, player->mo->x, player->mo->y); + if (rover->b_slope) + bottomheight = P_GetZAt(rover->b_slope, player->mo->x, player->mo->y); +#endif*/ + floorclimb = true; if (player->mo->eflags & MFE_VERTICALFLIP) { - if ((*rover->topheight < player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) < *rover->topheight)) + if ((topheight < player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) < topheight)) { floorclimb = true; } - if (*rover->topheight < player->mo->z) // Waaaay below the ledge. + if (topheight < player->mo->z) // Waaaay below the ledge. { floorclimb = false; } - if (*rover->bottomheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale)) + if (bottomheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale)) { floorclimb = false; } } else { - if ((*rover->bottomheight > player->mo->z) && ((player->mo->z - player->mo->momz) > *rover->bottomheight)) + if ((bottomheight > player->mo->z) && ((player->mo->z - player->mo->momz) > bottomheight)) { floorclimb = true; } - if (*rover->bottomheight > player->mo->z + player->mo->height) // Waaaay below the ledge. + if (bottomheight > player->mo->z + player->mo->height) // Waaaay below the ledge. { floorclimb = false; } - if (*rover->topheight < player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale)) + if (topheight < player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale)) { floorclimb = false; } @@ -2366,30 +2572,30 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle) if (player->mo->eflags & MFE_VERTICALFLIP) { - if ((glidesector->sector->floorheight <= player->mo->z + player->mo->height) - && ((player->mo->z + player->mo->height - player->mo->momz) <= glidesector->sector->floorheight)) + if ((floorz <= player->mo->z + player->mo->height) + && ((player->mo->z + player->mo->height - player->mo->momz) <= floorz)) floorclimb = true; - if ((glidesector->sector->floorheight > player->mo->z) + if ((floorz > player->mo->z) && glidesector->sector->floorpic == skyflatnum) return false; - if ((player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale) > glidesector->sector->ceilingheight) - || (player->mo->z + player->mo->height <= glidesector->sector->floorheight)) + if ((player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale) > ceilingz) + || (player->mo->z + player->mo->height <= floorz)) floorclimb = true; } else { - if ((glidesector->sector->ceilingheight >= player->mo->z) - && ((player->mo->z - player->mo->momz) >= glidesector->sector->ceilingheight)) + if ((ceilingz >= player->mo->z) + && ((player->mo->z - player->mo->momz) >= ceilingz)) floorclimb = true; - if ((glidesector->sector->ceilingheight < player->mo->z+player->mo->height) + if ((ceilingz < player->mo->z+player->mo->height) && glidesector->sector->ceilingpic == skyflatnum) return false; - if ((player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale) < glidesector->sector->floorheight) - || (player->mo->z >= glidesector->sector->ceilingheight)) + if ((player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale) < ceilingz) + || (player->mo->z >= ceilingz)) floorclimb = true; } @@ -2408,6 +2614,7 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle) static boolean PTR_SlideTraverse(intercept_t *in) { line_t *li; + fixed_t maxstep; I_Assert(in->isaline); @@ -2440,7 +2647,17 @@ static boolean PTR_SlideTraverse(intercept_t *in) if (opentop - slidemo->z < slidemo->height) goto isblocking; // mobj is too high - if (openbottom - slidemo->z > FixedMul(MAXSTEPMOVE, slidemo->scale)) + maxstep = FixedMul(MAXSTEPMOVE, slidemo->scale); + +#ifdef ESLOPE // TODO: Make this collosion better + // Maxstepmove = 0 means the object bounces like a nut while going down a slope + if (slidemo->subsector->sector->f_slope) + { + maxstep *= slidemo->subsector->sector->f_slope->zangle; + } +#endif + + if (openbottom - slidemo->z > maxstep) goto isblocking; // too big a step up // this line doesn't block movement @@ -2476,13 +2693,23 @@ isblocking: if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP)) continue; - if (*rover->topheight < slidemo->z) + fixed_t topheight = *rover->topheight; + fixed_t bottomheight = *rover->bottomheight; + +/*#ifdef ESLOPE + if (rover->t_slope) + topheight = P_GetZAt(rover->t_slope, slidemo->x, slidemo->y); + if (rover->b_slope) + bottomheight = P_GetZAt(rover->b_slope, slidemo->x, slidemo->y); +#endif*/ + + if (topheight < slidemo->z) continue; - if (*rover->bottomheight > slidemo->z + slidemo->height) + if (bottomheight > slidemo->z + slidemo->height) continue; - // Got this far, so I guess it's climbable. + // Got this far, so I guess it's climbable. // TODO: Climbing check, also, better method to do this? if (rover->master->flags & ML_TFERLINE) { size_t linenum = li-checksector->lines[0]; @@ -3109,9 +3336,19 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush) || ((rover->flags & FF_BLOCKOTHERS) && !thing->player)) || !(rover->flags & FF_EXISTS)) continue; - delta1 = thing->z - (*rover->bottomheight + *rover->topheight)/2; - delta2 = thingtop - (*rover->bottomheight + *rover->topheight)/2; - if (*rover->bottomheight <= thing->ceilingz && abs(delta1) >= abs(delta2)) + fixed_t topheight = *rover->topheight; + fixed_t bottomheight = *rover->bottomheight; + +/*#ifdef ESLOPE + if (rover->t_slope) + topheight = P_GetZAt(rover->t_slope, thing->x, thing->y); + if (rover->b_slope) + bottomheight = P_GetZAt(rover->b_slope, thing->x, thing->y); +#endif*/ + + delta1 = thing->z - (bottomheight + topheight)/2; + delta2 = thingtop - (bottomheight + topheight)/2; + if (bottomheight <= thing->ceilingz && abs(delta1) >= abs(delta2)) { if (thing->flags & MF_PUSHABLE) { @@ -3785,7 +4022,7 @@ void P_MapEnd(void) } // P_FloorzAtPos -// Returns the floorz of the XYZ position +// Returns the floorz of the XYZ position // TODO: Need ceilingpos function too // Tails 05-26-2003 fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height) { @@ -3806,9 +4043,19 @@ fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height) if ((!(rover->flags & FF_SOLID || rover->flags & FF_QUICKSAND) || (rover->flags & FF_SWIMMABLE))) continue; + fixed_t topheight = *rover->topheight; + fixed_t bottomheight = *rover->bottomheight; + +/*#ifdef ESLOPE + if (rover->t_slope) + topheight = P_GetZAt(rover->t_slope, x, y); + if (rover->b_slope) + bottomheight = P_GetZAt(rover->b_slope, x, y); +#endif*/ + if (rover->flags & FF_QUICKSAND) { - if (z < *rover->topheight && *rover->bottomheight < thingtop) + if (z < topheight && bottomheight < thingtop) { if (floorz < z) floorz = z; @@ -3816,10 +4063,10 @@ fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height) continue; } - delta1 = z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2)); - delta2 = thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2)); - if (*rover->topheight > floorz && abs(delta1) < abs(delta2)) - floorz = *rover->topheight; + delta1 = z - (bottomheight + ((topheight - bottomheight)/2)); + delta2 = thingtop - (bottomheight + ((topheight - bottomheight)/2)); + if (topheight > floorz && abs(delta1) < abs(delta2)) + floorz = topheight; } } diff --git a/src/p_maputl.c b/src/p_maputl.c index 48dd54e8d..f311bffce 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -20,6 +20,9 @@ #include "p_maputl.h" #include "p_polyobj.h" #include "z_zone.h" +#ifdef ESLOPE +#include "p_slopes.h" +#endif // // P_AproxDistance @@ -347,31 +350,68 @@ void P_CameraLineOpening(line_t *linedef) { frontfloor = sectors[front->camsec].floorheight; frontceiling = sectors[front->camsec].ceilingheight; +#ifdef ESLOPE + if (sectors[front->camsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope) + frontfloor = P_GetZAt(sectors[front->camsec].f_slope, camera.x, camera.y); + if (sectors[front->camsec].c_slope) + frontceiling = P_GetZAt(sectors[front->camsec].c_slope, camera.x, camera.y); +#endif + } else if (front->heightsec >= 0) { frontfloor = sectors[front->heightsec].floorheight; frontceiling = sectors[front->heightsec].ceilingheight; +#ifdef ESLOPE + if (sectors[front->heightsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope) + frontfloor = P_GetZAt(sectors[front->heightsec].f_slope, camera.x, camera.y); + if (sectors[front->heightsec].c_slope) + frontceiling = P_GetZAt(sectors[front->heightsec].c_slope, camera.x, camera.y); +#endif } else { frontfloor = front->floorheight; frontceiling = front->ceilingheight; +#ifdef ESLOPE + if (front->f_slope) + frontfloor = P_GetZAt(front->f_slope, camera.x, camera.y); + if (front->c_slope) + frontceiling = P_GetZAt(front->c_slope, camera.x, camera.y); +#endif } if (back->camsec >= 0) { backfloor = sectors[back->camsec].floorheight; backceiling = sectors[back->camsec].ceilingheight; +#ifdef ESLOPE + if (sectors[back->camsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope) + frontfloor = P_GetZAt(sectors[back->camsec].f_slope, camera.x, camera.y); + if (sectors[back->camsec].c_slope) + frontceiling = P_GetZAt(sectors[back->camsec].c_slope, camera.x, camera.y); +#endif } else if (back->heightsec >= 0) { backfloor = sectors[back->heightsec].floorheight; backceiling = sectors[back->heightsec].ceilingheight; +#ifdef ESLOPE + if (sectors[back->heightsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope) + frontfloor = P_GetZAt(sectors[back->heightsec].f_slope, camera.x, camera.y); + if (sectors[back->heightsec].c_slope) + frontceiling = P_GetZAt(sectors[back->heightsec].c_slope, camera.x, camera.y); +#endif } else { backfloor = back->floorheight; backceiling = back->ceilingheight; +#ifdef ESLOPE + if (back->f_slope) + frontfloor = P_GetZAt(back->f_slope, camera.x, camera.y); + if (back->c_slope) + frontceiling = P_GetZAt(back->c_slope, camera.x, camera.y); +#endif } { @@ -416,17 +456,28 @@ void P_CameraLineOpening(line_t *linedef) if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12) continue; - delta1 = abs(mapcampointer->z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2))); - delta2 = abs(thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2))); - if (*rover->bottomheight < lowestceiling && delta1 >= delta2) - lowestceiling = *rover->bottomheight; - else if (*rover->bottomheight < highestceiling && delta1 >= delta2) - highestceiling = *rover->bottomheight; + fixed_t topheight = *rover->topheight; + fixed_t bottomheight = *rover->bottomheight; - if (*rover->topheight > highestfloor && delta1 < delta2) - highestfloor = *rover->topheight; - else if (*rover->topheight > lowestfloor && delta1 < delta2) - lowestfloor = *rover->topheight; +/*#ifdef ESLOPE + if (rover->t_slope) + topheight = P_GetZAt(rover->t_slope, camera.x, camera.y); + + if (rover->b_slope) + bottomheight = P_GetZAt(rover->b_slope, camera.x, camera.y); +#endif // ESLOPE*/ + + delta1 = abs(mapcampointer->z - (bottomheight + ((topheight - bottomheight)/2))); + delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2))); + if (bottomheight < lowestceiling && delta1 >= delta2) + lowestceiling = bottomheight; + else if (bottomheight < highestceiling && delta1 >= delta2) + highestceiling = bottomheight; + + if (topheight > highestfloor && delta1 < delta2) + highestfloor = topheight; + else if (topheight > lowestfloor && delta1 < delta2) + lowestfloor = topheight; } // Check for backsectors fake floors @@ -436,17 +487,28 @@ void P_CameraLineOpening(line_t *linedef) if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12) continue; - delta1 = abs(mapcampointer->z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2))); - delta2 = abs(thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2))); - if (*rover->bottomheight < lowestceiling && delta1 >= delta2) - lowestceiling = *rover->bottomheight; - else if (*rover->bottomheight < highestceiling && delta1 >= delta2) - highestceiling = *rover->bottomheight; + fixed_t topheight = *rover->topheight; + fixed_t bottomheight = *rover->bottomheight; - if (*rover->topheight > highestfloor && delta1 < delta2) - highestfloor = *rover->topheight; - else if (*rover->topheight > lowestfloor && delta1 < delta2) - lowestfloor = *rover->topheight; +/*#ifdef ESLOPE + if (rover->t_slope) + topheight = P_GetZAt(rover->t_slope, camera.x, camera.y); + + if (rover->b_slope) + bottomheight = P_GetZAt(rover->b_slope, camera.x, camera.y); +#endif // ESLOPE*/ + + delta1 = abs(mapcampointer->z - (bottomheight + ((topheight - bottomheight)/2))); + delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2))); + if (bottomheight < lowestceiling && delta1 >= delta2) + lowestceiling = bottomheight; + else if (bottomheight < highestceiling && delta1 >= delta2) + highestceiling = bottomheight; + + if (topheight > highestfloor && delta1 < delta2) + highestfloor = topheight; + else if (topheight > lowestfloor && delta1 < delta2) + lowestfloor = topheight; } if (highestceiling < highceiling) @@ -520,6 +582,33 @@ void P_LineOpening(line_t *linedef) { fixed_t thingtop = tmthing->z + tmthing->height; +#ifdef ESLOPE + // I suspect the math here is wrong and we should be comparing the slope Zs + // if either are slopes. + // -- Fury + if (front->c_slope && front->ceilingheight < back->ceilingheight) + { + opentop = P_GetZAt(front->c_slope, tmthing->x, tmthing->y); + if (back->c_slope) highceiling = P_GetZAt(back->c_slope, tmthing->x, tmthing->y); + } + else if (back->c_slope && front->ceilingheight >= back->ceilingheight) + { + opentop = P_GetZAt(back->c_slope, tmthing->x, tmthing->y); + if (front->c_slope) highceiling = P_GetZAt(front->c_slope, tmthing->x, tmthing->y); + } + + if (front->c_slope && front->floorheight < back->floorheight) + { + openbottom = P_GetZAt(front->f_slope, tmthing->x, tmthing->y); + if (back->f_slope) lowfloor = P_GetZAt(back->f_slope, tmthing->x, tmthing->y); + } + if (back->f_slope && front->floorheight >= back->floorheight) + { + openbottom = P_GetZAt(back->f_slope, tmthing->x, tmthing->y); + if (front->f_slope) lowfloor = P_GetZAt(back->f_slope, tmthing->x, tmthing->y); + } +#endif + // Check for fake floors in the sector. if (front->ffloors || back->ffloors #ifdef POLYOBJECTS @@ -547,23 +636,34 @@ void P_LineOpening(line_t *linedef) || (rover->flags & FF_BLOCKOTHERS && !tmthing->player))) continue; - delta1 = abs(tmthing->z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2))); - delta2 = abs(thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2))); + fixed_t topheight = *rover->topheight; + fixed_t bottomheight = *rover->bottomheight; + +/*#ifdef ESLOPE + if (rover->t_slope) + topheight = P_GetZAt(rover->t_slope, camera.x, camera.y); + + if (rover->b_slope) + bottomheight = P_GetZAt(rover->b_slope, camera.x, camera.y); +#endif*/ + + delta1 = abs(tmthing->z - (bottomheight + ((topheight - bottomheight)/2))); + delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2))); if (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF { - if (*rover->bottomheight < lowestceiling) - lowestceiling = *rover->bottomheight; - else if (*rover->bottomheight < highestceiling) - highestceiling = *rover->bottomheight; + if (bottomheight < lowestceiling) + lowestceiling = bottomheight; + else if (bottomheight < highestceiling) + highestceiling = bottomheight; } if (delta1 < delta2 && !(rover->flags & FF_REVERSEPLATFORM)) // thing is above FOF { - if (*rover->topheight > highestfloor) - highestfloor = *rover->topheight; - else if (*rover->topheight > lowestfloor) - lowestfloor = *rover->topheight; + if (topheight > highestfloor) + highestfloor = topheight; + else if (topheight > lowestfloor) + lowestfloor = topheight; } } @@ -579,23 +679,34 @@ void P_LineOpening(line_t *linedef) || (rover->flags & FF_BLOCKOTHERS && !tmthing->player))) continue; - delta1 = abs(tmthing->z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2))); - delta2 = abs(thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2))); + fixed_t topheight = *rover->topheight; + fixed_t bottomheight = *rover->bottomheight; + +/*#ifdef ESLOPE + if (rover->t_slope) + topheight = P_GetZAt(rover->t_slope, tmthing->x, tmthing->y); + + if (rover->b_slope) + bottomheight = P_GetZAt(rover->b_slope, tmthing->x, tmthing->y); +#endif*/ + + delta1 = abs(tmthing->z - (bottomheight + ((topheight - bottomheight)/2))); + delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2))); if (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF { - if (*rover->bottomheight < lowestceiling) - lowestceiling = *rover->bottomheight; - else if (*rover->bottomheight < highestceiling) - highestceiling = *rover->bottomheight; + if (bottomheight < lowestceiling) + lowestceiling = bottomheight; + else if (bottomheight < highestceiling) + highestceiling = bottomheight; } if (delta1 < delta2 && !(rover->flags & FF_REVERSEPLATFORM)) // thing is above FOF { - if (*rover->topheight > highestfloor) - highestfloor = *rover->topheight; - else if (*rover->topheight > lowestfloor) - lowestfloor = *rover->topheight; + if (topheight > highestfloor) + highestfloor = topheight; + else if (topheight > lowestfloor) + lowestfloor = topheight; } } @@ -732,6 +843,16 @@ void P_SetThingPosition(mobj_t *thing) ss = thing->subsector = R_PointInSubsector(thing->x, thing->y); + fixed_t tfloorz, tceilz; + tfloorz = ss->sector->floorheight; + tceilz = ss->sector->ceilingheight; +#ifdef ESLOPE + if (ss->sector->f_slope) + tfloorz = P_GetZAt(ss->sector->f_slope, thing->x, thing->y); + if (ss->sector->c_slope) + tceilz = P_GetZAt(ss->sector->c_slope, thing->x, thing->y); +#endif + if (!(thing->flags & MF_NOSECTOR)) { // invisible things don't go into the sector links @@ -794,10 +915,10 @@ void P_SetThingPosition(mobj_t *thing) { if (thing->eflags & MFE_VERTICALFLIP) { - if (thing->z + thing->height >= thing->subsector->sector->ceilingheight) + if (thing->z + thing->height >= tceilz) thing->eflags |= MFE_JUSTSTEPPEDDOWN; } - else if (thing->z <= thing->subsector->sector->floorheight) + else if (thing->z <= tfloorz) thing->eflags |= MFE_JUSTSTEPPEDDOWN; } } diff --git a/src/p_mobj.c b/src/p_mobj.c index e85e25b05..9c6ce831f 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -31,6 +31,9 @@ #include "i_video.h" #include "lua_hook.h" #include "b_bot.h" +#ifdef ESLOPE +#include "p_slopes.h" +#endif // protos. static CV_PossibleValue_t viewheight_cons_t[] = {{16, "MIN"}, {56, "MAX"}, {0, NULL}}; @@ -700,15 +703,75 @@ boolean P_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover) || ((rover->flags & FF_BLOCKOTHERS) && !mobj->player))) return false; - if (mobj->z > *rover->topheight) + fixed_t topheight = *rover->topheight; + fixed_t bottomheight = *rover->bottomheight; + +/*#ifdef ESLOPE + if (rover->t_slope) + topheight = P_GetZAt(rover->t_slope, mobj->x, mobj->y); + if (rover->b_slope) + bottomheight = P_GetZAt(rover->b_slope, mobj->x, mobj->y); +#endif*/ + + if (mobj->z > topheight) return false; - if (mobj->z + mobj->height < *rover->bottomheight) + if (mobj->z + mobj->height < bottomheight) return false; return true; } +fixed_t P_GetMobjZAtSecF(mobj_t *mobj, sector_t *sector) // SRB2CBTODO: This needs to be over all the code +{ + I_Assert(mobj != NULL); +#ifdef ESLOPE + if (sector->f_slope) + return P_GetZAt(sector->f_slope, mobj->x, mobj->y); + else +#endif + return sector->floorheight; +} + +fixed_t P_GetMobjZAtF(mobj_t *mobj) // SRB2CBTODO: This needs to be over all the code +{ + I_Assert(mobj != NULL); + sector_t *sector; + sector = R_PointInSubsector(mobj->x, mobj->y)->sector; + +#ifdef ESLOPE + if (sector->f_slope) + return P_GetZAt(sector->f_slope, mobj->x, mobj->y); + else +#endif + return sector->floorheight; +} + +fixed_t P_GetMobjZAtSecC(mobj_t *mobj, sector_t *sector) // SRB2CBTODO: This needs to be over all the code +{ + I_Assert(mobj != NULL); +#ifdef ESLOPE + if (sector->c_slope) + return P_GetZAt(sector->c_slope, mobj->x, mobj->y); + else +#endif + return sector->ceilingheight; +} + +fixed_t P_GetMobjZAtC(mobj_t *mobj) // SRB2CBTODO: This needs to be over all the code +{ + I_Assert(mobj != NULL); + sector_t *sector; + sector = R_PointInSubsector(mobj->x, mobj->y)->sector; + +#ifdef ESLOPE + if (sector->c_slope) + return P_GetZAt(sector->c_slope, mobj->x, mobj->y); + else +#endif + return sector->ceilingheight; +} + static void P_PlayerFlip(mobj_t *mo) { if (!mo->player) @@ -2455,6 +2518,11 @@ void P_MobjCheckWater(mobj_t *mobj) // Default if no water exists. mobj->watertop = mobj->waterbottom = mobj->subsector->sector->floorheight - 1000*FRACUNIT; +#ifdef ESLOPE // Set the correct waterbottom/top to be below the lowest point of the slope + if (mobj->subsector->sector->f_slope) + mobj->watertop = mobj->waterbottom = mobj->subsector->sector->f_slope->lowz - 1000*FRACUNIT; +#endif + // Reset water state. mobj->eflags &= ~(MFE_UNDERWATER|MFE_TOUCHWATER|MFE_GOOWATER); @@ -2465,34 +2533,45 @@ void P_MobjCheckWater(mobj_t *mobj) || ((rover->flags & FF_BLOCKOTHERS) && !mobj->player))) continue; + fixed_t topheight = *rover->topheight; + fixed_t bottomheight = *rover->bottomheight; + +/*#ifdef ESLOPE + if (rover->t_slope) + topheight = P_GetZAt(rover->t_slope, mobj->x, mobj->y); + + if (rover->b_slope) + bottomheight = P_GetZAt(rover->b_slope, mobj->x, mobj->y); +#endif*/ + if (mobj->eflags & MFE_VERTICALFLIP) { - if (*rover->topheight < (thingtop - FixedMul(mobj->info->height/2, mobj->scale)) - || *rover->bottomheight > thingtop) + if (topheight < (thingtop - FixedMul(mobj->info->height/2, mobj->scale)) + || bottomheight > thingtop) continue; } else { - if (*rover->topheight < mobj->z - || *rover->bottomheight > (mobj->z + FixedMul(mobj->info->height/2, mobj->scale))) + if (topheight < mobj->z + || bottomheight > (mobj->z + FixedMul(mobj->info->height/2, mobj->scale))) continue; } // Set the watertop and waterbottom - mobj->watertop = *rover->topheight; - mobj->waterbottom = *rover->bottomheight; + mobj->watertop = topheight; + mobj->waterbottom = bottomheight; // Just touching the water? - if (((mobj->eflags & MFE_VERTICALFLIP) && thingtop - FixedMul(mobj->info->height, mobj->scale) < *rover->bottomheight) - || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z + FixedMul(mobj->info->height, mobj->scale) > *rover->topheight)) + if (((mobj->eflags & MFE_VERTICALFLIP) && thingtop - FixedMul(mobj->info->height, mobj->scale) < bottomheight) + || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z + FixedMul(mobj->info->height, mobj->scale) > topheight)) { mobj->eflags |= MFE_TOUCHWATER; if (rover->flags & FF_GOOWATER && !(mobj->flags & MF_NOGRAVITY)) mobj->eflags |= MFE_GOOWATER; } // Actually in the water? - if (((mobj->eflags & MFE_VERTICALFLIP) && thingtop - FixedMul(mobj->info->height/2, mobj->scale) > *rover->bottomheight) - || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z + FixedMul(mobj->info->height/2, mobj->scale) < *rover->topheight)) + if (((mobj->eflags & MFE_VERTICALFLIP) && thingtop - FixedMul(mobj->info->height/2, mobj->scale) > bottomheight) + || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z + FixedMul(mobj->info->height/2, mobj->scale) < topheight)) { mobj->eflags |= MFE_UNDERWATER; if (rover->flags & FF_GOOWATER && !(mobj->flags & MF_NOGRAVITY)) diff --git a/src/p_mobj.h b/src/p_mobj.h index 6d120c473..4acdde18c 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -28,6 +28,11 @@ // Needs precompiled tables/data structures. #include "info.h" +// For slope code, we need v3float_t +#ifdef ESLOPE +#include "m_vector.h" +#endif + // // NOTES: mobj_t // @@ -349,6 +354,11 @@ typedef struct mobj_s INT32 cusval; INT32 cvmem; +#ifdef ESLOPE + angle_t pitchangle; + v3float_t vector; +#endif + // WARNING: New fields must be added separately to savegame and Lua. } mobj_t; diff --git a/src/p_slopes.c b/src/p_slopes.c new file mode 100644 index 000000000..c448b580c --- /dev/null +++ b/src/p_slopes.c @@ -0,0 +1,1211 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// Copyright(C) 2004 Stephen McGranahan +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//-------------------------------------------------------------------------- +// +// DESCRIPTION: +// Slopes +// SoM created 05/10/09 +// ZDoom + Eternity Engine Slopes, ported and enhanced by Kalaron +// +//----------------------------------------------------------------------------- + + +#include "doomdef.h" +#include "r_defs.h" +#include "r_state.h" +#include "m_bbox.h" +#include "z_zone.h" +#include "p_spec.h" +#include "p_slopes.h" +#include "r_main.h" +#include "p_maputl.h" +#include "w_wad.h" + +#ifdef ESLOPE + +// +// P_MakeSlope +// +// Alocates and fill the contents of a slope structure. +// +static pslope_t *P_MakeSlope(const v3float_t *o, const v2float_t *d, + const float zdelta, boolean isceiling) +{ + pslope_t *ret = Z_Malloc(sizeof(pslope_t), PU_LEVEL, NULL); + memset(ret, 0, sizeof(*ret)); + + ret->o.x = FLOAT_TO_FIXED(ret->of.x = o->x); + ret->o.y = FLOAT_TO_FIXED(ret->of.y = o->y); + ret->o.z = FLOAT_TO_FIXED(ret->of.z = o->z); + + ret->d.x = FLOAT_TO_FIXED(ret->df.x = d->x); + ret->d.y = FLOAT_TO_FIXED(ret->df.y = d->y); + + ret->zdelta = FLOAT_TO_FIXED(ret->zdeltaf = zdelta); + + // d = direction (v2float_t) + // + // direction.x = line->nx; + // direction.y = line->ny; + // + // o = origin (v3float_t) + // origin.x = (FIXED_TO_FLOAT(line->v2->x) + FIXED_TO_FLOAT(line->v1->x)) * 0.5f; + // origin.y = (FIXED_TO_FLOAT(line->v2->y) + FIXED_TO_FLOAT(line->v1->y)) * 0.5f; + + { + // Now calculate the normal of the plane! + v3float_t v1, v2, v3, d1, d2; + float len; + + v1.x = o->x; + v1.y = o->y; + v1.z = o->z; + + v2.x = v1.x; + v2.y = v1.y + 10.0f; + v2.z = P_GetZAtf(ret, v2.x, v2.y); + + v3.x = v1.x + 10.0f; + v3.y = v1.y; + v3.z = P_GetZAtf(ret, v3.x, v3.y); + + if (isceiling) + { + M_SubVec3f(&d1, &v1, &v3); + M_SubVec3f(&d2, &v2, &v3); + } + else + { + M_SubVec3f(&d1, &v1, &v2); + M_SubVec3f(&d2, &v3, &v2); + } + + M_CrossProduct3f(&ret->normalf, &d1, &d2); + + // Cross product length + len = (float)sqrt(ret->normalf.x * ret->normalf.x + + ret->normalf.y * ret->normalf.y + + ret->normalf.z * ret->normalf.z); + +#ifdef SLOPETHINGS + if (len == 0) + { + // Only happens when all vertices in this sector are on the same line. + // Let's just ignore this case. + CONS_Printf("Slope thing at (%d,%d) lies directly on its target line.\n", int(x>>16), int(y>>16)); + return; + } +#endif + + ret->normalf.x /= len; + ret->normalf.y /= len; + ret->normalf.z /= len; + + // ZDoom + // cross = ret->normalf + + // Fix backward normals + if ((ret->normalf.z < 0 && !isceiling) || (ret->normalf.z > 0 && isceiling)) + { + ret->normalf.x = -ret->normalf.x; + ret->normalf.y = -ret->normalf.x; + ret->normalf.z = -ret->normalf.x; + } + + } + + return ret; +} + +// +// P_CopySlope +// +// Allocates and returns a copy of the given slope structure. +// +static pslope_t *P_CopySlope(const pslope_t *src) +{ + pslope_t *ret = Z_Malloc(sizeof(pslope_t), PU_LEVEL, NULL); + memcpy(ret, src, sizeof(*ret)); + + return ret; +} + +// +// P_MakeLineNormal +// +// Calculates a 2D normal for the given line and stores it in the line +// +void P_MakeLineNormal(line_t *line) +{ + float linedx, linedy, length; + + // SRB2CBTODO: Give linedefs an fx+fy(float xy coords)? + // May cause slow downs since the float would always have to be converted/updated + linedx = FIXED_TO_FLOAT(line->v2->x) - FIXED_TO_FLOAT(line->v1->x); + linedy = FIXED_TO_FLOAT(line->v2->y) - FIXED_TO_FLOAT(line->v1->y); + + length = (float)sqrt(linedx * linedx + linedy * linedy); + line->nx = linedy / length; + line->ny = -linedx / length; + line->len = length; +} + +// +// P_GetExtent +// +// Returns the distance to the first line within the sector that +// is intersected by a line parallel to the plane normal with the point (ox, oy) +// +static float P_GetExtent(sector_t *sector, line_t *line, v3float_t *o, v2float_t *d) +{ + // ZDoom code reference: v3float_t = vertex_t + float fardist = -1.0f; + size_t i; + + // Find furthest vertex from the reference line. It, along with the two ends + // of the line, will define the plane. + // SRB2CBTODO: Use a formula to get the slope to slide objects depending on how steep + for(i = 0; i < sector->linecount; i++) + { + line_t *li = sector->lines[i]; + float dist; + + // Don't compare to the slope line. + if(li == line) + continue; + + // ZDoom code in P_AlignPlane + // dist = fabs((double(line->v1->y) - vert->y) * line->dx - (double(line->v1->x) - vert->x) * line->dy); + dist = (float)fabs((FIXED_TO_FLOAT(li->v1->x) - o->x) * d->x + (FIXED_TO_FLOAT(li->v1->y) - o->y) * d->y); + if(dist > fardist) + fardist = dist; + + dist = (float)fabs((FIXED_TO_FLOAT(li->v2->x) - o->x) * d->x + (FIXED_TO_FLOAT(li->v2->y) - o->y) * d->y); + if(dist > fardist) + fardist = dist; + } + + return fardist; +} + + +// +// P_SpawnSlope_Line +// +// Creates one or more slopes based on the given line type and front/back +// sectors. +// Kalaron: Check if dynamic slopes need recalculation +// +void P_SpawnSlope_Line(int linenum) +{ + // With dynamic slopes, it's fine to just leave this function as normal, + // because checking to see if a slope had changed will waste more memory than + // if the slope was just updated when called + line_t *line = lines + linenum; + int special = line->special; + pslope_t *fslope = NULL, *cslope = NULL; + v3float_t origin, point; + v2float_t direction; + float dz, extent; + + boolean frontfloor = (special == 386 || special == 388 || special == 393); + boolean backfloor = (special == 389 || special == 391 || special == 392); + boolean frontceil = (special == 387 || special == 388 || special == 392); + boolean backceil = (special == 390 || special == 391 || special == 393); + + if(!frontfloor && !backfloor && !frontceil && !backceil) + { + CONS_Printf("P_SpawnSlope_Line called with non-slope line special.\n"); + return; + } + + if(!line->frontsector || !line->backsector) + { + CONS_Printf("P_SpawnSlope_Line used on a line without two sides.\n"); + return; + } + + // SRB2CBTODO: Transform origin relative to the bounds of an individual FOF + origin.x = (FIXED_TO_FLOAT(line->v2->x) + FIXED_TO_FLOAT(line->v1->x)) * 0.5f; + origin.y = (FIXED_TO_FLOAT(line->v2->y) + FIXED_TO_FLOAT(line->v1->y)) * 0.5f; + + // For FOF slopes, make a special function to copy to the xy origin & direction relative to the position of the FOF on the map! + if(frontfloor || frontceil) + { + origin.z = FIXED_TO_FLOAT(line->backsector->floorheight); + direction.x = line->nx; + direction.y = line->ny; + + extent = P_GetExtent(line->frontsector, line, &origin, &direction); + + if(extent < 0.0f) + { + CONS_Printf("P_SpawnSlope_Line failed to get frontsector extent on line number %i\n", linenum); + return; + } + + // reposition the origin according to the extent + point.x = origin.x + direction.x * extent; + point.y = origin.y + direction.y * extent; + direction.x = -direction.x; + direction.y = -direction.y; + + // TODO: We take origin and point 's xy values and translate them to the center of an FOF! + + if(frontfloor) + { + + point.z = FIXED_TO_FLOAT(line->frontsector->floorheight); // Startz + dz = (FIXED_TO_FLOAT(line->backsector->floorheight) - point.z) / extent; // Destinationz + + // In P_SpawnSlopeLine the origin is the centerpoint of the sourcelinedef + + int slopeangle = 0; // All floors by default have no slope (an angle of 0, completely flat) + + v3float_t A = origin; // = line source + v3float_t B = point; // destination's value + v3float_t C = origin; // Point used to make a right triangle from A & B + + C.z = point.z; + + // To find the "angle" of a slope, we make a right triangle out of the points we have, + // point A - is point 1 of the hypotenuse, + // point B - is point 2 of the hypotenuse + // point C - has the same Z value as point b, and the same XY value as A + // + // We want to find the angle accross from the right angle + // so we use some triginometry to find the angle(fun, right?) + // We want to find the tanjent of this angle, this is: + // Opposite + // ------- = tan(x) + // Adjecent + // But actually tan doesn't do want we really want, we have to use atan to find the actual angle of the triangle's corner + float triangopplength = abs(B.z - A.z); + float triangadjlength = sqrt((B.x-C.x)*(B.x-C.x) + (B.y - C.y)*(B.y - C.y)); + //float trianghyplength = sqrt(triangopplength*triangopplength + triangadjlength*triangadjlength); // This is the hypotenuse + + // So tanjent = opposite divided by adjecent + float tanrelat = triangopplength/ triangadjlength; // tanjent = opposite / adjecent + slopeangle = atan(tanrelat)* 180 / M_PI; // Now we use atan: *180 /M_PI is needed to convert the value into degrees + + fslope = line->frontsector->f_slope = + P_MakeSlope(&point, &direction, dz, false); + + // Now remember that f_slope IS a vector + // fslope->o = origin 3D point 1 of the vector + // fslope->d = destination 3D point 2 of the vector + // fslope->normal is a 3D line perpendicular to the 3D vector + + // Sync the linedata of the line that started this slope + // SRB2CBTODO: Anything special for remote(control sector)-based slopes later? + line->frontsector->f_slope->sourceline = line; + + // To find the real highz/lowz of a slope, you need to check all the vertexes + // in the slope's sector with P_GetZAt to get the REAL lowz & highz + // Although these slopes are set by floorheights the ANGLE is what a slope is, + // so technically any slope can extend on forever (they are just bound by sectors) + // *You can use sourceline as a reference to see if two slopes really are the same + + // Default points for high and low + fixed_t highest = point.z > origin.z ? point.z : origin.z; + fixed_t lowest = point.z < origin.z ? point.z : origin.z; + highest = FLOAT_TO_FIXED(highest); + lowest = FLOAT_TO_FIXED(lowest); + + // Now check to see what the REAL high and low points of the slope inside the sector + size_t l; + + for (l = 0; l < line->frontsector->linecount; l++) + { + if (P_GetZAt(line->frontsector->f_slope, line->frontsector->lines[l]->v1->x, line->frontsector->lines[l]->v1->y) > highest) + highest = P_GetZAt(line->frontsector->f_slope, line->frontsector->lines[l]->v1->x, line->frontsector->lines[l]->v1->y); + + if (P_GetZAt(line->frontsector->f_slope, line->frontsector->lines[l]->v1->x, line->frontsector->lines[l]->v1->y) < lowest) + lowest = P_GetZAt(line->frontsector->f_slope, line->frontsector->lines[l]->v1->x, line->frontsector->lines[l]->v1->y); + } + + // Sets extra clipping data for the frontsector's slope + fslope->highz = line->frontsector->f_slope->highz = highest; + fslope->lowz = line->frontsector->f_slope->lowz = lowest; + + fslope->zangle = slopeangle; + fslope->xydirection = R_PointToAngle2(FLOAT_TO_FIXED(A.x), FLOAT_TO_FIXED(A.y), FLOAT_TO_FIXED(B.x), FLOAT_TO_FIXED(B.y))/(ANGLE_45/45); + + secplane_t *srcplane = Z_Calloc(sizeof(*srcplane), PU_LEVEL, NULL); + // ZDoom secplane port! YAY + // ret = f_slope or c_slope + srcplane->a = FLOAT_TO_FIXED (fslope->normalf.x); // cross[0] + srcplane->b = FLOAT_TO_FIXED (fslope->normalf.y); // cross[1] + srcplane->c = FLOAT_TO_FIXED (fslope->normalf.z); // cross[2] + srcplane->ic = DivScale32 (1, srcplane->c); // (1 << 32/srcplane->c) or FLOAT_TO_FIXED(1.0f/cross[2]); + + // destheight takes the destination height used in dz + srcplane->d = -TMulScale16 (srcplane->a, line->v1->x, // x + srcplane->b, line->v1->y, // y + srcplane->c, line->backsector->floorheight); // z + + // Sync the secplane! + fslope->secplane = line->frontsector->f_slope->secplane = *srcplane; + + } + if(frontceil) + { + point.z = FIXED_TO_FLOAT(line->frontsector->ceilingheight); + dz = (FIXED_TO_FLOAT(line->backsector->ceilingheight) - point.z) / extent; + + cslope = line->frontsector->c_slope = + P_MakeSlope(&point, &direction, dz, true); + + // Sync the linedata of the line that started this slope + // SRB2CBTODO: Anything special for remote(control sector)-based slopes later? + line->frontsector->c_slope->sourceline = line; + + // Remember the way the slope is formed + fixed_t highest = point.z > origin.z ? point.z : origin.z; + fixed_t lowest = point.z < origin.z ? point.z : origin.z; + highest = FLOAT_TO_FIXED(highest); + lowest = FLOAT_TO_FIXED(lowest); + size_t l; + + for (l = 0; l < line->frontsector->linecount; l++) + { + if (P_GetZAt(line->frontsector->c_slope, line->frontsector->lines[l]->v1->x, line->frontsector->lines[l]->v1->y) > highest) + highest = P_GetZAt(line->frontsector->c_slope, line->frontsector->lines[l]->v1->x, line->frontsector->lines[l]->v1->y); + + if (P_GetZAt(line->frontsector->c_slope, line->frontsector->lines[l]->v1->x, line->frontsector->lines[l]->v1->y) < lowest) + lowest = P_GetZAt(line->frontsector->c_slope, line->frontsector->lines[l]->v1->x, line->frontsector->lines[l]->v1->y); + } + + // This line special sets extra clipping data for the frontsector's slope + cslope->highz = line->frontsector->c_slope->highz = highest; + cslope->lowz = line->frontsector->c_slope->lowz = lowest; + + // SRB2CBTODO: Get XY angle of a slope and then awesome physics! // ESLOPE: + //cslope->zangle = line->frontsector->c_slope->zangle = P_GetSlopezangle(line->frontsector, highvert, lowvert); + //100*(ANG45/45);//R_PointToAngle2(direction.x, direction.y, origin.x, origin.y); + // Get slope XY angle with secplane_t + secplane_t *srcplane = Z_Calloc(sizeof(*srcplane), PU_LEVEL, NULL); + // ZDoom secplane port! + // secplane_t! woot! + // ret = f_slope or c_slope + srcplane->a = FLOAT_TO_FIXED (cslope->normalf.x); // cross[0] + srcplane->b = FLOAT_TO_FIXED (cslope->normalf.y); // cross[1] + srcplane->c = FLOAT_TO_FIXED (cslope->normalf.z); // cross[2] + //plane->ic = FLOAT_TO_FIXED (1.f/cross[2]); + srcplane->ic = DivScale32 (1, srcplane->c); // (1 << 32/srcplane->c) +#ifdef SLOPETHINGS // For setting thing-based slopes + srcplane->d = -TMulScale16 (plane->a, x, + plane->b, y, + plane->c, z); +#endif + //srcheight = isceiling ? sec->GetPlaneTexZ(sector_t::floor) : sec->GetPlaneTexZ(sector_t::ceiling); + //destheight = isceiling ? refsec->GetPlaneTexZ(sector_t::floor) : refsec->GetPlaneTexZ(sector_t::ceiling); + //P_GetZAtf(ret, v2.x, v2.y) + // destheight takes the destination height used in dz + srcplane->d = -TMulScale16 (srcplane->a, line->v1->x, + srcplane->b, line->v1->y, + srcplane->c, line->backsector->ceilingheight); + + // Sync the secplane! + cslope->secplane = line->frontsector->c_slope->secplane = *srcplane; + } + } + if(backfloor || backceil) + { + origin.z = FIXED_TO_FLOAT(line->frontsector->floorheight); + // Backsector + direction.x = -line->nx; + direction.y = -line->ny; + + extent = P_GetExtent(line->backsector, line, &origin, &direction); + + if(extent < 0.0f) + { + CONS_Printf("P_SpawnSlope_Line failed to get backsector extent on line number %i\n", linenum); + return; + } + + // reposition the origin according to the extent + point.x = origin.x + direction.x * extent; + point.y = origin.y + direction.y * extent; + direction.x = -direction.x; + direction.y = -direction.y; + + if(backfloor) + { + point.z = FIXED_TO_FLOAT(line->backsector->floorheight); + dz = (FIXED_TO_FLOAT(line->frontsector->floorheight) - point.z) / extent; + + fslope = line->backsector->f_slope = + P_MakeSlope(&point, &direction, dz, false); + + // Sync the linedata of the line that started this slope + // SRB2CBTODO: Anything special for remote(control sector)-based slopes later? + line->backsector->f_slope->sourceline = line; + + int slopeangle = 0; // All floors by default have no slope (an angle of 0) + + v3float_t A = origin; // = line source + v3float_t B = point; // destination's value + v3float_t C = origin; + + C.z = point.z; + + // To find the "angle" of a slope, we make a right triangle out of the points we have, + // point A - is point 1 of the hypotenuse, + // point B - is point 2 of the hypotenuse + // point C - has the same Z value as point b, and the same XY value as A + // + // We want to find the angle accross from the right angle + // so we use some triginometry to find the angle(fun, right?) + // We want to find the tanjent of this angle, this is: + // Opposite + // ------- = tan(x) + // Adjecent + // But actually tan doesn't do want we really want, we have to use atan to find the actual angle of the triangle's corner + float triangopplength = abs(B.z - A.z); + float triangadjlength = sqrt((B.x-C.x)*(B.x-C.x) + (B.y - C.y)*(B.y - C.y)); + //float trianghyplength = sqrt(triangopplength*triangopplength + triangadjlength*triangadjlength); // This is the hypotenuse + + // So tanjent = opposite divided by adjecent + float tanrelat = triangopplength/ triangadjlength; // tanjent = opposite / adjecent + slopeangle = atan(tanrelat)* 180 / M_PI; // Now we use atan - *180 /M_PI is needed to convert the value into degrees + + // Remember the way the slope is formed + fixed_t highest = point.z > origin.z ? point.z : origin.z; + fixed_t lowest = point.z < origin.z ? point.z : origin.z; + highest = FLOAT_TO_FIXED(highest); + lowest = FLOAT_TO_FIXED(lowest); + size_t l; + + for (l = 0; l < line->backsector->linecount; l++) + { + if (P_GetZAt(line->backsector->f_slope, line->backsector->lines[l]->v1->x, line->backsector->lines[l]->v1->y) > highest) + highest = P_GetZAt(line->backsector->f_slope, line->backsector->lines[l]->v1->x, line->backsector->lines[l]->v1->y); + + if (P_GetZAt(line->backsector->f_slope, line->backsector->lines[l]->v1->x, line->backsector->lines[l]->v1->y) < lowest) + lowest = P_GetZAt(line->backsector->f_slope, line->backsector->lines[l]->v1->x, line->backsector->lines[l]->v1->y); + } + + // This line special sets extra clipping data for the frontsector's slope + fslope->highz = line->backsector->f_slope->highz = highest; + fslope->lowz = line->backsector->f_slope->lowz = lowest; + + fslope->zangle = slopeangle; + // Get slope XY angle with secplane_t + secplane_t *srcplane = Z_Calloc(sizeof(*srcplane), PU_LEVEL, NULL); + // ZDoom secplane port! + // secplane_t! woot! + // ret = f_slope or c_slope + srcplane->a = FLOAT_TO_FIXED (fslope->normalf.x); // cross[0] + srcplane->b = FLOAT_TO_FIXED (fslope->normalf.y); // cross[1] + srcplane->c = FLOAT_TO_FIXED (fslope->normalf.z); // cross[2] + //plane->ic = FLOAT_TO_FIXED (1.f/cross[2]); + srcplane->ic = DivScale32 (1, srcplane->c); // (1 << 32/srcplane->c) +#ifdef SLOPETHINGS // For setting thing-based slopes + srcplane->d = -TMulScale16 (plane->a, x, + plane->b, y, + plane->c, z); +#endif + //srcheight = isceiling ? sec->GetPlaneTexZ(sector_t::floor) : sec->GetPlaneTexZ(sector_t::ceiling); + //destheight = isceiling ? refsec->GetPlaneTexZ(sector_t::floor) : refsec->GetPlaneTexZ(sector_t::ceiling); + //P_GetZAtf(ret, v2.x, v2.y) + // destheight takes the destination height used in dz + srcplane->d = -TMulScale16 (srcplane->a, line->v1->x, + srcplane->b, line->v1->y, + srcplane->c, line->frontsector->floorheight); + + // Sync the secplane! + fslope->secplane = line->backsector->f_slope->secplane = *srcplane; + } + if(backceil) + { + point.z = FIXED_TO_FLOAT(line->backsector->ceilingheight); + dz = (FIXED_TO_FLOAT(line->frontsector->ceilingheight) - point.z) / extent; + + cslope = line->backsector->c_slope = + P_MakeSlope(&point, &direction, dz, true); + + // Sync the linedata of the line that started this slope + // SRB2CBTODO: Anything special for remote(control sector)-based slopes later? + line->backsector->c_slope->sourceline = line; + + // Remember the way the slope is formed + fixed_t highest = point.z > origin.z ? point.z : origin.z; + fixed_t lowest = point.z < origin.z ? point.z : origin.z; + highest = FLOAT_TO_FIXED(highest); + lowest = FLOAT_TO_FIXED(lowest); + + size_t l; + + for (l = 0; l < line->backsector->linecount; l++) + { + if (P_GetZAt(line->backsector->c_slope, line->backsector->lines[l]->v1->x, line->backsector->lines[l]->v1->y) > highest) + highest = P_GetZAt(line->backsector->c_slope, line->backsector->lines[l]->v1->x, line->backsector->lines[l]->v1->y); + + if (P_GetZAt(line->backsector->c_slope, line->backsector->lines[l]->v1->x, line->backsector->lines[l]->v1->y) < lowest) + lowest = P_GetZAt(line->backsector->c_slope, line->backsector->lines[l]->v1->x, line->backsector->lines[l]->v1->y); + } + + // This line special sets extra clipping data for the backsector's slope + cslope->highz = line->backsector->c_slope->highz = highest; + cslope->lowz = line->backsector->c_slope->lowz = lowest; + + // SRB2CBTODO: Get XY angle of a slope and then awesome physics! // ESLOPE: + //cslope->zangle = line->backsector->c_slope->zangle = P_GetSlopezangle(line->backsector, highvert, lowvert); + //100*(ANG45/45);//R_PointToAngle2(direction.x, direction.y, origin.x, origin.y); + // Get slope XY angle with secplane_t + secplane_t *srcplane = Z_Calloc(sizeof(*srcplane), PU_LEVEL, NULL); + // ZDoom secplane port! + // secplane_t! woot! + // ret = f_slope or c_slope + srcplane->a = FLOAT_TO_FIXED (cslope->normalf.x); // cross[0] + srcplane->b = FLOAT_TO_FIXED (cslope->normalf.y); // cross[1] + srcplane->c = FLOAT_TO_FIXED (cslope->normalf.z); // cross[2] + //plane->ic = FLOAT_TO_FIXED (1.f/cross[2]); + srcplane->ic = DivScale32 (1, srcplane->c); // (1 << 32/srcplane->c) +#ifdef SLOPETHINGS // For setting thing-based slopes + srcplane->d = -TMulScale16 (plane->a, x, + plane->b, y, + plane->c, z); +#endif + //srcheight = isceiling ? sec->GetPlaneTexZ(sector_t::floor) : sec->GetPlaneTexZ(sector_t::ceiling); + //destheight = isceiling ? refsec->GetPlaneTexZ(sector_t::floor) : refsec->GetPlaneTexZ(sector_t::ceiling); + //P_GetZAtf(ret, v2.x, v2.y) + // destheight takes the destination height used in dz + srcplane->d = -TMulScale16 (srcplane->a, line->v1->x, + srcplane->b, line->v1->y, + srcplane->c, line->frontsector->ceilingheight); + + // Sync the secplane! + cslope->secplane = line->backsector->c_slope->secplane = *srcplane; + } + } + + if(!line->tag) + return; +} + + + +// +// P_CopySectorSlope +// +// Searches through tagged sectors and copies +// +void P_CopySectorSlope(line_t *line) +{ + sector_t *fsec = line->frontsector; + int i, special = line->special; + + // Check for copy linedefs + for(i = -1; (i = P_FindSectorFromLineTag(line, i)) >= 0;) + { + sector_t *srcsec = sectors + i; + + if((special - 393) & 1 && !fsec->f_slope && srcsec->f_slope) + fsec->f_slope = P_CopySlope(srcsec->f_slope); + if((special - 393) & 2 && !fsec->c_slope && srcsec->c_slope) + fsec->c_slope = P_CopySlope(srcsec->c_slope); + } + + //SRB2CBTODO: ESLOPE: Maybe we do need it for another to check for a plane slope? + line->special = 0; // Linedef was use to set slopes, it finished its job, so now make it a normal linedef +} + + +#include "byteptr.h" + +/* +typedef struct +{ + fixed_t z1; + fixed_t z2; +} mapvert_t;*/ + +#include "p_setup.h" +#include "p_local.h" + +//========================================================================== +// +// P_SetSlopesFromVertexHeights +// +//========================================================================== +void P_SetSlopesFromVertexHeights(lumpnum_t lumpnum) +{ + mapthing_t *mt; + boolean vt_found = false; + size_t i, j, k, l, q; + + //size_t i; + //mapthing_t *mt; + char *data; + char *datastart; + + // SRB2CBTODO: WHAT IS (5 * sizeof (short))?! It = 10 + // anything else seems to make a map not load properly, + // but this hard-coded value MUST have some reason for being what it is + size_t snummapthings = W_LumpLength(lumpnum) / (5 * sizeof (short)); + mapthing_t *smapthings = Z_Calloc(snummapthings * sizeof (*smapthings), PU_LEVEL, NULL); + fixed_t x, y; + sector_t *sector; + // Spawn axis points first so they are + // at the front of the list for fast searching. + data = datastart = W_CacheLumpNum(lumpnum, PU_LEVEL); + mt = smapthings; + for (i = 0; i < snummapthings; i++, mt++) + { + mt->x = READINT16(data); + mt->y = READINT16(data); + mt->angle = READINT16(data); + mt->type = READINT16(data); + mt->options = READINT16(data); + // mt->z hasn't been set yet! + //mt->extrainfo = (byte)(mt->type >> 12); // slope things are special, they have a bigger range of types + + //mt->type &= 4095; // SRB2CBTODO: WHAT IS THIS???? Mobj type limits?!!!! + x = mt->x*FRACUNIT; + y = mt->y*FRACUNIT; + sector = R_PointInSubsector(x, y)->sector; + // Z for objects +#ifdef ESLOPE + if (sector->f_slope) + mt->z = (short)(P_GetZAt(sector->f_slope, x, y)>>FRACBITS); + else +#endif + mt->z = (short)(sector->floorheight>>FRACBITS); + + mt->z = mt->z + (mt->options >> ZSHIFT); + + if (mt->type == THING_VertexFloorZ || mt->type == THING_VertexCeilingZ) // THING_VertexFloorZ + { + for(l = 0; l < numvertexes; l++) + { + if (vertexes[l].x == mt->x*FRACUNIT && vertexes[l].y == mt->y*FRACUNIT) + { + if (mt->type == THING_VertexFloorZ) + { + vertexes[l].z = mt->z*FRACUNIT; + //I_Error("Z value: %i", vertexes[l].z/FRACUNIT); + + } + else + { + vertexes[l].z = mt->z*FRACUNIT; // celing floor + } + vt_found = true; + } + } + //mt->type = 0; // VPHYSICS: Dynamic slopes + + + + + + + if (vt_found) + { + for (k = 0; k < numsectors; k++) + { + sector_t *sec = §ors[k]; + if (sec->linecount != 3) continue; // only works with triangular sectors + + v3float_t vt1, vt2, vt3; // cross = ret->normalf + v3float_t vec1, vec2; + + int vi1, vi2, vi3; + + vi1 = (int)(sec->lines[0]->v1 - vertexes); + vi2 = (int)(sec->lines[0]->v2 - vertexes); + vi3 = (sec->lines[1]->v1 == sec->lines[0]->v1 || sec->lines[1]->v1 == sec->lines[0]->v2)? + (int)(sec->lines[1]->v2 - vertexes) : (int)(sec->lines[1]->v1 - vertexes); + + //if (vertexes[vi1].z) + // I_Error("OSNAP %i", vertexes[vi1].z/FRACUNIT); + //if (vertexes[vi2].z) + // I_Error("OSNAP %i", vertexes[vi2].z/FRACUNIT); + //if (vertexes[vi3].z) + // I_Error("OSNAP %i", vertexes[vi3].z/FRACUNIT); + + //I_Error("%i, %i", mt->z*FRACUNIT, vertexes[vi1].z); + + //I_Error("%i, %i, %i", mt->x, mt->y, mt->z); + //P_SpawnMobj(mt->x*FRACUNIT, mt->y*FRACUNIT, mt->z*FRACUNIT, MT_RING); + + // TODO: Make sure not to spawn in the same place 2x! (we need an object in every vertex of the + // triangle sector to setup the real vertex slopes + // Check for the vertexes of all sectors + for(q = 0; q < numvertexes; q++) + { + if (vertexes[q].x == mt->x*FRACUNIT && vertexes[q].y == mt->y*FRACUNIT) + { + //I_Error("yeah %i", vertexes[q].z); + P_SpawnMobj(vertexes[q].x, vertexes[q].y, vertexes[q].z, MT_RING); +#if 0 + if ((mt->y*FRACUNIT == vertexes[vi1].y && mt->x*FRACUNIT == vertexes[vi1].x && mt->z*FRACUNIT == vertexes[vi1].z) + && !(mt->y*FRACUNIT == vertexes[vi2].y && mt->x*FRACUNIT == vertexes[vi2].x && mt->z*FRACUNIT == vertexes[vi2].z) + && !(mt->y*FRACUNIT == vertexes[vi3].y && mt->x*FRACUNIT == vertexes[vi3].x && mt->z*FRACUNIT == vertexes[vi3].z)) + P_SpawnMobj(vertexes[vi1].x, vertexes[vi1].y, vertexes[vi1].z, MT_RING); + else if ((mt->y*FRACUNIT == vertexes[vi2].y && mt->x*FRACUNIT == vertexes[vi2].x && mt->z*FRACUNIT == vertexes[vi2].z) + && !(mt->y*FRACUNIT == vertexes[vi1].y && mt->x*FRACUNIT == vertexes[vi1].x && mt->z*FRACUNIT == vertexes[vi1].z) + && !(mt->y*FRACUNIT == vertexes[vi3].y && mt->x*FRACUNIT == vertexes[vi3].x && mt->z*FRACUNIT == vertexes[vi3].z)) + P_SpawnMobj(vertexes[vi2].x, vertexes[vi2].y, vertexes[vi2].z, MT_BOUNCETV); + else if ((mt->y*FRACUNIT == vertexes[vi3].y && mt->x*FRACUNIT == vertexes[vi3].x && mt->z*FRACUNIT == vertexes[vi3].z) + && !(mt->y*FRACUNIT == vertexes[vi2].y && mt->x*FRACUNIT == vertexes[vi2].x && mt->z*FRACUNIT == vertexes[vi2].z) + && !(mt->y*FRACUNIT == vertexes[vi1].y && mt->x*FRACUNIT == vertexes[vi1].x && mt->z*FRACUNIT == vertexes[vi1].z)) + P_SpawnMobj(vertexes[vi3].x, vertexes[vi3].y, vertexes[vi3].z, MT_GFZFLOWER1); + else +#endif + continue; + } + } + + vt1.x = FIXED_TO_FLOAT(vertexes[vi1].x); + vt1.y = FIXED_TO_FLOAT(vertexes[vi1].y); + vt2.x = FIXED_TO_FLOAT(vertexes[vi2].x); + vt2.y = FIXED_TO_FLOAT(vertexes[vi2].y); + vt3.x = FIXED_TO_FLOAT(vertexes[vi3].x); + vt3.y = FIXED_TO_FLOAT(vertexes[vi3].y); + + for(j = 0; j < 2; j++) + { + + fixed_t z3; + //I_Error("Lo hicimos"); + + vt1.z = mt->z;//FIXED_TO_FLOAT(j==0 ? sec->floorheight : sec->ceilingheight); + vt2.z = mt->z;//FIXED_TO_FLOAT(j==0? sec->floorheight : sec->ceilingheight); + z3 = mt->z;//j==0? sec->floorheight : sec->ceilingheight; // Destination height + vt3.z = FIXED_TO_FLOAT(z3); + + if (P_PointOnLineSide(vertexes[vi3].x, vertexes[vi3].y, sec->lines[0]) == 0) + { + vec1.x = vt2.x - vt3.x; + vec1.y = vt2.y - vt3.y; + vec1.z = vt2.z - vt3.z; + + vec2.x = vt1.x - vt3.x; + vec2.y = vt1.y - vt3.y; + vec2.z = vt1.z - vt3.z; + } + else + { + vec1.x = vt1.x - vt3.x; + vec1.y = vt1.y - vt3.y; + vec1.z = vt1.z - vt3.z; + + vec2.x = vt2.x - vt3.x; + vec2.y = vt2.y - vt3.y; + vec2.z = vt2.z - vt3.z; + } + + + pslope_t *ret = Z_Malloc(sizeof(pslope_t), PU_LEVEL, NULL); + memset(ret, 0, sizeof(*ret)); + + { + M_CrossProduct3f(&ret->normalf, &vec1, &vec2); + + // Cross product length + float len = (float)sqrt(ret->normalf.x * ret->normalf.x + + ret->normalf.y * ret->normalf.y + + ret->normalf.z * ret->normalf.z); + + if (len == 0) + { + // Only happens when all vertices in this sector are on the same line. + // Let's just ignore this case. + //CONS_Printf("Slope thing at (%d,%d) lies directly on its target line.\n", (int)(x>>16), (int)(y>>16)); + return; + } + // cross/len + ret->normalf.x /= len; + ret->normalf.y /= len; + ret->normalf.z /= len; + + // ZDoom cross = ret->normalf + // Fix backward normals + if ((ret->normalf.z < 0 && j == 0) || (ret->normalf.z > 0 && j == 1)) + { + // cross = -cross + ret->normalf.x = -ret->normalf.x; + ret->normalf.y = -ret->normalf.x; + ret->normalf.z = -ret->normalf.x; + } + } + + secplane_t *srcplane = Z_Calloc(sizeof(*srcplane), PU_LEVEL, NULL); + + srcplane->a = FLOAT_TO_FIXED (ret->normalf.x); + srcplane->b = FLOAT_TO_FIXED (ret->normalf.y); + srcplane->c = FLOAT_TO_FIXED (ret->normalf.z); + //srcplane->ic = DivScale32 (1, srcplane->c); + srcplane->d = -TMulScale16 (srcplane->a, vertexes[vi3].x, + srcplane->b, vertexes[vi3].y, + srcplane->c, z3); + + if (j == 0) + { + sec->f_slope = ret; + sec->f_slope->secplane = *srcplane; + } + else if (j == 1) + { + sec->c_slope = ret; + sec->c_slope->secplane = *srcplane; + } + } + } + } + + + + + + + + + } + } + Z_Free(datastart); + +#if 0 // UDMF support + for(i = 0; i < numvertexdatas; i++) + { + if (vertexdatas[i].flags & VERTEXFLAG_ZCeilingEnabled) + { + vt_heights[1][i] = vertexdatas[i].zCeiling; + vt_found = true; + } + + if (vertexdatas[i].flags & VERTEXFLAG_ZFloorEnabled) + { + vt_heights[0][i] = vertexdatas[i].zFloor; + vt_found = true; + } + } + + // If vertexdata_t is ever extended for non-slope usage, this will obviously have to be deferred or removed. + delete[] vertexdatas; + vertexdatas = NULL; + numvertexdatas = 0; +#endif + + + + +} + +#include "p_maputl.h" + +#if 0 +static void P_SlopeLineToPointo (int lineid, fixed_t x, fixed_t y, fixed_t z, boolean slopeCeil) +{ + int linenum = -1; + + while ((linenum = P_FindLineFromID (lineid, linenum)) != -1) + { + const line_t *line = &lines[linenum]; + sector_t *sec; + secplane_t *plane; + + if (P_PointOnLineSide (x, y, line) == 0) + { + sec = line->frontsector; + } + else + { + sec = line->backsector; + } + if (sec == NULL) + { + continue; + } + if (slopeCeil) + { + plane = &sec->ceilingplane; + } + else + { + plane = &sec->floorplane; + } + + FVector3 p, v1, v2, cross; + + p[0] = FIXED2FLOAT (line->v1->x); + p[1] = FIXED2FLOAT (line->v1->y); + p[2] = FIXED2FLOAT (plane->ZatPoint (line->v1->x, line->v1->y)); + v1[0] = FIXED2FLOAT (line->dx); + v1[1] = FIXED2FLOAT (line->dy); + v1[2] = FIXED2FLOAT (plane->ZatPoint (line->v2->x, line->v2->y)) - p[2]; + v2[0] = FIXED2FLOAT (x - line->v1->x); + v2[1] = FIXED2FLOAT (y - line->v1->y); + v2[2] = FIXED2FLOAT (z) - p[2]; + + cross = v1 ^ v2; + double len = cross.Length(); + if (len == 0) + { + Printf ("Slope thing at (%d,%d) lies directly on its target line.\n", int(x>>16), int(y>>16)); + return; + } + cross /= len; + // Fix backward normals + if ((cross.Z < 0 && !slopeCeil) || (cross.Z > 0 && slopeCeil)) + { + cross = -cross; + } + + plane->a = FLOAT2FIXED (cross[0]); + plane->b = FLOAT2FIXED (cross[1]); + plane->c = FLOAT2FIXED (cross[2]); + //plane->ic = FLOAT2FIXED (1.f/cross[2]); + plane->ic = DivScale32 (1, plane->c); + plane->d = -TMulScale16 (plane->a, x, + plane->b, y, + plane->c, z); + } +} +#else +#if 0 +// P_SlopeLineToPoint, start from a specific linedef number(not tag) and slope to a mapthing with the angle of the linedef +static void P_SlopeLineToPoint(int linenum) +{ + line_t *line = lines + linenum; + int special = line->special; + pslope_t *fslope = NULL, *cslope = NULL; + v3float_t origin, point; + v2float_t direction; + float dz, extent; + + boolean frontfloor = (special == 386 || special == 388 || special == 393); + boolean backfloor = (special == 389 || special == 391 || special == 392); + boolean frontceil = (special == 387 || special == 388 || special == 392); + boolean backceil = (special == 390 || special == 391 || special == 393); + + // SoM: We don't need the line to retain its special type + line->special = 0; //SRB2CBTODO: ESLOPE: Maybe we do need it for another to check for a plane slope? + + if(!frontfloor && !backfloor && !frontceil && !backceil) + { + CONS_Printf("P_SpawnSlope_Line called with non-slope line special.\n"); + return; + } + + if(!line->frontsector || !line->backsector) + { + CONS_Printf("P_SpawnSlope_Line used on a line without two sides.\n"); + return; + } + + origin.x = (FIXED_TO_FLOAT(line->v2->x) + FIXED_TO_FLOAT(line->v1->x)) * 0.5f; + origin.y = (FIXED_TO_FLOAT(line->v2->y) + FIXED_TO_FLOAT(line->v1->y)) * 0.5f; + + if(frontfloor || frontceil) + { + // Do the front sector + direction.x = line->nx; + direction.y = line->ny; + + extent = P_GetExtent(line->frontsector, line, &origin, &direction); + + if(extent < 0.0f) + { + CONS_Printf("P_SpawnSlope_Line failed to get frontsector extent on line number %i\n", linenum); + return; + } + + // reposition the origin according to the extent + point.x = origin.x + direction.x * extent; + point.y = origin.y + direction.y * extent; + direction.x = -direction.x; + direction.y = -direction.y; + + // CONS_Printf("Test: X: %f, Y: %f\n", origin.x, origin.y); + + if(frontfloor) + { + point.z = FIXED_TO_FLOAT(line->frontsector->floorheight); // Startz + dz = (FIXED_TO_FLOAT(line->backsector->floorheight) - point.z) / extent; // Destinationz + + fslope = line->frontsector->f_slope = + P_MakeSlope(&point, &direction, dz, false); + + // Sync the linedata of the line that started this slope + // SRB2CBTODO: Anything special for remote(control sector)-based slopes later? + line->frontsector->f_slope->sourceline = line; + + // Remember the way the slope is formed + fixed_t highest = line->frontsector->floorheight > line->backsector->floorheight ? + line->frontsector->floorheight : line->backsector->floorheight; + fixed_t lowest = line->frontsector->floorheight < line->backsector->floorheight ? + line->frontsector->floorheight : line->backsector->floorheight; + // This line special sets extra clipping data for the frontsector's slope + fslope->highz = line->frontsector->f_slope->highz = highest; + fslope->lowz = line->frontsector->f_slope->lowz = lowest; + + // SRB2CBTODO: Get XY angle of a slope and then awesome physics! // ESLOPE: + //fslope->zangle = line->frontsector->f_slope->zangle = P_GetSlopezangle(line->frontsector, highvert, lowvert); + //100*(ANG45/45);//R_PointToAngle2(direction.x, direction.y, origin.x, origin.y); + // Get slope XY angle with secplane_t + secplane_t *srcplane = Z_Calloc(sizeof(*srcplane), PU_LEVEL, NULL); + // ZDoom secplane port! + // secplane_t! woot! + // ret = f_slope or c_slope + srcplane->a = FLOAT_TO_FIXED (fslope->normalf.x); // cross[0] + srcplane->b = FLOAT_TO_FIXED (fslope->normalf.y); // cross[1] + srcplane->c = FLOAT_TO_FIXED (fslope->normalf.z); // cross[2] + //plane->ic = FLOAT_TO_FIXED (1.f/cross[2]); + srcplane->ic = DivScale32 (1, srcplane->c); // (1 << 32/srcplane->c) +#ifdef SLOPETHINGS // For setting thing-based slopes + srcplane->d = -TMulScale16 (plane->a, x, + plane->b, y, + plane->c, z); +#endif + //srcheight = isceiling ? sec->GetPlaneTexZ(sector_t::floor) : sec->GetPlaneTexZ(sector_t::ceiling); + //destheight = isceiling ? refsec->GetPlaneTexZ(sector_t::floor) : refsec->GetPlaneTexZ(sector_t::ceiling); + //P_GetZAtf(ret, v2.x, v2.y) + // destheight takes the destination height used in dz + srcplane->d = -TMulScale16 (srcplane->a, line->v1->x, + srcplane->b, line->v1->y, + srcplane->c, line->backsector->floorheight); + + // Sync the secplane! + fslope->secplane = line->frontsector->f_slope->secplane = *srcplane; + + } + } +} +#endif +#endif + + + +//=========================================================================== +// +// P_SpawnSlopeMakers +// +//=========================================================================== +#if 0 +void P_SpawnSlopeMakers (FMapThing *firstmt, FMapThing *lastmt) +{ + FMapThing *mt; + + for (mt = firstmt; mt < lastmt; ++mt) + { + if ((mt->type >= THING_SlopeFloorPointLine && + mt->type <= THING_SetCeilingSlope) || + mt->type==THING_VavoomFloor || mt->type==THING_VavoomCeiling) + { + fixed_t x, y, z; + secplane_t *refplane; + sector_t *sec; + + x = mt->x; + y = mt->y; + sec = P_PointInSector (x, y); + if (mt->type & 1) + { + refplane = &sec->ceilingplane; + } + else + { + refplane = &sec->floorplane; + } + z = refplane->ZatPoint (x, y) + (mt->z); + if (mt->type==THING_VavoomFloor || mt->type==THING_VavoomCeiling) + { + P_VavoomSlope(sec, mt->thingid, x, y, mt->z, mt->type & 1); + } + else if (mt->type <= THING_SlopeCeilingPointLine) + { + P_SlopeLineToPoint (mt->args[0], x, y, z, mt->type & 1); + } + else + { + P_SetSlope (refplane, mt->type & 1, mt->angle, mt->args[0], x, y, z); + } + mt->type = 0; + } + } + + for (mt = firstmt; mt < lastmt; ++mt) + { + if (mt->type == THING_CopyFloorPlane || + mt->type == THING_CopyCeilingPlane) + { + P_CopyPlane (mt->args[0], mt->x, mt->y, mt->type & 1); + mt->type = 0; + } + } + + P_SetSlopesFromVertexHeights(firstmt, lastmt); +} +#endif + + + + +// ============================================================================ +// +// Various utilities related to slopes +// + +// +// P_GetZAt +// +// Returns the height of the sloped plane at (x, y) as a fixed_t +// +fixed_t P_GetZAt(pslope_t *slope, fixed_t x, fixed_t y) +{ + fixed_t dist = FixedMul(x - slope->o.x, slope->d.x) + + FixedMul(y - slope->o.y, slope->d.y); + + return slope->o.z + FixedMul(dist, slope->zdelta); +} + +// +// P_GetZAtf +// +// Returns the height of the sloped plane at (x, y) as a float +// +float P_GetZAtf(pslope_t *slope, float x, float y) +{ + //if (!slope) // SRB2CBTODO: keep this when done with debugging + // I_Error("P_GetZAtf: slope parameter is NULL"); + + float dist = (x - slope->of.x) * slope->df.x + (y - slope->of.y) * slope->df.y; + return slope->of.z + (dist * slope->zdeltaf); +} + +// +// P_DistFromPlanef +// +float P_DistFromPlanef(const v3float_t *point, const v3float_t *pori, + const v3float_t *pnormal) +{ + return (point->x - pori->x) * pnormal->x + + (point->y - pori->y) * pnormal->y + + (point->z - pori->z) * pnormal->z; +} + +// EOF +#endif // #ifdef ESLOPE + diff --git a/src/p_slopes.h b/src/p_slopes.h new file mode 100644 index 000000000..8449c1020 --- /dev/null +++ b/src/p_slopes.h @@ -0,0 +1,84 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// Copyright(C) 2004 Stephen McGranahan +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//-------------------------------------------------------------------------- +// +// DESCRIPTION: +// Slopes +// SoM created 05/10/09 +// +//----------------------------------------------------------------------------- + +#ifndef P_SLOPES_H__ +#define P_SLOPES_H__ + +#ifdef ESLOPE +// P_MakeLineNormal +// Calculates a 2D normal for the given line and stores it in the line +void P_MakeLineNormal(line_t *line); + + +// P_SpawnSlope_Line +// Creates one or more slopes based on the given line type and front/back +// sectors. +void P_SpawnSlope_Line(int linenum); + + +// Loads just map objects that make slopes, +// terrain affecting objects have to be spawned first +void P_SetSlopesFromVertexHeights(lumpnum_t lumpnum); + +typedef enum +{ + THING_SlopeFloorPointLine = 9500, + THING_SlopeCeilingPointLine = 9501, + THING_SetFloorSlope = 9502, + THING_SetCeilingSlope = 9503, + THING_CopyFloorPlane = 9510, + THING_CopyCeilingPlane = 9511, + THING_VavoomFloor=1500, + THING_VavoomCeiling=1501, + THING_VertexFloorZ=1504, + THING_VertexCeilingZ=1505, +} slopething_e; + +// +// P_CopySectorSlope +// +// Searches through tagged sectors and copies +// +void P_CopySectorSlope(line_t *line); + +// Returns the height of the sloped plane at (x, y) as a fixed_t +fixed_t P_GetZAt(pslope_t *slope, fixed_t x, fixed_t y); + + +// Returns the height of the sloped plane at (x, y) as a float +float P_GetZAtf(pslope_t *slope, float x, float y); + + +// Returns the distance of the given point from the given origin and normal. +float P_DistFromPlanef(const v3float_t *point, const v3float_t *pori, + const v3float_t *pnormal); + +#endif + +// EOF +#endif // #ifdef ESLOPE + diff --git a/src/p_spec.c b/src/p_spec.c index 323b93c6d..228273de0 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -33,6 +33,9 @@ #include "m_misc.h" #include "m_cond.h" //unlock triggers #include "lua_hook.h" // LUAh_LinedefExecute +#ifdef ESLOPE +#include "p_slopes.h" +#endif #ifdef HW3SOUND #include "hardware/hw3sound.h" @@ -4579,16 +4582,27 @@ static void P_RunSpecialSectorCheck(player_t *player, sector_t *sector) return; } + fixed_t f_affectpoint = sector->floorheight; + fixed_t c_affectpoint = sector->ceilingheight; + +#ifdef ESLOPE + if (sector->f_slope) + f_affectpoint = P_GetZAt(sector->f_slope, player->mo->x, player->mo->y); + + if (sector->c_slope) + c_affectpoint = P_GetZAt(sector->c_slope, player->mo->x, player->mo->y); +#endif + // Only go further if on the ground - if ((sector->flags & SF_FLIPSPECIAL_FLOOR) && !(sector->flags & SF_FLIPSPECIAL_CEILING) && player->mo->z != sector->floorheight) + if ((sector->flags & SF_FLIPSPECIAL_FLOOR) && !(sector->flags & SF_FLIPSPECIAL_CEILING) && player->mo->z != f_affectpoint) return; - if ((sector->flags & SF_FLIPSPECIAL_CEILING) && !(sector->flags & SF_FLIPSPECIAL_FLOOR) && player->mo->z + player->mo->height != sector->ceilingheight) + if ((sector->flags & SF_FLIPSPECIAL_CEILING) && !(sector->flags & SF_FLIPSPECIAL_FLOOR) && player->mo->z + player->mo->height != c_affectpoint) return; if ((sector->flags & SF_FLIPSPECIAL_BOTH) - && player->mo->z != sector->floorheight - && player->mo->z + player->mo->height != sector->ceilingheight) + && player->mo->z != f_affectpoint + && player->mo->z + player->mo->height != c_affectpoint) return; P_ProcessSpecialSector(player, sector, NULL); @@ -4749,6 +4763,9 @@ void P_UpdateSpecials(void) // POINT LIMIT P_CheckPointLimit(); + // Kalaron: ...We...have dynamic slopes *YESSSS* + P_SpawnDeferredSpecials(); + // ANIMATE TEXTURES for (anim = anims; anim < lastanim; anim++) { @@ -6500,6 +6517,63 @@ void P_SpawnSpecials(INT32 fromnetsave) P_RunLevelLoadExecutors(); } +#ifdef ESLOPE +// +// P_SpawnDeferredSpecials +// +// SoM: Specials that copy slopes, ect., need to be collected in a separate +// pass +// NOTE: SRB2CBTODO: A new function, P_SpawnDeferredSpecials is needed if objects +// are to be needed in this function, because this function currently needs to be +// done before 'things' are loaded, because slopes are part of this function, +// and slope height adjustments are needed for spawning objects +void P_SpawnDeferredSpecials(void) +{ + size_t i; + line_t *line; + + for(i = 0; i < numlines; i++) + { + line = lines + i; + + switch(line->special) + { + // Slopes, Eternity engine + /*{ 386, "Slope_FrontsectorFloor" }, + { 387, "Slope_FrontsectorCeiling" }, + { 388, "Slope_FrontsectorFloorAndCeiling" }, + { 389, "Slope_BacksectorFloor" }, + { 390, "Slope_BacksectorCeiling" }, + { 391, "Slope_BacksectorFloorAndCeiling" }, + { 392, "Slope_BackFloorAndFrontCeiling" }, + { 393, "Slope_BackCeilingAndFrontFloor" }, + + { 394, "Slope_FrontFloorToTaggedSlope" }, + { 395, "Slope_FrontCeilingToTaggedSlope" }, + { 396, "Slope_FrontFloorAndCeilingToTaggedSlope" },*/ + + // SoM 05/10/09: Slopes // SRB2CBTODO:! + case 386: + case 387: + case 388: + case 389: + case 390: + case 391: + case 392: + case 393: + P_SpawnSlope_Line(i); + break; + // SoM: Copy slopes + case 394: + case 395: + case 396: + P_CopySectorSlope(line); + break; + } + } +} +#endif + /** Adds 3Dfloors as appropriate based on a common control linedef. * * \param line Control linedef to use. @@ -7399,8 +7473,12 @@ void T_Pusher(pusher_t *p) || GETSECSPECIAL(referrer->special, 3) == 3) foundfloor = true; } - else if (!(GETSECSPECIAL(sec->special, 3) == 2 - || GETSECSPECIAL(sec->special, 3) == 3)) + else if ( +#ifdef ESLOPE + (!sec->f_slope) && +#endif + (!(GETSECSPECIAL(sec->special, 3) == 2 + || GETSECSPECIAL(sec->special, 3) == 3))) return; if (p->roverpusher && foundfloor == false) // Not even a 3d floor has the PUSH_MASK. diff --git a/src/p_spec.h b/src/p_spec.h index 7b6a5655c..c8cfc76da 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -36,6 +36,11 @@ void P_SpawnSpecials(INT32 fromnetsave); // every tic void P_UpdateSpecials(void); + +#ifdef ESLOPE +void P_SpawnDeferredSpecials(void); +#endif + sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 number); void P_PlayerInSpecialSector(player_t *player); void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *roversector); diff --git a/src/p_user.c b/src/p_user.c index 3c2d34a6e..e095f2a97 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1201,6 +1201,87 @@ boolean P_IsObjectOnGround(mobj_t *mo) return false; } +#ifdef ESLOPE +// +// P_IsObjectOnSlope +// +// Returns true if the player is +// on a slope. Takes reverse +// gravity into account. +// +boolean P_IsObjectOnSlope(mobj_t *mo, boolean ceiling) +{ + if (ceiling && (mo->eflags & MFE_VERTICALFLIP)) + { + if ((mo->z + mo->height >= mo->ceilingz) && mo->subsector->sector->c_slope) // SRB2CBTODO: allow being on underside of mobj too? + return true; + } + else + { + if (mo->z <= mo->floorz && mo->subsector->sector->f_slope) + return true; + } + + return false; +} + +// +// P_SlopeGreaterThan +// +// Returns true if the object is on a slope +// that has an angle greater than the value +// +boolean P_SlopeGreaterThan(mobj_t *mo, boolean ceiling, int value) +{ + if (ceiling && (mo->eflags & MFE_VERTICALFLIP)) + { + if ((mo->z + mo->height >= mo->ceilingz) && mo->subsector->sector->c_slope) + { + if (value < mo->subsector->sector->c_slope->zangle) + return true; + } + } + else + { + if (mo->z <= mo->floorz && mo->subsector->sector->f_slope) + { + if (value < mo->subsector->sector->f_slope->zangle) + return true; + } + } + + return false; +} + +// +// P_SlopeLessThan +// +// Returns true if the object is on a slope +// that has an angle less than the value +// +boolean P_SlopeLessThan(mobj_t *mo, boolean ceiling, int value) +{ + if (ceiling && (mo->eflags & MFE_VERTICALFLIP)) + { + if ((mo->z + mo->height >= mo->ceilingz) && mo->subsector->sector->c_slope) + { + if (value < mo->subsector->sector->c_slope->zangle) + return true; + } + } + else + { + if (mo->z <= mo->floorz && mo->subsector->sector->f_slope) + { + if (value < mo->subsector->sector->f_slope->zangle) + return true; + } + } + + return false; +} +#endif + // // P_IsObjectOnGroundIn // diff --git a/src/r_defs.h b/src/r_defs.h index 7f8bd7e1d..251140a3f 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -224,6 +224,49 @@ typedef struct secplane_t fixed_t a, b, c, d, ic; } secplane_t; +// Kalaron Slopes +#ifdef ESLOPE + +#include "m_vector.h" + +typedef struct +{ + // --- Information used in clipping/projection --- + // Origin vector for the plane + // NOTE: All similarly named entries in this struct do the same thing, + // differing with just 'f' in the name for float: + // o = of, d = df, zdelta = zdeltaf; the only difference is that one's fixed, + // and the one with the 'f' is floating point, for easier reference elsewhere in the code + v3fixed_t o; + v3float_t of; + + // The normal of the 3d plane the slope creates. + v3float_t normalf; + + // 2-Dimentional vector (x, y) normalized. Used to determine distance from + // the origin in 2d mapspace. + v2fixed_t d; + v2float_t df; + + // The rate at which z changes based on distance from the origin plane. + fixed_t zdelta; + float zdeltaf; + + // For comparing when a slope should be rendered + fixed_t lowz; + fixed_t highz; + + // SRB2CBTODO: This could be used for something? + // Determining the relative z values in a slope? + struct line_s *sourceline; + + // This values only check and must be updated if the slope itself is modified + USHORT zangle; // Angle of the plane going up from the ground (not mesured in degrees) + angle_t xydirection; // The direction the slope is facing (north, west, south, etc.) + secplane_t secplane; // Extra data for collision and stuff +} pslope_t; +#endif + typedef enum { SF_FLIPSPECIAL_FLOOR = 1, @@ -337,6 +380,11 @@ typedef struct sector_s precipmobj_t *preciplist; struct mprecipsecnode_s *touching_preciplist; +#ifdef ESLOPE + // Eternity engine slope + pslope_t *f_slope; // floor slope + pslope_t *c_slope; // ceiling slope +#endif // these are saved for netgames, so do not let Lua touch these! // offsets sector spawned with (via linedef type 7) @@ -396,6 +444,12 @@ typedef struct line_s char *text; // a concatination of all front and back texture names, for linedef specials that require a string. INT16 callcount; // no. of calls left before triggering, for the "X calls" linedef specials, defaults to 0 + +#ifdef ESLOPE + // SoM 05/11/09: Pre-calculated 2D normal for the line + float nx, ny; + float len; +#endif } line_t; // diff --git a/src/tables.c b/src/tables.c index fa71effef..cfc17c9c9 100644 --- a/src/tables.c +++ b/src/tables.c @@ -2225,9 +2225,6 @@ angle_t tantoangle[2049] = 536870912 }; - -#ifdef NEED_FIXED_VECTOR - static angle_t fineacon[65536*2] = { ANGLE_MAX, 2143707442, 2142143280, 2140943052, 2139931208, 2139039753, 2138233813, 2137492672, 2136802831, 2136154917, 2135542102, 2134959233, 2134402306, 2133868139, 2133354148, 2132858208, 2132378539, 2131913638, 2131462220, 2131023174, 2130595537, 2130178462, 2129771202, 2129373097, 2128983555, 2128602046, 2128228092, 2127861261, 2127501162, 2127147436, 2126799757, 2126457825, @@ -10429,6 +10426,8 @@ FUNCMATH angle_t FixedAcos(fixed_t x) return fineacon[((x<<(FINE_FRACBITS-FRACBITS)))+FRACUNIT]; } +#ifdef NEED_FIXED_VECTOR + // // AngleBetweenVectors // diff --git a/src/tables.h b/src/tables.h index 219d668b9..cd6a17ff5 100644 --- a/src/tables.h +++ b/src/tables.h @@ -96,12 +96,11 @@ FUNCMATH angle_t FixedAngle(fixed_t fa); // and with a factor, with +factor for (fa/factor) and -factor for (fa*factor) FUNCMATH angle_t FixedAngleC(fixed_t fa, fixed_t factor); - -#ifdef NEED_FIXED_VECTOR - /// The FixedAcos function FUNCMATH angle_t FixedAcos(fixed_t x); +#ifdef NEED_FIXED_VECTOR + /// Fixed Point Vector functions angle_t FV2_AngleBetweenVectors(const vector2_t *Vector1, const vector2_t *Vector2); angle_t FV3_AngleBetweenVectors(const vector3_t *Vector1, const vector3_t *Vector2); From 6e1f7e5f3ab098876a60d720563cbf31bd627525 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Sun, 19 Apr 2015 16:21:19 -0500 Subject: [PATCH 02/91] Add slope files to CMakeLists --- src/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6859e27c3..f319523b9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -32,6 +32,7 @@ set(SRB2_CORE_SOURCES m_misc.c m_queue.c m_random.c + m_vector.c md5.c mserv.c s_sound.c @@ -95,6 +96,7 @@ set(SRB2_CORE_HEADERS m_queue.h m_random.h m_swap.h + m_vector.h md5.h mserv.h p5prof.h @@ -150,6 +152,7 @@ set(SRB2_CORE_GAME_SOURCES p_saveg.c p_setup.c p_sight.c + p_slopes.c p_spec.c p_telept.c p_tick.c @@ -162,6 +165,7 @@ set(SRB2_CORE_GAME_SOURCES p_pspr.h p_saveg.h p_setup.h + p_slopes.h p_spec.h p_tick.h ) From 8d35c5064aee66f1ec038ba0f751a72e59cbf67d Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Sun, 19 Apr 2015 16:54:20 -0500 Subject: [PATCH 03/91] Fix slope generation Physics seem to work at least partially, but no rendering yet (not even in OGL) --- src/p_setup.c | 8 ++++++++ src/p_slopes.c | 16 ++++++++++------ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index f2b0c49d8..9ddd52b58 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -72,6 +72,10 @@ #include "hardware/hw_light.h" #endif +#ifdef ESLOPE +#include "p_slopes.h" +#endif + // // Map MD5, calculated on level load. // Sent to clients in PT_SERVERINFO. @@ -1166,6 +1170,10 @@ static void P_LoadLineDefs(lumpnum_t lumpnum) #ifdef POLYOBJECTS ld->polyobj = NULL; #endif + +#ifdef ESLOPE + P_MakeLineNormal(ld); +#endif } Z_Free(data); diff --git a/src/p_slopes.c b/src/p_slopes.c index c448b580c..23ba35f58 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -185,23 +185,27 @@ static float P_GetExtent(sector_t *sector, line_t *line, v3float_t *o, v2float_t for(i = 0; i < sector->linecount; i++) { line_t *li = sector->lines[i]; + vertex_t tempv; float dist; - + // Don't compare to the slope line. if(li == line) continue; - + // ZDoom code in P_AlignPlane // dist = fabs((double(line->v1->y) - vert->y) * line->dx - (double(line->v1->x) - vert->x) * line->dy); - dist = (float)fabs((FIXED_TO_FLOAT(li->v1->x) - o->x) * d->x + (FIXED_TO_FLOAT(li->v1->y) - o->y) * d->y); + //dist = (float)fabs((FIXED_TO_FLOAT(li->v1->x) - o->x) * d->x + (FIXED_TO_FLOAT(li->v1->y) - o->y) * d->y); + P_ClosestPointOnLine(li->v1->x, li->v1->y, line, &tempv); + dist = FIXED_TO_FLOAT(R_PointToDist2(tempv.x, tempv.y, line->v1->x, line->v1->y)); if(dist > fardist) fardist = dist; - dist = (float)fabs((FIXED_TO_FLOAT(li->v2->x) - o->x) * d->x + (FIXED_TO_FLOAT(li->v2->y) - o->y) * d->y); + // We shouldn't have to do this for v2... -Red + /*dist = (float)fabs((FIXED_TO_FLOAT(li->v2->x) - o->x) * d->x + (FIXED_TO_FLOAT(li->v2->y) - o->y) * d->y); if(dist > fardist) - fardist = dist; + fardist = dist;*/ } - + return fardist; } From 65719c5b998a2bf2bfde983c8f11562e769fa4ba Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Sun, 19 Apr 2015 22:20:54 -0500 Subject: [PATCH 04/91] Make wall renderer account for slopes properly (in most cases) --- src/r_bsp.c | 12 +++- src/r_segs.c | 198 ++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 200 insertions(+), 10 deletions(-) diff --git a/src/r_bsp.c b/src/r_bsp.c index fb25b8e4d..d4f769433 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -854,7 +854,11 @@ static void R_Subsector(size_t num) sub->sector->extra_colormap = frontsector->extra_colormap; - if ((frontsector->floorheight < viewz || (frontsector->heightsec != -1 + if ((( +#ifdef ESLOPE + frontsector->f_slope ? P_GetZAt(frontsector->f_slope, viewx, viewy) : +#endif + frontsector->floorheight) < viewz || (frontsector->heightsec != -1 && sectors[frontsector->heightsec].ceilingpic == skyflatnum))) { floorplane = R_FindPlane(frontsector->floorheight, frontsector->floorpic, floorlightlevel, @@ -863,7 +867,11 @@ static void R_Subsector(size_t num) else floorplane = NULL; - if ((frontsector->ceilingheight > viewz || frontsector->ceilingpic == skyflatnum + if ((( +#ifdef ESLOPE + frontsector->c_slope ? P_GetZAt(frontsector->c_slope, viewx, viewy) : +#endif + frontsector->ceilingheight) > viewz || frontsector->ceilingpic == skyflatnum || (frontsector->heightsec != -1 && sectors[frontsector->heightsec].floorpic == skyflatnum))) { diff --git a/src/r_segs.c b/src/r_segs.c index 7467f5324..d582f13fe 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -50,6 +50,9 @@ static fixed_t rw_offset2; // for splats static fixed_t rw_scale, rw_scalestep; static fixed_t rw_midtexturemid, rw_toptexturemid, rw_bottomtexturemid; static INT32 worldtop, worldbottom, worldhigh, worldlow; +#ifdef ESLOPE +static INT32 worldtopslope, worldbottomslope, worldhighslope, worldlowslope; // worldtop/bottom at end of slope +#endif static fixed_t pixhigh, pixlow, pixhighstep, pixlowstep; static fixed_t topfrac, topstep; static fixed_t bottomfrac, bottomstep; @@ -1402,6 +1405,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) INT32 i, p; lightlist_t *light; r_lightlist_t *rlight; +#ifdef ESLOPE + vertex_t segleft, segright; +#endif static size_t maxdrawsegs = 0; if (ds_p == drawsegs+maxdrawsegs) @@ -1502,8 +1508,104 @@ void R_StoreWallRange(INT32 start, INT32 stop) // calculate texture boundaries // and decide if floor / ceiling marks are needed - worldtop = frontsector->ceilingheight - viewz; - worldbottom = frontsector->floorheight - viewz; +#ifdef ESLOPE + // Figure out map coordinates of where start and end are mapping to on seg, so we can clip right for slope bullshit + if (frontsector->c_slope || frontsector->f_slope || (backsector && (backsector->c_slope || backsector->f_slope))) { + angle_t temp; + fixed_t tan; + + // left + temp = xtoviewangle[start]+viewangle; + + if (curline->v1->x == curline->v2->x) { + // Line seg is vertical, so no line-slope form for it + tan = FINETANGENT((temp+ANGLE_90)>>ANGLETOFINESHIFT); + + segleft.x = curline->v1->x; + + segleft.y = curline->v1->y-FixedMul(viewx-segleft.x, tan); + } else if (temp>>ANGLETOFINESHIFT == ANGLE_90>>ANGLETOFINESHIFT || temp>>ANGLETOFINESHIFT == ANGLE_270>>ANGLETOFINESHIFT) { + // Same problem as above, except this time with the view angle + tan = FixedDiv(curline->v2->y-curline->v1->y, curline->v2->x-curline->v1->x); + + segleft.x = viewx; + segleft.y = curline->v1->y-FixedMul(viewx-curline->v1->x, tan); + } else { + // Both lines can be written in slope-intercept form, so figure out line intersection + float a1, b1, c1, a2, b2, c2, det; // 1 is the seg, 2 is the view angle vector... + + a1 = FIXED_TO_FLOAT(curline->v2->y-curline->v1->y); + b1 = FIXED_TO_FLOAT(curline->v1->x-curline->v2->x); + c1 = a1*FIXED_TO_FLOAT(curline->v1->x) + b1*FIXED_TO_FLOAT(curline->v1->y); + + a2 = -FIXED_TO_FLOAT(FINESINE(temp>>ANGLETOFINESHIFT)); + b2 = FIXED_TO_FLOAT(FINECOSINE(temp>>ANGLETOFINESHIFT)); + c2 = a2*FIXED_TO_FLOAT(viewx) + b2*FIXED_TO_FLOAT(viewy); + + det = a1*b2 - a2*b1; + + segleft.x = FLOAT_TO_FIXED((b2*c1 - b1*c2)/det); + segleft.y = FLOAT_TO_FIXED((a1*c2 - a2*c1)/det); + } + + // right + temp = xtoviewangle[stop]+viewangle; + + if (curline->v1->x == curline->v2->x) { + // Line seg is vertical, so no line-slope form for it + tan = FINETANGENT((temp+ANGLE_90)>>ANGLETOFINESHIFT); + + segright.x = curline->v1->x; + + segright.y = curline->v1->y-FixedMul(viewx-segright.x, tan); + } else if (temp>>ANGLETOFINESHIFT == ANGLE_90>>ANGLETOFINESHIFT || temp>>ANGLETOFINESHIFT == ANGLE_270>>ANGLETOFINESHIFT) { + // Same problem as above, except this time with the view angle + tan = FixedDiv(curline->v2->y-curline->v1->y, curline->v2->x-curline->v1->x); + + segright.x = viewx; + segright.y = curline->v1->y-FixedMul(viewx-curline->v1->x, tan); + } else { + // Both lines can be written in slope-intercept form, so figure out line intersection + float a1, b1, c1, a2, b2, c2, det; // 1 is the seg, 2 is the view angle vector... + + a1 = FIXED_TO_FLOAT(curline->v2->y-curline->v1->y); + b1 = FIXED_TO_FLOAT(curline->v1->x-curline->v2->x); + c1 = a1*FIXED_TO_FLOAT(curline->v1->x) + b1*FIXED_TO_FLOAT(curline->v1->y); + + a2 = -FIXED_TO_FLOAT(FINESINE(temp>>ANGLETOFINESHIFT)); + b2 = FIXED_TO_FLOAT(FINECOSINE(temp>>ANGLETOFINESHIFT)); + c2 = a2*FIXED_TO_FLOAT(viewx) + b2*FIXED_TO_FLOAT(viewy); + + det = a1*b2 - a2*b1; + + segright.x = FLOAT_TO_FIXED((b2*c1 - b1*c2)/det); + segright.y = FLOAT_TO_FIXED((a1*c2 - a2*c1)/det); + } + } + + if (frontsector->c_slope) { + worldtop = P_GetZAt(frontsector->c_slope, segleft.x, segleft.y) - viewz; + worldtopslope = P_GetZAt(frontsector->c_slope, segright.x, segright.y) - viewz; + } else { + worldtopslope = +#else + { +#endif + worldtop = frontsector->ceilingheight - viewz; + } + + +#ifdef ESLOPE + if (frontsector->f_slope) { + worldbottom = P_GetZAt(frontsector->f_slope, segleft.x, segleft.y) - viewz; + worldbottomslope = P_GetZAt(frontsector->f_slope, segright.x, segright.y) - viewz; + } else { + worldbottomslope = +#else + { +#endif + worldbottom = frontsector->floorheight - viewz; + } midtexture = toptexture = bottomtexture = maskedtexture = 0; ds_p->maskedtexturecol = NULL; @@ -1616,17 +1718,46 @@ void R_StoreWallRange(INT32 start, INT32 stop) } } - worldhigh = backsector->ceilingheight - viewz; - worldlow = backsector->floorheight - viewz; +#ifdef ESLOPE + if (backsector->c_slope) { + worldhigh = P_GetZAt(backsector->c_slope, segleft.x, segleft.y) - viewz; + worldhighslope = P_GetZAt(backsector->c_slope, segright.x, segright.y) - viewz; + } else { + worldhighslope = +#else + { +#endif + worldhigh = backsector->ceilingheight - viewz; + } + + +#ifdef ESLOPE + if (backsector->f_slope) { + worldlow = P_GetZAt(backsector->f_slope, segleft.x, segleft.y) - viewz; + worldlowslope = P_GetZAt(backsector->f_slope, segright.x, segright.y) - viewz; + } else { + worldlowslope = +#else + { +#endif + worldlow = backsector->floorheight - viewz; + } + // hack to allow height changes in outdoor areas if (frontsector->ceilingpic == skyflatnum && backsector->ceilingpic == skyflatnum) { +#ifdef ESLOPE + worldtopslope = worldhighslope = +#endif worldtop = worldhigh; } if (worldlow != worldbottom +#ifdef ESLOPE + || worldlowslope != worldbottomslope +#endif || backsector->floorpic != frontsector->floorpic || backsector->lightlevel != frontsector->lightlevel //SoM: 3/22/2000: Check floor x and y offsets. @@ -1649,6 +1780,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) } if (worldhigh != worldtop +#ifdef ESLOPE + || worldhighslope != worldtopslope +#endif || backsector->ceilingpic != frontsector->ceilingpic || backsector->lightlevel != frontsector->lightlevel //SoM: 3/22/2000: Check floor x and y offsets. @@ -1678,7 +1812,11 @@ void R_StoreWallRange(INT32 start, INT32 stop) } // check TOP TEXTURE - if (worldhigh < worldtop) + if (worldhigh < worldtop +#ifdef ESLOPE + || worldhighslope < worldtopslope +#endif + ) { // top texture if ((linedef->flags & (ML_DONTPEGTOP) && (linedef->flags & ML_DONTPEGBOTTOM)) @@ -1721,7 +1859,11 @@ void R_StoreWallRange(INT32 start, INT32 stop) } } // check BOTTOM TEXTURE - if (worldlow > worldbottom) //seulement si VISIBLE!!! + if (worldlow > worldbottom +#ifdef ESLOPE + || worldlowslope > worldbottomslope +#endif + ) //seulement si VISIBLE!!! { // bottom texture bottomtexture = texturetranslation[sidedef->bottomtexture]; @@ -1967,6 +2109,10 @@ void R_StoreWallRange(INT32 start, INT32 stop) // calculate incremental stepping values for texture edges worldtop >>= 4; worldbottom >>= 4; +#ifdef ESLOPE + worldtopslope >>= 4; + worldbottomslope >>= 4; +#endif topstep = -FixedMul (rw_scalestep, worldtop); topfrac = (centeryfrac>>4) - FixedMul (worldtop, rw_scale); @@ -1974,6 +2120,17 @@ void R_StoreWallRange(INT32 start, INT32 stop) bottomstep = -FixedMul (rw_scalestep,worldbottom); bottomfrac = (centeryfrac>>4) - FixedMul (worldbottom, rw_scale); +#ifdef ESLOPE + if (frontsector->c_slope) { + fixed_t topfracend = (centeryfrac>>4) - FixedMul (worldtopslope, ds_p->scale2); + topstep = (topfracend-topfrac)/(stop-start+1); + } + if (frontsector->f_slope) { + fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldbottomslope, ds_p->scale2); + bottomstep = (bottomfracend-bottomfrac)/(stop-start+1); + } +#endif + dc_numlights = 0; if (frontsector->numlights) @@ -2036,17 +2193,42 @@ void R_StoreWallRange(INT32 start, INT32 stop) { worldhigh >>= 4; worldlow >>= 4; +#ifdef ESLOPE + worldhighslope >>= 4; + worldlowslope >>= 4; +#endif - if (worldhigh < worldtop) + if (worldhigh < worldtop +#ifdef ESLOPE + || worldhighslope < worldtopslope +#endif + ) { pixhigh = (centeryfrac>>4) - FixedMul (worldhigh, rw_scale); pixhighstep = -FixedMul (rw_scalestep,worldhigh); + +#ifdef ESLOPE + if (backsector->c_slope) { + fixed_t topfracend = (centeryfrac>>4) - FixedMul (worldhighslope, ds_p->scale2); + pixhighstep = (topfracend-pixhigh)/(stop-start+1); + } +#endif } - if (worldlow > worldbottom) + if (worldlow > worldbottom +#ifdef ESLOPE + || worldlowslope > worldbottomslope +#endif + ) { pixlow = (centeryfrac>>4) - FixedMul (worldlow, rw_scale); pixlowstep = -FixedMul (rw_scalestep,worldlow); +#ifdef ESLOPE + if (backsector->f_slope) { + fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldlowslope, ds_p->scale2); + pixlowstep = (bottomfracend-pixlow)/(stop-start+1); + } +#endif } { From 779faaa93f480035e46ee4082c12a6ac3b44c780 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Mon, 20 Apr 2015 02:10:14 -0500 Subject: [PATCH 05/91] SLOPES IN SOFTWARE MOD EHOLY SHIT --- src/r_bsp.c | 40 +++++++++++++++++++---- src/r_draw.c | 6 ++++ src/r_draw.h | 9 ++++++ src/r_draw8.c | 43 ++++++++++++++++++++++++ src/r_main.c | 2 ++ src/r_plane.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++-- src/r_plane.h | 9 +++++- src/r_segs.c | 14 ++++++-- 8 files changed, 202 insertions(+), 11 deletions(-) diff --git a/src/r_bsp.c b/src/r_bsp.c index d4f769433..01d2be671 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -487,6 +487,10 @@ static void R_AddLine(seg_t *line) #endif backsector->ceilingpic == frontsector->ceilingpic && backsector->floorpic == frontsector->floorpic +#ifdef ESLOPE + && backsector->f_slope == frontsector->f_slope + && backsector->c_slope == frontsector->c_slope +#endif && backsector->lightlevel == frontsector->lightlevel && !curline->sidedef->midtexture // Check offsets too! @@ -862,7 +866,11 @@ static void R_Subsector(size_t num) && sectors[frontsector->heightsec].ceilingpic == skyflatnum))) { floorplane = R_FindPlane(frontsector->floorheight, frontsector->floorpic, floorlightlevel, - frontsector->floor_xoffs, frontsector->floor_yoffs, frontsector->floorpic_angle, floorcolormap, NULL); + frontsector->floor_xoffs, frontsector->floor_yoffs, frontsector->floorpic_angle, floorcolormap, NULL +#ifdef ESLOPE + , frontsector->f_slope +#endif + ); } else floorplane = NULL; @@ -877,7 +885,11 @@ static void R_Subsector(size_t num) { ceilingplane = R_FindPlane(frontsector->ceilingheight, frontsector->ceilingpic, ceilinglightlevel, frontsector->ceiling_xoffs, frontsector->ceiling_yoffs, frontsector->ceilingpic_angle, - ceilingcolormap, NULL); + ceilingcolormap, NULL +#ifdef ESLOPE + , frontsector->c_slope +#endif + ); } else ceilingplane = NULL; @@ -914,7 +926,11 @@ static void R_Subsector(size_t num) viewz < *rover->bottomheight); ffloor[numffloors].plane = R_FindPlane(*rover->bottomheight, *rover->bottompic, *frontsector->lightlist[light].lightlevel, *rover->bottomxoffs, - *rover->bottomyoffs, *rover->bottomangle, frontsector->lightlist[light].extra_colormap, rover); + *rover->bottomyoffs, *rover->bottomangle, frontsector->lightlist[light].extra_colormap, rover +#ifdef ESLOPE + , NULL // will ffloors be slopable eventually? +#endif + ); ffloor[numffloors].height = *rover->bottomheight; ffloor[numffloors].ffloor = rover; @@ -932,7 +948,11 @@ static void R_Subsector(size_t num) light = R_GetPlaneLight(frontsector, *rover->topheight, viewz < *rover->topheight); ffloor[numffloors].plane = R_FindPlane(*rover->topheight, *rover->toppic, *frontsector->lightlist[light].lightlevel, *rover->topxoffs, *rover->topyoffs, *rover->topangle, - frontsector->lightlist[light].extra_colormap, rover); + frontsector->lightlist[light].extra_colormap, rover +#ifdef ESLOPE + , NULL // will ffloors be slopable eventually? +#endif + ); ffloor[numffloors].height = *rover->topheight; ffloor[numffloors].ffloor = rover; numffloors++; @@ -985,7 +1005,11 @@ static void R_Subsector(size_t num) polysec->lightlevel, xoff, yoff, polysec->floorpic_angle-po->angle, NULL, - NULL); + NULL +#ifdef ESLOPE + , NULL // will ffloors be slopable eventually? +#endif + ); //ffloor[numffloors].plane->polyobj = po; ffloor[numffloors].height = polysec->floorheight; @@ -1022,7 +1046,11 @@ static void R_Subsector(size_t num) light = 0; ffloor[numffloors].plane = R_FindPlane(polysec->ceilingheight, polysec->ceilingpic, polysec->lightlevel, xoff, yoff, polysec->ceilingpic_angle-po->angle, - NULL, NULL); + NULL, NULL +#ifdef ESLOPE + , NULL // will ffloors be slopable eventually? +#endif + ); //ffloor[numffloors].plane->polyobj = po; ffloor[numffloors].polyobj = po; diff --git a/src/r_draw.c b/src/r_draw.c index cd219c15f..f4886d262 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -103,6 +103,12 @@ fixed_t ds_xfrac, ds_yfrac, ds_xstep, ds_ystep; UINT8 *ds_source; // start of a 64*64 tile image UINT8 *ds_transmap; // one of the translucency tables +#ifdef ESLOPE +pslope_t *ds_slope; // Current slope being used +v3float_t ds_su, ds_sv, ds_sz; // Vectors for... stuff? +float focallengthf; +#endif + /** \brief Variable flat sizes */ diff --git a/src/r_draw.h b/src/r_draw.h index 061a271b1..179887536 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -60,6 +60,12 @@ extern fixed_t ds_xfrac, ds_yfrac, ds_xstep, ds_ystep; extern UINT8 *ds_source; // start of a 64*64 tile image extern UINT8 *ds_transmap; +#ifdef ESLOPE +pslope_t *ds_slope; // Current slope being used +v3float_t ds_su, ds_sv, ds_sz; // Vectors for... stuff? +float focallengthf; +#endif + // Variable flat sizes extern UINT32 nflatxshift; extern UINT32 nflatyshift; @@ -141,6 +147,9 @@ void ASMCALL R_DrawSpan_8_MMX(void); void R_DrawTranslatedColumn_8(void); void R_DrawTranslatedTranslucentColumn_8(void); void R_DrawSpan_8(void); +#ifdef ESLOPE +void R_DrawTiltedSpan_8(void); +#endif void R_DrawSplat_8(void); void R_DrawTranslucentSplat_8(void); void R_DrawTranslucentSpan_8(void); diff --git a/src/r_draw8.c b/src/r_draw8.c index e0264ba92..6a240c349 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -526,6 +526,49 @@ void R_DrawSpan_8 (void) } } +#ifdef ESLOPE +/** \brief The R_DrawTiltedSpan_8 function + Draw slopes! Holy sheit! +*/ +void R_DrawTiltedSpan_8(void) +{ + // x1, x2 = ds_x1, ds_x2 + int width = ds_x2 - ds_x1; + double iz, uz, vz; + BYTE *fb; + DWORD u, v; + int i; + + UINT8 *source; + UINT8 *colormap; + UINT8 *dest; + + iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx); + + uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx); + vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx); + + dest = ylookup[ds_y] + columnofs[ds_x1]; + source = ds_source; + colormap = ds_colormap; + + // The "perfect" reference version of this routine. Pretty slow. + // Use it only to see how things are supposed to look. + i = 0; + do + { + double z = 1.f/iz; + u = (INT64)(uz*z) + viewx; + v = (INT64)(vz*z) + viewy; + *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; + dest++; + iz += ds_sz.x; + uz += ds_su.x; + vz += ds_sv.x; + } while (--width >= 0); +} +#endif // ESLOPE + /** \brief The R_DrawSplat_8 function Just like R_DrawSpan_8, but skips transparent pixels. */ diff --git a/src/r_main.c b/src/r_main.c index 1edcb815b..127801598 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -527,6 +527,8 @@ static void R_InitTextureMapping(void) focallength = FixedDiv(centerxfrac, FINETANGENT(FINEANGLES/4+/*cv_fov.value*/ FIELDOFVIEW/2)); + focallengthf = FIXED_TO_FLOAT(focallength); + for (i = 0; i < FINEANGLES/2; i++) { if (FINETANGENT(i) > FRACUNIT*2) diff --git a/src/r_plane.c b/src/r_plane.c index dcff25c13..44b65ad10 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -423,7 +423,11 @@ static visplane_t *new_visplane(unsigned hash) // visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, fixed_t xoff, fixed_t yoff, angle_t plangle, extracolormap_t *planecolormap, - ffloor_t *pfloor) + ffloor_t *pfloor +#ifdef ESLOPE + , pslope_t *slope +#endif + ) { visplane_t *check; unsigned hash; @@ -462,7 +466,11 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, && xoff == check->xoffs && yoff == check->yoffs && planecolormap == check->extra_colormap && !pfloor && !check->ffloor && check->viewz == viewz - && check->viewangle == viewangle) + && check->viewangle == viewangle +#ifdef ESLOPE + && check->slope == slope +#endif + ) { return check; } @@ -485,6 +493,9 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, #ifdef POLYOBJECTS_PLANES check->polyobj = NULL; #endif +#ifdef ESLOPE + check->slope = slope; +#endif memset(check->top, 0xff, sizeof (check->top)); memset(check->bottom, 0x00, sizeof (check->bottom)); @@ -551,6 +562,9 @@ visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop) new_pl->plangle = pl->plangle; #ifdef POLYOBJECTS_PLANES new_pl->polyobj = pl->polyobj; +#endif +#ifdef ESLOPE + new_pl->slope = pl->slope; #endif pl = new_pl; pl->minx = start; @@ -905,6 +919,78 @@ void R_DrawSinglePlane(visplane_t *pl) break; } +#ifdef ESLOPE + if (pl->slope) { + // Potentially override other stuff for now cus we're mean. :< But draw a slope plane! + // I copied ZDoom's code and adapted it to SRB2... -Red + static const float ifloatpow2[16] = + { + // ifloatpow2[i] = 1 / (1 << i) + 64.f, 32.f, 16.f, 8.f, 4.f, 2.f, 1.f, 0.5f, + 0.25f, 0.125f, 0.0625f, 0.03125f, 0.015625f, 0.0078125f, + 0.00390625f, 0.001953125f + /*, 0.0009765625f, 0.00048828125f, 0.000244140625f, + 1.220703125e-4f, 6.103515625e-5, 3.0517578125e-5*/ + }; + double lxscale, lyscale; + double xscale, yscale; + v3float_t p, m, n; + angle_t ang; + double zeroheight; + + double vx = FIXED_TO_FLOAT(viewx); + double vy = FIXED_TO_FLOAT(viewy); + double vz = FIXED_TO_FLOAT(viewz); + + zeroheight = FIXED_TO_FLOAT(P_GetZAt(pl->slope, viewx, viewy)); + + // p is the texture origin in view space + // Don't add in the offsets at this stage, because doing so can result in + // errors if the flat is rotated. + ang = (ANGLE_270 - viewangle)>>ANGLETOFINESHIFT; + p.x = vx * FIXED_TO_FLOAT(FINECOSINE(ang)) - vy * FIXED_TO_FLOAT(FINESINE(ang)); + p.z = vx * FIXED_TO_FLOAT(FINESINE(ang)) + vy * FIXED_TO_FLOAT(FINECOSINE(ang)); + p.y = FIXED_TO_FLOAT(P_GetZAt(pl->slope, 0, 0)) - vz; + + // m is the v direction vector in view space + ang = (ANGLE_180 - viewangle - pl->plangle) >> ANGLETOFINESHIFT; + m.x = FIXED_TO_FLOAT(FINECOSINE(ang)); + m.z = FIXED_TO_FLOAT(FINESINE(ang)); + + // n is the u direction vector in view space + ang += ANGLE_90>>ANGLETOFINESHIFT; + ang &= FINEMASK; + n.x = -FIXED_TO_FLOAT(FINECOSINE(ang)); + n.z = -FIXED_TO_FLOAT(FINESINE(ang)); + + ang = pl->plangle>>ANGLETOFINESHIFT; + m.y = FIXED_TO_FLOAT(P_GetZAt(pl->slope, viewx + FINESINE(ang), viewy + FINECOSINE(ang))) - zeroheight; + ang += ANGLE_90>>ANGLETOFINESHIFT; + ang &= FINEMASK; + n.y = FIXED_TO_FLOAT(P_GetZAt(pl->slope, viewx + FINESINE(ang), viewy + FINECOSINE(ang))) - zeroheight; + + M_CrossProduct3f(&ds_su, &p, &m); + M_CrossProduct3f(&ds_sv, &p, &n); + M_CrossProduct3f(&ds_sz, &m, &n); + + ds_su.z *= focallengthf; + ds_sv.z *= focallengthf; + ds_sz.z *= focallengthf; + + // Premultiply the texture vectors with the scale factors +#define SFMULT 65536.f*(1<xoffs; yoffs = pl->yoffs; planeheight = abs(pl->height - pl->viewz); diff --git a/src/r_plane.h b/src/r_plane.h index f3a7f573f..b2346636b 100644 --- a/src/r_plane.h +++ b/src/r_plane.h @@ -61,6 +61,9 @@ typedef struct visplane_s #ifdef POLYOBJECTS_PLANES polyobj_t *polyobj; #endif +#ifdef ESLOPE + pslope_t *slope; +#endif } visplane_t; extern visplane_t *floorplane; @@ -91,7 +94,11 @@ void R_MapPlane(INT32 y, INT32 x1, INT32 x2); void R_MakeSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2); void R_DrawPlanes(void); visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, fixed_t xoff, fixed_t yoff, angle_t plangle, - extracolormap_t *planecolormap, ffloor_t *ffloor); + extracolormap_t *planecolormap, ffloor_t *ffloor +#ifdef ESLOPE + , pslope_t *slope +#endif + ); visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop); void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop); void R_PlaneBounds(visplane_t *plane); diff --git a/src/r_segs.c b/src/r_segs.c index d582f13fe..2cb04b25e 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -1757,6 +1757,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (worldlow != worldbottom #ifdef ESLOPE || worldlowslope != worldbottomslope + || backsector->f_slope != frontsector->f_slope #endif || backsector->floorpic != frontsector->floorpic || backsector->lightlevel != frontsector->lightlevel @@ -1782,6 +1783,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (worldhigh != worldtop #ifdef ESLOPE || worldhighslope != worldtopslope + || backsector->c_slope != frontsector->c_slope #endif || backsector->ceilingpic != frontsector->ceilingpic || backsector->lightlevel != frontsector->lightlevel @@ -2092,13 +2094,21 @@ void R_StoreWallRange(INT32 start, INT32 stop) // and doesn't need to be marked. if (frontsector->heightsec == -1) { - if (frontsector->floorheight >= viewz) + if (( +#ifdef ESLOPE + frontsector->f_slope ? P_GetZAt(frontsector->f_slope, viewx, viewy) : +#endif + frontsector->floorheight) >= viewz) { // above view plane markfloor = false; } - if (frontsector->ceilingheight <= viewz && + if (( +#ifdef ESLOPE + frontsector->c_slope ? P_GetZAt(frontsector->c_slope, viewx, viewy) : +#endif + frontsector->ceilingheight) <= viewz && frontsector->ceilingpic != skyflatnum) { // below view plane From 12202d94a99e8003b8861d6b398a8bb4984d597c Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Mon, 20 Apr 2015 12:18:56 -0500 Subject: [PATCH 06/91] Fix calculation of slope extent, whoops --- src/p_slopes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_slopes.c b/src/p_slopes.c index 23ba35f58..44f05dedd 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -196,7 +196,7 @@ static float P_GetExtent(sector_t *sector, line_t *line, v3float_t *o, v2float_t // dist = fabs((double(line->v1->y) - vert->y) * line->dx - (double(line->v1->x) - vert->x) * line->dy); //dist = (float)fabs((FIXED_TO_FLOAT(li->v1->x) - o->x) * d->x + (FIXED_TO_FLOAT(li->v1->y) - o->y) * d->y); P_ClosestPointOnLine(li->v1->x, li->v1->y, line, &tempv); - dist = FIXED_TO_FLOAT(R_PointToDist2(tempv.x, tempv.y, line->v1->x, line->v1->y)); + dist = FIXED_TO_FLOAT(R_PointToDist2(tempv.x, tempv.y, li->v1->x, li->v1->y)); if(dist > fardist) fardist = dist; From f4ea285f028ec2c838142bebe91259e096f2f36f Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Mon, 20 Apr 2015 12:31:30 -0500 Subject: [PATCH 07/91] Fix vertical linedefs on slopes rendering improperly --- src/r_segs.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/r_segs.c b/src/r_segs.c index 2cb04b25e..c313c955c 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -1517,7 +1517,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) // left temp = xtoviewangle[start]+viewangle; - if (curline->v1->x == curline->v2->x) { + /*if (curline->v1->x == curline->v2->x) { // Line seg is vertical, so no line-slope form for it tan = FINETANGENT((temp+ANGLE_90)>>ANGLETOFINESHIFT); @@ -1530,7 +1530,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) segleft.x = viewx; segleft.y = curline->v1->y-FixedMul(viewx-curline->v1->x, tan); - } else { + } else */{ // Both lines can be written in slope-intercept form, so figure out line intersection float a1, b1, c1, a2, b2, c2, det; // 1 is the seg, 2 is the view angle vector... @@ -1551,7 +1551,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) // right temp = xtoviewangle[stop]+viewangle; - if (curline->v1->x == curline->v2->x) { + /*if (curline->v1->x == curline->v2->x) { // Line seg is vertical, so no line-slope form for it tan = FINETANGENT((temp+ANGLE_90)>>ANGLETOFINESHIFT); @@ -1564,7 +1564,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) segright.x = viewx; segright.y = curline->v1->y-FixedMul(viewx-curline->v1->x, tan); - } else { + } else */{ // Both lines can be written in slope-intercept form, so figure out line intersection float a1, b1, c1, a2, b2, c2, det; // 1 is the seg, 2 is the view angle vector... From 7703eae0e8d531e986149324b97783a44bc6b8d3 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Mon, 20 Apr 2015 13:25:39 -0500 Subject: [PATCH 08/91] Actually fix slope generation (also whitespace stuff) --- src/p_slopes.c | 363 +++++++++++++++++++++++++------------------------ 1 file changed, 182 insertions(+), 181 deletions(-) diff --git a/src/p_slopes.c b/src/p_slopes.c index 44f05dedd..2c18d3611 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -1,4 +1,4 @@ -// Emacs style mode select -*- C++ -*- +// Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // Copyright(C) 2004 Stephen McGranahan @@ -7,12 +7,12 @@ // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. -// +// // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. -// +// // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA @@ -45,7 +45,7 @@ // // Alocates and fill the contents of a slope structure. // -static pslope_t *P_MakeSlope(const v3float_t *o, const v2float_t *d, +static pslope_t *P_MakeSlope(const v3float_t *o, const v2float_t *d, const float zdelta, boolean isceiling) { pslope_t *ret = Z_Malloc(sizeof(pslope_t), PU_LEVEL, NULL); @@ -59,7 +59,7 @@ static pslope_t *P_MakeSlope(const v3float_t *o, const v2float_t *d, ret->d.y = FLOAT_TO_FIXED(ret->df.y = d->y); ret->zdelta = FLOAT_TO_FIXED(ret->zdeltaf = zdelta); - + // d = direction (v2float_t) // // direction.x = line->nx; @@ -101,9 +101,9 @@ static pslope_t *P_MakeSlope(const v3float_t *o, const v2float_t *d, // Cross product length len = (float)sqrt(ret->normalf.x * ret->normalf.x + - ret->normalf.y * ret->normalf.y + + ret->normalf.y * ret->normalf.y + ret->normalf.z * ret->normalf.z); - + #ifdef SLOPETHINGS if (len == 0) { @@ -117,18 +117,18 @@ static pslope_t *P_MakeSlope(const v3float_t *o, const v2float_t *d, ret->normalf.x /= len; ret->normalf.y /= len; ret->normalf.z /= len; - + // ZDoom // cross = ret->normalf - + // Fix backward normals if ((ret->normalf.z < 0 && !isceiling) || (ret->normalf.z > 0 && isceiling)) { ret->normalf.x = -ret->normalf.x; ret->normalf.y = -ret->normalf.x; ret->normalf.z = -ret->normalf.x; - } - + } + } return ret; @@ -200,10 +200,11 @@ static float P_GetExtent(sector_t *sector, line_t *line, v3float_t *o, v2float_t if(dist > fardist) fardist = dist; - // We shouldn't have to do this for v2... -Red - /*dist = (float)fabs((FIXED_TO_FLOAT(li->v2->x) - o->x) * d->x + (FIXED_TO_FLOAT(li->v2->y) - o->y) * d->y); + // Okay, maybe do it for v2 as well? + P_ClosestPointOnLine(li->v2->x, li->v2->y, line, &tempv); + dist = FIXED_TO_FLOAT(R_PointToDist2(tempv.x, tempv.y, li->v2->x, li->v2->y)); if(dist > fardist) - fardist = dist;*/ + fardist = dist; } return fardist; @@ -228,72 +229,72 @@ void P_SpawnSlope_Line(int linenum) v3float_t origin, point; v2float_t direction; float dz, extent; - + boolean frontfloor = (special == 386 || special == 388 || special == 393); boolean backfloor = (special == 389 || special == 391 || special == 392); boolean frontceil = (special == 387 || special == 388 || special == 392); boolean backceil = (special == 390 || special == 391 || special == 393); - + if(!frontfloor && !backfloor && !frontceil && !backceil) { CONS_Printf("P_SpawnSlope_Line called with non-slope line special.\n"); return; } - + if(!line->frontsector || !line->backsector) { CONS_Printf("P_SpawnSlope_Line used on a line without two sides.\n"); return; } - + // SRB2CBTODO: Transform origin relative to the bounds of an individual FOF origin.x = (FIXED_TO_FLOAT(line->v2->x) + FIXED_TO_FLOAT(line->v1->x)) * 0.5f; origin.y = (FIXED_TO_FLOAT(line->v2->y) + FIXED_TO_FLOAT(line->v1->y)) * 0.5f; - + // For FOF slopes, make a special function to copy to the xy origin & direction relative to the position of the FOF on the map! if(frontfloor || frontceil) { origin.z = FIXED_TO_FLOAT(line->backsector->floorheight); direction.x = line->nx; direction.y = line->ny; - + extent = P_GetExtent(line->frontsector, line, &origin, &direction); - + if(extent < 0.0f) { CONS_Printf("P_SpawnSlope_Line failed to get frontsector extent on line number %i\n", linenum); return; } - + // reposition the origin according to the extent point.x = origin.x + direction.x * extent; point.y = origin.y + direction.y * extent; direction.x = -direction.x; direction.y = -direction.y; - + // TODO: We take origin and point 's xy values and translate them to the center of an FOF! - + if(frontfloor) { - + point.z = FIXED_TO_FLOAT(line->frontsector->floorheight); // Startz dz = (FIXED_TO_FLOAT(line->backsector->floorheight) - point.z) / extent; // Destinationz - + // In P_SpawnSlopeLine the origin is the centerpoint of the sourcelinedef - + int slopeangle = 0; // All floors by default have no slope (an angle of 0, completely flat) - + v3float_t A = origin; // = line source v3float_t B = point; // destination's value v3float_t C = origin; // Point used to make a right triangle from A & B - + C.z = point.z; - + // To find the "angle" of a slope, we make a right triangle out of the points we have, // point A - is point 1 of the hypotenuse, // point B - is point 2 of the hypotenuse // point C - has the same Z value as point b, and the same XY value as A - // + // // We want to find the angle accross from the right angle // so we use some triginometry to find the angle(fun, right?) // We want to find the tanjent of this angle, this is: @@ -304,54 +305,54 @@ void P_SpawnSlope_Line(int linenum) float triangopplength = abs(B.z - A.z); float triangadjlength = sqrt((B.x-C.x)*(B.x-C.x) + (B.y - C.y)*(B.y - C.y)); //float trianghyplength = sqrt(triangopplength*triangopplength + triangadjlength*triangadjlength); // This is the hypotenuse - + // So tanjent = opposite divided by adjecent float tanrelat = triangopplength/ triangadjlength; // tanjent = opposite / adjecent slopeangle = atan(tanrelat)* 180 / M_PI; // Now we use atan: *180 /M_PI is needed to convert the value into degrees - - fslope = line->frontsector->f_slope = + + fslope = line->frontsector->f_slope = P_MakeSlope(&point, &direction, dz, false); - + // Now remember that f_slope IS a vector // fslope->o = origin 3D point 1 of the vector // fslope->d = destination 3D point 2 of the vector // fslope->normal is a 3D line perpendicular to the 3D vector - + // Sync the linedata of the line that started this slope // SRB2CBTODO: Anything special for remote(control sector)-based slopes later? line->frontsector->f_slope->sourceline = line; - + // To find the real highz/lowz of a slope, you need to check all the vertexes // in the slope's sector with P_GetZAt to get the REAL lowz & highz // Although these slopes are set by floorheights the ANGLE is what a slope is, // so technically any slope can extend on forever (they are just bound by sectors) // *You can use sourceline as a reference to see if two slopes really are the same - + // Default points for high and low fixed_t highest = point.z > origin.z ? point.z : origin.z; fixed_t lowest = point.z < origin.z ? point.z : origin.z; highest = FLOAT_TO_FIXED(highest); lowest = FLOAT_TO_FIXED(lowest); - + // Now check to see what the REAL high and low points of the slope inside the sector size_t l; - + for (l = 0; l < line->frontsector->linecount; l++) { if (P_GetZAt(line->frontsector->f_slope, line->frontsector->lines[l]->v1->x, line->frontsector->lines[l]->v1->y) > highest) highest = P_GetZAt(line->frontsector->f_slope, line->frontsector->lines[l]->v1->x, line->frontsector->lines[l]->v1->y); - + if (P_GetZAt(line->frontsector->f_slope, line->frontsector->lines[l]->v1->x, line->frontsector->lines[l]->v1->y) < lowest) lowest = P_GetZAt(line->frontsector->f_slope, line->frontsector->lines[l]->v1->x, line->frontsector->lines[l]->v1->y); } - + // Sets extra clipping data for the frontsector's slope fslope->highz = line->frontsector->f_slope->highz = highest; fslope->lowz = line->frontsector->f_slope->lowz = lowest; - + fslope->zangle = slopeangle; fslope->xydirection = R_PointToAngle2(FLOAT_TO_FIXED(A.x), FLOAT_TO_FIXED(A.y), FLOAT_TO_FIXED(B.x), FLOAT_TO_FIXED(B.y))/(ANGLE_45/45); - + secplane_t *srcplane = Z_Calloc(sizeof(*srcplane), PU_LEVEL, NULL); // ZDoom secplane port! YAY // ret = f_slope or c_slope @@ -359,48 +360,48 @@ void P_SpawnSlope_Line(int linenum) srcplane->b = FLOAT_TO_FIXED (fslope->normalf.y); // cross[1] srcplane->c = FLOAT_TO_FIXED (fslope->normalf.z); // cross[2] srcplane->ic = DivScale32 (1, srcplane->c); // (1 << 32/srcplane->c) or FLOAT_TO_FIXED(1.0f/cross[2]); - - // destheight takes the destination height used in dz + + // destheight takes the destination height used in dz srcplane->d = -TMulScale16 (srcplane->a, line->v1->x, // x srcplane->b, line->v1->y, // y srcplane->c, line->backsector->floorheight); // z - + // Sync the secplane! fslope->secplane = line->frontsector->f_slope->secplane = *srcplane; - + } if(frontceil) { point.z = FIXED_TO_FLOAT(line->frontsector->ceilingheight); dz = (FIXED_TO_FLOAT(line->backsector->ceilingheight) - point.z) / extent; - - cslope = line->frontsector->c_slope = + + cslope = line->frontsector->c_slope = P_MakeSlope(&point, &direction, dz, true); - + // Sync the linedata of the line that started this slope // SRB2CBTODO: Anything special for remote(control sector)-based slopes later? line->frontsector->c_slope->sourceline = line; - + // Remember the way the slope is formed fixed_t highest = point.z > origin.z ? point.z : origin.z; fixed_t lowest = point.z < origin.z ? point.z : origin.z; highest = FLOAT_TO_FIXED(highest); lowest = FLOAT_TO_FIXED(lowest); size_t l; - + for (l = 0; l < line->frontsector->linecount; l++) { if (P_GetZAt(line->frontsector->c_slope, line->frontsector->lines[l]->v1->x, line->frontsector->lines[l]->v1->y) > highest) highest = P_GetZAt(line->frontsector->c_slope, line->frontsector->lines[l]->v1->x, line->frontsector->lines[l]->v1->y); - + if (P_GetZAt(line->frontsector->c_slope, line->frontsector->lines[l]->v1->x, line->frontsector->lines[l]->v1->y) < lowest) lowest = P_GetZAt(line->frontsector->c_slope, line->frontsector->lines[l]->v1->x, line->frontsector->lines[l]->v1->y); } - + // This line special sets extra clipping data for the frontsector's slope cslope->highz = line->frontsector->c_slope->highz = highest; cslope->lowz = line->frontsector->c_slope->lowz = lowest; - + // SRB2CBTODO: Get XY angle of a slope and then awesome physics! // ESLOPE: //cslope->zangle = line->frontsector->c_slope->zangle = P_GetSlopezangle(line->frontsector, highvert, lowvert); //100*(ANG45/45);//R_PointToAngle2(direction.x, direction.y, origin.x, origin.y); @@ -422,11 +423,11 @@ void P_SpawnSlope_Line(int linenum) //srcheight = isceiling ? sec->GetPlaneTexZ(sector_t::floor) : sec->GetPlaneTexZ(sector_t::ceiling); //destheight = isceiling ? refsec->GetPlaneTexZ(sector_t::floor) : refsec->GetPlaneTexZ(sector_t::ceiling); //P_GetZAtf(ret, v2.x, v2.y) - // destheight takes the destination height used in dz + // destheight takes the destination height used in dz srcplane->d = -TMulScale16 (srcplane->a, line->v1->x, srcplane->b, line->v1->y, srcplane->c, line->backsector->ceilingheight); - + // Sync the secplane! cslope->secplane = line->frontsector->c_slope->secplane = *srcplane; } @@ -437,46 +438,46 @@ void P_SpawnSlope_Line(int linenum) // Backsector direction.x = -line->nx; direction.y = -line->ny; - + extent = P_GetExtent(line->backsector, line, &origin, &direction); - + if(extent < 0.0f) { CONS_Printf("P_SpawnSlope_Line failed to get backsector extent on line number %i\n", linenum); return; } - + // reposition the origin according to the extent point.x = origin.x + direction.x * extent; point.y = origin.y + direction.y * extent; direction.x = -direction.x; direction.y = -direction.y; - + if(backfloor) { point.z = FIXED_TO_FLOAT(line->backsector->floorheight); dz = (FIXED_TO_FLOAT(line->frontsector->floorheight) - point.z) / extent; - - fslope = line->backsector->f_slope = + + fslope = line->backsector->f_slope = P_MakeSlope(&point, &direction, dz, false); - + // Sync the linedata of the line that started this slope // SRB2CBTODO: Anything special for remote(control sector)-based slopes later? line->backsector->f_slope->sourceline = line; - + int slopeangle = 0; // All floors by default have no slope (an angle of 0) - + v3float_t A = origin; // = line source v3float_t B = point; // destination's value v3float_t C = origin; - + C.z = point.z; - + // To find the "angle" of a slope, we make a right triangle out of the points we have, // point A - is point 1 of the hypotenuse, // point B - is point 2 of the hypotenuse // point C - has the same Z value as point b, and the same XY value as A - // + // // We want to find the angle accross from the right angle // so we use some triginometry to find the angle(fun, right?) // We want to find the tanjent of this angle, this is: @@ -487,31 +488,31 @@ void P_SpawnSlope_Line(int linenum) float triangopplength = abs(B.z - A.z); float triangadjlength = sqrt((B.x-C.x)*(B.x-C.x) + (B.y - C.y)*(B.y - C.y)); //float trianghyplength = sqrt(triangopplength*triangopplength + triangadjlength*triangadjlength); // This is the hypotenuse - + // So tanjent = opposite divided by adjecent float tanrelat = triangopplength/ triangadjlength; // tanjent = opposite / adjecent slopeangle = atan(tanrelat)* 180 / M_PI; // Now we use atan - *180 /M_PI is needed to convert the value into degrees - + // Remember the way the slope is formed fixed_t highest = point.z > origin.z ? point.z : origin.z; fixed_t lowest = point.z < origin.z ? point.z : origin.z; highest = FLOAT_TO_FIXED(highest); lowest = FLOAT_TO_FIXED(lowest); size_t l; - + for (l = 0; l < line->backsector->linecount; l++) { if (P_GetZAt(line->backsector->f_slope, line->backsector->lines[l]->v1->x, line->backsector->lines[l]->v1->y) > highest) highest = P_GetZAt(line->backsector->f_slope, line->backsector->lines[l]->v1->x, line->backsector->lines[l]->v1->y); - + if (P_GetZAt(line->backsector->f_slope, line->backsector->lines[l]->v1->x, line->backsector->lines[l]->v1->y) < lowest) lowest = P_GetZAt(line->backsector->f_slope, line->backsector->lines[l]->v1->x, line->backsector->lines[l]->v1->y); } - + // This line special sets extra clipping data for the frontsector's slope fslope->highz = line->backsector->f_slope->highz = highest; fslope->lowz = line->backsector->f_slope->lowz = lowest; - + fslope->zangle = slopeangle; // Get slope XY angle with secplane_t secplane_t *srcplane = Z_Calloc(sizeof(*srcplane), PU_LEVEL, NULL); @@ -531,11 +532,11 @@ void P_SpawnSlope_Line(int linenum) //srcheight = isceiling ? sec->GetPlaneTexZ(sector_t::floor) : sec->GetPlaneTexZ(sector_t::ceiling); //destheight = isceiling ? refsec->GetPlaneTexZ(sector_t::floor) : refsec->GetPlaneTexZ(sector_t::ceiling); //P_GetZAtf(ret, v2.x, v2.y) - // destheight takes the destination height used in dz + // destheight takes the destination height used in dz srcplane->d = -TMulScale16 (srcplane->a, line->v1->x, srcplane->b, line->v1->y, srcplane->c, line->frontsector->floorheight); - + // Sync the secplane! fslope->secplane = line->backsector->f_slope->secplane = *srcplane; } @@ -543,35 +544,35 @@ void P_SpawnSlope_Line(int linenum) { point.z = FIXED_TO_FLOAT(line->backsector->ceilingheight); dz = (FIXED_TO_FLOAT(line->frontsector->ceilingheight) - point.z) / extent; - - cslope = line->backsector->c_slope = + + cslope = line->backsector->c_slope = P_MakeSlope(&point, &direction, dz, true); - + // Sync the linedata of the line that started this slope // SRB2CBTODO: Anything special for remote(control sector)-based slopes later? line->backsector->c_slope->sourceline = line; - + // Remember the way the slope is formed fixed_t highest = point.z > origin.z ? point.z : origin.z; fixed_t lowest = point.z < origin.z ? point.z : origin.z; highest = FLOAT_TO_FIXED(highest); lowest = FLOAT_TO_FIXED(lowest); - + size_t l; - + for (l = 0; l < line->backsector->linecount; l++) { if (P_GetZAt(line->backsector->c_slope, line->backsector->lines[l]->v1->x, line->backsector->lines[l]->v1->y) > highest) highest = P_GetZAt(line->backsector->c_slope, line->backsector->lines[l]->v1->x, line->backsector->lines[l]->v1->y); - + if (P_GetZAt(line->backsector->c_slope, line->backsector->lines[l]->v1->x, line->backsector->lines[l]->v1->y) < lowest) lowest = P_GetZAt(line->backsector->c_slope, line->backsector->lines[l]->v1->x, line->backsector->lines[l]->v1->y); } - + // This line special sets extra clipping data for the backsector's slope cslope->highz = line->backsector->c_slope->highz = highest; cslope->lowz = line->backsector->c_slope->lowz = lowest; - + // SRB2CBTODO: Get XY angle of a slope and then awesome physics! // ESLOPE: //cslope->zangle = line->backsector->c_slope->zangle = P_GetSlopezangle(line->backsector, highvert, lowvert); //100*(ANG45/45);//R_PointToAngle2(direction.x, direction.y, origin.x, origin.y); @@ -593,16 +594,16 @@ void P_SpawnSlope_Line(int linenum) //srcheight = isceiling ? sec->GetPlaneTexZ(sector_t::floor) : sec->GetPlaneTexZ(sector_t::ceiling); //destheight = isceiling ? refsec->GetPlaneTexZ(sector_t::floor) : refsec->GetPlaneTexZ(sector_t::ceiling); //P_GetZAtf(ret, v2.x, v2.y) - // destheight takes the destination height used in dz + // destheight takes the destination height used in dz srcplane->d = -TMulScale16 (srcplane->a, line->v1->x, srcplane->b, line->v1->y, srcplane->c, line->frontsector->ceilingheight); - + // Sync the secplane! cslope->secplane = line->backsector->c_slope->secplane = *srcplane; } } - + if(!line->tag) return; } @@ -657,12 +658,12 @@ void P_SetSlopesFromVertexHeights(lumpnum_t lumpnum) mapthing_t *mt; boolean vt_found = false; size_t i, j, k, l, q; - + //size_t i; //mapthing_t *mt; char *data; char *datastart; - + // SRB2CBTODO: WHAT IS (5 * sizeof (short))?! It = 10 // anything else seems to make a map not load properly, // but this hard-coded value MUST have some reason for being what it is @@ -683,34 +684,34 @@ void P_SetSlopesFromVertexHeights(lumpnum_t lumpnum) mt->options = READINT16(data); // mt->z hasn't been set yet! //mt->extrainfo = (byte)(mt->type >> 12); // slope things are special, they have a bigger range of types - + //mt->type &= 4095; // SRB2CBTODO: WHAT IS THIS???? Mobj type limits?!!!! x = mt->x*FRACUNIT; y = mt->y*FRACUNIT; sector = R_PointInSubsector(x, y)->sector; // Z for objects -#ifdef ESLOPE +#ifdef ESLOPE if (sector->f_slope) mt->z = (short)(P_GetZAt(sector->f_slope, x, y)>>FRACBITS); else #endif mt->z = (short)(sector->floorheight>>FRACBITS); - + mt->z = mt->z + (mt->options >> ZSHIFT); - + if (mt->type == THING_VertexFloorZ || mt->type == THING_VertexCeilingZ) // THING_VertexFloorZ { for(l = 0; l < numvertexes; l++) { if (vertexes[l].x == mt->x*FRACUNIT && vertexes[l].y == mt->y*FRACUNIT) { - if (mt->type == THING_VertexFloorZ) + if (mt->type == THING_VertexFloorZ) { vertexes[l].z = mt->z*FRACUNIT; //I_Error("Z value: %i", vertexes[l].z/FRACUNIT); - + } - else + else { vertexes[l].z = mt->z*FRACUNIT; // celing floor } @@ -718,41 +719,41 @@ void P_SetSlopesFromVertexHeights(lumpnum_t lumpnum) } } //mt->type = 0; // VPHYSICS: Dynamic slopes - - - - - - + + + + + + if (vt_found) { for (k = 0; k < numsectors; k++) { sector_t *sec = §ors[k]; if (sec->linecount != 3) continue; // only works with triangular sectors - + v3float_t vt1, vt2, vt3; // cross = ret->normalf v3float_t vec1, vec2; - + int vi1, vi2, vi3; - + vi1 = (int)(sec->lines[0]->v1 - vertexes); vi2 = (int)(sec->lines[0]->v2 - vertexes); vi3 = (sec->lines[1]->v1 == sec->lines[0]->v1 || sec->lines[1]->v1 == sec->lines[0]->v2)? (int)(sec->lines[1]->v2 - vertexes) : (int)(sec->lines[1]->v1 - vertexes); - + //if (vertexes[vi1].z) // I_Error("OSNAP %i", vertexes[vi1].z/FRACUNIT); //if (vertexes[vi2].z) // I_Error("OSNAP %i", vertexes[vi2].z/FRACUNIT); //if (vertexes[vi3].z) // I_Error("OSNAP %i", vertexes[vi3].z/FRACUNIT); - + //I_Error("%i, %i", mt->z*FRACUNIT, vertexes[vi1].z); - + //I_Error("%i, %i, %i", mt->x, mt->y, mt->z); //P_SpawnMobj(mt->x*FRACUNIT, mt->y*FRACUNIT, mt->z*FRACUNIT, MT_RING); - + // TODO: Make sure not to spawn in the same place 2x! (we need an object in every vertex of the // triangle sector to setup the real vertex slopes // Check for the vertexes of all sectors @@ -780,31 +781,31 @@ void P_SetSlopesFromVertexHeights(lumpnum_t lumpnum) continue; } } - + vt1.x = FIXED_TO_FLOAT(vertexes[vi1].x); vt1.y = FIXED_TO_FLOAT(vertexes[vi1].y); vt2.x = FIXED_TO_FLOAT(vertexes[vi2].x); vt2.y = FIXED_TO_FLOAT(vertexes[vi2].y); vt3.x = FIXED_TO_FLOAT(vertexes[vi3].x); vt3.y = FIXED_TO_FLOAT(vertexes[vi3].y); - + for(j = 0; j < 2; j++) { - + fixed_t z3; //I_Error("Lo hicimos"); - + vt1.z = mt->z;//FIXED_TO_FLOAT(j==0 ? sec->floorheight : sec->ceilingheight); vt2.z = mt->z;//FIXED_TO_FLOAT(j==0? sec->floorheight : sec->ceilingheight); z3 = mt->z;//j==0? sec->floorheight : sec->ceilingheight; // Destination height vt3.z = FIXED_TO_FLOAT(z3); - + if (P_PointOnLineSide(vertexes[vi3].x, vertexes[vi3].y, sec->lines[0]) == 0) { vec1.x = vt2.x - vt3.x; vec1.y = vt2.y - vt3.y; vec1.z = vt2.z - vt3.z; - + vec2.x = vt1.x - vt3.x; vec2.y = vt1.y - vt3.y; vec2.z = vt1.z - vt3.z; @@ -814,24 +815,24 @@ void P_SetSlopesFromVertexHeights(lumpnum_t lumpnum) vec1.x = vt1.x - vt3.x; vec1.y = vt1.y - vt3.y; vec1.z = vt1.z - vt3.z; - + vec2.x = vt2.x - vt3.x; vec2.y = vt2.y - vt3.y; vec2.z = vt2.z - vt3.z; } - - + + pslope_t *ret = Z_Malloc(sizeof(pslope_t), PU_LEVEL, NULL); memset(ret, 0, sizeof(*ret)); - + { M_CrossProduct3f(&ret->normalf, &vec1, &vec2); - + // Cross product length float len = (float)sqrt(ret->normalf.x * ret->normalf.x + - ret->normalf.y * ret->normalf.y + + ret->normalf.y * ret->normalf.y + ret->normalf.z * ret->normalf.z); - + if (len == 0) { // Only happens when all vertices in this sector are on the same line. @@ -843,7 +844,7 @@ void P_SetSlopesFromVertexHeights(lumpnum_t lumpnum) ret->normalf.x /= len; ret->normalf.y /= len; ret->normalf.z /= len; - + // ZDoom cross = ret->normalf // Fix backward normals if ((ret->normalf.z < 0 && j == 0) || (ret->normalf.z > 0 && j == 1)) @@ -852,11 +853,11 @@ void P_SetSlopesFromVertexHeights(lumpnum_t lumpnum) ret->normalf.x = -ret->normalf.x; ret->normalf.y = -ret->normalf.x; ret->normalf.z = -ret->normalf.x; - } + } } - + secplane_t *srcplane = Z_Calloc(sizeof(*srcplane), PU_LEVEL, NULL); - + srcplane->a = FLOAT_TO_FIXED (ret->normalf.x); srcplane->b = FLOAT_TO_FIXED (ret->normalf.y); srcplane->c = FLOAT_TO_FIXED (ret->normalf.z); @@ -864,7 +865,7 @@ void P_SetSlopesFromVertexHeights(lumpnum_t lumpnum) srcplane->d = -TMulScale16 (srcplane->a, vertexes[vi3].x, srcplane->b, vertexes[vi3].y, srcplane->c, z3); - + if (j == 0) { sec->f_slope = ret; @@ -876,20 +877,20 @@ void P_SetSlopesFromVertexHeights(lumpnum_t lumpnum) sec->c_slope->secplane = *srcplane; } } - } + } } - - - - - - - - + + + + + + + + } } Z_Free(datastart); - + #if 0 // UDMF support for(i = 0; i < numvertexdatas; i++) { @@ -898,23 +899,23 @@ void P_SetSlopesFromVertexHeights(lumpnum_t lumpnum) vt_heights[1][i] = vertexdatas[i].zCeiling; vt_found = true; } - + if (vertexdatas[i].flags & VERTEXFLAG_ZFloorEnabled) { vt_heights[0][i] = vertexdatas[i].zFloor; vt_found = true; } } - + // If vertexdata_t is ever extended for non-slope usage, this will obviously have to be deferred or removed. delete[] vertexdatas; vertexdatas = NULL; numvertexdatas = 0; #endif - - - + + + } #include "p_maputl.h" @@ -923,13 +924,13 @@ void P_SetSlopesFromVertexHeights(lumpnum_t lumpnum) static void P_SlopeLineToPointo (int lineid, fixed_t x, fixed_t y, fixed_t z, boolean slopeCeil) { int linenum = -1; - + while ((linenum = P_FindLineFromID (lineid, linenum)) != -1) { const line_t *line = &lines[linenum]; sector_t *sec; secplane_t *plane; - + if (P_PointOnLineSide (x, y, line) == 0) { sec = line->frontsector; @@ -950,9 +951,9 @@ static void P_SlopeLineToPointo (int lineid, fixed_t x, fixed_t y, fixed_t z, bo { plane = &sec->floorplane; } - + FVector3 p, v1, v2, cross; - + p[0] = FIXED2FLOAT (line->v1->x); p[1] = FIXED2FLOAT (line->v1->y); p[2] = FIXED2FLOAT (plane->ZatPoint (line->v1->x, line->v1->y)); @@ -962,7 +963,7 @@ static void P_SlopeLineToPointo (int lineid, fixed_t x, fixed_t y, fixed_t z, bo v2[0] = FIXED2FLOAT (x - line->v1->x); v2[1] = FIXED2FLOAT (y - line->v1->y); v2[2] = FIXED2FLOAT (z) - p[2]; - + cross = v1 ^ v2; double len = cross.Length(); if (len == 0) @@ -976,7 +977,7 @@ static void P_SlopeLineToPointo (int lineid, fixed_t x, fixed_t y, fixed_t z, bo { cross = -cross; } - + plane->a = FLOAT2FIXED (cross[0]); plane->b = FLOAT2FIXED (cross[1]); plane->c = FLOAT2FIXED (cross[2]); @@ -989,7 +990,7 @@ static void P_SlopeLineToPointo (int lineid, fixed_t x, fixed_t y, fixed_t z, bo } #else #if 0 -// P_SlopeLineToPoint, start from a specific linedef number(not tag) and slope to a mapthing with the angle of the linedef +// P_SlopeLineToPoint, start from a specific linedef number(not tag) and slope to a mapthing with the angle of the linedef static void P_SlopeLineToPoint(int linenum) { line_t *line = lines + linenum; @@ -998,73 +999,73 @@ static void P_SlopeLineToPoint(int linenum) v3float_t origin, point; v2float_t direction; float dz, extent; - + boolean frontfloor = (special == 386 || special == 388 || special == 393); boolean backfloor = (special == 389 || special == 391 || special == 392); boolean frontceil = (special == 387 || special == 388 || special == 392); boolean backceil = (special == 390 || special == 391 || special == 393); - + // SoM: We don't need the line to retain its special type line->special = 0; //SRB2CBTODO: ESLOPE: Maybe we do need it for another to check for a plane slope? - + if(!frontfloor && !backfloor && !frontceil && !backceil) { CONS_Printf("P_SpawnSlope_Line called with non-slope line special.\n"); return; } - + if(!line->frontsector || !line->backsector) { CONS_Printf("P_SpawnSlope_Line used on a line without two sides.\n"); return; } - + origin.x = (FIXED_TO_FLOAT(line->v2->x) + FIXED_TO_FLOAT(line->v1->x)) * 0.5f; origin.y = (FIXED_TO_FLOAT(line->v2->y) + FIXED_TO_FLOAT(line->v1->y)) * 0.5f; - + if(frontfloor || frontceil) { // Do the front sector direction.x = line->nx; direction.y = line->ny; - + extent = P_GetExtent(line->frontsector, line, &origin, &direction); - + if(extent < 0.0f) { CONS_Printf("P_SpawnSlope_Line failed to get frontsector extent on line number %i\n", linenum); return; } - + // reposition the origin according to the extent point.x = origin.x + direction.x * extent; point.y = origin.y + direction.y * extent; direction.x = -direction.x; direction.y = -direction.y; - + // CONS_Printf("Test: X: %f, Y: %f\n", origin.x, origin.y); - + if(frontfloor) { point.z = FIXED_TO_FLOAT(line->frontsector->floorheight); // Startz dz = (FIXED_TO_FLOAT(line->backsector->floorheight) - point.z) / extent; // Destinationz - - fslope = line->frontsector->f_slope = + + fslope = line->frontsector->f_slope = P_MakeSlope(&point, &direction, dz, false); - + // Sync the linedata of the line that started this slope // SRB2CBTODO: Anything special for remote(control sector)-based slopes later? line->frontsector->f_slope->sourceline = line; - + // Remember the way the slope is formed - fixed_t highest = line->frontsector->floorheight > line->backsector->floorheight ? + fixed_t highest = line->frontsector->floorheight > line->backsector->floorheight ? line->frontsector->floorheight : line->backsector->floorheight; - fixed_t lowest = line->frontsector->floorheight < line->backsector->floorheight ? + fixed_t lowest = line->frontsector->floorheight < line->backsector->floorheight ? line->frontsector->floorheight : line->backsector->floorheight; // This line special sets extra clipping data for the frontsector's slope fslope->highz = line->frontsector->f_slope->highz = highest; fslope->lowz = line->frontsector->f_slope->lowz = lowest; - + // SRB2CBTODO: Get XY angle of a slope and then awesome physics! // ESLOPE: //fslope->zangle = line->frontsector->f_slope->zangle = P_GetSlopezangle(line->frontsector, highvert, lowvert); //100*(ANG45/45);//R_PointToAngle2(direction.x, direction.y, origin.x, origin.y); @@ -1086,14 +1087,14 @@ static void P_SlopeLineToPoint(int linenum) //srcheight = isceiling ? sec->GetPlaneTexZ(sector_t::floor) : sec->GetPlaneTexZ(sector_t::ceiling); //destheight = isceiling ? refsec->GetPlaneTexZ(sector_t::floor) : refsec->GetPlaneTexZ(sector_t::ceiling); //P_GetZAtf(ret, v2.x, v2.y) - // destheight takes the destination height used in dz + // destheight takes the destination height used in dz srcplane->d = -TMulScale16 (srcplane->a, line->v1->x, srcplane->b, line->v1->y, srcplane->c, line->backsector->floorheight); - + // Sync the secplane! fslope->secplane = line->frontsector->f_slope->secplane = *srcplane; - + } } } @@ -1111,7 +1112,7 @@ static void P_SlopeLineToPoint(int linenum) void P_SpawnSlopeMakers (FMapThing *firstmt, FMapThing *lastmt) { FMapThing *mt; - + for (mt = firstmt; mt < lastmt; ++mt) { if ((mt->type >= THING_SlopeFloorPointLine && @@ -1121,7 +1122,7 @@ void P_SpawnSlopeMakers (FMapThing *firstmt, FMapThing *lastmt) fixed_t x, y, z; secplane_t *refplane; sector_t *sec; - + x = mt->x; y = mt->y; sec = P_PointInSector (x, y); @@ -1136,7 +1137,7 @@ void P_SpawnSlopeMakers (FMapThing *firstmt, FMapThing *lastmt) z = refplane->ZatPoint (x, y) + (mt->z); if (mt->type==THING_VavoomFloor || mt->type==THING_VavoomCeiling) { - P_VavoomSlope(sec, mt->thingid, x, y, mt->z, mt->type & 1); + P_VavoomSlope(sec, mt->thingid, x, y, mt->z, mt->type & 1); } else if (mt->type <= THING_SlopeCeilingPointLine) { @@ -1149,7 +1150,7 @@ void P_SpawnSlopeMakers (FMapThing *firstmt, FMapThing *lastmt) mt->type = 0; } } - + for (mt = firstmt; mt < lastmt; ++mt) { if (mt->type == THING_CopyFloorPlane || @@ -1159,7 +1160,7 @@ void P_SpawnSlopeMakers (FMapThing *firstmt, FMapThing *lastmt) mt->type = 0; } } - + P_SetSlopesFromVertexHeights(firstmt, lastmt); } #endif @@ -1194,7 +1195,7 @@ float P_GetZAtf(pslope_t *slope, float x, float y) { //if (!slope) // SRB2CBTODO: keep this when done with debugging // I_Error("P_GetZAtf: slope parameter is NULL"); - + float dist = (x - slope->of.x) * slope->df.x + (y - slope->of.y) * slope->df.y; return slope->of.z + (dist * slope->zdeltaf); } @@ -1202,10 +1203,10 @@ float P_GetZAtf(pslope_t *slope, float x, float y) // // P_DistFromPlanef // -float P_DistFromPlanef(const v3float_t *point, const v3float_t *pori, +float P_DistFromPlanef(const v3float_t *point, const v3float_t *pori, const v3float_t *pnormal) { - return (point->x - pori->x) * pnormal->x + + return (point->x - pori->x) * pnormal->x + (point->y - pori->y) * pnormal->y + (point->z - pori->z) * pnormal->z; } From f130a529b1e2c21b51dace958ca55b22e374a670 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Tue, 21 Apr 2015 10:01:51 -0500 Subject: [PATCH 09/91] make stupid slopes render on stupid unix stupids --- src/r_draw8.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/r_draw8.c b/src/r_draw8.c index 6a240c349..86b06089e 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -535,8 +535,7 @@ void R_DrawTiltedSpan_8(void) // x1, x2 = ds_x1, ds_x2 int width = ds_x2 - ds_x1; double iz, uz, vz; - BYTE *fb; - DWORD u, v; + UINT32 u, v; int i; UINT8 *source; From bac34d783e7238282bc9fcac06fc6796623efbc8 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Sat, 25 Apr 2015 20:39:18 -0500 Subject: [PATCH 10/91] Fix crash with ceiling slopes and line collisions --- src/p_maputl.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/p_maputl.c b/src/p_maputl.c index 2f65ea8de..f0a08883c 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -357,7 +357,7 @@ void P_CameraLineOpening(line_t *linedef) if (sectors[front->camsec].c_slope) frontceiling = P_GetZAt(sectors[front->camsec].c_slope, camera.x, camera.y); #endif - + } else if (front->heightsec >= 0) { @@ -463,7 +463,7 @@ void P_CameraLineOpening(line_t *linedef) /*#ifdef ESLOPE if (rover->t_slope) topheight = P_GetZAt(rover->t_slope, camera.x, camera.y); - + if (rover->b_slope) bottomheight = P_GetZAt(rover->b_slope, camera.x, camera.y); #endif // ESLOPE*/ @@ -494,7 +494,7 @@ void P_CameraLineOpening(line_t *linedef) /*#ifdef ESLOPE if (rover->t_slope) topheight = P_GetZAt(rover->t_slope, camera.x, camera.y); - + if (rover->b_slope) bottomheight = P_GetZAt(rover->b_slope, camera.x, camera.y); #endif // ESLOPE*/ @@ -642,7 +642,7 @@ void P_LineOpening(line_t *linedef) if (front->c_slope) highceiling = P_GetZAt(front->c_slope, tmthing->x, tmthing->y); } - if (front->c_slope && front->floorheight < back->floorheight) + if (front->f_slope && front->floorheight < back->floorheight) { openbottom = P_GetZAt(front->f_slope, tmthing->x, tmthing->y); if (back->f_slope) lowfloor = P_GetZAt(back->f_slope, tmthing->x, tmthing->y); @@ -683,11 +683,11 @@ void P_LineOpening(line_t *linedef) fixed_t topheight = *rover->topheight; fixed_t bottomheight = *rover->bottomheight; - + /*#ifdef ESLOPE if (rover->t_slope) topheight = P_GetZAt(rover->t_slope, camera.x, camera.y); - + if (rover->b_slope) bottomheight = P_GetZAt(rover->b_slope, camera.x, camera.y); #endif*/ @@ -730,7 +730,7 @@ void P_LineOpening(line_t *linedef) /*#ifdef ESLOPE if (rover->t_slope) topheight = P_GetZAt(rover->t_slope, tmthing->x, tmthing->y); - + if (rover->b_slope) bottomheight = P_GetZAt(rover->b_slope, tmthing->x, tmthing->y); #endif*/ From 5070a964b962ac91361e9f7448a09f8900ae4e81 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Sat, 25 Apr 2015 22:22:50 -0500 Subject: [PATCH 11/91] Starting to clean up a bit of Kal's mess I still don't know why Git reacts so strangely to the new files' line breaks... --- src/m_fixed.h | 22 ---- src/m_vector.c | 262 ++++++++++++++++++++++----------------------- src/p_slopes.c | 285 +------------------------------------------------ 3 files changed, 135 insertions(+), 434 deletions(-) diff --git a/src/m_fixed.h b/src/m_fixed.h index 8bf160204..92b992632 100644 --- a/src/m_fixed.h +++ b/src/m_fixed.h @@ -357,28 +357,6 @@ FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedRound(fixed_t x) return INT32_MAX; } -/*! - \brief convert a fixed_t number into double floating number - */ -#define FIXED_TO_DOUBLE(f) ((double)((f) / FRACUNIT)) - -/*! - \brief convert a double floating number into fixed_t number - */ -#define DOUBLE_TO_FIXED(f) ((fixed_t)((f) * FRACUNIT)) - -/*! - \brief convert a integer into fixed_t number - */ -#define INT_TO_FIXED(x) ((int)((x) * FRACUNIT)) - -/*! - \brief convert a fixed_t number into integer - */ -#define FIXED_TO_INT(x) (((int)(x)) / (FRACUNIT)) - -static inline int DivScale32 (fixed_t a, fixed_t b) { return (fixed_t)(((INT64)a << 32) / b); } - #ifdef NEED_FIXED_VECTOR diff --git a/src/m_vector.c b/src/m_vector.c index af5189853..53b869adc 100644 --- a/src/m_vector.c +++ b/src/m_vector.c @@ -1,4 +1,4 @@ -// Emacs style mode select -*- C++ -*- +// Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // Copyright(C) 2004 Stephen McGranahan @@ -7,12 +7,12 @@ // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. -// +// // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. -// +// // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA @@ -87,32 +87,32 @@ v3float_t *M_MakeVec3f(const v3float_t *point1, const v3float_t *point2, v3float return a_o; } -// +// // M_TranslateVec3 // // Translates the given vector (in the game's coordinate system) to the camera // space (in right-handed coordinate system) This function is used for slopes. -// +// void M_TranslateVec3(v3fixed_t *vec) { fixed_t tx, ty, tz; - + tx = vec->x - viewx; ty = viewz - vec->y; tz = vec->z - viewy; - + // Just like wall projection. vec->x = (tx * viewcos) - (tz * viewsin); vec->z = (tz * viewcos) + (tx * viewsin); vec->y = ty; } -// +// // M_TranslateVec3f // // Translates the given vector (in the game's coordinate system) to the camera // space (in right-handed coordinate system) This function is used for slopes. -// +// void M_TranslateVec3f(v3float_t *vec) { float tx, ty, tz; @@ -128,20 +128,20 @@ void M_TranslateVec3f(v3float_t *vec) } #ifdef SESLOPE -// +// // M_TranslateVec3d // // Translates the given vector (in the game's coordinate system) to the camera // space (in right-handed coordinate system) This function is used for slopes. -// +// void M_TranslateVec3d(v3double_t *vec) { double tx, ty, tz; - + tx = vec->x - viewx; // SRB2CBTODO: This may need float viewxyz ty = viewz - vec->y; tz = vec->z - viewy; - + // Just like wall projection. vec->x = (tx * viewcos) - (tz * viewsin); vec->z = (tz * viewcos) + (tx * viewsin); @@ -185,7 +185,7 @@ void M_SubVec3(v3fixed_t *dest, const v3fixed_t *v1, const v3fixed_t *v2) // SRB dest->z = v1->z - v2->z; } -// +// // M_SubVec3f // // Subtracts v2 from v1 stores in dest @@ -197,7 +197,7 @@ void M_SubVec3f(v3float_t *dest, const v3float_t *v1, const v3float_t *v2) dest->z = v1->z - v2->z; } -// +// // M_DotVec3 // // Returns the dot product of v1 and v2 @@ -207,7 +207,7 @@ fixed_t M_DotVec3(const v3fixed_t *v1, const v3fixed_t *v2) return FixedMul(v1->x, v2->x) + FixedMul(v1->y, v2->y) + FixedMul(v1->z, v2->z); } -// +// // M_DotVec3f // // Returns the dot product of v1 and v2 @@ -216,13 +216,11 @@ float M_DotVec3f(const v3float_t *v1, const v3float_t *v2) { if (!v1 || !v2) I_Error("M_DotVec3f: No vertexes!"); - if (!(v1 || v2 || v1->x || v1->y || v1->z || v2->x || v2->y || v2->z)) - I_Error("M_DotVec3f: No vertexes!"); - return (v1->x * v2->x) + (v1->y * v2->y) + (v1->z * v2->z); + return (v1->x * v2->x) + (v1->y * v2->y) + (v1->z * v2->z); } #ifdef SESLOPE -// +// // M_DotVec3d // // Returns the dot product of v1 and v2 @@ -236,7 +234,7 @@ double M_DotVec3d(const v3double_t *v1, const v3double_t *v2) // // M_CrossProduct3 // -// Gets the cross product of v1 and v2 and stores in dest +// Gets the cross product of v1 and v2 and stores in dest // void M_CrossProduct3(v3fixed_t *dest, const v3fixed_t *v1, const v3fixed_t *v2) { @@ -250,7 +248,7 @@ void M_CrossProduct3(v3fixed_t *dest, const v3fixed_t *v1, const v3fixed_t *v2) // // M_CrossProduct3f // -// Gets the cross product of v1 and v2 and stores in dest +// Gets the cross product of v1 and v2 and stores in dest // void M_CrossProduct3f(v3float_t *dest, const v3float_t *v1, const v3float_t *v2) { @@ -316,7 +314,7 @@ v3float_t *FV_Midpointf(const v3float_t *a_1, const v3float_t *a_2, v3float_t *a // This checks to see if a point is inside the ranges of a polygon // angle_t FV_AngleBetweenVectors(const v3fixed_t *Vector1, const v3fixed_t *Vector2) -{ +{ // Remember, above we said that the Dot Product of returns the cosine of the angle // between 2 vectors? Well, that is assuming they are unit vectors (normalize vectors). // So, if we don't have a unit vector, then instead of just saying arcCos(DotProduct(A, B)) @@ -324,19 +322,19 @@ angle_t FV_AngleBetweenVectors(const v3fixed_t *Vector1, const v3fixed_t *Vector // Here is the equation: arc cosine of (V . W / || V || * || W || ) // the || V || means the magnitude of V. This then cancels out the magnitudes dot product magnitudes. // But basically, if you have normalize vectors already, you can forget about the magnitude part. - + // Get the dot product of the vectors fixed_t dotProduct = M_DotVec3(Vector1, Vector2); - + // Get the product of both of the vectors magnitudes fixed_t vectorsMagnitude = FixedMul(FV_Magnitude(Vector1), FV_Magnitude(Vector2)); - + // Return the arc cosine of the (dotProduct / vectorsMagnitude) which is the angle in RADIANS. return FixedAcos(FixedDiv(dotProduct, vectorsMagnitude)); } float FV_AngleBetweenVectorsf(const v3float_t *Vector1, const v3float_t *Vector2) -{ +{ // Remember, above we said that the Dot Product of returns the cosine of the angle // between 2 vectors? Well, that is assuming they are unit vectors (normalize vectors). // So, if we don't have a unit vector, then instead of just saying arcCos(DotProduct(A, B)) @@ -344,13 +342,13 @@ float FV_AngleBetweenVectorsf(const v3float_t *Vector1, const v3float_t *Vector2 // Here is the equation: arc cosine of (V . W / || V || * || W || ) // the || V || means the magnitude of V. This then cancels out the magnitudes dot product magnitudes. // But basically, if you have normalize vectors already, you can forget about the magnitude part. - + // Get the dot product of the vectors float dotProduct = M_DotVec3f(Vector1, Vector2); - + // Get the product of both of the vectors magnitudes float vectorsMagnitude = FV_Magnitudef(Vector1)*FV_Magnitudef(Vector2); - + // Return the arc cosine of the (dotProduct / vectorsMagnitude) which is the angle in RADIANS. return acos(dotProduct/vectorsMagnitude); } @@ -370,7 +368,7 @@ float M_VectorPitch(v3float_t v) #include "z_zone.h" -// Returns pitch roll and yaw values, allows objects to align to a slope +// Returns pitch roll and yaw values, allows objects to align to a slope angles3d_t *M_VectorAlignTo(float Pitch, float Yaw, float Roll, v3float_t v, byte AngleAxis, float Rate) { CONS_Printf("P %f\n", Pitch); @@ -380,7 +378,7 @@ angles3d_t *M_VectorAlignTo(float Pitch, float Yaw, float Roll, v3float_t v, byt { float DestYaw = (atan2(v.z,v.x)* 180 / M_PI); float DestRoll = (atan2(v.y,v.x)* 180 / M_PI); - + Yaw = Yaw+(DestYaw-Yaw)*Rate; Roll = Roll+(DestRoll-Roll)*Rate; } @@ -388,7 +386,7 @@ angles3d_t *M_VectorAlignTo(float Pitch, float Yaw, float Roll, v3float_t v, byt { float DestPitch = (atan2(v.z,v.y)* 180 / M_PI); float DestRoll = (-atan2(v.x,v.y)* 180 / M_PI); - + Pitch = Pitch+(DestPitch-Pitch)*Rate; Roll = Roll+(DestRoll-Roll)*Rate; } @@ -396,19 +394,19 @@ angles3d_t *M_VectorAlignTo(float Pitch, float Yaw, float Roll, v3float_t v, byt { float DestPitch = (-atan2(v.y,v.z)* 180 / M_PI); float DestYaw = (-atan2(v.x,v.z)* 180 / M_PI); - + Pitch = Pitch+(DestPitch-Pitch)*Rate; Yaw = Yaw+(DestYaw-Yaw)*Rate; } - + angles3d_t *returnangles = Z_Malloc(sizeof(angles3d_t), PU_LEVEL, NULL); memset(returnangles, 0, sizeof(*returnangles)); returnangles->yaw = Yaw; returnangles->pitch = Pitch; returnangles->roll = Roll; - + return returnangles; - + } @@ -427,28 +425,28 @@ v3fixed_t *FV_SubO(const v3fixed_t *a_i, const v3fixed_t *a_c, v3fixed_t *a_o) boolean FV_Equal(const v3fixed_t *a_1, const v3fixed_t *a_2) { fixed_t Epsilon = FRACUNIT/FRACUNIT; - + if ((abs(a_2->x - a_1->x) > Epsilon) || (abs(a_2->y - a_1->y) > Epsilon) || (abs(a_2->z - a_1->z) > Epsilon)) { return true; } - + return false; } boolean FV_Equalf(const v3float_t *a_1, const v3float_t *a_2) { float Epsilon = 1.0f/1.0f; - + if ((abs(a_2->x - a_1->x) > Epsilon) || (abs(a_2->y - a_1->y) > Epsilon) || (abs(a_2->z - a_1->z) > Epsilon)) { return true; } - + return false; } @@ -461,12 +459,12 @@ void FV_Normal (const v3fixed_t *a_triangle, v3fixed_t *a_normal) { v3fixed_t a_1; v3fixed_t a_2; - + FV_Point2Vec(&a_triangle[2], &a_triangle[0], &a_1); FV_Point2Vec(&a_triangle[1], &a_triangle[0], &a_2); - + FV_Cross(&a_1, &a_2, a_normal); - + FV_NormalizeO(a_normal, a_normal); } @@ -474,30 +472,30 @@ void FV_Normal (const v3fixed_t *a_triangle, v3fixed_t *a_normal) // PlaneDistance // // Calculates distance between a plane and the origin. -// +// fixed_t FV_PlaneDistance(const v3fixed_t *a_normal, const v3fixed_t *a_point) -{ +{ return -(FixedMul(a_normal->x, a_point->x) + FixedMul(a_normal->y, a_point->y) + FixedMul(a_normal->z, a_point->z)); } boolean FV_IntersectedPlane(const v3fixed_t *a_triangle, const v3fixed_t *a_line, v3fixed_t *a_normal, fixed_t *originDistance) { fixed_t distance1 = 0, distance2 = 0; - + FV_Normal(a_triangle, a_normal); - + *originDistance = FV_PlaneDistance(a_normal, &a_triangle[0]); - + distance1 = (FixedMul(a_normal->x, a_line[0].x) + FixedMul(a_normal->y, a_line[0].y) + FixedMul(a_normal->z, a_line[0].z)) + *originDistance; - + distance2 = (FixedMul(a_normal->x, a_line[1].x) + FixedMul(a_normal->y, a_line[1].y) + FixedMul(a_normal->z, a_line[1].z)) + *originDistance; - + // Positive or zero number means no intersection if (FixedMul(distance1, distance2) >= 0) return false; - + return true; } @@ -522,7 +520,7 @@ fixed_t FV_PlaneIntersection(const v3fixed_t *pOrigin, const v3fixed_t *pNormal, // IntersectRaySphere // Input : rO - origin of ray in world space // rV - vector describing direction of ray in world space -// sO - Origin of sphere +// sO - Origin of sphere // sR - radius of sphere // Notes : Normalized directional vectors expected // Return: distance to sphere in world units, -1 if no intersection. @@ -532,15 +530,15 @@ fixed_t FV_IntersectRaySphere(const v3fixed_t *rO, const v3fixed_t *rV, const v3 v3fixed_t Q; fixed_t c, v, d; FV_SubO(sO, rO, &Q); - + c = FV_Magnitude(&Q); v = FV_Dot(&Q, rV); d = FixedMul(sR, sR) - (FixedMul(c,c) - FixedMul(v,v)); - + // If there was no intersection, return -1 if (d < 0*FRACUNIT) return (-1*FRACUNIT); - + // Return the distance to the [first] intersecting point return (v - FixedSqrt(d)); } @@ -554,15 +552,15 @@ v3fixed_t *FV_IntersectionPoint(const v3fixed_t *vNormal, const v3fixed_t *vLine { v3fixed_t vLineDir; // Variables to hold the point and the line's direction fixed_t Numerator = 0, Denominator = 0, dist = 0; - + // Here comes the confusing part. We need to find the 3D point that is actually // on the plane. Here are some steps to do that: - + // 1) First we need to get the vector of our line, Then normalize it so it's a length of 1 FV_Point2Vec(&vLine[1], &vLine[0], &vLineDir); // Get the Vector of the line FV_NormalizeO(&vLineDir, &vLineDir); // Normalize the lines vector - - + + // 2) Use the plane equation (distance = Ax + By + Cz + D) to find the distance from one of our points to the plane. // Here I just chose a arbitrary point as the point to find that distance. You notice we negate that // distance. We negate the distance because we want to eventually go BACKWARDS from our point to the plane. @@ -570,17 +568,17 @@ v3fixed_t *FV_IntersectionPoint(const v3fixed_t *vNormal, const v3fixed_t *vLine Numerator = - (FixedMul(vNormal->x, vLine[0].x) + // Use the plane equation with the normal and the line FixedMul(vNormal->y, vLine[0].y) + FixedMul(vNormal->z, vLine[0].z) + distance); - + // 3) If we take the dot product between our line vector and the normal of the polygon, // this will give us the cosine of the angle between the 2 (since they are both normalized - length 1). // We will then divide our Numerator by this value to find the offset towards the plane from our arbitrary point. Denominator = FV_Dot(vNormal, &vLineDir); // Get the dot product of the line's vector and the normal of the plane - + // Since we are using division, we need to make sure we don't get a divide by zero error // If we do get a 0, that means that there are INFINITE points because the the line is - // on the plane (the normal is perpendicular to the line - (Normal.Vector = 0)). + // on the plane (the normal is perpendicular to the line - (Normal.Vector = 0)). // In this case, we should just return any point on the line. - + if( Denominator == 0*FRACUNIT) // Check so we don't divide by zero { ReturnVec->x = vLine[0].x; @@ -588,7 +586,7 @@ v3fixed_t *FV_IntersectionPoint(const v3fixed_t *vNormal, const v3fixed_t *vLine ReturnVec->z = vLine[0].z; return ReturnVec; // Return an arbitrary point on the line } - + // We divide the (distance from the point to the plane) by (the dot product) // to get the distance (dist) that we need to move from our arbitrary point. We need // to then times this distance (dist) by our line's vector (direction). When you times @@ -601,13 +599,13 @@ v3fixed_t *FV_IntersectionPoint(const v3fixed_t *vNormal, const v3fixed_t *vLine // way down the line's length. The distance from the plane is short, but the distance from // the actual intersection point is pretty long. If we divide the distance by the dot product // of our line vector and the normal of the plane, we get the correct length. Cool huh? - + dist = FixedDiv(Numerator, Denominator); // Divide to get the multiplying (percentage) factor - + // Now, like we said above, we times the dist by the vector, then add our arbitrary point. // This essentially moves the point along the vector to a certain distance. This now gives // us the intersection point. Yay! - + // Return the intersection point ReturnVec->x = vLine[0].x + FixedMul(vLineDir.x, dist); ReturnVec->y = vLine[0].y + FixedMul(vLineDir.y, dist); @@ -639,16 +637,16 @@ unsigned int FV_PointOnLineSide(const v3fixed_t *point, const v3fixed_t *line) boolean FV_PointInsideBox(const v3fixed_t *point, const v3fixed_t *box) { v3fixed_t lastLine[2]; - + FV_Load(&lastLine[0], box[3].x, box[3].y, box[3].z); FV_Load(&lastLine[1], box[0].x, box[0].y, box[0].z); - + if (FV_PointOnLineSide(point, &box[0]) || FV_PointOnLineSide(point, &box[1]) || FV_PointOnLineSide(point, &box[2]) || FV_PointOnLineSide(point, lastLine)) return false; - + return true; } // @@ -660,7 +658,7 @@ void FM_LoadIdentity(fmatrix_t* matrix) { #define M(row,col) matrix->m[col * 4 + row] memset(matrix, 0x00, sizeof(fmatrix_t)); - + M(0, 0) = FRACUNIT; M(1, 1) = FRACUNIT; M(2, 2) = FRACUNIT; @@ -679,29 +677,29 @@ void FM_CreateObjectMatrix(fmatrix_t *matrix, fixed_t x, fixed_t y, fixed_t z, f v3fixed_t upcross; v3fixed_t upvec; v3fixed_t basevec; - + FV_Load(&upvec, upx, upy, upz); FV_Load(&basevec, anglex, angley, anglez); FV_Cross(&upvec, &basevec, &upcross); FV_Normalize(&upcross); - + FM_LoadIdentity(matrix); - + matrix->m[0] = upcross.x; matrix->m[1] = upcross.y; matrix->m[2] = upcross.z; matrix->m[3] = 0*FRACUNIT; - + matrix->m[4] = upx; matrix->m[5] = upy; matrix->m[6] = upz; matrix->m[7] = 0; - + matrix->m[8] = anglex; matrix->m[9] = angley; matrix->m[10] = anglez; matrix->m[11] = 0; - + matrix->m[12] = x - FixedMul(upx,radius); matrix->m[13] = y - FixedMul(upy,radius); matrix->m[14] = z - FixedMul(upz,radius); @@ -720,12 +718,12 @@ void FM_MultMatrixVec(const fmatrix_t *matrix, const v3fixed_t *vec, v3fixed_t * + FixedMul(vec->y,M(0, 1)) + FixedMul(vec->z,M(0, 2)) + M(0, 3); - + out->y = FixedMul(vec->x,M(1, 0)) + FixedMul(vec->y,M(1, 1)) + FixedMul(vec->z,M(1, 2)) + M(1, 3); - + out->z = FixedMul(vec->x,M(2, 0)) + FixedMul(vec->y,M(2, 1)) + FixedMul(vec->z,M(2, 2)) @@ -745,15 +743,15 @@ void FM_MultMatrix(fmatrix_t *dest, const fmatrix_t *multme) #define M(row,col) multme->m[col * 4 + row] #define D(row,col) dest->m[col * 4 + row] #define R(row,col) result.m[col * 4 + row] - + for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) R(i, j) = FixedMul(D(i, 0),M(0, j)) + FixedMul(D(i, 1),M(1, j)) + FixedMul(D(i, 2),M(2, j)) + FixedMul(D(i, 3),M(3, j)); } - + M_Memcpy(dest, &result, sizeof(fmatrix_t)); - + #undef R #undef D #undef M @@ -768,14 +766,14 @@ void FM_Translate(fmatrix_t *dest, fixed_t x, fixed_t y, fixed_t z) { fmatrix_t trans; #define M(row,col) trans.m[col * 4 + row] - + memset(&trans, 0x00, sizeof(fmatrix_t)); - + M(0, 0) = M(1, 1) = M(2, 2) = M(3, 3) = FRACUNIT; M(0, 3) = x; M(1, 3) = y; M(2, 3) = z; - + FM_MultMatrix(dest, &trans); #undef M } @@ -789,14 +787,14 @@ void FM_Scale(fmatrix_t *dest, fixed_t x, fixed_t y, fixed_t z) { fmatrix_t scale; #define M(row,col) scale.m[col * 4 + row] - + memset(&scale, 0x00, sizeof(fmatrix_t)); - + M(3, 3) = FRACUNIT; M(0, 0) = x; M(1, 1) = y; M(2, 2) = z; - + FM_MultMatrix(dest, &scale); #undef M } @@ -824,10 +822,10 @@ v3fixed_t *FV_ClosestPointOnLine(const v3fixed_t *Line, const v3fixed_t *p, v3fi FV_SubO(p, &Line[0], &c); FV_SubO(&Line[1], &Line[0], &V); FV_NormalizeO(&V, &V); - + d = FV_Distance(&Line[0], &Line[1]); t = FV_Dot(&V, &c); - + // Check to see if √´t√≠ is beyond the extents of the line segment if (t < 0) { @@ -837,10 +835,10 @@ v3fixed_t *FV_ClosestPointOnLine(const v3fixed_t *Line, const v3fixed_t *p, v3fi { return FV_Copy(out, &Line[1]); } - + // Return the point between √´Line[0]√≠ and √´Line[1]√≠ FV_Mul(&V, t); - + return FV_AddO(&Line[0], &V, out); } @@ -857,33 +855,33 @@ void FV_ClosestPointOnTriangle (const v3fixed_t *tri, const v3fixed_t *point, v3 fixed_t dist, closestdist; v3fixed_t EdgePoints[3]; v3fixed_t Line[2]; - + FV_Copy(&Line[0], (v3fixed_t*)&tri[0]); FV_Copy(&Line[1], (v3fixed_t*)&tri[1]); FV_ClosestPointOnLine(Line, point, &EdgePoints[0]); - + FV_Copy(&Line[0], (v3fixed_t*)&tri[1]); FV_Copy(&Line[1], (v3fixed_t*)&tri[2]); FV_ClosestPointOnLine(Line, point, &EdgePoints[1]); - + FV_Copy(&Line[0], (v3fixed_t*)&tri[2]); FV_Copy(&Line[1], (v3fixed_t*)&tri[0]); FV_ClosestPointOnLine(Line, point, &EdgePoints[2]); - + // Find the closest one of the three FV_Copy(result, &EdgePoints[0]); closestdist = FV_Distance(point, &EdgePoints[0]); for (i = 1; i < 3; i++) { dist = FV_Distance(point, &EdgePoints[i]); - + if (dist < closestdist) { closestdist = dist; FV_Copy(result, &EdgePoints[i]); } } - + // We now have the closest point! Whee! } @@ -897,7 +895,7 @@ boolean FV_InsidePolygon(const fvector_t *vIntersection, const fvector_t *Poly, int i; UINT64 Angle = 0; // Initialize the angle fvector_t vA, vB; // Create temp vectors - + // Just because we intersected the plane, doesn't mean we were anywhere near the polygon. // This functions checks our intersection point to make sure it is inside of the polygon. // This is another tough function to grasp at first, but let me try and explain. @@ -911,26 +909,26 @@ boolean FV_InsidePolygon(const fvector_t *vIntersection, const fvector_t *Poly, // all of the angles in a triangle we get 360 right? Well, that is kinda what we are doing, // but the inverse of that. Say your triangle is an isosceles triangle, so add up the angles // and you will get 360 degree angles. 90 + 90 + 90 is 360. - + for (i = 0; i < vertexCount; i++) // Go in a circle to each vertex and get the angle between - { + { FV_Point2Vec(&Poly[i], vIntersection, &vA); // Subtract the intersection point from the current vertex // Subtract the point from the next vertex FV_Point2Vec(&Poly[(i + 1) % vertexCount], vIntersection, &vB); - + Angle += FV_AngleBetweenVectors(&vA, &vB); // Find the angle between the 2 vectors and add them all up as we go along } - + // Now that we have the total angles added up, we need to check if they add up to 360 degrees. // Since we are using the dot product, we are working in radians, so we check if the angles // equals 2*PI. We defined PI in 3DMath.h. You will notice that we use a MATCH_FACTOR // in conjunction with our desired degree. This is because of the inaccuracy when working // with floating point numbers. It usually won't always be perfectly 2 * PI, so we need // to use a little twiddling. I use .9999, but you can change this to fit your own desired accuracy. - + if(Angle >= ANGLE_MAX) // If the angle is greater than 2 PI, (360 degrees) return 1; // The point is inside of the polygon - + return 0; // If you get here, it obviously wasn't inside the polygon. } @@ -943,27 +941,27 @@ boolean FV_IntersectedPolygon(const fvector_t *vPoly, const fvector_t *vLine, co { fvector_t vNormal, vIntersection; fixed_t originDistance = 0*FRACUNIT; - - + + // First we check to see if our line intersected the plane. If this isn't true // there is no need to go on, so return false immediately. // We pass in address of vNormal and originDistance so we only calculate it once - + if(!FV_IntersectedPlane(vPoly, vLine, &vNormal, &originDistance)) return false; - - // Now that we have our normal and distance passed back from IntersectedPlane(), + + // Now that we have our normal and distance passed back from IntersectedPlane(), // we can use it to calculate the intersection point. The intersection point // is the point that actually is ON the plane. It is between the line. We need // this point test next, if we are inside the polygon. To get the I-Point, we // give our function the normal of the plane, the points of the line, and the originDistance. - + FV_IntersectionPoint(&vNormal, vLine, originDistance, &vIntersection); - + // Now that we have the intersection point, we need to test if it's inside the polygon. // To do this, we pass in : // (our intersection point, the polygon, and the number of vertices our polygon has) - + if(FV_InsidePolygon(&vIntersection, vPoly, vertexCount)) { if (collisionPoint != NULL) // Optional - load the collision point. @@ -974,7 +972,7 @@ boolean FV_IntersectedPolygon(const fvector_t *vPoly, const fvector_t *vLine, co } return true; // We collided! } - + // If we get here, we must have NOT collided return false; } @@ -1017,7 +1015,7 @@ void FV_Rotate(fvector_t *rotVec, const fvector_t *axisVec, const angle_t angle) fixed_t ex = FixedMul(vz-wy, sa); fixed_t ey = FixedMul(wx-uz, sa); fixed_t ez = FixedMul(uy-vx, sa); - + rotVec->x = ax+dx+ex; rotVec->y = ay+dy+ey; rotVec->z = az+dz+ez; @@ -1033,41 +1031,41 @@ void FM_Rotate(fmatrix_t *dest, angle_t angle, fixed_t x, fixed_t y, fixed_t z) fixed_t xSq, ySq, zSq; fixed_t sx, sy, sz; fixed_t sxy, sxz, syz; - + FV_Normalize(&nrm); - + x = nrm.x; y = nrm.y; z = nrm.z; - + xSq = FixedMul(x, FixedMul(invCosA,x)); ySq = FixedMul(y, FixedMul(invCosA,y)); zSq = FixedMul(z, FixedMul(invCosA,z)); - + sx = FixedMul(sinA, x); sy = FixedMul(sinA, y); sz = FixedMul(sinA, z); - + sxy = FixedMul(x, FixedMul(invCosA,y)); sxz = FixedMul(x, FixedMul(invCosA,z)); syz = FixedMul(y, FixedMul(invCosA,z)); - - + + M(0, 0) = xSq + cosA; M(1, 0) = sxy - sz; M(2, 0) = sxz + sy; M(3, 0) = 0; - + M(0, 1) = sxy + sz; M(1, 1) = ySq + cosA; M(2, 1) = syz - sx; M(3, 1) = 0; - + M(0, 2) = sxz - sy; M(1, 2) = syz + sx; M(2, 2) = zSq + cosA; M(3, 2) = 0; - + M(0, 3) = 0; M(1, 3) = 0; M(2, 3) = 0; @@ -1127,12 +1125,12 @@ void FV_Normal(const v3fixed_t *a_triangle, v3fixed_t *a_normal) { v3fixed_t a_1; v3fixed_t a_2; - + M_MakeVec3(&a_triangle[2], &a_triangle[0], &a_1); M_MakeVec3(&a_triangle[1], &a_triangle[0], &a_2); - + M_CrossProduct3(&a_1, &a_2, a_normal); - + FV_NormalizeO(a_normal, a_normal); } @@ -1145,12 +1143,12 @@ void FV_Normalf(const v3float_t *a_triangle, v3float_t *a_normal) { v3float_t a_1; v3float_t a_2; - + M_MakeVec3f(&a_triangle[2], &a_triangle[0], &a_1); M_MakeVec3f(&a_triangle[1], &a_triangle[0], &a_2); - + M_CrossProduct3f(&a_1, &a_2, a_normal); - + FV_NormalizeOf(a_normal, a_normal); } diff --git a/src/p_slopes.c b/src/p_slopes.c index 2c18d3611..15aa6d7fe 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -359,7 +359,7 @@ void P_SpawnSlope_Line(int linenum) srcplane->a = FLOAT_TO_FIXED (fslope->normalf.x); // cross[0] srcplane->b = FLOAT_TO_FIXED (fslope->normalf.y); // cross[1] srcplane->c = FLOAT_TO_FIXED (fslope->normalf.z); // cross[2] - srcplane->ic = DivScale32 (1, srcplane->c); // (1 << 32/srcplane->c) or FLOAT_TO_FIXED(1.0f/cross[2]); + srcplane->ic = FixedDiv(FRACUNIT, srcplane->c); // (1 << 32/srcplane->c) or FLOAT_TO_FIXED(1.0f/cross[2]); // destheight takes the destination height used in dz srcplane->d = -TMulScale16 (srcplane->a, line->v1->x, // x @@ -414,7 +414,7 @@ void P_SpawnSlope_Line(int linenum) srcplane->b = FLOAT_TO_FIXED (cslope->normalf.y); // cross[1] srcplane->c = FLOAT_TO_FIXED (cslope->normalf.z); // cross[2] //plane->ic = FLOAT_TO_FIXED (1.f/cross[2]); - srcplane->ic = DivScale32 (1, srcplane->c); // (1 << 32/srcplane->c) + srcplane->ic = FixedDiv(FRACUNIT, srcplane->c); // (1 << 32/srcplane->c) #ifdef SLOPETHINGS // For setting thing-based slopes srcplane->d = -TMulScale16 (plane->a, x, plane->b, y, @@ -523,7 +523,7 @@ void P_SpawnSlope_Line(int linenum) srcplane->b = FLOAT_TO_FIXED (fslope->normalf.y); // cross[1] srcplane->c = FLOAT_TO_FIXED (fslope->normalf.z); // cross[2] //plane->ic = FLOAT_TO_FIXED (1.f/cross[2]); - srcplane->ic = DivScale32 (1, srcplane->c); // (1 << 32/srcplane->c) + srcplane->ic = FixedDiv(FRACUNIT, srcplane->c); // (1 << 32/srcplane->c) #ifdef SLOPETHINGS // For setting thing-based slopes srcplane->d = -TMulScale16 (plane->a, x, plane->b, y, @@ -585,7 +585,7 @@ void P_SpawnSlope_Line(int linenum) srcplane->b = FLOAT_TO_FIXED (cslope->normalf.y); // cross[1] srcplane->c = FLOAT_TO_FIXED (cslope->normalf.z); // cross[2] //plane->ic = FLOAT_TO_FIXED (1.f/cross[2]); - srcplane->ic = DivScale32 (1, srcplane->c); // (1 << 32/srcplane->c) + srcplane->ic = FixedDiv(FRACUNIT, srcplane->c); // (1 << 32/srcplane->c) #ifdef SLOPETHINGS // For setting thing-based slopes srcplane->d = -TMulScale16 (plane->a, x, plane->b, y, @@ -638,13 +638,6 @@ void P_CopySectorSlope(line_t *line) #include "byteptr.h" -/* -typedef struct -{ - fixed_t z1; - fixed_t z2; -} mapvert_t;*/ - #include "p_setup.h" #include "p_local.h" @@ -861,7 +854,7 @@ void P_SetSlopesFromVertexHeights(lumpnum_t lumpnum) srcplane->a = FLOAT_TO_FIXED (ret->normalf.x); srcplane->b = FLOAT_TO_FIXED (ret->normalf.y); srcplane->c = FLOAT_TO_FIXED (ret->normalf.z); - //srcplane->ic = DivScale32 (1, srcplane->c); + //srcplane->ic = FixedDiv(FRACUNIT, srcplane->c); srcplane->d = -TMulScale16 (srcplane->a, vertexes[vi3].x, srcplane->b, vertexes[vi3].y, srcplane->c, z3); @@ -891,279 +884,11 @@ void P_SetSlopesFromVertexHeights(lumpnum_t lumpnum) } Z_Free(datastart); -#if 0 // UDMF support - for(i = 0; i < numvertexdatas; i++) - { - if (vertexdatas[i].flags & VERTEXFLAG_ZCeilingEnabled) - { - vt_heights[1][i] = vertexdatas[i].zCeiling; - vt_found = true; - } - - if (vertexdatas[i].flags & VERTEXFLAG_ZFloorEnabled) - { - vt_heights[0][i] = vertexdatas[i].zFloor; - vt_found = true; - } - } - - // If vertexdata_t is ever extended for non-slope usage, this will obviously have to be deferred or removed. - delete[] vertexdatas; - vertexdatas = NULL; - numvertexdatas = 0; -#endif - } -#include "p_maputl.h" - -#if 0 -static void P_SlopeLineToPointo (int lineid, fixed_t x, fixed_t y, fixed_t z, boolean slopeCeil) -{ - int linenum = -1; - - while ((linenum = P_FindLineFromID (lineid, linenum)) != -1) - { - const line_t *line = &lines[linenum]; - sector_t *sec; - secplane_t *plane; - - if (P_PointOnLineSide (x, y, line) == 0) - { - sec = line->frontsector; - } - else - { - sec = line->backsector; - } - if (sec == NULL) - { - continue; - } - if (slopeCeil) - { - plane = &sec->ceilingplane; - } - else - { - plane = &sec->floorplane; - } - - FVector3 p, v1, v2, cross; - - p[0] = FIXED2FLOAT (line->v1->x); - p[1] = FIXED2FLOAT (line->v1->y); - p[2] = FIXED2FLOAT (plane->ZatPoint (line->v1->x, line->v1->y)); - v1[0] = FIXED2FLOAT (line->dx); - v1[1] = FIXED2FLOAT (line->dy); - v1[2] = FIXED2FLOAT (plane->ZatPoint (line->v2->x, line->v2->y)) - p[2]; - v2[0] = FIXED2FLOAT (x - line->v1->x); - v2[1] = FIXED2FLOAT (y - line->v1->y); - v2[2] = FIXED2FLOAT (z) - p[2]; - - cross = v1 ^ v2; - double len = cross.Length(); - if (len == 0) - { - Printf ("Slope thing at (%d,%d) lies directly on its target line.\n", int(x>>16), int(y>>16)); - return; - } - cross /= len; - // Fix backward normals - if ((cross.Z < 0 && !slopeCeil) || (cross.Z > 0 && slopeCeil)) - { - cross = -cross; - } - - plane->a = FLOAT2FIXED (cross[0]); - plane->b = FLOAT2FIXED (cross[1]); - plane->c = FLOAT2FIXED (cross[2]); - //plane->ic = FLOAT2FIXED (1.f/cross[2]); - plane->ic = DivScale32 (1, plane->c); - plane->d = -TMulScale16 (plane->a, x, - plane->b, y, - plane->c, z); - } -} -#else -#if 0 -// P_SlopeLineToPoint, start from a specific linedef number(not tag) and slope to a mapthing with the angle of the linedef -static void P_SlopeLineToPoint(int linenum) -{ - line_t *line = lines + linenum; - int special = line->special; - pslope_t *fslope = NULL, *cslope = NULL; - v3float_t origin, point; - v2float_t direction; - float dz, extent; - - boolean frontfloor = (special == 386 || special == 388 || special == 393); - boolean backfloor = (special == 389 || special == 391 || special == 392); - boolean frontceil = (special == 387 || special == 388 || special == 392); - boolean backceil = (special == 390 || special == 391 || special == 393); - - // SoM: We don't need the line to retain its special type - line->special = 0; //SRB2CBTODO: ESLOPE: Maybe we do need it for another to check for a plane slope? - - if(!frontfloor && !backfloor && !frontceil && !backceil) - { - CONS_Printf("P_SpawnSlope_Line called with non-slope line special.\n"); - return; - } - - if(!line->frontsector || !line->backsector) - { - CONS_Printf("P_SpawnSlope_Line used on a line without two sides.\n"); - return; - } - - origin.x = (FIXED_TO_FLOAT(line->v2->x) + FIXED_TO_FLOAT(line->v1->x)) * 0.5f; - origin.y = (FIXED_TO_FLOAT(line->v2->y) + FIXED_TO_FLOAT(line->v1->y)) * 0.5f; - - if(frontfloor || frontceil) - { - // Do the front sector - direction.x = line->nx; - direction.y = line->ny; - - extent = P_GetExtent(line->frontsector, line, &origin, &direction); - - if(extent < 0.0f) - { - CONS_Printf("P_SpawnSlope_Line failed to get frontsector extent on line number %i\n", linenum); - return; - } - - // reposition the origin according to the extent - point.x = origin.x + direction.x * extent; - point.y = origin.y + direction.y * extent; - direction.x = -direction.x; - direction.y = -direction.y; - - // CONS_Printf("Test: X: %f, Y: %f\n", origin.x, origin.y); - - if(frontfloor) - { - point.z = FIXED_TO_FLOAT(line->frontsector->floorheight); // Startz - dz = (FIXED_TO_FLOAT(line->backsector->floorheight) - point.z) / extent; // Destinationz - - fslope = line->frontsector->f_slope = - P_MakeSlope(&point, &direction, dz, false); - - // Sync the linedata of the line that started this slope - // SRB2CBTODO: Anything special for remote(control sector)-based slopes later? - line->frontsector->f_slope->sourceline = line; - - // Remember the way the slope is formed - fixed_t highest = line->frontsector->floorheight > line->backsector->floorheight ? - line->frontsector->floorheight : line->backsector->floorheight; - fixed_t lowest = line->frontsector->floorheight < line->backsector->floorheight ? - line->frontsector->floorheight : line->backsector->floorheight; - // This line special sets extra clipping data for the frontsector's slope - fslope->highz = line->frontsector->f_slope->highz = highest; - fslope->lowz = line->frontsector->f_slope->lowz = lowest; - - // SRB2CBTODO: Get XY angle of a slope and then awesome physics! // ESLOPE: - //fslope->zangle = line->frontsector->f_slope->zangle = P_GetSlopezangle(line->frontsector, highvert, lowvert); - //100*(ANG45/45);//R_PointToAngle2(direction.x, direction.y, origin.x, origin.y); - // Get slope XY angle with secplane_t - secplane_t *srcplane = Z_Calloc(sizeof(*srcplane), PU_LEVEL, NULL); - // ZDoom secplane port! - // secplane_t! woot! - // ret = f_slope or c_slope - srcplane->a = FLOAT_TO_FIXED (fslope->normalf.x); // cross[0] - srcplane->b = FLOAT_TO_FIXED (fslope->normalf.y); // cross[1] - srcplane->c = FLOAT_TO_FIXED (fslope->normalf.z); // cross[2] - //plane->ic = FLOAT_TO_FIXED (1.f/cross[2]); - srcplane->ic = DivScale32 (1, srcplane->c); // (1 << 32/srcplane->c) -#ifdef SLOPETHINGS // For setting thing-based slopes - srcplane->d = -TMulScale16 (plane->a, x, - plane->b, y, - plane->c, z); -#endif - //srcheight = isceiling ? sec->GetPlaneTexZ(sector_t::floor) : sec->GetPlaneTexZ(sector_t::ceiling); - //destheight = isceiling ? refsec->GetPlaneTexZ(sector_t::floor) : refsec->GetPlaneTexZ(sector_t::ceiling); - //P_GetZAtf(ret, v2.x, v2.y) - // destheight takes the destination height used in dz - srcplane->d = -TMulScale16 (srcplane->a, line->v1->x, - srcplane->b, line->v1->y, - srcplane->c, line->backsector->floorheight); - - // Sync the secplane! - fslope->secplane = line->frontsector->f_slope->secplane = *srcplane; - - } - } -} -#endif -#endif - - - -//=========================================================================== -// -// P_SpawnSlopeMakers -// -//=========================================================================== -#if 0 -void P_SpawnSlopeMakers (FMapThing *firstmt, FMapThing *lastmt) -{ - FMapThing *mt; - - for (mt = firstmt; mt < lastmt; ++mt) - { - if ((mt->type >= THING_SlopeFloorPointLine && - mt->type <= THING_SetCeilingSlope) || - mt->type==THING_VavoomFloor || mt->type==THING_VavoomCeiling) - { - fixed_t x, y, z; - secplane_t *refplane; - sector_t *sec; - - x = mt->x; - y = mt->y; - sec = P_PointInSector (x, y); - if (mt->type & 1) - { - refplane = &sec->ceilingplane; - } - else - { - refplane = &sec->floorplane; - } - z = refplane->ZatPoint (x, y) + (mt->z); - if (mt->type==THING_VavoomFloor || mt->type==THING_VavoomCeiling) - { - P_VavoomSlope(sec, mt->thingid, x, y, mt->z, mt->type & 1); - } - else if (mt->type <= THING_SlopeCeilingPointLine) - { - P_SlopeLineToPoint (mt->args[0], x, y, z, mt->type & 1); - } - else - { - P_SetSlope (refplane, mt->type & 1, mt->angle, mt->args[0], x, y, z); - } - mt->type = 0; - } - } - - for (mt = firstmt; mt < lastmt; ++mt) - { - if (mt->type == THING_CopyFloorPlane || - mt->type == THING_CopyCeilingPlane) - { - P_CopyPlane (mt->args[0], mt->x, mt->y, mt->type & 1); - mt->type = 0; - } - } - - P_SetSlopesFromVertexHeights(firstmt, lastmt); -} -#endif From aeef23e8164fae1fe05cf9a9559e76b9b40be21b Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Sun, 26 Apr 2015 13:06:23 -0500 Subject: [PATCH 12/91] MakeSlope_Line cleanup/fixed-point conversion --- src/p_setup.c | 4 - src/p_slopes.c | 454 ++++++++++++------------------------------------- src/r_defs.h | 21 +-- 3 files changed, 117 insertions(+), 362 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 9ddd52b58..e2ce083f9 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1170,10 +1170,6 @@ static void P_LoadLineDefs(lumpnum_t lumpnum) #ifdef POLYOBJECTS ld->polyobj = NULL; #endif - -#ifdef ESLOPE - P_MakeLineNormal(ld); -#endif } Z_Free(data); diff --git a/src/p_slopes.c b/src/p_slopes.c index 15aa6d7fe..e75552f11 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -45,91 +45,20 @@ // // Alocates and fill the contents of a slope structure. // -static pslope_t *P_MakeSlope(const v3float_t *o, const v2float_t *d, - const float zdelta, boolean isceiling) +static pslope_t *P_MakeSlope(const v3fixed_t *o, const v2fixed_t *d, + const fixed_t zdelta, boolean isceiling) { pslope_t *ret = Z_Malloc(sizeof(pslope_t), PU_LEVEL, NULL); memset(ret, 0, sizeof(*ret)); - ret->o.x = FLOAT_TO_FIXED(ret->of.x = o->x); - ret->o.y = FLOAT_TO_FIXED(ret->of.y = o->y); - ret->o.z = FLOAT_TO_FIXED(ret->of.z = o->z); + ret->of.x = FIXED_TO_FLOAT(ret->o.x = o->x); + ret->of.y = FIXED_TO_FLOAT(ret->o.y = o->y); + ret->of.z = FIXED_TO_FLOAT(ret->o.z = o->z); - ret->d.x = FLOAT_TO_FIXED(ret->df.x = d->x); - ret->d.y = FLOAT_TO_FIXED(ret->df.y = d->y); + ret->df.x = FIXED_TO_FLOAT(ret->d.x = d->x); + ret->df.y = FIXED_TO_FLOAT(ret->d.y = d->y); - ret->zdelta = FLOAT_TO_FIXED(ret->zdeltaf = zdelta); - - // d = direction (v2float_t) - // - // direction.x = line->nx; - // direction.y = line->ny; - // - // o = origin (v3float_t) - // origin.x = (FIXED_TO_FLOAT(line->v2->x) + FIXED_TO_FLOAT(line->v1->x)) * 0.5f; - // origin.y = (FIXED_TO_FLOAT(line->v2->y) + FIXED_TO_FLOAT(line->v1->y)) * 0.5f; - - { - // Now calculate the normal of the plane! - v3float_t v1, v2, v3, d1, d2; - float len; - - v1.x = o->x; - v1.y = o->y; - v1.z = o->z; - - v2.x = v1.x; - v2.y = v1.y + 10.0f; - v2.z = P_GetZAtf(ret, v2.x, v2.y); - - v3.x = v1.x + 10.0f; - v3.y = v1.y; - v3.z = P_GetZAtf(ret, v3.x, v3.y); - - if (isceiling) - { - M_SubVec3f(&d1, &v1, &v3); - M_SubVec3f(&d2, &v2, &v3); - } - else - { - M_SubVec3f(&d1, &v1, &v2); - M_SubVec3f(&d2, &v3, &v2); - } - - M_CrossProduct3f(&ret->normalf, &d1, &d2); - - // Cross product length - len = (float)sqrt(ret->normalf.x * ret->normalf.x + - ret->normalf.y * ret->normalf.y + - ret->normalf.z * ret->normalf.z); - -#ifdef SLOPETHINGS - if (len == 0) - { - // Only happens when all vertices in this sector are on the same line. - // Let's just ignore this case. - CONS_Printf("Slope thing at (%d,%d) lies directly on its target line.\n", int(x>>16), int(y>>16)); - return; - } -#endif - - ret->normalf.x /= len; - ret->normalf.y /= len; - ret->normalf.z /= len; - - // ZDoom - // cross = ret->normalf - - // Fix backward normals - if ((ret->normalf.z < 0 && !isceiling) || (ret->normalf.z > 0 && isceiling)) - { - ret->normalf.x = -ret->normalf.x; - ret->normalf.y = -ret->normalf.x; - ret->normalf.z = -ret->normalf.x; - } - - } + ret->zdeltaf = FIXED_TO_FLOAT(ret->zdelta = zdelta); return ret; } @@ -147,65 +76,42 @@ static pslope_t *P_CopySlope(const pslope_t *src) return ret; } -// -// P_MakeLineNormal -// -// Calculates a 2D normal for the given line and stores it in the line -// -void P_MakeLineNormal(line_t *line) -{ - float linedx, linedy, length; - - // SRB2CBTODO: Give linedefs an fx+fy(float xy coords)? - // May cause slow downs since the float would always have to be converted/updated - linedx = FIXED_TO_FLOAT(line->v2->x) - FIXED_TO_FLOAT(line->v1->x); - linedy = FIXED_TO_FLOAT(line->v2->y) - FIXED_TO_FLOAT(line->v1->y); - - length = (float)sqrt(linedx * linedx + linedy * linedy); - line->nx = linedy / length; - line->ny = -linedx / length; - line->len = length; -} - // // P_GetExtent // // Returns the distance to the first line within the sector that // is intersected by a line parallel to the plane normal with the point (ox, oy) // -static float P_GetExtent(sector_t *sector, line_t *line, v3float_t *o, v2float_t *d) +static fixed_t P_GetExtent(sector_t *sector, line_t *line) { // ZDoom code reference: v3float_t = vertex_t - float fardist = -1.0f; - size_t i; + fixed_t fardist = -FRACUNIT; + size_t i; // Find furthest vertex from the reference line. It, along with the two ends // of the line, will define the plane. // SRB2CBTODO: Use a formula to get the slope to slide objects depending on how steep - for(i = 0; i < sector->linecount; i++) - { - line_t *li = sector->lines[i]; - vertex_t tempv; - float dist; + for(i = 0; i < sector->linecount; i++) + { + line_t *li = sector->lines[i]; + vertex_t tempv; + fixed_t dist; - // Don't compare to the slope line. - if(li == line) - continue; + // Don't compare to the slope line. + if(li == line) + continue; - // ZDoom code in P_AlignPlane - // dist = fabs((double(line->v1->y) - vert->y) * line->dx - (double(line->v1->x) - vert->x) * line->dy); - //dist = (float)fabs((FIXED_TO_FLOAT(li->v1->x) - o->x) * d->x + (FIXED_TO_FLOAT(li->v1->y) - o->y) * d->y); - P_ClosestPointOnLine(li->v1->x, li->v1->y, line, &tempv); - dist = FIXED_TO_FLOAT(R_PointToDist2(tempv.x, tempv.y, li->v1->x, li->v1->y)); - if(dist > fardist) - fardist = dist; + P_ClosestPointOnLine(li->v1->x, li->v1->y, line, &tempv); + dist = R_PointToDist2(tempv.x, tempv.y, li->v1->x, li->v1->y); + if(dist > fardist) + fardist = dist; // Okay, maybe do it for v2 as well? - P_ClosestPointOnLine(li->v2->x, li->v2->y, line, &tempv); - dist = FIXED_TO_FLOAT(R_PointToDist2(tempv.x, tempv.y, li->v2->x, li->v2->y)); - if(dist > fardist) - fardist = dist; - } + P_ClosestPointOnLine(li->v2->x, li->v2->y, line, &tempv); + dist = R_PointToDist2(tempv.x, tempv.y, li->v2->x, li->v2->y); + if(dist > fardist) + fardist = dist; + } return fardist; } @@ -224,11 +130,11 @@ void P_SpawnSlope_Line(int linenum) // because checking to see if a slope had changed will waste more memory than // if the slope was just updated when called line_t *line = lines + linenum; - int special = line->special; + INT16 special = line->special; pslope_t *fslope = NULL, *cslope = NULL; - v3float_t origin, point; - v2float_t direction; - float dz, extent; + v3fixed_t origin, point; + v2fixed_t direction; + fixed_t nx, ny, dz, extent; boolean frontfloor = (special == 386 || special == 388 || special == 393); boolean backfloor = (special == 389 || special == 391 || special == 392); @@ -247,28 +153,34 @@ void P_SpawnSlope_Line(int linenum) return; } + { + fixed_t len = R_PointToDist2(0, 0, line->dx, line->dy); + nx = FixedDiv(line->dy, len); + ny = -FixedDiv(line->dx, len); + } + // SRB2CBTODO: Transform origin relative to the bounds of an individual FOF - origin.x = (FIXED_TO_FLOAT(line->v2->x) + FIXED_TO_FLOAT(line->v1->x)) * 0.5f; - origin.y = (FIXED_TO_FLOAT(line->v2->y) + FIXED_TO_FLOAT(line->v1->y)) * 0.5f; + origin.x = line->v1->x + (line->v2->x - line->v1->x)/2; + origin.y = line->v1->y + (line->v2->y - line->v1->y)/2; // For FOF slopes, make a special function to copy to the xy origin & direction relative to the position of the FOF on the map! if(frontfloor || frontceil) { - origin.z = FIXED_TO_FLOAT(line->backsector->floorheight); - direction.x = line->nx; - direction.y = line->ny; + origin.z = line->backsector->floorheight; + direction.x = nx; + direction.y = ny; - extent = P_GetExtent(line->frontsector, line, &origin, &direction); + extent = P_GetExtent(line->frontsector, line); - if(extent < 0.0f) + if(extent < 0) { CONS_Printf("P_SpawnSlope_Line failed to get frontsector extent on line number %i\n", linenum); return; } // reposition the origin according to the extent - point.x = origin.x + direction.x * extent; - point.y = origin.y + direction.y * extent; + point.x = origin.x + FixedMul(direction.x, extent); + point.y = origin.y + FixedMul(direction.y, extent); direction.x = -direction.x; direction.y = -direction.y; @@ -277,39 +189,11 @@ void P_SpawnSlope_Line(int linenum) if(frontfloor) { - point.z = FIXED_TO_FLOAT(line->frontsector->floorheight); // Startz - dz = (FIXED_TO_FLOAT(line->backsector->floorheight) - point.z) / extent; // Destinationz + point.z = line->frontsector->floorheight; // Startz + dz = FixedDiv(line->backsector->floorheight - point.z, extent); // Destinationz // In P_SpawnSlopeLine the origin is the centerpoint of the sourcelinedef - int slopeangle = 0; // All floors by default have no slope (an angle of 0, completely flat) - - v3float_t A = origin; // = line source - v3float_t B = point; // destination's value - v3float_t C = origin; // Point used to make a right triangle from A & B - - C.z = point.z; - - // To find the "angle" of a slope, we make a right triangle out of the points we have, - // point A - is point 1 of the hypotenuse, - // point B - is point 2 of the hypotenuse - // point C - has the same Z value as point b, and the same XY value as A - // - // We want to find the angle accross from the right angle - // so we use some triginometry to find the angle(fun, right?) - // We want to find the tanjent of this angle, this is: - // Opposite - // ------- = tan(x) - // Adjecent - // But actually tan doesn't do want we really want, we have to use atan to find the actual angle of the triangle's corner - float triangopplength = abs(B.z - A.z); - float triangadjlength = sqrt((B.x-C.x)*(B.x-C.x) + (B.y - C.y)*(B.y - C.y)); - //float trianghyplength = sqrt(triangopplength*triangopplength + triangadjlength*triangadjlength); // This is the hypotenuse - - // So tanjent = opposite divided by adjecent - float tanrelat = triangopplength/ triangadjlength; // tanjent = opposite / adjecent - slopeangle = atan(tanrelat)* 180 / M_PI; // Now we use atan: *180 /M_PI is needed to convert the value into degrees - fslope = line->frontsector->f_slope = P_MakeSlope(&point, &direction, dz, false); @@ -320,7 +204,7 @@ void P_SpawnSlope_Line(int linenum) // Sync the linedata of the line that started this slope // SRB2CBTODO: Anything special for remote(control sector)-based slopes later? - line->frontsector->f_slope->sourceline = line; + fslope->sourceline = line; // To find the real highz/lowz of a slope, you need to check all the vertexes // in the slope's sector with P_GetZAt to get the REAL lowz & highz @@ -331,276 +215,156 @@ void P_SpawnSlope_Line(int linenum) // Default points for high and low fixed_t highest = point.z > origin.z ? point.z : origin.z; fixed_t lowest = point.z < origin.z ? point.z : origin.z; - highest = FLOAT_TO_FIXED(highest); - lowest = FLOAT_TO_FIXED(lowest); // Now check to see what the REAL high and low points of the slope inside the sector + // TODO: Is this really needed outside of FOFs? -Red size_t l; for (l = 0; l < line->frontsector->linecount; l++) { - if (P_GetZAt(line->frontsector->f_slope, line->frontsector->lines[l]->v1->x, line->frontsector->lines[l]->v1->y) > highest) - highest = P_GetZAt(line->frontsector->f_slope, line->frontsector->lines[l]->v1->x, line->frontsector->lines[l]->v1->y); + fixed_t height = P_GetZAt(line->frontsector->f_slope, line->frontsector->lines[l]->v1->x, line->frontsector->lines[l]->v1->y); - if (P_GetZAt(line->frontsector->f_slope, line->frontsector->lines[l]->v1->x, line->frontsector->lines[l]->v1->y) < lowest) - lowest = P_GetZAt(line->frontsector->f_slope, line->frontsector->lines[l]->v1->x, line->frontsector->lines[l]->v1->y); + if (height > highest) + highest = height; + + if (height < lowest) + lowest = height; } // Sets extra clipping data for the frontsector's slope - fslope->highz = line->frontsector->f_slope->highz = highest; - fslope->lowz = line->frontsector->f_slope->lowz = lowest; - - fslope->zangle = slopeangle; - fslope->xydirection = R_PointToAngle2(FLOAT_TO_FIXED(A.x), FLOAT_TO_FIXED(A.y), FLOAT_TO_FIXED(B.x), FLOAT_TO_FIXED(B.y))/(ANGLE_45/45); - - secplane_t *srcplane = Z_Calloc(sizeof(*srcplane), PU_LEVEL, NULL); - // ZDoom secplane port! YAY - // ret = f_slope or c_slope - srcplane->a = FLOAT_TO_FIXED (fslope->normalf.x); // cross[0] - srcplane->b = FLOAT_TO_FIXED (fslope->normalf.y); // cross[1] - srcplane->c = FLOAT_TO_FIXED (fslope->normalf.z); // cross[2] - srcplane->ic = FixedDiv(FRACUNIT, srcplane->c); // (1 << 32/srcplane->c) or FLOAT_TO_FIXED(1.0f/cross[2]); - - // destheight takes the destination height used in dz - srcplane->d = -TMulScale16 (srcplane->a, line->v1->x, // x - srcplane->b, line->v1->y, // y - srcplane->c, line->backsector->floorheight); // z - - // Sync the secplane! - fslope->secplane = line->frontsector->f_slope->secplane = *srcplane; + fslope->highz = highest; + fslope->lowz = lowest; + fslope->zangle = R_PointToAngle2(0, origin.z, R_PointToDist2(origin.x, origin.y, point.x, point.y), point.z); + fslope->xydirection = R_PointToAngle2(origin.x, origin.y, point.x, point.y); } if(frontceil) { - point.z = FIXED_TO_FLOAT(line->frontsector->ceilingheight); - dz = (FIXED_TO_FLOAT(line->backsector->ceilingheight) - point.z) / extent; + point.z = line->frontsector->ceilingheight; + dz = FixedDiv(line->backsector->ceilingheight - point.z, extent); cslope = line->frontsector->c_slope = P_MakeSlope(&point, &direction, dz, true); // Sync the linedata of the line that started this slope // SRB2CBTODO: Anything special for remote(control sector)-based slopes later? - line->frontsector->c_slope->sourceline = line; + cslope->sourceline = line; // Remember the way the slope is formed fixed_t highest = point.z > origin.z ? point.z : origin.z; fixed_t lowest = point.z < origin.z ? point.z : origin.z; - highest = FLOAT_TO_FIXED(highest); - lowest = FLOAT_TO_FIXED(lowest); size_t l; for (l = 0; l < line->frontsector->linecount; l++) { - if (P_GetZAt(line->frontsector->c_slope, line->frontsector->lines[l]->v1->x, line->frontsector->lines[l]->v1->y) > highest) - highest = P_GetZAt(line->frontsector->c_slope, line->frontsector->lines[l]->v1->x, line->frontsector->lines[l]->v1->y); + fixed_t height = P_GetZAt(line->frontsector->c_slope, line->frontsector->lines[l]->v1->x, line->frontsector->lines[l]->v1->y); - if (P_GetZAt(line->frontsector->c_slope, line->frontsector->lines[l]->v1->x, line->frontsector->lines[l]->v1->y) < lowest) - lowest = P_GetZAt(line->frontsector->c_slope, line->frontsector->lines[l]->v1->x, line->frontsector->lines[l]->v1->y); + if (height > highest) + highest = height; + + if (height < lowest) + lowest = height; } // This line special sets extra clipping data for the frontsector's slope - cslope->highz = line->frontsector->c_slope->highz = highest; - cslope->lowz = line->frontsector->c_slope->lowz = lowest; + cslope->highz = highest; + cslope->lowz = lowest; - // SRB2CBTODO: Get XY angle of a slope and then awesome physics! // ESLOPE: - //cslope->zangle = line->frontsector->c_slope->zangle = P_GetSlopezangle(line->frontsector, highvert, lowvert); - //100*(ANG45/45);//R_PointToAngle2(direction.x, direction.y, origin.x, origin.y); - // Get slope XY angle with secplane_t - secplane_t *srcplane = Z_Calloc(sizeof(*srcplane), PU_LEVEL, NULL); - // ZDoom secplane port! - // secplane_t! woot! - // ret = f_slope or c_slope - srcplane->a = FLOAT_TO_FIXED (cslope->normalf.x); // cross[0] - srcplane->b = FLOAT_TO_FIXED (cslope->normalf.y); // cross[1] - srcplane->c = FLOAT_TO_FIXED (cslope->normalf.z); // cross[2] - //plane->ic = FLOAT_TO_FIXED (1.f/cross[2]); - srcplane->ic = FixedDiv(FRACUNIT, srcplane->c); // (1 << 32/srcplane->c) -#ifdef SLOPETHINGS // For setting thing-based slopes - srcplane->d = -TMulScale16 (plane->a, x, - plane->b, y, - plane->c, z); -#endif - //srcheight = isceiling ? sec->GetPlaneTexZ(sector_t::floor) : sec->GetPlaneTexZ(sector_t::ceiling); - //destheight = isceiling ? refsec->GetPlaneTexZ(sector_t::floor) : refsec->GetPlaneTexZ(sector_t::ceiling); - //P_GetZAtf(ret, v2.x, v2.y) - // destheight takes the destination height used in dz - srcplane->d = -TMulScale16 (srcplane->a, line->v1->x, - srcplane->b, line->v1->y, - srcplane->c, line->backsector->ceilingheight); - - // Sync the secplane! - cslope->secplane = line->frontsector->c_slope->secplane = *srcplane; + cslope->zangle = R_PointToAngle2(0, origin.z, R_PointToDist2(origin.x, origin.y, point.x, point.y), point.z); + cslope->xydirection = R_PointToAngle2(origin.x, origin.y, point.x, point.y); } } if(backfloor || backceil) { - origin.z = FIXED_TO_FLOAT(line->frontsector->floorheight); + origin.z = line->frontsector->floorheight; // Backsector - direction.x = -line->nx; - direction.y = -line->ny; + direction.x = -nx; + direction.y = -ny; - extent = P_GetExtent(line->backsector, line, &origin, &direction); + extent = P_GetExtent(line->backsector, line); - if(extent < 0.0f) + if(extent < 0) { CONS_Printf("P_SpawnSlope_Line failed to get backsector extent on line number %i\n", linenum); return; } // reposition the origin according to the extent - point.x = origin.x + direction.x * extent; - point.y = origin.y + direction.y * extent; + point.x = origin.x + FixedMul(direction.x, extent); + point.y = origin.y + FixedMul(direction.y, extent); direction.x = -direction.x; direction.y = -direction.y; if(backfloor) { - point.z = FIXED_TO_FLOAT(line->backsector->floorheight); - dz = (FIXED_TO_FLOAT(line->frontsector->floorheight) - point.z) / extent; + point.z = line->backsector->floorheight; + dz = FixedDiv(line->frontsector->floorheight - point.z, extent); fslope = line->backsector->f_slope = P_MakeSlope(&point, &direction, dz, false); // Sync the linedata of the line that started this slope // SRB2CBTODO: Anything special for remote(control sector)-based slopes later? - line->backsector->f_slope->sourceline = line; - - int slopeangle = 0; // All floors by default have no slope (an angle of 0) - - v3float_t A = origin; // = line source - v3float_t B = point; // destination's value - v3float_t C = origin; - - C.z = point.z; - - // To find the "angle" of a slope, we make a right triangle out of the points we have, - // point A - is point 1 of the hypotenuse, - // point B - is point 2 of the hypotenuse - // point C - has the same Z value as point b, and the same XY value as A - // - // We want to find the angle accross from the right angle - // so we use some triginometry to find the angle(fun, right?) - // We want to find the tanjent of this angle, this is: - // Opposite - // ------- = tan(x) - // Adjecent - // But actually tan doesn't do want we really want, we have to use atan to find the actual angle of the triangle's corner - float triangopplength = abs(B.z - A.z); - float triangadjlength = sqrt((B.x-C.x)*(B.x-C.x) + (B.y - C.y)*(B.y - C.y)); - //float trianghyplength = sqrt(triangopplength*triangopplength + triangadjlength*triangadjlength); // This is the hypotenuse - - // So tanjent = opposite divided by adjecent - float tanrelat = triangopplength/ triangadjlength; // tanjent = opposite / adjecent - slopeangle = atan(tanrelat)* 180 / M_PI; // Now we use atan - *180 /M_PI is needed to convert the value into degrees + fslope->sourceline = line; // Remember the way the slope is formed fixed_t highest = point.z > origin.z ? point.z : origin.z; fixed_t lowest = point.z < origin.z ? point.z : origin.z; - highest = FLOAT_TO_FIXED(highest); - lowest = FLOAT_TO_FIXED(lowest); size_t l; for (l = 0; l < line->backsector->linecount; l++) { - if (P_GetZAt(line->backsector->f_slope, line->backsector->lines[l]->v1->x, line->backsector->lines[l]->v1->y) > highest) - highest = P_GetZAt(line->backsector->f_slope, line->backsector->lines[l]->v1->x, line->backsector->lines[l]->v1->y); + fixed_t height = P_GetZAt(line->backsector->f_slope, line->backsector->lines[l]->v1->x, line->backsector->lines[l]->v1->y); - if (P_GetZAt(line->backsector->f_slope, line->backsector->lines[l]->v1->x, line->backsector->lines[l]->v1->y) < lowest) - lowest = P_GetZAt(line->backsector->f_slope, line->backsector->lines[l]->v1->x, line->backsector->lines[l]->v1->y); + if (height > highest) + highest = height; + + if (height < lowest) + lowest = height; } // This line special sets extra clipping data for the frontsector's slope - fslope->highz = line->backsector->f_slope->highz = highest; - fslope->lowz = line->backsector->f_slope->lowz = lowest; + fslope->highz = highest; + fslope->lowz = lowest; - fslope->zangle = slopeangle; - // Get slope XY angle with secplane_t - secplane_t *srcplane = Z_Calloc(sizeof(*srcplane), PU_LEVEL, NULL); - // ZDoom secplane port! - // secplane_t! woot! - // ret = f_slope or c_slope - srcplane->a = FLOAT_TO_FIXED (fslope->normalf.x); // cross[0] - srcplane->b = FLOAT_TO_FIXED (fslope->normalf.y); // cross[1] - srcplane->c = FLOAT_TO_FIXED (fslope->normalf.z); // cross[2] - //plane->ic = FLOAT_TO_FIXED (1.f/cross[2]); - srcplane->ic = FixedDiv(FRACUNIT, srcplane->c); // (1 << 32/srcplane->c) -#ifdef SLOPETHINGS // For setting thing-based slopes - srcplane->d = -TMulScale16 (plane->a, x, - plane->b, y, - plane->c, z); -#endif - //srcheight = isceiling ? sec->GetPlaneTexZ(sector_t::floor) : sec->GetPlaneTexZ(sector_t::ceiling); - //destheight = isceiling ? refsec->GetPlaneTexZ(sector_t::floor) : refsec->GetPlaneTexZ(sector_t::ceiling); - //P_GetZAtf(ret, v2.x, v2.y) - // destheight takes the destination height used in dz - srcplane->d = -TMulScale16 (srcplane->a, line->v1->x, - srcplane->b, line->v1->y, - srcplane->c, line->frontsector->floorheight); - - // Sync the secplane! - fslope->secplane = line->backsector->f_slope->secplane = *srcplane; + cslope->zangle = R_PointToAngle2(0, origin.z, R_PointToDist2(origin.x, origin.y, point.x, point.y), point.z); + cslope->xydirection = R_PointToAngle2(origin.x, origin.y, point.x, point.y); } if(backceil) { - point.z = FIXED_TO_FLOAT(line->backsector->ceilingheight); - dz = (FIXED_TO_FLOAT(line->frontsector->ceilingheight) - point.z) / extent; + point.z = line->backsector->ceilingheight; + dz = FixedDiv(line->frontsector->ceilingheight - point.z, extent); cslope = line->backsector->c_slope = P_MakeSlope(&point, &direction, dz, true); // Sync the linedata of the line that started this slope // SRB2CBTODO: Anything special for remote(control sector)-based slopes later? - line->backsector->c_slope->sourceline = line; + cslope->sourceline = line; // Remember the way the slope is formed fixed_t highest = point.z > origin.z ? point.z : origin.z; fixed_t lowest = point.z < origin.z ? point.z : origin.z; - highest = FLOAT_TO_FIXED(highest); - lowest = FLOAT_TO_FIXED(lowest); size_t l; for (l = 0; l < line->backsector->linecount; l++) { - if (P_GetZAt(line->backsector->c_slope, line->backsector->lines[l]->v1->x, line->backsector->lines[l]->v1->y) > highest) - highest = P_GetZAt(line->backsector->c_slope, line->backsector->lines[l]->v1->x, line->backsector->lines[l]->v1->y); + fixed_t height = P_GetZAt(line->backsector->c_slope, line->backsector->lines[l]->v1->x, line->backsector->lines[l]->v1->y); - if (P_GetZAt(line->backsector->c_slope, line->backsector->lines[l]->v1->x, line->backsector->lines[l]->v1->y) < lowest) - lowest = P_GetZAt(line->backsector->c_slope, line->backsector->lines[l]->v1->x, line->backsector->lines[l]->v1->y); + if (height > highest) + highest = height; + + if (height < lowest) + lowest = height; } // This line special sets extra clipping data for the backsector's slope - cslope->highz = line->backsector->c_slope->highz = highest; - cslope->lowz = line->backsector->c_slope->lowz = lowest; + cslope->highz = highest; + cslope->lowz = lowest; - // SRB2CBTODO: Get XY angle of a slope and then awesome physics! // ESLOPE: - //cslope->zangle = line->backsector->c_slope->zangle = P_GetSlopezangle(line->backsector, highvert, lowvert); - //100*(ANG45/45);//R_PointToAngle2(direction.x, direction.y, origin.x, origin.y); - // Get slope XY angle with secplane_t - secplane_t *srcplane = Z_Calloc(sizeof(*srcplane), PU_LEVEL, NULL); - // ZDoom secplane port! - // secplane_t! woot! - // ret = f_slope or c_slope - srcplane->a = FLOAT_TO_FIXED (cslope->normalf.x); // cross[0] - srcplane->b = FLOAT_TO_FIXED (cslope->normalf.y); // cross[1] - srcplane->c = FLOAT_TO_FIXED (cslope->normalf.z); // cross[2] - //plane->ic = FLOAT_TO_FIXED (1.f/cross[2]); - srcplane->ic = FixedDiv(FRACUNIT, srcplane->c); // (1 << 32/srcplane->c) -#ifdef SLOPETHINGS // For setting thing-based slopes - srcplane->d = -TMulScale16 (plane->a, x, - plane->b, y, - plane->c, z); -#endif - //srcheight = isceiling ? sec->GetPlaneTexZ(sector_t::floor) : sec->GetPlaneTexZ(sector_t::ceiling); - //destheight = isceiling ? refsec->GetPlaneTexZ(sector_t::floor) : refsec->GetPlaneTexZ(sector_t::ceiling); - //P_GetZAtf(ret, v2.x, v2.y) - // destheight takes the destination height used in dz - srcplane->d = -TMulScale16 (srcplane->a, line->v1->x, - srcplane->b, line->v1->y, - srcplane->c, line->frontsector->ceilingheight); - - // Sync the secplane! - cslope->secplane = line->backsector->c_slope->secplane = *srcplane; + cslope->zangle = R_PointToAngle2(0, origin.z, R_PointToDist2(origin.x, origin.y, point.x, point.y), point.z); + cslope->xydirection = R_PointToAngle2(origin.x, origin.y, point.x, point.y); } } @@ -626,9 +390,9 @@ void P_CopySectorSlope(line_t *line) sector_t *srcsec = sectors + i; if((special - 393) & 1 && !fsec->f_slope && srcsec->f_slope) - fsec->f_slope = P_CopySlope(srcsec->f_slope); + fsec->f_slope = srcsec->f_slope; //P_CopySlope(srcsec->f_slope); if((special - 393) & 2 && !fsec->c_slope && srcsec->c_slope) - fsec->c_slope = P_CopySlope(srcsec->c_slope); + fsec->c_slope = srcsec->c_slope; //P_CopySlope(srcsec->c_slope); } //SRB2CBTODO: ESLOPE: Maybe we do need it for another to check for a plane slope? diff --git a/src/r_defs.h b/src/r_defs.h index 251140a3f..ac02b999c 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -239,29 +239,30 @@ typedef struct // and the one with the 'f' is floating point, for easier reference elsewhere in the code v3fixed_t o; v3float_t of; - + // The normal of the 3d plane the slope creates. + v3fixed_t normal; v3float_t normalf; - + // 2-Dimentional vector (x, y) normalized. Used to determine distance from // the origin in 2d mapspace. v2fixed_t d; v2float_t df; - + // The rate at which z changes based on distance from the origin plane. fixed_t zdelta; float zdeltaf; - + // For comparing when a slope should be rendered fixed_t lowz; fixed_t highz; - + // SRB2CBTODO: This could be used for something? // Determining the relative z values in a slope? struct line_s *sourceline; - + // This values only check and must be updated if the slope itself is modified - USHORT zangle; // Angle of the plane going up from the ground (not mesured in degrees) + angle_t zangle; // Angle of the plane going up from the ground (not mesured in degrees) angle_t xydirection; // The direction the slope is facing (north, west, south, etc.) secplane_t secplane; // Extra data for collision and stuff } pslope_t; @@ -444,12 +445,6 @@ typedef struct line_s char *text; // a concatination of all front and back texture names, for linedef specials that require a string. INT16 callcount; // no. of calls left before triggering, for the "X calls" linedef specials, defaults to 0 - -#ifdef ESLOPE - // SoM 05/11/09: Pre-calculated 2D normal for the line - float nx, ny; - float len; -#endif } line_t; // From d0a726c00ba57616aa6d71b257d10d93ed9d57aa Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Sun, 26 Apr 2015 13:06:45 -0500 Subject: [PATCH 13/91] Teeny optimization in renderer code?? --- src/r_plane.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/r_plane.c b/src/r_plane.c index 44b65ad10..2839392d0 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -965,9 +965,7 @@ void R_DrawSinglePlane(visplane_t *pl) ang = pl->plangle>>ANGLETOFINESHIFT; m.y = FIXED_TO_FLOAT(P_GetZAt(pl->slope, viewx + FINESINE(ang), viewy + FINECOSINE(ang))) - zeroheight; - ang += ANGLE_90>>ANGLETOFINESHIFT; - ang &= FINEMASK; - n.y = FIXED_TO_FLOAT(P_GetZAt(pl->slope, viewx + FINESINE(ang), viewy + FINECOSINE(ang))) - zeroheight; + n.y = FIXED_TO_FLOAT(P_GetZAt(pl->slope, viewx + FINECOSINE(ang), viewy - FINESINE(ang))) - zeroheight; M_CrossProduct3f(&ds_su, &p, &m); M_CrossProduct3f(&ds_sv, &p, &n); From 6fa1448f59d04fdf9f424324de9cdac7d4c4c771 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Sun, 26 Apr 2015 21:50:50 -0500 Subject: [PATCH 14/91] More cleanup, and made dynamic sloping more efficient/fixed memory leak --- src/p_setup.c | 1 + src/p_slopes.c | 112 +++++++++++++++++++++++++++++++++++++++++-------- src/p_slopes.h | 11 +++-- src/p_spec.c | 23 +++++++++- src/r_defs.h | 22 +++++----- 5 files changed, 134 insertions(+), 35 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index e2ce083f9..a75668b68 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2544,6 +2544,7 @@ boolean P_SetupLevel(boolean skipprecip) break; // set up world state + P_ResetDynamicSlopes(); P_SpawnSpecials(fromnetsave); if (loadprecip) // ugly hack for P_NetUnArchiveMisc (and P_LoadNetGame) diff --git a/src/p_slopes.c b/src/p_slopes.c index e75552f11..7dbb4b8db 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -40,27 +40,79 @@ #ifdef ESLOPE +static pslope_t *dynslopes = NULL; + +// Reset the dynamic slopes pointer +void P_ResetDynamicSlopes(void) { + dynslopes = NULL; +} + +// Calculate line normal +void P_CalculateSlopeNormal(pslope_t *slope) { + slope->normal.z = FINECOSINE(slope->zangle>>ANGLETOFINESHIFT); + slope->normal.x = -FixedMul(FINESINE(slope->zangle>>ANGLETOFINESHIFT), slope->d.x); + slope->normal.y = -FixedMul(FINESINE(slope->zangle>>ANGLETOFINESHIFT), slope->d.y); +} + +// Recalculate dynamic slopes +void P_RunDynamicSlopes(void) { + pslope_t *slope; + + for (slope = dynslopes; slope; slope = slope->next) { + fixed_t zdelta; + + switch(slope->refpos) { + case 1: // front floor + zdelta = slope->sourceline->backsector->floorheight - slope->sourceline->frontsector->floorheight; + break; + case 2: // front ceiling + zdelta = slope->sourceline->backsector->ceilingheight - slope->sourceline->frontsector->ceilingheight; + break; + case 3: // back floor + zdelta = slope->sourceline->frontsector->floorheight - slope->sourceline->backsector->floorheight; + break; + case 4: // back ceiling + zdelta = slope->sourceline->frontsector->ceilingheight - slope->sourceline->backsector->ceilingheight; + break; + + default: + I_Error("P_RunDynamicSlopes: slope has invalid type!"); + } + + if (slope->zdelta != FixedDiv(zdelta, slope->extent)) { + slope->zdeltaf = FIXED_TO_FLOAT(slope->zdelta = FixedDiv(zdelta, slope->extent)); + slope->zangle = R_PointToAngle2(0, 0, slope->extent, zdelta); + P_CalculateSlopeNormal(slope); + } + } +} + // // P_MakeSlope // // Alocates and fill the contents of a slope structure. // static pslope_t *P_MakeSlope(const v3fixed_t *o, const v2fixed_t *d, - const fixed_t zdelta, boolean isceiling) + const fixed_t zdelta, boolean dynamic) { - pslope_t *ret = Z_Malloc(sizeof(pslope_t), PU_LEVEL, NULL); - memset(ret, 0, sizeof(*ret)); + pslope_t *ret = Z_Malloc(sizeof(pslope_t), PU_LEVEL, NULL); + memset(ret, 0, sizeof(*ret)); - ret->of.x = FIXED_TO_FLOAT(ret->o.x = o->x); - ret->of.y = FIXED_TO_FLOAT(ret->o.y = o->y); - ret->of.z = FIXED_TO_FLOAT(ret->o.z = o->z); + ret->of.x = FIXED_TO_FLOAT(ret->o.x = o->x); + ret->of.y = FIXED_TO_FLOAT(ret->o.y = o->y); + ret->of.z = FIXED_TO_FLOAT(ret->o.z = o->z); - ret->df.x = FIXED_TO_FLOAT(ret->d.x = d->x); - ret->df.y = FIXED_TO_FLOAT(ret->d.y = d->y); + ret->df.x = FIXED_TO_FLOAT(ret->d.x = d->x); + ret->df.y = FIXED_TO_FLOAT(ret->d.y = d->y); - ret->zdeltaf = FIXED_TO_FLOAT(ret->zdelta = zdelta); + ret->zdeltaf = FIXED_TO_FLOAT(ret->zdelta = zdelta); - return ret; + if (dynamic) { // Add to the dynamic slopes list + ret->next = dynslopes; + dynslopes = ret; + } + + return ret; } // @@ -195,7 +247,11 @@ void P_SpawnSlope_Line(int linenum) // In P_SpawnSlopeLine the origin is the centerpoint of the sourcelinedef fslope = line->frontsector->f_slope = - P_MakeSlope(&point, &direction, dz, false); + P_MakeSlope(&point, &direction, dz, true); + + // Set up some shit + fslope->extent = extent; + fslope->refpos = 1; // Now remember that f_slope IS a vector // fslope->o = origin 3D point 1 of the vector @@ -235,8 +291,10 @@ void P_SpawnSlope_Line(int linenum) fslope->highz = highest; fslope->lowz = lowest; - fslope->zangle = R_PointToAngle2(0, origin.z, R_PointToDist2(origin.x, origin.y, point.x, point.y), point.z); + fslope->zangle = R_PointToAngle2(0, origin.z, extent, point.z); fslope->xydirection = R_PointToAngle2(origin.x, origin.y, point.x, point.y); + + P_CalculateSlopeNormal(fslope); } if(frontceil) { @@ -246,6 +304,10 @@ void P_SpawnSlope_Line(int linenum) cslope = line->frontsector->c_slope = P_MakeSlope(&point, &direction, dz, true); + // Set up some shit + cslope->extent = extent; + cslope->refpos = 2; + // Sync the linedata of the line that started this slope // SRB2CBTODO: Anything special for remote(control sector)-based slopes later? cslope->sourceline = line; @@ -270,8 +332,10 @@ void P_SpawnSlope_Line(int linenum) cslope->highz = highest; cslope->lowz = lowest; - cslope->zangle = R_PointToAngle2(0, origin.z, R_PointToDist2(origin.x, origin.y, point.x, point.y), point.z); + cslope->zangle = R_PointToAngle2(0, origin.z, extent, point.z); cslope->xydirection = R_PointToAngle2(origin.x, origin.y, point.x, point.y); + + P_CalculateSlopeNormal(cslope); } } if(backfloor || backceil) @@ -301,7 +365,11 @@ void P_SpawnSlope_Line(int linenum) dz = FixedDiv(line->frontsector->floorheight - point.z, extent); fslope = line->backsector->f_slope = - P_MakeSlope(&point, &direction, dz, false); + P_MakeSlope(&point, &direction, dz, true); + + // Set up some shit + fslope->extent = extent; + fslope->refpos = 3; // Sync the linedata of the line that started this slope // SRB2CBTODO: Anything special for remote(control sector)-based slopes later? @@ -327,8 +395,10 @@ void P_SpawnSlope_Line(int linenum) fslope->highz = highest; fslope->lowz = lowest; - cslope->zangle = R_PointToAngle2(0, origin.z, R_PointToDist2(origin.x, origin.y, point.x, point.y), point.z); + cslope->zangle = R_PointToAngle2(0, origin.z, extent, point.z); cslope->xydirection = R_PointToAngle2(origin.x, origin.y, point.x, point.y); + + P_CalculateSlopeNormal(fslope); } if(backceil) { @@ -338,6 +408,10 @@ void P_SpawnSlope_Line(int linenum) cslope = line->backsector->c_slope = P_MakeSlope(&point, &direction, dz, true); + // Set up some shit + cslope->extent = extent; + cslope->refpos = 4; + // Sync the linedata of the line that started this slope // SRB2CBTODO: Anything special for remote(control sector)-based slopes later? cslope->sourceline = line; @@ -363,8 +437,10 @@ void P_SpawnSlope_Line(int linenum) cslope->highz = highest; cslope->lowz = lowest; - cslope->zangle = R_PointToAngle2(0, origin.z, R_PointToDist2(origin.x, origin.y, point.x, point.y), point.z); + cslope->zangle = R_PointToAngle2(0, origin.z, extent, point.z); cslope->xydirection = R_PointToAngle2(origin.x, origin.y, point.x, point.y); + + P_CalculateSlopeNormal(cslope); } } @@ -399,7 +475,7 @@ void P_CopySectorSlope(line_t *line) line->special = 0; // Linedef was use to set slopes, it finished its job, so now make it a normal linedef } - +#ifdef SPRINGCLEAN #include "byteptr.h" #include "p_setup.h" @@ -652,7 +728,7 @@ void P_SetSlopesFromVertexHeights(lumpnum_t lumpnum) } - +#endif diff --git a/src/p_slopes.h b/src/p_slopes.h index 8449c1020..e522d79ba 100644 --- a/src/p_slopes.h +++ b/src/p_slopes.h @@ -1,4 +1,4 @@ -// Emacs style mode select -*- C++ -*- +// Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // Copyright(C) 2004 Stephen McGranahan @@ -7,12 +7,12 @@ // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. -// +// // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. -// +// // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA @@ -29,6 +29,9 @@ #define P_SLOPES_H__ #ifdef ESLOPE +void P_ResetDynamicSlopes(void); +void P_RunDynamicSlopes(void); + // P_MakeLineNormal // Calculates a 2D normal for the given line and stores it in the line void P_MakeLineNormal(line_t *line); @@ -74,7 +77,7 @@ float P_GetZAtf(pslope_t *slope, float x, float y); // Returns the distance of the given point from the given origin and normal. -float P_DistFromPlanef(const v3float_t *point, const v3float_t *pori, +float P_DistFromPlanef(const v3float_t *point, const v3float_t *pori, const v3float_t *pnormal); #endif diff --git a/src/p_spec.c b/src/p_spec.c index a81905503..4ed668ce7 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4765,8 +4765,8 @@ void P_UpdateSpecials(void) // POINT LIMIT P_CheckPointLimit(); - // Kalaron: ...We...have dynamic slopes *YESSSS* - P_SpawnDeferredSpecials(); + // Dynamic slopeness + P_RunDynamicSlopes(); // ANIMATE TEXTURES for (anim = anims; anim < lastanim; anim++) @@ -6447,6 +6447,25 @@ void P_SpawnSpecials(INT32 fromnetsave) sectors[s].midmap = lines[i].frontsector->midmap; break; +#ifdef ESLOPE // Slope specials. TODO move these to a different spot, maybe? + case 386: + case 387: + case 388: + case 389: + case 390: + case 391: + case 392: + case 393: + P_SpawnSlope_Line(i); + break; + // SoM: Copy slopes + case 394: + case 395: + case 396: + P_CopySectorSlope(&lines[i]); + break; +#endif + default: break; } diff --git a/src/r_defs.h b/src/r_defs.h index ac02b999c..f2ae0ba8b 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -229,7 +229,7 @@ typedef struct secplane_t #include "m_vector.h" -typedef struct +typedef struct pslope_s { // --- Information used in clipping/projection --- // Origin vector for the plane @@ -240,12 +240,8 @@ typedef struct v3fixed_t o; v3float_t of; - // The normal of the 3d plane the slope creates. - v3fixed_t normal; - v3float_t normalf; - // 2-Dimentional vector (x, y) normalized. Used to determine distance from - // the origin in 2d mapspace. + // the origin in 2d mapspace. (Basically a thrust of FRACUNIT in xydirection angle) v2fixed_t d; v2float_t df; @@ -253,18 +249,22 @@ typedef struct fixed_t zdelta; float zdeltaf; + // The normal of the slope; will always point upward, and thus be inverted on ceilings. I think it's only needed for physics? -Red + v3fixed_t normal; + // For comparing when a slope should be rendered fixed_t lowz; fixed_t highz; - // SRB2CBTODO: This could be used for something? - // Determining the relative z values in a slope? - struct line_s *sourceline; - // This values only check and must be updated if the slope itself is modified angle_t zangle; // Angle of the plane going up from the ground (not mesured in degrees) angle_t xydirection; // The direction the slope is facing (north, west, south, etc.) - secplane_t secplane; // Extra data for collision and stuff + + struct line_s *sourceline; // The line that generated the slope + fixed_t extent; // Distance value used for recalculating zdelta + UINT8 refpos; // 1=front floor 2=front ceiling 3=back floor 4=back ceiling (used for dynamic sloping) 0=disabled + + struct pslope_s *next; // Make a linked list of dynamic slopes, for easy reference later } pslope_t; #endif From 0c477c685d4ce8394330d6d8f87e32c446d9f29b Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Sun, 26 Apr 2015 22:20:03 -0500 Subject: [PATCH 15/91] Removing unused cruft --- src/p_slopes.c | 16 +------------- src/p_slopes.h | 10 +++------ src/p_spec.c | 57 -------------------------------------------------- src/p_spec.h | 5 ----- 4 files changed, 4 insertions(+), 84 deletions(-) diff --git a/src/p_slopes.c b/src/p_slopes.c index 7dbb4b8db..efa15aed4 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -115,19 +115,6 @@ static pslope_t *P_MakeSlope(const v3fixed_t *o, const v2fixed_t *d, return ret; } -// -// P_CopySlope -// -// Allocates and returns a copy of the given slope structure. -// -static pslope_t *P_CopySlope(const pslope_t *src) -{ - pslope_t *ret = Z_Malloc(sizeof(pslope_t), PU_LEVEL, NULL); - memcpy(ret, src, sizeof(*ret)); - - return ret; -} - // // P_GetExtent // @@ -471,7 +458,6 @@ void P_CopySectorSlope(line_t *line) fsec->c_slope = srcsec->c_slope; //P_CopySlope(srcsec->c_slope); } - //SRB2CBTODO: ESLOPE: Maybe we do need it for another to check for a plane slope? line->special = 0; // Linedef was use to set slopes, it finished its job, so now make it a normal linedef } @@ -765,7 +751,7 @@ float P_GetZAtf(pslope_t *slope, float x, float y) return slope->of.z + (dist * slope->zdeltaf); } -// +// Unused? -Red // P_DistFromPlanef // float P_DistFromPlanef(const v3float_t *point, const v3float_t *pori, diff --git a/src/p_slopes.h b/src/p_slopes.h index e522d79ba..8f408d6f0 100644 --- a/src/p_slopes.h +++ b/src/p_slopes.h @@ -31,18 +31,12 @@ #ifdef ESLOPE void P_ResetDynamicSlopes(void); void P_RunDynamicSlopes(void); - -// P_MakeLineNormal -// Calculates a 2D normal for the given line and stores it in the line -void P_MakeLineNormal(line_t *line); - - // P_SpawnSlope_Line // Creates one or more slopes based on the given line type and front/back // sectors. void P_SpawnSlope_Line(int linenum); - +#ifdef SPRINGCLEAN // Loads just map objects that make slopes, // terrain affecting objects have to be spawned first void P_SetSlopesFromVertexHeights(lumpnum_t lumpnum); @@ -60,6 +54,7 @@ typedef enum THING_VertexFloorZ=1504, THING_VertexCeilingZ=1505, } slopething_e; +#endif // // P_CopySectorSlope @@ -76,6 +71,7 @@ fixed_t P_GetZAt(pslope_t *slope, fixed_t x, fixed_t y); float P_GetZAtf(pslope_t *slope, float x, float y); +// Unused? -Red // Returns the distance of the given point from the given origin and normal. float P_DistFromPlanef(const v3float_t *point, const v3float_t *pori, const v3float_t *pnormal); diff --git a/src/p_spec.c b/src/p_spec.c index 4ed668ce7..e33dd474c 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -6500,63 +6500,6 @@ void P_SpawnSpecials(INT32 fromnetsave) P_RunLevelLoadExecutors(); } -#ifdef ESLOPE -// -// P_SpawnDeferredSpecials -// -// SoM: Specials that copy slopes, ect., need to be collected in a separate -// pass -// NOTE: SRB2CBTODO: A new function, P_SpawnDeferredSpecials is needed if objects -// are to be needed in this function, because this function currently needs to be -// done before 'things' are loaded, because slopes are part of this function, -// and slope height adjustments are needed for spawning objects -void P_SpawnDeferredSpecials(void) -{ - size_t i; - line_t *line; - - for(i = 0; i < numlines; i++) - { - line = lines + i; - - switch(line->special) - { - // Slopes, Eternity engine - /*{ 386, "Slope_FrontsectorFloor" }, - { 387, "Slope_FrontsectorCeiling" }, - { 388, "Slope_FrontsectorFloorAndCeiling" }, - { 389, "Slope_BacksectorFloor" }, - { 390, "Slope_BacksectorCeiling" }, - { 391, "Slope_BacksectorFloorAndCeiling" }, - { 392, "Slope_BackFloorAndFrontCeiling" }, - { 393, "Slope_BackCeilingAndFrontFloor" }, - - { 394, "Slope_FrontFloorToTaggedSlope" }, - { 395, "Slope_FrontCeilingToTaggedSlope" }, - { 396, "Slope_FrontFloorAndCeilingToTaggedSlope" },*/ - - // SoM 05/10/09: Slopes // SRB2CBTODO:! - case 386: - case 387: - case 388: - case 389: - case 390: - case 391: - case 392: - case 393: - P_SpawnSlope_Line(i); - break; - // SoM: Copy slopes - case 394: - case 395: - case 396: - P_CopySectorSlope(line); - break; - } - } -} -#endif - /** Adds 3Dfloors as appropriate based on a common control linedef. * * \param line Control linedef to use. diff --git a/src/p_spec.h b/src/p_spec.h index c8cfc76da..7b6a5655c 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -36,11 +36,6 @@ void P_SpawnSpecials(INT32 fromnetsave); // every tic void P_UpdateSpecials(void); - -#ifdef ESLOPE -void P_SpawnDeferredSpecials(void); -#endif - sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 number); void P_PlayerInSpecialSector(player_t *player); void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *roversector); From 58dd6d42afde5523e2ca2819f135512e413bc77d Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Mon, 27 Apr 2015 13:18:12 -0500 Subject: [PATCH 16/91] Add P_GetFloorZ and P_GetCeilingZ as boilerplate to facilitate better slope collision I have not used this anywhere in the code yet. --- src/p_local.h | 3 + src/p_mobj.c | 245 +++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 215 insertions(+), 33 deletions(-) diff --git a/src/p_local.h b/src/p_local.h index eab78c785..53e5b18b4 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -232,6 +232,9 @@ boolean P_RailThinker(mobj_t *mobj); void P_PushableThinker(mobj_t *mobj); void P_SceneryThinker(mobj_t *mobj); +fixed_t P_GetFloorZ(mobj_t *mobj, sector_t *sector, fixed_t x, fixed_t y, line_t *line); +fixed_t P_GetCeilingZ(mobj_t *mobj, sector_t *sector, fixed_t x, fixed_t y, line_t *line); + boolean P_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover); boolean P_CheckDeathPitCollide(mobj_t *mo); boolean P_CheckSolidLava(mobj_t *mo, ffloor_t *rover); diff --git a/src/p_mobj.c b/src/p_mobj.c index f660edff4..1be713bf4 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -722,52 +722,231 @@ boolean P_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover) return true; } -fixed_t P_GetMobjZAtSecF(mobj_t *mobj, sector_t *sector) // SRB2CBTODO: This needs to be over all the code +// P_GetFloorZ (and its ceiling counterpart) +// Gets the floor height (or ceiling height) of the mobj's contact point in sector, assuming object's center if moved to [x, y] +// If line is supplied, it's a divider line on the sector. Set it to NULL if you're not checking for collision with a line +fixed_t P_GetFloorZ(mobj_t *mobj, sector_t *sector, fixed_t x, fixed_t y, line_t *line) // SRB2CBTODO: This needs to be over all the code { I_Assert(mobj != NULL); + I_Assert(sector != NULL); #ifdef ESLOPE - if (sector->f_slope) - return P_GetZAt(sector->f_slope, mobj->x, mobj->y); - else + if (sector->f_slope) { + fixed_t testx, testy; + pslope_t *slope = sector->f_slope; + + // Get the corner of the object that should be the highest on the slope + if (slope->d.x < 0) + testx = mobj->radius; + else + testx = -mobj->radius; + + if (slope->d.y < 0) + testy = mobj->radius; + else + testy = -mobj->radius; + + if (slope->zdelta > 0) { + testx = -testx; + testx = -testy; + } + + testx += x; + testy += y; + + // If the highest point is in the sector, then we have it easy! Just get the Z at that point + if (R_PointInSubsector(testx, testy)->sector == sector + // The following line is a hack to fix a bug where an object pops down on the frame its highest corner re-enters the sloped sector. + || R_PointInSubsector(testx+mobj->momx, testy+mobj->momy)->sector == sector + ) + return P_GetZAt(slope, testx, testy); + + // If we're just testing for base sector location (no collision line), just go for the center's spot... + // It'll get fixed when we test for collision anyway, and the final result can't be lower than this + if (line == NULL) + return P_GetZAt(slope, x, y); + + // Alright, so we're sitting on a line that contains our slope sector, and need to figure out the highest point we're touching... + // The solution is simple! Get the line's vertices, and pull each one in along its line until it touches the object's bounding box + // (assuming it isn't already inside), then test each point's slope Z and return the higher of the two. + { + vertex_t v1, v2; + v1.x = line->v1->x; + v1.y = line->v1->y; + v2.x = line->v2->x; + v2.y = line->v2->y; + + if (abs(v1.x-x) > mobj->radius) { + // v1's x is out of range, so rein it in + fixed_t diff = abs(v1.x-x) - mobj->radius; + + if (v1.x < x) { // Moving right + v1.x += diff; + v1.y += FixedMul(diff, FixedDiv(line->dy, line->dx)); + } else { // Moving left + v1.x -= diff; + v1.y -= FixedMul(diff, FixedDiv(line->dy, line->dx)); + } + } + + if (abs(v1.y-y) > mobj->radius) { + // v1's y is out of range, so rein it in + fixed_t diff = abs(v1.y-y) - mobj->radius; + + if (v1.y < y) { // Moving up + v1.y += diff; + v1.x += FixedMul(diff, FixedDiv(line->dx, line->dy)); + } else { // Moving down + v1.y -= diff; + v1.x -= FixedMul(diff, FixedDiv(line->dx, line->dy)); + } + } + + if (abs(v2.x-x) > mobj->radius) { + // v1's x is out of range, so rein it in + fixed_t diff = abs(v2.x-x) - mobj->radius; + + if (v2.x < x) { // Moving right + v2.x += diff; + v2.y += FixedMul(diff, FixedDiv(line->dy, line->dx)); + } else { // Moving left + v2.x -= diff; + v2.y -= FixedMul(diff, FixedDiv(line->dy, line->dx)); + } + } + + if (abs(v2.y-y) > mobj->radius) { + // v2's y is out of range, so rein it in + fixed_t diff = abs(v2.y-y) - mobj->radius; + + if (v2.y < y) { // Moving up + v2.y += diff; + v2.x += FixedMul(diff, FixedDiv(line->dx, line->dy)); + } else { // Moving down + v2.y -= diff; + v2.x -= FixedMul(diff, FixedDiv(line->dx, line->dy)); + } + } + + // Return the higher of the two points + return max( + P_GetZAt(slope, v1.x, v1.y), + P_GetZAt(slope, v2.x, v2.y) + ); + } + } else // Well, that makes it easy. Just get the floor height #endif return sector->floorheight; } -fixed_t P_GetMobjZAtF(mobj_t *mobj) // SRB2CBTODO: This needs to be over all the code +fixed_t P_GetCeilingZ(mobj_t *mobj, sector_t *sector, fixed_t x, fixed_t y, line_t *line) // SRB2CBTODO: This needs to be over all the code { I_Assert(mobj != NULL); - sector_t *sector; - sector = R_PointInSubsector(mobj->x, mobj->y)->sector; - + I_Assert(sector != NULL); #ifdef ESLOPE - if (sector->f_slope) - return P_GetZAt(sector->f_slope, mobj->x, mobj->y); - else -#endif - return sector->floorheight; -} + if (sector->c_slope) { + fixed_t testx, testy; + pslope_t *slope = sector->c_slope; -fixed_t P_GetMobjZAtSecC(mobj_t *mobj, sector_t *sector) // SRB2CBTODO: This needs to be over all the code -{ - I_Assert(mobj != NULL); -#ifdef ESLOPE - if (sector->c_slope) - return P_GetZAt(sector->c_slope, mobj->x, mobj->y); - else -#endif - return sector->ceilingheight; -} + // Get the corner of the object that should be the lowest on the slope + if (slope->d.x < 0) + testx = mobj->radius; + else + testx = -mobj->radius; -fixed_t P_GetMobjZAtC(mobj_t *mobj) // SRB2CBTODO: This needs to be over all the code -{ - I_Assert(mobj != NULL); - sector_t *sector; - sector = R_PointInSubsector(mobj->x, mobj->y)->sector; + if (slope->d.y < 0) + testy = mobj->radius; + else + testy = -mobj->radius; -#ifdef ESLOPE - if (sector->c_slope) - return P_GetZAt(sector->c_slope, mobj->x, mobj->y); - else + if (slope->zdelta < 0) { + testx = -testx; + testx = -testy; + } + + testx += x; + testy += y; + + // If the lowest point is in the sector, then we have it easy! Just get the Z at that point + if (R_PointInSubsector(testx, testy)->sector == sector + // The following line is a hack to fix a bug where an object pops down on the frame its highest corner re-enters the sloped sector. + || R_PointInSubsector(testx+mobj->momx, testy+mobj->momy)->sector == sector + ) + return P_GetZAt(slope, testx, testy); + + // If we're just testing for base sector location (no collision line), just go for the center's spot... + // It'll get fixed when we test for collision anyway, and the final result can't be higher than this + if (line == NULL) + return P_GetZAt(slope, x, y); + + // Alright, so we're sitting on a line that contains our slope sector, and need to figure out the highest point we're touching... + // The solution is simple! Get the line's vertices, and pull each one in along its line until it touches the object's bounding box + // (assuming it isn't already inside), then test each point's slope Z and return the lower of the two. + { + vertex_t v1, v2; + v1.x = line->v1->x; + v1.y = line->v1->y; + v2.x = line->v2->x; + v2.y = line->v2->y; + + if (abs(v1.x-x) > mobj->radius) { + // v1's x is out of range, so rein it in + fixed_t diff = abs(v1.x-x) - mobj->radius; + + if (v1.x < x) { // Moving right + v1.x += diff; + v1.y += FixedMul(diff, FixedDiv(line->dy, line->dx)); + } else { // Moving left + v1.x -= diff; + v1.y -= FixedMul(diff, FixedDiv(line->dy, line->dx)); + } + } + + if (abs(v1.y-y) > mobj->radius) { + // v1's y is out of range, so rein it in + fixed_t diff = abs(v1.y-y) - mobj->radius; + + if (v1.y < y) { // Moving up + v1.y += diff; + v1.x += FixedMul(diff, FixedDiv(line->dx, line->dy)); + } else { // Moving down + v1.y -= diff; + v1.x -= FixedMul(diff, FixedDiv(line->dx, line->dy)); + } + } + + if (abs(v2.x-x) > mobj->radius) { + // v1's x is out of range, so rein it in + fixed_t diff = abs(v2.x-x) - mobj->radius; + + if (v2.x < x) { // Moving right + v2.x += diff; + v2.y += FixedMul(diff, FixedDiv(line->dy, line->dx)); + } else { // Moving left + v2.x -= diff; + v2.y -= FixedMul(diff, FixedDiv(line->dy, line->dx)); + } + } + + if (abs(v2.y-y) > mobj->radius) { + // v2's y is out of range, so rein it in + fixed_t diff = abs(v2.y-y) - mobj->radius; + + if (v2.y < y) { // Moving up + v2.y += diff; + v2.x += FixedMul(diff, FixedDiv(line->dx, line->dy)); + } else { // Moving down + v2.y -= diff; + v2.x -= FixedMul(diff, FixedDiv(line->dx, line->dy)); + } + } + + // Return the lower of the two points + return min( + P_GetZAt(slope, v1.x, v1.y), + P_GetZAt(slope, v2.x, v2.y) + ); + } + } else // Well, that makes it easy. Just get the ceiling height #endif return sector->ceilingheight; } From 6694480f68c21c442a5081ed9ba87682fe834872 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Mon, 27 Apr 2015 13:20:50 -0500 Subject: [PATCH 17/91] Overhaul slope collision (NOT PHYSICS) to work almost perfectly --- src/p_enemy.c | 10 ++---- src/p_floor.c | 13 +++----- src/p_map.c | 70 ++++++++-------------------------------- src/p_maputl.c | 87 +++++++++++++++++++------------------------------- src/p_spec.c | 12 ++----- 5 files changed, 56 insertions(+), 136 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 1271c875d..43c0f5057 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -28,7 +28,7 @@ #include "hardware/hw3sound.h" #endif -#ifdef ESLOPE +#ifdef SPRINGCLEAN// ESLOPE #include "p_slopes.h" #endif @@ -5611,12 +5611,8 @@ void A_MixUp(mobj_t *actor) P_SetThingPosition(players[i].mo); #ifdef ESLOPE - players[i].mo->floorz = (players[i].mo->subsector->sector->f_slope ? - P_GetZAt(players[i].mo->subsector->sector->f_slope, players[i].mo->x, players[i].mo->y) : - players[i].mo->subsector->sector->floorheight); - players[i].mo->ceilingz = (players[i].mo->subsector->sector->c_slope ? - P_GetZAt(players[i].mo->subsector->sector->c_slope, players[i].mo->x, players[i].mo->y) : - players[i].mo->subsector->sector->ceilingheight); + players[i].mo->floorz = P_GetFloorZ(players[i].mo, players[i].mo->subsector->sector, players[i].mo->x, players[i].mo->y, NULL); + players[i].mo->ceilingz = P_GetCeilingZ(players[i].mo, players[i].mo->subsector->sector, players[i].mo->x, players[i].mo->y, NULL); #else players[i].mo->floorz = players[i].mo->subsector->sector->floorheight; players[i].mo->ceilingz = players[i].mo->subsector->sector->ceilingheight; diff --git a/src/p_floor.c b/src/p_floor.c index 23c460244..0d68becbf 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -19,7 +19,7 @@ #include "z_zone.h" #include "g_game.h" #include "r_main.h" -#ifdef ESLOPE +#ifdef SPRINGCLEAN// ESLOPE #include "p_slopes.h" #endif @@ -1177,18 +1177,15 @@ void T_SpikeSector(levelspecthink_t *spikes) if (affectsec == spikes->sector) // Applied to an actual sector { - fixed_t affectpoint = affectsec->floorheight; + fixed_t affectfloor = P_GetFloorZ(thing, affectsec, thing->x, thing->y, NULL); + fixed_t affectceil = P_GetCeilingZ(thing, affectsec, thing->x, thing->y, NULL); -#ifdef ESLOPE - if (affectsec->f_slope) - affectpoint = P_GetZAt(affectsec->f_slope, thing->x, thing->y); -#endif if (affectsec->flags & SF_FLIPSPECIAL_FLOOR) { if (!(thing->eflags & MFE_VERTICALFLIP) && thing->momz > 0) continue; - if (thing->z == affectpoint) + if (thing->z == affectfloor) dothepain = true; } @@ -1197,7 +1194,7 @@ void T_SpikeSector(levelspecthink_t *spikes) if ((thing->eflags & MFE_VERTICALFLIP) && thing->momz < 0) continue; - if (thing->z + thing->height == affectsec->ceilingheight) + if (thing->z + thing->height == affectceil) dothepain = true; } } diff --git a/src/p_map.c b/src/p_map.c index 565569844..50f172798 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -27,7 +27,7 @@ #include "r_splats.h" -#ifdef ESLOPE +#ifdef SPRINGCLEAN// ESLOPE #include "p_slopes.h" #endif @@ -125,7 +125,7 @@ void P_DoSpring(mobj_t *spring, mobj_t *object) /*Someone want to make these work like bumpers?*/ return; } - + object->eflags |= MFE_SPRUNG; // apply this flag asap! spring->flags &= ~(MF_SOLID|MF_SPECIAL); // De-solidify @@ -1208,21 +1208,8 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) // that contains the point. // Any contacted lines the step closer together // will adjust them. -#ifdef ESLOPE - if (newsubsec->sector->f_slope) - { - tmfloorz = tmdropoffz = P_GetZAt(newsubsec->sector->f_slope, thing->x, thing->y); - } - else -#endif - tmfloorz = tmdropoffz = newsubsec->sector->floorheight; - -#ifdef ESLOPE - if (newsubsec->sector->c_slope) - tmceilingz = P_GetZAt(newsubsec->sector->c_slope, thing->x, thing->y); - else -#endif - tmceilingz = newsubsec->sector->ceilingheight; + tmfloorz = tmdropoffz = P_GetFloorZ(thing, newsubsec->sector, thing->x, thing->y, NULL); //newsubsec->sector->floorheight; + tmceilingz = P_GetCeilingZ(thing, newsubsec->sector, thing->x, thing->y, NULL); //newsubsec->sector->ceilingheight; // Check list of fake floors and see if tmfloorz/tmceilingz need to be altered. if (newsubsec->sector->ffloors) @@ -1535,7 +1522,7 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam) fixed_t topheight = *rover->topheight; fixed_t bottomheight = *rover->bottomheight; - + /*#ifdef ESLOPE if (rover->t_slope) topheight = P_GetZAt(rover->t_slope, thiscam->x, thiscam->y); @@ -2033,7 +2020,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) // Link the thing into its new position P_UnsetThingPosition(thing); -#ifdef ESLOPE +#ifdef SRPINGCLEAN// ESLOPE // By virtue of being derived from SRB2 code, Kalaron's physics are GPL. if (P_IsObjectOnSlope(thing, false)) { @@ -2112,32 +2099,9 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) } #endif - // P_CheckPosition sets the tmfloorz with slopes, but after P_UnsetThingPosition, recheck the function here - // TODO: Make a function for floor/ceilingz auto check with slopes? -#ifdef ESLOPE - if (thing->subsector->sector->f_slope) - { - // TODO: Support a mobj's gravity for this too - if (P_GetZAt(thing->subsector->sector->f_slope, thing->x+thing->momx, thing->y+thing->momy) > P_GetZAt(thing->subsector->sector->f_slope, thing->x, thing->y)) - thing->floorz = P_GetZAt(thing->subsector->sector->f_slope, thing->x+thing->momx, thing->y+thing->momy); - else - thing->floorz = P_GetZAt(thing->subsector->sector->f_slope, thing->x, thing->y); - } - else -#endif - thing->floorz = tmfloorz; -#ifdef ESLOPE - if (thing->subsector->sector->c_slope) - { - // SRB2CBTODO: Support a mobj's gravity for this too - if (P_GetZAt(thing->subsector->sector->c_slope, thing->x+thing->momx, thing->y+thing->momy) < P_GetZAt(thing->subsector->sector->c_slope, thing->x, thing->y)) - thing->ceilingz = P_GetZAt(thing->subsector->sector->c_slope, thing->x, thing->y); - else - thing->ceilingz = P_GetZAt(thing->subsector->sector->c_slope, thing->x+thing->momx, thing->y+thing->momy); - } - else -#endif - thing->ceilingz = tmceilingz; + thing->floorz = tmfloorz; + thing->ceilingz = tmceilingz; + thing->x = x; thing->y = y; @@ -2494,16 +2458,8 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle) glidesector = R_PointInSubsector(player->mo->x + platx, player->mo->y + platy); - floorz = glidesector->sector->floorheight; -#ifdef ESLOPE - if (glidesector->sector->f_slope) - floorz = P_GetZAt(glidesector->sector->f_slope, player->mo->x + platx, player->mo->y + platy); -#endif - ceilingz = glidesector->sector->ceilingheight; -#ifdef ESLOPE - if (glidesector->sector->c_slope) - ceilingz = P_GetZAt(glidesector->sector->c_slope, player->mo->x + platx, player->mo->y + platy); -#endif + floorz = P_GetFloorZ(player->mo, glidesector->sector, player->mo->x + platx, player->mo->y + platy, NULL); + ceilingz = P_GetCeilingZ(player->mo, glidesector->sector, player->mo->x + platx, player->mo->y + platy, NULL); if (glidesector->sector != player->mo->subsector->sector) { @@ -2519,7 +2475,7 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle) fixed_t topheight = *rover->topheight; fixed_t bottomheight = *rover->bottomheight; - + /*#ifdef ESLOPE if (rover->t_slope) topheight = P_GetZAt(rover->t_slope, player->mo->x, player->mo->y); @@ -4046,7 +4002,7 @@ fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height) fixed_t topheight = *rover->topheight; fixed_t bottomheight = *rover->bottomheight; - + /*#ifdef ESLOPE if (rover->t_slope) topheight = P_GetZAt(rover->t_slope, x, y); diff --git a/src/p_maputl.c b/src/p_maputl.c index f0a08883c..7641dd1eb 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -21,7 +21,7 @@ #include "p_maputl.h" #include "p_polyobj.h" #include "z_zone.h" -#ifdef ESLOPE +#ifdef SPRINGCLEAN// ESLOPE #include "p_slopes.h" #endif @@ -557,26 +557,36 @@ void P_LineOpening(line_t *linedef) I_Assert(front != NULL); I_Assert(back != NULL); - if (front->ceilingheight < back->ceilingheight) - { - opentop = front->ceilingheight; - highceiling = back->ceilingheight; - } - else - { - opentop = back->ceilingheight; - highceiling = front->ceilingheight; - } + { // Set open and high/low values here + fixed_t frontheight, backheight; - if (front->floorheight > back->floorheight) - { - openbottom = front->floorheight; - lowfloor = back->floorheight; - } - else - { - openbottom = back->floorheight; - lowfloor = front->floorheight; + frontheight = P_GetCeilingZ(tmthing, front, tmthing->x, tmthing->y, linedef); + backheight = P_GetCeilingZ(tmthing, back, tmthing->x, tmthing->y, linedef); + + if (frontheight < backheight) + { + opentop = frontheight; + highceiling = backheight; + } + else + { + opentop = backheight; + highceiling = frontheight; + } + + frontheight = P_GetFloorZ(tmthing, front, tmthing->x, tmthing->y, linedef); + backheight = P_GetFloorZ(tmthing, back, tmthing->x, tmthing->y, linedef); + + if (frontheight > backheight) + { + openbottom = frontheight; + lowfloor = backheight; + } + else + { + openbottom = backheight; + lowfloor = frontheight; + } } if (tmthing) @@ -627,32 +637,6 @@ void P_LineOpening(line_t *linedef) openbottom = textop; } } -#ifdef ESLOPE - // I suspect the math here is wrong and we should be comparing the slope Zs - // if either are slopes. - // -- Fury - if (front->c_slope && front->ceilingheight < back->ceilingheight) - { - opentop = P_GetZAt(front->c_slope, tmthing->x, tmthing->y); - if (back->c_slope) highceiling = P_GetZAt(back->c_slope, tmthing->x, tmthing->y); - } - else if (back->c_slope && front->ceilingheight >= back->ceilingheight) - { - opentop = P_GetZAt(back->c_slope, tmthing->x, tmthing->y); - if (front->c_slope) highceiling = P_GetZAt(front->c_slope, tmthing->x, tmthing->y); - } - - if (front->f_slope && front->floorheight < back->floorheight) - { - openbottom = P_GetZAt(front->f_slope, tmthing->x, tmthing->y); - if (back->f_slope) lowfloor = P_GetZAt(back->f_slope, tmthing->x, tmthing->y); - } - if (back->f_slope && front->floorheight >= back->floorheight) - { - openbottom = P_GetZAt(back->f_slope, tmthing->x, tmthing->y); - if (front->f_slope) lowfloor = P_GetZAt(back->f_slope, tmthing->x, tmthing->y); - } -#endif // Check for fake floors in the sector. if (front->ffloors || back->ffloors @@ -889,14 +873,9 @@ void P_SetThingPosition(mobj_t *thing) ss = thing->subsector = R_PointInSubsector(thing->x, thing->y); fixed_t tfloorz, tceilz; - tfloorz = ss->sector->floorheight; - tceilz = ss->sector->ceilingheight; -#ifdef ESLOPE - if (ss->sector->f_slope) - tfloorz = P_GetZAt(ss->sector->f_slope, thing->x, thing->y); - if (ss->sector->c_slope) - tceilz = P_GetZAt(ss->sector->c_slope, thing->x, thing->y); -#endif + + tfloorz = P_GetFloorZ(thing, ss->sector, thing->x, thing->y, NULL); + tceilz = P_GetCeilingZ(thing, ss->sector, thing->x, thing->y, NULL); if (!(thing->flags & MF_NOSECTOR)) { diff --git a/src/p_spec.c b/src/p_spec.c index e33dd474c..fe3deba30 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4584,16 +4584,8 @@ static void P_RunSpecialSectorCheck(player_t *player, sector_t *sector) return; } - fixed_t f_affectpoint = sector->floorheight; - fixed_t c_affectpoint = sector->ceilingheight; - -#ifdef ESLOPE - if (sector->f_slope) - f_affectpoint = P_GetZAt(sector->f_slope, player->mo->x, player->mo->y); - - if (sector->c_slope) - c_affectpoint = P_GetZAt(sector->c_slope, player->mo->x, player->mo->y); -#endif + fixed_t f_affectpoint = P_GetFloorZ(player->mo, sector, player->mo->x, player->mo->y, NULL);//sector->floorheight; + fixed_t c_affectpoint = P_GetCeilingZ(player->mo, sector, player->mo->x, player->mo->y, NULL);//sector->ceilingheight; // Only go further if on the ground if ((sector->flags & SF_FLIPSPECIAL_FLOOR) && !(sector->flags & SF_FLIPSPECIAL_CEILING) && player->mo->z != f_affectpoint) From 10ba85087174a59c76b4934b61d21493caa50808 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Mon, 27 Apr 2015 14:07:04 -0500 Subject: [PATCH 18/91] Fix dynamic slopes not working right in some cases --- src/p_slopes.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/p_slopes.c b/src/p_slopes.c index efa15aed4..0a10901fc 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -64,15 +64,19 @@ void P_RunDynamicSlopes(void) { switch(slope->refpos) { case 1: // front floor zdelta = slope->sourceline->backsector->floorheight - slope->sourceline->frontsector->floorheight; + slope->o.z = slope->sourceline->frontsector->floorheight; break; case 2: // front ceiling zdelta = slope->sourceline->backsector->ceilingheight - slope->sourceline->frontsector->ceilingheight; + slope->o.z = slope->sourceline->frontsector->ceilingheight; break; case 3: // back floor zdelta = slope->sourceline->frontsector->floorheight - slope->sourceline->backsector->floorheight; + slope->o.z = slope->sourceline->backsector->floorheight; break; case 4: // back ceiling zdelta = slope->sourceline->frontsector->ceilingheight - slope->sourceline->backsector->ceilingheight; + slope->o.z = slope->sourceline->backsector->ceilingheight; break; default: From 776b5254e689e362276c815c7daad5d11f979c5c Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Wed, 29 Apr 2015 00:29:51 -0500 Subject: [PATCH 19/91] Slope collision fixes --- src/p_local.h | 2 ++ src/p_map.c | 22 ++++++++++++++++------ src/p_maputl.c | 8 ++++---- src/p_mobj.c | 26 ++++++++++++++++++++++++-- 4 files changed, 46 insertions(+), 12 deletions(-) diff --git a/src/p_local.h b/src/p_local.h index 53e5b18b4..c3e21dbe9 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -296,6 +296,8 @@ extern fixed_t tmfloorz; extern fixed_t tmceilingz; extern mobj_t *tmfloorthing, *tmthing; extern camera_t *mapcampointer; +extern fixed_t tmx; +extern fixed_t tmy; /* cphipps 2004/08/30 */ extern void P_MapStart(void); diff --git a/src/p_map.c b/src/p_map.c index 50f172798..31f0acc62 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -38,8 +38,8 @@ fixed_t tmbbox[4]; mobj_t *tmthing; static INT32 tmflags; -static fixed_t tmx; -static fixed_t tmy; +fixed_t tmx; +fixed_t tmy; static precipmobj_t *tmprecipthing; static fixed_t preciptmbbox[4]; @@ -1208,8 +1208,8 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) // that contains the point. // Any contacted lines the step closer together // will adjust them. - tmfloorz = tmdropoffz = P_GetFloorZ(thing, newsubsec->sector, thing->x, thing->y, NULL); //newsubsec->sector->floorheight; - tmceilingz = P_GetCeilingZ(thing, newsubsec->sector, thing->x, thing->y, NULL); //newsubsec->sector->ceilingheight; + tmfloorz = tmdropoffz = P_GetFloorZ(thing, newsubsec->sector, x, y, NULL); //newsubsec->sector->floorheight; + tmceilingz = P_GetCeilingZ(thing, newsubsec->sector, x, y, NULL); //newsubsec->sector->ceilingheight; // Check list of fake floors and see if tmfloorz/tmceilingz need to be altered. if (newsubsec->sector->ffloors) @@ -1945,13 +1945,23 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) { if (thingtop == thing->ceilingz && tmceilingz > thingtop && tmceilingz - thingtop <= maxstep) { - thing->z = tmceilingz - thing->height; + thing->z = (thing->ceilingz = thingtop = tmceilingz) - thing->height; + thing->eflags |= MFE_JUSTSTEPPEDDOWN; + } + else if (thingtop == thing->ceilingz && tmceilingz , thingtop && thingtop - tmceilingz <= maxstep) + { + thing->z = (thing->ceilingz = thingtop = tmceilingz) - thing->height; thing->eflags |= MFE_JUSTSTEPPEDDOWN; } } else if (thing->z == thing->floorz && tmfloorz < thing->z && thing->z - tmfloorz <= maxstep) { - thing->z = tmfloorz; + thing->z = thing->floorz = tmfloorz; + thing->eflags |= MFE_JUSTSTEPPEDDOWN; + } + else if (thing->z == thing->floorz && tmfloorz > thing->z && tmfloorz - thing->z <= maxstep) + { + thing->z = thing->floorz = tmfloorz; thing->eflags |= MFE_JUSTSTEPPEDDOWN; } } diff --git a/src/p_maputl.c b/src/p_maputl.c index 7641dd1eb..e9e0bb776 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -560,8 +560,8 @@ void P_LineOpening(line_t *linedef) { // Set open and high/low values here fixed_t frontheight, backheight; - frontheight = P_GetCeilingZ(tmthing, front, tmthing->x, tmthing->y, linedef); - backheight = P_GetCeilingZ(tmthing, back, tmthing->x, tmthing->y, linedef); + frontheight = P_GetCeilingZ(tmthing, front, tmx, tmy, linedef); + backheight = P_GetCeilingZ(tmthing, back, tmx, tmy, linedef); if (frontheight < backheight) { @@ -574,8 +574,8 @@ void P_LineOpening(line_t *linedef) highceiling = frontheight; } - frontheight = P_GetFloorZ(tmthing, front, tmthing->x, tmthing->y, linedef); - backheight = P_GetFloorZ(tmthing, back, tmthing->x, tmthing->y, linedef); + frontheight = P_GetFloorZ(tmthing, front, tmx, tmy, linedef); + backheight = P_GetFloorZ(tmthing, back, tmx, tmy, linedef); if (frontheight > backheight) { diff --git a/src/p_mobj.c b/src/p_mobj.c index 1be713bf4..d57e398ec 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -747,7 +747,7 @@ fixed_t P_GetFloorZ(mobj_t *mobj, sector_t *sector, fixed_t x, fixed_t y, line_t if (slope->zdelta > 0) { testx = -testx; - testx = -testy; + testy = -testy; } testx += x; @@ -775,6 +775,17 @@ fixed_t P_GetFloorZ(mobj_t *mobj, sector_t *sector, fixed_t x, fixed_t y, line_t v2.x = line->v2->x; v2.y = line->v2->y; + /*CONS_Printf("BEFORE: v1 = %f %f %f\n", + FIXED_TO_FLOAT(v1.x), + FIXED_TO_FLOAT(v1.y), + FIXED_TO_FLOAT(P_GetZAt(slope, v1.x, v1.y)) + ); + CONS_Printf(" v2 = %f %f %f\n", + FIXED_TO_FLOAT(v2.x), + FIXED_TO_FLOAT(v2.y), + FIXED_TO_FLOAT(P_GetZAt(slope, v2.x, v2.y)) + );*/ + if (abs(v1.x-x) > mobj->radius) { // v1's x is out of range, so rein it in fixed_t diff = abs(v1.x-x) - mobj->radius; @@ -827,6 +838,17 @@ fixed_t P_GetFloorZ(mobj_t *mobj, sector_t *sector, fixed_t x, fixed_t y, line_t } } + /*CONS_Printf("AFTER: v1 = %f %f %f\n", + FIXED_TO_FLOAT(v1.x), + FIXED_TO_FLOAT(v1.y), + FIXED_TO_FLOAT(P_GetZAt(slope, v1.x, v1.y)) + ); + CONS_Printf(" v2 = %f %f %f\n", + FIXED_TO_FLOAT(v2.x), + FIXED_TO_FLOAT(v2.y), + FIXED_TO_FLOAT(P_GetZAt(slope, v2.x, v2.y)) + );*/ + // Return the higher of the two points return max( P_GetZAt(slope, v1.x, v1.y), @@ -860,7 +882,7 @@ fixed_t P_GetCeilingZ(mobj_t *mobj, sector_t *sector, fixed_t x, fixed_t y, line if (slope->zdelta < 0) { testx = -testx; - testx = -testy; + testy = -testy; } testx += x; From de81d01fbc700afd115479faeb77bb4d648190fa Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Wed, 29 Apr 2015 00:30:39 -0500 Subject: [PATCH 20/91] Fixes to slope generation (backfloor crash and wrong zdelta/zangle) --- src/p_slopes.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/p_slopes.c b/src/p_slopes.c index 0a10901fc..518599849 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -85,7 +85,7 @@ void P_RunDynamicSlopes(void) { if (slope->zdelta != FixedDiv(zdelta, slope->extent)) { slope->zdeltaf = FIXED_TO_FLOAT(slope->zdelta = FixedDiv(zdelta, slope->extent)); - slope->zangle = R_PointToAngle2(0, 0, slope->extent, zdelta); + slope->zangle = R_PointToAngle2(0, 0, slope->extent, -zdelta); P_CalculateSlopeNormal(slope); } } @@ -233,7 +233,7 @@ void P_SpawnSlope_Line(int linenum) { point.z = line->frontsector->floorheight; // Startz - dz = FixedDiv(line->backsector->floorheight - point.z, extent); // Destinationz + dz = FixedDiv(origin.z - point.z, extent); // Destinationz // In P_SpawnSlopeLine the origin is the centerpoint of the sourcelinedef @@ -289,8 +289,9 @@ void P_SpawnSlope_Line(int linenum) } if(frontceil) { + origin.z = line->backsector->ceilingheight; point.z = line->frontsector->ceilingheight; - dz = FixedDiv(line->backsector->ceilingheight - point.z, extent); + dz = FixedDiv(origin.z - point.z, extent); cslope = line->frontsector->c_slope = P_MakeSlope(&point, &direction, dz, true); @@ -353,7 +354,7 @@ void P_SpawnSlope_Line(int linenum) if(backfloor) { point.z = line->backsector->floorheight; - dz = FixedDiv(line->frontsector->floorheight - point.z, extent); + dz = FixedDiv(origin.z - point.z, extent); fslope = line->backsector->f_slope = P_MakeSlope(&point, &direction, dz, true); @@ -386,15 +387,16 @@ void P_SpawnSlope_Line(int linenum) fslope->highz = highest; fslope->lowz = lowest; - cslope->zangle = R_PointToAngle2(0, origin.z, extent, point.z); - cslope->xydirection = R_PointToAngle2(origin.x, origin.y, point.x, point.y); + fslope->zangle = R_PointToAngle2(0, origin.z, extent, point.z); + fslope->xydirection = R_PointToAngle2(origin.x, origin.y, point.x, point.y); P_CalculateSlopeNormal(fslope); } if(backceil) { + origin.z = line->frontsector->ceilingheight; point.z = line->backsector->ceilingheight; - dz = FixedDiv(line->frontsector->ceilingheight - point.z, extent); + dz = FixedDiv(origin.z - point.z, extent); cslope = line->backsector->c_slope = P_MakeSlope(&point, &direction, dz, true); From 1f0f6b64c177904f8f5f284ceab1399707e3d067 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Wed, 29 Apr 2015 00:33:04 -0500 Subject: [PATCH 21/91] Store the slope an object is resting on (if applicable) --- src/p_local.h | 3 + src/p_map.c | 154 ++++++++++++++++++++++--------------------------- src/p_maputl.c | 19 +++++- src/p_maputl.h | 3 + src/p_mobj.h | 5 +- 5 files changed, 94 insertions(+), 90 deletions(-) diff --git a/src/p_local.h b/src/p_local.h index c3e21dbe9..2fd7bcbe2 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -298,6 +298,9 @@ extern mobj_t *tmfloorthing, *tmthing; extern camera_t *mapcampointer; extern fixed_t tmx; extern fixed_t tmy; +#ifdef ESLOPE +extern pslope_t *tmfloorslope, *tmceilingslope; +#endif /* cphipps 2004/08/30 */ extern void P_MapStart(void); diff --git a/src/p_map.c b/src/p_map.c index 31f0acc62..72b17473f 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -27,7 +27,7 @@ #include "r_splats.h" -#ifdef SPRINGCLEAN// ESLOPE +#ifdef ESLOPE #include "p_slopes.h" #endif @@ -52,6 +52,9 @@ fixed_t tmfloorz, tmceilingz; static fixed_t tmdropoffz, tmdrpoffceilz; // drop-off floor/ceiling heights mobj_t *tmfloorthing; // the thing corresponding to tmfloorz or NULL if tmfloorz is from a sector static mobj_t *tmhitthing; // the solid thing you bumped into (for collisions) +#ifdef ESLOPE +pslope_t *tmfloorslope, *tmceilingslope; +#endif // keep track of the line that lowers the ceiling, // so missiles don't explode against sky hack walls @@ -957,6 +960,9 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->z + thing->height > tmfloorz) { tmfloorz = thing->z + thing->height; +#ifdef ESLOPE + tmfloorslope = NULL; +#endif } return true; } @@ -975,6 +981,9 @@ static boolean PIT_CheckThing(mobj_t *thing) else if (topz < tmceilingz && tmthing->z+tmthing->height <= thing->z+thing->height) { tmceilingz = topz; +#ifdef ESLOPE + tmceilingslope = NULL; +#endif tmfloorthing = thing; // thing we may stand on } } @@ -988,6 +997,9 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->z < tmceilingz) { tmceilingz = thing->z; +#ifdef ESLOPE + tmceilingslope = NULL; +#endif } return true; } @@ -1005,6 +1017,9 @@ static boolean PIT_CheckThing(mobj_t *thing) else if (topz > tmfloorz && tmthing->z >= thing->z) { tmfloorz = topz; +#ifdef ESLOPE + tmfloorslope = NULL; +#endif tmfloorthing = thing; // thing we may stand on } } @@ -1127,11 +1142,13 @@ static boolean PIT_CheckLine(line_t *ld) { tmceilingz = opentop; ceilingline = ld; + tmceilingslope = opentopslope; } if (openbottom > tmfloorz) { tmfloorz = openbottom; + tmfloorslope = openbottomslope; } if (highceiling > tmdrpoffceilz) @@ -1210,6 +1227,10 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) // will adjust them. tmfloorz = tmdropoffz = P_GetFloorZ(thing, newsubsec->sector, x, y, NULL); //newsubsec->sector->floorheight; tmceilingz = P_GetCeilingZ(thing, newsubsec->sector, x, y, NULL); //newsubsec->sector->ceilingheight; +#ifdef ESLOPE + tmfloorslope = newsubsec->sector->f_slope; + tmceilingslope = newsubsec->sector->c_slope; +#endif // Check list of fake floors and see if tmfloorz/tmceilingz need to be altered. if (newsubsec->sector->ffloors) @@ -1252,13 +1273,21 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) // Land on the top or the bottom, depending on gravity flip. if (!(thing->eflags & MFE_VERTICALFLIP) && thing->z >= topheight - sinklevel && thing->momz <= 0) { - if (tmfloorz < topheight - sinklevel) + if (tmfloorz < topheight - sinklevel) { tmfloorz = topheight - sinklevel; +#ifdef ESLOPE + tmfloorslope = NULL; +#endif + } } else if (thing->eflags & MFE_VERTICALFLIP && thingtop <= bottomheight + sinklevel && thing->momz >= 0) { - if (tmceilingz > bottomheight + sinklevel) + if (tmceilingz > bottomheight + sinklevel) { tmceilingz = bottomheight + sinklevel; +#ifdef ESLOPE + tmceilingslope = NULL; +#endif + } } } continue; @@ -1277,8 +1306,12 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) { if (thing->z < topheight && bottomheight < thingtop) { - if (tmfloorz < thing->z) + if (tmfloorz < thing->z) { tmfloorz = thing->z; +#ifdef ESLOPE + tmfloorslope = NULL; +#endif + } } // Quicksand blocks never change heights otherwise. continue; @@ -1293,12 +1326,18 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) && !(rover->flags & FF_REVERSEPLATFORM)) { tmfloorz = tmdropoffz = topheight; +#ifdef ESLOPE + tmfloorslope = NULL; +#endif } if (bottomheight < tmceilingz && abs(delta1) >= abs(delta2) && !(rover->flags & FF_PLATFORM) && !(thing->type == MT_SKIM && (rover->flags & FF_SWIMMABLE))) { tmceilingz = tmdrpoffceilz = bottomheight; +#ifdef ESLOPE + tmceilingslope = NULL; +#endif } } } @@ -1371,11 +1410,19 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) delta1 = thing->z - (polybottom + ((polytop - polybottom)/2)); delta2 = thingtop - (polybottom + ((polytop - polybottom)/2)); - if (polytop > tmfloorz && abs(delta1) < abs(delta2)) + if (polytop > tmfloorz && abs(delta1) < abs(delta2)) { tmfloorz = tmdropoffz = polytop; +#ifdef ESLOPE + tmfloorslope = NULL; +#endif + } - if (polybottom < tmceilingz && abs(delta1) >= abs(delta2)) + if (polybottom < tmceilingz && abs(delta1) >= abs(delta2)) { tmceilingz = tmdrpoffceilz = polybottom; +#ifdef ESLOPE + tmceilingslope = NULL; +#endif + } } plink = (polymaplink_t *)(plink->link.next); } @@ -1824,6 +1871,10 @@ boolean PIT_PushableMoved(mobj_t *thing) mobj_t *oldthing = tmthing; line_t *oldceilline = ceilingline; line_t *oldblockline = blockingline; +#ifdef ESLOPE + pslope_t *oldfslope = tmfloorslope; + pslope_t *oldcslope = tmceilingslope; +#endif // Move the player P_TryMove(thing, thing->x+stand->momx, thing->y+stand->momy, true); @@ -1836,6 +1887,10 @@ boolean PIT_PushableMoved(mobj_t *thing) P_SetTarget(&tmthing, oldthing); ceilingline = oldceilline; blockingline = oldblockline; +#ifdef ESLOPE + tmfloorslope = oldfslope; + tmceilingslope = oldcslope; +#endif thing->momz = stand->momz; } else @@ -2030,88 +2085,17 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) // Link the thing into its new position P_UnsetThingPosition(thing); -#ifdef SRPINGCLEAN// ESLOPE - // By virtue of being derived from SRB2 code, Kalaron's physics are GPL. - if (P_IsObjectOnSlope(thing, false)) - { - fixed_t thingspeed = P_AproxDistance(thing->momx, thing->momy); - fixed_t predictmomx = x+(thing->momx/2); - fixed_t predictmomy = y+(thing->momy/2); - sector_t *nextsector = R_PointInSubsector(predictmomx, predictmomy)->sector; - sector_t *currentsector = R_PointInSubsector(thing->x, thing->y)->sector; - fixed_t zthrust = 0; - fixed_t slopeang = currentsector->f_slope->zangle; - fixed_t nextz = nextsector->floorheight; - if (nextsector->f_slope) - nextz = P_GetZAt(nextsector->f_slope, thing->x+predictmomx+thing->momx, thing->y+predictmomy+thing->momy); - - if (nextsector != currentsector) - { - // Give a boost up from the slope you came if the next sector is lower than the first - // If your next sector does not have a slope and you're comming off of one - if (currentsector->f_slope) - if (P_GetZAt(currentsector->f_slope, thing->x, thing->y)/FRACUNIT > (nextz/FRACUNIT)+(slopeang*3)) - //&& !nextsector->f_slope // TODO: VPHYSICS height check, not this hacky check? Or is this good enough? - if (currentsector->f_slope->zangle > 9) - { - fixed_t currentz = P_GetZAt(currentsector->f_slope, thing->x, thing->y); - fixed_t predictz = P_GetZAt(currentsector->f_slope, thing->x+thing->momx, thing->y+thing->momy); - - predictz += (((thing->pitchangle/(ANGLE_45/45))+90)/70.0f)+thingspeed/9; - - // Make sure that the z doesn't go too high for steep slopes - - predictz -= ((currentsector->f_slope->zangle)/4)*FRACUNIT; - if (currentsector->f_slope->zangle > 60) // really steep - { - predictz -= ((currentsector->f_slope->zangle)/2)*FRACUNIT; - } - - zthrust = (predictz - currentz)/2; - - if (zthrust > (30*thing->scale/100)*FRACUNIT) - zthrust = (30*thing->scale/100)*FRACUNIT; - - if (zthrust < -(30*thing->scale/100)*FRACUNIT) - zthrust = -(30*thing->scale/100)*FRACUNIT; - - if (currentz/FRACUNIT > (nextz/FRACUNIT)+(slopeang*3)) - { - // Now even out the momx/momy when catapulting off a steep slope - if (currentsector->f_slope->zangle > 65) - { - thing->momx /= 4.0f; - thing->momy /= 4.0f; - } - else if (currentsector->f_slope->zangle > 60) - { - thing->momx /= 3.5f; - thing->momy /= 3.5f; - } - else if (currentsector->f_slope->zangle > 50) - { - thing->momx /= 3.4f; - thing->momy /= 3.4f; - } - else if (currentsector->f_slope->zangle > 40) - { - thing->momx /= 3.3f; - thing->momy /= 3.3f; - } - } - - thing->momz += zthrust; // VPHYSICS TODO: Make a real formula for z trajectory going off a slope - /*CONS_Printf("CurZ %i, PredictZ %i\n", currentz/FRACUNIT, predictz/FRACUNIT); - CONS_Printf("Pitch: %i\n", thing->pitchangle/(ANG45/45)+90); - CONS_Printf("ZThrust: %i\n", zthrust/FRACUNIT);*/ - } - } - } -#endif - thing->floorz = tmfloorz; thing->ceilingz = tmceilingz; +#ifdef ESLOPE + // Assign thing's standingslope if needed + if (thing->z <= tmfloorz && thing->momz <= 0 && !(thing->eflags & MFE_VERTICALFLIP)) + thing->standingslope = tmfloorslope; + else if (thing->z+thing->height >= tmceilingz && thing->momz >= 0 && (thing->eflags & MFE_VERTICALFLIP)) + thing->standingslope = tmceilingslope; +#endif + thing->x = x; thing->y = y; diff --git a/src/p_maputl.c b/src/p_maputl.c index e9e0bb776..b5ac29507 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -325,6 +325,9 @@ fixed_t P_InterceptVector(divline_t *v2, divline_t *v1) // OPTIMIZE: keep this precalculated // fixed_t opentop, openbottom, openrange, lowfloor, highceiling; +#ifdef ESLOPE +pslope_t *opentopslope, *openbottomslope; +#endif // P_CameraLineOpening // P_LineOpening, but for camera @@ -567,11 +570,13 @@ void P_LineOpening(line_t *linedef) { opentop = frontheight; highceiling = backheight; + opentopslope = front->c_slope; } else { opentop = backheight; highceiling = frontheight; + opentopslope = back->c_slope; } frontheight = P_GetFloorZ(tmthing, front, tmx, tmy, linedef); @@ -581,11 +586,13 @@ void P_LineOpening(line_t *linedef) { openbottom = frontheight; lowfloor = backheight; + openbottomslope = front->f_slope; } else { openbottom = backheight; lowfloor = frontheight; + openbottomslope = back->f_slope; } } @@ -761,11 +768,19 @@ void P_LineOpening(line_t *linedef) if (highestceiling < highceiling) highceiling = highestceiling; - if (highestfloor > openbottom) + if (highestfloor > openbottom) { openbottom = highestfloor; +#ifdef ESLOPE + openbottomslope = NULL; +#endif + } - if (lowestceiling < opentop) + if (lowestceiling < opentop) { opentop = lowestceiling; +#ifdef ESLOPE + opentopslope = NULL; +#endif + } if (lowestfloor > lowfloor) lowfloor = lowestfloor; diff --git a/src/p_maputl.h b/src/p_maputl.h index 66f7db2db..7471899cc 100644 --- a/src/p_maputl.h +++ b/src/p_maputl.h @@ -55,6 +55,9 @@ void P_CreatePrecipSecNodeList(precipmobj_t *thing, fixed_t x,fixed_t y); boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y); extern fixed_t opentop, openbottom, openrange, lowfloor, highceiling; +#ifdef ESLOPE +extern pslope_t *opentopslope, *openbottomslope; +#endif void P_LineOpening(line_t *plinedef); diff --git a/src/p_mobj.h b/src/p_mobj.h index a9edc5047..0dc323d73 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -30,7 +30,7 @@ // For slope code, we need v3float_t #ifdef ESLOPE -#include "m_vector.h" +//#include "r_defs.h" #endif // @@ -358,8 +358,7 @@ typedef struct mobj_s INT32 cvmem; #ifdef ESLOPE - angle_t pitchangle; - v3float_t vector; + struct pslope_s *standingslope; // The slope that the object is standing on (shouldn't need synced in savegames, right?) #endif // WARNING: New fields must be added separately to savegame and Lua. From db883f6a23c9354d1f15e118d9b54fea7353ea7a Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Wed, 29 Apr 2015 00:35:54 -0500 Subject: [PATCH 22/91] Add a bunch of slope physics I know giant commits all at once like this are a bad thing, but too bad I worked without staging commits and now it's all here at once :) --- src/m_vector.c | 88 +++++++++++++++++++++++++------------------------- src/m_vector.h | 8 +++-- src/p_mobj.c | 71 +++++++++++++++++++++++++++++++++++++++- src/p_slopes.c | 63 ++++++++++++++++++++++++++++++++++++ src/p_slopes.h | 5 +++ 5 files changed, 187 insertions(+), 48 deletions(-) diff --git a/src/m_vector.c b/src/m_vector.c index 53b869adc..274a806a6 100644 --- a/src/m_vector.c +++ b/src/m_vector.c @@ -409,6 +409,50 @@ angles3d_t *M_VectorAlignTo(float Pitch, float Yaw, float Roll, v3float_t v, byt } +// +// RotateVector +// +// Rotates a vector around another vector +// +void M_VecRotate(v3fixed_t *rotVec, const v3fixed_t *axisVec, const angle_t angle) +{ + // Rotate the point (x,y,z) around the vector (u,v,w) + fixed_t ux = FixedMul(axisVec->x, rotVec->x); + fixed_t uy = FixedMul(axisVec->x, rotVec->y); + fixed_t uz = FixedMul(axisVec->x, rotVec->z); + fixed_t vx = FixedMul(axisVec->y, rotVec->x); + fixed_t vy = FixedMul(axisVec->y, rotVec->y); + fixed_t vz = FixedMul(axisVec->y, rotVec->z); + fixed_t wx = FixedMul(axisVec->z, rotVec->x); + fixed_t wy = FixedMul(axisVec->z, rotVec->y); + fixed_t wz = FixedMul(axisVec->z, rotVec->z); + fixed_t sa = FINESINE(angle>>ANGLETOFINESHIFT); + fixed_t ca = FINECOSINE(angle>>ANGLETOFINESHIFT); + fixed_t ua = ux+vy+wz; + fixed_t ax = FixedMul(axisVec->x,ua); + fixed_t ay = FixedMul(axisVec->y,ua); + fixed_t az = FixedMul(axisVec->z,ua); + fixed_t xs = FixedMul(axisVec->x,axisVec->x); + fixed_t ys = FixedMul(axisVec->y,axisVec->y); + fixed_t zs = FixedMul(axisVec->z,axisVec->z); + fixed_t bx = FixedMul(rotVec->x,ys+zs); + fixed_t by = FixedMul(rotVec->y,xs+zs); + fixed_t bz = FixedMul(rotVec->z,xs+ys); + fixed_t cx = FixedMul(axisVec->x,vy+wz); + fixed_t cy = FixedMul(axisVec->y,ux+wz); + fixed_t cz = FixedMul(axisVec->z,ux+vy); + fixed_t dx = FixedMul(bx-cx, ca); + fixed_t dy = FixedMul(by-cy, ca); + fixed_t dz = FixedMul(bz-cz, ca); + fixed_t ex = FixedMul(vz-wy, sa); + fixed_t ey = FixedMul(wx-uz, sa); + fixed_t ez = FixedMul(uy-vx, sa); + + rotVec->x = ax+dx+ex; + rotVec->y = ay+dy+ey; + rotVec->z = az+dz+ez; +} + @@ -977,50 +1021,6 @@ boolean FV_IntersectedPolygon(const fvector_t *vPoly, const fvector_t *vLine, co return false; } -// -// RotateVector -// -// Rotates a vector around another vector -// -void FV_Rotate(fvector_t *rotVec, const fvector_t *axisVec, const angle_t angle) -{ - // Rotate the point (x,y,z) around the vector (u,v,w) - fixed_t ux = FixedMul(axisVec->x, rotVec->x); - fixed_t uy = FixedMul(axisVec->x, rotVec->y); - fixed_t uz = FixedMul(axisVec->x, rotVec->z); - fixed_t vx = FixedMul(axisVec->y, rotVec->x); - fixed_t vy = FixedMul(axisVec->y, rotVec->y); - fixed_t vz = FixedMul(axisVec->y, rotVec->z); - fixed_t wx = FixedMul(axisVec->z, rotVec->x); - fixed_t wy = FixedMul(axisVec->z, rotVec->y); - fixed_t wz = FixedMul(axisVec->z, rotVec->z); - fixed_t sa = FINESINE(angle); - fixed_t ca = FINECOSINE(angle); - fixed_t ua = ux+vy+wz; - fixed_t ax = FixedMul(axisVec->x,ua); - fixed_t ay = FixedMul(axisVec->y,ua); - fixed_t az = FixedMul(axisVec->z,ua); - fixed_t xs = FixedMul(axisVec->x,axisVec->x); - fixed_t ys = FixedMul(axisVec->y,axisVec->y); - fixed_t zs = FixedMul(axisVec->z,axisVec->z); - fixed_t bx = FixedMul(rotVec->x,ys+zs); - fixed_t by = FixedMul(rotVec->y,xs+zs); - fixed_t bz = FixedMul(rotVec->z,xs+ys); - fixed_t cx = FixedMul(axisVec->x,vy+wz); - fixed_t cy = FixedMul(axisVec->y,ux+wz); - fixed_t cz = FixedMul(axisVec->z,ux+vy); - fixed_t dx = FixedMul(bx-cx, ca); - fixed_t dy = FixedMul(by-cy, ca); - fixed_t dz = FixedMul(bz-cz, ca); - fixed_t ex = FixedMul(vz-wy, sa); - fixed_t ey = FixedMul(wx-uz, sa); - fixed_t ez = FixedMul(uy-vx, sa); - - rotVec->x = ax+dx+ex; - rotVec->y = ay+dy+ey; - rotVec->z = az+dz+ez; -} - void FM_Rotate(fmatrix_t *dest, angle_t angle, fixed_t x, fixed_t y, fixed_t z) { #define M(row,col) dest->m[row * 4 + col] diff --git a/src/m_vector.h b/src/m_vector.h index 743a26023..37d30c746 100644 --- a/src/m_vector.h +++ b/src/m_vector.h @@ -1,4 +1,4 @@ -// Emacs style mode select -*- C++ -*- +// Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // Copyright(C) 2004 Stephen McGranahan @@ -7,12 +7,12 @@ // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. -// +// // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. -// +// // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA @@ -114,6 +114,8 @@ float M_VectorYaw(v3float_t v); float M_VectorPitch(v3float_t v); angles3d_t *M_VectorAlignTo(float Pitch, float Yaw, float Roll, v3float_t v, byte AngleAxis, float Rate); +void M_VecRotate(v3fixed_t *rotVec, const v3fixed_t *axisVec, const angle_t angle); + #endif diff --git a/src/p_mobj.c b/src/p_mobj.c index d57e398ec..e0e5cc9e9 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1239,7 +1239,11 @@ static void P_XYFriction(mobj_t *mo, fixed_t oldx, fixed_t oldy) } else if (abs(player->rmomx) < FixedMul(STOPSPEED, mo->scale) && abs(player->rmomy) < FixedMul(STOPSPEED, mo->scale) - && (!(player->cmd.forwardmove && !(twodlevel || mo->flags2 & MF2_TWOD)) && !player->cmd.sidemove && !(player->pflags & PF_SPINNING))) + && (!(player->cmd.forwardmove && !(twodlevel || mo->flags2 & MF2_TWOD)) && !player->cmd.sidemove && !(player->pflags & PF_SPINNING)) +#ifdef ESLOPE + && !(player->mo->standingslope && abs(player->mo->standingslope->zdelta) >= FRACUNIT/2) +#endif + ) { // if in a walking frame, stop moving if (player->panim == PA_WALK) @@ -1383,6 +1387,11 @@ void P_XYMovement(mobj_t *mo) fixed_t xmove, ymove; fixed_t oldx, oldy; // reducing bobbing/momentum on ice when up against walls boolean moved; +#ifdef ESLOPE + pslope_t *oldslope = NULL; + v3fixed_t slopemom; + fixed_t predictedz; +#endif I_Assert(mo != NULL); I_Assert(!P_MobjWasRemoved(mo)); @@ -1414,6 +1423,29 @@ void P_XYMovement(mobj_t *mo) oldx = mo->x; oldy = mo->y; +#ifdef ESLOPE + // adjust various things based on slope + if (mo->standingslope) { + if (!P_IsObjectOnGround(mo)) { // We fell off at some point? Do the twisty thing! + P_SlopeLaunch(mo); + xmove = mo->momx; + ymove = mo->momy; + } else { // Still on the ground. + slopemom.x = xmove; + slopemom.y = ymove; + slopemom.z = 0; + P_QuantizeMomentumToSlope(&slopemom, mo->standingslope); + + xmove = slopemom.x; + ymove = slopemom.y; + + predictedz = mo->z + slopemom.z; // We'll use this later... + + oldslope = mo->standingslope; + } + } +#endif + // Pushables can break some blocks if (CheckForBustableBlocks && mo->flags & MF_PUSHABLE) P_PushableCheckBustables(mo); @@ -1534,6 +1566,29 @@ void P_XYMovement(mobj_t *mo) if (P_MobjWasRemoved(mo)) // MF_SPECIAL touched a player! O_o;; return; +#ifdef ESLOPE + if (moved && oldslope) { // Check to see if we ran off + if (oldslope != mo->standingslope) { // First, compare different slopes + // Start by quantizing momentum on this slope + v3fixed_t test; + test.x = mo->momx; + test.y = mo->momy; + test.z = 0; + if (mo->standingslope) // Don't fuss with the rotation if we don't HAVE a slope + P_QuantizeMomentumToSlope(&test, mo->standingslope); + + // Now compare the Zs of the different quantizations + if (slopemom.z - test.z > 2*FRACUNIT) { // Allow for a bit of sticking - this value can be adjusted later + mo->standingslope = oldslope; + P_SlopeLaunch(mo); + } + } else if (predictedz-mo->z > 2*FRACUNIT) { // Now check if we were supposed to stick to this slope + mo->standingslope = oldslope; + P_SlopeLaunch(mo); + } + } +#endif + // Check the gravity status. P_CheckGravity(mo, false); @@ -1819,6 +1874,11 @@ static boolean P_ZMovement(mobj_t *mo) I_Assert(mo != NULL); I_Assert(!P_MobjWasRemoved(mo)); +#ifdef ESLOPE + if (mo->standingslope && !P_IsObjectOnGround(mo)) + P_SlopeLaunch(mo); +#endif + // Intercept the stupid 'fall through 3dfloors' bug if (mo->subsector->sector->ffloors) P_AdjustMobjFloorZ_FFloors(mo, mo->subsector->sector, 0); @@ -2231,6 +2291,11 @@ static void P_PlayerZMovement(mobj_t *mo) if (!mo->player) return; +#ifdef ESLOPE + if (mo->standingslope && !P_IsObjectOnGround(mo)) + P_SlopeLaunch(mo); +#endif + // Intercept the stupid 'fall through 3dfloors' bug if (mo->subsector->sector->ffloors) P_AdjustMobjFloorZ_FFloors(mo, mo->subsector->sector, 0); @@ -3183,6 +3248,10 @@ static void P_PlayerMobjThinker(mobj_t *mobj) P_MobjCheckWater(mobj); +#ifdef ESLOPE + P_ButteredSlope(mobj); +#endif + // momentum movement mobj->eflags &= ~MFE_JUSTSTEPPEDDOWN; diff --git a/src/p_slopes.c b/src/p_slopes.c index 518599849..6b6f147d9 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -768,6 +768,69 @@ float P_DistFromPlanef(const v3float_t *point, const v3float_t *pori, (point->z - pori->z) * pnormal->z; } +// +// P_QuantizeMomentumToSlope +// +// When given a vector, rotates it and aligns it to a slope +void P_QuantizeMomentumToSlope(v3fixed_t *momentum, pslope_t *slope) +{ + v3fixed_t axis; + axis.x = -slope->d.y; + axis.y = slope->d.x; + axis.z = 0; + + M_VecRotate(momentum, &axis, slope->zangle); +} + +// +// P_SlopeLaunch +// +// Handles slope ejection for objects +void P_SlopeLaunch(mobj_t *mo) +{ + // Double the pre-rotation Z, then halve the post-rotation Z. This reduces the + // vertical launch given from slopes while increasing the horizontal launch + // given. Good for SRB2's gravity and horizontal speeds. + v3fixed_t slopemom; + slopemom.x = mo->momx; + slopemom.y = mo->momy; + slopemom.z = mo->momz*2; + P_QuantizeMomentumToSlope(&slopemom, mo->standingslope); + + mo->momx = slopemom.x; + mo->momy = slopemom.y; + mo->momz = slopemom.z/2; + + CONS_Printf("Launched off of slope.\n"); + mo->standingslope = NULL; +} + +// https://yourlogicalfallacyis.com/slippery-slope +// Handles sliding down slopes, like if they were made of butter :) +void P_ButteredSlope(mobj_t *mo) +{ + fixed_t thrust; + + if (!mo->standingslope) + return; + + if (abs(mo->standingslope->zdelta) < FRACUNIT/2) + return; // Don't apply physics to slopes that aren't steep enough + + thrust = FINESINE(mo->standingslope->zangle>>ANGLETOFINESHIFT) * (mo->eflags & MFE_VERTICALFLIP ? 1 : -1); + + if (!(mo->player && (mo->player->pflags & PF_SPINNING))) { + if (mo->momx || mo->momy) // Slightly increase thrust based on the object's speed parallel to the slope direction + thrust = FixedMul(thrust, FRACUNIT+P_AproxDistance(mo->momx, mo->momy)/4); + // This solves the issue of being able to zigzag up steep slopes + } + + // Multiply by gravity + thrust = FixedMul(thrust, FRACUNIT/2); // TODO actually get this + + P_Thrust(mo, mo->standingslope->xydirection, thrust); +} + // EOF #endif // #ifdef ESLOPE diff --git a/src/p_slopes.h b/src/p_slopes.h index 8f408d6f0..f82d8a83d 100644 --- a/src/p_slopes.h +++ b/src/p_slopes.h @@ -76,6 +76,11 @@ float P_GetZAtf(pslope_t *slope, float x, float y); float P_DistFromPlanef(const v3float_t *point, const v3float_t *pori, const v3float_t *pnormal); +// Lots of physics-based bullshit +void P_QuantizeMomentumToSlope(v3fixed_t *momentum, pslope_t *slope); +void P_SlopeLaunch(mobj_t *mo); +void P_ButteredSlope(mobj_t *mo); + #endif // EOF From ae935a09554c3aac3a577ea7a628270d727179f1 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Wed, 29 Apr 2015 00:36:24 -0500 Subject: [PATCH 23/91] Stop rubbing my ass on the code long enough to fix reverse gravity --- src/p_map.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_map.c b/src/p_map.c index 72b17473f..468e2530a 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2003,7 +2003,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) thing->z = (thing->ceilingz = thingtop = tmceilingz) - thing->height; thing->eflags |= MFE_JUSTSTEPPEDDOWN; } - else if (thingtop == thing->ceilingz && tmceilingz , thingtop && thingtop - tmceilingz <= maxstep) + else if (thingtop == thing->ceilingz && tmceilingz < thingtop && thingtop - tmceilingz <= maxstep) { thing->z = (thing->ceilingz = thingtop = tmceilingz) - thing->height; thing->eflags |= MFE_JUSTSTEPPEDDOWN; From c4306b624d00499c148a69a8aa55b7d3c4381d94 Mon Sep 17 00:00:00 2001 From: "chi.miru" Date: Wed, 29 Apr 2015 02:36:18 -0400 Subject: [PATCH 24/91] Optimized R_DrawTiltedSpan_8 --- src/r_draw8.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 77 insertions(+), 2 deletions(-) diff --git a/src/r_draw8.c b/src/r_draw8.c index 86b06089e..25ca8f3bd 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -551,8 +551,8 @@ void R_DrawTiltedSpan_8(void) source = ds_source; colormap = ds_colormap; - // The "perfect" reference version of this routine. Pretty slow. - // Use it only to see how things are supposed to look. +#if 0 // The "perfect" reference version of this routine. Pretty slow. + // Use it only to see how things are supposed to look. i = 0; do { @@ -566,6 +566,81 @@ void R_DrawTiltedSpan_8(void) vz += ds_sv.x; } while (--width >= 0); } +#else +#define SPANSIZE 16 +#define INVSPAN 0.0625f + + double startz = 1.f/iz; + double startu = uz*startz; + double startv = vz*startz; + double izstep, uzstep, vzstep; + + izstep = ds_sz.x * SPANSIZE; + uzstep = ds_su.x * SPANSIZE; + vzstep = ds_sv.x * SPANSIZE; + //x1 = 0; + width++; + + while (width >= SPANSIZE) + { + iz += izstep; + uz += uzstep; + vz += vzstep; + + double endz = 1.f/iz; + double endu = uz*endz; + double endv = vz*endz; + UINT32 stepu = (INT64)((endu - startu) * INVSPAN); + UINT32 stepv = (INT64)((endv - startv) * INVSPAN); + u = (INT64)(startu) + viewx; + v = (INT64)(startv) + viewy; + + for (i = SPANSIZE-1; i >= 0; i--) + { + *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; + dest++; + u += stepu; + v += stepv; + } + startu = endu; + startv = endv; + width -= SPANSIZE; + } + if (width > 0) + { + if (width == 1) + { + u = (INT64)(startu); + v = (INT64)(startv); + *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; + } + else + { + double left = width; + iz += ds_sz.x * left; + uz += ds_su.x * left; + vz += ds_sv.x * left; + + double endz = 1.f/iz; + double endu = uz*endz; + double endv = vz*endz; + left = 1.f/left; + UINT32 stepu = (INT64)((endu - startu) * left); + UINT32 stepv = (INT64)((endv - startv) * left); + u = (INT64)(startu) + viewx; + v = (INT64)(startv) + viewy; + + for (; width != 0; width--) + { + *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; + dest++; + u += stepu; + v += stepv; + } + } + } +#endif +} #endif // ESLOPE /** \brief The R_DrawSplat_8 function From fe8a2ae6805727ad2660618e92c55a5a8c20b98f Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Wed, 29 Apr 2015 01:45:39 -0500 Subject: [PATCH 25/91] Fix compile error --- src/r_draw8.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/r_draw8.c b/src/r_draw8.c index 25ca8f3bd..fe218f3ba 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -565,7 +565,6 @@ void R_DrawTiltedSpan_8(void) uz += ds_su.x; vz += ds_sv.x; } while (--width >= 0); -} #else #define SPANSIZE 16 #define INVSPAN 0.0625f From 02d63aa011dbefa631ea0747b801f4732cfa3361 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Thu, 30 Apr 2015 00:32:44 -0500 Subject: [PATCH 26/91] Tweaks to slope physics + add accel rules for slopes Your acceleration vector parallel to the slope is reduced based on slope angle if it's going up the slope. The pull physics' momentum increase was toned down a bit to go along with this. Also, I removed the ifdefs for OLD_MOVEMENT_CODE because why should that be kept around? --- src/p_slopes.c | 14 +++--- src/p_user.c | 113 +++++++++++++++++-------------------------------- 2 files changed, 46 insertions(+), 81 deletions(-) diff --git a/src/p_slopes.c b/src/p_slopes.c index 6b6f147d9..5891756e8 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -801,7 +801,7 @@ void P_SlopeLaunch(mobj_t *mo) mo->momy = slopemom.y; mo->momz = slopemom.z/2; - CONS_Printf("Launched off of slope.\n"); + //CONS_Printf("Launched off of slope.\n"); mo->standingslope = NULL; } @@ -814,16 +814,14 @@ void P_ButteredSlope(mobj_t *mo) if (!mo->standingslope) return; - if (abs(mo->standingslope->zdelta) < FRACUNIT/2) + if (abs(mo->standingslope->zdelta) < FRACUNIT/3) return; // Don't apply physics to slopes that aren't steep enough - thrust = FINESINE(mo->standingslope->zangle>>ANGLETOFINESHIFT) * (mo->eflags & MFE_VERTICALFLIP ? 1 : -1); + thrust = FINESINE(mo->standingslope->zangle>>ANGLETOFINESHIFT) * 3 / 2 * (mo->eflags & MFE_VERTICALFLIP ? 1 : -1); - if (!(mo->player && (mo->player->pflags & PF_SPINNING))) { - if (mo->momx || mo->momy) // Slightly increase thrust based on the object's speed parallel to the slope direction - thrust = FixedMul(thrust, FRACUNIT+P_AproxDistance(mo->momx, mo->momy)/4); - // This solves the issue of being able to zigzag up steep slopes - } + if (mo->momx || mo->momy) // Slightly increase thrust based on the object's speed + thrust = FixedMul(thrust, FRACUNIT+P_AproxDistance(mo->momx, mo->momy)/16); + // This makes it harder to zigzag up steep slopes, as well as allows greater top speed when rolling down // Multiply by gravity thrust = FixedMul(thrust, FRACUNIT/2); // TODO actually get this diff --git a/src/p_user.c b/src/p_user.c index 66cdb5562..62022fccf 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4503,12 +4503,16 @@ static void P_3dMovement(player_t *player) angle_t dangle; // replaces old quadrants bits fixed_t normalspd = FixedMul(player->normalspeed, player->mo->scale); boolean analogmove = false; -#ifndef OLD_MOVEMENT_CODE fixed_t oldMagnitude, newMagnitude; +#ifdef ESLOPE + v3fixed_t totalthrust; + + totalthrust.x = totalthrust.y = 0; // I forget if this is needed + totalthrust.z = FRACUNIT*P_MobjFlip(player->mo); // A bit of extra push-back on slopes +#endif // ESLOPE // Get the old momentum; this will be needed at the end of the function! -SH oldMagnitude = R_PointToDist2(player->mo->momx - player->cmomx, player->mo->momy - player->cmomy, 0, 0); -#endif analogmove = P_AnalogMove(player); @@ -4685,17 +4689,10 @@ static void P_3dMovement(player_t *player) } movepushforward = FixedMul(movepushforward, player->mo->scale); -#ifdef OLD_MOVEMENT_CODE - if (player->speed < topspeed && mforward && cmd->forwardmove > 0) // Sonic's Speed - P_Thrust(player->mo, movepushangle, movepushforward); - else if (mforward && cmd->forwardmove < 0) - P_Thrust(player->mo, movepushangle, movepushforward); - else if (player->speed < topspeed && mbackward && cmd->forwardmove < 0) - P_Thrust(player->mo, movepushangle, movepushforward); - else if (mbackward && cmd->forwardmove > 0) - P_Thrust(player->mo, movepushangle, movepushforward); - else if (!mforward && !mbackward) - P_Thrust(player->mo, movepushangle, movepushforward); + +#ifdef ESLOPE + totalthrust.x += P_ReturnThrustX(player->mo, movepushangle, movepushforward); + totalthrust.y += P_ReturnThrustY(player->mo, movepushangle, movepushforward); #else P_Thrust(player->mo, movepushangle, movepushforward); #endif @@ -4714,33 +4711,12 @@ static void P_3dMovement(player_t *player) if (!(player->pflags & PF_GLIDING || player->exiting || P_PlayerInPain(player))) { angle_t controldirection; -#ifdef OLD_MOVEMENT_CODE - angle_t controlplayerdirection; - boolean cforward; // controls pointing forward from the player - boolean cbackward; // controls pointing backward from the player - angle_t dangle; - cforward = cbackward = false; -#endif // Calculate the angle at which the controls are pointing // to figure out the proper mforward and mbackward. // (Why was it so complicated before? ~Red) controldirection = R_PointToAngle2(0, 0, cmd->forwardmove*FRACUNIT, -cmd->sidemove*FRACUNIT)+movepushangle; -#ifdef OLD_MOVEMENT_CODE - controlplayerdirection = player->mo->angle; - - dangle = controldirection - controlplayerdirection; - - if (dangle > ANGLE_180) //flip to keep to one side - dangle = InvAngle(dangle); - - if (dangle > ANGLE_90) - cbackward = true; // Controls pointing backwards from player - else - cforward = true; // Controls pointing in player's general direction -#endif - movepushforward = max(abs(cmd->sidemove), abs(cmd->forwardmove)) * (thrustfactor * acceleration); // allow very small movement while in air for gameplay @@ -4763,13 +4739,10 @@ static void P_3dMovement(player_t *player) movepushsideangle = controldirection; movepushforward = FixedMul(movepushforward, player->mo->scale); -#ifdef OLD_MOVEMENT_CODE - if (player->speed < topspeed) - P_Thrust(player->mo, controldirection, movepushforward); - else if ((mforward) && (cbackward)) - P_Thrust(player->mo, controldirection, movepushforward); - else if ((mbackward) && (cforward)) - P_Thrust(player->mo, controldirection, movepushforward); + +#ifdef ESLOPE + totalthrust.x += P_ReturnThrustX(player->mo, controldirection, movepushforward); + totalthrust.y += P_ReturnThrustY(player->mo, controldirection, movepushforward); #else P_Thrust(player->mo, controldirection, movepushforward); #endif @@ -4777,29 +4750,6 @@ static void P_3dMovement(player_t *player) } else if (cmd->sidemove && !(player->pflags & PF_GLIDING) && !player->exiting && !P_PlayerInPain(player)) { -#ifdef OLD_MOVEMENT_CODE - boolean mright = 0; - boolean mleft = 0; - angle_t sideangle; - - sideangle = player->mo->angle - ANGLE_90; - - // Monster Iestyn - 04-11-13 - // Quadrants are stupid, excessive and broken, let's do this a much simpler way! - // Get delta angle from rmom angle and player angle first - dangle = R_PointToAngle2(0,0, player->rmomx, player->rmomy) - sideangle; - if (dangle > ANGLE_180) - dangle = InvAngle(dangle); - - // now use it to determine direction! - if (dangle <= ANGLE_45) // angles 0-45 or 315-360 - mright = 1; // going right - else if (dangle >= ANGLE_135) // angles 135-225 - mleft = 1; // going left - - // anything else will leave both at 0, so no need to do anything else -#endif - movepushside = cmd->sidemove * (thrustfactor * acceleration); if (!onground) @@ -4822,19 +4772,37 @@ static void P_3dMovement(player_t *player) // Finally move the player now that his speed/direction has been decided. movepushside = FixedMul(movepushside, player->mo->scale); -#ifdef OLD_MOVEMENT_CODE - if (player->speed < topspeed) - P_Thrust(player->mo, movepushsideangle, movepushside); - else if (mright && cmd->sidemove < 0) - P_Thrust(player->mo, movepushsideangle, movepushside); - else if (mleft && cmd->sidemove > 0) - P_Thrust(player->mo, movepushsideangle, movepushside); + +#ifdef ESLOPE + totalthrust.x += P_ReturnThrustX(player->mo, movepushsideangle, movepushside); + totalthrust.y += P_ReturnThrustY(player->mo, movepushsideangle, movepushside); #else P_Thrust(player->mo, movepushsideangle, movepushside); #endif } -#ifndef OLD_MOVEMENT_CODE +#ifdef ESLOPE + if ((totalthrust.x || totalthrust.y) + && player->mo->standingslope && abs(player->mo->standingslope->zdelta) > FRACUNIT/2) { + // Factor thrust to slope, but only for the part pushing up it! + // The rest is unaffected. + angle_t thrustangle = R_PointToAngle2(0, 0, totalthrust.x, totalthrust.y)-player->mo->standingslope->xydirection; + + if (player->mo->standingslope->zdelta < 0) { // Direction goes down, so thrustangle needs to face toward + if (thrustangle < ANGLE_90 || thrustangle > ANGLE_270) { + P_QuantizeMomentumToSlope(&totalthrust, player->mo->standingslope); + } + } else { // Direction goes up, so thrustangle needs to face away + if (thrustangle > ANGLE_90 && thrustangle < ANGLE_270) { + P_QuantizeMomentumToSlope(&totalthrust, player->mo->standingslope); + } + } + } + + player->mo->momx += totalthrust.x; + player->mo->momy += totalthrust.y; +#endif + // Time to ask three questions: // 1) Are we over topspeed? // 2) If "yes" to 1, were we moving over topspeed to begin with? @@ -4868,7 +4836,6 @@ static void P_3dMovement(player_t *player) player->mo->momy = tempmomy + player->cmomy; } } -#endif } // From 234f734fe56529fd1ba8b33da11b94d5a6ae5e12 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Thu, 30 Apr 2015 00:38:51 -0500 Subject: [PATCH 27/91] Fix sprite clipping and some blocking walls being rendered around slopes --- src/r_bsp.c | 5 ++ src/r_segs.c | 157 +++++++++++++++++++++++++++++++-------------------- 2 files changed, 102 insertions(+), 60 deletions(-) diff --git a/src/r_bsp.c b/src/r_bsp.c index 01d2be671..ae4e8ac67 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -459,6 +459,11 @@ static void R_AddLine(seg_t *line) doorclosed = 0; // Closed door. +#ifdef ESLOPE + // Just don't bother checking this if one side is sloped. This is probably inefficient, but it's better than + // random renderer stopping around slopes... + if (!(frontsector->f_slope || frontsector->c_slope || backsector->f_slope || backsector->c_slope)) +#endif if (backsector->ceilingheight <= frontsector->floorheight || backsector->floorheight >= frontsector->ceilingheight) { diff --git a/src/r_segs.c b/src/r_segs.c index c313c955c..6c8c95c49 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -1659,64 +1659,6 @@ void R_StoreWallRange(INT32 start, INT32 stop) else { // two sided line - ds_p->sprtopclip = ds_p->sprbottomclip = NULL; - ds_p->silhouette = 0; - - if (frontsector->floorheight > backsector->floorheight) - { - ds_p->silhouette = SIL_BOTTOM; - ds_p->bsilheight = frontsector->floorheight; - } - else if (backsector->floorheight > viewz) - { - ds_p->silhouette = SIL_BOTTOM; - ds_p->bsilheight = INT32_MAX; - // ds_p->sprbottomclip = negonearray; - } - - if (frontsector->ceilingheight < backsector->ceilingheight) - { - ds_p->silhouette |= SIL_TOP; - ds_p->tsilheight = frontsector->ceilingheight; - } - else if (backsector->ceilingheight < viewz) - { - ds_p->silhouette |= SIL_TOP; - ds_p->tsilheight = INT32_MIN; - // ds_p->sprtopclip = screenheightarray; - } - - if (backsector->ceilingheight <= frontsector->floorheight) - { - ds_p->sprbottomclip = negonearray; - ds_p->bsilheight = INT32_MAX; - ds_p->silhouette |= SIL_BOTTOM; - } - - if (backsector->floorheight >= frontsector->ceilingheight) - { - ds_p->sprtopclip = screenheightarray; - ds_p->tsilheight = INT32_MIN; - ds_p->silhouette |= SIL_TOP; - } - - //SoM: 3/25/2000: This code fixes an automap bug that didn't check - // frontsector->ceiling and backsector->floor to see if a door was closed. - // Without the following code, sprites get displayed behind closed doors. - { - if (doorclosed || backsector->ceilingheight <= frontsector->floorheight) - { - ds_p->sprbottomclip = negonearray; - ds_p->bsilheight = INT32_MAX; - ds_p->silhouette |= SIL_BOTTOM; - } - if (doorclosed || backsector->floorheight >= frontsector->ceilingheight) - { // killough 1/17/98, 2/8/98 - ds_p->sprtopclip = screenheightarray; - ds_p->tsilheight = INT32_MIN; - ds_p->silhouette |= SIL_TOP; - } - } #ifdef ESLOPE if (backsector->c_slope) { @@ -1754,6 +1696,101 @@ void R_StoreWallRange(INT32 start, INT32 stop) worldtop = worldhigh; } + ds_p->sprtopclip = ds_p->sprbottomclip = NULL; + ds_p->silhouette = 0; + + if ( +#ifdef ESLOPE + worldbottomslope > worldlowslope || +#endif + worldbottom > worldlow) + { + ds_p->silhouette = SIL_BOTTOM; +#ifdef ESLOPE + ds_p->bsilheight = (frontsector->f_slope ? INT32_MAX : frontsector->floorheight); +#else + ds_p->bsilheight = frontsector->floorheight; +#endif + } +#ifdef ESLOPE + else if ((backsector->f_slope ? P_GetZAt(backsector->f_slope, viewx, viewy) : backsector->floorheight) > viewz) +#else + else if (backsector->floorheight > viewz) +#endif + { + ds_p->silhouette = SIL_BOTTOM; + ds_p->bsilheight = INT32_MAX; + // ds_p->sprbottomclip = negonearray; + } + + if ( +#ifdef ESLOPE + worldtopslope < worldhighslope || +#endif + worldtop < worldhigh) + { + ds_p->silhouette |= SIL_TOP; +#ifdef ESLOPE + ds_p->tsilheight = (frontsector->c_slope ? INT32_MIN : frontsector->ceilingheight); +#else + ds_p->tsilheight = frontsector->ceilingheight; +#endif + } +#ifdef ESLOPE + else if ((backsector->c_slope ? P_GetZAt(backsector->c_slope, viewx, viewy) : backsector->ceilingheight) < viewz) +#else + else if (backsector->ceilingheight < viewz) +#endif + { + ds_p->silhouette |= SIL_TOP; + ds_p->tsilheight = INT32_MIN; + // ds_p->sprtopclip = screenheightarray; + } + +#ifdef ESLOPE + if (worldhigh <= worldbottom && worldhighslope <= worldbottomslope) +#else + if (worldhigh <= worldbottom) +#endif + { + ds_p->sprbottomclip = negonearray; + ds_p->bsilheight = INT32_MAX; + ds_p->silhouette |= SIL_BOTTOM; + } + +#ifdef ESLOPE + if (worldlow >= worldtop && worldlowslope >= worldtopslope) +#else + if (worldlow >= worldtop) +#endif + { + ds_p->sprtopclip = screenheightarray; + ds_p->tsilheight = INT32_MIN; + ds_p->silhouette |= SIL_TOP; + } + +#ifdef ESLOPE + // This causes issues with slopes. + if (!(frontsector->f_slope || frontsector->c_slope || backsector->f_slope || backsector->c_slope)) +#endif + //SoM: 3/25/2000: This code fixes an automap bug that didn't check + // frontsector->ceiling and backsector->floor to see if a door was closed. + // Without the following code, sprites get displayed behind closed doors. + { + if (doorclosed || backsector->ceilingheight <= frontsector->floorheight) + { + ds_p->sprbottomclip = negonearray; + ds_p->bsilheight = INT32_MAX; + ds_p->silhouette |= SIL_BOTTOM; + } + if (doorclosed || backsector->floorheight >= frontsector->ceilingheight) + { // killough 1/17/98, 2/8/98 + ds_p->sprtopclip = screenheightarray; + ds_p->tsilheight = INT32_MIN; + ds_p->silhouette |= SIL_TOP; + } + } + if (worldlow != worldbottom #ifdef ESLOPE || worldlowslope != worldbottomslope @@ -1816,7 +1853,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) // check TOP TEXTURE if (worldhigh < worldtop #ifdef ESLOPE - || worldhighslope < worldtopslope + /*-(FRACUNIT>>8)*/|| worldhighslope < worldtopslope/*-(FRACUNIT>>8)*/ #endif ) { @@ -1863,7 +1900,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) // check BOTTOM TEXTURE if (worldlow > worldbottom #ifdef ESLOPE - || worldlowslope > worldbottomslope + /*+(FRACUNIT>>8)*/ || worldlowslope > worldbottomslope/*+(FRACUNIT>>8)*/ // The leeway works around a weird rendering bug with slopes... #endif ) //seulement si VISIBLE!!! { From 3644d4d883a3ee787546f439617ced579722a811 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Thu, 30 Apr 2015 00:41:29 -0500 Subject: [PATCH 28/91] Minor code cleanup around renderer gunk (Who let that silhouette == 1/etc thing sit there all those years? :V) --- src/r_segs.c | 33 ++++----------------------------- src/r_things.c | 6 +++--- 2 files changed, 7 insertions(+), 32 deletions(-) diff --git a/src/r_segs.c b/src/r_segs.c index 6c8c95c49..5465e0d07 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -1512,27 +1512,14 @@ void R_StoreWallRange(INT32 start, INT32 stop) // Figure out map coordinates of where start and end are mapping to on seg, so we can clip right for slope bullshit if (frontsector->c_slope || frontsector->f_slope || (backsector && (backsector->c_slope || backsector->f_slope))) { angle_t temp; - fixed_t tan; // left temp = xtoviewangle[start]+viewangle; - /*if (curline->v1->x == curline->v2->x) { - // Line seg is vertical, so no line-slope form for it - tan = FINETANGENT((temp+ANGLE_90)>>ANGLETOFINESHIFT); - - segleft.x = curline->v1->x; - - segleft.y = curline->v1->y-FixedMul(viewx-segleft.x, tan); - } else if (temp>>ANGLETOFINESHIFT == ANGLE_90>>ANGLETOFINESHIFT || temp>>ANGLETOFINESHIFT == ANGLE_270>>ANGLETOFINESHIFT) { - // Same problem as above, except this time with the view angle - tan = FixedDiv(curline->v2->y-curline->v1->y, curline->v2->x-curline->v1->x); - - segleft.x = viewx; - segleft.y = curline->v1->y-FixedMul(viewx-curline->v1->x, tan); - } else */{ + { // Both lines can be written in slope-intercept form, so figure out line intersection float a1, b1, c1, a2, b2, c2, det; // 1 is the seg, 2 is the view angle vector... + ///TODO: convert to FPU a1 = FIXED_TO_FLOAT(curline->v2->y-curline->v1->y); b1 = FIXED_TO_FLOAT(curline->v1->x-curline->v2->x); @@ -1551,22 +1538,10 @@ void R_StoreWallRange(INT32 start, INT32 stop) // right temp = xtoviewangle[stop]+viewangle; - /*if (curline->v1->x == curline->v2->x) { - // Line seg is vertical, so no line-slope form for it - tan = FINETANGENT((temp+ANGLE_90)>>ANGLETOFINESHIFT); - - segright.x = curline->v1->x; - - segright.y = curline->v1->y-FixedMul(viewx-segright.x, tan); - } else if (temp>>ANGLETOFINESHIFT == ANGLE_90>>ANGLETOFINESHIFT || temp>>ANGLETOFINESHIFT == ANGLE_270>>ANGLETOFINESHIFT) { - // Same problem as above, except this time with the view angle - tan = FixedDiv(curline->v2->y-curline->v1->y, curline->v2->x-curline->v1->x); - - segright.x = viewx; - segright.y = curline->v1->y-FixedMul(viewx-curline->v1->x, tan); - } else */{ + { // Both lines can be written in slope-intercept form, so figure out line intersection float a1, b1, c1, a2, b2, c2, det; // 1 is the seg, 2 is the view angle vector... + ///TODO: convert to FPU a1 = FIXED_TO_FLOAT(curline->v2->y-curline->v1->y); b1 = FIXED_TO_FLOAT(curline->v1->x-curline->v2->x); diff --git a/src/r_things.c b/src/r_things.c index f1b2e7199..a759dd1d0 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2030,21 +2030,21 @@ void R_ClipSprites(void) if (spr->gzt <= ds->tsilheight) silhouette &= ~SIL_TOP; - if (silhouette == 1) + if (silhouette == SIL_BOTTOM) { // bottom sil for (x = r1; x <= r2; x++) if (spr->clipbot[x] == -2) spr->clipbot[x] = ds->sprbottomclip[x]; } - else if (silhouette == 2) + else if (silhouette == SIL_TOP) { // top sil for (x = r1; x <= r2; x++) if (spr->cliptop[x] == -2) spr->cliptop[x] = ds->sprtopclip[x]; } - else if (silhouette == 3) + else if (silhouette == (SIL_TOP|SIL_BOTTOM)) { // both for (x = r1; x <= r2; x++) From 79fedf91a0e2592d0ffdfe5c9a5ffc0d5627093c Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Thu, 30 Apr 2015 18:36:21 -0500 Subject: [PATCH 29/91] Fix occasionally running into an invisible wall around slopes --- src/p_mobj.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index e0e5cc9e9..5af7b99a6 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -754,10 +754,7 @@ fixed_t P_GetFloorZ(mobj_t *mobj, sector_t *sector, fixed_t x, fixed_t y, line_t testy += y; // If the highest point is in the sector, then we have it easy! Just get the Z at that point - if (R_PointInSubsector(testx, testy)->sector == sector - // The following line is a hack to fix a bug where an object pops down on the frame its highest corner re-enters the sloped sector. - || R_PointInSubsector(testx+mobj->momx, testy+mobj->momy)->sector == sector - ) + if (R_PointInSubsector(testx, testy)->sector == sector) return P_GetZAt(slope, testx, testy); // If we're just testing for base sector location (no collision line), just go for the center's spot... @@ -889,10 +886,7 @@ fixed_t P_GetCeilingZ(mobj_t *mobj, sector_t *sector, fixed_t x, fixed_t y, line testy += y; // If the lowest point is in the sector, then we have it easy! Just get the Z at that point - if (R_PointInSubsector(testx, testy)->sector == sector - // The following line is a hack to fix a bug where an object pops down on the frame its highest corner re-enters the sloped sector. - || R_PointInSubsector(testx+mobj->momx, testy+mobj->momy)->sector == sector - ) + if (R_PointInSubsector(testx, testy)->sector == sector) return P_GetZAt(slope, testx, testy); // If we're just testing for base sector location (no collision line), just go for the center's spot... From c66bb1c330d15d8ac6fba0c8b564319d42e3a24b Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Sun, 3 May 2015 15:47:40 -0500 Subject: [PATCH 30/91] Make textures skew according to slope (midtextures not fixed yet) --- src/r_segs.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/src/r_segs.c b/src/r_segs.c index 5465e0d07..490051eea 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -52,6 +52,7 @@ static fixed_t rw_midtexturemid, rw_toptexturemid, rw_bottomtexturemid; static INT32 worldtop, worldbottom, worldhigh, worldlow; #ifdef ESLOPE static INT32 worldtopslope, worldbottomslope, worldhighslope, worldlowslope; // worldtop/bottom at end of slope +static fixed_t rw_toptextureslide, rw_midtextureslide, rw_bottomtextureslide; // Defines how to adjust Y offsets along the wall for slopes #endif static fixed_t pixhigh, pixlow, pixhighstep, pixlowstep; static fixed_t topfrac, topstep; @@ -1064,6 +1065,7 @@ static void R_RenderSegLoop (void) INT32 mid; fixed_t texturecolumn = 0; + fixed_t oldtexturecolumn = -1; INT32 top; INT32 bottom; INT32 i; @@ -1200,6 +1202,16 @@ static void R_RenderSegLoop (void) // calculate texture offset angle = (rw_centerangle + xtoviewangle[rw_x])>>ANGLETOFINESHIFT; texturecolumn = rw_offset-FixedMul(FINETANGENT(angle),rw_distance); + +#ifdef ESLOPE + if (oldtexturecolumn != -1) { + rw_bottomtexturemid += FixedMul(rw_bottomtextureslide, oldtexturecolumn-texturecolumn); + rw_midtexturemid += FixedMul(rw_midtextureslide, oldtexturecolumn-texturecolumn); + rw_toptexturemid += FixedMul(rw_toptextureslide, oldtexturecolumn-texturecolumn); + } + oldtexturecolumn = texturecolumn; +#endif + texturecolumn >>= FRACBITS; // texturecolumn and lighting are independent of wall tiers @@ -1407,6 +1419,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) r_lightlist_t *rlight; #ifdef ESLOPE vertex_t segleft, segright; + fixed_t ceilingfrontslide, floorfrontslide, ceilingbackslide, floorbackslide; #endif static size_t maxdrawsegs = 0; @@ -1605,6 +1618,28 @@ void R_StoreWallRange(INT32 start, INT32 stop) } } +#ifdef ESLOPE + // Set up texture Y offset slides for sloped walls + rw_toptextureslide = rw_midtextureslide = rw_bottomtextureslide = 0; + ceilingfrontslide = floorfrontslide = ceilingbackslide = floorbackslide = 0; + + { + angle_t lineangle = R_PointToAngle2(curline->v1->x, curline->v1->y, curline->v2->x, curline->v2->y); + + if (frontsector->f_slope) + floorfrontslide = FixedMul(frontsector->f_slope->zdelta, FINECOSINE((lineangle-frontsector->f_slope->xydirection)>>ANGLETOFINESHIFT)); + + if (frontsector->c_slope) + ceilingfrontslide = FixedMul(frontsector->c_slope->zdelta, FINECOSINE((lineangle-frontsector->c_slope->xydirection)>>ANGLETOFINESHIFT)); + + if (backsector && backsector->f_slope) + floorbackslide = FixedMul(backsector->f_slope->zdelta, FINECOSINE((lineangle-backsector->f_slope->xydirection)>>ANGLETOFINESHIFT)); + + if (backsector && backsector->c_slope) + ceilingbackslide = FixedMul(backsector->c_slope->zdelta, FINECOSINE((lineangle-backsector->c_slope->xydirection)>>ANGLETOFINESHIFT)); + } +#endif + if (!backsector) { // single sided line @@ -1614,14 +1649,22 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (linedef->flags & ML_DONTPEGBOTTOM) { +#ifdef ESLOPE + rw_midtexturemid = worldbottom + textureheight[sidedef->midtexture]; + rw_midtextureslide = floorfrontslide; +#else vtop = frontsector->floorheight + textureheight[sidedef->midtexture]; // bottom of texture at bottom rw_midtexturemid = vtop - viewz; +#endif } else { // top of texture at top rw_midtexturemid = worldtop; +#ifdef ESLOPE + rw_midtextureslide = ceilingfrontslide; +#endif } rw_midtexturemid += sidedef->rowoffset; @@ -1847,12 +1890,20 @@ void R_StoreWallRange(INT32 start, INT32 stop) { // top of texture at top rw_toptexturemid = worldtop; +#ifdef ESLOPE + rw_toptextureslide = ceilingfrontslide; +#endif } else { +#ifdef ESLOPE + rw_toptexturemid = worldhigh + textureheight[def->toptexture]; + rw_toptextureslide = ceilingbackslide; +#else vtop = backsector->ceilingheight + textureheight[def->toptexture]; // bottom of texture rw_toptexturemid = vtop - viewz; +#endif } } else @@ -1863,12 +1914,20 @@ void R_StoreWallRange(INT32 start, INT32 stop) { // top of texture at top rw_toptexturemid = worldtop; +#ifdef ESLOPE + rw_toptextureslide = ceilingfrontslide; +#endif } else { +#ifdef ESLOPE + rw_toptexturemid = worldhigh + textureheight[sidedef->toptexture]; + rw_toptextureslide = ceilingbackslide; +#else vtop = backsector->ceilingheight + textureheight[sidedef->toptexture]; // bottom of texture rw_toptexturemid = vtop - viewz; +#endif } } } @@ -1887,9 +1946,16 @@ void R_StoreWallRange(INT32 start, INT32 stop) // bottom of texture at bottom // top of texture at top rw_bottomtexturemid = worldtop; +#ifdef ESLOPE + rw_bottomtextureslide = floorfrontslide; +#endif } - else // top of texture at top + else { // top of texture at top rw_bottomtexturemid = worldlow; +#ifdef ESLOPE + rw_bottomtextureslide = floorbackslide; +#endif + } } rw_toptexturemid += sidedef->rowoffset; From 1b9180111ce60986902ad622672174e06d035627 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Mon, 4 May 2015 15:15:57 -0500 Subject: [PATCH 31/91] Pin midtextures based on slopes, including bending on wall crossing --- src/r_defs.h | 3 +++ src/r_segs.c | 47 ++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/src/r_defs.h b/src/r_defs.h index f2ae0ba8b..9a9679d4a 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -661,6 +661,9 @@ typedef struct drawseg_s INT16 *thicksidecol; INT32 numthicksides; fixed_t frontscale[MAXVIDWIDTH]; +#ifdef ESLOPE + fixed_t maskedtextureheight[MAXVIDWIDTH]; // For handling sloped midtextures +#endif } drawseg_t; typedef enum diff --git a/src/r_segs.c b/src/r_segs.c index 490051eea..b96731c95 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -53,6 +53,7 @@ static INT32 worldtop, worldbottom, worldhigh, worldlow; #ifdef ESLOPE static INT32 worldtopslope, worldbottomslope, worldhighslope, worldlowslope; // worldtop/bottom at end of slope static fixed_t rw_toptextureslide, rw_midtextureslide, rw_bottomtextureslide; // Defines how to adjust Y offsets along the wall for slopes +static fixed_t rw_midtextureback, rw_midtexturebackslide; // Values for masked midtexture height calculation #endif static fixed_t pixhigh, pixlow, pixhighstep, pixlowstep; static fixed_t topfrac, topstep; @@ -60,6 +61,9 @@ static fixed_t bottomfrac, bottomstep; static lighttable_t **walllights; static INT16 *maskedtexturecol; +#ifdef ESLOPE +static fixed_t *maskedtextureheight = NULL; +#endif // ========================================================================== // R_Splats Wall Splats Drawer @@ -478,6 +482,8 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep; } + +#ifndef ESLOPE if (curline->linedef->flags & ML_DONTPEGBOTTOM) { dc_texturemid = front->floorheight > back->floorheight @@ -496,12 +502,21 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) dc_texturemid += (textureheight[texnum])*times; else dc_texturemid -= (textureheight[texnum])*times; +#endif dc_texheight = textureheight[texnum]>>FRACBITS; // draw the columns for (dc_x = x1; dc_x <= x2; dc_x++) { +#ifdef ESLOPE + dc_texturemid = ds->maskedtextureheight[dc_x]; + + if (curline->linedef->flags & ML_DONTPEGBOTTOM) + dc_texturemid += (textureheight[texnum])*times + textureheight[texnum]; + else + dc_texturemid -= (textureheight[texnum])*times; +#endif // calculate lighting if (maskedtexturecol[dc_x] != INT16_MAX) { @@ -1205,9 +1220,10 @@ static void R_RenderSegLoop (void) #ifdef ESLOPE if (oldtexturecolumn != -1) { - rw_bottomtexturemid += FixedMul(rw_bottomtextureslide, oldtexturecolumn-texturecolumn); - rw_midtexturemid += FixedMul(rw_midtextureslide, oldtexturecolumn-texturecolumn); - rw_toptexturemid += FixedMul(rw_toptextureslide, oldtexturecolumn-texturecolumn); + rw_bottomtexturemid += FixedMul(rw_bottomtextureslide, oldtexturecolumn-texturecolumn); + rw_midtexturemid += FixedMul(rw_midtextureslide, oldtexturecolumn-texturecolumn); + rw_toptexturemid += FixedMul(rw_toptextureslide, oldtexturecolumn-texturecolumn); + rw_midtextureback += FixedMul(rw_midtexturebackslide, oldtexturecolumn-texturecolumn); } oldtexturecolumn = texturecolumn; #endif @@ -1360,6 +1376,14 @@ static void R_RenderSegLoop (void) // save texturecol // for backdrawing of masked mid texture maskedtexturecol[rw_x] = (INT16)texturecolumn; + +#ifdef ESLOPE + if (maskedtexture) { + maskedtextureheight[rw_x] = (curline->linedef->flags & ML_DONTPEGBOTTOM ? + max(rw_midtexturemid, rw_midtextureback) : + min(rw_midtexturemid, rw_midtextureback)); + } +#endif } if (dc_numlights) @@ -2120,6 +2144,23 @@ void R_StoreWallRange(INT32 start, INT32 stop) else ds_p->maskedtexturecol = ds_p->thicksidecol; +#ifdef ESLOPE + maskedtextureheight = &(ds_p->maskedtextureheight[0]); // ???? + + // Set midtexture starting height + if (linedef->flags & ML_DONTPEGBOTTOM) { + rw_midtexturemid = worldbottom; + rw_midtextureslide = floorfrontslide; + rw_midtextureback = worldlow; + rw_midtexturebackslide = floorbackslide; + } else { + rw_midtexturemid = worldtop; + rw_midtextureslide = ceilingfrontslide; + rw_midtextureback = worldhigh; + rw_midtexturebackslide = ceilingbackslide; + } +#endif + maskedtexture = true; } } From 7e13cb8b471e25358b9db126bde91d4e6cd1836d Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Mon, 4 May 2015 16:40:02 -0500 Subject: [PATCH 32/91] Fix various issues/crashes with texture alignments --- src/r_segs.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/r_segs.c b/src/r_segs.c index b96731c95..425cc4a3c 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -1378,7 +1378,7 @@ static void R_RenderSegLoop (void) maskedtexturecol[rw_x] = (INT16)texturecolumn; #ifdef ESLOPE - if (maskedtexture) { + if (maskedtextureheight != NULL) { maskedtextureheight[rw_x] = (curline->linedef->flags & ML_DONTPEGBOTTOM ? max(rw_midtexturemid, rw_midtextureback) : min(rw_midtexturemid, rw_midtextureback)); @@ -1447,6 +1447,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) #endif static size_t maxdrawsegs = 0; + maskedtextureheight = NULL; + if (ds_p == drawsegs+maxdrawsegs) { size_t pos = ds_p - drawsegs; @@ -1969,7 +1971,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) { // bottom of texture at bottom // top of texture at top - rw_bottomtexturemid = worldtop; + rw_bottomtexturemid = worldbottom; #ifdef ESLOPE rw_bottomtextureslide = floorfrontslide; #endif @@ -2159,6 +2161,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) rw_midtextureback = worldhigh; rw_midtexturebackslide = ceilingbackslide; } + rw_midtexturemid += sidedef->rowoffset; + rw_midtextureback += sidedef->rowoffset; #endif maskedtexture = true; From 2183912100cf32e41b39eae5e97695c6df0ff4d1 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Mon, 4 May 2015 17:45:02 -0500 Subject: [PATCH 33/91] Change upper/lower textures to not skew by default, add new linedef flags on normal linedefs: Effect 1: Restore skewing on upper/lower textures Effect 2: Disable skewing on midtextures Effect 3: Flips effect of Lower Unpegged for midtextures only (Effect 3 w/o LU: midtexture sticks to bottom, bottom texture sticks to upper edge. Effect 3 w/ LU: midtexture sticks to top, bottom texture sticks to lower edge.) --- src/r_segs.c | 46 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/src/r_segs.c b/src/r_segs.c index 425cc4a3c..8db5fa73a 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -512,7 +512,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) #ifdef ESLOPE dc_texturemid = ds->maskedtextureheight[dc_x]; - if (curline->linedef->flags & ML_DONTPEGBOTTOM) + if (!!(curline->linedef->flags & ML_DONTPEGBOTTOM) ^ !!(curline->linedef->flags & ML_EFFECT3)) dc_texturemid += (textureheight[texnum])*times + textureheight[texnum]; else dc_texturemid -= (textureheight[texnum])*times; @@ -1379,7 +1379,7 @@ static void R_RenderSegLoop (void) #ifdef ESLOPE if (maskedtextureheight != NULL) { - maskedtextureheight[rw_x] = (curline->linedef->flags & ML_DONTPEGBOTTOM ? + maskedtextureheight[rw_x] = (!!(curline->linedef->flags & ML_DONTPEGBOTTOM) ^ !!(curline->linedef->flags & ML_EFFECT3) ? max(rw_midtexturemid, rw_midtextureback) : min(rw_midtexturemid, rw_midtextureback)); } @@ -1672,7 +1672,14 @@ void R_StoreWallRange(INT32 start, INT32 stop) midtexture = texturetranslation[sidedef->midtexture]; // a single sided line is terminal, so it must mark ends markfloor = markceiling = true; - +#ifdef ESLOPE + if (!(linedef->flags & ML_EFFECT1)) { + if (linedef->flags & ML_DONTPEGBOTTOM) + rw_midtexturemid = frontsector->floorheight + textureheight[sidedef->midtexture] - viewz; + else + rw_midtexturemid = frontsector->ceilingheight; + } +#endif if (linedef->flags & ML_DONTPEGBOTTOM) { #ifdef ESLOPE @@ -1912,6 +1919,14 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (!toptexture) //Second side has no texture, use the first side's instead. toptexture = texturetranslation[sidedef->toptexture]; +#ifdef ESLOPE + if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked + if (linedef->flags & ML_DONTPEGTOP) + rw_toptexturemid = frontsector->ceilingheight - viewz; + else + rw_toptexturemid = backsector->ceilingheight - viewz; + } else +#endif if (linedef->flags & ML_DONTPEGTOP) { // top of texture at top @@ -1936,6 +1951,14 @@ void R_StoreWallRange(INT32 start, INT32 stop) { toptexture = texturetranslation[sidedef->toptexture]; +#ifdef ESLOPE + if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked + if (linedef->flags & ML_DONTPEGTOP) + rw_toptexturemid = frontsector->ceilingheight - viewz; + else + rw_toptexturemid = backsector->ceilingheight - viewz; + } else +#endif if (linedef->flags & ML_DONTPEGTOP) { // top of texture at top @@ -1967,6 +1990,14 @@ void R_StoreWallRange(INT32 start, INT32 stop) // bottom texture bottomtexture = texturetranslation[sidedef->bottomtexture]; +#ifdef ESLOPE + if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked + if (linedef->flags & ML_DONTPEGBOTTOM) + rw_bottomtexturemid = frontsector->floorheight - viewz; + else + rw_bottomtexturemid = backsector->floorheight - viewz; + } else +#endif if (linedef->flags & ML_DONTPEGBOTTOM) { // bottom of texture at bottom @@ -2150,7 +2181,14 @@ void R_StoreWallRange(INT32 start, INT32 stop) maskedtextureheight = &(ds_p->maskedtextureheight[0]); // ???? // Set midtexture starting height - if (linedef->flags & ML_DONTPEGBOTTOM) { + if (linedef->flags & ML_EFFECT2) { // Ignore slopes when texturing + rw_midtextureslide = rw_midtexturebackslide = 0; + if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) + rw_midtexturemid = rw_midtextureback = max(frontsector->floorheight, backsector->floorheight) - viewz; + else + rw_midtexturemid = rw_midtextureback = min(frontsector->ceilingheight, backsector->ceilingheight) - viewz; + + } else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) { rw_midtexturemid = worldbottom; rw_midtextureslide = floorfrontslide; rw_midtextureback = worldlow; From 371e23d55d0965d4fbdb55c0a6f1566e57fd7b98 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Wed, 13 May 2015 16:02:19 -0500 Subject: [PATCH 34/91] Reduce acceleration pushback to less absurd levels --- src/p_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index 62022fccf..0f2bd19b9 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4508,7 +4508,7 @@ static void P_3dMovement(player_t *player) v3fixed_t totalthrust; totalthrust.x = totalthrust.y = 0; // I forget if this is needed - totalthrust.z = FRACUNIT*P_MobjFlip(player->mo); // A bit of extra push-back on slopes + totalthrust.z = FRACUNIT*P_MobjFlip(player->mo)/3; // A bit of extra push-back on slopes #endif // ESLOPE // Get the old momentum; this will be needed at the end of the function! -SH From a3358479f0bc942df043c8fbff24f6efba62ad91 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Wed, 13 May 2015 16:15:32 -0500 Subject: [PATCH 35/91] Improvements related to slope collision, and quantize momentum properly for landing --- src/p_map.c | 25 +++++++++++++++++++------ src/p_mobj.c | 6 ++++++ src/p_slopes.c | 20 ++++++++++++++++++++ src/p_slopes.h | 1 + 4 files changed, 46 insertions(+), 6 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index 468e2530a..4b74b0f02 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1912,6 +1912,9 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) fixed_t tryy = thing->y; fixed_t radius = thing->radius; fixed_t thingtop = thing->z + thing->height; +#ifdef ESLOPE + fixed_t startingonground = P_IsObjectOnGround(thing); +#endif floatok = false; if (radius < MAXRADIUS/2) @@ -2003,7 +2006,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) thing->z = (thing->ceilingz = thingtop = tmceilingz) - thing->height; thing->eflags |= MFE_JUSTSTEPPEDDOWN; } - else if (thingtop == thing->ceilingz && tmceilingz < thingtop && thingtop - tmceilingz <= maxstep) + else if (tmceilingz < thingtop && thingtop - tmceilingz <= maxstep) { thing->z = (thing->ceilingz = thingtop = tmceilingz) - thing->height; thing->eflags |= MFE_JUSTSTEPPEDDOWN; @@ -2014,7 +2017,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) thing->z = thing->floorz = tmfloorz; thing->eflags |= MFE_JUSTSTEPPEDDOWN; } - else if (thing->z == thing->floorz && tmfloorz > thing->z && tmfloorz - thing->z <= maxstep) + else if (tmfloorz > thing->z && tmfloorz - thing->z <= maxstep) { thing->z = thing->floorz = tmfloorz; thing->eflags |= MFE_JUSTSTEPPEDDOWN; @@ -2090,10 +2093,20 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) #ifdef ESLOPE // Assign thing's standingslope if needed - if (thing->z <= tmfloorz && thing->momz <= 0 && !(thing->eflags & MFE_VERTICALFLIP)) - thing->standingslope = tmfloorslope; - else if (thing->z+thing->height >= tmceilingz && thing->momz >= 0 && (thing->eflags & MFE_VERTICALFLIP)) - thing->standingslope = tmceilingslope; + if (thing->z <= tmfloorz && !(thing->eflags & MFE_VERTICALFLIP)) { + if (!startingonground && tmfloorslope) + P_HandleSlopeLanding(thing, tmfloorslope); + + if (thing->momz <= 0) + thing->standingslope = tmfloorslope; + } + else if (thing->z+thing->height >= tmceilingz /*&& thing->momz >= 0*/ && (thing->eflags & MFE_VERTICALFLIP)) { + if (!startingonground && tmceilingslope) + P_HandleSlopeLanding(thing, tmceilingslope); + + if (thing->momz >= 0) + thing->standingslope = tmceilingslope; + } #endif thing->x = x; diff --git a/src/p_mobj.c b/src/p_mobj.c index 5af7b99a6..ac193b73e 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2344,6 +2344,12 @@ static void P_PlayerZMovement(mobj_t *mo) if (mo->state == &states[mo->info->painstate] || mo->state == &states[S_PLAY_SUPERHIT]) P_SetPlayerMobjState(mo, S_PLAY_STND); +#ifdef ESLOPE + if (mo->eflags & MFE_VERTICALFLIP ? tmceilingslope : tmfloorslope) + // Handle landing on slope during Z movement + P_HandleSlopeLanding(mo, (mo->eflags & MFE_VERTICALFLIP ? tmceilingslope : tmfloorslope)); +#endif + if (P_MobjFlip(mo)*mo->momz < 0) // falling { // Squat down. Decrease viewheight for a moment after hitting the ground (hard), diff --git a/src/p_slopes.c b/src/p_slopes.c index 5891756e8..cf786f1bb 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -805,6 +805,26 @@ void P_SlopeLaunch(mobj_t *mo) mo->standingslope = NULL; } +// Function to help handle landing on slopes +void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope) +{ + v3fixed_t mom; + mom.x = thing->momx; + mom.y = thing->momy; + mom.z = thing->momz*2; + + // Reverse quantizing might could use its own function later + slope->zangle = ANGLE_MAX-slope->zangle; + P_QuantizeMomentumToSlope(&mom, slope); + slope->zangle = ANGLE_MAX-slope->zangle; + + if (P_MobjFlip(thing)*mom.z < 0) { // falling, land on slope + thing->momx = mom.x; + thing->momy = mom.y; + thing->momz = -P_MobjFlip(thing); + } +} + // https://yourlogicalfallacyis.com/slippery-slope // Handles sliding down slopes, like if they were made of butter :) void P_ButteredSlope(mobj_t *mo) diff --git a/src/p_slopes.h b/src/p_slopes.h index f82d8a83d..4281d5796 100644 --- a/src/p_slopes.h +++ b/src/p_slopes.h @@ -79,6 +79,7 @@ float P_DistFromPlanef(const v3float_t *point, const v3float_t *pori, // Lots of physics-based bullshit void P_QuantizeMomentumToSlope(v3fixed_t *momentum, pslope_t *slope); void P_SlopeLaunch(mobj_t *mo); +void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope); void P_ButteredSlope(mobj_t *mo); #endif From 2187dac49bdf2f3075e4a97879c738ad9f674459 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Wed, 13 May 2015 16:48:34 -0500 Subject: [PATCH 36/91] Fix random texture triangles rendering on lines with slopes????? --- src/r_segs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/r_segs.c b/src/r_segs.c index 8db5fa73a..73e0a8696 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -2371,7 +2371,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (worldhigh < worldtop #ifdef ESLOPE - || worldhighslope < worldtopslope + || worldhighslope <= worldtopslope #endif ) { @@ -2388,7 +2388,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (worldlow > worldbottom #ifdef ESLOPE - || worldlowslope > worldbottomslope + || worldlowslope >= worldbottomslope #endif ) { From 0cc917a0ff18af54051975db730b7313f8a49a23 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Wed, 13 May 2015 21:41:54 -0500 Subject: [PATCH 37/91] Plane lighting for slopes now actually acts like it should --- src/r_draw.c | 2 +- src/r_draw.h | 2 +- src/r_draw8.c | 44 +++++++++++++++++++++++++++++++++++++++++++- src/r_plane.c | 44 ++++++++++++++++++++------------------------ src/r_plane.h | 2 ++ 5 files changed, 67 insertions(+), 27 deletions(-) diff --git a/src/r_draw.c b/src/r_draw.c index f4886d262..e63aa5a2b 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -106,7 +106,7 @@ UINT8 *ds_transmap; // one of the translucency tables #ifdef ESLOPE pslope_t *ds_slope; // Current slope being used v3float_t ds_su, ds_sv, ds_sz; // Vectors for... stuff? -float focallengthf; +float focallengthf, zeroheight; #endif /** \brief Variable flat sizes diff --git a/src/r_draw.h b/src/r_draw.h index 179887536..fa2cb22d0 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -63,7 +63,7 @@ extern UINT8 *ds_transmap; #ifdef ESLOPE pslope_t *ds_slope; // Current slope being used v3float_t ds_su, ds_sv, ds_sz; // Vectors for... stuff? -float focallengthf; +float focallengthf, zeroheight; #endif // Variable flat sizes diff --git a/src/r_draw8.c b/src/r_draw8.c index fe218f3ba..71e6458bb 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -527,6 +527,30 @@ void R_DrawSpan_8 (void) } #ifdef ESLOPE +// R_CalcTiltedLighting +// Exactly what it says on the tin. I wish I wasn't too lazy to explain things properly. +static size_t tiltlighting[MAXVIDWIDTH]; +void R_CalcTiltedLighting(fixed_t start, fixed_t end) +{ + // ZDoom uses a different lighting setup to us, and I couldn't figure out how to adapt their version + // of this function. Here's my own. + INT32 left = ds_x1, right = ds_x2; + fixed_t step = (end-start)/(ds_x2-ds_x1+1); + size_t i; + + // I wanna do some optimizing by checking for out-of-range segments on either side to fill in all at once, + // but I'm too bad at coding to not crash the game trying to do that. I guess this is fast enough for now... + + for (i = left; i <= right; i++) { + tiltlighting[i] = (start += step) >> FRACBITS; + if (tiltlighting[i] < 0) + tiltlighting[i] = 0; + else if (tiltlighting[i] >= MAXLIGHTSCALE) + tiltlighting[i] = MAXLIGHTSCALE-1; + } +} + + /** \brief The R_DrawTiltedSpan_8 function Draw slopes! Holy sheit! */ @@ -544,12 +568,24 @@ void R_DrawTiltedSpan_8(void) iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx); + // Lighting is simple. It's just linear interpolation from start to end + { + float planelightfloat = BASEVIDWIDTH*BASEVIDWIDTH/vid.width / (fabs(zeroheight - FIXED_TO_FLOAT(viewz))) / -21.0f; + float lightstart, lightend; + + lightend = (iz + ds_sz.x*width) * planelightfloat; + lightstart = iz * planelightfloat; + + R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend)); + //CONS_Printf("tilted lighting %f to %f (foc %f)\n", vz, uz, focallengthf); + } + uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx); vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx); dest = ylookup[ds_y] + columnofs[ds_x1]; source = ds_source; - colormap = ds_colormap; + //colormap = ds_colormap; #if 0 // The "perfect" reference version of this routine. Pretty slow. // Use it only to see how things are supposed to look. @@ -559,6 +595,9 @@ void R_DrawTiltedSpan_8(void) double z = 1.f/iz; u = (INT64)(uz*z) + viewx; v = (INT64)(vz*z) + viewy; + + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; dest++; iz += ds_sz.x; @@ -596,6 +635,7 @@ void R_DrawTiltedSpan_8(void) for (i = SPANSIZE-1; i >= 0; i--) { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; dest++; u += stepu; @@ -611,6 +651,7 @@ void R_DrawTiltedSpan_8(void) { u = (INT64)(startu); v = (INT64)(startv); + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; } else @@ -631,6 +672,7 @@ void R_DrawTiltedSpan_8(void) for (; width != 0; width--) { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; dest++; u += stepu; diff --git a/src/r_plane.c b/src/r_plane.c index 2839392d0..c0d26811d 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -74,7 +74,7 @@ static INT32 spanstart[MAXVIDHEIGHT]; // // texture mapping // -static lighttable_t **planezlight; +lighttable_t **planezlight; static fixed_t planeheight; //added : 10-02-98: yslopetab is what yslope used to be, @@ -327,6 +327,11 @@ void R_MapPlane(INT32 y, INT32 x1, INT32 x2) if (pindex >= MAXLIGHTZ) pindex = MAXLIGHTZ - 1; +#ifdef ESLOPE + if (currentplane->slope) + ds_colormap = colormaps; + else +#endif ds_colormap = planezlight[pindex]; if (currentplane->extra_colormap) @@ -919,24 +924,23 @@ void R_DrawSinglePlane(visplane_t *pl) break; } + xoffs = pl->xoffs; + yoffs = pl->yoffs; + planeheight = abs(pl->height - pl->viewz); + + if (light >= LIGHTLEVELS) + light = LIGHTLEVELS-1; + + if (light < 0) + light = 0; + #ifdef ESLOPE if (pl->slope) { // Potentially override other stuff for now cus we're mean. :< But draw a slope plane! // I copied ZDoom's code and adapted it to SRB2... -Red - static const float ifloatpow2[16] = - { - // ifloatpow2[i] = 1 / (1 << i) - 64.f, 32.f, 16.f, 8.f, 4.f, 2.f, 1.f, 0.5f, - 0.25f, 0.125f, 0.0625f, 0.03125f, 0.015625f, 0.0078125f, - 0.00390625f, 0.001953125f - /*, 0.0009765625f, 0.00048828125f, 0.000244140625f, - 1.220703125e-4f, 6.103515625e-5, 3.0517578125e-5*/ - }; - double lxscale, lyscale; - double xscale, yscale; v3float_t p, m, n; angle_t ang; - double zeroheight; + //double zeroheight; double vx = FIXED_TO_FLOAT(viewx); double vy = FIXED_TO_FLOAT(viewy); @@ -986,19 +990,11 @@ void R_DrawSinglePlane(visplane_t *pl) #undef SFMULT spanfunc = R_DrawTiltedSpan_8; - } + + planezlight = scalelight[light]; + } else #endif // ESLOPE - xoffs = pl->xoffs; - yoffs = pl->yoffs; - planeheight = abs(pl->height - pl->viewz); - - if (light >= LIGHTLEVELS) - light = LIGHTLEVELS-1; - - if (light < 0) - light = 0; - planezlight = zlight[light]; // set the maximum value for unsigned diff --git a/src/r_plane.h b/src/r_plane.h index b2346636b..2ef49cb39 100644 --- a/src/r_plane.h +++ b/src/r_plane.h @@ -82,6 +82,8 @@ extern fixed_t cachedxstep[MAXVIDHEIGHT]; extern fixed_t cachedystep[MAXVIDHEIGHT]; extern fixed_t basexscale, baseyscale; +extern lighttable_t **planezlight; + extern fixed_t *yslope; extern fixed_t distscale[MAXVIDWIDTH]; From e39c8aa62e76ecaa91aa3cf594de36578d94ea92 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Wed, 13 May 2015 21:57:47 -0500 Subject: [PATCH 38/91] Fix ceiling slopes lol --- src/r_draw8.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/r_draw8.c b/src/r_draw8.c index 71e6458bb..b292f4617 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -570,14 +570,14 @@ void R_DrawTiltedSpan_8(void) // Lighting is simple. It's just linear interpolation from start to end { - float planelightfloat = BASEVIDWIDTH*BASEVIDWIDTH/vid.width / (fabs(zeroheight - FIXED_TO_FLOAT(viewz))) / -21.0f; + float planelightfloat = BASEVIDWIDTH*BASEVIDWIDTH/vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f; float lightstart, lightend; lightend = (iz + ds_sz.x*width) * planelightfloat; lightstart = iz * planelightfloat; R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend)); - //CONS_Printf("tilted lighting %f to %f (foc %f)\n", vz, uz, focallengthf); + //CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf); } uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx); From bd0b7829bb53319ac10fdc7a115a95585ab9f852 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Thu, 14 May 2015 10:55:43 -0500 Subject: [PATCH 39/91] Fix rotated flats on slopes --- src/r_plane.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/r_plane.c b/src/r_plane.c index c0d26811d..c39be11a9 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -861,6 +861,9 @@ void R_DrawSinglePlane(visplane_t *pl) } else light = (pl->lightlevel >> LIGHTSEGSHIFT); +#ifdef ESLOPE + if (!pl->slope) // Don't mess with angle on slopes! We'll handle this ourselves later +#endif if (viewangle != pl->viewangle) { memset(cachedheight, 0, sizeof (cachedheight)); @@ -962,10 +965,8 @@ void R_DrawSinglePlane(visplane_t *pl) m.z = FIXED_TO_FLOAT(FINESINE(ang)); // n is the u direction vector in view space - ang += ANGLE_90>>ANGLETOFINESHIFT; - ang &= FINEMASK; - n.x = -FIXED_TO_FLOAT(FINECOSINE(ang)); - n.z = -FIXED_TO_FLOAT(FINESINE(ang)); + n.x = FIXED_TO_FLOAT(FINESINE(ang)); + n.z = -FIXED_TO_FLOAT(FINECOSINE(ang)); ang = pl->plangle>>ANGLETOFINESHIFT; m.y = FIXED_TO_FLOAT(P_GetZAt(pl->slope, viewx + FINESINE(ang), viewy + FINECOSINE(ang))) - zeroheight; From b69678f1a6d265061d89b2199ae703b8b96a8db1 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Fri, 15 May 2015 10:23:53 -0500 Subject: [PATCH 40/91] PLACEHOLDER, DO NOT PUSH THIS COMMIT --- src/p_mobj.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index ac193b73e..837c0c3a4 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1437,7 +1437,8 @@ void P_XYMovement(mobj_t *mo) oldslope = mo->standingslope; } - } + } else if (P_IsObjectOnGround(mo)) + predictedz = mo->z; #endif // Pushables can break some blocks @@ -1447,7 +1448,6 @@ void P_XYMovement(mobj_t *mo) if (!P_TryMove(mo, mo->x + xmove, mo->y + ymove, true) && !(mo->eflags & MFE_SPRUNG)) { // blocked move - if (player) { moved = false; if (player->bot) @@ -1562,6 +1562,8 @@ void P_XYMovement(mobj_t *mo) #ifdef ESLOPE if (moved && oldslope) { // Check to see if we ran off + //angle_t moveangle = R_PointToAngle2(mo->momx, mo->momy); + if (oldslope != mo->standingslope) { // First, compare different slopes // Start by quantizing momentum on this slope v3fixed_t test; @@ -1572,14 +1574,27 @@ void P_XYMovement(mobj_t *mo) P_QuantizeMomentumToSlope(&test, mo->standingslope); // Now compare the Zs of the different quantizations - if (slopemom.z - test.z > 2*FRACUNIT) { // Allow for a bit of sticking - this value can be adjusted later + if (slopemom.z - test.z > P_AproxDistance(slopemom.x, slopemom.y/3) { // Allow for a bit of sticking - this value can be adjusted later mo->standingslope = oldslope; P_SlopeLaunch(mo); } - } else if (predictedz-mo->z > 2*FRACUNIT) { // Now check if we were supposed to stick to this slope + } else if (predictedz-mo->z > P_AproxDistance(slopemom.x, slopemom.y)/3) { // Now check if we were supposed to stick to this slope mo->standingslope = oldslope; P_SlopeLaunch(mo); } + } else if (moved && mo->standingslope && predictedz) { + slopemom.x = mo->momx; + slopemom.y = mo->momy; + slopemom.z = 0; + + P_QuantizeMomentumToSlope(&slopemom, mo->standingslope); + + if (-slopemom.z > P_AproxDistance(mo->momx, mo->momy)/3) { + mo->momz = P_MobjFlip(mo)*FRACUNIT/2; + mo->z = predictedz + P_MobjFlip(mo); + mo->standingslope = NULL; + CONS_Printf("Launched off of flat surface running into downward slope\n"); + } } #endif From 445e778309e84d80095085defc3742dd464f55de Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Fri, 15 May 2015 12:35:54 -0500 Subject: [PATCH 41/91] Improvements to slope collision/landing/ejecting/fajitas --- src/p_mobj.c | 63 +++++++++++++++++++++++++++++--------------------- src/p_slopes.c | 4 ++++ 2 files changed, 41 insertions(+), 26 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 837c0c3a4..855e9355c 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1384,7 +1384,7 @@ void P_XYMovement(mobj_t *mo) #ifdef ESLOPE pslope_t *oldslope = NULL; v3fixed_t slopemom; - fixed_t predictedz; + fixed_t predictedz = 0; #endif I_Assert(mo != NULL); @@ -1437,7 +1437,7 @@ void P_XYMovement(mobj_t *mo) oldslope = mo->standingslope; } - } else if (P_IsObjectOnGround(mo)) + } else if (P_IsObjectOnGround(mo) && !mo->momz) predictedz = mo->z; #endif @@ -1562,38 +1562,48 @@ void P_XYMovement(mobj_t *mo) #ifdef ESLOPE if (moved && oldslope) { // Check to see if we ran off - //angle_t moveangle = R_PointToAngle2(mo->momx, mo->momy); if (oldslope != mo->standingslope) { // First, compare different slopes - // Start by quantizing momentum on this slope - v3fixed_t test; - test.x = mo->momx; - test.y = mo->momy; - test.z = 0; - if (mo->standingslope) // Don't fuss with the rotation if we don't HAVE a slope - P_QuantizeMomentumToSlope(&test, mo->standingslope); + angle_t oldangle, newangle; + angle_t moveangle = R_PointToAngle2(0, 0, mo->momx, mo->momy); + + oldangle = FixedMul((signed)oldslope->zangle, FINECOSINE((moveangle - oldslope->xydirection) >> ANGLETOFINESHIFT)); + + if (mo->standingslope) + newangle = FixedMul((signed)mo->standingslope->zangle, FINECOSINE((moveangle - mo->standingslope->xydirection) >> ANGLETOFINESHIFT)); + else + newangle = 0; // Now compare the Zs of the different quantizations - if (slopemom.z - test.z > P_AproxDistance(slopemom.x, slopemom.y/3) { // Allow for a bit of sticking - this value can be adjusted later + if (oldangle-newangle > ANG30 && oldangle-newangle < ANGLE_180) { // Allow for a bit of sticking - this value can be adjusted later mo->standingslope = oldslope; P_SlopeLaunch(mo); + + //CONS_Printf("launched off of slope - "); } - } else if (predictedz-mo->z > P_AproxDistance(slopemom.x, slopemom.y)/3) { // Now check if we were supposed to stick to this slope - mo->standingslope = oldslope; + + /*CONS_Printf("old angle %f - new angle %f = %f\n", + FIXED_TO_FLOAT(AngleFixed(oldangle)), + FIXED_TO_FLOAT(AngleFixed(newangle)), + FIXED_TO_FLOAT(AngleFixed(oldangle-newangle)) + );*/ + } else if (predictedz-mo->z > abs(slopemom.z/2)) { // Now check if we were supposed to stick to this slope + //CONS_Printf("%d-%d > %d\n", (predictedz), (mo->z), (slopemom.z/2)); P_SlopeLaunch(mo); } } else if (moved && mo->standingslope && predictedz) { - slopemom.x = mo->momx; - slopemom.y = mo->momy; - slopemom.z = 0; + angle_t moveangle = R_PointToAngle2(0, 0, mo->momx, mo->momy); + angle_t newangle = FixedMul((signed)mo->standingslope->zangle, FINECOSINE((moveangle - mo->standingslope->xydirection) >> ANGLETOFINESHIFT)); - P_QuantizeMomentumToSlope(&slopemom, mo->standingslope); - - if (-slopemom.z > P_AproxDistance(mo->momx, mo->momy)/3) { + /*CONS_Printf("flat to angle %f - predicted z of %f\n", + FIXED_TO_FLOAT(AngleFixed(ANGLE_MAX-newangle)), + FIXED_TO_FLOAT(predictedz) + );*/ + if (ANGLE_MAX-newangle > ANG30 && newangle > ANGLE_180) { mo->momz = P_MobjFlip(mo)*FRACUNIT/2; mo->z = predictedz + P_MobjFlip(mo); mo->standingslope = NULL; - CONS_Printf("Launched off of flat surface running into downward slope\n"); + //CONS_Printf("Launched off of flat surface running into downward slope\n"); } } #endif @@ -2300,11 +2310,6 @@ static void P_PlayerZMovement(mobj_t *mo) if (!mo->player) return; -#ifdef ESLOPE - if (mo->standingslope && !P_IsObjectOnGround(mo)) - P_SlopeLaunch(mo); -#endif - // Intercept the stupid 'fall through 3dfloors' bug if (mo->subsector->sector->ffloors) P_AdjustMobjFloorZ_FFloors(mo, mo->subsector->sector, 0); @@ -2338,6 +2343,11 @@ static void P_PlayerZMovement(mobj_t *mo) || mo->player->playerstate == PST_REBORN) return; +#ifdef ESLOPE + if (mo->standingslope && !P_IsObjectOnGround(mo)) + P_SlopeLaunch(mo); +#endif + // clip movement if (P_IsObjectOnGround(mo) && !(mo->flags & MF_NOCLIPHEIGHT)) { @@ -2360,9 +2370,10 @@ static void P_PlayerZMovement(mobj_t *mo) P_SetPlayerMobjState(mo, S_PLAY_STND); #ifdef ESLOPE - if (mo->eflags & MFE_VERTICALFLIP ? tmceilingslope : tmfloorslope) + if (!mo->standingslope && (mo->eflags & MFE_VERTICALFLIP ? tmceilingslope : tmfloorslope)) { // Handle landing on slope during Z movement P_HandleSlopeLanding(mo, (mo->eflags & MFE_VERTICALFLIP ? tmceilingslope : tmfloorslope)); + } #endif if (P_MobjFlip(mo)*mo->momz < 0) // falling diff --git a/src/p_slopes.c b/src/p_slopes.c index cf786f1bb..39eac6db7 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -813,6 +813,8 @@ void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope) mom.y = thing->momy; mom.z = thing->momz*2; + //CONS_Printf("langing on slope\n"); + // Reverse quantizing might could use its own function later slope->zangle = ANGLE_MAX-slope->zangle; P_QuantizeMomentumToSlope(&mom, slope); @@ -822,6 +824,8 @@ void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope) thing->momx = mom.x; thing->momy = mom.y; thing->momz = -P_MobjFlip(thing); + + thing->standingslope = slope; } } From 36d576adf44eb7c7a6708f6365b7601faf8fac0b Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Fri, 15 May 2015 12:36:16 -0500 Subject: [PATCH 42/91] I think those were being cast wrong --- src/r_draw8.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/r_draw8.c b/src/r_draw8.c index b292f4617..b8b23b1b3 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -593,8 +593,8 @@ void R_DrawTiltedSpan_8(void) do { double z = 1.f/iz; - u = (INT64)(uz*z) + viewx; - v = (INT64)(vz*z) + viewy; + u = (UINT32)(uz*z) + viewx; + v = (UINT32)(vz*z) + viewy; colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); @@ -628,10 +628,10 @@ void R_DrawTiltedSpan_8(void) double endz = 1.f/iz; double endu = uz*endz; double endv = vz*endz; - UINT32 stepu = (INT64)((endu - startu) * INVSPAN); - UINT32 stepv = (INT64)((endv - startv) * INVSPAN); - u = (INT64)(startu) + viewx; - v = (INT64)(startv) + viewy; + UINT32 stepu = (UINT32)((endu - startu) * INVSPAN); + UINT32 stepv = (UINT32)((endv - startv) * INVSPAN); + u = (UINT32)(startu) + viewx; + v = (UINT32)(startv) + viewy; for (i = SPANSIZE-1; i >= 0; i--) { @@ -649,8 +649,8 @@ void R_DrawTiltedSpan_8(void) { if (width == 1) { - u = (INT64)(startu); - v = (INT64)(startv); + u = (UINT32)(startu); + v = (UINT32)(startv); colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; } @@ -665,10 +665,10 @@ void R_DrawTiltedSpan_8(void) double endu = uz*endz; double endv = vz*endz; left = 1.f/left; - UINT32 stepu = (INT64)((endu - startu) * left); - UINT32 stepv = (INT64)((endv - startv) * left); - u = (INT64)(startu) + viewx; - v = (INT64)(startv) + viewy; + UINT32 stepu = (UINT32)((endu - startu) * left); + UINT32 stepv = (UINT32)((endv - startv) * left); + u = (UINT32)(startu) + viewx; + v = (UINT32)(startv) + viewy; for (; width != 0; width--) { From 6fcdac494fc27b75503b1f47b9b772d252c5d12f Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Sat, 16 May 2015 00:02:01 -0500 Subject: [PATCH 43/91] Spawned things spawn relative to slope floor/ceiling heights now This was a headache. :< --- src/p_mobj.c | 108 ++++++++++++++++++++++++++++++++++++++++--------- src/p_setup.c | 14 +++++-- src/p_slopes.c | 34 +++++++++++++--- src/p_spec.c | 13 +----- 4 files changed, 131 insertions(+), 38 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 855e9355c..af832d585 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7306,8 +7306,16 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) // Make sure scale matches destscale immediately when spawned P_SetScale(mobj, mobj->destscale); - mobj->floorz = mobj->subsector->sector->floorheight; - mobj->ceilingz = mobj->subsector->sector->ceilingheight; + mobj->floorz = +#ifdef ESLOPE + mobj->subsector->sector->f_slope ? P_GetZAt(mobj->subsector->sector->f_slope, x, y) : +#endif + mobj->subsector->sector->floorheight; + mobj->ceilingz = +#ifdef ESLOPE + mobj->subsector->sector->c_slope ? P_GetZAt(mobj->subsector->sector->c_slope, x, y) : +#endif + mobj->subsector->sector->ceilingheight; // Tells MobjCheckWater that the water height was not set. mobj->watertop = INT32_MAX; @@ -8364,7 +8372,11 @@ void P_SpawnMapThing(mapthing_t *mthing) return; ss = R_PointInSubsector(mthing->x << FRACBITS, mthing->y << FRACBITS); - mthing->z = (INT16)((ss->sector->floorheight>>FRACBITS) + (mthing->options >> ZSHIFT)); + mthing->z = (INT16)((( +#ifdef ESLOPE + ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, mthing->x << FRACBITS, mthing->y << FRACBITS) : +#endif + ss->sector->floorheight)>>FRACBITS) + (mthing->options >> ZSHIFT)); if (numhuntemeralds < MAXHUNTEMERALDS) huntemeralds[numhuntemeralds++] = mthing; @@ -8482,14 +8494,22 @@ void P_SpawnMapThing(mapthing_t *mthing) ss = R_PointInSubsector(x, y); if (i == MT_NIGHTSBUMPER) - z = ss->sector->floorheight + ((mthing->options >> ZSHIFT) << FRACBITS); + z = ( +#ifdef ESLOPE + ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, x, y) : +#endif + ss->sector->floorheight) + ((mthing->options >> ZSHIFT) << FRACBITS); else if (i == MT_AXIS || i == MT_AXISTRANSFER || i == MT_AXISTRANSFERLINE) z = ONFLOORZ; else if (i == MT_SPECIALSPIKEBALL || P_WeaponOrPanel(i) || i == MT_EMERALDSPAWN || i == MT_EMMY) { if (mthing->options & MTF_OBJECTFLIP) { - z = ss->sector->ceilingheight; + z = ( +#ifdef ESLOPE + ss->sector->c_slope ? P_GetZAt(ss->sector->c_slope, x, y) : +#endif + ss->sector->ceilingheight); if (mthing->options & MTF_AMBUSH) // Special flag for rings z -= 24*FRACUNIT; @@ -8500,7 +8520,11 @@ void P_SpawnMapThing(mapthing_t *mthing) } else { - z = ss->sector->floorheight; + z = ( +#ifdef ESLOPE + ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, x, y) : +#endif + ss->sector->floorheight); if (mthing->options & MTF_AMBUSH) // Special flag for rings z += 24*FRACUNIT; @@ -8520,9 +8544,17 @@ void P_SpawnMapThing(mapthing_t *mthing) // base positions if (flip) - z = ss->sector->ceilingheight - mobjinfo[i].height; + z = ( +#ifdef ESLOPE + ss->sector->c_slope ? P_GetZAt(ss->sector->c_slope, x, y) : +#endif + ss->sector->ceilingheight) - mobjinfo[i].height; else - z = ss->sector->floorheight; + z = ( +#ifdef ESLOPE + ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, x, y) : +#endif + ss->sector->floorheight); // offsetting if (mthing->options >> ZSHIFT) @@ -9036,7 +9068,11 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) // Screw these damn hoops, I need this thinker. //hoopcenter->flags |= MF_NOTHINK; - z += sec->floorheight; + z += +#ifdef ESLOPE + sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : +#endif + sec->floorheight; hoopcenter->z = z - hoopcenter->height/2; @@ -9169,7 +9205,11 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) hoopcenter = P_SpawnMobj(x, y, z, MT_HOOPCENTER); hoopcenter->spawnpoint = mthing; - z += sec->floorheight; + z += +#ifdef ESLOPE + sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : +#endif + sec->floorheight; hoopcenter->z = z - hoopcenter->height/2; P_UnsetThingPosition(hoopcenter); @@ -9281,7 +9321,11 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) // Wing logo item. else if (mthing->type == mobjinfo[MT_NIGHTSWING].doomednum) { - z = sec->floorheight; + z = +#ifdef ESLOPE + sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : +#endif + sec->floorheight; if (mthing->options >> ZSHIFT) z += ((mthing->options >> ZSHIFT) << FRACBITS); @@ -9333,13 +9377,21 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) // Set proper height if (mthing->options & MTF_OBJECTFLIP) { - z = sec->ceilingheight - mobjinfo[ringthing].height; + z = ( +#ifdef ESLOPE + sec->c_slope ? P_GetZAt(sec->c_slope, x, y) : +#endif + sec->ceilingheight) - mobjinfo[ringthing].height; if (mthing->options >> ZSHIFT) z -= ((mthing->options >> ZSHIFT) << FRACBITS); } else { - z = sec->floorheight; + z = +#ifdef ESLOPE + sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : +#endif + sec->floorheight; if (mthing->options >> ZSHIFT) z += ((mthing->options >> ZSHIFT) << FRACBITS); } @@ -9393,13 +9445,21 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) { if (mthing->options & MTF_OBJECTFLIP) { - z = sec->ceilingheight - mobjinfo[ringthing].height - dist*r; + z = ( +#ifdef ESLOPE + sec->c_slope ? P_GetZAt(sec->c_slope, x, y) : +#endif + sec->ceilingheight) - mobjinfo[ringthing].height - dist*r; if (mthing->options >> ZSHIFT) z -= ((mthing->options >> ZSHIFT) << FRACBITS); } else { - z = sec->floorheight + dist*r; + z = ( +#ifdef ESLOPE + sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : +#endif + sec->floorheight) + dist*r; if (mthing->options >> ZSHIFT) z += ((mthing->options >> ZSHIFT) << FRACBITS); } @@ -9445,13 +9505,21 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) if (mthing->options & MTF_OBJECTFLIP) { - z = sec->ceilingheight - mobjinfo[ringthing].height - 64*FRACUNIT*r; + z = ( +#ifdef ESLOPE + sec->c_slope ? P_GetZAt(sec->c_slope, x, y) : +#endif + sec->ceilingheight) - mobjinfo[ringthing].height - 64*FRACUNIT*r; if (mthing->options >> ZSHIFT) z -= ((mthing->options >> ZSHIFT) << FRACBITS); } else { - z = sec->floorheight + 64*FRACUNIT*r; + z = ( +#ifdef ESLOPE + sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : +#endif + sec->floorheight) + 64*FRACUNIT*r; if (mthing->options >> ZSHIFT) z += ((mthing->options >> ZSHIFT) << FRACBITS); } @@ -9482,7 +9550,11 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) size = 192*FRACUNIT; } - z = sec->floorheight; + z = +#ifdef ESLOPE + sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : +#endif + sec->floorheight; if (mthing->options >> ZSHIFT) z += ((mthing->options >> ZSHIFT) << FRACBITS); diff --git a/src/p_setup.c b/src/p_setup.c index a75668b68..c836d601c 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -892,9 +892,14 @@ static void P_LoadThings(lumpnum_t lumpnum) numhuntemeralds = 0; for (i = 0; i < nummapthings; i++, mt++) { + sector_t *mtsector = R_PointInSubsector(mt->x << FRACBITS, mt->y << FRACBITS)->sector; + // Z for objects - mt->z = (INT16)(R_PointInSubsector(mt->x << FRACBITS, mt->y << FRACBITS) - ->sector->floorheight>>FRACBITS); + mt->z = (INT16)( +#ifdef ESLOPE + mtsector->f_slope ? P_GetZAt(mtsector->f_slope, mt->x << FRACBITS, mt->y << FRACBITS) : +#endif + mtsector->floorheight)>>FRACBITS; if (mt->type == 1700 // MT_AXIS || mt->type == 1701 // MT_AXISTRANSFER @@ -2535,6 +2540,10 @@ boolean P_SetupLevel(boolean skipprecip) P_MapStart(); +#ifdef ESLOPE + P_ResetDynamicSlopes(); +#endif + P_LoadThings(lastloadedmaplumpnum + ML_THINGS); P_SpawnSecretItems(loademblems); @@ -2544,7 +2553,6 @@ boolean P_SetupLevel(boolean skipprecip) break; // set up world state - P_ResetDynamicSlopes(); P_SpawnSpecials(fromnetsave); if (loadprecip) // ugly hack for P_NetUnArchiveMisc (and P_LoadNetGame) diff --git a/src/p_slopes.c b/src/p_slopes.c index 39eac6db7..e7d05768c 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -42,11 +42,6 @@ static pslope_t *dynslopes = NULL; -// Reset the dynamic slopes pointer -void P_ResetDynamicSlopes(void) { - dynslopes = NULL; -} - // Calculate line normal void P_CalculateSlopeNormal(pslope_t *slope) { slope->normal.z = FINECOSINE(slope->zangle>>ANGLETOFINESHIFT); @@ -722,6 +717,35 @@ void P_SetSlopesFromVertexHeights(lumpnum_t lumpnum) } #endif +// Reset the dynamic slopes pointer, and read all of the fancy schmancy slopes +void P_ResetDynamicSlopes(void) { + size_t i; + + dynslopes = NULL; + + // We'll handle copy slopes later, after all the tag lists have been made. + // Yes, this means copied slopes won't affect things' spawning heights. Too bad for you. + for (i = 0; i < numlines; i++) + { + switch (lines[i].special) + { + case 386: + case 387: + case 388: + case 389: + case 390: + case 391: + case 392: + case 393: + P_SpawnSlope_Line(i); + break; + + default: + break; + } + } +} + diff --git a/src/p_spec.c b/src/p_spec.c index fe3deba30..b276d1c17 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -6439,18 +6439,7 @@ void P_SpawnSpecials(INT32 fromnetsave) sectors[s].midmap = lines[i].frontsector->midmap; break; -#ifdef ESLOPE // Slope specials. TODO move these to a different spot, maybe? - case 386: - case 387: - case 388: - case 389: - case 390: - case 391: - case 392: - case 393: - P_SpawnSlope_Line(i); - break; - // SoM: Copy slopes +#ifdef ESLOPE // Slope copy specials. Handled here for sanity. case 394: case 395: case 396: From 09f8dec7d14214494516bb727f44d11f57ff4379 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Sat, 16 May 2015 00:04:19 -0500 Subject: [PATCH 44/91] Optimization/configuration option: No Tails on a slope line makes a slope non-dynamic --- src/p_slopes.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/p_slopes.c b/src/p_slopes.c index e7d05768c..9cd22f35b 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -233,7 +233,7 @@ void P_SpawnSlope_Line(int linenum) // In P_SpawnSlopeLine the origin is the centerpoint of the sourcelinedef fslope = line->frontsector->f_slope = - P_MakeSlope(&point, &direction, dz, true); + P_MakeSlope(&point, &direction, dz, !(line->flags & ML_NOTAILS)); // Set up some shit fslope->extent = extent; @@ -289,7 +289,7 @@ void P_SpawnSlope_Line(int linenum) dz = FixedDiv(origin.z - point.z, extent); cslope = line->frontsector->c_slope = - P_MakeSlope(&point, &direction, dz, true); + P_MakeSlope(&point, &direction, dz, !(line->flags & ML_NOTAILS)); // Set up some shit cslope->extent = extent; @@ -352,7 +352,7 @@ void P_SpawnSlope_Line(int linenum) dz = FixedDiv(origin.z - point.z, extent); fslope = line->backsector->f_slope = - P_MakeSlope(&point, &direction, dz, true); + P_MakeSlope(&point, &direction, dz, !(line->flags & ML_NOTAILS)); // Set up some shit fslope->extent = extent; @@ -394,7 +394,7 @@ void P_SpawnSlope_Line(int linenum) dz = FixedDiv(origin.z - point.z, extent); cslope = line->backsector->c_slope = - P_MakeSlope(&point, &direction, dz, true); + P_MakeSlope(&point, &direction, dz, !(line->flags & ML_NOTAILS)); // Set up some shit cslope->extent = extent; From d81cecdac9d058d7509f9bf1bd86bb33eda41866 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Sat, 16 May 2015 19:59:52 -0500 Subject: [PATCH 45/91] Minor cleanup so it stops bugging me --- src/r_segs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/r_segs.c b/src/r_segs.c index 73e0a8696..a4b57d39d 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -1904,7 +1904,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) // check TOP TEXTURE if (worldhigh < worldtop #ifdef ESLOPE - /*-(FRACUNIT>>8)*/|| worldhighslope < worldtopslope/*-(FRACUNIT>>8)*/ + || worldhighslope < worldtopslope #endif ) { @@ -1983,7 +1983,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) // check BOTTOM TEXTURE if (worldlow > worldbottom #ifdef ESLOPE - /*+(FRACUNIT>>8)*/ || worldlowslope > worldbottomslope/*+(FRACUNIT>>8)*/ // The leeway works around a weird rendering bug with slopes... + || worldlowslope > worldbottomslope #endif ) //seulement si VISIBLE!!! { From 4e11d6d6152f13ad4d33e9a46cb5650139f61353 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Sat, 16 May 2015 22:32:12 -0500 Subject: [PATCH 46/91] Make FOF planes render slopedly if set --- src/p_spec.c | 6 ++ src/r_bsp.c | 48 +++++++++-- src/r_defs.h | 6 ++ src/r_plane.h | 8 ++ src/r_segs.c | 235 +++++++++++++++++++++++++++++++++++++++++++++++--- 5 files changed, 282 insertions(+), 21 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index b276d1c17..3126413b5 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4903,6 +4903,12 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f ffloor->topyoffs = &sec2->ceiling_yoffs; ffloor->topangle = &sec2->ceilingpic_angle; +#ifdef ESLOPE + // Add slopes + ffloor->t_slope = &sec2->c_slope; + ffloor->b_slope = &sec2->f_slope; +#endif + if ((flags & FF_SOLID) && (master->flags & ML_EFFECT1)) // Block player only flags &= ~FF_BLOCKOTHERS; diff --git a/src/r_bsp.c b/src/r_bsp.c index ae4e8ac67..283029ca5 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -905,6 +905,7 @@ static void R_Subsector(size_t num) if (frontsector->ffloors) { ffloor_t *rover; + fixed_t heightcheck; for (rover = frontsector->ffloors; rover && numffloors < MAXFFLOORS; rover = rover->next) { @@ -922,10 +923,16 @@ static void R_Subsector(size_t num) ffloor[numffloors].plane = NULL; ffloor[numffloors].polyobj = NULL; + + heightcheck = +#ifdef ESLOPE + *rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : +#endif + *rover->bottomheight; if (*rover->bottomheight <= frontsector->ceilingheight && *rover->bottomheight >= frontsector->floorheight - && ((viewz < *rover->bottomheight && !(rover->flags & FF_INVERTPLANES)) - || (viewz > *rover->bottomheight && (rover->flags & FF_BOTHPLANES)))) + && ((viewz < heightcheck && !(rover->flags & FF_INVERTPLANES)) + || (viewz > heightcheck && (rover->flags & FF_BOTHPLANES)))) { light = R_GetPlaneLight(frontsector, *rover->bottomheight, viewz < *rover->bottomheight); @@ -933,11 +940,20 @@ static void R_Subsector(size_t num) *frontsector->lightlist[light].lightlevel, *rover->bottomxoffs, *rover->bottomyoffs, *rover->bottomangle, frontsector->lightlist[light].extra_colormap, rover #ifdef ESLOPE - , NULL // will ffloors be slopable eventually? + , *rover->b_slope #endif ); - ffloor[numffloors].height = *rover->bottomheight; +#ifdef ESLOPE + ffloor[numffloors].slope = *rover->b_slope; +#endif + + ffloor[numffloors].height = +#ifdef ESLOPE + *rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : +#endif + *rover->bottomheight; + ffloor[numffloors].ffloor = rover; numffloors++; } @@ -945,20 +961,36 @@ static void R_Subsector(size_t num) break; ffloor[numffloors].plane = NULL; ffloor[numffloors].polyobj = NULL; + + heightcheck = +#ifdef ESLOPE + *rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : +#endif + *rover->topheight; if (*rover->topheight >= frontsector->floorheight && *rover->topheight <= frontsector->ceilingheight - && ((viewz > *rover->topheight && !(rover->flags & FF_INVERTPLANES)) - || (viewz < *rover->topheight && (rover->flags & FF_BOTHPLANES)))) + && ((viewz > heightcheck && !(rover->flags & FF_INVERTPLANES)) + || (viewz < heightcheck && (rover->flags & FF_BOTHPLANES)))) { light = R_GetPlaneLight(frontsector, *rover->topheight, viewz < *rover->topheight); ffloor[numffloors].plane = R_FindPlane(*rover->topheight, *rover->toppic, *frontsector->lightlist[light].lightlevel, *rover->topxoffs, *rover->topyoffs, *rover->topangle, frontsector->lightlist[light].extra_colormap, rover #ifdef ESLOPE - , NULL // will ffloors be slopable eventually? + , *rover->t_slope #endif ); - ffloor[numffloors].height = *rover->topheight; + +#ifdef ESLOPE + ffloor[numffloors].slope = *rover->t_slope; +#endif + + ffloor[numffloors].height = +#ifdef ESLOPE + *rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : +#endif + *rover->topheight; + ffloor[numffloors].ffloor = rover; numffloors++; } diff --git a/src/r_defs.h b/src/r_defs.h index 9a9679d4a..1f0f2a62d 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -155,6 +155,12 @@ typedef struct ffloor_s fixed_t *bottomyoffs; angle_t *bottomangle; +#ifdef ESLOPE + // Pointers to pointers. Yup. + struct pslope_s **t_slope; + struct pslope_s **b_slope; +#endif + size_t secnum; ffloortype_e flags; struct line_s *master; diff --git a/src/r_plane.h b/src/r_plane.h index 2ef49cb39..239723ed1 100644 --- a/src/r_plane.h +++ b/src/r_plane.h @@ -119,6 +119,14 @@ typedef struct planemgr_s INT16 f_clip[MAXVIDWIDTH]; INT16 c_clip[MAXVIDWIDTH]; +#ifdef ESLOPE + // For slope rendering; the height at the other end + fixed_t f_pos_slope; + fixed_t b_pos_slope; + + struct pslope_s *slope; +#endif + struct ffloor_s *ffloor; #ifdef POLYOBJECTS_PLANES polyobj_t *polyobj; diff --git a/src/r_segs.c b/src/r_segs.c index a4b57d39d..a8f956a85 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -1549,7 +1549,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) // and decide if floor / ceiling marks are needed #ifdef ESLOPE // Figure out map coordinates of where start and end are mapping to on seg, so we can clip right for slope bullshit - if (frontsector->c_slope || frontsector->f_slope || (backsector && (backsector->c_slope || backsector->f_slope))) { + //if (frontsector->c_slope || frontsector->f_slope || (backsector && (backsector->c_slope || backsector->f_slope))) // Commenting this out for FOFslop. -Red + { angle_t temp; // left @@ -1640,6 +1641,14 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (ffloor[i].polyobj && (!ds_p->curline->polyseg || ffloor[i].polyobj != ds_p->curline->polyseg)) continue; #endif + +#ifdef ESLOPE + if (ffloor[i].slope) { + ffloor[i].f_pos = P_GetZAt(ffloor[i].slope, segleft.x, segleft.y) - viewz; + ffloor[i].f_pos_slope = P_GetZAt(ffloor[i].slope, segright.x, segright.y) - viewz; + } else + ffloor[i].f_pos_slope = +#endif ffloor[i].f_pos = ffloor[i].height - viewz; } } @@ -2024,6 +2033,12 @@ void R_StoreWallRange(INT32 start, INT32 stop) ffloor_t *rover; ffloor_t *r2; fixed_t lowcut, highcut; +#ifdef ESLOPE + fixed_t lowcutslope, highcutslope; + + // Used for height comparisons and etc across FOFs and slopes + fixed_t high1, highslope1, low1, lowslope1, high2, highslope2, low2, lowslope2; +#endif //markceiling = markfloor = true; maskedtexture = true; @@ -2031,8 +2046,12 @@ void R_StoreWallRange(INT32 start, INT32 stop) ds_p->thicksidecol = maskedtexturecol = lastopening - rw_x; lastopening += rw_stopx - rw_x; - lowcut = frontsector->floorheight > backsector->floorheight ? frontsector->floorheight : backsector->floorheight; - highcut = frontsector->ceilingheight < backsector->ceilingheight ? frontsector->ceilingheight : backsector->ceilingheight; + lowcut = max(worldbottom, worldlow) + viewz; + highcut = min(worldtop, worldhigh) + viewz; +#ifdef ESLOPE + lowcutslope = max(worldbottomslope, worldlowslope) + viewz; + highcutslope = min(worldtopslope, worldhighslope) + viewz; +#endif if (frontsector->ffloors && backsector->ffloors) { @@ -2043,16 +2062,33 @@ void R_StoreWallRange(INT32 start, INT32 stop) continue; if (rover->flags & FF_INVERTSIDES) continue; - if (*rover->topheight < lowcut || *rover->bottomheight > highcut) - continue; if (rover->norender == leveltime) continue; +#ifdef ESLOPE + if (*rover->t_slope) { + high1 = P_GetZAt(*rover->t_slope, segleft.x, segleft.y); + highslope1 = P_GetZAt(*rover->t_slope, segright.x, segright.y); + } else + high1 = highslope1 = *rover->topheight; + if (*rover->b_slope) { + low1 = P_GetZAt(*rover->b_slope, segleft.x, segleft.y); + lowslope1 = P_GetZAt(*rover->b_slope, segright.x, segright.y); + } else + low1 = lowslope1 = *rover->bottomheight; + + if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope)) + continue; +#else + if (*rover->topheight < lowcut || *rover->bottomheight > highcut) + continue; +#endif + for (r2 = frontsector->ffloors; r2; r2 = r2->next) { if (!(r2->flags & FF_EXISTS) || !(r2->flags & FF_RENDERSIDES) - || *r2->topheight < lowcut || *r2->bottomheight > highcut) + || *r2->topheight < lowcut || *r2->bottomheight > highcut) ///TODO: make these account for slopes -Red continue; if (r2->norender == leveltime) @@ -2072,8 +2108,24 @@ void R_StoreWallRange(INT32 start, INT32 stop) continue; } +#ifdef ESLOPE + if (*r2->t_slope) { + high2 = P_GetZAt(*r2->t_slope, segleft.x, segleft.y); + highslope2 = P_GetZAt(*r2->t_slope, segright.x, segright.y); + } else + high2 = highslope2 = *r2->topheight; + if (*r2->b_slope) { + low2 = P_GetZAt(*r2->b_slope, segleft.x, segleft.y); + lowslope2 = P_GetZAt(*r2->b_slope, segright.x, segright.y); + } else + low2 = lowslope2 = *r2->bottomheight; + + if ((high1 > high2 && highslope1 > highslope2) || (low1 < low2 && lowslope1 < lowslope2)) + continue; +#else if (*rover->topheight > *r2->topheight || *rover->bottomheight < *r2->bottomheight) continue; +#endif break; } @@ -2090,16 +2142,33 @@ void R_StoreWallRange(INT32 start, INT32 stop) continue; if (!(rover->flags & FF_ALLSIDES)) continue; - if (*rover->topheight < lowcut || *rover->bottomheight > highcut) - continue; if (rover->norender == leveltime) continue; +#ifdef ESLOPE + if (*rover->t_slope) { + high1 = P_GetZAt(*rover->t_slope, segleft.x, segleft.y); + highslope1 = P_GetZAt(*rover->t_slope, segright.x, segright.y); + } else + high1 = highslope1 = *rover->topheight; + if (*rover->b_slope) { + low1 = P_GetZAt(*rover->b_slope, segleft.x, segleft.y); + lowslope1 = P_GetZAt(*rover->b_slope, segright.x, segright.y); + } else + low1 = lowslope1 = *rover->bottomheight; + + if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope)) + continue; +#else + if (*rover->topheight < lowcut || *rover->bottomheight > highcut) + continue; +#endif + for (r2 = backsector->ffloors; r2; r2 = r2->next) { if (!(r2->flags & FF_EXISTS) || !(r2->flags & FF_RENDERSIDES) - || *r2->topheight < lowcut || *r2->bottomheight > highcut) + || *r2->topheight < lowcut || *r2->bottomheight > highcut) ///TODO: make these account for slopes -Red continue; if (r2->norender == leveltime) @@ -2119,8 +2188,24 @@ void R_StoreWallRange(INT32 start, INT32 stop) continue; } +#ifdef ESLOPE + if (*r2->t_slope) { + high2 = P_GetZAt(*r2->t_slope, segleft.x, segleft.y); + highslope2 = P_GetZAt(*r2->t_slope, segright.x, segright.y); + } else + high2 = highslope2 = *r2->topheight; + if (*r2->b_slope) { + low2 = P_GetZAt(*r2->b_slope, segleft.x, segleft.y); + lowslope2 = P_GetZAt(*r2->b_slope, segright.x, segright.y); + } else + low2 = lowslope2 = *r2->bottomheight; + + if ((high1 > high2 && highslope1 > highslope2) || (low1 < low2 && lowslope1 < lowslope2)) + continue; +#else if (*rover->topheight > *r2->topheight || *rover->bottomheight < *r2->bottomheight) continue; +#endif break; } @@ -2137,11 +2222,21 @@ void R_StoreWallRange(INT32 start, INT32 stop) { if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS) || rover->flags & FF_INVERTSIDES) continue; - if (*rover->topheight <= frontsector->floorheight || *rover->bottomheight >= frontsector->ceilingheight) - continue; if (rover->norender == leveltime) continue; +#ifdef ESLOPE + // Oy vey. + if (( (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) <= worldbottom+viewz + && (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) <= worldbottomslope+viewz) + ||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) >= worldtop+viewz + && (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldtopslope+viewz)) + continue; +#else + if (*rover->topheight <= frontsector->floorheight || *rover->bottomheight >= frontsector->ceilingheight) + continue; +#endif + ds_p->thicksides[i] = rover; i++; } @@ -2152,12 +2247,27 @@ void R_StoreWallRange(INT32 start, INT32 stop) { if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_ALLSIDES)) continue; + if (rover->norender == leveltime) + continue; +#ifdef ESLOPE + // Oy vey. + if (( (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) <= worldbottom+viewz + && (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) <= worldbottomslope+viewz) + ||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) >= worldtop+viewz + && (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldtopslope+viewz)) + continue; + + if (( (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) <= worldlow+viewz + && (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) <= worldlowslope+viewz) + ||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) >= worldhigh+viewz + && (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldhighslope+viewz)) + continue; +#else if (*rover->topheight <= frontsector->floorheight || *rover->bottomheight >= frontsector->ceilingheight) continue; if (*rover->topheight <= backsector->floorheight || *rover->bottomheight >= backsector->ceilingheight) continue; - if (rover->norender == leveltime) - continue; +#endif ds_p->thicksides[i] = rover; i++; @@ -2355,8 +2465,14 @@ void R_StoreWallRange(INT32 start, INT32 stop) #endif ffloor[i].f_pos >>= 4; +#ifdef ESLOPE + ffloor[i].f_pos_slope >>= 4; + ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw_scale); + ffloor[i].f_step = ((centeryfrac>>4) - FixedMul(ffloor[i].f_pos_slope, ds_p->scale2) - ffloor[i].f_frac)/(stop-start+1); +#else ffloor[i].f_step = FixedMul(-rw_scalestep, ffloor[i].f_pos); ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw_scale); +#endif } } @@ -2405,6 +2521,10 @@ void R_StoreWallRange(INT32 start, INT32 stop) { ffloor_t * rover; i = 0; +#ifdef ESLOPE + fixed_t rovertest; + fixed_t planevistest; +#endif if (backsector->ffloors) { @@ -2415,6 +2535,48 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (rover->norender == leveltime) continue; +#ifdef ESLOPE + rovertest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz; + planevistest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : *rover->bottomheight); + + if (rovertest>>4 <= worldhigh && + rovertest>>4 >= worldlow && + ((viewz < planevistest && !(rover->flags & FF_INVERTPLANES)) || + (viewz > planevistest && (rover->flags & FF_BOTHPLANES)))) + { + ffloor[i].slope = *rover->b_slope; + ffloor[i].b_pos = (ffloor[i].slope ? P_GetZAt(ffloor[i].slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz; + ffloor[i].b_pos_slope = (ffloor[i].slope ? P_GetZAt(ffloor[i].slope, segright.x, segright.y) : *rover->bottomheight) - viewz; + ffloor[i].b_pos >>= 4; + ffloor[i].b_pos_slope >>= 4; + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); + ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(stop-start+1); + i++; + } + + if (i >= MAXFFLOORS) + break; + + rovertest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) - viewz; + planevistest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : *rover->topheight); + + if (rovertest>>4 <= worldhigh && + rovertest>>4 >= worldlow && + ((viewz > planevistest && !(rover->flags & FF_INVERTPLANES)) || + (viewz < planevistest && (rover->flags & FF_BOTHPLANES)))) + { + ffloor[i].slope = *rover->t_slope; + ffloor[i].b_pos = (ffloor[i].slope ? P_GetZAt(ffloor[i].slope, segleft.x, segleft.y) : *rover->topheight) - viewz; + ffloor[i].b_pos_slope = (ffloor[i].slope ? P_GetZAt(ffloor[i].slope, segright.x, segright.y) : *rover->topheight) - viewz; + ffloor[i].b_pos >>= 4; + ffloor[i].b_pos_slope >>= 4; + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); + ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(stop-start+1); + i++; + } +#else if (*rover->bottomheight <= backsector->ceilingheight && *rover->bottomheight >= backsector->floorheight && ((viewz < *rover->bottomheight && !(rover->flags & FF_INVERTPLANES)) || @@ -2426,8 +2588,10 @@ void R_StoreWallRange(INT32 start, INT32 stop) ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); i++; } + if (i >= MAXFFLOORS) break; + if (*rover->topheight >= backsector->floorheight && *rover->topheight <= backsector->ceilingheight && ((viewz > *rover->topheight && !(rover->flags & FF_INVERTPLANES)) || @@ -2439,6 +2603,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); i++; } +#endif } } else if (frontsector && frontsector->ffloors) @@ -2450,6 +2615,49 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (rover->norender == leveltime) continue; + +#ifdef ESLOPE + rovertest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz; + planevistest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : *rover->bottomheight); + + if (rovertest>>4 <= worldtop && + rovertest>>4 >= worldbottom && + ((viewz < planevistest && !(rover->flags & FF_INVERTPLANES)) || + (viewz > planevistest && (rover->flags & FF_BOTHPLANES)))) + { + ffloor[i].slope = *rover->b_slope; + ffloor[i].b_pos = (ffloor[i].slope ? P_GetZAt(ffloor[i].slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz; + ffloor[i].b_pos_slope = (ffloor[i].slope ? P_GetZAt(ffloor[i].slope, segright.x, segright.y) : *rover->bottomheight) - viewz; + ffloor[i].b_pos >>= 4; + ffloor[i].b_pos_slope >>= 4; + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); + ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(stop-start+1); + i++; + } + + if (i >= MAXFFLOORS) + break; + + rovertest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) - viewz; + planevistest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : *rover->topheight); + + if (rovertest>>4 <= worldtop && + rovertest>>4 >= worldbottom && + ((viewz > planevistest && !(rover->flags & FF_INVERTPLANES)) || + (viewz < planevistest && (rover->flags & FF_BOTHPLANES)))) + { + ffloor[i].slope = *rover->t_slope; + ffloor[i].b_pos = (ffloor[i].slope ? P_GetZAt(ffloor[i].slope, segleft.x, segleft.y) : *rover->topheight) - viewz; + ffloor[i].b_pos_slope = (ffloor[i].slope ? P_GetZAt(ffloor[i].slope, segright.x, segright.y) : *rover->topheight) - viewz; + ffloor[i].b_pos >>= 4; + ffloor[i].b_pos_slope >>= 4; + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); + ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(stop-start+1); + i++; + } +#else if (*rover->bottomheight <= frontsector->ceilingheight && *rover->bottomheight >= frontsector->floorheight && ((viewz < *rover->bottomheight && !(rover->flags & FF_INVERTPLANES)) || @@ -2474,6 +2682,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); i++; } +#endif } } #ifdef POLYOBJECTS_PLANES From c08253d796fcb146a8e3081db88b626598b9a77e Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Sat, 16 May 2015 23:04:54 -0500 Subject: [PATCH 47/91] FOF sides now render slopified too! --- src/r_defs.h | 3 +++ src/r_segs.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 60 insertions(+), 4 deletions(-) diff --git a/src/r_defs.h b/src/r_defs.h index 1f0f2a62d..b3667c05a 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -667,8 +667,11 @@ typedef struct drawseg_s INT16 *thicksidecol; INT32 numthicksides; fixed_t frontscale[MAXVIDWIDTH]; + #ifdef ESLOPE fixed_t maskedtextureheight[MAXVIDWIDTH]; // For handling sloped midtextures + + vertex_t leftpos, rightpos; // Used for rendering FOF walls with slopes #endif } drawseg_t; diff --git a/src/r_segs.c b/src/r_segs.c index a8f956a85..5d434b9a9 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -698,6 +698,10 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) r_lightlist_t *rlight; fixed_t lheight; line_t *newline = NULL; +#ifdef ESLOPE + // Render FOF sides kinda like normal sides, with the frac and step and everything + fixed_t top_frac, top_step, bottom_frac, bottom_step; +#endif void (*colfunc_2s) (column_t *); @@ -872,6 +876,34 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) column2s_length = textures[texnum]->height; } +#ifdef ESLOPE + // Set heights according to plane, or slope, whichever + { + fixed_t left_top, right_top, left_bottom, right_bottom; + + left_top = *pfloor->t_slope ? P_GetZAt(*pfloor->t_slope, ds->leftpos.x, ds->leftpos.y) : *pfloor->topheight; + right_top = *pfloor->t_slope ? P_GetZAt(*pfloor->t_slope, ds->rightpos.x, ds->rightpos.y) : *pfloor->topheight; + left_bottom = *pfloor->b_slope ? P_GetZAt(*pfloor->b_slope, ds->leftpos.x, ds->leftpos.y) : *pfloor->bottomheight; + right_bottom = *pfloor->b_slope ? P_GetZAt(*pfloor->b_slope, ds->rightpos.x, ds->rightpos.y) : *pfloor->bottomheight; + + left_top -= viewz; + right_top -= viewz; + left_bottom -= viewz; + right_bottom -= viewz; + + top_frac = centeryfrac - FixedMul(left_top, ds->scale1); + bottom_frac = centeryfrac - FixedMul(left_bottom, ds->scale1); + top_step = centeryfrac - FixedMul(right_top, ds->scale2); + bottom_step = centeryfrac - FixedMul(right_bottom, ds->scale2); + + top_step = (top_step-top_frac)/(ds->x2-ds->x1+1); + bottom_step = (bottom_step-bottom_frac)/(ds->x2-ds->x1+1); + + top_frac += top_step * (x1 - ds->x1); + bottom_frac += bottom_step * (x1 - ds->x1); + } +#endif + // draw the columns for (dc_x = x1; dc_x <= x2; dc_x++) { @@ -887,8 +919,16 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) INT32 solid = 0; INT32 lighteffect = 0; +#ifdef ESLOPE + sprtopscreen = windowtop = top_frac; + sprbotscreen = windowbottom = bottom_frac; + + top_frac += top_step; + bottom_frac += bottom_step; +#else sprtopscreen = windowtop = (centeryfrac - FixedMul((dc_texturemid - offsetvalue), spryscale)); sprbotscreen = windowbottom = FixedMul(*pfloor->topheight - *pfloor->bottomheight, spryscale) + sprtopscreen; +#endif // SoM: If column is out of range, why bother with it?? if (windowbottom < topbounds || windowtop > bottombounds) @@ -1030,11 +1070,24 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) || ((signed)dc_texturemid < 0 && (spryscale) && (signed)(dc_texturemid)>>FRACBITS < (INT32_MIN / spryscale))) { spryscale += rw_scalestep; +#ifdef ESLOPE + top_frac += top_step; + bottom_frac += bottom_step; +#endif continue; } +#ifdef ESLOPE + sprtopscreen = windowtop = top_frac; + sprbotscreen = windowbottom = bottom_frac; + + top_frac += top_step; + bottom_frac += bottom_step; +#else sprtopscreen = windowtop = (centeryfrac - FixedMul((dc_texturemid - offsetvalue), spryscale)); sprbotscreen = windowbottom = FixedMul(*pfloor->topheight - *pfloor->bottomheight, spryscale) + sprtopscreen; +#endif + dc_iscale = 0xffffffffu / (unsigned)spryscale; // draw the texture @@ -1571,8 +1624,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) det = a1*b2 - a2*b1; - segleft.x = FLOAT_TO_FIXED((b2*c1 - b1*c2)/det); - segleft.y = FLOAT_TO_FIXED((a1*c2 - a2*c1)/det); + ds_p->leftpos.x = segleft.x = FLOAT_TO_FIXED((b2*c1 - b1*c2)/det); + ds_p->leftpos.y = segleft.y = FLOAT_TO_FIXED((a1*c2 - a2*c1)/det); } // right @@ -1593,8 +1646,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) det = a1*b2 - a2*b1; - segright.x = FLOAT_TO_FIXED((b2*c1 - b1*c2)/det); - segright.y = FLOAT_TO_FIXED((a1*c2 - a2*c1)/det); + ds_p->rightpos.x = segright.x = FLOAT_TO_FIXED((b2*c1 - b1*c2)/det); + ds_p->rightpos.y = segright.y = FLOAT_TO_FIXED((a1*c2 - a2*c1)/det); } } From 8ba5b668531366686e8483ec1a82dca69795ddb0 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Sat, 16 May 2015 23:55:49 -0500 Subject: [PATCH 48/91] Slight optimization (don't get seg ends for slopes if there are no slopes) --- src/p_slopes.c | 6 ++++++ src/r_bsp.c | 8 ++++++++ src/r_defs.h | 2 ++ src/r_segs.c | 10 +++++++++- 4 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/p_slopes.c b/src/p_slopes.c index 9cd22f35b..60bd1087b 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -204,6 +204,8 @@ void P_SpawnSlope_Line(int linenum) // For FOF slopes, make a special function to copy to the xy origin & direction relative to the position of the FOF on the map! if(frontfloor || frontceil) { + line->frontsector->hasslope = true; // Tell the software renderer that we're sloped + origin.z = line->backsector->floorheight; direction.x = nx; direction.y = ny; @@ -327,6 +329,8 @@ void P_SpawnSlope_Line(int linenum) } if(backfloor || backceil) { + line->backsector->hasslope = true; // Tell the software renderer that we're sloped + origin.z = line->frontsector->floorheight; // Backsector direction.x = -nx; @@ -459,6 +463,8 @@ void P_CopySectorSlope(line_t *line) fsec->c_slope = srcsec->c_slope; //P_CopySlope(srcsec->c_slope); } + fsec->hasslope = true; + line->special = 0; // Linedef was use to set slopes, it finished its job, so now make it a normal linedef } diff --git a/src/r_bsp.c b/src/r_bsp.c index 283029ca5..8907ff42f 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -946,6 +946,10 @@ static void R_Subsector(size_t num) #ifdef ESLOPE ffloor[numffloors].slope = *rover->b_slope; + + // Tell the renderer this sector has slopes in it. + if (ffloor[numffloors].slope) + frontsector->hasslope = true; #endif ffloor[numffloors].height = @@ -983,6 +987,10 @@ static void R_Subsector(size_t num) #ifdef ESLOPE ffloor[numffloors].slope = *rover->t_slope; + + // Tell the renderer this sector has slopes in it. + if (ffloor[numffloors].slope) + frontsector->hasslope = true; #endif ffloor[numffloors].height = diff --git a/src/r_defs.h b/src/r_defs.h index b3667c05a..b5b589e77 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -391,7 +391,9 @@ typedef struct sector_s // Eternity engine slope pslope_t *f_slope; // floor slope pslope_t *c_slope; // ceiling slope + boolean hasslope; // The sector, or one of its visible FOFs, contains a slope #endif + // these are saved for netgames, so do not let Lua touch these! // offsets sector spawned with (via linedef type 7) diff --git a/src/r_segs.c b/src/r_segs.c index 5d434b9a9..a9d6c3024 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -1602,7 +1602,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) // and decide if floor / ceiling marks are needed #ifdef ESLOPE // Figure out map coordinates of where start and end are mapping to on seg, so we can clip right for slope bullshit - //if (frontsector->c_slope || frontsector->f_slope || (backsector && (backsector->c_slope || backsector->f_slope))) // Commenting this out for FOFslop. -Red + if (frontsector->hasslope || (backsector && backsector->hasslope)) // Commenting this out for FOFslop. -Red { angle_t temp; @@ -2589,6 +2589,10 @@ void R_StoreWallRange(INT32 start, INT32 stop) continue; #ifdef ESLOPE + // Let the renderer know this sector is sloped. + if (*rover->b_slope || *rover->t_slope) + backsector->hasslope = true; + rovertest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz; planevistest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : *rover->bottomheight); @@ -2670,6 +2674,10 @@ void R_StoreWallRange(INT32 start, INT32 stop) #ifdef ESLOPE + // Let the renderer know this sector is sloped. + if (*rover->b_slope || *rover->t_slope) + frontsector->hasslope = true; + rovertest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz; planevistest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : *rover->bottomheight); From d138f7e14fc0aba6cc878eb1532f5e4987b2ac90 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Sun, 17 May 2015 11:53:28 -0500 Subject: [PATCH 49/91] Collision with FOF slopes (might be unfinished, idk) --- src/p_local.h | 2 + src/p_map.c | 31 ++---- src/p_maputl.c | 68 +++++++----- src/p_mobj.c | 289 +++++++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 323 insertions(+), 67 deletions(-) diff --git a/src/p_local.h b/src/p_local.h index 2fd7bcbe2..472c0706e 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -234,6 +234,8 @@ void P_SceneryThinker(mobj_t *mobj); fixed_t P_GetFloorZ(mobj_t *mobj, sector_t *sector, fixed_t x, fixed_t y, line_t *line); fixed_t P_GetCeilingZ(mobj_t *mobj, sector_t *sector, fixed_t x, fixed_t y, line_t *line); +fixed_t P_GetFOFTopZ(mobj_t *mobj, sector_t *sector, ffloor_t *fof, fixed_t x, fixed_t y, line_t *line); +fixed_t P_GetFOFBottomZ(mobj_t *mobj, sector_t *sector, ffloor_t *fof, fixed_t x, fixed_t y, line_t *line); boolean P_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover); boolean P_CheckDeathPitCollide(mobj_t *mo); diff --git a/src/p_map.c b/src/p_map.c index 4b74b0f02..6257ede1b 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1244,15 +1244,8 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) if (!(rover->flags & FF_EXISTS)) continue; - fixed_t topheight = *rover->topheight; - fixed_t bottomheight = *rover->bottomheight; - -/*#ifdef ESLOPE - if (rover->t_slope) - topheight = P_GetZAt(rover->t_slope, thing->x, thing->y); - if (rover->b_slope) - bottomheight = P_GetZAt(rover->b_slope, thing->x, thing->y); -#endif*/ + fixed_t topheight = P_GetFOFTopZ(thing, newsubsec->sector, rover, x, y, NULL); + fixed_t bottomheight = P_GetFOFBottomZ(thing, newsubsec->sector, rover, x, y, NULL); if (rover->flags & FF_GOOWATER && !(thing->flags & MF_NOGRAVITY)) { @@ -1276,7 +1269,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) if (tmfloorz < topheight - sinklevel) { tmfloorz = topheight - sinklevel; #ifdef ESLOPE - tmfloorslope = NULL; + tmfloorslope = *rover->t_slope; #endif } } @@ -1285,7 +1278,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) if (tmceilingz > bottomheight + sinklevel) { tmceilingz = bottomheight + sinklevel; #ifdef ESLOPE - tmceilingslope = NULL; + tmceilingslope = *rover->b_slope; #endif } } @@ -1327,7 +1320,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) { tmfloorz = tmdropoffz = topheight; #ifdef ESLOPE - tmfloorslope = NULL; + tmfloorslope = *rover->t_slope; #endif } if (bottomheight < tmceilingz && abs(delta1) >= abs(delta2) @@ -1336,7 +1329,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) { tmceilingz = tmdrpoffceilz = bottomheight; #ifdef ESLOPE - tmceilingslope = NULL; + tmceilingslope = *rover->b_slope; #endif } } @@ -4010,12 +4003,12 @@ fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height) fixed_t topheight = *rover->topheight; fixed_t bottomheight = *rover->bottomheight; -/*#ifdef ESLOPE - if (rover->t_slope) - topheight = P_GetZAt(rover->t_slope, x, y); - if (rover->b_slope) - bottomheight = P_GetZAt(rover->b_slope, x, y); -#endif*/ +#ifdef ESLOPE + if (*rover->t_slope) + topheight = P_GetZAt(*rover->t_slope, x, y); + if (*rover->b_slope) + bottomheight = P_GetZAt(*rover->b_slope, x, y); +#endif if (rover->flags & FF_QUICKSAND) { diff --git a/src/p_maputl.c b/src/p_maputl.c index b5ac29507..4037d769b 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -659,6 +659,10 @@ void P_LineOpening(line_t *linedef) fixed_t highestfloor = openbottom; fixed_t lowestfloor = lowfloor; fixed_t delta1, delta2; +#ifdef ESLOPE + pslope_t *ceilingslope = opentopslope; + pslope_t *floorslope = openbottomslope; +#endif // Check for frontsector's fake floors for (rover = front->ffloors; rover; rover = rover->next) @@ -672,32 +676,32 @@ void P_LineOpening(line_t *linedef) || (rover->flags & FF_BLOCKOTHERS && !tmthing->player))) continue; - fixed_t topheight = *rover->topheight; - fixed_t bottomheight = *rover->bottomheight; - -/*#ifdef ESLOPE - if (rover->t_slope) - topheight = P_GetZAt(rover->t_slope, camera.x, camera.y); - - if (rover->b_slope) - bottomheight = P_GetZAt(rover->b_slope, camera.x, camera.y); -#endif*/ + fixed_t topheight = P_GetFOFTopZ(tmthing, front, rover, tmx, tmy, linedef); + fixed_t bottomheight = P_GetFOFBottomZ(tmthing, front, rover, tmx, tmy, linedef); delta1 = abs(tmthing->z - (bottomheight + ((topheight - bottomheight)/2))); delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2))); if (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF { - if (bottomheight < lowestceiling) + if (bottomheight < lowestceiling) { lowestceiling = bottomheight; +#ifdef ESLOPE + ceilingslope = *rover->b_slope; +#endif + } else if (bottomheight < highestceiling) highestceiling = bottomheight; } if (delta1 < delta2 && !(rover->flags & FF_REVERSEPLATFORM)) // thing is above FOF { - if (topheight > highestfloor) + if (topheight > highestfloor) { highestfloor = topheight; +#ifdef ESLOPE + floorslope = *rover->t_slope; +#endif + } else if (topheight > lowestfloor) lowestfloor = topheight; } @@ -715,32 +719,32 @@ void P_LineOpening(line_t *linedef) || (rover->flags & FF_BLOCKOTHERS && !tmthing->player))) continue; - fixed_t topheight = *rover->topheight; - fixed_t bottomheight = *rover->bottomheight; - -/*#ifdef ESLOPE - if (rover->t_slope) - topheight = P_GetZAt(rover->t_slope, tmthing->x, tmthing->y); - - if (rover->b_slope) - bottomheight = P_GetZAt(rover->b_slope, tmthing->x, tmthing->y); -#endif*/ + fixed_t topheight = P_GetFOFTopZ(tmthing, back, rover, tmx, tmy, linedef); + fixed_t bottomheight = P_GetFOFBottomZ(tmthing, back, rover, tmx, tmy, linedef); delta1 = abs(tmthing->z - (bottomheight + ((topheight - bottomheight)/2))); delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2))); if (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF { - if (bottomheight < lowestceiling) + if (bottomheight < lowestceiling) { lowestceiling = bottomheight; +#ifdef ESLOPE + ceilingslope = *rover->b_slope; +#endif + } else if (bottomheight < highestceiling) highestceiling = bottomheight; } if (delta1 < delta2 && !(rover->flags & FF_REVERSEPLATFORM)) // thing is above FOF { - if (topheight > highestfloor) + if (topheight > highestfloor) { highestfloor = topheight; +#ifdef ESLOPE + floorslope = *rover->t_slope; +#endif + } else if (topheight > lowestfloor) lowestfloor = topheight; } @@ -754,13 +758,21 @@ void P_LineOpening(line_t *linedef) delta1 = abs(tmthing->z - (polysec->floorheight + ((polysec->ceilingheight - polysec->floorheight)/2))); delta2 = abs(thingtop - (polysec->floorheight + ((polysec->ceilingheight - polysec->floorheight)/2))); - if (polysec->floorheight < lowestceiling && delta1 >= delta2) + if (polysec->floorheight < lowestceiling && delta1 >= delta2) { lowestceiling = polysec->floorheight; +#ifdef ESLOPE + ceilingslope = NULL; +#endif + } else if (polysec->floorheight < highestceiling && delta1 >= delta2) highestceiling = polysec->floorheight; - if (polysec->ceilingheight > highestfloor && delta1 < delta2) + if (polysec->ceilingheight > highestfloor && delta1 < delta2) { highestfloor = polysec->ceilingheight; +#ifdef ESLOPE + floorslope = NULL; +#endif + } else if (polysec->ceilingheight > lowestfloor && delta1 < delta2) lowestfloor = polysec->ceilingheight; } @@ -771,14 +783,14 @@ void P_LineOpening(line_t *linedef) if (highestfloor > openbottom) { openbottom = highestfloor; #ifdef ESLOPE - openbottomslope = NULL; + openbottomslope = floorslope; #endif } if (lowestceiling < opentop) { opentop = lowestceiling; #ifdef ESLOPE - opentopslope = NULL; + opentopslope = ceilingslope; #endif } diff --git a/src/p_mobj.c b/src/p_mobj.c index af832d585..421ec400a 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -706,12 +706,12 @@ boolean P_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover) fixed_t topheight = *rover->topheight; fixed_t bottomheight = *rover->bottomheight; -/*#ifdef ESLOPE - if (rover->t_slope) - topheight = P_GetZAt(rover->t_slope, mobj->x, mobj->y); - if (rover->b_slope) - bottomheight = P_GetZAt(rover->b_slope, mobj->x, mobj->y); -#endif*/ +#ifdef ESLOPE + if (*rover->t_slope) + topheight = P_GetZAt(*rover->t_slope, mobj->x, mobj->y); + if (*rover->b_slope) + bottomheight = P_GetZAt(*rover->b_slope, mobj->x, mobj->y); +#endif if (mobj->z > topheight) return false; @@ -967,6 +967,251 @@ fixed_t P_GetCeilingZ(mobj_t *mobj, sector_t *sector, fixed_t x, fixed_t y, line return sector->ceilingheight; } +// Do the same as above, but for FOFs! +fixed_t P_GetFOFTopZ(mobj_t *mobj, sector_t *sector, ffloor_t *fof, fixed_t x, fixed_t y, line_t *line) // SRB2CBTODO: This needs to be over all the code +{ + I_Assert(mobj != NULL); + I_Assert(sector != NULL); + I_Assert(fof != NULL); +#ifdef ESLOPE + if (*fof->t_slope) { + fixed_t testx, testy; + pslope_t *slope = *fof->t_slope; + + // Get the corner of the object that should be the highest on the slope + if (slope->d.x < 0) + testx = mobj->radius; + else + testx = -mobj->radius; + + if (slope->d.y < 0) + testy = mobj->radius; + else + testy = -mobj->radius; + + if (slope->zdelta > 0) { + testx = -testx; + testy = -testy; + } + + testx += x; + testy += y; + + // If the highest point is in the sector, then we have it easy! Just get the Z at that point + if (R_PointInSubsector(testx, testy)->sector == sector) + return P_GetZAt(slope, testx, testy); + + // If we're just testing for base sector location (no collision line), just go for the center's spot... + // It'll get fixed when we test for collision anyway, and the final result can't be lower than this + if (line == NULL) + return P_GetZAt(slope, x, y); + + // Alright, so we're sitting on a line that contains our slope sector, and need to figure out the highest point we're touching... + // The solution is simple! Get the line's vertices, and pull each one in along its line until it touches the object's bounding box + // (assuming it isn't already inside), then test each point's slope Z and return the higher of the two. + { + vertex_t v1, v2; + v1.x = line->v1->x; + v1.y = line->v1->y; + v2.x = line->v2->x; + v2.y = line->v2->y; + + /*CONS_Printf("BEFORE: v1 = %f %f %f\n", + FIXED_TO_FLOAT(v1.x), + FIXED_TO_FLOAT(v1.y), + FIXED_TO_FLOAT(P_GetZAt(slope, v1.x, v1.y)) + ); + CONS_Printf(" v2 = %f %f %f\n", + FIXED_TO_FLOAT(v2.x), + FIXED_TO_FLOAT(v2.y), + FIXED_TO_FLOAT(P_GetZAt(slope, v2.x, v2.y)) + );*/ + + if (abs(v1.x-x) > mobj->radius) { + // v1's x is out of range, so rein it in + fixed_t diff = abs(v1.x-x) - mobj->radius; + + if (v1.x < x) { // Moving right + v1.x += diff; + v1.y += FixedMul(diff, FixedDiv(line->dy, line->dx)); + } else { // Moving left + v1.x -= diff; + v1.y -= FixedMul(diff, FixedDiv(line->dy, line->dx)); + } + } + + if (abs(v1.y-y) > mobj->radius) { + // v1's y is out of range, so rein it in + fixed_t diff = abs(v1.y-y) - mobj->radius; + + if (v1.y < y) { // Moving up + v1.y += diff; + v1.x += FixedMul(diff, FixedDiv(line->dx, line->dy)); + } else { // Moving down + v1.y -= diff; + v1.x -= FixedMul(diff, FixedDiv(line->dx, line->dy)); + } + } + + if (abs(v2.x-x) > mobj->radius) { + // v1's x is out of range, so rein it in + fixed_t diff = abs(v2.x-x) - mobj->radius; + + if (v2.x < x) { // Moving right + v2.x += diff; + v2.y += FixedMul(diff, FixedDiv(line->dy, line->dx)); + } else { // Moving left + v2.x -= diff; + v2.y -= FixedMul(diff, FixedDiv(line->dy, line->dx)); + } + } + + if (abs(v2.y-y) > mobj->radius) { + // v2's y is out of range, so rein it in + fixed_t diff = abs(v2.y-y) - mobj->radius; + + if (v2.y < y) { // Moving up + v2.y += diff; + v2.x += FixedMul(diff, FixedDiv(line->dx, line->dy)); + } else { // Moving down + v2.y -= diff; + v2.x -= FixedMul(diff, FixedDiv(line->dx, line->dy)); + } + } + + /*CONS_Printf("AFTER: v1 = %f %f %f\n", + FIXED_TO_FLOAT(v1.x), + FIXED_TO_FLOAT(v1.y), + FIXED_TO_FLOAT(P_GetZAt(slope, v1.x, v1.y)) + ); + CONS_Printf(" v2 = %f %f %f\n", + FIXED_TO_FLOAT(v2.x), + FIXED_TO_FLOAT(v2.y), + FIXED_TO_FLOAT(P_GetZAt(slope, v2.x, v2.y)) + );*/ + + // Return the higher of the two points + return max( + P_GetZAt(slope, v1.x, v1.y), + P_GetZAt(slope, v2.x, v2.y) + ); + } + } else // Well, that makes it easy. Just get the top height +#endif + return *fof->topheight; +} + +fixed_t P_GetFOFBottomZ(mobj_t *mobj, sector_t *sector, ffloor_t *fof, fixed_t x, fixed_t y, line_t *line) // SRB2CBTODO: This needs to be over all the code +{ + I_Assert(mobj != NULL); + I_Assert(sector != NULL); + I_Assert(fof != NULL); +#ifdef ESLOPE + if (*fof->t_slope) { + fixed_t testx, testy; + pslope_t *slope = *fof->t_slope; + + // Get the corner of the object that should be the lowest on the slope + if (slope->d.x < 0) + testx = mobj->radius; + else + testx = -mobj->radius; + + if (slope->d.y < 0) + testy = mobj->radius; + else + testy = -mobj->radius; + + if (slope->zdelta < 0) { + testx = -testx; + testy = -testy; + } + + testx += x; + testy += y; + + // If the lowest point is in the sector, then we have it easy! Just get the Z at that point + if (R_PointInSubsector(testx, testy)->sector == sector) + return P_GetZAt(slope, testx, testy); + + // If we're just testing for base sector location (no collision line), just go for the center's spot... + // It'll get fixed when we test for collision anyway, and the final result can't be higher than this + if (line == NULL) + return P_GetZAt(slope, x, y); + + // Alright, so we're sitting on a line that contains our slope sector, and need to figure out the highest point we're touching... + // The solution is simple! Get the line's vertices, and pull each one in along its line until it touches the object's bounding box + // (assuming it isn't already inside), then test each point's slope Z and return the lower of the two. + { + vertex_t v1, v2; + v1.x = line->v1->x; + v1.y = line->v1->y; + v2.x = line->v2->x; + v2.y = line->v2->y; + + if (abs(v1.x-x) > mobj->radius) { + // v1's x is out of range, so rein it in + fixed_t diff = abs(v1.x-x) - mobj->radius; + + if (v1.x < x) { // Moving right + v1.x += diff; + v1.y += FixedMul(diff, FixedDiv(line->dy, line->dx)); + } else { // Moving left + v1.x -= diff; + v1.y -= FixedMul(diff, FixedDiv(line->dy, line->dx)); + } + } + + if (abs(v1.y-y) > mobj->radius) { + // v1's y is out of range, so rein it in + fixed_t diff = abs(v1.y-y) - mobj->radius; + + if (v1.y < y) { // Moving up + v1.y += diff; + v1.x += FixedMul(diff, FixedDiv(line->dx, line->dy)); + } else { // Moving down + v1.y -= diff; + v1.x -= FixedMul(diff, FixedDiv(line->dx, line->dy)); + } + } + + if (abs(v2.x-x) > mobj->radius) { + // v1's x is out of range, so rein it in + fixed_t diff = abs(v2.x-x) - mobj->radius; + + if (v2.x < x) { // Moving right + v2.x += diff; + v2.y += FixedMul(diff, FixedDiv(line->dy, line->dx)); + } else { // Moving left + v2.x -= diff; + v2.y -= FixedMul(diff, FixedDiv(line->dy, line->dx)); + } + } + + if (abs(v2.y-y) > mobj->radius) { + // v2's y is out of range, so rein it in + fixed_t diff = abs(v2.y-y) - mobj->radius; + + if (v2.y < y) { // Moving up + v2.y += diff; + v2.x += FixedMul(diff, FixedDiv(line->dx, line->dy)); + } else { // Moving down + v2.y -= diff; + v2.x -= FixedMul(diff, FixedDiv(line->dx, line->dy)); + } + } + + // Return the lower of the two points + return min( + P_GetZAt(slope, v1.x, v1.y), + P_GetZAt(slope, v2.x, v2.y) + ); + } + } else // Well, that makes it easy. Just get the bottom height +#endif + return *fof->bottomheight; +} + static void P_PlayerFlip(mobj_t *mo) { if (!mo->player) @@ -1710,6 +1955,7 @@ static void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motyp { ffloor_t *rover; fixed_t delta1, delta2, thingtop; + fixed_t topheight, bottomheight; I_Assert(mo != NULL); I_Assert(!P_MobjWasRemoved(mo)); @@ -1721,6 +1967,9 @@ static void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motyp if (!(rover->flags & FF_EXISTS)) continue; + topheight = P_GetFOFTopZ(mo, sector, rover, mo->x, mo->y, NULL); + bottomheight = P_GetFOFBottomZ(mo, sector, rover, mo->x, mo->y, NULL); + if (mo->player && (P_CheckSolidLava(mo, rover) || P_CanRunOnWater(mo->player, rover))) // only the player should be affected ; else if (motype != 0 && rover->flags & FF_SWIMMABLE) // "scenery" only @@ -1735,14 +1984,14 @@ static void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motyp switch (motype) { case 2: // scenery does things differently for some reason - if (mo->z < *rover->topheight && *rover->bottomheight < thingtop) + if (mo->z < topheight && bottomheight < thingtop) { mo->floorz = mo->z; continue; } break; default: - if (mo->z < *rover->topheight && *rover->bottomheight < thingtop) + if (mo->z < topheight && bottomheight < thingtop) { if (mo->floorz < mo->z) mo->floorz = mo->z; @@ -1751,17 +2000,17 @@ static void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motyp } } - delta1 = mo->z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2)); - delta2 = thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2)); - if (*rover->topheight > mo->floorz && abs(delta1) < abs(delta2) + delta1 = mo->z - (bottomheight + ((topheight - bottomheight)/2)); + delta2 = thingtop - (bottomheight + ((topheight - bottomheight)/2)); + if (topheight > mo->floorz && abs(delta1) < abs(delta2) && !(rover->flags & FF_REVERSEPLATFORM)) { - mo->floorz = *rover->topheight; + mo->floorz = topheight; } - if (*rover->bottomheight < mo->ceilingz && abs(delta1) >= abs(delta2) + if (bottomheight < mo->ceilingz && abs(delta1) >= abs(delta2) && !(rover->flags & FF_PLATFORM)) { - mo->ceilingz = *rover->bottomheight; + mo->ceilingz = bottomheight; } } } @@ -2804,13 +3053,13 @@ void P_MobjCheckWater(mobj_t *mobj) fixed_t topheight = *rover->topheight; fixed_t bottomheight = *rover->bottomheight; -/*#ifdef ESLOPE - if (rover->t_slope) - topheight = P_GetZAt(rover->t_slope, mobj->x, mobj->y); +#ifdef ESLOPE + if (*rover->t_slope) + topheight = P_GetZAt(*rover->t_slope, mobj->x, mobj->y); - if (rover->b_slope) - bottomheight = P_GetZAt(rover->b_slope, mobj->x, mobj->y); -#endif*/ + if (*rover->b_slope) + bottomheight = P_GetZAt(*rover->b_slope, mobj->x, mobj->y); +#endif if (mobj->eflags & MFE_VERTICALFLIP) { From 780c568aafd0dcaaf5105d2b0c5ea3f7f3a93d1f Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Sun, 17 May 2015 12:03:52 -0500 Subject: [PATCH 50/91] Fix sprite-to-plane sorting on sloped FOFs --- src/r_things.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index a759dd1d0..0de6a1282 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1752,24 +1752,32 @@ static void R_CreateDrawNodes(void) { if (r2->plane) { + fixed_t planeobjectz; if (r2->plane->minx > rover->x2 || r2->plane->maxx < rover->x1) continue; if (rover->szt > r2->plane->low || rover->sz < r2->plane->high) continue; + // Gotta get the plane's height AT THE OBJECT POSITION if we're using slopes -Red + planeobjectz = +#ifdef ESLOPE + r2->plane->slope ? P_GetZAt(r2->plane->slope, rover->gx, rover->gy) : +#endif + r2->plane->height; + if (rover->mobjflags & MF_NOCLIPHEIGHT) { //Objects with NOCLIPHEIGHT can appear halfway in. - if (r2->plane->height < viewz && rover->pz+(rover->thingheight/2) >= r2->plane->height) + if (r2->plane->height < viewz && rover->pz+(rover->thingheight/2) >= planeobjectz) continue; - if (r2->plane->height > viewz && rover->pzt-(rover->thingheight/2) <= r2->plane->height) + if (r2->plane->height > viewz && rover->pzt-(rover->thingheight/2) <= planeobjectz) continue; } else { - if (r2->plane->height < viewz && rover->pz >= r2->plane->height) + if (r2->plane->height < viewz && rover->pz >= planeobjectz) continue; - if (r2->plane->height > viewz && rover->pzt <= r2->plane->height) + if (r2->plane->height > viewz && rover->pzt <= planeobjectz) continue; } From 0af3852273c0252dbc46a2783d5319869113f2fd Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Sun, 17 May 2015 12:24:20 -0500 Subject: [PATCH 51/91] Add translucent slope renderer --- src/r_draw.h | 1 + src/r_draw8.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/r_plane.c | 5 +- 3 files changed, 138 insertions(+), 1 deletion(-) diff --git a/src/r_draw.h b/src/r_draw.h index fa2cb22d0..1116e1c25 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -149,6 +149,7 @@ void R_DrawTranslatedTranslucentColumn_8(void); void R_DrawSpan_8(void); #ifdef ESLOPE void R_DrawTiltedSpan_8(void); +void R_DrawTiltedTranslucentSpan_8(void); #endif void R_DrawSplat_8(void); void R_DrawTranslucentSplat_8(void); diff --git a/src/r_draw8.c b/src/r_draw8.c index b8b23b1b3..a028b9c12 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -682,6 +682,139 @@ void R_DrawTiltedSpan_8(void) } #endif } + + +/** \brief The R_DrawTiltedTranslucentSpan_8 function + Like DrawTiltedSpan, but translucent +*/ +void R_DrawTiltedTranslucentSpan_8(void) +{ + // x1, x2 = ds_x1, ds_x2 + int width = ds_x2 - ds_x1; + double iz, uz, vz; + UINT32 u, v; + int i; + + UINT8 *source; + UINT8 *colormap; + UINT8 *dest; + + iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx); + + // Lighting is simple. It's just linear interpolation from start to end + { + float planelightfloat = BASEVIDWIDTH*BASEVIDWIDTH/vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f; + float lightstart, lightend; + + lightend = (iz + ds_sz.x*width) * planelightfloat; + lightstart = iz * planelightfloat; + + R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend)); + //CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf); + } + + uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx); + vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx); + + dest = ylookup[ds_y] + columnofs[ds_x1]; + source = ds_source; + //colormap = ds_colormap; + +#if 0 // The "perfect" reference version of this routine. Pretty slow. + // Use it only to see how things are supposed to look. + i = 0; + do + { + double z = 1.f/iz; + u = (UINT32)(uz*z) + viewx; + v = (UINT32)(vz*z) + viewy; + + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + + *dest = colormap[*(ds_transmap + (source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)] << 8) + dest[0])]; + dest++; + iz += ds_sz.x; + uz += ds_su.x; + vz += ds_sv.x; + } while (--width >= 0); +#else +#define SPANSIZE 16 +#define INVSPAN 0.0625f + + double startz = 1.f/iz; + double startu = uz*startz; + double startv = vz*startz; + double izstep, uzstep, vzstep; + + izstep = ds_sz.x * SPANSIZE; + uzstep = ds_su.x * SPANSIZE; + vzstep = ds_sv.x * SPANSIZE; + //x1 = 0; + width++; + + while (width >= SPANSIZE) + { + iz += izstep; + uz += uzstep; + vz += vzstep; + + double endz = 1.f/iz; + double endu = uz*endz; + double endv = vz*endz; + UINT32 stepu = (UINT32)((endu - startu) * INVSPAN); + UINT32 stepv = (UINT32)((endv - startv) * INVSPAN); + u = (UINT32)(startu) + viewx; + v = (UINT32)(startv) + viewy; + + for (i = SPANSIZE-1; i >= 0; i--) + { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + *dest = colormap[*(ds_transmap + (source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)] << 8) + dest[0])]; + dest++; + u += stepu; + v += stepv; + } + startu = endu; + startv = endv; + width -= SPANSIZE; + } + if (width > 0) + { + if (width == 1) + { + u = (UINT32)(startu); + v = (UINT32)(startv); + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + *dest = colormap[*(ds_transmap + (source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)] << 8) + dest[0])]; + } + else + { + double left = width; + iz += ds_sz.x * left; + uz += ds_su.x * left; + vz += ds_sv.x * left; + + double endz = 1.f/iz; + double endu = uz*endz; + double endv = vz*endz; + left = 1.f/left; + UINT32 stepu = (UINT32)((endu - startu) * left); + UINT32 stepv = (UINT32)((endv - startv) * left); + u = (UINT32)(startu) + viewx; + v = (UINT32)(startv) + viewy; + + for (; width != 0; width--) + { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + *dest = colormap[*(ds_transmap + (source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)] << 8) + dest[0])]; + dest++; + u += stepu; + v += stepv; + } + } + } +#endif +} #endif // ESLOPE /** \brief The R_DrawSplat_8 function diff --git a/src/r_plane.c b/src/r_plane.c index c39be11a9..b0768539b 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -990,7 +990,10 @@ void R_DrawSinglePlane(visplane_t *pl) ds_sv.z *= SFMULT; #undef SFMULT - spanfunc = R_DrawTiltedSpan_8; + if (spanfunc == R_DrawTranslucentSpan_8) + spanfunc = R_DrawTiltedTranslucentSpan_8; + else + spanfunc = R_DrawTiltedSpan_8; planezlight = scalelight[light]; } else From 41573b118c42f4457f6dc6f5dac08785a87d4d16 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Sun, 17 May 2015 12:36:06 -0500 Subject: [PATCH 52/91] I'm a dumbass --- src/p_mobj.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 421ec400a..013f523c6 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1107,9 +1107,9 @@ fixed_t P_GetFOFBottomZ(mobj_t *mobj, sector_t *sector, ffloor_t *fof, fixed_t x I_Assert(sector != NULL); I_Assert(fof != NULL); #ifdef ESLOPE - if (*fof->t_slope) { + if (*fof->b_slope) { fixed_t testx, testy; - pslope_t *slope = *fof->t_slope; + pslope_t *slope = *fof->b_slope; // Get the corner of the object that should be the lowest on the slope if (slope->d.x < 0) From e83844796e5dd4af6c5c7205c708364d0fad502b Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Sun, 17 May 2015 21:49:13 -0500 Subject: [PATCH 53/91] Proper sorting fix for sloped FOFs and sprites --- src/r_things.c | 43 +++++++++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 0de6a1282..c83fdf03e 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1752,32 +1752,34 @@ static void R_CreateDrawNodes(void) { if (r2->plane) { - fixed_t planeobjectz; + fixed_t planeobjectz, planecameraz; if (r2->plane->minx > rover->x2 || r2->plane->maxx < rover->x1) continue; if (rover->szt > r2->plane->low || rover->sz < r2->plane->high) continue; - // Gotta get the plane's height AT THE OBJECT POSITION if we're using slopes -Red - planeobjectz = #ifdef ESLOPE - r2->plane->slope ? P_GetZAt(r2->plane->slope, rover->gx, rover->gy) : + // Effective height may be different for each comparison in the case of slopes + if (r2->plane->slope) { + planeobjectz = P_GetZAt(r2->plane->slope, rover->gx, rover->gy); + planecameraz = P_GetZAt(r2->plane->slope, viewx, viewy); + } else #endif - r2->plane->height; + planeobjectz = planecameraz = r2->plane->height; if (rover->mobjflags & MF_NOCLIPHEIGHT) { //Objects with NOCLIPHEIGHT can appear halfway in. - if (r2->plane->height < viewz && rover->pz+(rover->thingheight/2) >= planeobjectz) + if (planecameraz < viewz && rover->pz+(rover->thingheight/2) >= planeobjectz) continue; - if (r2->plane->height > viewz && rover->pzt-(rover->thingheight/2) <= planeobjectz) + if (planecameraz > viewz && rover->pzt-(rover->thingheight/2) <= planeobjectz) continue; } else { - if (r2->plane->height < viewz && rover->pz >= planeobjectz) + if (planecameraz < viewz && rover->pz >= planeobjectz) continue; - if (r2->plane->height > viewz && rover->pzt <= planeobjectz) + if (planecameraz > viewz && rover->pzt <= planeobjectz) continue; } @@ -1807,6 +1809,7 @@ static void R_CreateDrawNodes(void) } else if (r2->thickseg) { + fixed_t topplaneobjectz, topplanecameraz, botplaneobjectz, botplanecameraz; if (rover->x1 > r2->thickseg->x2 || rover->x2 < r2->thickseg->x1) continue; @@ -1817,9 +1820,25 @@ static void R_CreateDrawNodes(void) if (scale <= rover->scale) continue; - if ((*r2->ffloor->topheight > viewz && *r2->ffloor->bottomheight < viewz) || - (*r2->ffloor->topheight < viewz && rover->gzt < *r2->ffloor->topheight) || - (*r2->ffloor->bottomheight > viewz && rover->gz > *r2->ffloor->bottomheight)) +#ifdef ESLOPE + if (*r2->ffloor->t_slope) { + topplaneobjectz = P_GetZAt(*r2->ffloor->t_slope, rover->gx, rover->gy); + topplanecameraz = P_GetZAt(*r2->ffloor->t_slope, viewx, viewy); + } else +#endif + topplaneobjectz = topplanecameraz = *r2->ffloor->topheight; + +#ifdef ESLOPE + if (*r2->ffloor->b_slope) { + botplaneobjectz = P_GetZAt(*r2->ffloor->b_slope, rover->gx, rover->gy); + botplanecameraz = P_GetZAt(*r2->ffloor->b_slope, viewx, viewy); + } else +#endif + botplaneobjectz = botplanecameraz = *r2->ffloor->bottomheight; + + if ((topplanecameraz > viewz && botplanecameraz < viewz) || + (topplanecameraz < viewz && rover->gzt < topplaneobjectz) || + (botplanecameraz > viewz && rover->gz > botplaneobjectz)) { entry = R_CreateDrawNode(NULL); (entry->prev = r2->prev)->next = entry; From e7bc004bbf19cac95825eef47a8def3175b3592d Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Sun, 17 May 2015 23:51:38 -0500 Subject: [PATCH 54/91] Sloped lights n shit --- src/r_bsp.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++-- src/r_defs.h | 3 +++ src/r_segs.c | 57 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 125 insertions(+), 2 deletions(-) diff --git a/src/r_bsp.c b/src/r_bsp.c index 8907ff42f..35f82f01c 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -851,11 +851,19 @@ static void R_Subsector(size_t num) sub->sector->moved = frontsector->moved = false; } - light = R_GetPlaneLight(frontsector, frontsector->floorheight, false); + light = R_GetPlaneLight(frontsector, +#ifdef ESLOPE + frontsector->f_slope ? P_GetZAt(frontsector->f_slope, frontsector->soundorg.x, frontsector->soundorg.y) : +#endif + frontsector->floorheight, false); if (frontsector->floorlightsec == -1) floorlightlevel = *frontsector->lightlist[light].lightlevel; floorcolormap = frontsector->lightlist[light].extra_colormap; - light = R_GetPlaneLight(frontsector, frontsector->ceilingheight, false); + light = R_GetPlaneLight(frontsector, +#ifdef ESLOPE + frontsector->c_slope ? P_GetZAt(frontsector->c_slope, frontsector->soundorg.x, frontsector->soundorg.y) : +#endif + frontsector->ceilingheight, false); if (frontsector->ceilinglightsec == -1) ceilinglightlevel = *frontsector->lightlist[light].lightlevel; ceilingcolormap = frontsector->lightlist[light].extra_colormap; @@ -934,8 +942,14 @@ static void R_Subsector(size_t num) && ((viewz < heightcheck && !(rover->flags & FF_INVERTPLANES)) || (viewz > heightcheck && (rover->flags & FF_BOTHPLANES)))) { +#ifdef ESLOPE + light = R_GetPlaneLight(frontsector, + *rover->b_slope ? P_GetZAt(*rover->b_slope, frontsector->soundorg.x, frontsector->soundorg.y) : *rover->bottomheight, + viewz < (*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : *rover->bottomheight)); +#else light = R_GetPlaneLight(frontsector, *rover->bottomheight, viewz < *rover->bottomheight); +#endif ffloor[numffloors].plane = R_FindPlane(*rover->bottomheight, *rover->bottompic, *frontsector->lightlist[light].lightlevel, *rover->bottomxoffs, *rover->bottomyoffs, *rover->bottomangle, frontsector->lightlist[light].extra_colormap, rover @@ -976,7 +990,13 @@ static void R_Subsector(size_t num) && ((viewz > heightcheck && !(rover->flags & FF_INVERTPLANES)) || (viewz < heightcheck && (rover->flags & FF_BOTHPLANES)))) { +#ifdef ESLOPE + light = R_GetPlaneLight(frontsector, + *rover->t_slope ? P_GetZAt(*rover->t_slope, frontsector->soundorg.x, frontsector->soundorg.y) : *rover->topheight, + viewz < (*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : *rover->topheight)); +#else light = R_GetPlaneLight(frontsector, *rover->topheight, viewz < *rover->topheight); +#endif ffloor[numffloors].plane = R_FindPlane(*rover->topheight, *rover->toppic, *frontsector->lightlist[light].lightlevel, *rover->topxoffs, *rover->topyoffs, *rover->topangle, frontsector->lightlist[light].extra_colormap, rover @@ -1158,6 +1178,11 @@ void R_Prep3DFloors(sector_t *sector) fixed_t bestheight, maxheight; INT32 count, i, mapnum; sector_t *sec; +#ifdef ESLOPE + pslope_t *bestslope; + fixed_t heighttest; // I think it's better to check the Z height at the sector's center + // than assume unsloped heights are accurate indicators of order in sloped sectors. -Red +#endif count = 1; for (rover = sector->ffloors; rover; rover = rover->next) @@ -1180,7 +1205,13 @@ void R_Prep3DFloors(sector_t *sector) else memset(sector->lightlist, 0, sizeof (lightlist_t) * count); +#ifdef ESLOPE + heighttest = sector->c_slope ? P_GetZAt(sector->c_slope, sector->soundorg.x, sector->soundorg.y) : sector->ceilingheight; + + sector->lightlist[0].height = heighttest + 1; +#else sector->lightlist[0].height = sector->ceilingheight + 1; +#endif sector->lightlist[0].lightlevel = §or->lightlevel; sector->lightlist[0].caster = NULL; sector->lightlist[0].extra_colormap = sector->extra_colormap; @@ -1198,6 +1229,29 @@ void R_Prep3DFloors(sector_t *sector) && !(rover->flags & FF_CUTLEVEL) && !(rover->flags & FF_CUTSPRITES))) continue; +#ifdef ESLOPE + heighttest = *rover->t_slope ? P_GetZAt(*rover->t_slope, sector->soundorg.x, sector->soundorg.y) : *rover->topheight; + + if (heighttest > bestheight && heighttest < maxheight) + { + best = rover; + bestheight = heighttest; + bestslope = *rover->t_slope; + continue; + } + if (rover->flags & FF_DOUBLESHADOW) { + heighttest = *rover->b_slope ? P_GetZAt(*rover->b_slope, sector->soundorg.x, sector->soundorg.y) : *rover->bottomheight; + + if (heighttest > bestheight + && heighttest < maxheight) + { + best = rover; + bestheight = heighttest; + bestslope = *rover->b_slope; + continue; + } + } +#else if (*rover->topheight > bestheight && *rover->topheight < maxheight) { best = rover; @@ -1211,6 +1265,7 @@ void R_Prep3DFloors(sector_t *sector) bestheight = *rover->bottomheight; continue; } +#endif } if (!best) { @@ -1221,6 +1276,9 @@ void R_Prep3DFloors(sector_t *sector) sector->lightlist[i].height = maxheight = bestheight; sector->lightlist[i].caster = best; sector->lightlist[i].flags = best->flags; +#ifdef ESLOPE + sector->lightlist[i].slope = bestslope; +#endif sec = §ors[best->secnum]; mapnum = sec->midmap; if (mapnum >= 0 && (size_t)mapnum < num_extra_colormaps) @@ -1246,7 +1304,12 @@ void R_Prep3DFloors(sector_t *sector) if (best->flags & FF_DOUBLESHADOW) { +#ifdef ESLOPE + heighttest = *best->b_slope ? P_GetZAt(*best->b_slope, sector->soundorg.x, sector->soundorg.y) : *best->bottomheight; + if (bestheight == heighttest) ///TODO: do this in a more efficient way -Red +#else if (bestheight == *best->bottomheight) +#endif { sector->lightlist[i].lightlevel = sector->lightlist[best->lastlight].lightlevel; sector->lightlist[i].extra_colormap = diff --git a/src/r_defs.h b/src/r_defs.h index b5b589e77..27e4b9170 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -190,6 +190,9 @@ typedef struct lightlist_s extracolormap_t *extra_colormap; INT32 flags; ffloor_t *caster; +#ifdef ESLOPE + struct pslope_s *slope; // FF_DOUBLESHADOW makes me have to store this pointer here. Bluh bluh. +#endif } lightlist_t; diff --git a/src/r_segs.c b/src/r_segs.c index a9d6c3024..ce0260a63 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -2478,26 +2478,83 @@ void R_StoreWallRange(INT32 start, INT32 stop) for (i = p = 0; i < dc_numlights; i++) { +#ifdef ESLOPE + fixed_t leftheight, rightheight; +#endif + light = &frontsector->lightlist[i]; rlight = &dc_lightlist[p]; +#ifdef ESLOPE + if (light->slope) { + leftheight = P_GetZAt(light->slope, segleft.x, segleft.y); + rightheight = P_GetZAt(light->slope, segright.x, segright.y); + + // Flag sector as having slopes + frontsector->hasslope = true; + } else + leftheight = rightheight = light->height; + + leftheight -= viewz; + rightheight -= viewz; + + leftheight >>= 4; + rightheight >>= 4; +#endif + if (i != 0) { +#ifdef ESLOPE + if (leftheight < worldbottom && rightheight < worldbottomslope) + continue; + + if (leftheight > worldtop && rightheight > worldtopslope && i+1 < dc_numlights && frontsector->lightlist[i+1].height > frontsector->ceilingheight) + continue; +#else if (light->height < frontsector->floorheight) continue; if (light->height > frontsector->ceilingheight && i+1 < dc_numlights && frontsector->lightlist[i+1].height > frontsector->ceilingheight) continue; +#endif } +#ifdef ESLOPE + rlight->height = (centeryfrac>>4) - FixedMul(leftheight, rw_scale); + rlight->heightstep = (centeryfrac>>4) - FixedMul(rightheight, ds_p->scale2); + rlight->heightstep = (rlight->heightstep-rlight->height)/(stop-start+1); +#else rlight->height = (centeryfrac>>4) - FixedMul((light->height - viewz) >> 4, rw_scale); rlight->heightstep = -FixedMul (rw_scalestep, (light->height - viewz) >> 4); +#endif rlight->flags = light->flags; if (light->caster && light->caster->flags & FF_SOLID) { +#ifdef ESLOPE + if (*light->caster->b_slope) { + leftheight = P_GetZAt(*light->caster->b_slope, segleft.x, segleft.y); + rightheight = P_GetZAt(*light->caster->b_slope, segright.x, segright.y); + + // Flag sector as having slopes + frontsector->hasslope = true; + } else + leftheight = rightheight = *light->caster->bottomheight; + + leftheight -= viewz; + rightheight -= viewz; + + leftheight >>= 4; + rightheight >>= 4; + + rlight->botheight = (centeryfrac>>4) - FixedMul(leftheight, rw_scale); + rlight->botheightstep = (centeryfrac>>4) - FixedMul(rightheight, ds_p->scale2); + rlight->botheightstep = (rlight->botheightstep-rlight->botheight)/(stop-start+1); + +#else rlight->botheight = (centeryfrac >> 4) - FixedMul((*light->caster->bottomheight - viewz) >> 4, rw_scale); rlight->botheightstep = -FixedMul (rw_scalestep, (*light->caster->bottomheight - viewz) >> 4); +#endif } rlight->lightlevel = *light->lightlevel; From 1376f399d3f8053e4090121995e627b13d6ed571 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Mon, 18 May 2015 00:23:44 -0500 Subject: [PATCH 55/91] Sprite lighting obeys the slope overlords now --- src/r_things.c | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index c83fdf03e..3a38eb482 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -950,12 +950,22 @@ static void R_SplitSprite(vissprite_t *sprite, mobj_t *thing) for (i = 1; i < sector->numlights; i++) { - if (sector->lightlist[i].height >= sprite->gzt || !(sector->lightlist[i].caster->flags & FF_CUTSPRITES)) + fixed_t testheight = sector->lightlist[i].height; + + if (!(sector->lightlist[i].caster->flags & FF_CUTSPRITES)) continue; - if (sector->lightlist[i].height <= sprite->gz) + +#ifdef ESLOPE + if (sector->lightlist[i].slope) + testheight = P_GetZAt(sector->lightlist[i].slope, sprite->gx, sprite->gy); +#endif + + if (testheight >= sprite->gzt) + continue; + if (testheight <= sprite->gz) return; - cutfrac = (INT16)((centeryfrac - FixedMul(sector->lightlist[i].height - viewz, sprite->scale))>>FRACBITS); + cutfrac = (INT16)((centeryfrac - FixedMul(testheight - viewz, sprite->scale))>>FRACBITS); if (cutfrac < 0) continue; if (cutfrac > vid.height) @@ -966,15 +976,15 @@ static void R_SplitSprite(vissprite_t *sprite, mobj_t *thing) newsprite = M_Memcpy(R_NewVisSprite(), sprite, sizeof (vissprite_t)); sprite->cut |= SC_BOTTOM; - sprite->gz = sector->lightlist[i].height; + sprite->gz = testheight; newsprite->gzt = sprite->gz; sprite->sz = cutfrac; newsprite->szt = (INT16)(sprite->sz - 1); - if (sector->lightlist[i].height < sprite->pzt && sector->lightlist[i].height > sprite->pz) - sprite->pz = newsprite->pzt = sector->lightlist[i].height; + if (testheight < sprite->pzt && testheight > sprite->pz) + sprite->pz = newsprite->pzt = testheight; else { newsprite->pz = newsprite->gz; @@ -1191,7 +1201,20 @@ static void R_ProjectSprite(mobj_t *thing) if (thing->subsector->sector->numlights) { INT32 lightnum; +#ifdef ESLOPE // R_GetPlaneLight won't work on sloped lights! + light = thing->subsector->sector->numlights - 1; + + for (lightnum = 1; lightnum < thing->subsector->sector->numlights; lightnum++) { + fixed_t h = thing->subsector->sector->lightlist[lightnum].slope ? P_GetZAt(thing->subsector->sector->lightlist[lightnum].slope, thing->x, thing->y) + : thing->subsector->sector->lightlist[lightnum].height; + if (h <= gzt) { + light = lightnum - 1; + break; + } + } +#else light = R_GetPlaneLight(thing->subsector->sector, gzt, false); +#endif lightnum = (*thing->subsector->sector->lightlist[light].lightlevel >> LIGHTSEGSHIFT); if (lightnum < 0) From 7b0e98ef35ce756060dba5e23f41591a0da09fb0 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Wed, 20 May 2015 13:18:41 -0500 Subject: [PATCH 56/91] Change sliding physics and standing/rolling rules on slopes --- src/p_slopes.c | 25 +++++++++++++++++++++++-- src/p_user.c | 18 +++++++++++++++--- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/src/p_slopes.c b/src/p_slopes.c index 60bd1087b..c5798707e 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -868,11 +868,32 @@ void P_ButteredSlope(mobj_t *mo) if (!mo->standingslope) return; - if (abs(mo->standingslope->zdelta) < FRACUNIT/3) - return; // Don't apply physics to slopes that aren't steep enough + if (mo->player) { + if (abs(mo->standingslope->zdelta) < FRACUNIT/4 && !(mo->player->pflags & PF_SPINNING)) + return; // Don't slide on non-steep slopes unless spinning + + if (abs(mo->standingslope->zdelta) < FRACUNIT/2 && !(mo->player->rmomx || mo->player->rmomy)) + return; // Allow the player to stand still on slopes below a certain steepness + } thrust = FINESINE(mo->standingslope->zangle>>ANGLETOFINESHIFT) * 3 / 2 * (mo->eflags & MFE_VERTICALFLIP ? 1 : -1); + if (mo->player && (mo->player->pflags & PF_SPINNING)) { + fixed_t mult = 0; + if (mo->momx || mo->momy) { + angle_t angle = R_PointToAngle2(0, 0, mo->momx, mo->momy) - mo->standingslope->xydirection; + + if (P_MobjFlip(mo) * mo->standingslope->zdelta < 0) + angle ^= ANGLE_180; + + mult = FINECOSINE(angle >> ANGLETOFINESHIFT); + } + + CONS_Printf("%d\n", mult); + + thrust = FixedMul(thrust, FRACUNIT*2/3 + mult/8); + } + if (mo->momx || mo->momy) // Slightly increase thrust based on the object's speed thrust = FixedMul(thrust, FRACUNIT+P_AproxDistance(mo->momx, mo->momy)/16); // This makes it harder to zigzag up steep slopes, as well as allows greater top speed when rolling down diff --git a/src/p_user.c b/src/p_user.c index 0f2bd19b9..c0ff792cc 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -3758,7 +3758,11 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd) if ((player->charability2 == CA2_SPINDASH) && !(player->pflags & PF_SLIDING) && !player->exiting && !P_PlayerInPain(player)) // subsequent revs { - if ((cmd->buttons & BT_USE) && player->speed < FixedMul(5<mo->scale) && !player->mo->momz && onground && !(player->pflags & PF_USEDOWN) && !(player->pflags & PF_SPINNING)) + if ((cmd->buttons & BT_USE) && player->speed < FixedMul(5<mo->scale) && !player->mo->momz && onground && !(player->pflags & PF_USEDOWN) && !(player->pflags & PF_SPINNING) +#ifdef ESLOPE + && (!player->mo->standingslope || abs(player->mo->standingslope->zdelta) < FRACUNIT/2) +#endif + ) { player->mo->momx = player->cmomx; player->mo->momy = player->cmomy; @@ -3787,7 +3791,11 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd) // down the spin button and not spinning. // AKA Just go into a spin on the ground, you idiot. ;) else if ((cmd->buttons & BT_USE || ((twodlevel || (player->mo->flags2 & MF2_TWOD)) && cmd->forwardmove < -20)) - && !player->climbing && !player->mo->momz && onground && player->speed > FixedMul(5<mo->scale) && !(player->pflags & PF_USEDOWN) && !(player->pflags & PF_SPINNING)) + && !player->climbing && !player->mo->momz && onground && (player->speed > FixedMul(5<mo->scale) +#ifdef ESLOPE + || (player->mo->standingslope && abs(player->mo->standingslope->zdelta) >= FRACUNIT/2) +#endif + ) && !(player->pflags & PF_USEDOWN) && !(player->pflags & PF_SPINNING)) { player->pflags |= PF_SPINNING; P_SetPlayerMobjState(player->mo, S_PLAY_ATK1); @@ -3799,7 +3807,11 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd) // Rolling normally if (onground && player->pflags & PF_SPINNING && !(player->pflags & PF_STARTDASH) - && player->speed < FixedMul(5*FRACUNIT,player->mo->scale)) + && player->speed < FixedMul(5*FRACUNIT,player->mo->scale) +#ifdef ESLOPE + && (!player->mo->standingslope || abs(player->mo->standingslope->zdelta) < FRACUNIT/2) +#endif + ) { if (GETSECSPECIAL(player->mo->subsector->sector->special, 4) == 7 || (player->mo->ceilingz - player->mo->floorz < P_GetPlayerHeight(player))) P_InstaThrust(player->mo, player->mo->angle, FixedMul(10*FRACUNIT, player->mo->scale)); From 0e94cc66ff7fb837c56bfa6e7486ac12db5b9552 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Wed, 20 May 2015 19:08:49 -0500 Subject: [PATCH 57/91] 2-in-1! Fixed slide movement AND climbing when around slopes --- src/p_map.c | 41 ++++++++++------------ src/p_slopes.c | 2 +- src/p_user.c | 94 ++++++++++++++++++++++++++++++++++++-------------- 3 files changed, 88 insertions(+), 49 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index 6257ede1b..4bf032056 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2458,8 +2458,13 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle) glidesector = R_PointInSubsector(player->mo->x + platx, player->mo->y + platy); - floorz = P_GetFloorZ(player->mo, glidesector->sector, player->mo->x + platx, player->mo->y + platy, NULL); - ceilingz = P_GetCeilingZ(player->mo, glidesector->sector, player->mo->x + platx, player->mo->y + platy, NULL); +#ifdef ESLOPE + floorz = glidesector->sector->f_slope ? P_GetZAt(glidesector->sector->f_slope, player->mo->x, player->mo->y) : glidesector->sector->floorheight; + ceilingz = glidesector->sector->c_slope ? P_GetZAt(glidesector->sector->c_slope, player->mo->x, player->mo->y) : glidesector->sector->ceilingheight; +#else + floorz = glidesector->sector->floorheight; + ceilingz = glidesector->sector->ceilingheight; +#endif if (glidesector->sector != player->mo->subsector->sector) { @@ -2476,12 +2481,12 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle) fixed_t topheight = *rover->topheight; fixed_t bottomheight = *rover->bottomheight; -/*#ifdef ESLOPE - if (rover->t_slope) - topheight = P_GetZAt(rover->t_slope, player->mo->x, player->mo->y); - if (rover->b_slope) - bottomheight = P_GetZAt(rover->b_slope, player->mo->x, player->mo->y); -#endif*/ +#ifdef ESLOPE + if (*rover->t_slope) + topheight = P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y); + if (*rover->b_slope) + bottomheight = P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y); +#endif floorclimb = true; @@ -2600,14 +2605,6 @@ static boolean PTR_SlideTraverse(intercept_t *in) maxstep = FixedMul(MAXSTEPMOVE, slidemo->scale); -#ifdef ESLOPE // TODO: Make this collosion better - // Maxstepmove = 0 means the object bounces like a nut while going down a slope - if (slidemo->subsector->sector->f_slope) - { - maxstep *= slidemo->subsector->sector->f_slope->zangle; - } -#endif - if (openbottom - slidemo->z > maxstep) goto isblocking; // too big a step up @@ -2647,12 +2644,12 @@ isblocking: fixed_t topheight = *rover->topheight; fixed_t bottomheight = *rover->bottomheight; -/*#ifdef ESLOPE - if (rover->t_slope) - topheight = P_GetZAt(rover->t_slope, slidemo->x, slidemo->y); - if (rover->b_slope) - bottomheight = P_GetZAt(rover->b_slope, slidemo->x, slidemo->y); -#endif*/ +#ifdef ESLOPE + if (*rover->t_slope) + topheight = P_GetZAt(*rover->t_slope, slidemo->x, slidemo->y); + if (*rover->b_slope) + bottomheight = P_GetZAt(*rover->b_slope, slidemo->x, slidemo->y); +#endif if (topheight < slidemo->z) continue; diff --git a/src/p_slopes.c b/src/p_slopes.c index c5798707e..a4f334caf 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -889,7 +889,7 @@ void P_ButteredSlope(mobj_t *mo) mult = FINECOSINE(angle >> ANGLETOFINESHIFT); } - CONS_Printf("%d\n", mult); + //CONS_Printf("%d\n", mult); thrust = FixedMul(thrust, FRACUNIT*2/3 + mult/8); } diff --git a/src/p_user.c b/src/p_user.c index c0ff792cc..6898ee910 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2361,10 +2361,23 @@ static void P_DoClimbing(player_t *player) floorclimb = false; boostup = false; skyclimber = false; + fixed_t floorheight, ceilingheight; // ESLOPE + +#ifdef ESLOPE + floorheight = glidesector->sector->f_slope ? P_GetZAt(glidesector->sector->f_slope, player->mo->x, player->mo->y) + : glidesector->sector->floorheight; + ceilingheight = glidesector->sector->c_slope ? P_GetZAt(glidesector->sector->c_slope, player->mo->x, player->mo->y) + : glidesector->sector->ceilingheight; +#else + floorheight = glidesector->sector->floorheight; + ceilingheight = glidesector->sector->ceilingheight; +#endif if (glidesector->sector->ffloors) { ffloor_t *rover; + fixed_t topheight, bottomheight; // ESLOPE + for (rover = glidesector->sector->ffloors; rover; rover = rover->next) { if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP)) @@ -2372,13 +2385,21 @@ static void P_DoClimbing(player_t *player) floorclimb = true; +#ifdef ESLOPE + bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight; + topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight; +#else + bottomheight = *rover->bottomheight; + topheight = *rover->topheight; +#endif + // Only supports rovers that are moving like an 'elevator', not just the top or bottom. if (rover->master->frontsector->floorspeed && rover->master->frontsector->ceilspeed == 42) { - if ((!(player->mo->eflags & MFE_VERTICALFLIP) && (*rover->bottomheight < player->mo->z+player->mo->height) - && (*rover->topheight >= player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale))) - || ((player->mo->eflags & MFE_VERTICALFLIP) && (*rover->topheight > player->mo->z) - && (*rover->bottomheight <= player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale)))) + if ((!(player->mo->eflags & MFE_VERTICALFLIP) && (bottomheight < player->mo->z+player->mo->height) + && (topheight >= player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale))) + || ((player->mo->eflags & MFE_VERTICALFLIP) && (topheight > player->mo->z) + && (bottomheight <= player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale)))) { if (cmd->forwardmove != 0) player->mo->momz += rover->master->frontsector->floorspeed; @@ -2394,8 +2415,9 @@ static void P_DoClimbing(player_t *player) if (player->mo->eflags & MFE_VERTICALFLIP) { // Trying to climb down past the bottom of the FOF - if ((*rover->topheight >= player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) >= *rover->topheight)) + if ((topheight >= player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) >= topheight)) { + fixed_t bottomheight2; ffloor_t *roverbelow; boolean foundfof = false; floorclimb = true; @@ -2410,7 +2432,13 @@ static void P_DoClimbing(player_t *player) if (roverbelow == rover) continue; - if (*roverbelow->bottomheight < *rover->topheight + FixedMul(16*FRACUNIT, player->mo->scale)) +#ifdef ESLOPE + bottomheight2 = *roverbelow->b_slope ? P_GetZAt(*roverbelow->b_slope, player->mo->x, player->mo->y) : *roverbelow->bottomheight; +#else + bottomheight2 = *roverbelow->bottomheight; +#endif + + if (bottomheight2 < topheight + FixedMul(16*FRACUNIT, player->mo->scale)) foundfof = true; } @@ -2419,7 +2447,7 @@ static void P_DoClimbing(player_t *player) } // Below the FOF - if (*rover->topheight <= player->mo->z) + if (topheight <= player->mo->z) { floorclimb = false; boostup = false; @@ -2427,7 +2455,7 @@ static void P_DoClimbing(player_t *player) } // Above the FOF - if (*rover->bottomheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale)) + if (bottomheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale)) { floorclimb = false; thrust = true; @@ -2437,8 +2465,9 @@ static void P_DoClimbing(player_t *player) else { // Trying to climb down past the bottom of a FOF - if ((*rover->bottomheight <= player->mo->z) && ((player->mo->z + player->mo->momz) <= *rover->bottomheight)) + if ((bottomheight <= player->mo->z) && ((player->mo->z + player->mo->momz) <= bottomheight)) { + fixed_t topheight2; ffloor_t *roverbelow; boolean foundfof = false; floorclimb = true; @@ -2453,7 +2482,13 @@ static void P_DoClimbing(player_t *player) if (roverbelow == rover) continue; - if (*roverbelow->topheight > *rover->bottomheight - FixedMul(16*FRACUNIT, player->mo->scale)) +#ifdef ESLOPE + topheight2 = *roverbelow->t_slope ? P_GetZAt(*roverbelow->t_slope, player->mo->x, player->mo->y) : *roverbelow->topheight; +#else + topheight2 = *roverbelow->topheight; +#endif + + if (topheight2 > bottomheight - FixedMul(16*FRACUNIT, player->mo->scale)) foundfof = true; } @@ -2462,7 +2497,7 @@ static void P_DoClimbing(player_t *player) } // Below the FOF - if (*rover->bottomheight >= player->mo->z + player->mo->height) + if (bottomheight >= player->mo->z + player->mo->height) { floorclimb = false; boostup = false; @@ -2470,7 +2505,7 @@ static void P_DoClimbing(player_t *player) } // Above the FOF - if (*rover->topheight < player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale)) + if (topheight < player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale)) { floorclimb = false; thrust = true; @@ -2491,7 +2526,7 @@ static void P_DoClimbing(player_t *player) if (player->mo->eflags & MFE_VERTICALFLIP) { // Trying to climb down past the upper texture area - if ((glidesector->sector->floorheight >= player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) >= glidesector->sector->floorheight)) + if ((floorheight >= player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) >= floorheight)) { boolean foundfof = false; floorclimb = true; @@ -2499,13 +2534,20 @@ static void P_DoClimbing(player_t *player) // Is there a FOF directly below that we can move onto? if (glidesector->sector->ffloors) { + fixed_t bottomheight; ffloor_t *rover; for (rover = glidesector->sector->ffloors; rover; rover = rover->next) { if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP)) continue; - if (*rover->bottomheight < glidesector->sector->floorheight + FixedMul(16*FRACUNIT, player->mo->scale)) +#ifdef ESLOPE + bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight; +#else + bottomheight = *rover->bottomheight; +#endif + + if (bottomheight < floorheight + FixedMul(16*FRACUNIT, player->mo->scale)) { foundfof = true; break; @@ -2518,8 +2560,8 @@ static void P_DoClimbing(player_t *player) } // Reached the top of the lower texture area - if (!floorclimb && glidesector->sector->ceilingheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale) - && (glidesector->sector->ceilingpic == skyflatnum || glidesector->sector->floorheight < (player->mo->z - FixedMul(8*FRACUNIT, player->mo->scale)))) + if (!floorclimb && ceilingheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale) + && (glidesector->sector->ceilingpic == skyflatnum || floorheight < (player->mo->z - FixedMul(8*FRACUNIT, player->mo->scale)))) { thrust = true; boostup = true; @@ -2529,7 +2571,7 @@ static void P_DoClimbing(player_t *player) else { // Trying to climb down past the upper texture area - if ((glidesector->sector->ceilingheight <= player->mo->z) && ((player->mo->z + player->mo->momz) <= glidesector->sector->ceilingheight)) + if ((ceilingheight <= player->mo->z) && ((player->mo->z + player->mo->momz) <= ceilingheight)) { boolean foundfof = false; floorclimb = true; @@ -2543,7 +2585,7 @@ static void P_DoClimbing(player_t *player) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP)) continue; - if (*rover->topheight > glidesector->sector->ceilingheight - FixedMul(16*FRACUNIT, player->mo->scale)) + if (*rover->topheight > ceilingheight - FixedMul(16*FRACUNIT, player->mo->scale)) { foundfof = true; break; @@ -2556,7 +2598,7 @@ static void P_DoClimbing(player_t *player) } // Allow climbing from a FOF or lower texture onto the upper texture and vice versa. - if (player->mo->z > glidesector->sector->ceilingheight - FixedMul(16*FRACUNIT, player->mo->scale)) + if (player->mo->z > ceilingheight - FixedMul(16*FRACUNIT, player->mo->scale)) { floorclimb = true; thrust = false; @@ -2564,8 +2606,8 @@ static void P_DoClimbing(player_t *player) } // Reached the top of the lower texture area - if (!floorclimb && glidesector->sector->floorheight < player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale) - && (glidesector->sector->ceilingpic == skyflatnum || glidesector->sector->ceilingheight > (player->mo->z + player->mo->height + FixedMul(8*FRACUNIT, player->mo->scale)))) + if (!floorclimb && floorheight < player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale) + && (glidesector->sector->ceilingpic == skyflatnum || ceilingheight > (player->mo->z + player->mo->height + FixedMul(8*FRACUNIT, player->mo->scale)))) { thrust = true; boostup = true; @@ -2574,14 +2616,14 @@ static void P_DoClimbing(player_t *player) } // Trying to climb on the sky - if ((glidesector->sector->ceilingheight < player->mo->z) && glidesector->sector->ceilingpic == skyflatnum) + if ((ceilingheight < player->mo->z) && glidesector->sector->ceilingpic == skyflatnum) { skyclimber = true; } // Climbing on the lower texture area? - if ((!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale) < glidesector->sector->floorheight) - || ((player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + player->mo->height <= glidesector->sector->floorheight)) + if ((!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale) < floorheight) + || ((player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + player->mo->height <= floorheight)) { floorclimb = true; @@ -2597,8 +2639,8 @@ static void P_DoClimbing(player_t *player) } } // Climbing on the upper texture area? - else if ((!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z >= glidesector->sector->ceilingheight) - || ((player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale) > glidesector->sector->ceilingheight)) + else if ((!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z >= ceilingheight) + || ((player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale) > ceilingheight)) { floorclimb = true; From 7a3c5b3dd9a76c2378029a1699d2a7f97b86f3e6 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Wed, 20 May 2015 19:21:44 -0500 Subject: [PATCH 58/91] Scenery objects (notably, bubbles) now use slope when finding water surfaces --- src/p_mobj.c | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 013f523c6..33dc1cbb0 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -3033,12 +3033,7 @@ void P_MobjCheckWater(mobj_t *mobj) player_t *p = mobj->player; // Will just be null if not a player. // Default if no water exists. - mobj->watertop = mobj->waterbottom = mobj->subsector->sector->floorheight - 1000*FRACUNIT; - -#ifdef ESLOPE // Set the correct waterbottom/top to be below the lowest point of the slope - if (mobj->subsector->sector->f_slope) - mobj->watertop = mobj->waterbottom = mobj->subsector->sector->f_slope->lowz - 1000*FRACUNIT; -#endif + mobj->watertop = mobj->waterbottom = mobj->z - 1000*FRACUNIT; // Reset water state. mobj->eflags &= ~(MFE_UNDERWATER|MFE_TOUCHWATER|MFE_GOOWATER); @@ -3267,7 +3262,7 @@ static void P_SceneryCheckWater(mobj_t *mobj) sector_t *sector; // Default if no water exists. - mobj->watertop = mobj->waterbottom = mobj->subsector->sector->floorheight - 1000*FRACUNIT; + mobj->watertop = mobj->waterbottom = mobj->z - 1000*FRACUNIT; // see if we are in water, and set some flags for later sector = mobj->subsector->sector; @@ -3275,6 +3270,7 @@ static void P_SceneryCheckWater(mobj_t *mobj) if (sector->ffloors) { ffloor_t *rover; + fixed_t topheight, bottomheight; mobj->eflags &= ~(MFE_UNDERWATER|MFE_TOUCHWATER); @@ -3282,20 +3278,32 @@ static void P_SceneryCheckWater(mobj_t *mobj) { if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE) || rover->flags & FF_BLOCKOTHERS) continue; - if (*rover->topheight <= mobj->z - || *rover->bottomheight > (mobj->z + FixedMul(mobj->info->height >> 1, mobj->scale))) + + topheight = *rover->topheight; + bottomheight = *rover->bottomheight; + +#ifdef ESLOPE + if (*rover->t_slope) + topheight = P_GetZAt(*rover->t_slope, mobj->x, mobj->y); + + if (*rover->b_slope) + bottomheight = P_GetZAt(*rover->b_slope, mobj->x, mobj->y); +#endif + + if (topheight <= mobj->z + || bottomheight > (mobj->z + FixedMul(mobj->info->height >> 1, mobj->scale))) continue; - if (mobj->z + FixedMul(mobj->info->height, mobj->scale) > *rover->topheight) + if (mobj->z + FixedMul(mobj->info->height, mobj->scale) > topheight) mobj->eflags |= MFE_TOUCHWATER; else mobj->eflags &= ~MFE_TOUCHWATER; // Set the watertop and waterbottom - mobj->watertop = *rover->topheight; - mobj->waterbottom = *rover->bottomheight; + mobj->watertop = topheight; + mobj->waterbottom = bottomheight; - if (mobj->z + FixedMul(mobj->info->height >> 1, mobj->scale) < *rover->topheight) + if (mobj->z + FixedMul(mobj->info->height >> 1, mobj->scale) < topheight) mobj->eflags |= MFE_UNDERWATER; else mobj->eflags &= ~MFE_UNDERWATER; From 3d2b71b24c4bacd2bda771e9ce9db779e0997720 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Thu, 21 May 2015 09:36:20 -0500 Subject: [PATCH 59/91] Make cameras properly collide with slopes --- src/p_local.h | 5 + src/p_map.c | 27 +-- src/p_maputl.c | 44 +---- src/p_mobj.c | 508 ++++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 523 insertions(+), 61 deletions(-) diff --git a/src/p_local.h b/src/p_local.h index 472c0706e..f2376494a 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -237,6 +237,11 @@ fixed_t P_GetCeilingZ(mobj_t *mobj, sector_t *sector, fixed_t x, fixed_t y, line fixed_t P_GetFOFTopZ(mobj_t *mobj, sector_t *sector, ffloor_t *fof, fixed_t x, fixed_t y, line_t *line); fixed_t P_GetFOFBottomZ(mobj_t *mobj, sector_t *sector, ffloor_t *fof, fixed_t x, fixed_t y, line_t *line); +fixed_t P_CameraGetFloorZ(camera_t *mobj, sector_t *sector, fixed_t x, fixed_t y, line_t *line); +fixed_t P_CameraGetCeilingZ(camera_t *mobj, sector_t *sector, fixed_t x, fixed_t y, line_t *line); +fixed_t P_CameraGetFOFTopZ(camera_t *mobj, sector_t *sector, ffloor_t *fof, fixed_t x, fixed_t y, line_t *line); +fixed_t P_CameraGetFOFBottomZ(camera_t *mobj, sector_t *sector, ffloor_t *fof, fixed_t x, fixed_t y, line_t *line); + boolean P_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover); boolean P_CheckDeathPitCollide(mobj_t *mo); boolean P_CheckSolidLava(mobj_t *mo, ffloor_t *rover); diff --git a/src/p_map.c b/src/p_map.c index 4bf032056..e2ea76b88 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1517,21 +1517,9 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam) // that contains the point. // Any contacted lines the step closer together // will adjust them. -#ifdef ESLOPE - if (newsubsec->sector->f_slope) - { - tmfloorz = tmdropoffz = P_GetZAt(newsubsec->sector->f_slope, thiscam->x, thiscam->y); - } - else -#endif - tmfloorz = tmdropoffz = newsubsec->sector->floorheight; + tmfloorz = tmdropoffz = P_CameraGetFloorZ(thiscam, newsubsec->sector, x, y, NULL); -#ifdef ESLOPE - if (newsubsec->sector->c_slope) - tmceilingz = P_GetZAt(newsubsec->sector->c_slope, thiscam->x, thiscam->y); - else -#endif - tmceilingz = newsubsec->sector->ceilingheight; + tmceilingz = P_CameraGetCeilingZ(thiscam, newsubsec->sector, x, y, NULL); // Cameras use the heightsec's heights rather then the actual sector heights. // If you can see through it, why not move the camera through it too? @@ -1560,15 +1548,8 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam) if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERALL) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12) continue; - fixed_t topheight = *rover->topheight; - fixed_t bottomheight = *rover->bottomheight; - -/*#ifdef ESLOPE - if (rover->t_slope) - topheight = P_GetZAt(rover->t_slope, thiscam->x, thiscam->y); - if (rover->b_slope) - bottomheight = P_GetZAt(rover->b_slope, thiscam->x, thiscam->y); -#endif*/ + fixed_t topheight = P_CameraGetFOFTopZ(thiscam, newsubsec->sector, rover, x, y, NULL); + fixed_t bottomheight = P_CameraGetFOFBottomZ(thiscam, newsubsec->sector, rover, x, y, NULL); delta1 = thiscam->z - (bottomheight + ((topheight - bottomheight)/2)); diff --git a/src/p_maputl.c b/src/p_maputl.c index 4037d769b..a60d9232d 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -375,14 +375,8 @@ void P_CameraLineOpening(line_t *linedef) } else { - frontfloor = front->floorheight; - frontceiling = front->ceilingheight; -#ifdef ESLOPE - if (front->f_slope) - frontfloor = P_GetZAt(front->f_slope, camera.x, camera.y); - if (front->c_slope) - frontceiling = P_GetZAt(front->c_slope, camera.x, camera.y); -#endif + frontfloor = P_CameraGetFloorZ(mapcampointer, front, tmx, tmy, linedef); + frontceiling = P_CameraGetCeilingZ(mapcampointer, front, tmx, tmy, linedef); } if (back->camsec >= 0) { @@ -408,14 +402,8 @@ void P_CameraLineOpening(line_t *linedef) } else { - backfloor = back->floorheight; - backceiling = back->ceilingheight; -#ifdef ESLOPE - if (back->f_slope) - frontfloor = P_GetZAt(back->f_slope, camera.x, camera.y); - if (back->c_slope) - frontceiling = P_GetZAt(back->c_slope, camera.x, camera.y); -#endif + backfloor = P_CameraGetFloorZ(mapcampointer, back, tmx, tmy, linedef); + backceiling = P_CameraGetCeilingZ(mapcampointer, back, tmx, tmy, linedef); } { @@ -460,16 +448,8 @@ void P_CameraLineOpening(line_t *linedef) if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12) continue; - fixed_t topheight = *rover->topheight; - fixed_t bottomheight = *rover->bottomheight; - -/*#ifdef ESLOPE - if (rover->t_slope) - topheight = P_GetZAt(rover->t_slope, camera.x, camera.y); - - if (rover->b_slope) - bottomheight = P_GetZAt(rover->b_slope, camera.x, camera.y); -#endif // ESLOPE*/ + fixed_t topheight = P_CameraGetFOFTopZ(mapcampointer, front, rover, tmx, tmy, linedef); + fixed_t bottomheight = P_CameraGetFOFBottomZ(mapcampointer, front, rover, tmx, tmy, linedef); delta1 = abs(mapcampointer->z - (bottomheight + ((topheight - bottomheight)/2))); delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2))); @@ -491,16 +471,8 @@ void P_CameraLineOpening(line_t *linedef) if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12) continue; - fixed_t topheight = *rover->topheight; - fixed_t bottomheight = *rover->bottomheight; - -/*#ifdef ESLOPE - if (rover->t_slope) - topheight = P_GetZAt(rover->t_slope, camera.x, camera.y); - - if (rover->b_slope) - bottomheight = P_GetZAt(rover->b_slope, camera.x, camera.y); -#endif // ESLOPE*/ + fixed_t topheight = P_CameraGetFOFTopZ(mapcampointer, back, rover, tmx, tmy, linedef); + fixed_t bottomheight = P_CameraGetFOFBottomZ(mapcampointer, back, rover, tmx, tmy, linedef); delta1 = abs(mapcampointer->z - (bottomheight + ((topheight - bottomheight)/2))); delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2))); diff --git a/src/p_mobj.c b/src/p_mobj.c index 33dc1cbb0..4fe59bfab 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1212,6 +1212,494 @@ fixed_t P_GetFOFBottomZ(mobj_t *mobj, sector_t *sector, ffloor_t *fof, fixed_t x return *fof->bottomheight; } +// Now do the same as all above, but for cameras because apparently cameras are special? +fixed_t P_CameraGetFloorZ(camera_t *mobj, sector_t *sector, fixed_t x, fixed_t y, line_t *line) // SRB2CBTODO: This needs to be over all the code +{ + I_Assert(mobj != NULL); + I_Assert(sector != NULL); +#ifdef ESLOPE + if (sector->f_slope) { + fixed_t testx, testy; + pslope_t *slope = sector->f_slope; + + // Get the corner of the object that should be the highest on the slope + if (slope->d.x < 0) + testx = mobj->radius; + else + testx = -mobj->radius; + + if (slope->d.y < 0) + testy = mobj->radius; + else + testy = -mobj->radius; + + if (slope->zdelta > 0) { + testx = -testx; + testy = -testy; + } + + testx += x; + testy += y; + + // If the highest point is in the sector, then we have it easy! Just get the Z at that point + if (R_PointInSubsector(testx, testy)->sector == sector) + return P_GetZAt(slope, testx, testy); + + // If we're just testing for base sector location (no collision line), just go for the center's spot... + // It'll get fixed when we test for collision anyway, and the final result can't be lower than this + if (line == NULL) + return P_GetZAt(slope, x, y); + + // Alright, so we're sitting on a line that contains our slope sector, and need to figure out the highest point we're touching... + // The solution is simple! Get the line's vertices, and pull each one in along its line until it touches the object's bounding box + // (assuming it isn't already inside), then test each point's slope Z and return the higher of the two. + { + vertex_t v1, v2; + v1.x = line->v1->x; + v1.y = line->v1->y; + v2.x = line->v2->x; + v2.y = line->v2->y; + + /*CONS_Printf("BEFORE: v1 = %f %f %f\n", + FIXED_TO_FLOAT(v1.x), + FIXED_TO_FLOAT(v1.y), + FIXED_TO_FLOAT(P_GetZAt(slope, v1.x, v1.y)) + ); + CONS_Printf(" v2 = %f %f %f\n", + FIXED_TO_FLOAT(v2.x), + FIXED_TO_FLOAT(v2.y), + FIXED_TO_FLOAT(P_GetZAt(slope, v2.x, v2.y)) + );*/ + + if (abs(v1.x-x) > mobj->radius) { + // v1's x is out of range, so rein it in + fixed_t diff = abs(v1.x-x) - mobj->radius; + + if (v1.x < x) { // Moving right + v1.x += diff; + v1.y += FixedMul(diff, FixedDiv(line->dy, line->dx)); + } else { // Moving left + v1.x -= diff; + v1.y -= FixedMul(diff, FixedDiv(line->dy, line->dx)); + } + } + + if (abs(v1.y-y) > mobj->radius) { + // v1's y is out of range, so rein it in + fixed_t diff = abs(v1.y-y) - mobj->radius; + + if (v1.y < y) { // Moving up + v1.y += diff; + v1.x += FixedMul(diff, FixedDiv(line->dx, line->dy)); + } else { // Moving down + v1.y -= diff; + v1.x -= FixedMul(diff, FixedDiv(line->dx, line->dy)); + } + } + + if (abs(v2.x-x) > mobj->radius) { + // v1's x is out of range, so rein it in + fixed_t diff = abs(v2.x-x) - mobj->radius; + + if (v2.x < x) { // Moving right + v2.x += diff; + v2.y += FixedMul(diff, FixedDiv(line->dy, line->dx)); + } else { // Moving left + v2.x -= diff; + v2.y -= FixedMul(diff, FixedDiv(line->dy, line->dx)); + } + } + + if (abs(v2.y-y) > mobj->radius) { + // v2's y is out of range, so rein it in + fixed_t diff = abs(v2.y-y) - mobj->radius; + + if (v2.y < y) { // Moving up + v2.y += diff; + v2.x += FixedMul(diff, FixedDiv(line->dx, line->dy)); + } else { // Moving down + v2.y -= diff; + v2.x -= FixedMul(diff, FixedDiv(line->dx, line->dy)); + } + } + + /*CONS_Printf("AFTER: v1 = %f %f %f\n", + FIXED_TO_FLOAT(v1.x), + FIXED_TO_FLOAT(v1.y), + FIXED_TO_FLOAT(P_GetZAt(slope, v1.x, v1.y)) + ); + CONS_Printf(" v2 = %f %f %f\n", + FIXED_TO_FLOAT(v2.x), + FIXED_TO_FLOAT(v2.y), + FIXED_TO_FLOAT(P_GetZAt(slope, v2.x, v2.y)) + );*/ + + // Return the higher of the two points + return max( + P_GetZAt(slope, v1.x, v1.y), + P_GetZAt(slope, v2.x, v2.y) + ); + } + } else // Well, that makes it easy. Just get the floor height +#endif + return sector->floorheight; +} + +fixed_t P_CameraGetCeilingZ(camera_t *mobj, sector_t *sector, fixed_t x, fixed_t y, line_t *line) // SRB2CBTODO: This needs to be over all the code +{ + I_Assert(mobj != NULL); + I_Assert(sector != NULL); +#ifdef ESLOPE + if (sector->c_slope) { + fixed_t testx, testy; + pslope_t *slope = sector->c_slope; + + // Get the corner of the object that should be the lowest on the slope + if (slope->d.x < 0) + testx = mobj->radius; + else + testx = -mobj->radius; + + if (slope->d.y < 0) + testy = mobj->radius; + else + testy = -mobj->radius; + + if (slope->zdelta < 0) { + testx = -testx; + testy = -testy; + } + + testx += x; + testy += y; + + // If the lowest point is in the sector, then we have it easy! Just get the Z at that point + if (R_PointInSubsector(testx, testy)->sector == sector) + return P_GetZAt(slope, testx, testy); + + // If we're just testing for base sector location (no collision line), just go for the center's spot... + // It'll get fixed when we test for collision anyway, and the final result can't be higher than this + if (line == NULL) + return P_GetZAt(slope, x, y); + + // Alright, so we're sitting on a line that contains our slope sector, and need to figure out the highest point we're touching... + // The solution is simple! Get the line's vertices, and pull each one in along its line until it touches the object's bounding box + // (assuming it isn't already inside), then test each point's slope Z and return the lower of the two. + { + vertex_t v1, v2; + v1.x = line->v1->x; + v1.y = line->v1->y; + v2.x = line->v2->x; + v2.y = line->v2->y; + + if (abs(v1.x-x) > mobj->radius) { + // v1's x is out of range, so rein it in + fixed_t diff = abs(v1.x-x) - mobj->radius; + + if (v1.x < x) { // Moving right + v1.x += diff; + v1.y += FixedMul(diff, FixedDiv(line->dy, line->dx)); + } else { // Moving left + v1.x -= diff; + v1.y -= FixedMul(diff, FixedDiv(line->dy, line->dx)); + } + } + + if (abs(v1.y-y) > mobj->radius) { + // v1's y is out of range, so rein it in + fixed_t diff = abs(v1.y-y) - mobj->radius; + + if (v1.y < y) { // Moving up + v1.y += diff; + v1.x += FixedMul(diff, FixedDiv(line->dx, line->dy)); + } else { // Moving down + v1.y -= diff; + v1.x -= FixedMul(diff, FixedDiv(line->dx, line->dy)); + } + } + + if (abs(v2.x-x) > mobj->radius) { + // v1's x is out of range, so rein it in + fixed_t diff = abs(v2.x-x) - mobj->radius; + + if (v2.x < x) { // Moving right + v2.x += diff; + v2.y += FixedMul(diff, FixedDiv(line->dy, line->dx)); + } else { // Moving left + v2.x -= diff; + v2.y -= FixedMul(diff, FixedDiv(line->dy, line->dx)); + } + } + + if (abs(v2.y-y) > mobj->radius) { + // v2's y is out of range, so rein it in + fixed_t diff = abs(v2.y-y) - mobj->radius; + + if (v2.y < y) { // Moving up + v2.y += diff; + v2.x += FixedMul(diff, FixedDiv(line->dx, line->dy)); + } else { // Moving down + v2.y -= diff; + v2.x -= FixedMul(diff, FixedDiv(line->dx, line->dy)); + } + } + + // Return the lower of the two points + return min( + P_GetZAt(slope, v1.x, v1.y), + P_GetZAt(slope, v2.x, v2.y) + ); + } + } else // Well, that makes it easy. Just get the ceiling height +#endif + return sector->ceilingheight; +} + +// Do the same as above, but for FOFs! +fixed_t P_CameraGetFOFTopZ(camera_t *mobj, sector_t *sector, ffloor_t *fof, fixed_t x, fixed_t y, line_t *line) // SRB2CBTODO: This needs to be over all the code +{ + I_Assert(mobj != NULL); + I_Assert(sector != NULL); + I_Assert(fof != NULL); +#ifdef ESLOPE + if (*fof->t_slope) { + fixed_t testx, testy; + pslope_t *slope = *fof->t_slope; + + // Get the corner of the object that should be the highest on the slope + if (slope->d.x < 0) + testx = mobj->radius; + else + testx = -mobj->radius; + + if (slope->d.y < 0) + testy = mobj->radius; + else + testy = -mobj->radius; + + if (slope->zdelta > 0) { + testx = -testx; + testy = -testy; + } + + testx += x; + testy += y; + + // If the highest point is in the sector, then we have it easy! Just get the Z at that point + if (R_PointInSubsector(testx, testy)->sector == sector) + return P_GetZAt(slope, testx, testy); + + // If we're just testing for base sector location (no collision line), just go for the center's spot... + // It'll get fixed when we test for collision anyway, and the final result can't be lower than this + if (line == NULL) + return P_GetZAt(slope, x, y); + + // Alright, so we're sitting on a line that contains our slope sector, and need to figure out the highest point we're touching... + // The solution is simple! Get the line's vertices, and pull each one in along its line until it touches the object's bounding box + // (assuming it isn't already inside), then test each point's slope Z and return the higher of the two. + { + vertex_t v1, v2; + v1.x = line->v1->x; + v1.y = line->v1->y; + v2.x = line->v2->x; + v2.y = line->v2->y; + + /*CONS_Printf("BEFORE: v1 = %f %f %f\n", + FIXED_TO_FLOAT(v1.x), + FIXED_TO_FLOAT(v1.y), + FIXED_TO_FLOAT(P_GetZAt(slope, v1.x, v1.y)) + ); + CONS_Printf(" v2 = %f %f %f\n", + FIXED_TO_FLOAT(v2.x), + FIXED_TO_FLOAT(v2.y), + FIXED_TO_FLOAT(P_GetZAt(slope, v2.x, v2.y)) + );*/ + + if (abs(v1.x-x) > mobj->radius) { + // v1's x is out of range, so rein it in + fixed_t diff = abs(v1.x-x) - mobj->radius; + + if (v1.x < x) { // Moving right + v1.x += diff; + v1.y += FixedMul(diff, FixedDiv(line->dy, line->dx)); + } else { // Moving left + v1.x -= diff; + v1.y -= FixedMul(diff, FixedDiv(line->dy, line->dx)); + } + } + + if (abs(v1.y-y) > mobj->radius) { + // v1's y is out of range, so rein it in + fixed_t diff = abs(v1.y-y) - mobj->radius; + + if (v1.y < y) { // Moving up + v1.y += diff; + v1.x += FixedMul(diff, FixedDiv(line->dx, line->dy)); + } else { // Moving down + v1.y -= diff; + v1.x -= FixedMul(diff, FixedDiv(line->dx, line->dy)); + } + } + + if (abs(v2.x-x) > mobj->radius) { + // v1's x is out of range, so rein it in + fixed_t diff = abs(v2.x-x) - mobj->radius; + + if (v2.x < x) { // Moving right + v2.x += diff; + v2.y += FixedMul(diff, FixedDiv(line->dy, line->dx)); + } else { // Moving left + v2.x -= diff; + v2.y -= FixedMul(diff, FixedDiv(line->dy, line->dx)); + } + } + + if (abs(v2.y-y) > mobj->radius) { + // v2's y is out of range, so rein it in + fixed_t diff = abs(v2.y-y) - mobj->radius; + + if (v2.y < y) { // Moving up + v2.y += diff; + v2.x += FixedMul(diff, FixedDiv(line->dx, line->dy)); + } else { // Moving down + v2.y -= diff; + v2.x -= FixedMul(diff, FixedDiv(line->dx, line->dy)); + } + } + + /*CONS_Printf("AFTER: v1 = %f %f %f\n", + FIXED_TO_FLOAT(v1.x), + FIXED_TO_FLOAT(v1.y), + FIXED_TO_FLOAT(P_GetZAt(slope, v1.x, v1.y)) + ); + CONS_Printf(" v2 = %f %f %f\n", + FIXED_TO_FLOAT(v2.x), + FIXED_TO_FLOAT(v2.y), + FIXED_TO_FLOAT(P_GetZAt(slope, v2.x, v2.y)) + );*/ + + // Return the higher of the two points + return max( + P_GetZAt(slope, v1.x, v1.y), + P_GetZAt(slope, v2.x, v2.y) + ); + } + } else // Well, that makes it easy. Just get the top height +#endif + return *fof->topheight; +} + +fixed_t P_CameraGetFOFBottomZ(camera_t *mobj, sector_t *sector, ffloor_t *fof, fixed_t x, fixed_t y, line_t *line) // SRB2CBTODO: This needs to be over all the code +{ + I_Assert(mobj != NULL); + I_Assert(sector != NULL); + I_Assert(fof != NULL); +#ifdef ESLOPE + if (*fof->b_slope) { + fixed_t testx, testy; + pslope_t *slope = *fof->b_slope; + + // Get the corner of the object that should be the lowest on the slope + if (slope->d.x < 0) + testx = mobj->radius; + else + testx = -mobj->radius; + + if (slope->d.y < 0) + testy = mobj->radius; + else + testy = -mobj->radius; + + if (slope->zdelta < 0) { + testx = -testx; + testy = -testy; + } + + testx += x; + testy += y; + + // If the lowest point is in the sector, then we have it easy! Just get the Z at that point + if (R_PointInSubsector(testx, testy)->sector == sector) + return P_GetZAt(slope, testx, testy); + + // If we're just testing for base sector location (no collision line), just go for the center's spot... + // It'll get fixed when we test for collision anyway, and the final result can't be higher than this + if (line == NULL) + return P_GetZAt(slope, x, y); + + // Alright, so we're sitting on a line that contains our slope sector, and need to figure out the highest point we're touching... + // The solution is simple! Get the line's vertices, and pull each one in along its line until it touches the object's bounding box + // (assuming it isn't already inside), then test each point's slope Z and return the lower of the two. + { + vertex_t v1, v2; + v1.x = line->v1->x; + v1.y = line->v1->y; + v2.x = line->v2->x; + v2.y = line->v2->y; + + if (abs(v1.x-x) > mobj->radius) { + // v1's x is out of range, so rein it in + fixed_t diff = abs(v1.x-x) - mobj->radius; + + if (v1.x < x) { // Moving right + v1.x += diff; + v1.y += FixedMul(diff, FixedDiv(line->dy, line->dx)); + } else { // Moving left + v1.x -= diff; + v1.y -= FixedMul(diff, FixedDiv(line->dy, line->dx)); + } + } + + if (abs(v1.y-y) > mobj->radius) { + // v1's y is out of range, so rein it in + fixed_t diff = abs(v1.y-y) - mobj->radius; + + if (v1.y < y) { // Moving up + v1.y += diff; + v1.x += FixedMul(diff, FixedDiv(line->dx, line->dy)); + } else { // Moving down + v1.y -= diff; + v1.x -= FixedMul(diff, FixedDiv(line->dx, line->dy)); + } + } + + if (abs(v2.x-x) > mobj->radius) { + // v1's x is out of range, so rein it in + fixed_t diff = abs(v2.x-x) - mobj->radius; + + if (v2.x < x) { // Moving right + v2.x += diff; + v2.y += FixedMul(diff, FixedDiv(line->dy, line->dx)); + } else { // Moving left + v2.x -= diff; + v2.y -= FixedMul(diff, FixedDiv(line->dy, line->dx)); + } + } + + if (abs(v2.y-y) > mobj->radius) { + // v2's y is out of range, so rein it in + fixed_t diff = abs(v2.y-y) - mobj->radius; + + if (v2.y < y) { // Moving up + v2.y += diff; + v2.x += FixedMul(diff, FixedDiv(line->dx, line->dy)); + } else { // Moving down + v2.y -= diff; + v2.x -= FixedMul(diff, FixedDiv(line->dx, line->dy)); + } + } + + // Return the lower of the two points + return min( + P_GetZAt(slope, v1.x, v1.y), + P_GetZAt(slope, v2.x, v2.y) + ); + } + } else // Well, that makes it easy. Just get the bottom height +#endif + return *fof->bottomheight; +} + static void P_PlayerFlip(mobj_t *mo) { if (!mo->player) @@ -3333,7 +3821,15 @@ static boolean P_CameraCheckHeat(camera_t *thiscam) if (!(rover->flags & FF_EXISTS)) continue; - if (halfheight >= *rover->topheight || halfheight <= *rover->bottomheight) + if (halfheight >= ( +#ifdef ESLOPE + *rover->t_slope ? P_GetZAt(*rover->t_slope, thiscam->x, thiscam->y) : +#endif + *rover->topheight) || halfheight <= ( +#ifdef ESLOPE + *rover->b_slope ? P_GetZAt(*rover->b_slope, thiscam->x, thiscam->y) : +#endif + *rover->bottomheight)) continue; if (P_FindSpecialLineFromTag(13, rover->master->frontsector->tag, -1) != -1) @@ -3361,7 +3857,15 @@ static boolean P_CameraCheckWater(camera_t *thiscam) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE) || rover->flags & FF_BLOCKOTHERS) continue; - if (halfheight >= *rover->topheight || halfheight <= *rover->bottomheight) + if (halfheight >= ( +#ifdef ESLOPE + *rover->t_slope ? P_GetZAt(*rover->t_slope, thiscam->x, thiscam->y) : +#endif + *rover->topheight) || halfheight <= ( +#ifdef ESLOPE + *rover->b_slope ? P_GetZAt(*rover->b_slope, thiscam->x, thiscam->y) : +#endif + *rover->bottomheight)) continue; return true; From e24595ed52d011a3e640bedaca5e13af102839f7 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Thu, 21 May 2015 10:17:53 -0500 Subject: [PATCH 60/91] Make the crumble check account for slopes for... some reason --- src/p_mobj.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 4fe59bfab..cd9d36089 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -4077,6 +4077,7 @@ static void P_PlayerMobjThinker(mobj_t *mobj) // Crumbling platforms for (node = mobj->touching_sectorlist; node; node = node->m_snext) { + fixed_t topheight, bottomheight; ffloor_t *rover; for (rover = node->m_sector->ffloors; rover; rover = rover->next) @@ -4084,8 +4085,11 @@ static void P_PlayerMobjThinker(mobj_t *mobj) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_CRUMBLE)) continue; - if ((*rover->topheight == mobj->z && !(mobj->eflags & MFE_VERTICALFLIP)) - || (*rover->bottomheight == mobj->z + mobj->height && mobj->eflags & MFE_VERTICALFLIP)) // You nut. + topheight = P_GetFOFTopZ(mobj, node->m_sector, rover, mobj->x, mobj->y, NULL); + bottomheight = P_GetFOFBottomZ(mobj, node->m_sector, rover, mobj->x, mobj->y, NULL); + + if ((topheight <= mobj->z + 16*mobj->scale && topheight >= mobj->z && !(mobj->eflags & MFE_VERTICALFLIP)) + || (bottomheight >= mobj->z + mobj->height && bottomheight <= mobj->z + mobj->height - 16*mobj->scale && mobj->eflags & MFE_VERTICALFLIP)) // You nut. EV_StartCrumble(rover->master->frontsector, rover, (rover->flags & FF_FLOATBOB), mobj->player, rover->alpha, !(rover->flags & FF_NORETURN)); } } From f23f5d4379bc92f402854568a3b8453e18e22c74 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Thu, 21 May 2015 15:49:26 -0500 Subject: [PATCH 61/91] Fix flat slopes eating jumps --- src/p_mobj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index cd9d36089..6b2df9727 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2152,7 +2152,7 @@ void P_XYMovement(mobj_t *mo) #ifdef ESLOPE // adjust various things based on slope - if (mo->standingslope) { + if (mo->standingslope && abs(mo->standingslope->zdelta) > FRACUNIT>>8) { if (!P_IsObjectOnGround(mo)) { // We fell off at some point? Do the twisty thing! P_SlopeLaunch(mo); xmove = mo->momx; From 0d9f8028b7045b349935923e169e31c2017504b4 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Thu, 21 May 2015 15:49:49 -0500 Subject: [PATCH 62/91] Players now bounce off of slopes on bouncy FOFs --- src/p_user.c | 47 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 6898ee910..450ebca76 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1870,6 +1870,9 @@ static void P_CheckBouncySectors(player_t *player) fixed_t oldx; fixed_t oldy; fixed_t oldz; +#ifdef ESLOPE + v3fixed_t momentum; +#endif oldx = player->mo->x; oldy = player->mo->y; @@ -1890,16 +1893,21 @@ static void P_CheckBouncySectors(player_t *player) { ffloor_t *rover; boolean top = true; + fixed_t topheight, bottomheight; for (rover = node->m_sector->ffloors; rover; rover = rover->next) { - if (player->mo->z > *rover->topheight) + topheight = P_GetFOFTopZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); + bottomheight = P_GetFOFBottomZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); + + if (player->mo->z > topheight) continue; - if (player->mo->z + player->mo->height < *rover->bottomheight) + if (player->mo->z + player->mo->height < bottomheight) continue; - if (oldz < *rover->topheight && oldz > *rover->bottomheight) + if (oldz < P_GetFOFTopZ(player->mo, node->m_sector, rover, oldx, oldy, NULL) + && oldz + player->mo->height > P_GetFOFBottomZ(player->mo, node->m_sector, rover, oldx, oldy, NULL)) top = false; if (GETSECSPECIAL(rover->master->frontsector->special, 1) == 15) @@ -1914,7 +1922,29 @@ static void P_CheckBouncySectors(player_t *player) { fixed_t newmom; +#ifdef ESLOPE + pslope_t *slope; + if (abs(oldz - topheight) < abs(oldz + player->mo->height - bottomheight)) { // Hit top + slope = *rover->t_slope; + } else { // Hit bottom + slope = *rover->b_slope; + } + + momentum.x = player->mo->momx; + momentum.y = player->mo->momy; + momentum.z = player->mo->momz*2; + + if (slope) { + // Reverse quantizing might could use its own function later + slope->zangle = ANGLE_MAX-slope->zangle; + P_QuantizeMomentumToSlope(&momentum, slope); + slope->zangle = ANGLE_MAX-slope->zangle; + } + + newmom = momentum.z = -FixedMul(momentum.z,linedist)/2; +#else newmom = -FixedMul(player->mo->momz,linedist); +#endif if (abs(newmom) < (linedist*2)) { @@ -1937,7 +1967,18 @@ static void P_CheckBouncySectors(player_t *player) else if (newmom < -P_GetPlayerHeight(player)/2) newmom = -P_GetPlayerHeight(player)/2; +#ifdef ESLOPE + momentum.z = newmom*2; + + if (slope) + P_QuantizeMomentumToSlope(&momentum, slope); + + player->mo->momx = momentum.x; + player->mo->momy = momentum.y; + player->mo->momz = momentum.z/2; +#else player->mo->momz = newmom; +#endif if (player->pflags & PF_SPINNING) { From fb9d07b8ba7955af94c6325536c5e8549bb07953 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Thu, 21 May 2015 22:13:51 -0500 Subject: [PATCH 63/91] Bugfixes to sloped FOF plane clipping --- src/r_bsp.c | 13 +++++++++++-- src/r_segs.c | 38 ++++++++++++++++++++++---------------- 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/src/r_bsp.c b/src/r_bsp.c index 35f82f01c..5474a4345 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -908,6 +908,9 @@ static void R_Subsector(size_t num) ceilingplane = NULL; numffloors = 0; +#ifdef ESLOPE + ffloor[numffloors].slope = NULL; +#endif ffloor[numffloors].plane = NULL; ffloor[numffloors].polyobj = NULL; if (frontsector->ffloors) @@ -945,7 +948,7 @@ static void R_Subsector(size_t num) #ifdef ESLOPE light = R_GetPlaneLight(frontsector, *rover->b_slope ? P_GetZAt(*rover->b_slope, frontsector->soundorg.x, frontsector->soundorg.y) : *rover->bottomheight, - viewz < (*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : *rover->bottomheight)); + viewz < heightcheck); #else light = R_GetPlaneLight(frontsector, *rover->bottomheight, viewz < *rover->bottomheight); @@ -993,7 +996,7 @@ static void R_Subsector(size_t num) #ifdef ESLOPE light = R_GetPlaneLight(frontsector, *rover->t_slope ? P_GetZAt(*rover->t_slope, frontsector->soundorg.x, frontsector->soundorg.y) : *rover->topheight, - viewz < (*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : *rover->topheight)); + viewz < heightcheck); #else light = R_GetPlaneLight(frontsector, *rover->topheight, viewz < *rover->topheight); #endif @@ -1079,6 +1082,9 @@ static void R_Subsector(size_t num) ffloor[numffloors].height = polysec->floorheight; ffloor[numffloors].polyobj = po; +#ifdef ESLOPE + ffloor[numffloors].slope = NULL; +#endif // ffloor[numffloors].ffloor = rover; po->visplane = ffloor[numffloors].plane; numffloors++; @@ -1120,6 +1126,9 @@ static void R_Subsector(size_t num) ffloor[numffloors].polyobj = po; ffloor[numffloors].height = polysec->ceilingheight; +#ifdef ESLOPE + ffloor[numffloors].slope = NULL; +#endif // ffloor[numffloors].ffloor = rover; po->visplane = ffloor[numffloors].plane; numffloors++; diff --git a/src/r_segs.c b/src/r_segs.c index ce0260a63..2d41d702c 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -2650,7 +2650,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (*rover->b_slope || *rover->t_slope) backsector->hasslope = true; - rovertest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz; + rovertest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, backsector->soundorg.x, backsector->soundorg.y) : *rover->bottomheight) - viewz; planevistest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : *rover->bottomheight); if (rovertest>>4 <= worldhigh && @@ -2658,9 +2658,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) ((viewz < planevistest && !(rover->flags & FF_INVERTPLANES)) || (viewz > planevistest && (rover->flags & FF_BOTHPLANES)))) { - ffloor[i].slope = *rover->b_slope; - ffloor[i].b_pos = (ffloor[i].slope ? P_GetZAt(ffloor[i].slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz; - ffloor[i].b_pos_slope = (ffloor[i].slope ? P_GetZAt(ffloor[i].slope, segright.x, segright.y) : *rover->bottomheight) - viewz; + //ffloor[i].slope = *rover->b_slope; + ffloor[i].b_pos = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz; + ffloor[i].b_pos_slope = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) - viewz; ffloor[i].b_pos >>= 4; ffloor[i].b_pos_slope >>= 4; ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); @@ -2672,7 +2672,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (i >= MAXFFLOORS) break; - rovertest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) - viewz; + rovertest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, backsector->soundorg.x, backsector->soundorg.y) : *rover->topheight) - viewz; planevistest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : *rover->topheight); if (rovertest>>4 <= worldhigh && @@ -2680,9 +2680,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) ((viewz > planevistest && !(rover->flags & FF_INVERTPLANES)) || (viewz < planevistest && (rover->flags & FF_BOTHPLANES)))) { - ffloor[i].slope = *rover->t_slope; - ffloor[i].b_pos = (ffloor[i].slope ? P_GetZAt(ffloor[i].slope, segleft.x, segleft.y) : *rover->topheight) - viewz; - ffloor[i].b_pos_slope = (ffloor[i].slope ? P_GetZAt(ffloor[i].slope, segright.x, segright.y) : *rover->topheight) - viewz; + //ffloor[i].slope = *rover->t_slope; + ffloor[i].b_pos = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) - viewz; + ffloor[i].b_pos_slope = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) - viewz; ffloor[i].b_pos >>= 4; ffloor[i].b_pos_slope >>= 4; ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); @@ -2735,7 +2735,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (*rover->b_slope || *rover->t_slope) frontsector->hasslope = true; - rovertest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz; + rovertest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, frontsector->soundorg.x, frontsector->soundorg.y) : *rover->bottomheight) - viewz; planevistest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : *rover->bottomheight); if (rovertest>>4 <= worldtop && @@ -2743,9 +2743,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) ((viewz < planevistest && !(rover->flags & FF_INVERTPLANES)) || (viewz > planevistest && (rover->flags & FF_BOTHPLANES)))) { - ffloor[i].slope = *rover->b_slope; - ffloor[i].b_pos = (ffloor[i].slope ? P_GetZAt(ffloor[i].slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz; - ffloor[i].b_pos_slope = (ffloor[i].slope ? P_GetZAt(ffloor[i].slope, segright.x, segright.y) : *rover->bottomheight) - viewz; + //ffloor[i].slope = *rover->b_slope; + ffloor[i].b_pos = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz; + ffloor[i].b_pos_slope = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) - viewz; ffloor[i].b_pos >>= 4; ffloor[i].b_pos_slope >>= 4; ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); @@ -2757,7 +2757,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (i >= MAXFFLOORS) break; - rovertest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) - viewz; + rovertest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, frontsector->soundorg.x, frontsector->soundorg.y) : *rover->topheight) - viewz; planevistest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : *rover->topheight); if (rovertest>>4 <= worldtop && @@ -2765,9 +2765,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) ((viewz > planevistest && !(rover->flags & FF_INVERTPLANES)) || (viewz < planevistest && (rover->flags & FF_BOTHPLANES)))) { - ffloor[i].slope = *rover->t_slope; - ffloor[i].b_pos = (ffloor[i].slope ? P_GetZAt(ffloor[i].slope, segleft.x, segleft.y) : *rover->topheight) - viewz; - ffloor[i].b_pos_slope = (ffloor[i].slope ? P_GetZAt(ffloor[i].slope, segright.x, segright.y) : *rover->topheight) - viewz; + //ffloor[i].slope = *rover->t_slope; + ffloor[i].b_pos = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) - viewz; + ffloor[i].b_pos_slope = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) - viewz; ffloor[i].b_pos >>= 4; ffloor[i].b_pos_slope >>= 4; ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); @@ -2817,6 +2817,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (ffloor[i].plane->maxx < ds_p->x2) ffloor[i].plane->maxx = ds_p->x2; +#ifdef ESLOPE + ffloor[i].slope = NULL; +#endif ffloor[i].b_pos = backsector->floorheight; ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); @@ -2833,6 +2836,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (ffloor[i].plane->maxx < ds_p->x2) ffloor[i].plane->maxx = ds_p->x2; +#ifdef ESLOPE + ffloor[i].slope = NULL; +#endif ffloor[i].b_pos = backsector->ceilingheight; ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); From 8c54ee44e776b87f9a7c32eca611ffdc30a25bb8 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Fri, 22 May 2015 12:33:12 -0500 Subject: [PATCH 64/91] Slopey physics for some things that aren't players This is incredibly messy and probably needs redone differently at some point, but... fuck it. --- src/p_mobj.c | 121 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 87 insertions(+), 34 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 6b2df9727..2564a842e 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2387,6 +2387,12 @@ void P_XYMovement(mobj_t *mo) if (player && player->homing) // no friction for homing return; +#ifdef ESLOPE + if ((mo->type == MT_BIGTUMBLEWEED || mo->type == MT_LITTLETUMBLEWEED) + && (mo->standingslope && abs(mo->standingslope->zdelta) > FRACUNIT>>8)) // Special exception for tumbleweeds on slopes + return; +#endif + if (((!(mo->eflags & MFE_VERTICALFLIP) && mo->z > mo->floorz) || (mo->eflags & MFE_VERTICALFLIP && mo->z+mo->height < mo->ceilingz)) && !(player && player->pflags & PF_SLIDING)) return; // no friction when airborne @@ -2822,6 +2828,21 @@ static boolean P_ZMovement(mobj_t *mo) || (mo->z + mo->height >= mo->ceilingz && mo->eflags & MFE_VERTICALFLIP)) && !(mo->flags & MF_NOCLIPHEIGHT)) { + v3fixed_t mom; + mom.x = mo->momx; + mom.y = mo->momy; + mom.z = mo->momz; + +#ifdef ESLOPE + P_TryMove(mo, mo->x, mo->y, true); // Sets mo->standingslope correctly + if (mo->standingslope) { + // Reverse quantizing might could use its own function later + mo->standingslope->zangle = ANGLE_MAX-mo->standingslope->zangle; + P_QuantizeMomentumToSlope(&mom, mo->standingslope); + mo->standingslope->zangle = ANGLE_MAX-mo->standingslope->zangle; + } +#endif + if (mo->eflags & MFE_VERTICALFLIP) mo->z = mo->ceilingz - mo->height; else @@ -2829,7 +2850,7 @@ static boolean P_ZMovement(mobj_t *mo) // hit the floor if (mo->type == MT_FIREBALL) // special case for the fireball - mo->momz = P_MobjFlip(mo)*FixedMul(5*FRACUNIT, mo->scale); + mom.z = P_MobjFlip(mo)*FixedMul(5*FRACUNIT, mo->scale); else if (mo->type == MT_SPINFIRE) // elemental shield fire is another exception here ; else if (mo->flags & MF_MISSILE) @@ -2844,12 +2865,12 @@ static boolean P_ZMovement(mobj_t *mo) if (mo->flags & MF_GRENADEBOUNCE) { // Going down? (Or up in reverse gravity?) - if (P_MobjFlip(mo)*mo->momz < 0) + if (P_MobjFlip(mo)*mom.z < 0) { // If going slower than a fracunit, just stop. - if (abs(mo->momz) < FixedMul(FRACUNIT, mo->scale)) + if (abs(mom.z) < FixedMul(FRACUNIT, mo->scale)) { - mo->momx = mo->momy = mo->momz = 0; + mom.x = mom.y = mom.z = 0; // Napalm hack if (mo->type == MT_CYBRAKDEMON_NAPALM_BOMB_LARGE && mo->fuse) @@ -2857,7 +2878,7 @@ static boolean P_ZMovement(mobj_t *mo) } // Otherwise bounce up at half speed. else - mo->momz = -mo->momz/2; + mom.z = -mom.z/2; S_StartSound(mo, mo->info->activesound); } } @@ -2880,14 +2901,14 @@ static boolean P_ZMovement(mobj_t *mo) } } - if (P_MobjFlip(mo)*mo->momz < 0) // falling + if (P_MobjFlip(mo)*mom.z < 0) // falling { if (!tmfloorthing || tmfloorthing->flags & (MF_PUSHABLE|MF_MONITOR) || tmfloorthing->flags2 & MF2_STANDONME || tmfloorthing->type == MT_PLAYER) mo->eflags |= MFE_JUSTHITFLOOR; if (mo->flags2 & MF2_SKULLFLY) // the skull slammed into something - mo->momz = -mo->momz; + mom.z = -mom.z; else // Flingrings bounce if (mo->type == MT_FLINGRING @@ -2900,35 +2921,42 @@ static boolean P_ZMovement(mobj_t *mo) || mo->type == MT_FALLINGROCK) { if (maptol & TOL_NIGHTS) - mo->momz = -FixedDiv(mo->momz, 10*FRACUNIT); + mom.z = -FixedDiv(mom.z, 10*FRACUNIT); else - mo->momz = -FixedMul(mo->momz, FixedDiv(17*FRACUNIT,20*FRACUNIT)); + mom.z = -FixedMul(mom.z, FixedDiv(17*FRACUNIT,20*FRACUNIT)); if (mo->type == MT_BIGTUMBLEWEED || mo->type == MT_LITTLETUMBLEWEED) { - if (abs(mo->momx) < FixedMul(STOPSPEED, mo->scale) - && abs(mo->momy) < FixedMul(STOPSPEED, mo->scale) - && abs(mo->momz) < FixedMul(STOPSPEED*3, mo->scale)) + if (abs(mom.x) < FixedMul(STOPSPEED, mo->scale) + && abs(mom.y) < FixedMul(STOPSPEED, mo->scale) + && abs(mom.z) < FixedMul(STOPSPEED*3, mo->scale)) { - if (!(mo->flags & MF_AMBUSH)) - { - mo->momx = mo->momy = mo->momz = 0; - P_SetMobjState(mo, mo->info->spawnstate); - } - else + if (mo->flags & MF_AMBUSH) { // If deafed, give the tumbleweed another random kick if it runs out of steam. - mo->momz += P_MobjFlip(mo)*FixedMul(6*FRACUNIT, mo->scale); + mom.z += P_MobjFlip(mo)*FixedMul(6*FRACUNIT, mo->scale); if (P_Random() & 1) - mo->momx += FixedMul(6*FRACUNIT, mo->scale); + mom.x += FixedMul(6*FRACUNIT, mo->scale); else - mo->momx -= FixedMul(6*FRACUNIT, mo->scale); + mom.x -= FixedMul(6*FRACUNIT, mo->scale); if (P_Random() & 1) - mo->momy += FixedMul(6*FRACUNIT, mo->scale); + mom.y += FixedMul(6*FRACUNIT, mo->scale); else - mo->momy -= FixedMul(6*FRACUNIT, mo->scale); + mom.y -= FixedMul(6*FRACUNIT, mo->scale); + } +#ifdef ESLOPE + else if (mo->standingslope && abs(mo->standingslope->zdelta) > FRACUNIT>>8) + { + // Pop the object up a bit to encourage bounciness + //mom.z = P_MobjFlip(mo)*mo->scale; + } +#endif + else + { + mom.x = mom.y = mom.z = 0; + P_SetMobjState(mo, mo->info->spawnstate); } } @@ -2938,14 +2966,14 @@ static boolean P_ZMovement(mobj_t *mo) } else if (mo->type == MT_FALLINGROCK) { - if (P_MobjFlip(mo)*mo->momz > FixedMul(2*FRACUNIT, mo->scale)) + if (P_MobjFlip(mo)*mom.z > FixedMul(2*FRACUNIT, mo->scale)) S_StartSound(mo, mo->info->activesound + P_RandomKey(mo->info->mass)); - mo->momz /= 2; // Rocks not so bouncy + mom.z /= 2; // Rocks not so bouncy - if (abs(mo->momx) < FixedMul(STOPSPEED, mo->scale) - && abs(mo->momy) < FixedMul(STOPSPEED, mo->scale) - && abs(mo->momz) < FixedMul(STOPSPEED*3, mo->scale)) + if (abs(mom.x) < FixedMul(STOPSPEED, mo->scale) + && abs(mom.y) < FixedMul(STOPSPEED, mo->scale) + && abs(mom.z) < FixedMul(STOPSPEED*3, mo->scale)) { P_RemoveMobj(mo); return false; @@ -2953,20 +2981,30 @@ static boolean P_ZMovement(mobj_t *mo) } else if (mo->type == MT_CANNONBALLDECOR) { - mo->momz /= 2; - if (abs(mo->momz) < FixedMul(STOPSPEED*3, mo->scale)) - mo->momz = 0; + mom.z /= 2; + if (abs(mom.z) < FixedMul(STOPSPEED*3, mo->scale)) + mom.z = 0; } } else if (tmfloorthing && (tmfloorthing->flags & (MF_PUSHABLE|MF_MONITOR) || tmfloorthing->flags2 & MF2_STANDONME || tmfloorthing->type == MT_PLAYER)) - mo->momz = tmfloorthing->momz; + mom.z = tmfloorthing->momz; else if (!tmfloorthing) - mo->momz = 0; + mom.z = 0; } else if (tmfloorthing && (tmfloorthing->flags & (MF_PUSHABLE|MF_MONITOR) || tmfloorthing->flags2 & MF2_STANDONME || tmfloorthing->type == MT_PLAYER)) - mo->momz = tmfloorthing->momz; + mom.z = tmfloorthing->momz; + +#ifdef ESLOPE + if (mo->standingslope) { + P_QuantizeMomentumToSlope(&mom, mo->standingslope); + } +#endif + + mo->momx = mom.x; + mo->momy = mom.y; + mo->momz = mom.z; if (mo->type == MT_STEAM) return true; @@ -7798,6 +7836,21 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s mobj->eflags &= ~MFE_JUSTHITFLOOR; } +#ifdef ESLOPE // Sliding physics for slidey mobjs! + if (mobj->type == MT_FLINGRING + || mobj->type == MT_FLINGCOIN + || P_WeaponOrPanel(mobj->type) + || mobj->type == MT_FLINGEMERALD + || mobj->type == MT_BIGTUMBLEWEED + || mobj->type == MT_LITTLETUMBLEWEED + || mobj->type == MT_CANNONBALLDECOR + || mobj->type == MT_FALLINGROCK) { + P_TryMove(mobj, mobj->x, mobj->y, true); // Sets mo->standingslope correctly + //if (mobj->standingslope) CONS_Printf("slope physics on mobj\n"); + P_ButteredSlope(mobj); + } +#endif + if (mobj->flags & (MF_ENEMY|MF_BOSS) && mobj->health && P_CheckDeathPitCollide(mobj)) // extra pit check in case these didn't have momz { From 3f8e7b173952c04fcc82e9e1ee856c0c280dce8b Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Fri, 22 May 2015 20:57:58 -0500 Subject: [PATCH 65/91] Revert/remove unused/broken junk from original slopes port m_vector removal to come later. The little thing commented out in it is so I could revert the weird tables.c change. --- src/m_vector.c | 2 +- src/p_enemy.c | 4 --- src/p_floor.c | 3 -- src/p_local.h | 15 ---------- src/p_map.c | 58 +++++++++--------------------------- src/p_maputl.c | 12 +++----- src/p_mobj.c | 1 + src/p_mobj.h | 5 ---- src/p_spec.c | 16 ++++------ src/p_user.c | 81 -------------------------------------------------- src/tables.c | 5 ++-- src/tables.h | 5 ++-- 12 files changed, 31 insertions(+), 176 deletions(-) diff --git a/src/m_vector.c b/src/m_vector.c index 274a806a6..96ed7cae0 100644 --- a/src/m_vector.c +++ b/src/m_vector.c @@ -330,7 +330,7 @@ angle_t FV_AngleBetweenVectors(const v3fixed_t *Vector1, const v3fixed_t *Vector fixed_t vectorsMagnitude = FixedMul(FV_Magnitude(Vector1), FV_Magnitude(Vector2)); // Return the arc cosine of the (dotProduct / vectorsMagnitude) which is the angle in RADIANS. - return FixedAcos(FixedDiv(dotProduct, vectorsMagnitude)); + return 0;//ALFALFA FixedAcos(FixedDiv(dotProduct, vectorsMagnitude)); } float FV_AngleBetweenVectorsf(const v3float_t *Vector1, const v3float_t *Vector2) diff --git a/src/p_enemy.c b/src/p_enemy.c index 43c0f5057..369b6f0c8 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -28,10 +28,6 @@ #include "hardware/hw3sound.h" #endif -#ifdef SPRINGCLEAN// ESLOPE -#include "p_slopes.h" -#endif - #ifdef HAVE_BLUA boolean LUA_CallAction(const char *action, mobj_t *actor); #endif diff --git a/src/p_floor.c b/src/p_floor.c index 0d68becbf..4e289c8d5 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -19,9 +19,6 @@ #include "z_zone.h" #include "g_game.h" #include "r_main.h" -#ifdef SPRINGCLEAN// ESLOPE -#include "p_slopes.h" -#endif // ========================================================================== // FLOORS diff --git a/src/p_local.h b/src/p_local.h index f2376494a..1c5874b93 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -53,15 +53,6 @@ // above this, a height difference is considered as a 'dropoff' #define MAXSTEPMOVE (24*FRACUNIT) -#ifdef ESLOPE -// [RH] Minimum floorplane.c value for walking -// The lower the value, the steeper the slope is -#define SECPLANESTEEPSLOPE 46000 -// ESLOPE stuff - a slope of 4 or lower is so level, treat it as flat -#define LEVELSLOPE 4 -#define STEEPSLOPE 65 -#endif - #define USERANGE (64*FRACUNIT) #define MELEERANGE (64*FRACUNIT) #define MISSILERANGE (32*64*FRACUNIT) @@ -147,12 +138,6 @@ boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec); boolean P_InSpaceSector(mobj_t *mo); boolean P_InQuicksand(mobj_t *mo); -#ifdef ESLOPE -boolean P_IsObjectOnSlope(mobj_t *mo, boolean ceiling); -boolean P_SlopeGreaterThan(mobj_t *mo, boolean ceiling, int value); -boolean P_SlopeLessThan(mobj_t *mo, boolean ceiling, int value); -#endif - void P_SetObjectMomZ(mobj_t *mo, fixed_t value, boolean relative); void P_RestoreMusic(player_t *player); void P_SpawnShieldOrb(player_t *player); diff --git a/src/p_map.c b/src/p_map.c index e2ea76b88..eeff412d8 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1756,30 +1756,8 @@ boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam) } else { -#ifdef ESLOPE // SRB2CBTODO: Checking the things momx/y help with collision issues, but makes going done slopes not as smooth - if (thiscam->subsector->sector && thiscam->subsector->sector->f_slope) - { - // SRB2CBTODO: Support a mobj's gravity for this too - if (P_GetZAt(thiscam->subsector->sector->f_slope, thiscam->x+thiscam->momx, thiscam->y+thiscam->momy) > P_GetZAt(thiscam->subsector->sector->f_slope, thiscam->x, thiscam->y)) - thiscam->floorz = P_GetZAt(thiscam->subsector->sector->f_slope, thiscam->x+thiscam->momx, thiscam->y+thiscam->momy); - else - thiscam->floorz = P_GetZAt(thiscam->subsector->sector->f_slope, thiscam->x, thiscam->y); - } - else -#endif - tmfloorz = thiscam->subsector->sector->floorheight; -#ifdef ESLOPE - if (thiscam->subsector->sector && thiscam->subsector->sector->c_slope) - { - // SRB2CBTODO: Support a mobj's gravity for this too - if (P_GetZAt(thiscam->subsector->sector->c_slope, thiscam->x+thiscam->momx, thiscam->y+thiscam->momy) < P_GetZAt(thiscam->subsector->sector->c_slope, thiscam->x, thiscam->y)) - thiscam->ceilingz = P_GetZAt(thiscam->subsector->sector->c_slope, thiscam->x, thiscam->y); - else - thiscam->ceilingz = P_GetZAt(thiscam->subsector->sector->c_slope, thiscam->x+thiscam->momx, thiscam->y+thiscam->momy); - } - else -#endif - tmceilingz = thiscam->subsector->sector->ceilingheight; + tmfloorz = P_CameraGetFloorZ(thiscam, thiscam->subsector->sector, x, y, NULL); + tmceilingz = P_CameraGetCeilingZ(thiscam, thiscam->subsector->sector, x, y, NULL); } // the move is ok, @@ -2074,7 +2052,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) if (thing->momz <= 0) thing->standingslope = tmfloorslope; } - else if (thing->z+thing->height >= tmceilingz /*&& thing->momz >= 0*/ && (thing->eflags & MFE_VERTICALFLIP)) { + else if (thing->z+thing->height >= tmceilingz && (thing->eflags & MFE_VERTICALFLIP)) { if (!startingonground && tmceilingslope) P_HandleSlopeLanding(thing, tmceilingslope); @@ -2120,15 +2098,7 @@ boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y) if (!(thing->flags & MF_NOCLIP)) { - fixed_t maxstep = MAXSTEPMOVE; - -#ifdef ESLOPE // TODO: Make this collosion better - // Maxstepmove = 0 means the object bounces like a nut while going down a slope - if (thing->subsector->sector->f_slope) - { - maxstep *= thing->subsector->sector->f_slope->zangle; - } -#endif + const fixed_t maxstep = MAXSTEPMOVE; if (tmceilingz - tmfloorz < thing->height) return false; // doesn't fit @@ -2450,6 +2420,7 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle) if (glidesector->sector != player->mo->subsector->sector) { boolean floorclimb = false; + fixed_t topheight, bottomheight; if (glidesector->sector->ffloors) { @@ -2459,8 +2430,8 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER)) continue; - fixed_t topheight = *rover->topheight; - fixed_t bottomheight = *rover->bottomheight; + topheight = *rover->topheight; + bottomheight = *rover->bottomheight; #ifdef ESLOPE if (*rover->t_slope) @@ -2551,7 +2522,6 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle) static boolean PTR_SlideTraverse(intercept_t *in) { line_t *li; - fixed_t maxstep; I_Assert(in->isaline); @@ -2584,9 +2554,7 @@ static boolean PTR_SlideTraverse(intercept_t *in) if (opentop - slidemo->z < slidemo->height) goto isblocking; // mobj is too high - maxstep = FixedMul(MAXSTEPMOVE, slidemo->scale); - - if (openbottom - slidemo->z > maxstep) + if (openbottom - slidemo->z > FixedMul(MAXSTEPMOVE, slidemo->scale)) goto isblocking; // too big a step up // this line doesn't block movement @@ -2607,6 +2575,7 @@ isblocking: line_t *checkline = li; sector_t *checksector; ffloor_t *rover; + fixed_t topheight, bottomheight; boolean fofline = false; INT32 side = P_PointOnLineSide(slidemo->x, slidemo->y, li); @@ -2622,8 +2591,8 @@ isblocking: if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP)) continue; - fixed_t topheight = *rover->topheight; - fixed_t bottomheight = *rover->bottomheight; + topheight = *rover->topheight; + bottomheight = *rover->bottomheight; #ifdef ESLOPE if (*rover->t_slope) @@ -3258,6 +3227,7 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush) if (thing->subsector->sector->ffloors && (realcrush || thing->flags & MF_PUSHABLE)) { ffloor_t *rover; + fixed_t topheight, bottomheight; fixed_t delta1, delta2; INT32 thingtop = thing->z + thing->height; @@ -3267,8 +3237,8 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush) || ((rover->flags & FF_BLOCKOTHERS) && !thing->player)) || !(rover->flags & FF_EXISTS)) continue; - fixed_t topheight = *rover->topheight; - fixed_t bottomheight = *rover->bottomheight; + topheight = *rover->topheight; + bottomheight = *rover->bottomheight; /*#ifdef ESLOPE if (rover->t_slope) diff --git a/src/p_maputl.c b/src/p_maputl.c index a60d9232d..c9a42bd43 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -21,9 +21,6 @@ #include "p_maputl.h" #include "p_polyobj.h" #include "z_zone.h" -#ifdef SPRINGCLEAN// ESLOPE -#include "p_slopes.h" -#endif // // P_AproxDistance @@ -862,6 +859,7 @@ void P_SetThingPosition(mobj_t *thing) { // link into subsector subsector_t *ss; sector_t *oldsec = NULL; + fixed_t tfloorz, tceilz; I_Assert(thing != NULL); I_Assert(!P_MobjWasRemoved(thing)); @@ -871,11 +869,6 @@ void P_SetThingPosition(mobj_t *thing) ss = thing->subsector = R_PointInSubsector(thing->x, thing->y); - fixed_t tfloorz, tceilz; - - tfloorz = P_GetFloorZ(thing, ss->sector, thing->x, thing->y, NULL); - tceilz = P_GetCeilingZ(thing, ss->sector, thing->x, thing->y, NULL); - if (!(thing->flags & MF_NOSECTOR)) { // invisible things don't go into the sector links @@ -936,6 +929,9 @@ void P_SetThingPosition(mobj_t *thing) // sector's floor is the same height. if (thing->player && oldsec != NULL && thing->subsector && oldsec != thing->subsector->sector) { + tfloorz = P_GetFloorZ(thing, ss->sector, thing->x, thing->y, NULL); + tceilz = P_GetCeilingZ(thing, ss->sector, thing->x, thing->y, NULL); + if (thing->eflags & MFE_VERTICALFLIP) { if (thing->z + thing->height >= tceilz) diff --git a/src/p_mobj.c b/src/p_mobj.c index 2564a842e..7a3ee0bbd 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2181,6 +2181,7 @@ void P_XYMovement(mobj_t *mo) if (!P_TryMove(mo, mo->x + xmove, mo->y + ymove, true) && !(mo->eflags & MFE_SPRUNG)) { // blocked move + if (player) { moved = false; if (player->bot) diff --git a/src/p_mobj.h b/src/p_mobj.h index 0dc323d73..d7a370c38 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -28,11 +28,6 @@ // Needs precompiled tables/data structures. #include "info.h" -// For slope code, we need v3float_t -#ifdef ESLOPE -//#include "r_defs.h" -#endif - // // NOTES: mobj_t // diff --git a/src/p_spec.c b/src/p_spec.c index 3126413b5..914e008d9 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -33,9 +33,6 @@ #include "m_misc.h" #include "m_cond.h" //unlock triggers #include "lua_hook.h" // LUAh_LinedefExecute -#ifdef ESLOPE -#include "p_slopes.h" -#endif #ifdef HW3SOUND #include "hardware/hw3sound.h" @@ -4522,6 +4519,7 @@ static void P_PlayerOnSpecial3DFloor(player_t *player, sector_t *sector) static void P_RunSpecialSectorCheck(player_t *player, sector_t *sector) { boolean nofloorneeded = false; + fixed_t f_affectpoint, c_affectpoint; if (!sector->special) // nothing special, exit return; @@ -4584,8 +4582,8 @@ static void P_RunSpecialSectorCheck(player_t *player, sector_t *sector) return; } - fixed_t f_affectpoint = P_GetFloorZ(player->mo, sector, player->mo->x, player->mo->y, NULL);//sector->floorheight; - fixed_t c_affectpoint = P_GetCeilingZ(player->mo, sector, player->mo->x, player->mo->y, NULL);//sector->ceilingheight; + f_affectpoint = P_GetFloorZ(player->mo, sector, player->mo->x, player->mo->y, NULL); + c_affectpoint = P_GetCeilingZ(player->mo, sector, player->mo->x, player->mo->y, NULL); // Only go further if on the ground if ((sector->flags & SF_FLIPSPECIAL_FLOOR) && !(sector->flags & SF_FLIPSPECIAL_CEILING) && player->mo->z != f_affectpoint) @@ -7386,12 +7384,8 @@ void T_Pusher(pusher_t *p) || GETSECSPECIAL(referrer->special, 3) == 3) foundfloor = true; } - else if ( -#ifdef ESLOPE - (!sec->f_slope) && -#endif - (!(GETSECSPECIAL(sec->special, 3) == 2 - || GETSECSPECIAL(sec->special, 3) == 3))) + else if (!(GETSECSPECIAL(sec->special, 3) == 2 + || GETSECSPECIAL(sec->special, 3) == 3)) return; if (p->roverpusher && foundfloor == false) // Not even a 3d floor has the PUSH_MASK. diff --git a/src/p_user.c b/src/p_user.c index 450ebca76..b389985b6 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1197,87 +1197,6 @@ boolean P_IsObjectOnGround(mobj_t *mo) return false; } -#ifdef ESLOPE -// -// P_IsObjectOnSlope -// -// Returns true if the player is -// on a slope. Takes reverse -// gravity into account. -// -boolean P_IsObjectOnSlope(mobj_t *mo, boolean ceiling) -{ - if (ceiling && (mo->eflags & MFE_VERTICALFLIP)) - { - if ((mo->z + mo->height >= mo->ceilingz) && mo->subsector->sector->c_slope) // SRB2CBTODO: allow being on underside of mobj too? - return true; - } - else - { - if (mo->z <= mo->floorz && mo->subsector->sector->f_slope) - return true; - } - - return false; -} - -// -// P_SlopeGreaterThan -// -// Returns true if the object is on a slope -// that has an angle greater than the value -// -boolean P_SlopeGreaterThan(mobj_t *mo, boolean ceiling, int value) -{ - if (ceiling && (mo->eflags & MFE_VERTICALFLIP)) - { - if ((mo->z + mo->height >= mo->ceilingz) && mo->subsector->sector->c_slope) - { - if (value < mo->subsector->sector->c_slope->zangle) - return true; - } - } - else - { - if (mo->z <= mo->floorz && mo->subsector->sector->f_slope) - { - if (value < mo->subsector->sector->f_slope->zangle) - return true; - } - } - - return false; -} - -// -// P_SlopeLessThan -// -// Returns true if the object is on a slope -// that has an angle less than the value -// -boolean P_SlopeLessThan(mobj_t *mo, boolean ceiling, int value) -{ - if (ceiling && (mo->eflags & MFE_VERTICALFLIP)) - { - if ((mo->z + mo->height >= mo->ceilingz) && mo->subsector->sector->c_slope) - { - if (value < mo->subsector->sector->c_slope->zangle) - return true; - } - } - else - { - if (mo->z <= mo->floorz && mo->subsector->sector->f_slope) - { - if (value < mo->subsector->sector->f_slope->zangle) - return true; - } - } - - return false; -} -#endif - // // P_IsObjectOnGroundIn // diff --git a/src/tables.c b/src/tables.c index cfc17c9c9..fa71effef 100644 --- a/src/tables.c +++ b/src/tables.c @@ -2225,6 +2225,9 @@ angle_t tantoangle[2049] = 536870912 }; + +#ifdef NEED_FIXED_VECTOR + static angle_t fineacon[65536*2] = { ANGLE_MAX, 2143707442, 2142143280, 2140943052, 2139931208, 2139039753, 2138233813, 2137492672, 2136802831, 2136154917, 2135542102, 2134959233, 2134402306, 2133868139, 2133354148, 2132858208, 2132378539, 2131913638, 2131462220, 2131023174, 2130595537, 2130178462, 2129771202, 2129373097, 2128983555, 2128602046, 2128228092, 2127861261, 2127501162, 2127147436, 2126799757, 2126457825, @@ -10426,8 +10429,6 @@ FUNCMATH angle_t FixedAcos(fixed_t x) return fineacon[((x<<(FINE_FRACBITS-FRACBITS)))+FRACUNIT]; } -#ifdef NEED_FIXED_VECTOR - // // AngleBetweenVectors // diff --git a/src/tables.h b/src/tables.h index cd6a17ff5..219d668b9 100644 --- a/src/tables.h +++ b/src/tables.h @@ -96,11 +96,12 @@ FUNCMATH angle_t FixedAngle(fixed_t fa); // and with a factor, with +factor for (fa/factor) and -factor for (fa*factor) FUNCMATH angle_t FixedAngleC(fixed_t fa, fixed_t factor); -/// The FixedAcos function -FUNCMATH angle_t FixedAcos(fixed_t x); #ifdef NEED_FIXED_VECTOR +/// The FixedAcos function +FUNCMATH angle_t FixedAcos(fixed_t x); + /// Fixed Point Vector functions angle_t FV2_AngleBetweenVectors(const vector2_t *Vector1, const vector2_t *Vector2); angle_t FV3_AngleBetweenVectors(const vector3_t *Vector1, const vector3_t *Vector2); From 89319b1c2a27c4a2fee5dca9caae1ebc12866e37 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Fri, 22 May 2015 22:07:07 -0500 Subject: [PATCH 66/91] Dummy out m_vector and use m_fixed's functions instead These functions were already here before, and I /swear/ the slope physics became slightly less glitchy after switching to them... Only issue is the slope plane mapping code hasn't been properly converted yet, so they don't render properly for now. --- src/doomdef.h | 1 - src/m_fixed.c | 2 +- src/m_fixed.h | 2 +- src/m_vector.c | 3 ++- src/m_vector.h | 2 +- src/p_mobj.c | 4 ++-- src/p_slopes.c | 44 +++++++++++++++++--------------------------- src/p_slopes.h | 7 +------ src/p_user.c | 4 ++-- src/r_defs.h | 15 +++------------ src/r_draw.c | 2 +- src/r_draw.h | 5 ++++- src/r_plane.c | 9 +++++---- src/tables.c | 2 +- src/tables.h | 2 +- 15 files changed, 42 insertions(+), 62 deletions(-) diff --git a/src/doomdef.h b/src/doomdef.h index c150b46b9..bfa5ee0ce 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -441,7 +441,6 @@ extern const char *compdate, *comptime, *comprevision; /// Kalaron/Eternity Engine slope code (SRB2CB ported) /// Depends on NEED_FIXED_VECTORS? for a few functions. -/// However, uses own vector types for math. #define ESLOPE /// Fixed and float point types diff --git a/src/m_fixed.c b/src/m_fixed.c index 25a25a966..739265aa2 100644 --- a/src/m_fixed.c +++ b/src/m_fixed.c @@ -119,7 +119,7 @@ fixed_t FixedHypot(fixed_t x, fixed_t y) return FixedMul(ax, yx1); // |x|*((1 + (x/y)^2)^1/2) } -#ifdef NEED_FIXED_VECTOR +#if 1 //#ifdef NEED_FIXED_VECTOR vector2_t *FV2_Load(vector2_t *vec, fixed_t x, fixed_t y) { diff --git a/src/m_fixed.h b/src/m_fixed.h index 92b992632..53962269b 100644 --- a/src/m_fixed.h +++ b/src/m_fixed.h @@ -358,7 +358,7 @@ FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedRound(fixed_t x) } -#ifdef NEED_FIXED_VECTOR +#if 1//#ifdef NEED_FIXED_VECTOR typedef struct { diff --git a/src/m_vector.c b/src/m_vector.c index 96ed7cae0..b417fd980 100644 --- a/src/m_vector.c +++ b/src/m_vector.c @@ -24,7 +24,7 @@ // SoM created 05/18/09 // //----------------------------------------------------------------------------- - +#if 0 // GET THIS SHEIT OUTTA HEEEEEEEEEEEEEEEEEEEEEEERE #include "doomdef.h" #include "m_vector.h" #include "r_main.h" @@ -1156,3 +1156,4 @@ void FV_Normalf(const v3float_t *a_triangle, v3float_t *a_normal) // EOF #endif // #ifdef ESLOPE +#endif diff --git a/src/m_vector.h b/src/m_vector.h index 37d30c746..a2be3a7de 100644 --- a/src/m_vector.h +++ b/src/m_vector.h @@ -28,7 +28,7 @@ #ifndef M_VECTOR_H__ #define M_VECTOR_H__ -#ifdef ESLOPE +#if 0 //#ifdef ESLOPE #include "m_fixed.h" #include "tables.h" diff --git a/src/p_mobj.c b/src/p_mobj.c index 7a3ee0bbd..270220f82 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2116,7 +2116,7 @@ void P_XYMovement(mobj_t *mo) boolean moved; #ifdef ESLOPE pslope_t *oldslope = NULL; - v3fixed_t slopemom; + vector3_t slopemom; fixed_t predictedz = 0; #endif @@ -2829,7 +2829,7 @@ static boolean P_ZMovement(mobj_t *mo) || (mo->z + mo->height >= mo->ceilingz && mo->eflags & MFE_VERTICALFLIP)) && !(mo->flags & MF_NOCLIPHEIGHT)) { - v3fixed_t mom; + vector3_t mom; mom.x = mo->momx; mom.y = mo->momy; mom.z = mo->momz; diff --git a/src/p_slopes.c b/src/p_slopes.c index a4f334caf..a1bfb01c3 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -79,7 +79,7 @@ void P_RunDynamicSlopes(void) { } if (slope->zdelta != FixedDiv(zdelta, slope->extent)) { - slope->zdeltaf = FIXED_TO_FLOAT(slope->zdelta = FixedDiv(zdelta, slope->extent)); + slope->zdelta = FixedDiv(zdelta, slope->extent); slope->zangle = R_PointToAngle2(0, 0, slope->extent, -zdelta); P_CalculateSlopeNormal(slope); } @@ -91,20 +91,20 @@ void P_RunDynamicSlopes(void) { // // Alocates and fill the contents of a slope structure. // -static pslope_t *P_MakeSlope(const v3fixed_t *o, const v2fixed_t *d, +static pslope_t *P_MakeSlope(const vector3_t *o, const vector2_t *d, const fixed_t zdelta, boolean dynamic) { pslope_t *ret = Z_Malloc(sizeof(pslope_t), PU_LEVEL, NULL); memset(ret, 0, sizeof(*ret)); - ret->of.x = FIXED_TO_FLOAT(ret->o.x = o->x); - ret->of.y = FIXED_TO_FLOAT(ret->o.y = o->y); - ret->of.z = FIXED_TO_FLOAT(ret->o.z = o->z); + ret->o.x = o->x; + ret->o.y = o->y; + ret->o.z = o->z; - ret->df.x = FIXED_TO_FLOAT(ret->d.x = d->x); - ret->df.y = FIXED_TO_FLOAT(ret->d.y = d->y); + ret->d.x = d->x; + ret->d.y = d->y; - ret->zdeltaf = FIXED_TO_FLOAT(ret->zdelta = zdelta); + ret->zdelta = zdelta; if (dynamic) { // Add to the dynamic slopes list ret->next = dynslopes; @@ -170,8 +170,8 @@ void P_SpawnSlope_Line(int linenum) line_t *line = lines + linenum; INT16 special = line->special; pslope_t *fslope = NULL, *cslope = NULL; - v3fixed_t origin, point; - v2fixed_t direction; + vector3_t origin, point; + vector2_t direction; fixed_t nx, ny, dz, extent; boolean frontfloor = (special == 386 || special == 388 || special == 393); @@ -772,7 +772,7 @@ fixed_t P_GetZAt(pslope_t *slope, fixed_t x, fixed_t y) return slope->o.z + FixedMul(dist, slope->zdelta); } - +#ifdef SPRINGCLEAN // // P_GetZAtf // @@ -786,30 +786,20 @@ float P_GetZAtf(pslope_t *slope, float x, float y) float dist = (x - slope->of.x) * slope->df.x + (y - slope->of.y) * slope->df.y; return slope->of.z + (dist * slope->zdeltaf); } - -// Unused? -Red -// P_DistFromPlanef -// -float P_DistFromPlanef(const v3float_t *point, const v3float_t *pori, - const v3float_t *pnormal) -{ - return (point->x - pori->x) * pnormal->x + - (point->y - pori->y) * pnormal->y + - (point->z - pori->z) * pnormal->z; -} +#endif // // P_QuantizeMomentumToSlope // // When given a vector, rotates it and aligns it to a slope -void P_QuantizeMomentumToSlope(v3fixed_t *momentum, pslope_t *slope) +void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope) { - v3fixed_t axis; + vector3_t axis; axis.x = -slope->d.y; axis.y = slope->d.x; axis.z = 0; - M_VecRotate(momentum, &axis, slope->zangle); + FV3_Rotate(momentum, &axis, slope->zangle >> ANGLETOFINESHIFT); } // @@ -821,7 +811,7 @@ void P_SlopeLaunch(mobj_t *mo) // Double the pre-rotation Z, then halve the post-rotation Z. This reduces the // vertical launch given from slopes while increasing the horizontal launch // given. Good for SRB2's gravity and horizontal speeds. - v3fixed_t slopemom; + vector3_t slopemom; slopemom.x = mo->momx; slopemom.y = mo->momy; slopemom.z = mo->momz*2; @@ -838,7 +828,7 @@ void P_SlopeLaunch(mobj_t *mo) // Function to help handle landing on slopes void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope) { - v3fixed_t mom; + vector3_t mom; mom.x = thing->momx; mom.y = thing->momy; mom.z = thing->momz*2; diff --git a/src/p_slopes.h b/src/p_slopes.h index 4281d5796..916690fe7 100644 --- a/src/p_slopes.h +++ b/src/p_slopes.h @@ -71,13 +71,8 @@ fixed_t P_GetZAt(pslope_t *slope, fixed_t x, fixed_t y); float P_GetZAtf(pslope_t *slope, float x, float y); -// Unused? -Red -// Returns the distance of the given point from the given origin and normal. -float P_DistFromPlanef(const v3float_t *point, const v3float_t *pori, - const v3float_t *pnormal); - // Lots of physics-based bullshit -void P_QuantizeMomentumToSlope(v3fixed_t *momentum, pslope_t *slope); +void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope); void P_SlopeLaunch(mobj_t *mo); void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope); void P_ButteredSlope(mobj_t *mo); diff --git a/src/p_user.c b/src/p_user.c index b389985b6..115c79638 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1790,7 +1790,7 @@ static void P_CheckBouncySectors(player_t *player) fixed_t oldy; fixed_t oldz; #ifdef ESLOPE - v3fixed_t momentum; + vector3_t momentum; #endif oldx = player->mo->x; @@ -4519,7 +4519,7 @@ static void P_3dMovement(player_t *player) boolean analogmove = false; fixed_t oldMagnitude, newMagnitude; #ifdef ESLOPE - v3fixed_t totalthrust; + vector3_t totalthrust; totalthrust.x = totalthrust.y = 0; // I forget if this is needed totalthrust.z = FRACUNIT*P_MobjFlip(player->mo)/3; // A bit of extra push-back on slopes diff --git a/src/r_defs.h b/src/r_defs.h index 27e4b9170..9f35af7e5 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -236,30 +236,21 @@ typedef struct secplane_t // Kalaron Slopes #ifdef ESLOPE -#include "m_vector.h" - typedef struct pslope_s { // --- Information used in clipping/projection --- // Origin vector for the plane - // NOTE: All similarly named entries in this struct do the same thing, - // differing with just 'f' in the name for float: - // o = of, d = df, zdelta = zdeltaf; the only difference is that one's fixed, - // and the one with the 'f' is floating point, for easier reference elsewhere in the code - v3fixed_t o; - v3float_t of; + vector3_t o; // 2-Dimentional vector (x, y) normalized. Used to determine distance from // the origin in 2d mapspace. (Basically a thrust of FRACUNIT in xydirection angle) - v2fixed_t d; - v2float_t df; + vector2_t d; // The rate at which z changes based on distance from the origin plane. fixed_t zdelta; - float zdeltaf; // The normal of the slope; will always point upward, and thus be inverted on ceilings. I think it's only needed for physics? -Red - v3fixed_t normal; + vector3_t normal; // For comparing when a slope should be rendered fixed_t lowz; diff --git a/src/r_draw.c b/src/r_draw.c index e63aa5a2b..f25ecfa04 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -105,7 +105,7 @@ UINT8 *ds_transmap; // one of the translucency tables #ifdef ESLOPE pslope_t *ds_slope; // Current slope being used -v3float_t ds_su, ds_sv, ds_sz; // Vectors for... stuff? +FVector ds_su, ds_sv, ds_sz; // Vectors for... stuff? float focallengthf, zeroheight; #endif diff --git a/src/r_draw.h b/src/r_draw.h index 1116e1c25..b29791cc4 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -61,8 +61,11 @@ extern UINT8 *ds_source; // start of a 64*64 tile image extern UINT8 *ds_transmap; #ifdef ESLOPE +///TODO: either convert ds_su, etc to FPU or declare a floating-point vector type somewhere +#include "hardware/hw_defs.h" + pslope_t *ds_slope; // Current slope being used -v3float_t ds_su, ds_sv, ds_sz; // Vectors for... stuff? +FVector ds_su, ds_sv, ds_sz; // Vectors for... stuff? float focallengthf, zeroheight; #endif diff --git a/src/r_plane.c b/src/r_plane.c index b0768539b..839f2fa38 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -941,7 +941,7 @@ void R_DrawSinglePlane(visplane_t *pl) if (pl->slope) { // Potentially override other stuff for now cus we're mean. :< But draw a slope plane! // I copied ZDoom's code and adapted it to SRB2... -Red - v3float_t p, m, n; + FVector p, m, n; angle_t ang; //double zeroheight; @@ -972,9 +972,10 @@ void R_DrawSinglePlane(visplane_t *pl) m.y = FIXED_TO_FLOAT(P_GetZAt(pl->slope, viewx + FINESINE(ang), viewy + FINECOSINE(ang))) - zeroheight; n.y = FIXED_TO_FLOAT(P_GetZAt(pl->slope, viewx + FINECOSINE(ang), viewy - FINESINE(ang))) - zeroheight; - M_CrossProduct3f(&ds_su, &p, &m); - M_CrossProduct3f(&ds_sv, &p, &n); - M_CrossProduct3f(&ds_sz, &m, &n); + ///TODO: slope FPU conversion stuff + //M_CrossProduct3f(&ds_su, &p, &m); + //M_CrossProduct3f(&ds_sv, &p, &n); + //M_CrossProduct3f(&ds_sz, &m, &n); ds_su.z *= focallengthf; ds_sv.z *= focallengthf; diff --git a/src/tables.c b/src/tables.c index fa71effef..3ee2685c8 100644 --- a/src/tables.c +++ b/src/tables.c @@ -2226,7 +2226,7 @@ angle_t tantoangle[2049] = }; -#ifdef NEED_FIXED_VECTOR +#if 1 //#ifdef NEED_FIXED_VECTOR static angle_t fineacon[65536*2] = { ANGLE_MAX, 2143707442, 2142143280, 2140943052, 2139931208, 2139039753, 2138233813, 2137492672, 2136802831, 2136154917, 2135542102, 2134959233, 2134402306, 2133868139, 2133354148, 2132858208, diff --git a/src/tables.h b/src/tables.h index 219d668b9..b1de1a428 100644 --- a/src/tables.h +++ b/src/tables.h @@ -97,7 +97,7 @@ FUNCMATH angle_t FixedAngle(fixed_t fa); FUNCMATH angle_t FixedAngleC(fixed_t fa, fixed_t factor); -#ifdef NEED_FIXED_VECTOR +#if 1 //#ifdef NEED_FIXED_VECTOR /// The FixedAcos function FUNCMATH angle_t FixedAcos(fixed_t x); From 3629a2141b47e53fefd3803188f6d6d36c3d831d Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Sat, 23 May 2015 01:19:38 -0500 Subject: [PATCH 67/91] Slope planes work again. I hacked an alignment fix in too. --- src/r_draw.c | 2 +- src/r_draw.h | 7 +++--- src/r_plane.c | 59 ++++++++++++++++++++++++++++++++++----------------- 3 files changed, 44 insertions(+), 24 deletions(-) diff --git a/src/r_draw.c b/src/r_draw.c index f25ecfa04..766e0428e 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -105,7 +105,7 @@ UINT8 *ds_transmap; // one of the translucency tables #ifdef ESLOPE pslope_t *ds_slope; // Current slope being used -FVector ds_su, ds_sv, ds_sz; // Vectors for... stuff? +floatv3_t ds_su, ds_sv, ds_sz; // Vectors for... stuff? float focallengthf, zeroheight; #endif diff --git a/src/r_draw.h b/src/r_draw.h index b29791cc4..e1818545b 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -61,11 +61,12 @@ extern UINT8 *ds_source; // start of a 64*64 tile image extern UINT8 *ds_transmap; #ifdef ESLOPE -///TODO: either convert ds_su, etc to FPU or declare a floating-point vector type somewhere -#include "hardware/hw_defs.h" +typedef struct { + float x, y, z; +} floatv3_t; pslope_t *ds_slope; // Current slope being used -FVector ds_su, ds_sv, ds_sz; // Vectors for... stuff? +floatv3_t ds_su, ds_sv, ds_sz; // Vectors for... stuff? float focallengthf, zeroheight; #endif diff --git a/src/r_plane.c b/src/r_plane.c index 839f2fa38..1c4abc8c5 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -941,41 +941,60 @@ void R_DrawSinglePlane(visplane_t *pl) if (pl->slope) { // Potentially override other stuff for now cus we're mean. :< But draw a slope plane! // I copied ZDoom's code and adapted it to SRB2... -Red - FVector p, m, n; - angle_t ang; + floatv3_t p, m, n; + float ang; //double zeroheight; + float fudge; - double vx = FIXED_TO_FLOAT(viewx); - double vy = FIXED_TO_FLOAT(viewy); - double vz = FIXED_TO_FLOAT(viewz); + float vx = FIXED_TO_FLOAT(viewx); + float vy = FIXED_TO_FLOAT(viewy); + float vz = FIXED_TO_FLOAT(viewz); zeroheight = FIXED_TO_FLOAT(P_GetZAt(pl->slope, viewx, viewy)); +#define ANG2RAD(angle) ((float)((angle)*M_PI)/ANGLE_180) + // p is the texture origin in view space // Don't add in the offsets at this stage, because doing so can result in // errors if the flat is rotated. - ang = (ANGLE_270 - viewangle)>>ANGLETOFINESHIFT; - p.x = vx * FIXED_TO_FLOAT(FINECOSINE(ang)) - vy * FIXED_TO_FLOAT(FINESINE(ang)); - p.z = vx * FIXED_TO_FLOAT(FINESINE(ang)) + vy * FIXED_TO_FLOAT(FINECOSINE(ang)); + ang = ANG2RAD(ANGLE_270 - viewangle); + p.x = vx * cos(ang) - vy * sin(ang); + p.z = vx * sin(ang) + vy * cos(ang); p.y = FIXED_TO_FLOAT(P_GetZAt(pl->slope, 0, 0)) - vz; // m is the v direction vector in view space - ang = (ANGLE_180 - viewangle - pl->plangle) >> ANGLETOFINESHIFT; - m.x = FIXED_TO_FLOAT(FINECOSINE(ang)); - m.z = FIXED_TO_FLOAT(FINESINE(ang)); + ang = ANG2RAD(ANGLE_180 - viewangle - pl->plangle); + m.x = cos(ang); + m.z = sin(ang); // n is the u direction vector in view space - n.x = FIXED_TO_FLOAT(FINESINE(ang)); - n.z = -FIXED_TO_FLOAT(FINECOSINE(ang)); + n.x = sin(ang); + n.z = -cos(ang); - ang = pl->plangle>>ANGLETOFINESHIFT; - m.y = FIXED_TO_FLOAT(P_GetZAt(pl->slope, viewx + FINESINE(ang), viewy + FINECOSINE(ang))) - zeroheight; - n.y = FIXED_TO_FLOAT(P_GetZAt(pl->slope, viewx + FINECOSINE(ang), viewy - FINESINE(ang))) - zeroheight; + ang = ANG2RAD(pl->plangle); + m.y = FIXED_TO_FLOAT(P_GetZAt(pl->slope, viewx + FLOAT_TO_FIXED(sin(ang)), viewy + FLOAT_TO_FIXED(cos(ang)))) - zeroheight; + n.y = FIXED_TO_FLOAT(P_GetZAt(pl->slope, viewx + FLOAT_TO_FIXED(cos(ang)), viewy - FLOAT_TO_FIXED(sin(ang)))) - zeroheight; - ///TODO: slope FPU conversion stuff - //M_CrossProduct3f(&ds_su, &p, &m); - //M_CrossProduct3f(&ds_sv, &p, &n); - //M_CrossProduct3f(&ds_sz, &m, &n); + // Okay, look, don't ask me why this works, but without this setup there's a disgusting-looking misalignment with the textures. -Red + fudge = ((1< Date: Sat, 23 May 2015 01:32:28 -0500 Subject: [PATCH 68/91] Sayonara, m_vector.c --- src/CMakeLists.txt | 2 - src/Makefile | 1 - src/m_vector.c | 1159 -------------------------------------------- src/m_vector.h | 125 ----- 4 files changed, 1287 deletions(-) delete mode 100644 src/m_vector.c delete mode 100644 src/m_vector.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f319523b9..bb4f9a4a6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -32,7 +32,6 @@ set(SRB2_CORE_SOURCES m_misc.c m_queue.c m_random.c - m_vector.c md5.c mserv.c s_sound.c @@ -96,7 +95,6 @@ set(SRB2_CORE_HEADERS m_queue.h m_random.h m_swap.h - m_vector.h md5.h mserv.h p5prof.h diff --git a/src/Makefile b/src/Makefile index 49785b9e9..bee608047 100644 --- a/src/Makefile +++ b/src/Makefile @@ -436,7 +436,6 @@ OBJS:=$(i_main_o) \ $(OBJDIR)/m_misc.o \ $(OBJDIR)/m_random.o \ $(OBJDIR)/m_queue.o \ - $(OBJDIR)/m_vector.o \ $(OBJDIR)/info.o \ $(OBJDIR)/p_ceilng.o \ $(OBJDIR)/p_enemy.o \ diff --git a/src/m_vector.c b/src/m_vector.c deleted file mode 100644 index b417fd980..000000000 --- a/src/m_vector.c +++ /dev/null @@ -1,1159 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright(C) 2004 Stephen McGranahan -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -//-------------------------------------------------------------------------- -// -// DESCRIPTION: -// Vectors -// SoM created 05/18/09 -// -//----------------------------------------------------------------------------- -#if 0 // GET THIS SHEIT OUTTA HEEEEEEEEEEEEEEEEEEEEEEERE -#include "doomdef.h" -#include "m_vector.h" -#include "r_main.h" -#include "m_fixed.h" -#include "m_misc.h" -#include "tables.h" - -#ifdef ESLOPE - -v3fixed_t *M_LoadVec(v3fixed_t *vec, fixed_t x, fixed_t y, fixed_t z) -{ - vec->x = x; - vec->y = y; - vec->z = z; - return vec; -} - -v3fixed_t *M_CopyVec(v3fixed_t *a_o, const v3fixed_t *a_i) -{ - return M_Memcpy(a_o, a_i, sizeof(v3fixed_t)); -} - -v3float_t *M_LoadVecf(v3float_t *vec, float x, float y, float z) -{ - vec->x = x; - vec->y = y; - vec->z = z; - return vec; -} - -v3float_t *M_CopyVecf(v3float_t *a_o, const v3float_t *a_i) -{ - return M_Memcpy(a_o, a_i, sizeof(v3float_t)); -} - -// -// M_MakeVec3 -// -// Given two points, create a vector between them. -// -v3fixed_t *M_MakeVec3(const v3fixed_t *point1, const v3fixed_t *point2, v3fixed_t *a_o) -{ - a_o->x = point1->x - point2->x; - a_o->y = point1->y - point2->y; - a_o->z = point1->z - point2->z; - return a_o; -} - - -// -// M_MakeVec3f -// -// Given two points, create a vector between them. -// -v3float_t *M_MakeVec3f(const v3float_t *point1, const v3float_t *point2, v3float_t *a_o) -{ - a_o->x = point1->x - point2->x; - a_o->y = point1->y - point2->y; - a_o->z = point1->z - point2->z; - return a_o; -} - -// -// M_TranslateVec3 -// -// Translates the given vector (in the game's coordinate system) to the camera -// space (in right-handed coordinate system) This function is used for slopes. -// -void M_TranslateVec3(v3fixed_t *vec) -{ - fixed_t tx, ty, tz; - - tx = vec->x - viewx; - ty = viewz - vec->y; - tz = vec->z - viewy; - - // Just like wall projection. - vec->x = (tx * viewcos) - (tz * viewsin); - vec->z = (tz * viewcos) + (tx * viewsin); - vec->y = ty; -} - -// -// M_TranslateVec3f -// -// Translates the given vector (in the game's coordinate system) to the camera -// space (in right-handed coordinate system) This function is used for slopes. -// -void M_TranslateVec3f(v3float_t *vec) -{ - float tx, ty, tz; - - tx = vec->x - viewx; // SRB2CBTODO: This may need float viewxyz - ty = viewz - vec->y; - tz = vec->z - viewy; - - // Just like wall projection. - vec->x = (tx * viewcos) - (tz * viewsin); - vec->z = (tz * viewcos) + (tx * viewsin); - vec->y = ty; -} - -#ifdef SESLOPE -// -// M_TranslateVec3d -// -// Translates the given vector (in the game's coordinate system) to the camera -// space (in right-handed coordinate system) This function is used for slopes. -// -void M_TranslateVec3d(v3double_t *vec) -{ - double tx, ty, tz; - - tx = vec->x - viewx; // SRB2CBTODO: This may need float viewxyz - ty = viewz - vec->y; - tz = vec->z - viewy; - - // Just like wall projection. - vec->x = (tx * viewcos) - (tz * viewsin); - vec->z = (tz * viewcos) + (tx * viewsin); - vec->y = ty; -} -#endif - -// -// M_AddVec3 -// -// Adds v2 to v1 stores in dest -// -void M_AddVec3(v3fixed_t *dest, const v3fixed_t *v1, const v3fixed_t *v2) -{ - dest->x = v1->x + v2->x; - dest->y = v1->y + v2->y; - dest->z = v1->z + v2->z; -} - -// -// M_AddVec3f -// -// Adds v2 to v1 stores in dest -// -void M_AddVec3f(v3float_t *dest, const v3float_t *v1, const v3float_t *v2) -{ - dest->x = v1->x + v2->x; - dest->y = v1->y + v2->y; - dest->z = v1->z + v2->z; -} - -// -// M_SubVec3 -// -// Adds v2 to v1 stores in dest -// -void M_SubVec3(v3fixed_t *dest, const v3fixed_t *v1, const v3fixed_t *v2) // SRB2CBTODO: Make a function that allows the destxyz to equal the change of 2 args -{ - dest->x = v1->x - v2->x; - dest->y = v1->y - v2->y; - dest->z = v1->z - v2->z; -} - -// -// M_SubVec3f -// -// Subtracts v2 from v1 stores in dest -// -void M_SubVec3f(v3float_t *dest, const v3float_t *v1, const v3float_t *v2) -{ - dest->x = v1->x - v2->x; - dest->y = v1->y - v2->y; - dest->z = v1->z - v2->z; -} - -// -// M_DotVec3 -// -// Returns the dot product of v1 and v2 -// -fixed_t M_DotVec3(const v3fixed_t *v1, const v3fixed_t *v2) -{ - return FixedMul(v1->x, v2->x) + FixedMul(v1->y, v2->y) + FixedMul(v1->z, v2->z); -} - -// -// M_DotVec3f -// -// Returns the dot product of v1 and v2 -// -float M_DotVec3f(const v3float_t *v1, const v3float_t *v2) -{ - if (!v1 || !v2) - I_Error("M_DotVec3f: No vertexes!"); - return (v1->x * v2->x) + (v1->y * v2->y) + (v1->z * v2->z); -} - -#ifdef SESLOPE -// -// M_DotVec3d -// -// Returns the dot product of v1 and v2 -// -double M_DotVec3d(const v3double_t *v1, const v3double_t *v2) -{ - return (v1->x * v2->x) + (v1->y * v2->y) + (v1->z * v2->z); -} -#endif - -// -// M_CrossProduct3 -// -// Gets the cross product of v1 and v2 and stores in dest -// -void M_CrossProduct3(v3fixed_t *dest, const v3fixed_t *v1, const v3fixed_t *v2) -{ - v3fixed_t tmp; - tmp.x = (v1->y * v2->z) - (v1->z * v2->y); - tmp.y = (v1->z * v2->x) - (v1->x * v2->z); - tmp.z = (v1->x * v2->y) - (v1->y * v2->x); - memcpy(dest, &tmp, sizeof(v3fixed_t)); -} - -// -// M_CrossProduct3f -// -// Gets the cross product of v1 and v2 and stores in dest -// -void M_CrossProduct3f(v3float_t *dest, const v3float_t *v1, const v3float_t *v2) -{ - v3float_t tmp; - tmp.x = (v1->y * v2->z) - (v1->z * v2->y); - tmp.y = (v1->z * v2->x) - (v1->x * v2->z); - tmp.z = (v1->x * v2->y) - (v1->y * v2->x); - memcpy(dest, &tmp, sizeof(v3float_t)); -} - -fixed_t FV_Magnitude(const v3fixed_t *a_normal) -{ - fixed_t xs = FixedMul(a_normal->x,a_normal->x); - fixed_t ys = FixedMul(a_normal->y,a_normal->y); - fixed_t zs = FixedMul(a_normal->z,a_normal->z); - return FixedSqrt(xs+ys+zs); -} - -float FV_Magnitudef(const v3float_t *a_normal) -{ - float xs = (a_normal->x * a_normal->x); - float ys = (a_normal->y * a_normal->y); - float zs = (a_normal->z * a_normal->z); - return (float)sqrt(xs+ys+zs); -} - -// Vector Complex Math -v3fixed_t *FV_Midpoint(const v3fixed_t *a_1, const v3fixed_t *a_2, v3fixed_t *a_o) -{ - a_o->x = FixedDiv(a_2->x - a_1->x, 2*FRACUNIT); - a_o->y = FixedDiv(a_2->y - a_1->y, 2*FRACUNIT); - a_o->z = FixedDiv(a_2->z - a_1->z, 2*FRACUNIT); - a_o->x = a_1->x + a_o->x; - a_o->y = a_1->y + a_o->y; - a_o->z = a_1->z + a_o->z; - return a_o; -} - -fixed_t FV_Distance(const v3fixed_t *p1, const v3fixed_t *p2) -{ - fixed_t xs = FixedMul(p2->x-p1->x,p2->x-p1->x); - fixed_t ys = FixedMul(p2->y-p1->y,p2->y-p1->y); - fixed_t zs = FixedMul(p2->z-p1->z,p2->z-p1->z); - return FixedSqrt(xs+ys+zs); -} - -v3float_t *FV_Midpointf(const v3float_t *a_1, const v3float_t *a_2, v3float_t *a_o) -{ - a_o->x = (a_2->x - a_1->x / 2.0f); - a_o->y = (a_2->y - a_1->y / 2.0f); - a_o->z = (a_2->z - a_1->z / 2.0f); - a_o->x = a_1->x + a_o->x; - a_o->y = a_1->y + a_o->y; - a_o->z = a_1->z + a_o->z; - return a_o; -} - - - -// -// AngleBetweenVectors -// -// This checks to see if a point is inside the ranges of a polygon -// -angle_t FV_AngleBetweenVectors(const v3fixed_t *Vector1, const v3fixed_t *Vector2) -{ - // Remember, above we said that the Dot Product of returns the cosine of the angle - // between 2 vectors? Well, that is assuming they are unit vectors (normalize vectors). - // So, if we don't have a unit vector, then instead of just saying arcCos(DotProduct(A, B)) - // We need to divide the dot product by the magnitude of the 2 vectors multiplied by each other. - // Here is the equation: arc cosine of (V . W / || V || * || W || ) - // the || V || means the magnitude of V. This then cancels out the magnitudes dot product magnitudes. - // But basically, if you have normalize vectors already, you can forget about the magnitude part. - - // Get the dot product of the vectors - fixed_t dotProduct = M_DotVec3(Vector1, Vector2); - - // Get the product of both of the vectors magnitudes - fixed_t vectorsMagnitude = FixedMul(FV_Magnitude(Vector1), FV_Magnitude(Vector2)); - - // Return the arc cosine of the (dotProduct / vectorsMagnitude) which is the angle in RADIANS. - return 0;//ALFALFA FixedAcos(FixedDiv(dotProduct, vectorsMagnitude)); -} - -float FV_AngleBetweenVectorsf(const v3float_t *Vector1, const v3float_t *Vector2) -{ - // Remember, above we said that the Dot Product of returns the cosine of the angle - // between 2 vectors? Well, that is assuming they are unit vectors (normalize vectors). - // So, if we don't have a unit vector, then instead of just saying arcCos(DotProduct(A, B)) - // We need to divide the dot product by the magnitude of the 2 vectors multiplied by each other. - // Here is the equation: arc cosine of (V . W / || V || * || W || ) - // the || V || means the magnitude of V. This then cancels out the magnitudes dot product magnitudes. - // But basically, if you have normalize vectors already, you can forget about the magnitude part. - - // Get the dot product of the vectors - float dotProduct = M_DotVec3f(Vector1, Vector2); - - // Get the product of both of the vectors magnitudes - float vectorsMagnitude = FV_Magnitudef(Vector1)*FV_Magnitudef(Vector2); - - // Return the arc cosine of the (dotProduct / vectorsMagnitude) which is the angle in RADIANS. - return acos(dotProduct/vectorsMagnitude); -} - - - -// Crazy physics code - -float M_VectorYaw(v3float_t v) -{ - return atan2(v.x, v.z); -} -float M_VectorPitch(v3float_t v) -{ - return -atan2(v.y, sqrt(v.x*v.x+v.z*v.z)); -} - -#include "z_zone.h" - -// Returns pitch roll and yaw values, allows objects to align to a slope -angles3d_t *M_VectorAlignTo(float Pitch, float Yaw, float Roll, v3float_t v, byte AngleAxis, float Rate) -{ - CONS_Printf("P %f\n", Pitch); - CONS_Printf("R %f\n", Roll); - CONS_Printf("Y %f\n", Yaw); - if (AngleAxis == 1) - { - float DestYaw = (atan2(v.z,v.x)* 180 / M_PI); - float DestRoll = (atan2(v.y,v.x)* 180 / M_PI); - - Yaw = Yaw+(DestYaw-Yaw)*Rate; - Roll = Roll+(DestRoll-Roll)*Rate; - } - else if (AngleAxis == 2) - { - float DestPitch = (atan2(v.z,v.y)* 180 / M_PI); - float DestRoll = (-atan2(v.x,v.y)* 180 / M_PI); - - Pitch = Pitch+(DestPitch-Pitch)*Rate; - Roll = Roll+(DestRoll-Roll)*Rate; - } - else if (AngleAxis == 3) - { - float DestPitch = (-atan2(v.y,v.z)* 180 / M_PI); - float DestYaw = (-atan2(v.x,v.z)* 180 / M_PI); - - Pitch = Pitch+(DestPitch-Pitch)*Rate; - Yaw = Yaw+(DestYaw-Yaw)*Rate; - } - - angles3d_t *returnangles = Z_Malloc(sizeof(angles3d_t), PU_LEVEL, NULL); - memset(returnangles, 0, sizeof(*returnangles)); - returnangles->yaw = Yaw; - returnangles->pitch = Pitch; - returnangles->roll = Roll; - - return returnangles; - -} - -// -// RotateVector -// -// Rotates a vector around another vector -// -void M_VecRotate(v3fixed_t *rotVec, const v3fixed_t *axisVec, const angle_t angle) -{ - // Rotate the point (x,y,z) around the vector (u,v,w) - fixed_t ux = FixedMul(axisVec->x, rotVec->x); - fixed_t uy = FixedMul(axisVec->x, rotVec->y); - fixed_t uz = FixedMul(axisVec->x, rotVec->z); - fixed_t vx = FixedMul(axisVec->y, rotVec->x); - fixed_t vy = FixedMul(axisVec->y, rotVec->y); - fixed_t vz = FixedMul(axisVec->y, rotVec->z); - fixed_t wx = FixedMul(axisVec->z, rotVec->x); - fixed_t wy = FixedMul(axisVec->z, rotVec->y); - fixed_t wz = FixedMul(axisVec->z, rotVec->z); - fixed_t sa = FINESINE(angle>>ANGLETOFINESHIFT); - fixed_t ca = FINECOSINE(angle>>ANGLETOFINESHIFT); - fixed_t ua = ux+vy+wz; - fixed_t ax = FixedMul(axisVec->x,ua); - fixed_t ay = FixedMul(axisVec->y,ua); - fixed_t az = FixedMul(axisVec->z,ua); - fixed_t xs = FixedMul(axisVec->x,axisVec->x); - fixed_t ys = FixedMul(axisVec->y,axisVec->y); - fixed_t zs = FixedMul(axisVec->z,axisVec->z); - fixed_t bx = FixedMul(rotVec->x,ys+zs); - fixed_t by = FixedMul(rotVec->y,xs+zs); - fixed_t bz = FixedMul(rotVec->z,xs+ys); - fixed_t cx = FixedMul(axisVec->x,vy+wz); - fixed_t cy = FixedMul(axisVec->y,ux+wz); - fixed_t cz = FixedMul(axisVec->z,ux+vy); - fixed_t dx = FixedMul(bx-cx, ca); - fixed_t dy = FixedMul(by-cy, ca); - fixed_t dz = FixedMul(bz-cz, ca); - fixed_t ex = FixedMul(vz-wy, sa); - fixed_t ey = FixedMul(wx-uz, sa); - fixed_t ez = FixedMul(uy-vx, sa); - - rotVec->x = ax+dx+ex; - rotVec->y = ay+dy+ey; - rotVec->z = az+dz+ez; -} - - - - - -#if 0 // Backport -v3fixed_t *FV_SubO(const v3fixed_t *a_i, const v3fixed_t *a_c, v3fixed_t *a_o) -{ - a_o->x = a_i->x - a_c->x; - a_o->y = a_i->y - a_c->y; - a_o->z = a_i->z - a_c->z; - return a_o; -} - -boolean FV_Equal(const v3fixed_t *a_1, const v3fixed_t *a_2) -{ - fixed_t Epsilon = FRACUNIT/FRACUNIT; - - if ((abs(a_2->x - a_1->x) > Epsilon) || - (abs(a_2->y - a_1->y) > Epsilon) || - (abs(a_2->z - a_1->z) > Epsilon)) - { - return true; - } - - return false; -} - -boolean FV_Equalf(const v3float_t *a_1, const v3float_t *a_2) -{ - float Epsilon = 1.0f/1.0f; - - if ((abs(a_2->x - a_1->x) > Epsilon) || - (abs(a_2->y - a_1->y) > Epsilon) || - (abs(a_2->z - a_1->z) > Epsilon)) - { - return true; - } - - return false; -} - -// -// Normal -// -// Calculates the normal of a polygon. -// -void FV_Normal (const v3fixed_t *a_triangle, v3fixed_t *a_normal) -{ - v3fixed_t a_1; - v3fixed_t a_2; - - FV_Point2Vec(&a_triangle[2], &a_triangle[0], &a_1); - FV_Point2Vec(&a_triangle[1], &a_triangle[0], &a_2); - - FV_Cross(&a_1, &a_2, a_normal); - - FV_NormalizeO(a_normal, a_normal); -} - -// -// PlaneDistance -// -// Calculates distance between a plane and the origin. -// -fixed_t FV_PlaneDistance(const v3fixed_t *a_normal, const v3fixed_t *a_point) -{ - return -(FixedMul(a_normal->x, a_point->x) + FixedMul(a_normal->y, a_point->y) + FixedMul(a_normal->z, a_point->z)); -} - -boolean FV_IntersectedPlane(const v3fixed_t *a_triangle, const v3fixed_t *a_line, v3fixed_t *a_normal, fixed_t *originDistance) -{ - fixed_t distance1 = 0, distance2 = 0; - - FV_Normal(a_triangle, a_normal); - - *originDistance = FV_PlaneDistance(a_normal, &a_triangle[0]); - - distance1 = (FixedMul(a_normal->x, a_line[0].x) + FixedMul(a_normal->y, a_line[0].y) - + FixedMul(a_normal->z, a_line[0].z)) + *originDistance; - - distance2 = (FixedMul(a_normal->x, a_line[1].x) + FixedMul(a_normal->y, a_line[1].y) - + FixedMul(a_normal->z, a_line[1].z)) + *originDistance; - - // Positive or zero number means no intersection - if (FixedMul(distance1, distance2) >= 0) - return false; - - return true; -} - -// -// PlaneIntersection -// -// Returns the distance from -// rOrigin to where the ray -// intersects the plane. Assumes -// you already know it intersects -// the plane. -// -fixed_t FV_PlaneIntersection(const v3fixed_t *pOrigin, const v3fixed_t *pNormal, const v3fixed_t *rOrigin, const v3fixed_t *rVector) -{ - fixed_t d = -(FV_Dot(pNormal, pOrigin)); - fixed_t number = FV_Dot(pNormal,rOrigin) + d; - fixed_t denom = FV_Dot(pNormal,rVector); - return -FixedDiv(number, denom); -} - -// -// IntersectRaySphere -// Input : rO - origin of ray in world space -// rV - vector describing direction of ray in world space -// sO - Origin of sphere -// sR - radius of sphere -// Notes : Normalized directional vectors expected -// Return: distance to sphere in world units, -1 if no intersection. -// -fixed_t FV_IntersectRaySphere(const v3fixed_t *rO, const v3fixed_t *rV, const v3fixed_t *sO, fixed_t sR) -{ - v3fixed_t Q; - fixed_t c, v, d; - FV_SubO(sO, rO, &Q); - - c = FV_Magnitude(&Q); - v = FV_Dot(&Q, rV); - d = FixedMul(sR, sR) - (FixedMul(c,c) - FixedMul(v,v)); - - // If there was no intersection, return -1 - if (d < 0*FRACUNIT) - return (-1*FRACUNIT); - - // Return the distance to the [first] intersecting point - return (v - FixedSqrt(d)); -} - -// -// IntersectionPoint -// -// This returns the intersection point of the line that intersects the plane -// -v3fixed_t *FV_IntersectionPoint(const v3fixed_t *vNormal, const v3fixed_t *vLine, fixed_t distance, v3fixed_t *ReturnVec) -{ - v3fixed_t vLineDir; // Variables to hold the point and the line's direction - fixed_t Numerator = 0, Denominator = 0, dist = 0; - - // Here comes the confusing part. We need to find the 3D point that is actually - // on the plane. Here are some steps to do that: - - // 1) First we need to get the vector of our line, Then normalize it so it's a length of 1 - FV_Point2Vec(&vLine[1], &vLine[0], &vLineDir); // Get the Vector of the line - FV_NormalizeO(&vLineDir, &vLineDir); // Normalize the lines vector - - - // 2) Use the plane equation (distance = Ax + By + Cz + D) to find the distance from one of our points to the plane. - // Here I just chose a arbitrary point as the point to find that distance. You notice we negate that - // distance. We negate the distance because we want to eventually go BACKWARDS from our point to the plane. - // By doing this is will basically bring us back to the plane to find our intersection point. - Numerator = - (FixedMul(vNormal->x, vLine[0].x) + // Use the plane equation with the normal and the line - FixedMul(vNormal->y, vLine[0].y) + - FixedMul(vNormal->z, vLine[0].z) + distance); - - // 3) If we take the dot product between our line vector and the normal of the polygon, - // this will give us the cosine of the angle between the 2 (since they are both normalized - length 1). - // We will then divide our Numerator by this value to find the offset towards the plane from our arbitrary point. - Denominator = FV_Dot(vNormal, &vLineDir); // Get the dot product of the line's vector and the normal of the plane - - // Since we are using division, we need to make sure we don't get a divide by zero error - // If we do get a 0, that means that there are INFINITE points because the the line is - // on the plane (the normal is perpendicular to the line - (Normal.Vector = 0)). - // In this case, we should just return any point on the line. - - if( Denominator == 0*FRACUNIT) // Check so we don't divide by zero - { - ReturnVec->x = vLine[0].x; - ReturnVec->y = vLine[0].y; - ReturnVec->z = vLine[0].z; - return ReturnVec; // Return an arbitrary point on the line - } - - // We divide the (distance from the point to the plane) by (the dot product) - // to get the distance (dist) that we need to move from our arbitrary point. We need - // to then times this distance (dist) by our line's vector (direction). When you times - // a scalar (single number) by a vector you move along that vector. That is what we are - // doing. We are moving from our arbitrary point we chose from the line BACK to the plane - // along the lines vector. It seems logical to just get the numerator, which is the distance - // from the point to the line, and then just move back that much along the line's vector. - // Well, the distance from the plane means the SHORTEST distance. What about in the case that - // the line is almost parallel with the polygon, but doesn't actually intersect it until half - // way down the line's length. The distance from the plane is short, but the distance from - // the actual intersection point is pretty long. If we divide the distance by the dot product - // of our line vector and the normal of the plane, we get the correct length. Cool huh? - - dist = FixedDiv(Numerator, Denominator); // Divide to get the multiplying (percentage) factor - - // Now, like we said above, we times the dist by the vector, then add our arbitrary point. - // This essentially moves the point along the vector to a certain distance. This now gives - // us the intersection point. Yay! - - // Return the intersection point - ReturnVec->x = vLine[0].x + FixedMul(vLineDir.x, dist); - ReturnVec->y = vLine[0].y + FixedMul(vLineDir.y, dist); - ReturnVec->z = vLine[0].z + FixedMul(vLineDir.z, dist); - return ReturnVec; -} - -// -// PointOnLineSide -// -// If on the front side of the line, returns 1. -// If on the back side of the line, returns 0. -// 2D only. -// -unsigned int FV_PointOnLineSide(const v3fixed_t *point, const v3fixed_t *line) -{ - fixed_t s1 = FixedMul((point->y - line[0].y),(line[1].x - line[0].x)); - fixed_t s2 = FixedMul((point->x - line[0].x),(line[1].y - line[0].y)); - return s1 - s2 < 0; -} - -// -// PointInsideBox -// -// Given four points of a box, -// determines if the supplied point is -// inside the box or not. -// -boolean FV_PointInsideBox(const v3fixed_t *point, const v3fixed_t *box) -{ - v3fixed_t lastLine[2]; - - FV_Load(&lastLine[0], box[3].x, box[3].y, box[3].z); - FV_Load(&lastLine[1], box[0].x, box[0].y, box[0].z); - - if (FV_PointOnLineSide(point, &box[0]) - || FV_PointOnLineSide(point, &box[1]) - || FV_PointOnLineSide(point, &box[2]) - || FV_PointOnLineSide(point, lastLine)) - return false; - - return true; -} -// -// LoadIdentity -// -// Loads the identity matrix into a matrix -// -void FM_LoadIdentity(fmatrix_t* matrix) -{ -#define M(row,col) matrix->m[col * 4 + row] - memset(matrix, 0x00, sizeof(fmatrix_t)); - - M(0, 0) = FRACUNIT; - M(1, 1) = FRACUNIT; - M(2, 2) = FRACUNIT; - M(3, 3) = FRACUNIT; -#undef M -} - -// -// CreateObjectMatrix -// -// Creates a matrix that can be used for -// adjusting the position of an object -// -void FM_CreateObjectMatrix(fmatrix_t *matrix, fixed_t x, fixed_t y, fixed_t z, fixed_t anglex, fixed_t angley, fixed_t anglez, fixed_t upx, fixed_t upy, fixed_t upz, fixed_t radius) -{ - v3fixed_t upcross; - v3fixed_t upvec; - v3fixed_t basevec; - - FV_Load(&upvec, upx, upy, upz); - FV_Load(&basevec, anglex, angley, anglez); - FV_Cross(&upvec, &basevec, &upcross); - FV_Normalize(&upcross); - - FM_LoadIdentity(matrix); - - matrix->m[0] = upcross.x; - matrix->m[1] = upcross.y; - matrix->m[2] = upcross.z; - matrix->m[3] = 0*FRACUNIT; - - matrix->m[4] = upx; - matrix->m[5] = upy; - matrix->m[6] = upz; - matrix->m[7] = 0; - - matrix->m[8] = anglex; - matrix->m[9] = angley; - matrix->m[10] = anglez; - matrix->m[11] = 0; - - matrix->m[12] = x - FixedMul(upx,radius); - matrix->m[13] = y - FixedMul(upy,radius); - matrix->m[14] = z - FixedMul(upz,radius); - matrix->m[15] = FRACUNIT; -} - -// -// MultMatrixVec -// -// Multiplies a vector by the specified matrix -// -void FM_MultMatrixVec(const fmatrix_t *matrix, const v3fixed_t *vec, v3fixed_t *out) -{ -#define M(row,col) matrix->m[col * 4 + row] - out->x = FixedMul(vec->x,M(0, 0)) - + FixedMul(vec->y,M(0, 1)) - + FixedMul(vec->z,M(0, 2)) - + M(0, 3); - - out->y = FixedMul(vec->x,M(1, 0)) - + FixedMul(vec->y,M(1, 1)) - + FixedMul(vec->z,M(1, 2)) - + M(1, 3); - - out->z = FixedMul(vec->x,M(2, 0)) - + FixedMul(vec->y,M(2, 1)) - + FixedMul(vec->z,M(2, 2)) - + M(2, 3); -#undef M -} - -// -// MultMatrix -// -// Multiples one matrix into another -// -void FM_MultMatrix(fmatrix_t *dest, const fmatrix_t *multme) -{ - fmatrix_t result; - unsigned int i, j; -#define M(row,col) multme->m[col * 4 + row] -#define D(row,col) dest->m[col * 4 + row] -#define R(row,col) result.m[col * 4 + row] - - for (i = 0; i < 4; i++) - { - for (j = 0; j < 4; j++) - R(i, j) = FixedMul(D(i, 0),M(0, j)) + FixedMul(D(i, 1),M(1, j)) + FixedMul(D(i, 2),M(2, j)) + FixedMul(D(i, 3),M(3, j)); - } - - M_Memcpy(dest, &result, sizeof(fmatrix_t)); - -#undef R -#undef D -#undef M -} - -// -// Translate -// -// Translates a matrix -// -void FM_Translate(fmatrix_t *dest, fixed_t x, fixed_t y, fixed_t z) -{ - fmatrix_t trans; -#define M(row,col) trans.m[col * 4 + row] - - memset(&trans, 0x00, sizeof(fmatrix_t)); - - M(0, 0) = M(1, 1) = M(2, 2) = M(3, 3) = FRACUNIT; - M(0, 3) = x; - M(1, 3) = y; - M(2, 3) = z; - - FM_MultMatrix(dest, &trans); -#undef M -} - -// -// Scale -// -// Scales a matrix -// -void FM_Scale(fmatrix_t *dest, fixed_t x, fixed_t y, fixed_t z) -{ - fmatrix_t scale; -#define M(row,col) scale.m[col * 4 + row] - - memset(&scale, 0x00, sizeof(fmatrix_t)); - - M(3, 3) = FRACUNIT; - M(0, 0) = x; - M(1, 1) = y; - M(2, 2) = z; - - FM_MultMatrix(dest, &scale); -#undef M -} - - -v3fixed_t *FV_Cross(const v3fixed_t *a_1, const v3fixed_t *a_2, v3fixed_t *a_o) -{ - a_o->x = FixedMul(a_1->y, a_2->z) - FixedMul(a_1->z, a_2->y); - a_o->y = FixedMul(a_1->z, a_2->x) - FixedMul(a_1->x, a_2->z); - a_o->z = FixedMul(a_1->x, a_2->y) - FixedMul(a_1->y, a_2->x); - return a_o; -} - -// -// ClosestPointOnLine -// -// Finds the point on a line closest -// to the specified point. -// -v3fixed_t *FV_ClosestPointOnLine(const v3fixed_t *Line, const v3fixed_t *p, v3fixed_t *out) -{ - // Determine t (the length of the vector from √´Line[0]√≠ to √´p√≠) - v3fixed_t c, V; - fixed_t t, d = 0; - FV_SubO(p, &Line[0], &c); - FV_SubO(&Line[1], &Line[0], &V); - FV_NormalizeO(&V, &V); - - d = FV_Distance(&Line[0], &Line[1]); - t = FV_Dot(&V, &c); - - // Check to see if √´t√≠ is beyond the extents of the line segment - if (t < 0) - { - return FV_Copy(out, &Line[0]); - } - if (t > d) - { - return FV_Copy(out, &Line[1]); - } - - // Return the point between √´Line[0]√≠ and √´Line[1]√≠ - FV_Mul(&V, t); - - return FV_AddO(&Line[0], &V, out); -} - -// -// ClosestPointOnTriangle -// -// Given a triangle and a point, -// the closest point on the edge of -// the triangle is returned. -// -void FV_ClosestPointOnTriangle (const v3fixed_t *tri, const v3fixed_t *point, v3fixed_t *result) -{ - unsigned int i; - fixed_t dist, closestdist; - v3fixed_t EdgePoints[3]; - v3fixed_t Line[2]; - - FV_Copy(&Line[0], (v3fixed_t*)&tri[0]); - FV_Copy(&Line[1], (v3fixed_t*)&tri[1]); - FV_ClosestPointOnLine(Line, point, &EdgePoints[0]); - - FV_Copy(&Line[0], (v3fixed_t*)&tri[1]); - FV_Copy(&Line[1], (v3fixed_t*)&tri[2]); - FV_ClosestPointOnLine(Line, point, &EdgePoints[1]); - - FV_Copy(&Line[0], (v3fixed_t*)&tri[2]); - FV_Copy(&Line[1], (v3fixed_t*)&tri[0]); - FV_ClosestPointOnLine(Line, point, &EdgePoints[2]); - - // Find the closest one of the three - FV_Copy(result, &EdgePoints[0]); - closestdist = FV_Distance(point, &EdgePoints[0]); - for (i = 1; i < 3; i++) - { - dist = FV_Distance(point, &EdgePoints[i]); - - if (dist < closestdist) - { - closestdist = dist; - FV_Copy(result, &EdgePoints[i]); - } - } - - // We now have the closest point! Whee! -} - -// -// InsidePolygon -// -// This checks to see if a point is inside the ranges of a polygon -// -boolean FV_InsidePolygon(const fvector_t *vIntersection, const fvector_t *Poly, const int vertexCount) -{ - int i; - UINT64 Angle = 0; // Initialize the angle - fvector_t vA, vB; // Create temp vectors - - // Just because we intersected the plane, doesn't mean we were anywhere near the polygon. - // This functions checks our intersection point to make sure it is inside of the polygon. - // This is another tough function to grasp at first, but let me try and explain. - // It's a brilliant method really, what it does is create triangles within the polygon - // from the intersection point. It then adds up the inner angle of each of those triangles. - // If the angles together add up to 360 degrees (or 2 * PI in radians) then we are inside! - // If the angle is under that value, we must be outside of polygon. To further - // understand why this works, take a pencil and draw a perfect triangle. Draw a dot in - // the middle of the triangle. Now, from that dot, draw a line to each of the vertices. - // Now, we have 3 triangles within that triangle right? Now, we know that if we add up - // all of the angles in a triangle we get 360 right? Well, that is kinda what we are doing, - // but the inverse of that. Say your triangle is an isosceles triangle, so add up the angles - // and you will get 360 degree angles. 90 + 90 + 90 is 360. - - for (i = 0; i < vertexCount; i++) // Go in a circle to each vertex and get the angle between - { - FV_Point2Vec(&Poly[i], vIntersection, &vA); // Subtract the intersection point from the current vertex - // Subtract the point from the next vertex - FV_Point2Vec(&Poly[(i + 1) % vertexCount], vIntersection, &vB); - - Angle += FV_AngleBetweenVectors(&vA, &vB); // Find the angle between the 2 vectors and add them all up as we go along - } - - // Now that we have the total angles added up, we need to check if they add up to 360 degrees. - // Since we are using the dot product, we are working in radians, so we check if the angles - // equals 2*PI. We defined PI in 3DMath.h. You will notice that we use a MATCH_FACTOR - // in conjunction with our desired degree. This is because of the inaccuracy when working - // with floating point numbers. It usually won't always be perfectly 2 * PI, so we need - // to use a little twiddling. I use .9999, but you can change this to fit your own desired accuracy. - - if(Angle >= ANGLE_MAX) // If the angle is greater than 2 PI, (360 degrees) - return 1; // The point is inside of the polygon - - return 0; // If you get here, it obviously wasn't inside the polygon. -} - -// -// IntersectedPolygon -// -// This checks if a line is intersecting a polygon -// -boolean FV_IntersectedPolygon(const fvector_t *vPoly, const fvector_t *vLine, const int vertexCount, fvector_t *collisionPoint) -{ - fvector_t vNormal, vIntersection; - fixed_t originDistance = 0*FRACUNIT; - - - // First we check to see if our line intersected the plane. If this isn't true - // there is no need to go on, so return false immediately. - // We pass in address of vNormal and originDistance so we only calculate it once - - if(!FV_IntersectedPlane(vPoly, vLine, &vNormal, &originDistance)) - return false; - - // Now that we have our normal and distance passed back from IntersectedPlane(), - // we can use it to calculate the intersection point. The intersection point - // is the point that actually is ON the plane. It is between the line. We need - // this point test next, if we are inside the polygon. To get the I-Point, we - // give our function the normal of the plane, the points of the line, and the originDistance. - - FV_IntersectionPoint(&vNormal, vLine, originDistance, &vIntersection); - - // Now that we have the intersection point, we need to test if it's inside the polygon. - // To do this, we pass in : - // (our intersection point, the polygon, and the number of vertices our polygon has) - - if(FV_InsidePolygon(&vIntersection, vPoly, vertexCount)) - { - if (collisionPoint != NULL) // Optional - load the collision point. - { - collisionPoint->x = vIntersection.x; - collisionPoint->y = vIntersection.y; - collisionPoint->z = vIntersection.z; - } - return true; // We collided! - } - - // If we get here, we must have NOT collided - return false; -} - -void FM_Rotate(fmatrix_t *dest, angle_t angle, fixed_t x, fixed_t y, fixed_t z) -{ -#define M(row,col) dest->m[row * 4 + col] - const fixed_t sinA = FINESINE(angle>>ANGLETOFINESHIFT); - const fixed_t cosA = FINECOSINE(angle>>ANGLETOFINESHIFT); - const fixed_t invCosA = FRACUNIT - cosA; - fvector_t nrm = {x, y, z}; - fixed_t xSq, ySq, zSq; - fixed_t sx, sy, sz; - fixed_t sxy, sxz, syz; - - FV_Normalize(&nrm); - - x = nrm.x; - y = nrm.y; - z = nrm.z; - - xSq = FixedMul(x, FixedMul(invCosA,x)); - ySq = FixedMul(y, FixedMul(invCosA,y)); - zSq = FixedMul(z, FixedMul(invCosA,z)); - - sx = FixedMul(sinA, x); - sy = FixedMul(sinA, y); - sz = FixedMul(sinA, z); - - sxy = FixedMul(x, FixedMul(invCosA,y)); - sxz = FixedMul(x, FixedMul(invCosA,z)); - syz = FixedMul(y, FixedMul(invCosA,z)); - - - M(0, 0) = xSq + cosA; - M(1, 0) = sxy - sz; - M(2, 0) = sxz + sy; - M(3, 0) = 0; - - M(0, 1) = sxy + sz; - M(1, 1) = ySq + cosA; - M(2, 1) = syz - sx; - M(3, 1) = 0; - - M(0, 2) = sxz - sy; - M(1, 2) = syz + sx; - M(2, 2) = zSq + cosA; - M(3, 2) = 0; - - M(0, 3) = 0; - M(1, 3) = 0; - M(2, 3) = 0; - M(3, 3) = FRACUNIT; -#undef M -} - -#endif - - - - -float FV_Distancef(const v3float_t *p1, const v3float_t *p2) -{ - float xs = (p2->x-p1->x * p2->x-p1->x); - float ys = (p2->y-p1->y * p2->y-p1->y); - float zs = (p2->z-p1->z * p2->z-p1->z); - return sqrt(xs+ys+zs); -} - -// Also returns the magnitude -fixed_t FV_NormalizeO(const v3fixed_t *a_normal, v3fixed_t *a_o) -{ - fixed_t magnitude = FV_Magnitude(a_normal); - a_o->x = FixedDiv(a_normal->x, magnitude); - a_o->y = FixedDiv(a_normal->y, magnitude); - a_o->z = FixedDiv(a_normal->z, magnitude); - return magnitude; -} - -// Also returns the magnitude -float FV_NormalizeOf(const v3float_t *a_normal, v3float_t *a_o) -{ - float magnitude = FV_Magnitudef(a_normal); - a_o->x = (a_normal->x/magnitude); - a_o->y = (a_normal->y/magnitude); - a_o->z = (a_normal->z/magnitude); - return magnitude; -} - -fixed_t FV_Normalize(v3fixed_t *a_normal) -{ - return FV_NormalizeO(a_normal, a_normal); -} - -fixed_t FV_Normalizef(v3float_t *a_normal) -{ - return FV_NormalizeOf(a_normal, a_normal); -} - -// -// FV_Normalf -// -// Calculates the normal of a polygon. -// -void FV_Normal(const v3fixed_t *a_triangle, v3fixed_t *a_normal) -{ - v3fixed_t a_1; - v3fixed_t a_2; - - M_MakeVec3(&a_triangle[2], &a_triangle[0], &a_1); - M_MakeVec3(&a_triangle[1], &a_triangle[0], &a_2); - - M_CrossProduct3(&a_1, &a_2, a_normal); - - FV_NormalizeO(a_normal, a_normal); -} - -// -// FV_Normalf -// -// Calculates the normal of a polygon. -// -void FV_Normalf(const v3float_t *a_triangle, v3float_t *a_normal) -{ - v3float_t a_1; - v3float_t a_2; - - M_MakeVec3f(&a_triangle[2], &a_triangle[0], &a_1); - M_MakeVec3f(&a_triangle[1], &a_triangle[0], &a_2); - - M_CrossProduct3f(&a_1, &a_2, a_normal); - - FV_NormalizeOf(a_normal, a_normal); -} - - -// EOF -#endif // #ifdef ESLOPE - -#endif diff --git a/src/m_vector.h b/src/m_vector.h deleted file mode 100644 index a2be3a7de..000000000 --- a/src/m_vector.h +++ /dev/null @@ -1,125 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright(C) 2004 Stephen McGranahan -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -//-------------------------------------------------------------------------- -// -// DESCRIPTION: -// Vectors -// SoM created 05/18/09 -// -//----------------------------------------------------------------------------- - -#ifndef M_VECTOR_H__ -#define M_VECTOR_H__ - -#if 0 //#ifdef ESLOPE - -#include "m_fixed.h" -#include "tables.h" - -#define TWOPI M_PI*2.0 -#define HALFPI M_PI*0.5 -#define QUARTERPI M_PI*0.25 -#define EPSILON 0.000001f -#define OMEGA 10000000.0f - -typedef struct -{ - fixed_t x, y, z; -} v3fixed_t; - -typedef struct -{ - fixed_t x, y; -} v2fixed_t; - -typedef struct -{ - float x, y, z; -} v3float_t; - -typedef struct -{ - float yaw, pitch, roll; -} angles3d_t; - -typedef struct -{ - double x, y, z; -} v3double_t; - -typedef struct -{ - float x, y; -} v2float_t; - - -v3fixed_t *M_MakeVec3(const v3fixed_t *point1, const v3fixed_t *point2, v3fixed_t *a_o); -v3float_t *M_MakeVec3f(const v3float_t *point1, const v3float_t *point2, v3float_t *a_o); -void M_TranslateVec3(v3fixed_t *vec); -void M_TranslateVec3f(v3float_t *vec); -void M_AddVec3(v3fixed_t *dest, const v3fixed_t *v1, const v3fixed_t *v2); -void M_AddVec3f(v3float_t *dest, const v3float_t *v1, const v3float_t *v2); -void M_SubVec3(v3fixed_t *dest, const v3fixed_t *v1, const v3fixed_t *v2); -void M_SubVec3f(v3float_t *dest, const v3float_t *v1, const v3float_t *v2); -fixed_t M_DotVec3(const v3fixed_t *v1, const v3fixed_t *v2); -float M_DotVec3f(const v3float_t *v1, const v3float_t *v2); - -#ifdef SESLOPE -v3double_t *M_MakeVec3d(const v3double_t *point1, const v3double_t *point2, v3double_t *a_o); -double M_DotVec3d(const v3double_t *v1, const v3double_t *v2); -void M_TranslateVec3d(v3double_t *vec); -#endif - -void M_CrossProduct3(v3fixed_t *dest, const v3fixed_t *v1, const v3fixed_t *v2); -void M_CrossProduct3f(v3float_t *dest, const v3float_t *v1, const v3float_t *v2); -fixed_t FV_Magnitude(const v3fixed_t *a_normal); -float FV_Magnitudef(const v3float_t *a_normal); -fixed_t FV_NormalizeO(const v3fixed_t *a_normal, v3fixed_t *a_o); -float FV_NormalizeOf(const v3float_t *a_normal, v3float_t *a_o); -fixed_t FV_Normalize(v3fixed_t *a_normal); -fixed_t FV_Normalizef(v3float_t *a_normal); -void FV_Normal(const v3fixed_t *a_triangle, v3fixed_t *a_normal); -void FV_Normalf(const v3float_t *a_triangle, v3float_t *a_normal); -v3fixed_t *M_LoadVec(v3fixed_t *vec, fixed_t x, fixed_t y, fixed_t z); -v3fixed_t *M_CopyVec(v3fixed_t *a_o, const v3fixed_t *a_i); -v3float_t *M_LoadVecf(v3float_t *vec, float x, float y, float z); -v3float_t *M_CopyVecf(v3float_t *a_o, const v3float_t *a_i); -v3fixed_t *FV_Midpoint(const v3fixed_t *a_1, const v3fixed_t *a_2, v3fixed_t *a_o); -fixed_t FV_Distance(const v3fixed_t *p1, const v3fixed_t *p2); -v3float_t *FV_Midpointf(const v3float_t *a_1, const v3float_t *a_2, v3float_t *a_o); -angle_t FV_AngleBetweenVectors(const v3fixed_t *Vector1, const v3fixed_t *Vector2); -float FV_AngleBetweenVectorsf(const v3float_t *Vector1, const v3float_t *Vector2); -float FV_Distancef(const v3float_t *p1, const v3float_t *p2); - - -// Kalaron: something crazy, vector physics -float M_VectorYaw(v3float_t v); -float M_VectorPitch(v3float_t v); -angles3d_t *M_VectorAlignTo(float Pitch, float Yaw, float Roll, v3float_t v, byte AngleAxis, float Rate); - -void M_VecRotate(v3fixed_t *rotVec, const v3fixed_t *axisVec, const angle_t angle); - - - -#endif - -// EOF -#endif // #ifdef ESLOPE - From 485f671f23a27526e4ad89ff559ec1e842dcd12d Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Sat, 23 May 2015 02:18:32 -0500 Subject: [PATCH 69/91] Sloped planes now respect flat offsets --- src/r_plane.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/r_plane.c b/src/r_plane.c index 1c4abc8c5..aad98364d 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -437,6 +437,9 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, visplane_t *check; unsigned hash; +#ifdef ESLOPE + if (slope); else // Don't mess with this right now if a slope is involved +#endif if (plangle != 0) { // Add the view offset, rotated by the plane angle. @@ -946,8 +949,8 @@ void R_DrawSinglePlane(visplane_t *pl) //double zeroheight; float fudge; - float vx = FIXED_TO_FLOAT(viewx); - float vy = FIXED_TO_FLOAT(viewy); + float vx = FIXED_TO_FLOAT(viewx+xoffs); + float vy = FIXED_TO_FLOAT(viewy-yoffs); float vz = FIXED_TO_FLOAT(viewz); zeroheight = FIXED_TO_FLOAT(P_GetZAt(pl->slope, viewx, viewy)); @@ -960,7 +963,7 @@ void R_DrawSinglePlane(visplane_t *pl) ang = ANG2RAD(ANGLE_270 - viewangle); p.x = vx * cos(ang) - vy * sin(ang); p.z = vx * sin(ang) + vy * cos(ang); - p.y = FIXED_TO_FLOAT(P_GetZAt(pl->slope, 0, 0)) - vz; + p.y = FIXED_TO_FLOAT(P_GetZAt(pl->slope, -xoffs, yoffs)) - vz; // m is the v direction vector in view space ang = ANG2RAD(ANGLE_180 - viewangle - pl->plangle); From b121bcca683066bb36316b791383b446722c7832 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Sat, 23 May 2015 12:23:24 -0500 Subject: [PATCH 70/91] Remove P_GetZAtf (it didn't seem to work right anyway) --- src/p_slopes.c | 14 -------------- src/p_slopes.h | 5 ----- 2 files changed, 19 deletions(-) diff --git a/src/p_slopes.c b/src/p_slopes.c index a1bfb01c3..ed9623e08 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -772,21 +772,7 @@ fixed_t P_GetZAt(pslope_t *slope, fixed_t x, fixed_t y) return slope->o.z + FixedMul(dist, slope->zdelta); } -#ifdef SPRINGCLEAN -// -// P_GetZAtf -// -// Returns the height of the sloped plane at (x, y) as a float -// -float P_GetZAtf(pslope_t *slope, float x, float y) -{ - //if (!slope) // SRB2CBTODO: keep this when done with debugging - // I_Error("P_GetZAtf: slope parameter is NULL"); - float dist = (x - slope->of.x) * slope->df.x + (y - slope->of.y) * slope->df.y; - return slope->of.z + (dist * slope->zdeltaf); -} -#endif // // P_QuantizeMomentumToSlope diff --git a/src/p_slopes.h b/src/p_slopes.h index 916690fe7..52988c18f 100644 --- a/src/p_slopes.h +++ b/src/p_slopes.h @@ -66,11 +66,6 @@ void P_CopySectorSlope(line_t *line); // Returns the height of the sloped plane at (x, y) as a fixed_t fixed_t P_GetZAt(pslope_t *slope, fixed_t x, fixed_t y); - -// Returns the height of the sloped plane at (x, y) as a float -float P_GetZAtf(pslope_t *slope, float x, float y); - - // Lots of physics-based bullshit void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope); void P_SlopeLaunch(mobj_t *mo); From 109d37998082fce34b58eff06c967a46e406ff0c Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Sat, 23 May 2015 15:44:53 -0500 Subject: [PATCH 71/91] Fix conveyor slopes eventually turning to static --- src/r_plane.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/r_plane.c b/src/r_plane.c index aad98364d..0cd158355 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -946,12 +946,15 @@ void R_DrawSinglePlane(visplane_t *pl) // I copied ZDoom's code and adapted it to SRB2... -Red floatv3_t p, m, n; float ang; - //double zeroheight; + float vx, vy, vz; float fudge; - float vx = FIXED_TO_FLOAT(viewx+xoffs); - float vy = FIXED_TO_FLOAT(viewy-yoffs); - float vz = FIXED_TO_FLOAT(viewz); + xoffs &= ((1 << (32-nflatshiftup))-1); + yoffs &= ((1 << (32-nflatshiftup))-1); + + vx = FIXED_TO_FLOAT(viewx+xoffs); + vy = FIXED_TO_FLOAT(viewy-yoffs); + vz = FIXED_TO_FLOAT(viewz); zeroheight = FIXED_TO_FLOAT(P_GetZAt(pl->slope, viewx, viewy)); From e0d97e4b1a3bc3e5c17f4538237b47754f1c0478 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Sat, 23 May 2015 16:27:15 -0500 Subject: [PATCH 72/91] Slope planes should now not turn into static in 99% of cases --- src/r_plane.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/r_plane.c b/src/r_plane.c index 0cd158355..6aae1e250 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -952,6 +952,15 @@ void R_DrawSinglePlane(visplane_t *pl) xoffs &= ((1 << (32-nflatshiftup))-1); yoffs &= ((1 << (32-nflatshiftup))-1); + xoffs -= (pl->slope->o.x + (1 << (31-nflatshiftup))) & ~((1 << (32-nflatshiftup))-1); + yoffs += (pl->slope->o.y + (1 << (31-nflatshiftup))) & ~((1 << (32-nflatshiftup))-1); + + // Okay, look, don't ask me why this works, but without this setup there's a disgusting-looking misalignment with the textures. -Red + fudge = ((1<slope, viewx + FLOAT_TO_FIXED(sin(ang)), viewy + FLOAT_TO_FIXED(cos(ang)))) - zeroheight; n.y = FIXED_TO_FLOAT(P_GetZAt(pl->slope, viewx + FLOAT_TO_FIXED(cos(ang)), viewy - FLOAT_TO_FIXED(sin(ang)))) - zeroheight; - // Okay, look, don't ask me why this works, but without this setup there's a disgusting-looking misalignment with the textures. -Red - fudge = ((1< Date: Sun, 24 May 2015 11:27:52 -0500 Subject: [PATCH 73/91] Condense GetFloor/CeilingZ into fewer functions, and use macros for the rest --- src/p_local.h | 23 +- src/p_mobj.c | 1084 ++++++++++++------------------------------------- 2 files changed, 276 insertions(+), 831 deletions(-) diff --git a/src/p_local.h b/src/p_local.h index 1c5874b93..543d800cd 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -217,15 +217,22 @@ boolean P_RailThinker(mobj_t *mobj); void P_PushableThinker(mobj_t *mobj); void P_SceneryThinker(mobj_t *mobj); -fixed_t P_GetFloorZ(mobj_t *mobj, sector_t *sector, fixed_t x, fixed_t y, line_t *line); -fixed_t P_GetCeilingZ(mobj_t *mobj, sector_t *sector, fixed_t x, fixed_t y, line_t *line); -fixed_t P_GetFOFTopZ(mobj_t *mobj, sector_t *sector, ffloor_t *fof, fixed_t x, fixed_t y, line_t *line); -fixed_t P_GetFOFBottomZ(mobj_t *mobj, sector_t *sector, ffloor_t *fof, fixed_t x, fixed_t y, line_t *line); -fixed_t P_CameraGetFloorZ(camera_t *mobj, sector_t *sector, fixed_t x, fixed_t y, line_t *line); -fixed_t P_CameraGetCeilingZ(camera_t *mobj, sector_t *sector, fixed_t x, fixed_t y, line_t *line); -fixed_t P_CameraGetFOFTopZ(camera_t *mobj, sector_t *sector, ffloor_t *fof, fixed_t x, fixed_t y, line_t *line); -fixed_t P_CameraGetFOFBottomZ(camera_t *mobj, sector_t *sector, ffloor_t *fof, fixed_t x, fixed_t y, line_t *line); +fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect); +fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect); +#define P_GetFloorZ(mobj, sector, x, y, line) P_MobjFloorZ(mobj, sector, NULL, x, y, line, false, false) +#define P_GetCeilingZ(mobj, sector, x, y, line) P_MobjCeilingZ(mobj, sector, NULL, x, y, line, true, false) +#define P_GetFOFTopZ(mobj, sector, fof, x, y, line) P_MobjCeilingZ(mobj, sectors + fof->secnum, sector, x, y, line, false, false) +#define P_GetFOFBottomZ(mobj, sector, fof, x, y, line) P_MobjFloorZ(mobj, sectors + fof->secnum, sector, x, y, line, true, false) +#define P_GetSpecialBottomZ(mobj, src, bound) P_MobjFloorZ(mobj, src, bound, mobj->x, mobj->y, NULL, src != bound, true) +#define P_GetSpecialTopZ(mobj, src, bound) P_MobjCeilingZ(mobj, src, bound, mobj->x, mobj->y, NULL, src == bound, true) + +fixed_t P_CameraFloorZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect); +fixed_t P_CameraCeilingZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect); +#define P_CameraGetFloorZ(mobj, sector, x, y, line) P_CameraFloorZ(mobj, sector, NULL, x, y, line, false, false) +#define P_CameraGetCeilingZ(mobj, sector, x, y, line) P_CameraCeilingZ(mobj, sector, NULL, x, y, line, true, false) +#define P_CameraGetFOFTopZ(mobj, sector, fof, x, y, line) P_CameraCeilingZ(mobj, sectors + fof->secnum, sector, x, y, line, false, false) +#define P_CameraGetFOFBottomZ(mobj, sector, fof, x, y, line) P_CameraFloorZ(mobj, sectors + fof->secnum, sector, x, y, line, true, false) boolean P_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover); boolean P_CheckDeathPitCollide(mobj_t *mo); diff --git a/src/p_mobj.c b/src/p_mobj.c index 270220f82..a11aa2c0b 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -725,7 +725,108 @@ boolean P_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover) // P_GetFloorZ (and its ceiling counterpart) // Gets the floor height (or ceiling height) of the mobj's contact point in sector, assuming object's center if moved to [x, y] // If line is supplied, it's a divider line on the sector. Set it to NULL if you're not checking for collision with a line -fixed_t P_GetFloorZ(mobj_t *mobj, sector_t *sector, fixed_t x, fixed_t y, line_t *line) // SRB2CBTODO: This needs to be over all the code +// Supply boundsec ONLY when checking for specials! It should be the "in-level" sector, and sector the control sector (if separate). +// If set, then this function will iterate through boundsec's linedefs to find the highest contact point on the slope. Non-special-checking +// usage will handle that later. +static fixed_t HighestOnLine(fixed_t radius, fixed_t x, fixed_t y, line_t *line, pslope_t *slope, boolean actuallylowest) +{ + // Alright, so we're sitting on a line that contains our slope sector, and need to figure out the highest point we're touching... + // The solution is simple! Get the line's vertices, and pull each one in along its line until it touches the object's bounding box + // (assuming it isn't already inside), then test each point's slope Z and return the higher of the two. + vertex_t v1, v2; + v1.x = line->v1->x; + v1.y = line->v1->y; + v2.x = line->v2->x; + v2.y = line->v2->y; + + /*CONS_Printf("BEFORE: v1 = %f %f %f\n", + FIXED_TO_FLOAT(v1.x), + FIXED_TO_FLOAT(v1.y), + FIXED_TO_FLOAT(P_GetZAt(slope, v1.x, v1.y)) + ); + CONS_Printf(" v2 = %f %f %f\n", + FIXED_TO_FLOAT(v2.x), + FIXED_TO_FLOAT(v2.y), + FIXED_TO_FLOAT(P_GetZAt(slope, v2.x, v2.y)) + );*/ + + if (abs(v1.x-x) > radius) { + // v1's x is out of range, so rein it in + fixed_t diff = abs(v1.x-x) - radius; + + if (v1.x < x) { // Moving right + v1.x += diff; + v1.y += FixedMul(diff, FixedDiv(line->dy, line->dx)); + } else { // Moving left + v1.x -= diff; + v1.y -= FixedMul(diff, FixedDiv(line->dy, line->dx)); + } + } + + if (abs(v1.y-y) > radius) { + // v1's y is out of range, so rein it in + fixed_t diff = abs(v1.y-y) - radius; + + if (v1.y < y) { // Moving up + v1.y += diff; + v1.x += FixedMul(diff, FixedDiv(line->dx, line->dy)); + } else { // Moving down + v1.y -= diff; + v1.x -= FixedMul(diff, FixedDiv(line->dx, line->dy)); + } + } + + if (abs(v2.x-x) > radius) { + // v1's x is out of range, so rein it in + fixed_t diff = abs(v2.x-x) - radius; + + if (v2.x < x) { // Moving right + v2.x += diff; + v2.y += FixedMul(diff, FixedDiv(line->dy, line->dx)); + } else { // Moving left + v2.x -= diff; + v2.y -= FixedMul(diff, FixedDiv(line->dy, line->dx)); + } + } + + if (abs(v2.y-y) > radius) { + // v2's y is out of range, so rein it in + fixed_t diff = abs(v2.y-y) - radius; + + if (v2.y < y) { // Moving up + v2.y += diff; + v2.x += FixedMul(diff, FixedDiv(line->dx, line->dy)); + } else { // Moving down + v2.y -= diff; + v2.x -= FixedMul(diff, FixedDiv(line->dx, line->dy)); + } + } + + /*CONS_Printf("AFTER: v1 = %f %f %f\n", + FIXED_TO_FLOAT(v1.x), + FIXED_TO_FLOAT(v1.y), + FIXED_TO_FLOAT(P_GetZAt(slope, v1.x, v1.y)) + ); + CONS_Printf(" v2 = %f %f %f\n", + FIXED_TO_FLOAT(v2.x), + FIXED_TO_FLOAT(v2.y), + FIXED_TO_FLOAT(P_GetZAt(slope, v2.x, v2.y)) + );*/ + + // Return the higher of the two points + if (actuallylowest) + return min( + P_GetZAt(slope, v1.x, v1.y), + P_GetZAt(slope, v2.x, v2.y) + ); + else + return max( + P_GetZAt(slope, v1.x, v1.y), + P_GetZAt(slope, v2.x, v2.y) + ); +} + +fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect) { I_Assert(mobj != NULL); I_Assert(sector != NULL); @@ -745,7 +846,7 @@ fixed_t P_GetFloorZ(mobj_t *mobj, sector_t *sector, fixed_t x, fixed_t y, line_t else testy = -mobj->radius; - if (slope->zdelta > 0) { + if ((slope->zdelta > 0) ^ !!(lowest)) { testx = -testx; testy = -testy; } @@ -754,110 +855,56 @@ fixed_t P_GetFloorZ(mobj_t *mobj, sector_t *sector, fixed_t x, fixed_t y, line_t testy += y; // If the highest point is in the sector, then we have it easy! Just get the Z at that point - if (R_PointInSubsector(testx, testy)->sector == sector) + if (R_PointInSubsector(testx, testy)->sector == (boundsec ?: sector)) return P_GetZAt(slope, testx, testy); + // If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point + if (perfect) { + size_t i; + line_t *ld; + fixed_t bbox[4]; + fixed_t finalheight; + + if (lowest) + finalheight = INT32_MAX; + else + finalheight = INT32_MIN; + + bbox[BOXLEFT] = x-mobj->radius; + bbox[BOXRIGHT] = x+mobj->radius; + bbox[BOXTOP] = y+mobj->radius; + bbox[BOXBOTTOM] = y-mobj->radius; + for (i = 0; i < boundsec->linecount; i++) { + ld = boundsec->lines[i]; + + if (bbox[BOXRIGHT] <= ld->bbox[BOXLEFT] || bbox[BOXLEFT] >= ld->bbox[BOXRIGHT] + || bbox[BOXTOP] <= ld->bbox[BOXBOTTOM] || bbox[BOXBOTTOM] >= ld->bbox[BOXTOP]) + continue; + + if (P_BoxOnLineSide(bbox, ld) != -1) + continue; + + if (lowest) + finalheight = min(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, true)); + else + finalheight = max(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, false)); + } + + return finalheight; + } + // If we're just testing for base sector location (no collision line), just go for the center's spot... // It'll get fixed when we test for collision anyway, and the final result can't be lower than this if (line == NULL) return P_GetZAt(slope, x, y); - // Alright, so we're sitting on a line that contains our slope sector, and need to figure out the highest point we're touching... - // The solution is simple! Get the line's vertices, and pull each one in along its line until it touches the object's bounding box - // (assuming it isn't already inside), then test each point's slope Z and return the higher of the two. - { - vertex_t v1, v2; - v1.x = line->v1->x; - v1.y = line->v1->y; - v2.x = line->v2->x; - v2.y = line->v2->y; - - /*CONS_Printf("BEFORE: v1 = %f %f %f\n", - FIXED_TO_FLOAT(v1.x), - FIXED_TO_FLOAT(v1.y), - FIXED_TO_FLOAT(P_GetZAt(slope, v1.x, v1.y)) - ); - CONS_Printf(" v2 = %f %f %f\n", - FIXED_TO_FLOAT(v2.x), - FIXED_TO_FLOAT(v2.y), - FIXED_TO_FLOAT(P_GetZAt(slope, v2.x, v2.y)) - );*/ - - if (abs(v1.x-x) > mobj->radius) { - // v1's x is out of range, so rein it in - fixed_t diff = abs(v1.x-x) - mobj->radius; - - if (v1.x < x) { // Moving right - v1.x += diff; - v1.y += FixedMul(diff, FixedDiv(line->dy, line->dx)); - } else { // Moving left - v1.x -= diff; - v1.y -= FixedMul(diff, FixedDiv(line->dy, line->dx)); - } - } - - if (abs(v1.y-y) > mobj->radius) { - // v1's y is out of range, so rein it in - fixed_t diff = abs(v1.y-y) - mobj->radius; - - if (v1.y < y) { // Moving up - v1.y += diff; - v1.x += FixedMul(diff, FixedDiv(line->dx, line->dy)); - } else { // Moving down - v1.y -= diff; - v1.x -= FixedMul(diff, FixedDiv(line->dx, line->dy)); - } - } - - if (abs(v2.x-x) > mobj->radius) { - // v1's x is out of range, so rein it in - fixed_t diff = abs(v2.x-x) - mobj->radius; - - if (v2.x < x) { // Moving right - v2.x += diff; - v2.y += FixedMul(diff, FixedDiv(line->dy, line->dx)); - } else { // Moving left - v2.x -= diff; - v2.y -= FixedMul(diff, FixedDiv(line->dy, line->dx)); - } - } - - if (abs(v2.y-y) > mobj->radius) { - // v2's y is out of range, so rein it in - fixed_t diff = abs(v2.y-y) - mobj->radius; - - if (v2.y < y) { // Moving up - v2.y += diff; - v2.x += FixedMul(diff, FixedDiv(line->dx, line->dy)); - } else { // Moving down - v2.y -= diff; - v2.x -= FixedMul(diff, FixedDiv(line->dx, line->dy)); - } - } - - /*CONS_Printf("AFTER: v1 = %f %f %f\n", - FIXED_TO_FLOAT(v1.x), - FIXED_TO_FLOAT(v1.y), - FIXED_TO_FLOAT(P_GetZAt(slope, v1.x, v1.y)) - ); - CONS_Printf(" v2 = %f %f %f\n", - FIXED_TO_FLOAT(v2.x), - FIXED_TO_FLOAT(v2.y), - FIXED_TO_FLOAT(P_GetZAt(slope, v2.x, v2.y)) - );*/ - - // Return the higher of the two points - return max( - P_GetZAt(slope, v1.x, v1.y), - P_GetZAt(slope, v2.x, v2.y) - ); - } + return HighestOnLine(mobj->radius, x, y, line, slope, lowest); } else // Well, that makes it easy. Just get the floor height #endif return sector->floorheight; } -fixed_t P_GetCeilingZ(mobj_t *mobj, sector_t *sector, fixed_t x, fixed_t y, line_t *line) // SRB2CBTODO: This needs to be over all the code +fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect) { I_Assert(mobj != NULL); I_Assert(sector != NULL); @@ -866,118 +913,6 @@ fixed_t P_GetCeilingZ(mobj_t *mobj, sector_t *sector, fixed_t x, fixed_t y, line fixed_t testx, testy; pslope_t *slope = sector->c_slope; - // Get the corner of the object that should be the lowest on the slope - if (slope->d.x < 0) - testx = mobj->radius; - else - testx = -mobj->radius; - - if (slope->d.y < 0) - testy = mobj->radius; - else - testy = -mobj->radius; - - if (slope->zdelta < 0) { - testx = -testx; - testy = -testy; - } - - testx += x; - testy += y; - - // If the lowest point is in the sector, then we have it easy! Just get the Z at that point - if (R_PointInSubsector(testx, testy)->sector == sector) - return P_GetZAt(slope, testx, testy); - - // If we're just testing for base sector location (no collision line), just go for the center's spot... - // It'll get fixed when we test for collision anyway, and the final result can't be higher than this - if (line == NULL) - return P_GetZAt(slope, x, y); - - // Alright, so we're sitting on a line that contains our slope sector, and need to figure out the highest point we're touching... - // The solution is simple! Get the line's vertices, and pull each one in along its line until it touches the object's bounding box - // (assuming it isn't already inside), then test each point's slope Z and return the lower of the two. - { - vertex_t v1, v2; - v1.x = line->v1->x; - v1.y = line->v1->y; - v2.x = line->v2->x; - v2.y = line->v2->y; - - if (abs(v1.x-x) > mobj->radius) { - // v1's x is out of range, so rein it in - fixed_t diff = abs(v1.x-x) - mobj->radius; - - if (v1.x < x) { // Moving right - v1.x += diff; - v1.y += FixedMul(diff, FixedDiv(line->dy, line->dx)); - } else { // Moving left - v1.x -= diff; - v1.y -= FixedMul(diff, FixedDiv(line->dy, line->dx)); - } - } - - if (abs(v1.y-y) > mobj->radius) { - // v1's y is out of range, so rein it in - fixed_t diff = abs(v1.y-y) - mobj->radius; - - if (v1.y < y) { // Moving up - v1.y += diff; - v1.x += FixedMul(diff, FixedDiv(line->dx, line->dy)); - } else { // Moving down - v1.y -= diff; - v1.x -= FixedMul(diff, FixedDiv(line->dx, line->dy)); - } - } - - if (abs(v2.x-x) > mobj->radius) { - // v1's x is out of range, so rein it in - fixed_t diff = abs(v2.x-x) - mobj->radius; - - if (v2.x < x) { // Moving right - v2.x += diff; - v2.y += FixedMul(diff, FixedDiv(line->dy, line->dx)); - } else { // Moving left - v2.x -= diff; - v2.y -= FixedMul(diff, FixedDiv(line->dy, line->dx)); - } - } - - if (abs(v2.y-y) > mobj->radius) { - // v2's y is out of range, so rein it in - fixed_t diff = abs(v2.y-y) - mobj->radius; - - if (v2.y < y) { // Moving up - v2.y += diff; - v2.x += FixedMul(diff, FixedDiv(line->dx, line->dy)); - } else { // Moving down - v2.y -= diff; - v2.x -= FixedMul(diff, FixedDiv(line->dx, line->dy)); - } - } - - // Return the lower of the two points - return min( - P_GetZAt(slope, v1.x, v1.y), - P_GetZAt(slope, v2.x, v2.y) - ); - } - } else // Well, that makes it easy. Just get the ceiling height -#endif - return sector->ceilingheight; -} - -// Do the same as above, but for FOFs! -fixed_t P_GetFOFTopZ(mobj_t *mobj, sector_t *sector, ffloor_t *fof, fixed_t x, fixed_t y, line_t *line) // SRB2CBTODO: This needs to be over all the code -{ - I_Assert(mobj != NULL); - I_Assert(sector != NULL); - I_Assert(fof != NULL); -#ifdef ESLOPE - if (*fof->t_slope) { - fixed_t testx, testy; - pslope_t *slope = *fof->t_slope; - // Get the corner of the object that should be the highest on the slope if (slope->d.x < 0) testx = mobj->radius; @@ -989,7 +924,7 @@ fixed_t P_GetFOFTopZ(mobj_t *mobj, sector_t *sector, ffloor_t *fof, fixed_t x, f else testy = -mobj->radius; - if (slope->zdelta > 0) { + if ((slope->zdelta > 0) ^ !!(lowest)) { testx = -testx; testy = -testy; } @@ -998,222 +933,57 @@ fixed_t P_GetFOFTopZ(mobj_t *mobj, sector_t *sector, ffloor_t *fof, fixed_t x, f testy += y; // If the highest point is in the sector, then we have it easy! Just get the Z at that point - if (R_PointInSubsector(testx, testy)->sector == sector) + if (R_PointInSubsector(testx, testy)->sector == (boundsec ?: sector)) return P_GetZAt(slope, testx, testy); + // If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point + if (perfect) { + size_t i; + line_t *ld; + fixed_t bbox[4]; + fixed_t finalheight; + + if (lowest) + finalheight = INT32_MAX; + else + finalheight = INT32_MIN; + + bbox[BOXLEFT] = x-mobj->radius; + bbox[BOXRIGHT] = x+mobj->radius; + bbox[BOXTOP] = y+mobj->radius; + bbox[BOXBOTTOM] = y-mobj->radius; + for (i = 0; i < boundsec->linecount; i++) { + ld = boundsec->lines[i]; + + if (bbox[BOXRIGHT] <= ld->bbox[BOXLEFT] || bbox[BOXLEFT] >= ld->bbox[BOXRIGHT] + || bbox[BOXTOP] <= ld->bbox[BOXBOTTOM] || bbox[BOXBOTTOM] >= ld->bbox[BOXTOP]) + continue; + + if (P_BoxOnLineSide(bbox, ld) != -1) + continue; + + if (lowest) + finalheight = min(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, true)); + else + finalheight = max(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, false)); + } + + return finalheight; + } + // If we're just testing for base sector location (no collision line), just go for the center's spot... // It'll get fixed when we test for collision anyway, and the final result can't be lower than this if (line == NULL) return P_GetZAt(slope, x, y); - // Alright, so we're sitting on a line that contains our slope sector, and need to figure out the highest point we're touching... - // The solution is simple! Get the line's vertices, and pull each one in along its line until it touches the object's bounding box - // (assuming it isn't already inside), then test each point's slope Z and return the higher of the two. - { - vertex_t v1, v2; - v1.x = line->v1->x; - v1.y = line->v1->y; - v2.x = line->v2->x; - v2.y = line->v2->y; - - /*CONS_Printf("BEFORE: v1 = %f %f %f\n", - FIXED_TO_FLOAT(v1.x), - FIXED_TO_FLOAT(v1.y), - FIXED_TO_FLOAT(P_GetZAt(slope, v1.x, v1.y)) - ); - CONS_Printf(" v2 = %f %f %f\n", - FIXED_TO_FLOAT(v2.x), - FIXED_TO_FLOAT(v2.y), - FIXED_TO_FLOAT(P_GetZAt(slope, v2.x, v2.y)) - );*/ - - if (abs(v1.x-x) > mobj->radius) { - // v1's x is out of range, so rein it in - fixed_t diff = abs(v1.x-x) - mobj->radius; - - if (v1.x < x) { // Moving right - v1.x += diff; - v1.y += FixedMul(diff, FixedDiv(line->dy, line->dx)); - } else { // Moving left - v1.x -= diff; - v1.y -= FixedMul(diff, FixedDiv(line->dy, line->dx)); - } - } - - if (abs(v1.y-y) > mobj->radius) { - // v1's y is out of range, so rein it in - fixed_t diff = abs(v1.y-y) - mobj->radius; - - if (v1.y < y) { // Moving up - v1.y += diff; - v1.x += FixedMul(diff, FixedDiv(line->dx, line->dy)); - } else { // Moving down - v1.y -= diff; - v1.x -= FixedMul(diff, FixedDiv(line->dx, line->dy)); - } - } - - if (abs(v2.x-x) > mobj->radius) { - // v1's x is out of range, so rein it in - fixed_t diff = abs(v2.x-x) - mobj->radius; - - if (v2.x < x) { // Moving right - v2.x += diff; - v2.y += FixedMul(diff, FixedDiv(line->dy, line->dx)); - } else { // Moving left - v2.x -= diff; - v2.y -= FixedMul(diff, FixedDiv(line->dy, line->dx)); - } - } - - if (abs(v2.y-y) > mobj->radius) { - // v2's y is out of range, so rein it in - fixed_t diff = abs(v2.y-y) - mobj->radius; - - if (v2.y < y) { // Moving up - v2.y += diff; - v2.x += FixedMul(diff, FixedDiv(line->dx, line->dy)); - } else { // Moving down - v2.y -= diff; - v2.x -= FixedMul(diff, FixedDiv(line->dx, line->dy)); - } - } - - /*CONS_Printf("AFTER: v1 = %f %f %f\n", - FIXED_TO_FLOAT(v1.x), - FIXED_TO_FLOAT(v1.y), - FIXED_TO_FLOAT(P_GetZAt(slope, v1.x, v1.y)) - ); - CONS_Printf(" v2 = %f %f %f\n", - FIXED_TO_FLOAT(v2.x), - FIXED_TO_FLOAT(v2.y), - FIXED_TO_FLOAT(P_GetZAt(slope, v2.x, v2.y)) - );*/ - - // Return the higher of the two points - return max( - P_GetZAt(slope, v1.x, v1.y), - P_GetZAt(slope, v2.x, v2.y) - ); - } - } else // Well, that makes it easy. Just get the top height + return HighestOnLine(mobj->radius, x, y, line, slope, lowest); + } else // Well, that makes it easy. Just get the ceiling height #endif - return *fof->topheight; -} - -fixed_t P_GetFOFBottomZ(mobj_t *mobj, sector_t *sector, ffloor_t *fof, fixed_t x, fixed_t y, line_t *line) // SRB2CBTODO: This needs to be over all the code -{ - I_Assert(mobj != NULL); - I_Assert(sector != NULL); - I_Assert(fof != NULL); -#ifdef ESLOPE - if (*fof->b_slope) { - fixed_t testx, testy; - pslope_t *slope = *fof->b_slope; - - // Get the corner of the object that should be the lowest on the slope - if (slope->d.x < 0) - testx = mobj->radius; - else - testx = -mobj->radius; - - if (slope->d.y < 0) - testy = mobj->radius; - else - testy = -mobj->radius; - - if (slope->zdelta < 0) { - testx = -testx; - testy = -testy; - } - - testx += x; - testy += y; - - // If the lowest point is in the sector, then we have it easy! Just get the Z at that point - if (R_PointInSubsector(testx, testy)->sector == sector) - return P_GetZAt(slope, testx, testy); - - // If we're just testing for base sector location (no collision line), just go for the center's spot... - // It'll get fixed when we test for collision anyway, and the final result can't be higher than this - if (line == NULL) - return P_GetZAt(slope, x, y); - - // Alright, so we're sitting on a line that contains our slope sector, and need to figure out the highest point we're touching... - // The solution is simple! Get the line's vertices, and pull each one in along its line until it touches the object's bounding box - // (assuming it isn't already inside), then test each point's slope Z and return the lower of the two. - { - vertex_t v1, v2; - v1.x = line->v1->x; - v1.y = line->v1->y; - v2.x = line->v2->x; - v2.y = line->v2->y; - - if (abs(v1.x-x) > mobj->radius) { - // v1's x is out of range, so rein it in - fixed_t diff = abs(v1.x-x) - mobj->radius; - - if (v1.x < x) { // Moving right - v1.x += diff; - v1.y += FixedMul(diff, FixedDiv(line->dy, line->dx)); - } else { // Moving left - v1.x -= diff; - v1.y -= FixedMul(diff, FixedDiv(line->dy, line->dx)); - } - } - - if (abs(v1.y-y) > mobj->radius) { - // v1's y is out of range, so rein it in - fixed_t diff = abs(v1.y-y) - mobj->radius; - - if (v1.y < y) { // Moving up - v1.y += diff; - v1.x += FixedMul(diff, FixedDiv(line->dx, line->dy)); - } else { // Moving down - v1.y -= diff; - v1.x -= FixedMul(diff, FixedDiv(line->dx, line->dy)); - } - } - - if (abs(v2.x-x) > mobj->radius) { - // v1's x is out of range, so rein it in - fixed_t diff = abs(v2.x-x) - mobj->radius; - - if (v2.x < x) { // Moving right - v2.x += diff; - v2.y += FixedMul(diff, FixedDiv(line->dy, line->dx)); - } else { // Moving left - v2.x -= diff; - v2.y -= FixedMul(diff, FixedDiv(line->dy, line->dx)); - } - } - - if (abs(v2.y-y) > mobj->radius) { - // v2's y is out of range, so rein it in - fixed_t diff = abs(v2.y-y) - mobj->radius; - - if (v2.y < y) { // Moving up - v2.y += diff; - v2.x += FixedMul(diff, FixedDiv(line->dx, line->dy)); - } else { // Moving down - v2.y -= diff; - v2.x -= FixedMul(diff, FixedDiv(line->dx, line->dy)); - } - } - - // Return the lower of the two points - return min( - P_GetZAt(slope, v1.x, v1.y), - P_GetZAt(slope, v2.x, v2.y) - ); - } - } else // Well, that makes it easy. Just get the bottom height -#endif - return *fof->bottomheight; + return sector->ceilingheight; } // Now do the same as all above, but for cameras because apparently cameras are special? -fixed_t P_CameraGetFloorZ(camera_t *mobj, sector_t *sector, fixed_t x, fixed_t y, line_t *line) // SRB2CBTODO: This needs to be over all the code +fixed_t P_CameraFloorZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect) { I_Assert(mobj != NULL); I_Assert(sector != NULL); @@ -1233,7 +1003,7 @@ fixed_t P_CameraGetFloorZ(camera_t *mobj, sector_t *sector, fixed_t x, fixed_t y else testy = -mobj->radius; - if (slope->zdelta > 0) { + if ((slope->zdelta > 0) ^ !!(lowest)) { testx = -testx; testy = -testy; } @@ -1242,110 +1012,56 @@ fixed_t P_CameraGetFloorZ(camera_t *mobj, sector_t *sector, fixed_t x, fixed_t y testy += y; // If the highest point is in the sector, then we have it easy! Just get the Z at that point - if (R_PointInSubsector(testx, testy)->sector == sector) + if (R_PointInSubsector(testx, testy)->sector == (boundsec ?: sector)) return P_GetZAt(slope, testx, testy); + // If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point + if (perfect) { + size_t i; + line_t *ld; + fixed_t bbox[4]; + fixed_t finalheight; + + if (lowest) + finalheight = INT32_MAX; + else + finalheight = INT32_MIN; + + bbox[BOXLEFT] = x-mobj->radius; + bbox[BOXRIGHT] = x+mobj->radius; + bbox[BOXTOP] = y+mobj->radius; + bbox[BOXBOTTOM] = y-mobj->radius; + for (i = 0; i < boundsec->linecount; i++) { + ld = boundsec->lines[i]; + + if (bbox[BOXRIGHT] <= ld->bbox[BOXLEFT] || bbox[BOXLEFT] >= ld->bbox[BOXRIGHT] + || bbox[BOXTOP] <= ld->bbox[BOXBOTTOM] || bbox[BOXBOTTOM] >= ld->bbox[BOXTOP]) + continue; + + if (P_BoxOnLineSide(bbox, ld) != -1) + continue; + + if (lowest) + finalheight = min(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, true)); + else + finalheight = max(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, false)); + } + + return finalheight; + } + // If we're just testing for base sector location (no collision line), just go for the center's spot... // It'll get fixed when we test for collision anyway, and the final result can't be lower than this if (line == NULL) return P_GetZAt(slope, x, y); - // Alright, so we're sitting on a line that contains our slope sector, and need to figure out the highest point we're touching... - // The solution is simple! Get the line's vertices, and pull each one in along its line until it touches the object's bounding box - // (assuming it isn't already inside), then test each point's slope Z and return the higher of the two. - { - vertex_t v1, v2; - v1.x = line->v1->x; - v1.y = line->v1->y; - v2.x = line->v2->x; - v2.y = line->v2->y; - - /*CONS_Printf("BEFORE: v1 = %f %f %f\n", - FIXED_TO_FLOAT(v1.x), - FIXED_TO_FLOAT(v1.y), - FIXED_TO_FLOAT(P_GetZAt(slope, v1.x, v1.y)) - ); - CONS_Printf(" v2 = %f %f %f\n", - FIXED_TO_FLOAT(v2.x), - FIXED_TO_FLOAT(v2.y), - FIXED_TO_FLOAT(P_GetZAt(slope, v2.x, v2.y)) - );*/ - - if (abs(v1.x-x) > mobj->radius) { - // v1's x is out of range, so rein it in - fixed_t diff = abs(v1.x-x) - mobj->radius; - - if (v1.x < x) { // Moving right - v1.x += diff; - v1.y += FixedMul(diff, FixedDiv(line->dy, line->dx)); - } else { // Moving left - v1.x -= diff; - v1.y -= FixedMul(diff, FixedDiv(line->dy, line->dx)); - } - } - - if (abs(v1.y-y) > mobj->radius) { - // v1's y is out of range, so rein it in - fixed_t diff = abs(v1.y-y) - mobj->radius; - - if (v1.y < y) { // Moving up - v1.y += diff; - v1.x += FixedMul(diff, FixedDiv(line->dx, line->dy)); - } else { // Moving down - v1.y -= diff; - v1.x -= FixedMul(diff, FixedDiv(line->dx, line->dy)); - } - } - - if (abs(v2.x-x) > mobj->radius) { - // v1's x is out of range, so rein it in - fixed_t diff = abs(v2.x-x) - mobj->radius; - - if (v2.x < x) { // Moving right - v2.x += diff; - v2.y += FixedMul(diff, FixedDiv(line->dy, line->dx)); - } else { // Moving left - v2.x -= diff; - v2.y -= FixedMul(diff, FixedDiv(line->dy, line->dx)); - } - } - - if (abs(v2.y-y) > mobj->radius) { - // v2's y is out of range, so rein it in - fixed_t diff = abs(v2.y-y) - mobj->radius; - - if (v2.y < y) { // Moving up - v2.y += diff; - v2.x += FixedMul(diff, FixedDiv(line->dx, line->dy)); - } else { // Moving down - v2.y -= diff; - v2.x -= FixedMul(diff, FixedDiv(line->dx, line->dy)); - } - } - - /*CONS_Printf("AFTER: v1 = %f %f %f\n", - FIXED_TO_FLOAT(v1.x), - FIXED_TO_FLOAT(v1.y), - FIXED_TO_FLOAT(P_GetZAt(slope, v1.x, v1.y)) - ); - CONS_Printf(" v2 = %f %f %f\n", - FIXED_TO_FLOAT(v2.x), - FIXED_TO_FLOAT(v2.y), - FIXED_TO_FLOAT(P_GetZAt(slope, v2.x, v2.y)) - );*/ - - // Return the higher of the two points - return max( - P_GetZAt(slope, v1.x, v1.y), - P_GetZAt(slope, v2.x, v2.y) - ); - } + return HighestOnLine(mobj->radius, x, y, line, slope, lowest); } else // Well, that makes it easy. Just get the floor height #endif return sector->floorheight; } -fixed_t P_CameraGetCeilingZ(camera_t *mobj, sector_t *sector, fixed_t x, fixed_t y, line_t *line) // SRB2CBTODO: This needs to be over all the code +fixed_t P_CameraCeilingZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect) { I_Assert(mobj != NULL); I_Assert(sector != NULL); @@ -1354,118 +1070,6 @@ fixed_t P_CameraGetCeilingZ(camera_t *mobj, sector_t *sector, fixed_t x, fixed_t fixed_t testx, testy; pslope_t *slope = sector->c_slope; - // Get the corner of the object that should be the lowest on the slope - if (slope->d.x < 0) - testx = mobj->radius; - else - testx = -mobj->radius; - - if (slope->d.y < 0) - testy = mobj->radius; - else - testy = -mobj->radius; - - if (slope->zdelta < 0) { - testx = -testx; - testy = -testy; - } - - testx += x; - testy += y; - - // If the lowest point is in the sector, then we have it easy! Just get the Z at that point - if (R_PointInSubsector(testx, testy)->sector == sector) - return P_GetZAt(slope, testx, testy); - - // If we're just testing for base sector location (no collision line), just go for the center's spot... - // It'll get fixed when we test for collision anyway, and the final result can't be higher than this - if (line == NULL) - return P_GetZAt(slope, x, y); - - // Alright, so we're sitting on a line that contains our slope sector, and need to figure out the highest point we're touching... - // The solution is simple! Get the line's vertices, and pull each one in along its line until it touches the object's bounding box - // (assuming it isn't already inside), then test each point's slope Z and return the lower of the two. - { - vertex_t v1, v2; - v1.x = line->v1->x; - v1.y = line->v1->y; - v2.x = line->v2->x; - v2.y = line->v2->y; - - if (abs(v1.x-x) > mobj->radius) { - // v1's x is out of range, so rein it in - fixed_t diff = abs(v1.x-x) - mobj->radius; - - if (v1.x < x) { // Moving right - v1.x += diff; - v1.y += FixedMul(diff, FixedDiv(line->dy, line->dx)); - } else { // Moving left - v1.x -= diff; - v1.y -= FixedMul(diff, FixedDiv(line->dy, line->dx)); - } - } - - if (abs(v1.y-y) > mobj->radius) { - // v1's y is out of range, so rein it in - fixed_t diff = abs(v1.y-y) - mobj->radius; - - if (v1.y < y) { // Moving up - v1.y += diff; - v1.x += FixedMul(diff, FixedDiv(line->dx, line->dy)); - } else { // Moving down - v1.y -= diff; - v1.x -= FixedMul(diff, FixedDiv(line->dx, line->dy)); - } - } - - if (abs(v2.x-x) > mobj->radius) { - // v1's x is out of range, so rein it in - fixed_t diff = abs(v2.x-x) - mobj->radius; - - if (v2.x < x) { // Moving right - v2.x += diff; - v2.y += FixedMul(diff, FixedDiv(line->dy, line->dx)); - } else { // Moving left - v2.x -= diff; - v2.y -= FixedMul(diff, FixedDiv(line->dy, line->dx)); - } - } - - if (abs(v2.y-y) > mobj->radius) { - // v2's y is out of range, so rein it in - fixed_t diff = abs(v2.y-y) - mobj->radius; - - if (v2.y < y) { // Moving up - v2.y += diff; - v2.x += FixedMul(diff, FixedDiv(line->dx, line->dy)); - } else { // Moving down - v2.y -= diff; - v2.x -= FixedMul(diff, FixedDiv(line->dx, line->dy)); - } - } - - // Return the lower of the two points - return min( - P_GetZAt(slope, v1.x, v1.y), - P_GetZAt(slope, v2.x, v2.y) - ); - } - } else // Well, that makes it easy. Just get the ceiling height -#endif - return sector->ceilingheight; -} - -// Do the same as above, but for FOFs! -fixed_t P_CameraGetFOFTopZ(camera_t *mobj, sector_t *sector, ffloor_t *fof, fixed_t x, fixed_t y, line_t *line) // SRB2CBTODO: This needs to be over all the code -{ - I_Assert(mobj != NULL); - I_Assert(sector != NULL); - I_Assert(fof != NULL); -#ifdef ESLOPE - if (*fof->t_slope) { - fixed_t testx, testy; - pslope_t *slope = *fof->t_slope; - // Get the corner of the object that should be the highest on the slope if (slope->d.x < 0) testx = mobj->radius; @@ -1477,7 +1081,7 @@ fixed_t P_CameraGetFOFTopZ(camera_t *mobj, sector_t *sector, ffloor_t *fof, fixe else testy = -mobj->radius; - if (slope->zdelta > 0) { + if ((slope->zdelta > 0) ^ !!(lowest)) { testx = -testx; testy = -testy; } @@ -1486,220 +1090,54 @@ fixed_t P_CameraGetFOFTopZ(camera_t *mobj, sector_t *sector, ffloor_t *fof, fixe testy += y; // If the highest point is in the sector, then we have it easy! Just get the Z at that point - if (R_PointInSubsector(testx, testy)->sector == sector) + if (R_PointInSubsector(testx, testy)->sector == (boundsec ?: sector)) return P_GetZAt(slope, testx, testy); + // If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point + if (perfect) { + size_t i; + line_t *ld; + fixed_t bbox[4]; + fixed_t finalheight; + + if (lowest) + finalheight = INT32_MAX; + else + finalheight = INT32_MIN; + + bbox[BOXLEFT] = x-mobj->radius; + bbox[BOXRIGHT] = x+mobj->radius; + bbox[BOXTOP] = y+mobj->radius; + bbox[BOXBOTTOM] = y-mobj->radius; + for (i = 0; i < boundsec->linecount; i++) { + ld = boundsec->lines[i]; + + if (bbox[BOXRIGHT] <= ld->bbox[BOXLEFT] || bbox[BOXLEFT] >= ld->bbox[BOXRIGHT] + || bbox[BOXTOP] <= ld->bbox[BOXBOTTOM] || bbox[BOXBOTTOM] >= ld->bbox[BOXTOP]) + continue; + + if (P_BoxOnLineSide(bbox, ld) != -1) + continue; + + if (lowest) + finalheight = min(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, true)); + else + finalheight = max(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, false)); + } + + return finalheight; + } + // If we're just testing for base sector location (no collision line), just go for the center's spot... // It'll get fixed when we test for collision anyway, and the final result can't be lower than this if (line == NULL) return P_GetZAt(slope, x, y); - // Alright, so we're sitting on a line that contains our slope sector, and need to figure out the highest point we're touching... - // The solution is simple! Get the line's vertices, and pull each one in along its line until it touches the object's bounding box - // (assuming it isn't already inside), then test each point's slope Z and return the higher of the two. - { - vertex_t v1, v2; - v1.x = line->v1->x; - v1.y = line->v1->y; - v2.x = line->v2->x; - v2.y = line->v2->y; - - /*CONS_Printf("BEFORE: v1 = %f %f %f\n", - FIXED_TO_FLOAT(v1.x), - FIXED_TO_FLOAT(v1.y), - FIXED_TO_FLOAT(P_GetZAt(slope, v1.x, v1.y)) - ); - CONS_Printf(" v2 = %f %f %f\n", - FIXED_TO_FLOAT(v2.x), - FIXED_TO_FLOAT(v2.y), - FIXED_TO_FLOAT(P_GetZAt(slope, v2.x, v2.y)) - );*/ - - if (abs(v1.x-x) > mobj->radius) { - // v1's x is out of range, so rein it in - fixed_t diff = abs(v1.x-x) - mobj->radius; - - if (v1.x < x) { // Moving right - v1.x += diff; - v1.y += FixedMul(diff, FixedDiv(line->dy, line->dx)); - } else { // Moving left - v1.x -= diff; - v1.y -= FixedMul(diff, FixedDiv(line->dy, line->dx)); - } - } - - if (abs(v1.y-y) > mobj->radius) { - // v1's y is out of range, so rein it in - fixed_t diff = abs(v1.y-y) - mobj->radius; - - if (v1.y < y) { // Moving up - v1.y += diff; - v1.x += FixedMul(diff, FixedDiv(line->dx, line->dy)); - } else { // Moving down - v1.y -= diff; - v1.x -= FixedMul(diff, FixedDiv(line->dx, line->dy)); - } - } - - if (abs(v2.x-x) > mobj->radius) { - // v1's x is out of range, so rein it in - fixed_t diff = abs(v2.x-x) - mobj->radius; - - if (v2.x < x) { // Moving right - v2.x += diff; - v2.y += FixedMul(diff, FixedDiv(line->dy, line->dx)); - } else { // Moving left - v2.x -= diff; - v2.y -= FixedMul(diff, FixedDiv(line->dy, line->dx)); - } - } - - if (abs(v2.y-y) > mobj->radius) { - // v2's y is out of range, so rein it in - fixed_t diff = abs(v2.y-y) - mobj->radius; - - if (v2.y < y) { // Moving up - v2.y += diff; - v2.x += FixedMul(diff, FixedDiv(line->dx, line->dy)); - } else { // Moving down - v2.y -= diff; - v2.x -= FixedMul(diff, FixedDiv(line->dx, line->dy)); - } - } - - /*CONS_Printf("AFTER: v1 = %f %f %f\n", - FIXED_TO_FLOAT(v1.x), - FIXED_TO_FLOAT(v1.y), - FIXED_TO_FLOAT(P_GetZAt(slope, v1.x, v1.y)) - ); - CONS_Printf(" v2 = %f %f %f\n", - FIXED_TO_FLOAT(v2.x), - FIXED_TO_FLOAT(v2.y), - FIXED_TO_FLOAT(P_GetZAt(slope, v2.x, v2.y)) - );*/ - - // Return the higher of the two points - return max( - P_GetZAt(slope, v1.x, v1.y), - P_GetZAt(slope, v2.x, v2.y) - ); - } - } else // Well, that makes it easy. Just get the top height + return HighestOnLine(mobj->radius, x, y, line, slope, lowest); + } else // Well, that makes it easy. Just get the ceiling height #endif - return *fof->topheight; + return sector->ceilingheight; } - -fixed_t P_CameraGetFOFBottomZ(camera_t *mobj, sector_t *sector, ffloor_t *fof, fixed_t x, fixed_t y, line_t *line) // SRB2CBTODO: This needs to be over all the code -{ - I_Assert(mobj != NULL); - I_Assert(sector != NULL); - I_Assert(fof != NULL); -#ifdef ESLOPE - if (*fof->b_slope) { - fixed_t testx, testy; - pslope_t *slope = *fof->b_slope; - - // Get the corner of the object that should be the lowest on the slope - if (slope->d.x < 0) - testx = mobj->radius; - else - testx = -mobj->radius; - - if (slope->d.y < 0) - testy = mobj->radius; - else - testy = -mobj->radius; - - if (slope->zdelta < 0) { - testx = -testx; - testy = -testy; - } - - testx += x; - testy += y; - - // If the lowest point is in the sector, then we have it easy! Just get the Z at that point - if (R_PointInSubsector(testx, testy)->sector == sector) - return P_GetZAt(slope, testx, testy); - - // If we're just testing for base sector location (no collision line), just go for the center's spot... - // It'll get fixed when we test for collision anyway, and the final result can't be higher than this - if (line == NULL) - return P_GetZAt(slope, x, y); - - // Alright, so we're sitting on a line that contains our slope sector, and need to figure out the highest point we're touching... - // The solution is simple! Get the line's vertices, and pull each one in along its line until it touches the object's bounding box - // (assuming it isn't already inside), then test each point's slope Z and return the lower of the two. - { - vertex_t v1, v2; - v1.x = line->v1->x; - v1.y = line->v1->y; - v2.x = line->v2->x; - v2.y = line->v2->y; - - if (abs(v1.x-x) > mobj->radius) { - // v1's x is out of range, so rein it in - fixed_t diff = abs(v1.x-x) - mobj->radius; - - if (v1.x < x) { // Moving right - v1.x += diff; - v1.y += FixedMul(diff, FixedDiv(line->dy, line->dx)); - } else { // Moving left - v1.x -= diff; - v1.y -= FixedMul(diff, FixedDiv(line->dy, line->dx)); - } - } - - if (abs(v1.y-y) > mobj->radius) { - // v1's y is out of range, so rein it in - fixed_t diff = abs(v1.y-y) - mobj->radius; - - if (v1.y < y) { // Moving up - v1.y += diff; - v1.x += FixedMul(diff, FixedDiv(line->dx, line->dy)); - } else { // Moving down - v1.y -= diff; - v1.x -= FixedMul(diff, FixedDiv(line->dx, line->dy)); - } - } - - if (abs(v2.x-x) > mobj->radius) { - // v1's x is out of range, so rein it in - fixed_t diff = abs(v2.x-x) - mobj->radius; - - if (v2.x < x) { // Moving right - v2.x += diff; - v2.y += FixedMul(diff, FixedDiv(line->dy, line->dx)); - } else { // Moving left - v2.x -= diff; - v2.y -= FixedMul(diff, FixedDiv(line->dy, line->dx)); - } - } - - if (abs(v2.y-y) > mobj->radius) { - // v2's y is out of range, so rein it in - fixed_t diff = abs(v2.y-y) - mobj->radius; - - if (v2.y < y) { // Moving up - v2.y += diff; - v2.x += FixedMul(diff, FixedDiv(line->dx, line->dy)); - } else { // Moving down - v2.y -= diff; - v2.x -= FixedMul(diff, FixedDiv(line->dx, line->dy)); - } - } - - // Return the lower of the two points - return min( - P_GetZAt(slope, v1.x, v1.y), - P_GetZAt(slope, v2.x, v2.y) - ); - } - } else // Well, that makes it easy. Just get the bottom height -#endif - return *fof->bottomheight; -} - static void P_PlayerFlip(mobj_t *mo) { if (!mo->player) From a9d49cd9fa1d2237948fecbd159eb3af82f1754f Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Sun, 24 May 2015 12:53:30 -0500 Subject: [PATCH 74/91] Make all specials reliant on floor touch work right with sloeps (I might've missed some, though) --- src/p_floor.c | 20 +++++++---- src/p_mobj.c | 8 ++--- src/p_spec.c | 97 +++++++++++++++++++++++++++------------------------ src/p_user.c | 8 ++--- 4 files changed, 73 insertions(+), 60 deletions(-) diff --git a/src/p_floor.c b/src/p_floor.c index 4e289c8d5..b8d3f7b5e 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -1174,8 +1174,8 @@ void T_SpikeSector(levelspecthink_t *spikes) if (affectsec == spikes->sector) // Applied to an actual sector { - fixed_t affectfloor = P_GetFloorZ(thing, affectsec, thing->x, thing->y, NULL); - fixed_t affectceil = P_GetCeilingZ(thing, affectsec, thing->x, thing->y, NULL); + fixed_t affectfloor = P_GetSpecialBottomZ(thing, affectsec, affectsec); + fixed_t affectceil = P_GetSpecialTopZ(thing, affectsec, affectsec); if (affectsec->flags & SF_FLIPSPECIAL_FLOOR) { @@ -1197,12 +1197,14 @@ void T_SpikeSector(levelspecthink_t *spikes) } else { + fixed_t affectfloor = P_GetSpecialBottomZ(thing, affectsec, spikes->sector); + fixed_t affectceil = P_GetSpecialTopZ(thing, affectsec, spikes->sector); if (affectsec->flags & SF_FLIPSPECIAL_FLOOR) { if (!(thing->eflags & MFE_VERTICALFLIP) && thing->momz > 0) continue; - if (thing->z == affectsec->ceilingheight) + if (thing->z == affectceil) dothepain = true; } @@ -1211,7 +1213,7 @@ void T_SpikeSector(levelspecthink_t *spikes) if ((thing->eflags & MFE_VERTICALFLIP) && thing->momz < 0) continue; - if (thing->z + thing->height == affectsec->floorheight) + if (thing->z + thing->height == affectfloor) dothepain = true; } } @@ -2090,6 +2092,7 @@ void T_EachTimeThinker(levelspecthink_t *eachtime) boolean FOFsector = false; boolean inAndOut = false; boolean floortouch = false; + fixed_t bottomheight, topheight; for (i = 0; i < MAXPLAYERS; i++) { @@ -2154,10 +2157,13 @@ void T_EachTimeThinker(levelspecthink_t *eachtime) if (players[j].mo->subsector->sector != targetsec) continue; - if (players[j].mo->z > sec->ceilingheight) + topheight = P_GetSpecialTopZ(players[j].mo, sec, targetsec); + bottomheight = P_GetSpecialBottomZ(players[j].mo, sec, targetsec); + + if (players[j].mo->z > topheight) continue; - if (players[j].mo->z + players[j].mo->height < sec->floorheight) + if (players[j].mo->z + players[j].mo->height < bottomheight) continue; if (floortouch == true && P_IsObjectOnGroundIn(players[j].mo, targetsec)) @@ -2317,7 +2323,7 @@ void T_RaiseSector(levelspecthink_t *raise) if (raise->vars[1] && !(thing->player->pflags & PF_STARTDASH)) continue; - if (!(thing->z == raise->sector->ceilingheight)) + if (!(thing->z == P_GetSpecialTopZ(thing, raise->sector, sector))) continue; playeronme = true; diff --git a/src/p_mobj.c b/src/p_mobj.c index a11aa2c0b..edf30d58a 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -3562,11 +3562,11 @@ static void P_PlayerMobjThinker(mobj_t *mobj) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_CRUMBLE)) continue; - topheight = P_GetFOFTopZ(mobj, node->m_sector, rover, mobj->x, mobj->y, NULL); - bottomheight = P_GetFOFBottomZ(mobj, node->m_sector, rover, mobj->x, mobj->y, NULL); + topheight = P_GetSpecialTopZ(mobj, sectors + rover->secnum, node->m_sector); + bottomheight = P_GetSpecialBottomZ(mobj, sectors + rover->secnum, node->m_sector); - if ((topheight <= mobj->z + 16*mobj->scale && topheight >= mobj->z && !(mobj->eflags & MFE_VERTICALFLIP)) - || (bottomheight >= mobj->z + mobj->height && bottomheight <= mobj->z + mobj->height - 16*mobj->scale && mobj->eflags & MFE_VERTICALFLIP)) // You nut. + if ((topheight == mobj->z && !(mobj->eflags & MFE_VERTICALFLIP)) + || (bottomheight == mobj->z + mobj->height && mobj->eflags & MFE_VERTICALFLIP)) // You nut. EV_StartCrumble(rover->master->frontsector, rover, (rover->flags & FF_FLOATBOB), mobj->player, rover->alpha, !(rover->flags & FF_NORETURN)); } } diff --git a/src/p_spec.c b/src/p_spec.c index 914e008d9..6cc0e2f45 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3365,6 +3365,7 @@ sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 n static boolean P_ThingIsOnThe3DFloor(mobj_t *mo, sector_t *sector, sector_t *targetsec) { ffloor_t *rover; + fixed_t top, bottom; if (!mo->player) // should NEVER happen return false; @@ -3381,6 +3382,9 @@ static boolean P_ThingIsOnThe3DFloor(mobj_t *mo, sector_t *sector, sector_t *tar //if (!(rover->flags & FF_EXISTS)) // return false; + top = P_GetSpecialTopZ(mo, sector, targetsec); + bottom = P_GetSpecialBottomZ(mo, sector, targetsec); + // Check the 3D floor's type... if (rover->flags & FF_BLOCKPLAYER) { @@ -3388,27 +3392,27 @@ static boolean P_ThingIsOnThe3DFloor(mobj_t *mo, sector_t *sector, sector_t *tar if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR) && !(rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING)) { - if ((mo->eflags & MFE_VERTICALFLIP) || mo->z != *rover->topheight) + if ((mo->eflags & MFE_VERTICALFLIP) || mo->z != top) return false; } else if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING) && !(rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR)) { if (!(mo->eflags & MFE_VERTICALFLIP) - || mo->z + mo->height != *rover->bottomheight) + || mo->z + mo->height != bottom) return false; } else if (rover->master->frontsector->flags & SF_FLIPSPECIAL_BOTH) { - if (!((mo->eflags & MFE_VERTICALFLIP && mo->z + mo->height == *rover->bottomheight) - || (!(mo->eflags & MFE_VERTICALFLIP) && mo->z == *rover->topheight))) + if (!((mo->eflags & MFE_VERTICALFLIP && mo->z + mo->height == bottom) + || (!(mo->eflags & MFE_VERTICALFLIP) && mo->z == top))) return false; } } else { // Water and intangible FOFs - if (mo->z > *rover->topheight || (mo->z + mo->height) < *rover->bottomheight) + if (mo->z > top || (mo->z + mo->height) < bottom) return false; } @@ -3426,9 +3430,9 @@ static boolean P_ThingIsOnThe3DFloor(mobj_t *mo, sector_t *sector, sector_t *tar static inline boolean P_MobjReadyToTrigger(mobj_t *mo, sector_t *sec) { if (mo->eflags & MFE_VERTICALFLIP) - return (mo->z+mo->height == sec->ceilingheight && sec->flags & SF_FLIPSPECIAL_CEILING); + return (mo->z+mo->height == P_GetSpecialTopZ(mo, sec, sec) && sec->flags & SF_FLIPSPECIAL_CEILING); else - return (mo->z == sec->floorheight && sec->flags & SF_FLIPSPECIAL_FLOOR); + return (mo->z == P_GetSpecialBottomZ(mo, sec, sec) && sec->flags & SF_FLIPSPECIAL_FLOOR); } /** Applies a sector special to a player. @@ -4389,27 +4393,27 @@ static void P_PlayerOnSpecial3DFloor(player_t *player, sector_t *sector) if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR) && !(rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING)) { - if ((player->mo->eflags & MFE_VERTICALFLIP) || player->mo->z != *rover->topheight) + if ((player->mo->eflags & MFE_VERTICALFLIP) || player->mo->z != P_GetSpecialTopZ(player->mo, sectors + rover->secnum, sector)) continue; } else if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING) && !(rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR)) { if (!(player->mo->eflags & MFE_VERTICALFLIP) - || player->mo->z + player->mo->height != *rover->bottomheight) + || player->mo->z + player->mo->height != P_GetSpecialBottomZ(player->mo, sectors + rover->secnum, sector)) continue; } else if (rover->master->frontsector->flags & SF_FLIPSPECIAL_BOTH) { - if (!((player->mo->eflags & MFE_VERTICALFLIP && player->mo->z + player->mo->height == *rover->bottomheight) - || (!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z == *rover->topheight))) + if (!((player->mo->eflags & MFE_VERTICALFLIP && player->mo->z + player->mo->height == P_GetSpecialBottomZ(player->mo, sectors + rover->secnum, sector)) + || (!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z == P_GetSpecialTopZ(player->mo, sectors + rover->secnum, sector)))) continue; } } else { // Water and DEATH FOG!!! heh - if (player->mo->z > *rover->topheight || (player->mo->z + player->mo->height) < *rover->bottomheight) + if (player->mo->z > P_GetSpecialTopZ(player->mo, sectors + rover->secnum, sector) || (player->mo->z + player->mo->height) < P_GetSpecialTopZ(player->mo, sectors + rover->secnum, sector)) continue; } @@ -4582,8 +4586,8 @@ static void P_RunSpecialSectorCheck(player_t *player, sector_t *sector) return; } - f_affectpoint = P_GetFloorZ(player->mo, sector, player->mo->x, player->mo->y, NULL); - c_affectpoint = P_GetCeilingZ(player->mo, sector, player->mo->x, player->mo->y, NULL); + f_affectpoint = P_GetSpecialBottomZ(player->mo, sector, sector); + c_affectpoint = P_GetSpecialTopZ(player->mo, sector, sector); // Only go further if on the ground if ((sector->flags & SF_FLIPSPECIAL_FLOOR) && !(sector->flags & SF_FLIPSPECIAL_CEILING) && player->mo->z != f_affectpoint) @@ -5340,6 +5344,7 @@ void T_LaserFlash(laserthink_t *flash) sector_t *sourcesec; ffloor_t *ffloor = flash->ffloor; sector_t *sector = flash->sector; + fixed_t top, bottom; if (!ffloor || !(ffloor->flags & FF_EXISTS)) return; @@ -5363,8 +5368,11 @@ void T_LaserFlash(laserthink_t *flash) && thing->flags & MF_BOSS) continue; // Don't hurt bosses - if (thing->z >= sourcesec->ceilingheight - || thing->z + thing->height <= sourcesec->floorheight) + top = P_GetSpecialTopZ(thing, sourcesec, sector); + bottom = P_GetSpecialBottomZ(thing, sourcesec, sector); + + if (thing->z >= top + || thing->z + thing->height <= bottom) continue; if (thing->flags & MF_SHOOTABLE) @@ -6655,6 +6663,8 @@ void T_Scroll(scroll_t *s) if (thing->eflags & MFE_PUSHED) // Already pushed this tic by an exclusive pusher. continue; + height = P_GetSpecialBottomZ(thing, sec, psec); + if (!(thing->flags & MF_NOCLIP)) // Thing must be clipped if (!(thing->flags & MF_NOGRAVITY || thing->z+thing->height != height)) // Thing must a) be non-floating and have z+height == height { @@ -6675,6 +6685,8 @@ void T_Scroll(scroll_t *s) if (thing->eflags & MFE_PUSHED) continue; + height = P_GetSpecialBottomZ(thing, sec, sec); + if (!(thing->flags & MF_NOCLIP) && (!(thing->flags & MF_NOGRAVITY || thing->z > height))) { @@ -6714,6 +6726,8 @@ void T_Scroll(scroll_t *s) if (thing->eflags & MFE_PUSHED) continue; + height = P_GetSpecialTopZ(thing, sec, psec); + if (!(thing->flags & MF_NOCLIP)) // Thing must be clipped if (!(thing->flags & MF_NOGRAVITY || thing->z != height))// Thing must a) be non-floating and have z == height { @@ -6734,6 +6748,8 @@ void T_Scroll(scroll_t *s) if (thing->eflags & MFE_PUSHED) continue; + height = P_GetSpecialTopZ(thing, sec, sec); + if (!(thing->flags & MF_NOCLIP) && (!(thing->flags & MF_NOGRAVITY || thing->z+thing->height < height))) { @@ -7027,7 +7043,7 @@ static void Add_Friction(INT32 friction, INT32 movefactor, INT32 affectee, INT32 */ void T_Friction(friction_t *f) { - sector_t *sec; + sector_t *sec, *referrer; mobj_t *thing; msecnode_t *node; @@ -7036,7 +7052,7 @@ void T_Friction(friction_t *f) // Make sure the sector type hasn't changed if (f->roverfriction) { - sector_t *referrer = sectors + f->referrer; + referrer = sectors + f->referrer; if (!(GETSECSPECIAL(referrer->special, 3) == 1 || GETSECSPECIAL(referrer->special, 3) == 3)) @@ -7068,9 +7084,7 @@ void T_Friction(friction_t *f) { if (f->roverfriction) { - sector_t *referrer = §ors[f->referrer]; - - if (thing->floorz != referrer->ceilingheight) + if (thing->floorz != P_GetSpecialTopZ(thing, referrer, sec)) { node = node->m_snext; continue; @@ -7083,7 +7097,7 @@ void T_Friction(friction_t *f) thing->movefactor = f->movefactor; } } - else if (sec->floorheight == thing->floorz && (thing->friction == ORIG_FRICTION // normal friction? + else if (P_GetSpecialBottomZ(thing, sec, sec) == thing->floorz && (thing->friction == ORIG_FRICTION // normal friction? || f->friction < thing->friction)) { thing->friction = f->friction; @@ -7357,7 +7371,7 @@ static inline boolean PIT_PushThing(mobj_t *thing) */ void T_Pusher(pusher_t *p) { - sector_t *sec; + sector_t *sec, *referrer; mobj_t *thing; msecnode_t *node; INT32 xspeed = 0,yspeed = 0; @@ -7366,7 +7380,6 @@ void T_Pusher(pusher_t *p) //INT32 ht = 0; boolean inFOF; boolean touching; - boolean foundfloor = false; boolean moved; xspeed = yspeed = 0; @@ -7378,19 +7391,16 @@ void T_Pusher(pusher_t *p) if (p->roverpusher) { - sector_t *referrer = §ors[p->referrer]; + referrer = §ors[p->referrer]; - if (GETSECSPECIAL(referrer->special, 3) == 2 - || GETSECSPECIAL(referrer->special, 3) == 3) - foundfloor = true; + if (!(GETSECSPECIAL(referrer->special, 3) == 2 + || GETSECSPECIAL(referrer->special, 3) == 3)) + return; } else if (!(GETSECSPECIAL(sec->special, 3) == 2 || GETSECSPECIAL(sec->special, 3) == 3)) return; - if (p->roverpusher && foundfloor == false) // Not even a 3d floor has the PUSH_MASK. - return; - // For constant pushers (wind/current) there are 3 situations: // // 1) Affected Thing is above the floor. @@ -7465,41 +7475,38 @@ void T_Pusher(pusher_t *p) // Find the area that the 'thing' is in if (p->roverpusher) { - sector_t *referrer = §ors[p->referrer]; - INT32 special; + fixed_t top, bottom; - special = GETSECSPECIAL(referrer->special, 3); - - if (!(special == 2 || special == 3)) - return; + top = P_GetSpecialTopZ(thing, referrer, sec); + bottom = P_GetSpecialBottomZ(thing, referrer, sec); if (thing->eflags & MFE_VERTICALFLIP) { - if (referrer->floorheight > thing->z + thing->height - || referrer->ceilingheight < (thing->z + (thing->height >> 1))) + if (bottom > thing->z + thing->height + || top < (thing->z + (thing->height >> 1))) continue; - if (thing->z < referrer->floorheight) + if (thing->z < bottom) touching = true; - if (thing->z + (thing->height >> 1) > referrer->floorheight) + if (thing->z + (thing->height >> 1) > bottom) inFOF = true; } else { - if (referrer->ceilingheight < thing->z || referrer->floorheight > (thing->z + (thing->height >> 1))) + if (top < thing->z || referrer->floorheight > (thing->z + (thing->height >> 1))) continue; - if (thing->z + thing->height > referrer->ceilingheight) + if (thing->z + thing->height > top) touching = true; - if (thing->z + (thing->height >> 1) < referrer->ceilingheight) + if (thing->z + (thing->height >> 1) < top) inFOF = true; } } else // Treat the entire sector as one big FOF { - if (thing->z == thing->subsector->sector->floorheight) + if (thing->z == P_GetSpecialBottomZ(thing, sec, sec)) touching = true; else if (p->type != p_current) inFOF = true; diff --git a/src/p_user.c b/src/p_user.c index 115c79638..d57d5cb99 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1212,7 +1212,7 @@ boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec) if (mo->eflags & MFE_VERTICALFLIP) { // Detect if the player is on the ceiling. - if (mo->z+mo->height >= sec->ceilingheight) + if (mo->z+mo->height >= P_GetSpecialTopZ(mo, sec, sec)) return true; // Otherwise, detect if the player is on the bottom of a FOF. else @@ -1236,7 +1236,7 @@ boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec) continue; // Actually check if the player is on the suitable FOF. - if (mo->z+mo->height == *rover->bottomheight) + if (mo->z+mo->height == P_GetSpecialBottomZ(mo, sectors + rover->secnum, sec)) return true; } } @@ -1245,7 +1245,7 @@ boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec) else { // Detect if the player is on the floor. - if (mo->z <= sec->floorheight) + if (mo->z <= P_GetSpecialBottomZ(mo, sec, sec)) return true; // Otherwise, detect if the player is on the top of a FOF. else @@ -1269,7 +1269,7 @@ boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec) continue; // Actually check if the player is on the suitable FOF. - if (mo->z == *rover->topheight) + if (mo->z == P_GetSpecialTopZ(mo, sectors + rover->secnum, sec)) return true; } } From bddcf98355fd3d3af9d7652ffd01614f13fbac42 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Sun, 24 May 2015 15:59:17 -0500 Subject: [PATCH 75/91] Remap slope line specials to 7xx range: shim old values for now --- src/p_slopes.c | 49 +++++++++++++++++++++++++++++++++++++++++++------ src/p_spec.c | 6 +++--- 2 files changed, 46 insertions(+), 9 deletions(-) diff --git a/src/p_slopes.c b/src/p_slopes.c index ed9623e08..d0b202168 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -174,10 +174,10 @@ void P_SpawnSlope_Line(int linenum) vector2_t direction; fixed_t nx, ny, dz, extent; - boolean frontfloor = (special == 386 || special == 388 || special == 393); - boolean backfloor = (special == 389 || special == 391 || special == 392); - boolean frontceil = (special == 387 || special == 388 || special == 392); - boolean backceil = (special == 390 || special == 391 || special == 393); + boolean frontfloor = (special == 700 || special == 702 || special == 703); + boolean backfloor = (special == 710 || special == 712 || special == 713); + boolean frontceil = (special == 701 || special == 702 || special == 713); + boolean backceil = (special == 711 || special == 712 || special == 703); if(!frontfloor && !backfloor && !frontceil && !backceil) { @@ -457,9 +457,9 @@ void P_CopySectorSlope(line_t *line) { sector_t *srcsec = sectors + i; - if((special - 393) & 1 && !fsec->f_slope && srcsec->f_slope) + if((special - 719) & 1 && !fsec->f_slope && srcsec->f_slope) fsec->f_slope = srcsec->f_slope; //P_CopySlope(srcsec->f_slope); - if((special - 393) & 2 && !fsec->c_slope && srcsec->c_slope) + if((special - 719) & 2 && !fsec->c_slope && srcsec->c_slope) fsec->c_slope = srcsec->c_slope; //P_CopySlope(srcsec->c_slope); } @@ -726,6 +726,9 @@ void P_SetSlopesFromVertexHeights(lumpnum_t lumpnum) // Reset the dynamic slopes pointer, and read all of the fancy schmancy slopes void P_ResetDynamicSlopes(void) { size_t i; +#if 1 // Rewrite old specials to new ones, and give a console warning + boolean warned = false; +#endif dynslopes = NULL; @@ -735,14 +738,48 @@ void P_ResetDynamicSlopes(void) { { switch (lines[i].special) { +#if 1 // Rewrite old specials to new ones, and give a console warning +#define WARNME if (!warned) {warned = true; CONS_Alert(CONS_WARNING, "This level uses old slope specials.\nA conversion will be needed before 2.2's release.\n");} case 386: case 387: case 388: + lines[i].special += 700-386; + WARNME + P_SpawnSlope_Line(i); + break; + case 389: case 390: case 391: case 392: + lines[i].special += 710-389; + WARNME + P_SpawnSlope_Line(i); + break; + case 393: + lines[i].special = 703; + WARNME + P_SpawnSlope_Line(i); + break; + + case 394: + case 395: + case 396: + lines[i].special += 720-394; + WARNME + break; + +#endif + + case 700: + case 701: + case 702: + case 703: + case 710: + case 711: + case 712: + case 713: P_SpawnSlope_Line(i); break; diff --git a/src/p_spec.c b/src/p_spec.c index 6cc0e2f45..30564ea23 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -6452,9 +6452,9 @@ void P_SpawnSpecials(INT32 fromnetsave) break; #ifdef ESLOPE // Slope copy specials. Handled here for sanity. - case 394: - case 395: - case 396: + case 720: + case 721: + case 722: P_CopySectorSlope(&lines[i]); break; #endif From 32759312a153e857a4c0a9d6d79af0ef582e3480 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Sun, 24 May 2015 18:22:56 -0500 Subject: [PATCH 76/91] Shut up the Kalaron --- src/r_draw8.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/r_draw8.c b/src/r_draw8.c index a028b9c12..279690492 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -628,8 +628,8 @@ void R_DrawTiltedSpan_8(void) double endz = 1.f/iz; double endu = uz*endz; double endv = vz*endz; - UINT32 stepu = (UINT32)((endu - startu) * INVSPAN); - UINT32 stepv = (UINT32)((endv - startv) * INVSPAN); + UINT32 stepu = (INT64)((endu - startu) * INVSPAN); + UINT32 stepv = (INT64)((endv - startv) * INVSPAN); u = (UINT32)(startu) + viewx; v = (UINT32)(startv) + viewy; @@ -665,8 +665,8 @@ void R_DrawTiltedSpan_8(void) double endu = uz*endz; double endv = vz*endz; left = 1.f/left; - UINT32 stepu = (UINT32)((endu - startu) * left); - UINT32 stepv = (UINT32)((endv - startv) * left); + UINT32 stepu = (INT64)((endu - startu) * left); + UINT32 stepv = (INT64)((endv - startv) * left); u = (UINT32)(startu) + viewx; v = (UINT32)(startv) + viewy; @@ -761,8 +761,8 @@ void R_DrawTiltedTranslucentSpan_8(void) double endz = 1.f/iz; double endu = uz*endz; double endv = vz*endz; - UINT32 stepu = (UINT32)((endu - startu) * INVSPAN); - UINT32 stepv = (UINT32)((endv - startv) * INVSPAN); + UINT32 stepu = (INT64)((endu - startu) * INVSPAN); + UINT32 stepv = (INT64)((endv - startv) * INVSPAN); u = (UINT32)(startu) + viewx; v = (UINT32)(startv) + viewy; @@ -798,8 +798,8 @@ void R_DrawTiltedTranslucentSpan_8(void) double endu = uz*endz; double endv = vz*endz; left = 1.f/left; - UINT32 stepu = (UINT32)((endu - startu) * left); - UINT32 stepv = (UINT32)((endv - startv) * left); + UINT32 stepu = (INT64)((endu - startu) * left); + UINT32 stepv = (INT64)((endv - startv) * left); u = (UINT32)(startu) + viewx; v = (UINT32)(startv) + viewy; From d9d3752b4e3a3fcff69f1e2b5055a4d0f1fafd04 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Mon, 25 May 2015 11:46:09 -0500 Subject: [PATCH 77/91] Unbreak FOF specials --- src/p_spec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_spec.c b/src/p_spec.c index 30564ea23..694893502 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4413,7 +4413,7 @@ static void P_PlayerOnSpecial3DFloor(player_t *player, sector_t *sector) else { // Water and DEATH FOG!!! heh - if (player->mo->z > P_GetSpecialTopZ(player->mo, sectors + rover->secnum, sector) || (player->mo->z + player->mo->height) < P_GetSpecialTopZ(player->mo, sectors + rover->secnum, sector)) + if (player->mo->z > P_GetSpecialTopZ(player->mo, sectors + rover->secnum, sector) || (player->mo->z + player->mo->height) < P_GetSpecialBottomZ(player->mo, sectors + rover->secnum, sector)) continue; } From 5e18db79e9061291157216613179b0f1d5b0f4fe Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Mon, 25 May 2015 12:16:19 -0500 Subject: [PATCH 78/91] Fix mobjs sometimes clipping through floors (whoops!) --- src/p_mobj.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index edf30d58a..e44279347 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2272,6 +2272,11 @@ static boolean P_ZMovement(mobj_t *mo) mom.y = mo->momy; mom.z = mo->momz; + if (mo->eflags & MFE_VERTICALFLIP) + mo->z = mo->ceilingz - mo->height; + else + mo->z = mo->floorz; + #ifdef ESLOPE P_TryMove(mo, mo->x, mo->y, true); // Sets mo->standingslope correctly if (mo->standingslope) { @@ -2282,11 +2287,6 @@ static boolean P_ZMovement(mobj_t *mo) } #endif - if (mo->eflags & MFE_VERTICALFLIP) - mo->z = mo->ceilingz - mo->height; - else - mo->z = mo->floorz; - // hit the floor if (mo->type == MT_FIREBALL) // special case for the fireball mom.z = P_MobjFlip(mo)*FixedMul(5*FRACUNIT, mo->scale); From e00d6821859bef7d6d6d0c3b2c1970d8163bae20 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Mon, 25 May 2015 13:25:23 -0500 Subject: [PATCH 79/91] Fix issue with objects getting stuck IN floors --- src/p_mobj.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index e44279347..7d48ca60c 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2278,8 +2278,10 @@ static boolean P_ZMovement(mobj_t *mo) mo->z = mo->floorz; #ifdef ESLOPE - P_TryMove(mo, mo->x, mo->y, true); // Sets mo->standingslope correctly - if (mo->standingslope) { + P_CheckPosition(mo, mo->x, mo->y); // Sets mo->standingslope correctly + if ((mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope) { + mo->standingslope = (mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope; + // Reverse quantizing might could use its own function later mo->standingslope->zangle = ANGLE_MAX-mo->standingslope->zangle; P_QuantizeMomentumToSlope(&mom, mo->standingslope); From 6026fa42eb1cea15614348e901cbe9f1cd279bdf Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Mon, 3 Aug 2015 14:47:05 -0500 Subject: [PATCH 80/91] Add masked FOF slopes (+other rendering tweaks) --- src/r_draw.h | 1 + src/r_draw8.c | 171 +++++++++++++++++++++++++++++++++++++++++++++----- src/r_plane.c | 8 ++- 3 files changed, 163 insertions(+), 17 deletions(-) diff --git a/src/r_draw.h b/src/r_draw.h index e1818545b..63fecc046 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -154,6 +154,7 @@ void R_DrawSpan_8(void); #ifdef ESLOPE void R_DrawTiltedSpan_8(void); void R_DrawTiltedTranslucentSpan_8(void); +void R_DrawTiltedSplat_8(void); #endif void R_DrawSplat_8(void); void R_DrawTranslucentSplat_8(void); diff --git a/src/r_draw8.c b/src/r_draw8.c index 279690492..f78f1494b 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -593,8 +593,8 @@ void R_DrawTiltedSpan_8(void) do { double z = 1.f/iz; - u = (UINT32)(uz*z) + viewx; - v = (UINT32)(vz*z) + viewy; + u = (INT64)(uz*z) + viewx; + v = (INT64)(vz*z) + viewy; colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); @@ -630,8 +630,8 @@ void R_DrawTiltedSpan_8(void) double endv = vz*endz; UINT32 stepu = (INT64)((endu - startu) * INVSPAN); UINT32 stepv = (INT64)((endv - startv) * INVSPAN); - u = (UINT32)(startu) + viewx; - v = (UINT32)(startv) + viewy; + u = (INT64)(startu) + viewx; + v = (INT64)(startv) + viewy; for (i = SPANSIZE-1; i >= 0; i--) { @@ -649,8 +649,8 @@ void R_DrawTiltedSpan_8(void) { if (width == 1) { - u = (UINT32)(startu); - v = (UINT32)(startv); + u = (INT64)(startu); + v = (INT64)(startv); colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; } @@ -667,8 +667,8 @@ void R_DrawTiltedSpan_8(void) left = 1.f/left; UINT32 stepu = (INT64)((endu - startu) * left); UINT32 stepv = (INT64)((endv - startv) * left); - u = (UINT32)(startu) + viewx; - v = (UINT32)(startv) + viewy; + u = (INT64)(startu) + viewx; + v = (INT64)(startv) + viewy; for (; width != 0; width--) { @@ -726,8 +726,8 @@ void R_DrawTiltedTranslucentSpan_8(void) do { double z = 1.f/iz; - u = (UINT32)(uz*z) + viewx; - v = (UINT32)(vz*z) + viewy; + u = (INT64)(uz*z) + viewx; + v = (INT64)(vz*z) + viewy; colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); @@ -763,8 +763,8 @@ void R_DrawTiltedTranslucentSpan_8(void) double endv = vz*endz; UINT32 stepu = (INT64)((endu - startu) * INVSPAN); UINT32 stepv = (INT64)((endv - startv) * INVSPAN); - u = (UINT32)(startu) + viewx; - v = (UINT32)(startv) + viewy; + u = (INT64)(startu) + viewx; + v = (INT64)(startv) + viewy; for (i = SPANSIZE-1; i >= 0; i--) { @@ -782,8 +782,8 @@ void R_DrawTiltedTranslucentSpan_8(void) { if (width == 1) { - u = (UINT32)(startu); - v = (UINT32)(startv); + u = (INT64)(startu); + v = (INT64)(startv); colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); *dest = colormap[*(ds_transmap + (source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)] << 8) + dest[0])]; } @@ -800,8 +800,8 @@ void R_DrawTiltedTranslucentSpan_8(void) left = 1.f/left; UINT32 stepu = (INT64)((endu - startu) * left); UINT32 stepv = (INT64)((endv - startv) * left); - u = (UINT32)(startu) + viewx; - v = (UINT32)(startv) + viewy; + u = (INT64)(startu) + viewx; + v = (INT64)(startv) + viewy; for (; width != 0; width--) { @@ -815,6 +815,145 @@ void R_DrawTiltedTranslucentSpan_8(void) } #endif } + +void R_DrawTiltedSplat_8(void) +{ + // x1, x2 = ds_x1, ds_x2 + int width = ds_x2 - ds_x1; + double iz, uz, vz; + UINT32 u, v; + int i; + + UINT8 *source; + UINT8 *colormap; + UINT8 *dest; + + UINT8 val; + + iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx); + + // Lighting is simple. It's just linear interpolation from start to end + { + float planelightfloat = BASEVIDWIDTH*BASEVIDWIDTH/vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f; + float lightstart, lightend; + + lightend = (iz + ds_sz.x*width) * planelightfloat; + lightstart = iz * planelightfloat; + + R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend)); + //CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf); + } + + uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx); + vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx); + + dest = ylookup[ds_y] + columnofs[ds_x1]; + source = ds_source; + //colormap = ds_colormap; + +#if 0 // The "perfect" reference version of this routine. Pretty slow. + // Use it only to see how things are supposed to look. + i = 0; + do + { + double z = 1.f/iz; + u = (INT64)(uz*z) + viewx; + v = (INT64)(vz*z) + viewy; + + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + + val = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; + if (val != TRANSPARENTPIXEL) + *dest = val; + dest++; + iz += ds_sz.x; + uz += ds_su.x; + vz += ds_sv.x; + } while (--width >= 0); +#else +#define SPANSIZE 16 +#define INVSPAN 0.0625f + + double startz = 1.f/iz; + double startu = uz*startz; + double startv = vz*startz; + double izstep, uzstep, vzstep; + + izstep = ds_sz.x * SPANSIZE; + uzstep = ds_su.x * SPANSIZE; + vzstep = ds_sv.x * SPANSIZE; + //x1 = 0; + width++; + + while (width >= SPANSIZE) + { + iz += izstep; + uz += uzstep; + vz += vzstep; + + double endz = 1.f/iz; + double endu = uz*endz; + double endv = vz*endz; + UINT32 stepu = (INT64)((endu - startu) * INVSPAN); + UINT32 stepv = (INT64)((endv - startv) * INVSPAN); + u = (INT64)(startu) + viewx; + v = (INT64)(startv) + viewy; + + for (i = SPANSIZE-1; i >= 0; i--) + { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + val = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; + if (val != TRANSPARENTPIXEL) + *dest = val; + dest++; + u += stepu; + v += stepv; + } + startu = endu; + startv = endv; + width -= SPANSIZE; + } + if (width > 0) + { + if (width == 1) + { + u = (INT64)(startu); + v = (INT64)(startv); + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + val = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; + if (val != TRANSPARENTPIXEL) + *dest = val; + } + else + { + double left = width; + iz += ds_sz.x * left; + uz += ds_su.x * left; + vz += ds_sv.x * left; + + double endz = 1.f/iz; + double endu = uz*endz; + double endv = vz*endz; + left = 1.f/left; + UINT32 stepu = (INT64)((endu - startu) * left); + UINT32 stepv = (INT64)((endv - startv) * left); + u = (INT64)(startu) + viewx; + v = (INT64)(startv) + viewy; + + for (; width != 0; width--) + { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + val = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; + if (val != TRANSPARENTPIXEL) + *dest = val; + dest++; + u += stepu; + v += stepv; + } + } + } +#endif +} #endif // ESLOPE /** \brief The R_DrawSplat_8 function diff --git a/src/r_plane.c b/src/r_plane.c index 6aae1e250..406a38d7b 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -836,7 +836,11 @@ void R_DrawSinglePlane(visplane_t *pl) else light = (pl->lightlevel >> LIGHTSEGSHIFT); #ifndef NOWATER - if (pl->ffloor->flags & FF_RIPPLE) + if (pl->ffloor->flags & FF_RIPPLE +#ifdef ESLOPE + && !pl->slope +#endif + ) { INT32 top, bottom; @@ -1024,6 +1028,8 @@ void R_DrawSinglePlane(visplane_t *pl) if (spanfunc == R_DrawTranslucentSpan_8) spanfunc = R_DrawTiltedTranslucentSpan_8; + else if (spanfunc == splatfunc) + spanfunc = R_DrawTiltedSplat_8; else spanfunc = R_DrawTiltedSpan_8; From 049bbce5c00854c1446c28e6b2d15c04eaa19cdd Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Mon, 3 Aug 2015 17:37:50 -0500 Subject: [PATCH 81/91] Add data to slope struct that will be useful later --- src/r_defs.h | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/r_defs.h b/src/r_defs.h index 9f35af7e5..6f9127ee9 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -233,11 +233,19 @@ typedef struct secplane_t fixed_t a, b, c, d, ic; } secplane_t; -// Kalaron Slopes +// Slopes #ifdef ESLOPE +typedef enum { + SL_NOPHYSICS = 1, // Don't do momentum adjustment with this slope + SL_NODYNAMIC = 1<<1, // Slope will never need to move during the level, so don't fuss with recalculating it + SL_ANCHORVERTEX = 1<<2, // Slope is using a Slope Vertex Thing to anchor its position + SL_VERTEXSLOPE = 1<<3, // Slope is built from three Slope Vertex Things +} slopeflags_t; typedef struct pslope_s { + UINT16 id; // The number of the slope, mostly used for netgame syncing purposes + // --- Information used in clipping/projection --- // Origin vector for the plane vector3_t o; @@ -262,7 +270,10 @@ typedef struct pslope_s struct line_s *sourceline; // The line that generated the slope fixed_t extent; // Distance value used for recalculating zdelta - UINT8 refpos; // 1=front floor 2=front ceiling 3=back floor 4=back ceiling (used for dynamic sloping) 0=disabled + UINT8 refpos; // 1=front floor 2=front ceiling 3=back floor 4=back ceiling (used for dynamic sloping) + + UINT8 flags; // Slope options + struct mobj_s **vertices; // List should be three long for slopes made by vertex things, or one long for slopes using one vertex thing to anchor struct pslope_s *next; // Make a linked list of dynamic slopes, for easy reference later } pslope_t; From 51284c01d8cb84fe889cb8fc36bc132054bd1e6a Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Mon, 3 Aug 2015 17:39:33 -0500 Subject: [PATCH 82/91] Start using slope flags/id in creation process --- src/p_slopes.c | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/src/p_slopes.c b/src/p_slopes.c index d0b202168..77b0347d9 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -40,7 +40,8 @@ #ifdef ESLOPE -static pslope_t *dynslopes = NULL; +static pslope_t *slopelist = NULL; +static UINT16 slopecount = 0; // Calculate line normal void P_CalculateSlopeNormal(pslope_t *slope) { @@ -53,9 +54,12 @@ void P_CalculateSlopeNormal(pslope_t *slope) { void P_RunDynamicSlopes(void) { pslope_t *slope; - for (slope = dynslopes; slope; slope = slope->next) { + for (slope = slopelist; slope; slope = slope->next) { fixed_t zdelta; + if (slope->flags & SL_NODYNAMIC) + continue; + switch(slope->refpos) { case 1: // front floor zdelta = slope->sourceline->backsector->floorheight - slope->sourceline->frontsector->floorheight; @@ -92,7 +96,7 @@ void P_RunDynamicSlopes(void) { // Alocates and fill the contents of a slope structure. // static pslope_t *P_MakeSlope(const vector3_t *o, const vector2_t *d, - const fixed_t zdelta, boolean dynamic) + const fixed_t zdelta, UINT8 flags) { pslope_t *ret = Z_Malloc(sizeof(pslope_t), PU_LEVEL, NULL); memset(ret, 0, sizeof(*ret)); @@ -106,10 +110,14 @@ static pslope_t *P_MakeSlope(const vector3_t *o, const vector2_t *d, ret->zdelta = zdelta; - if (dynamic) { // Add to the dynamic slopes list - ret->next = dynslopes; - dynslopes = ret; - } + ret->flags = flags; + + // Add to the slope list + ret->next = slopelist; + slopelist = ret; + + slopecount++; + ret->id = slopecount; return ret; } @@ -179,6 +187,14 @@ void P_SpawnSlope_Line(int linenum) boolean frontceil = (special == 701 || special == 702 || special == 713); boolean backceil = (special == 711 || special == 712 || special == 703); + UINT8 flags = 0; // Slope flags + if (line->flags & ML_NOSONIC) + flags |= SL_NOPHYSICS; + if (line->flags & ML_NOTAILS) + flags |= SL_NODYNAMIC; + if (line->flags & ML_NOKNUX) + flags |= SL_ANCHORVERTEX; + if(!frontfloor && !backfloor && !frontceil && !backceil) { CONS_Printf("P_SpawnSlope_Line called with non-slope line special.\n"); @@ -235,7 +251,7 @@ void P_SpawnSlope_Line(int linenum) // In P_SpawnSlopeLine the origin is the centerpoint of the sourcelinedef fslope = line->frontsector->f_slope = - P_MakeSlope(&point, &direction, dz, !(line->flags & ML_NOTAILS)); + P_MakeSlope(&point, &direction, dz, flags); // Set up some shit fslope->extent = extent; @@ -291,7 +307,7 @@ void P_SpawnSlope_Line(int linenum) dz = FixedDiv(origin.z - point.z, extent); cslope = line->frontsector->c_slope = - P_MakeSlope(&point, &direction, dz, !(line->flags & ML_NOTAILS)); + P_MakeSlope(&point, &direction, dz, flags); // Set up some shit cslope->extent = extent; @@ -356,7 +372,7 @@ void P_SpawnSlope_Line(int linenum) dz = FixedDiv(origin.z - point.z, extent); fslope = line->backsector->f_slope = - P_MakeSlope(&point, &direction, dz, !(line->flags & ML_NOTAILS)); + P_MakeSlope(&point, &direction, dz, flags); // Set up some shit fslope->extent = extent; @@ -398,7 +414,7 @@ void P_SpawnSlope_Line(int linenum) dz = FixedDiv(origin.z - point.z, extent); cslope = line->backsector->c_slope = - P_MakeSlope(&point, &direction, dz, !(line->flags & ML_NOTAILS)); + P_MakeSlope(&point, &direction, dz, flags); // Set up some shit cslope->extent = extent; @@ -730,7 +746,8 @@ void P_ResetDynamicSlopes(void) { boolean warned = false; #endif - dynslopes = NULL; + slopelist = NULL; + slopecount = 0; // We'll handle copy slopes later, after all the tag lists have been made. // Yes, this means copied slopes won't affect things' spawning heights. Too bad for you. From 14ea936f7478e1c5c6473d4e31f902fb5bba2378 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Mon, 3 Aug 2015 18:06:42 -0500 Subject: [PATCH 83/91] Sync mobj->standingslope in netgames --- src/p_saveg.c | 13 ++++++++++++- src/p_slopes.c | 12 ++++++++++++ src/p_slopes.h | 2 ++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/p_saveg.c b/src/p_saveg.c index eec3dbf3e..621abcb48 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -30,6 +30,9 @@ #include "r_sky.h" #include "p_polyobj.h" #include "lua_script.h" +#ifdef ESLOPE +#include "p_slopes.h" +#endif savedata_t savedata; UINT8 *save_p; @@ -921,7 +924,8 @@ typedef enum MD2_EXTVAL1 = 1<<5, MD2_EXTVAL2 = 1<<6, MD2_HNEXT = 1<<7, - MD2_HPREV = 1<<8 + MD2_HPREV = 1<<8, + MD2_SLOPE = 1<<9 } mobj_diff2_t; typedef enum @@ -1109,6 +1113,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) diff2 |= MD2_HNEXT; if (mobj->hprev) diff2 |= MD2_HPREV; + if (mobj->standingslope) + diff2 |= MD2_SLOPE; if (diff2 != 0) diff |= MD_MORE; @@ -1221,6 +1227,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) WRITEUINT32(save_p, mobj->hnext->mobjnum); if (diff2 & MD2_HPREV) WRITEUINT32(save_p, mobj->hprev->mobjnum); + if (diff2 & MD2_SLOPE) + WRITEUINT16(save_p, mobj->standingslope->id); WRITEUINT32(save_p, mobj->mobjnum); } @@ -2068,6 +2076,9 @@ static void LoadMobjThinker(actionf_p1 thinker) mobj->hnext = (mobj_t *)(size_t)READUINT32(save_p); if (diff2 & MD2_HPREV) mobj->hprev = (mobj_t *)(size_t)READUINT32(save_p); + if (diff2 & MD2_SLOPE) + mobj->standingslope = P_SlopeById(READUINT16(save_p)); + if (diff & MD_REDFLAG) { diff --git a/src/p_slopes.c b/src/p_slopes.c index 77b0347d9..316a953b8 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -484,6 +484,18 @@ void P_CopySectorSlope(line_t *line) line->special = 0; // Linedef was use to set slopes, it finished its job, so now make it a normal linedef } +// +// P_SlopeById +// +// Looks in the slope list for a slope with a specified ID. Mostly useful for netgame sync +// +pslope_t *P_SlopeById(UINT16 id) +{ + pslope_t *ret; + for (ret = slopelist; ret && ret->id != id; ret = ret->next); + return ret; +} + #ifdef SPRINGCLEAN #include "byteptr.h" diff --git a/src/p_slopes.h b/src/p_slopes.h index 52988c18f..e92198675 100644 --- a/src/p_slopes.h +++ b/src/p_slopes.h @@ -63,6 +63,8 @@ typedef enum // void P_CopySectorSlope(line_t *line); +pslope_t *P_SlopeById(UINT16 id); + // Returns the height of the sloped plane at (x, y) as a fixed_t fixed_t P_GetZAt(pslope_t *slope, fixed_t x, fixed_t y); From c7b6cd705f790a23bc8b81b84f1697e486f56283 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Mon, 3 Aug 2015 19:27:10 -0500 Subject: [PATCH 84/91] Separate P_LoadThings into two functions to make the next commit cleaner --- src/p_setup.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index c836d601c..3491669c7 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -850,7 +850,7 @@ void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum) // // P_LoadThings // -static void P_LoadThings(lumpnum_t lumpnum) +static void P_PrepareThings(lumpnum_t lumpnum) { size_t i; mapthing_t *mt; @@ -888,6 +888,15 @@ static void P_LoadThings(lumpnum_t lumpnum) } Z_Free(datastart); +} + +static void P_LoadThings(void) +{ + size_t i; + mapthing_t *mt; + + // Loading the things lump itself into memory is now handled in P_PrepareThings, above + mt = mapthings; numhuntemeralds = 0; for (i = 0; i < nummapthings; i++, mt++) @@ -2123,7 +2132,8 @@ void P_LoadThingsOnly(void) P_LevelInitStuff(); - P_LoadThings(lastloadedmaplumpnum + ML_THINGS); + P_PrepareThings(lastloadedmaplumpnum + ML_THINGS); + P_LoadThings(); P_SpawnSecretItems(true); } @@ -2540,11 +2550,13 @@ boolean P_SetupLevel(boolean skipprecip) P_MapStart(); + P_PrepareThings(lastloadedmaplumpnum + ML_THINGS); + #ifdef ESLOPE P_ResetDynamicSlopes(); #endif - P_LoadThings(lastloadedmaplumpnum + ML_THINGS); + P_LoadThings(); P_SpawnSecretItems(loademblems); From 1f5fc04d60be12f85c953730556ed68de3f002ec Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Mon, 3 Aug 2015 22:15:59 -0500 Subject: [PATCH 85/91] Add vertex slopes --- src/p_slopes.c | 158 +++++++++++++++++++++++++++++++++++++++++++++++++ src/r_defs.h | 2 +- 2 files changed, 159 insertions(+), 1 deletion(-) diff --git a/src/p_slopes.c b/src/p_slopes.c index 316a953b8..f14fc0f60 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -34,6 +34,7 @@ #include "z_zone.h" #include "p_spec.h" #include "p_slopes.h" +#include "p_setup.h" #include "r_main.h" #include "p_maputl.h" #include "w_wad.h" @@ -50,6 +51,65 @@ void P_CalculateSlopeNormal(pslope_t *slope) { slope->normal.y = -FixedMul(FINESINE(slope->zangle>>ANGLETOFINESHIFT), slope->d.y); } +// With a vertex slope that has its vertices set, configure relevant slope info +void P_ReconfigureVertexSlope(pslope_t *slope) +{ + vector3_t vec1, vec2; + + // Set slope normal + vec1.x = (slope->vertices[1]->x - slope->vertices[0]->x) << FRACBITS; + vec1.y = (slope->vertices[1]->y - slope->vertices[0]->y) << FRACBITS; + vec1.z = (slope->vertices[1]->z - slope->vertices[0]->z) << FRACBITS; + + vec2.x = (slope->vertices[2]->x - slope->vertices[0]->x) << FRACBITS; + vec2.y = (slope->vertices[2]->y - slope->vertices[0]->y) << FRACBITS; + vec2.z = (slope->vertices[2]->z - slope->vertices[0]->z) << FRACBITS; + + // ugggggggh fixed-point maaaaaaath + slope->extent = max( + max(max(abs(vec1.x), abs(vec1.y)), abs(vec1.z)), + max(max(abs(vec2.x), abs(vec2.y)), abs(vec2.z)) + ) >> (FRACBITS+5); + vec1.x /= slope->extent; + vec1.y /= slope->extent; + vec1.z /= slope->extent; + vec2.x /= slope->extent; + vec2.y /= slope->extent; + vec2.z /= slope->extent; + + FV3_Cross(&vec1, &vec2, &slope->normal); + + slope->extent = R_PointToDist2(0, 0, R_PointToDist2(0, 0, slope->normal.x, slope->normal.y), slope->normal.z); + if (slope->normal.z < 0) + slope->extent = -slope->extent; + + slope->normal.x = FixedDiv(slope->normal.x, slope->extent); + slope->normal.y = FixedDiv(slope->normal.y, slope->extent); + slope->normal.z = FixedDiv(slope->normal.z, slope->extent); + + // Set origin + slope->o.x = slope->vertices[0]->x << FRACBITS; + slope->o.y = slope->vertices[0]->y << FRACBITS; + slope->o.z = slope->vertices[0]->z << FRACBITS; + + if (slope->normal.x == 0 && slope->normal.y == 0) { // Set some defaults for a non-sloped "slope" + slope->zangle = slope->xydirection = 0; + slope->zdelta = slope->d.x = slope->d.y = 0; + } else { + // Get direction vector + slope->extent = R_PointToDist2(0, 0, slope->normal.x, slope->normal.y); + slope->d.x = -FixedDiv(slope->normal.x, slope->extent); + slope->d.y = -FixedDiv(slope->normal.y, slope->extent); + + // Z delta + slope->zdelta = FixedDiv(slope->extent, slope->normal.z); + + // Get angles + slope->xydirection = R_PointToAngle2(0, 0, slope->d.x, slope->d.y)+ANGLE_180; + slope->zangle = -R_PointToAngle2(0, 0, FRACUNIT, slope->zdelta); + } +} + // Recalculate dynamic slopes void P_RunDynamicSlopes(void) { pslope_t *slope; @@ -77,6 +137,24 @@ void P_RunDynamicSlopes(void) { zdelta = slope->sourceline->frontsector->ceilingheight - slope->sourceline->backsector->ceilingheight; slope->o.z = slope->sourceline->backsector->ceilingheight; break; + case 5: // vertices + { + mapthing_t *mt; + size_t i, l; + line_t *line; + + for (i = 0; i < 3; i++) { + mt = slope->vertices[i]; + l = P_FindSpecialLineFromTag(799, mt->angle, -1); + if (l != -1) { + line = &lines[l]; + mt->z = line->frontsector->floorheight >> FRACBITS; + } + } + + P_ReconfigureVertexSlope(slope); + } + continue; // TODO default: I_Error("P_RunDynamicSlopes: slope has invalid type!"); @@ -456,6 +534,68 @@ void P_SpawnSlope_Line(int linenum) return; } +// +// P_NewVertexSlope +// +// Creates a new slope from three vertices with the specified IDs +// +pslope_t *P_NewVertexSlope(INT16 tag1, INT16 tag2, INT16 tag3, UINT8 flags) +{ + size_t i; + mapthing_t *mt = mapthings; + + pslope_t *ret = Z_Malloc(sizeof(pslope_t), PU_LEVEL, NULL); + memset(ret, 0, sizeof(*ret)); + + // Start by setting flags + ret->flags = flags; + + // Now set up the vertex list + ret->vertices = Z_Malloc(3*sizeof(mapthing_t), PU_LEVEL, NULL); + memset(ret->vertices, 0, 3*sizeof(mapthing_t)); + + // And... look for the vertices in question. + for (i = 0; i < nummapthings; i++, mt++) { + if (mt->type != 750) // Haha, I'm hijacking the old Chaos Spawn thingtype for something! + continue; + + if (!ret->vertices[0] && mt->angle == tag1) + ret->vertices[0] = mt; + else if (!ret->vertices[1] && mt->angle == tag2) + ret->vertices[1] = mt; + else if (!ret->vertices[2] && mt->angle == tag3) + ret->vertices[2] = mt; + } + + if (!ret->vertices[0]) + CONS_Printf("PANIC 0\n"); + if (!ret->vertices[1]) + CONS_Printf("PANIC 1\n"); + if (!ret->vertices[2]) + CONS_Printf("PANIC 2\n"); + + // Now set heights for each vertex, because they haven't been set yet + for (i = 0; i < 3; i++) { + mt = ret->vertices[i]; + if (mt->extrainfo) + mt->z = mt->options; + else + mt->z = (R_PointInSubsector(mt->x << FRACBITS, mt->y << FRACBITS)->sector->floorheight >> FRACBITS) + (mt->options >> ZSHIFT); + } + + P_ReconfigureVertexSlope(ret); + ret->refpos = 5; + + // Add to the slope list + ret->next = slopelist; + slopelist = ret; + + slopecount++; + ret->id = slopecount; + + return ret; +} + // @@ -812,6 +952,24 @@ void P_ResetDynamicSlopes(void) { P_SpawnSlope_Line(i); break; + case 704: + { + UINT8 flags = SL_VERTEXSLOPE; + if (lines[i].flags & ML_NOSONIC) + flags |= SL_NOPHYSICS; + if (!(lines[i].flags & ML_NOTAILS)) + flags |= SL_NODYNAMIC; + + if (lines[i].flags & ML_NOKNUX) + lines[i].frontsector->f_slope = P_NewVertexSlope(lines[i].tag, sides[lines[i].sidenum[0]].textureoffset >> FRACBITS, + sides[lines[i].sidenum[0]].rowoffset >> FRACBITS, flags); + else + lines[i].frontsector->f_slope = P_NewVertexSlope(lines[i].tag, lines[i].tag, lines[i].tag, flags); + + lines[i].frontsector->hasslope = true; + } + break; + default: break; } diff --git a/src/r_defs.h b/src/r_defs.h index 6f9127ee9..f18410fe8 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -273,7 +273,7 @@ typedef struct pslope_s UINT8 refpos; // 1=front floor 2=front ceiling 3=back floor 4=back ceiling (used for dynamic sloping) UINT8 flags; // Slope options - struct mobj_s **vertices; // List should be three long for slopes made by vertex things, or one long for slopes using one vertex thing to anchor + mapthing_t **vertices; // List should be three long for slopes made by vertex things, or one long for slopes using one vertex thing to anchor struct pslope_s *next; // Make a linked list of dynamic slopes, for easy reference later } pslope_t; From 50b5e978cc8fcf2ce8f05a92bca14d48d006be02 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Mon, 3 Aug 2015 23:09:50 -0500 Subject: [PATCH 86/91] Support ceiling/backsector vertex slopes --- src/p_slopes.c | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/src/p_slopes.c b/src/p_slopes.c index f14fc0f60..baec5e1ef 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -953,20 +953,47 @@ void P_ResetDynamicSlopes(void) { break; case 704: + case 705: + case 714: + case 715: { + pslope_t **slopetoset; + size_t which = lines[i].special; + UINT8 flags = SL_VERTEXSLOPE; if (lines[i].flags & ML_NOSONIC) flags |= SL_NOPHYSICS; if (!(lines[i].flags & ML_NOTAILS)) flags |= SL_NODYNAMIC; - if (lines[i].flags & ML_NOKNUX) - lines[i].frontsector->f_slope = P_NewVertexSlope(lines[i].tag, sides[lines[i].sidenum[0]].textureoffset >> FRACBITS, - sides[lines[i].sidenum[0]].rowoffset >> FRACBITS, flags); - else - lines[i].frontsector->f_slope = P_NewVertexSlope(lines[i].tag, lines[i].tag, lines[i].tag, flags); + if (which == 704) + { + slopetoset = &lines[i].frontsector->f_slope; + which = 0; + } + else if (which == 705) + { + slopetoset = &lines[i].frontsector->c_slope; + which = 0; + } + else if (which == 714) + { + slopetoset = &lines[i].backsector->f_slope; + which = 1; + } + else // 715 + { + slopetoset = &lines[i].backsector->c_slope; + which = 1; + } - lines[i].frontsector->hasslope = true; + if (lines[i].flags & ML_NOKNUX) + *slopetoset = P_NewVertexSlope(lines[i].tag, sides[lines[i].sidenum[which]].textureoffset >> FRACBITS, + sides[lines[i].sidenum[which]].rowoffset >> FRACBITS, flags); + else + *slopetoset = P_NewVertexSlope(lines[i].tag, lines[i].tag, lines[i].tag, flags); + + sides[lines[i].sidenum[which]].sector->hasslope = true; } break; From d5884a69573f9bdadb60cc78efb8b672eabbee9f Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Fri, 21 Aug 2015 18:23:37 -0500 Subject: [PATCH 87/91] Add Chee to credits (she helped port important drawing code!) --- src/f_finale.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/f_finale.c b/src/f_finale.c index f541995d4..a85fd11cb 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -982,6 +982,7 @@ static const char *credits[] = { "", "\1Programming", "\1Assistance", + "\"chi.miru\"", // Red's secret weapon, the REAL reason slopes exist (also helped port drawing code from ZDoom) "Andrew \"orospakr\" Clunis", "Gregor \"Oogaland\" Dick", "Julio \"Chaos Zero 64\" Guir", From f3d40c34a0ba498bf0e215ef46100e9bc012fec2 Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Fri, 21 Aug 2015 20:46:41 -0400 Subject: [PATCH 88/91] git warning: trailing whitespace --- src/hardware/hw_md2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index de648f1b9..67720231c 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -926,7 +926,7 @@ void HWR_InitMD2(void) CONS_Printf("MD2 for sprite PLAY detected in md2.dat, use a player skin instead!\n"); continue; } - + for (i = 0; i < NUMSPRITES; i++) { if (stricmp(name, sprnames[i]) == 0) From c64e4d58b70addea6e2f5f0ea6a0fe2f8e1a91d4 Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Fri, 21 Aug 2015 20:47:00 -0400 Subject: [PATCH 89/91] git warning: new blank line at EOF --- src/p_slopes.c | 1 - src/p_slopes.h | 1 - 2 files changed, 2 deletions(-) diff --git a/src/p_slopes.c b/src/p_slopes.c index baec5e1ef..bb150944e 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -1133,4 +1133,3 @@ void P_ButteredSlope(mobj_t *mo) // EOF #endif // #ifdef ESLOPE - diff --git a/src/p_slopes.h b/src/p_slopes.h index e92198675..8d82632ff 100644 --- a/src/p_slopes.h +++ b/src/p_slopes.h @@ -78,4 +78,3 @@ void P_ButteredSlope(mobj_t *mo); // EOF #endif // #ifdef ESLOPE - From 96c71c68c80ebc63aec3221edb1fbd67d3b5b2ac Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Fri, 21 Aug 2015 21:27:20 -0400 Subject: [PATCH 90/91] remove NEED_FIXED_VECTOR and fix angelchk testcase --- src/doomdef.h | 4 ---- src/m_fixed.c | 4 ---- src/m_fixed.h | 5 ----- src/tables.c | 5 ----- src/tables.h | 5 ----- tools/anglechk.c | 7 +++++++ 6 files changed, 7 insertions(+), 23 deletions(-) diff --git a/src/doomdef.h b/src/doomdef.h index bfa5ee0ce..92570f623 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -440,12 +440,8 @@ extern const char *compdate, *comptime, *comprevision; //#define SLOPENESS /// Kalaron/Eternity Engine slope code (SRB2CB ported) -/// Depends on NEED_FIXED_VECTORS? for a few functions. #define ESLOPE -/// Fixed and float point types -//#define NEED_FIXED_VECTOR - /// Delete file while the game is running. /// \note EXTREMELY buggy, tends to crash game. //#define DELFILE diff --git a/src/m_fixed.c b/src/m_fixed.c index 739265aa2..53974936e 100644 --- a/src/m_fixed.c +++ b/src/m_fixed.c @@ -119,8 +119,6 @@ fixed_t FixedHypot(fixed_t x, fixed_t y) return FixedMul(ax, yx1); // |x|*((1 + (x/y)^2)^1/2) } -#if 1 //#ifdef NEED_FIXED_VECTOR - vector2_t *FV2_Load(vector2_t *vec, fixed_t x, fixed_t y) { vec->x = x; @@ -863,8 +861,6 @@ void FM_Scale(matrix_t *dest, fixed_t x, fixed_t y, fixed_t z) #undef M } -#endif - #ifdef M_TESTCASE //#define MULDIV_TEST #define SQRT_TEST diff --git a/src/m_fixed.h b/src/m_fixed.h index 53962269b..cd22d483f 100644 --- a/src/m_fixed.h +++ b/src/m_fixed.h @@ -357,9 +357,6 @@ FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedRound(fixed_t x) return INT32_MAX; } - -#if 1//#ifdef NEED_FIXED_VECTOR - typedef struct { fixed_t x; @@ -438,6 +435,4 @@ void FM_MultMatrix(matrix_t *dest, const matrix_t *multme); void FM_Translate(matrix_t *dest, fixed_t x, fixed_t y, fixed_t z); void FM_Scale(matrix_t *dest, fixed_t x, fixed_t y, fixed_t z); -#endif // defined NEED_FIXED_VECTOR - #endif //m_fixed.h diff --git a/src/tables.c b/src/tables.c index 3ee2685c8..83e952832 100644 --- a/src/tables.c +++ b/src/tables.c @@ -2225,9 +2225,6 @@ angle_t tantoangle[2049] = 536870912 }; - -#if 1 //#ifdef NEED_FIXED_VECTOR - static angle_t fineacon[65536*2] = { ANGLE_MAX, 2143707442, 2142143280, 2140943052, 2139931208, 2139039753, 2138233813, 2137492672, 2136802831, 2136154917, 2135542102, 2134959233, 2134402306, 2133868139, 2133354148, 2132858208, 2132378539, 2131913638, 2131462220, 2131023174, 2130595537, 2130178462, 2129771202, 2129373097, 2128983555, 2128602046, 2128228092, 2127861261, 2127501162, 2127147436, 2126799757, 2126457825, @@ -10706,5 +10703,3 @@ void FM_Rotate(matrix_t *dest, angle_t angle, fixed_t x, fixed_t y, fixed_t z) M(3, 3) = FRACUNIT; #undef M } - -#endif diff --git a/src/tables.h b/src/tables.h index b1de1a428..d7ec589da 100644 --- a/src/tables.h +++ b/src/tables.h @@ -96,9 +96,6 @@ FUNCMATH angle_t FixedAngle(fixed_t fa); // and with a factor, with +factor for (fa/factor) and -factor for (fa*factor) FUNCMATH angle_t FixedAngleC(fixed_t fa, fixed_t factor); - -#if 1 //#ifdef NEED_FIXED_VECTOR - /// The FixedAcos function FUNCMATH angle_t FixedAcos(fixed_t x); @@ -112,8 +109,6 @@ void FV3_Rotate(vector3_t *rotVec, const vector3_t *axisVec, const angle_t angle /// Fixed Point Matrix functions void FM_Rotate(matrix_t *dest, angle_t angle, fixed_t x, fixed_t y, fixed_t z); -#endif // defined NEED_FIXED_VECTOR - // The table values in tables.c are calculated with this many fractional bits. #define FINE_FRACBITS 16 diff --git a/tools/anglechk.c b/tools/anglechk.c index bb9c4d9ea..4a67069bf 100644 --- a/tools/anglechk.c +++ b/tools/anglechk.c @@ -351,6 +351,13 @@ int main(int argc, char** argv) return 0; } +static void *cpu_cpy(void *dest, const void *src, size_t n) +{ + return memcpy(dest, src, n); +} + +void *(*M_Memcpy)(void* dest, const void* src, size_t n) = cpu_cpy; + void I_Error(const char *error, ...) { (void)error; From 9155fd6c14eb8ab09bbfc7bc3892eb2736c28099 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Mon, 24 Aug 2015 22:09:19 -0500 Subject: [PATCH 91/91] Fix unexpected behavior with colormaps in sloped sectors To be specific: when a sector had a sloped ceiling and a colormap was placed above it, the colormap wouldn't fill anything above where the ceiling height is at the sector's midpoint. This is fixed. --- src/r_bsp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/r_bsp.c b/src/r_bsp.c index 5474a4345..7d584a976 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -1218,6 +1218,7 @@ void R_Prep3DFloors(sector_t *sector) heighttest = sector->c_slope ? P_GetZAt(sector->c_slope, sector->soundorg.x, sector->soundorg.y) : sector->ceilingheight; sector->lightlist[0].height = heighttest + 1; + sector->lightlist[0].slope = sector->c_slope; #else sector->lightlist[0].height = sector->ceilingheight + 1; #endif