From c4d5afdd8093a8b7bdecc694d83d29e874d0a154 Mon Sep 17 00:00:00 2001 From: Arthur Date: Sat, 15 Dec 2018 08:46:08 -0500 Subject: [PATCH 01/74] New fixed math functions - ClosestPointOnVector, and Strength. Normal also returns length now, since it is free. --- src/m_fixed.c | 239 +++++++++++++++++++++++++++++--------------------- src/m_fixed.h | 4 +- 2 files changed, 140 insertions(+), 103 deletions(-) diff --git a/src/m_fixed.c b/src/m_fixed.c index d45bb70bf..5e7896739 100644 --- a/src/m_fixed.c +++ b/src/m_fixed.c @@ -56,7 +56,7 @@ fixed_t FixedDiv2(fixed_t a, fixed_t b) if (b == 0) I_Error("FixedDiv: divide by zero"); - ret = (((INT64)a * FRACUNIT) ) / b; + ret = (((INT64)a * FRACUNIT)) / b; if ((ret > INT32_MAX) || (ret < INT32_MIN)) I_Error("FixedDiv: divide by zero"); @@ -117,7 +117,7 @@ fixed_t FixedHypot(fixed_t x, fixed_t y) yx = FixedDiv(y, x); // (x/y) } yx2 = FixedMul(yx, yx); // (x/y)^2 - yx1 = FixedSqrt(1*FRACUNIT + yx2); // (1 + (x/y)^2)^1/2 + yx1 = FixedSqrt(1 * FRACUNIT + yx2); // (1 + (x/y)^2)^1/2 return FixedMul(ax, yx1); // |x|*((1 + (x/y)^2)^1/2) } @@ -191,8 +191,8 @@ vector2_t *FV2_Divide(vector2_t *a_i, fixed_t a_c) // Vector Complex Math vector2_t *FV2_Midpoint(const vector2_t *a_1, const vector2_t *a_2, vector2_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->x = FixedDiv(a_2->x - a_1->x, 2 * FRACUNIT); + a_o->y = FixedDiv(a_2->y - a_1->y, 2 * FRACUNIT); a_o->x = a_1->x + a_o->x; a_o->y = a_1->y + a_o->y; return a_o; @@ -200,16 +200,16 @@ vector2_t *FV2_Midpoint(const vector2_t *a_1, const vector2_t *a_2, vector2_t *a fixed_t FV2_Distance(const vector2_t *p1, const vector2_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); - return FixedSqrt(xs+ys); + fixed_t xs = FixedMul(p2->x - p1->x, p2->x - p1->x); + fixed_t ys = FixedMul(p2->y - p1->y, p2->y - p1->y); + return FixedSqrt(xs + ys); } fixed_t FV2_Magnitude(const vector2_t *a_normal) { - fixed_t xs = FixedMul(a_normal->x,a_normal->x); - fixed_t ys = FixedMul(a_normal->y,a_normal->y); - return FixedSqrt(xs+ys); + fixed_t xs = FixedMul(a_normal->x, a_normal->x); + fixed_t ys = FixedMul(a_normal->y, a_normal->y); + return FixedSqrt(xs + ys); } // Also returns the magnitude @@ -240,7 +240,7 @@ vector2_t *FV2_Negate(vector2_t *a_1) boolean FV2_Equal(const vector2_t *a_1, const vector2_t *a_2) { - fixed_t Epsilon = FRACUNIT/FRACUNIT; + fixed_t Epsilon = FRACUNIT / FRACUNIT; if ((abs(a_2->x - a_1->x) > Epsilon) || (abs(a_2->y - a_1->y) > Epsilon)) @@ -261,7 +261,7 @@ fixed_t FV2_Dot(const vector2_t *a_1, const vector2_t *a_2) // // Given two points, create a vector between them. // -vector2_t *FV2_Point2Vec (const vector2_t *point1, const vector2_t *point2, vector2_t *a_o) +vector2_t *FV2_Point2Vec(const vector2_t *point1, const vector2_t *point2, vector2_t *a_o) { a_o->x = point1->x - point2->x; a_o->y = point1->y - point2->y; @@ -344,9 +344,9 @@ vector3_t *FV3_Divide(vector3_t *a_i, fixed_t a_c) // Vector Complex Math vector3_t *FV3_Midpoint(const vector3_t *a_1, const vector3_t *a_2, vector3_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 = 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; @@ -355,18 +355,18 @@ vector3_t *FV3_Midpoint(const vector3_t *a_1, const vector3_t *a_2, vector3_t *a fixed_t FV3_Distance(const vector3_t *p1, const vector3_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); + 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); } fixed_t FV3_Magnitude(const vector3_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); + 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); } // Also returns the magnitude @@ -399,7 +399,7 @@ vector3_t *FV3_Negate(vector3_t *a_1) boolean FV3_Equal(const vector3_t *a_1, const vector3_t *a_2) { - fixed_t Epsilon = FRACUNIT/FRACUNIT; + fixed_t Epsilon = FRACUNIT / FRACUNIT; if ((abs(a_2->x - a_1->x) > Epsilon) || (abs(a_2->y - a_1->y) > Epsilon) || @@ -458,6 +458,20 @@ vector3_t *FV3_ClosestPointOnLine(const vector3_t *Line, const vector3_t *p, vec return FV3_AddEx(&Line[0], &V, out); } +// +// ClosestPointOnVector +// +// Similar to ClosestPointOnLine, but uses a vector instead of two points. +// +void FV3_ClosestPointOnVector(const vector3_t *dir, const vector3_t *p, vector3_t *out) +{ + fixed_t t = FV3_Dot(dir, p); + + // Return the point on the line closest + FV3_MulEx(dir, t, out); + return; +} + // // ClosestPointOnTriangle // @@ -465,7 +479,7 @@ vector3_t *FV3_ClosestPointOnLine(const vector3_t *Line, const vector3_t *p, vec // the closest point on the edge of // the triangle is returned. // -void FV3_ClosestPointOnTriangle (const vector3_t *tri, const vector3_t *point, vector3_t *result) +void FV3_ClosestPointOnTriangle(const vector3_t *tri, const vector3_t *point, vector3_t *result) { UINT8 i; fixed_t dist, closestdist; @@ -506,7 +520,7 @@ void FV3_ClosestPointOnTriangle (const vector3_t *tri, const vector3_t *point, v // // Given two points, create a vector between them. // -vector3_t *FV3_Point2Vec (const vector3_t *point1, const vector3_t *point2, vector3_t *a_o) +vector3_t *FV3_Point2Vec(const vector3_t *point1, const vector3_t *point2, vector3_t *a_o) { a_o->x = point1->x - point2->x; a_o->y = point1->y - point2->y; @@ -519,7 +533,7 @@ vector3_t *FV3_Point2Vec (const vector3_t *point1, const vector3_t *point2, vect // // Calculates the normal of a polygon. // -void FV3_Normal (const vector3_t *a_triangle, vector3_t *a_normal) +fixed_t FV3_Normal(const vector3_t *a_triangle, vector3_t *a_normal) { vector3_t a_1; vector3_t a_2; @@ -529,7 +543,28 @@ void FV3_Normal (const vector3_t *a_triangle, vector3_t *a_normal) FV3_Cross(&a_1, &a_2, a_normal); - FV3_NormalizeEx(a_normal, a_normal); + return FV3_NormalizeEx(a_normal, a_normal); +} + +// +// Strength +// +// Measures the 'strength' of a vector in a particular direction. +// +fixed_t FV3_Strength(const vector3_t *a_1, const vector3_t *dir) +{ + vector3_t normal; + fixed_t dist = FV3_NormalizeEx(a_1, &normal); + fixed_t dot = FV3_Dot(&normal, dir); + + FV3_ClosestPointOnVector(dir, a_1, &normal); + + dist = FV3_Magnitude(&normal); + + if (dot < 0) // Not facing same direction, so negate result. + dist = -dist; + + return dist; } // @@ -550,11 +585,11 @@ boolean FV3_IntersectedPlane(const vector3_t *a_triangle, const vector3_t *a_lin *originDistance = FV3_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; + 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; + 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) @@ -575,8 +610,8 @@ boolean FV3_IntersectedPlane(const vector3_t *a_triangle, const vector3_t *a_lin fixed_t FV3_PlaneIntersection(const vector3_t *pOrigin, const vector3_t *pNormal, const vector3_t *rOrigin, const vector3_t *rVector) { fixed_t d = -(FV3_Dot(pNormal, pOrigin)); - fixed_t number = FV3_Dot(pNormal,rOrigin) + d; - fixed_t denom = FV3_Dot(pNormal,rVector); + fixed_t number = FV3_Dot(pNormal, rOrigin) + d; + fixed_t denom = FV3_Dot(pNormal, rVector); return -FixedDiv(number, denom); } @@ -597,11 +632,11 @@ fixed_t FV3_IntersectRaySphere(const vector3_t *rO, const vector3_t *rV, const v c = FV3_Magnitude(&Q); v = FV3_Dot(&Q, rV); - d = FixedMul(sR, sR) - (FixedMul(c,c) - FixedMul(v,v)); + d = FixedMul(sR, sR) - (FixedMul(c, c) - FixedMul(v, v)); // If there was no intersection, return -1 - if (d < 0*FRACUNIT) - return (-1*FRACUNIT); + if (d < 0 * FRACUNIT) + return (-1 * FRACUNIT); // Return the distance to the [first] intersecting point return (v - FixedSqrt(d)); @@ -629,9 +664,9 @@ vector3_t *FV3_IntersectionPoint(const vector3_t *vNormal, const vector3_t *vLin // 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); + 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). @@ -643,7 +678,7 @@ vector3_t *FV3_IntersectionPoint(const vector3_t *vNormal, const vector3_t *vLin // 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 + if (Denominator == 0 * FRACUNIT) // Check so we don't divide by zero { ReturnVec->x = vLine[0].x; ReturnVec->y = vLine[0].y; @@ -686,8 +721,8 @@ vector3_t *FV3_IntersectionPoint(const vector3_t *vNormal, const vector3_t *vLin // UINT8 FV3_PointOnLineSide(const vector3_t *point, const vector3_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)); + 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 (UINT8)(s1 - s2 < 0); } @@ -752,7 +787,7 @@ void FM_CreateObjectMatrix(matrix_t *matrix, fixed_t x, fixed_t y, fixed_t z, fi matrix->m[0] = upcross.x; matrix->m[1] = upcross.y; matrix->m[2] = upcross.z; - matrix->m[3] = 0*FRACUNIT; + matrix->m[3] = 0 * FRACUNIT; matrix->m[4] = upx; matrix->m[5] = upy; @@ -764,9 +799,9 @@ void FM_CreateObjectMatrix(matrix_t *matrix, fixed_t x, fixed_t y, fixed_t z, fi 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[12] = x - FixedMul(upx, radius); + matrix->m[13] = y - FixedMul(upy, radius); + matrix->m[14] = z - FixedMul(upz, radius); matrix->m[15] = FRACUNIT; } @@ -778,20 +813,20 @@ void FM_CreateObjectMatrix(matrix_t *matrix, fixed_t x, fixed_t y, fixed_t z, fi void FM_MultMatrixVec3(const matrix_t *matrix, const vector3_t *vec, vector3_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->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->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); + 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 } @@ -811,7 +846,7 @@ void FM_MultMatrix(matrix_t *dest, const matrix_t *multme) 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)); + 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(matrix_t)); @@ -869,8 +904,8 @@ void FM_Scale(matrix_t *dest, fixed_t x, fixed_t y, fixed_t z) static inline void M_print(INT64 a) { - const fixed_t w = (a>>FRACBITS); - fixed_t f = a%FRACUNIT; + const fixed_t w = (a >> FRACBITS); + fixed_t f = a % FRACUNIT; fixed_t d = FRACUNIT; if (f == 0) @@ -878,7 +913,7 @@ static inline void M_print(INT64 a) printf("%d", (fixed_t)w); return; } - else while (f != 1 && f/2 == f>>1) + else while (f != 1 && f / 2 == f >> 1) { d /= 2; f /= 2; @@ -892,7 +927,7 @@ static inline void M_print(INT64 a) FUNCMATH FUNCINLINE static inline fixed_t FixedMulC(fixed_t a, fixed_t b) { - return (fixed_t)((((INT64)a * b) ) / FRACUNIT); + return (fixed_t)((((INT64)a * b)) / FRACUNIT); } FUNCMATH FUNCINLINE static inline fixed_t FixedDivC2(fixed_t a, fixed_t b) @@ -902,7 +937,7 @@ FUNCMATH FUNCINLINE static inline fixed_t FixedDivC2(fixed_t a, fixed_t b) if (b == 0) I_Error("FixedDiv: divide by zero"); - ret = (((INT64)a * FRACUNIT) ) / b; + ret = (((INT64)a * FRACUNIT)) / b; if ((ret > INT32_MAX) || (ret < INT32_MIN)) I_Error("FixedDiv: divide by zero"); @@ -911,7 +946,7 @@ FUNCMATH FUNCINLINE static inline fixed_t FixedDivC2(fixed_t a, fixed_t b) FUNCMATH FUNCINLINE static inline fixed_t FixedDivC(fixed_t a, fixed_t b) { - if ((abs(a) >> (FRACBITS-2)) >= abs(b)) + if ((abs(a) >> (FRACBITS - 2)) >= abs(b)) return (a^b) < 0 ? INT32_MIN : INT32_MAX; return FixedDivC2(a, b); @@ -938,43 +973,43 @@ int main(int argc, char** argv) #ifdef MULDIV_TEST for (a = 1; a <= INT32_MAX; a += FRACUNIT) - for (b = 0; b <= INT32_MAX; b += FRACUNIT) - { - c = FixedMul(a, b); - d = FixedMulC(a, b); - if (c != d) + for (b = 0; b <= INT32_MAX; b += FRACUNIT) { - printf("("); - M_print(a); - printf(") * ("); - M_print(b); - printf(") = ("); - M_print(c); - printf(") != ("); - M_print(d); - printf(") \n"); - n--; - printf("%d != %d\n", c, d); + c = FixedMul(a, b); + d = FixedMulC(a, b); + if (c != d) + { + printf("("); + M_print(a); + printf(") * ("); + M_print(b); + printf(") = ("); + M_print(c); + printf(") != ("); + M_print(d); + printf(") \n"); + n--; + printf("%d != %d\n", c, d); + } + c = FixedDiv(a, b); + d = FixedDivC(a, b); + if (c != d) + { + printf("("); + M_print(a); + printf(") / ("); + M_print(b); + printf(") = ("); + M_print(c); + printf(") != ("); + M_print(d); + printf(")\n"); + n--; + printf("%d != %d\n", c, d); + } + if (n <= 0) + exit(-1); } - c = FixedDiv(a, b); - d = FixedDivC(a, b); - if (c != d) - { - printf("("); - M_print(a); - printf(") / ("); - M_print(b); - printf(") = ("); - M_print(c); - printf(") != ("); - M_print(d); - printf(")\n"); - n--; - printf("%d != %d\n", c, d); - } - if (n <= 0) - exit(-1); - } #endif #ifdef SQRT_TEST @@ -982,7 +1017,7 @@ int main(int argc, char** argv) { c = FixedSqrt(a); d = FixedSqrtC(a); - b = abs(c-d); + b = abs(c - d); if (b > 1) { printf("sqrt("); diff --git a/src/m_fixed.h b/src/m_fixed.h index 4609913b7..8145a6917 100644 --- a/src/m_fixed.h +++ b/src/m_fixed.h @@ -394,9 +394,11 @@ boolean FV3_Equal(const vector3_t *a_1, const vector3_t *a_2); fixed_t FV3_Dot(const vector3_t *a_1, const vector3_t *a_2); vector3_t *FV3_Cross(const vector3_t *a_1, const vector3_t *a_2, vector3_t *a_o); vector3_t *FV3_ClosestPointOnLine(const vector3_t *Line, const vector3_t *p, vector3_t *out); +void FV3_ClosestPointOnVector(const vector3_t *dir, const vector3_t *p, vector3_t *out); void FV3_ClosestPointOnTriangle(const vector3_t *tri, const vector3_t *point, vector3_t *result); vector3_t *FV3_Point2Vec(const vector3_t *point1, const vector3_t *point2, vector3_t *a_o); -void FV3_Normal(const vector3_t *a_triangle, vector3_t *a_normal); +fixed_t FV3_Normal(const vector3_t *a_triangle, vector3_t *a_normal); +fixed_t FV3_Strength(const vector3_t *a_1, const vector3_t *dir); fixed_t FV3_PlaneDistance(const vector3_t *a_normal, const vector3_t *a_point); boolean FV3_IntersectedPlane(const vector3_t *a_triangle, const vector3_t *a_line, vector3_t *a_normal, fixed_t *originDistance); fixed_t FV3_PlaneIntersection(const vector3_t *pOrigin, const vector3_t *pNormal, const vector3_t *rOrigin, const vector3_t *rVector); From 3ed0edbcfe21b6342df514c62199ff159366337f Mon Sep 17 00:00:00 2001 From: Arthur Date: Sat, 15 Dec 2018 20:57:11 -0500 Subject: [PATCH 02/74] Common model format, with MD2/MD3 loading --- src/hardware/hw_drv.h | 6 +- src/hardware/hw_md2.c | 374 +------------ src/hardware/hw_md2.h | 94 +--- src/hardware/hw_md2load.c | 520 ++++++++++++++++++ src/hardware/hw_md2load.h | 19 + src/hardware/hw_md3load.c | 489 +++++++++++++++++ src/hardware/hw_md3load.h | 19 + src/hardware/hw_model.c | 706 +++++++++++++++++++++++++ src/hardware/hw_model.h | 104 ++++ src/hardware/r_opengl/r_opengl.c | 178 ++++--- src/hardware/u_list.c | 230 ++++++++ src/hardware/u_list.h | 29 + src/sdl/Srb2SDL-vc10.vcxproj | 10 +- src/sdl/Srb2SDL-vc10.vcxproj.filters | 24 + src/sdl/hwsym_sdl.c | 3 +- src/sdl/i_video.c | 3 +- src/win32/Srb2win-vc10.vcxproj | 10 +- src/win32/Srb2win-vc10.vcxproj.filters | 24 + src/win32/win_dll.c | 6 +- 19 files changed, 2333 insertions(+), 515 deletions(-) create mode 100644 src/hardware/hw_md2load.c create mode 100644 src/hardware/hw_md2load.h create mode 100644 src/hardware/hw_md3load.c create mode 100644 src/hardware/hw_md3load.h create mode 100644 src/hardware/hw_model.c create mode 100644 src/hardware/hw_model.h create mode 100644 src/hardware/u_list.c create mode 100644 src/hardware/u_list.h diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index e2fa90eb0..0afd6d272 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -58,8 +58,7 @@ EXPORT void HWRAPI(ClearMipMapCache) (void); EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value); //Hurdler: added for new development -EXPORT void HWRAPI(DrawMD2) (INT32 *gl_cmd_buffer, md2_frame_t *frame, FTransform *pos, float scale); -EXPORT void HWRAPI(DrawMD2i) (INT32 *gl_cmd_buffer, md2_frame_t *frame, INT32 duration, INT32 tics, md2_frame_t *nextframe, FTransform *pos, float scale, UINT8 flipped, UINT8 *color); +EXPORT void HWRAPI(DrawModel) (model_t *model, mdlframe_t *frame, INT32 duration, INT32 tics, mdlframe_t *nextframe, FTransform *pos, float scale, UINT8 flipped, UINT8 *color); EXPORT void HWRAPI(SetTransform) (FTransform *ptransform); EXPORT INT32 HWRAPI(GetTextureUsed) (void); EXPORT INT32 HWRAPI(GetRenderVersion) (void); @@ -96,8 +95,7 @@ struct hwdriver_s GClipRect pfnGClipRect; ClearMipMapCache pfnClearMipMapCache; SetSpecialState pfnSetSpecialState;//Hurdler: added for backward compatibility - DrawMD2 pfnDrawMD2; - DrawMD2i pfnDrawMD2i; + DrawModel pfnDrawModel; SetTransform pfnSetTransform; GetTextureUsed pfnGetTextureUsed; GetRenderVersion pfnGetRenderVersion; diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index cb33562d8..e323f1a41 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -40,6 +40,9 @@ #include "../w_wad.h" #include "../z_zone.h" #include "../r_things.h" +// #include "../r_draw.h" +// #include "../p_tick.h" +#include "hw_model.h" #include "hw_main.h" #include "../v_video.h" @@ -72,172 +75,6 @@ #include "errno.h" #endif -#define NUMVERTEXNORMALS 162 -float avertexnormals[NUMVERTEXNORMALS][3] = { -{-0.525731f, 0.000000f, 0.850651f}, -{-0.442863f, 0.238856f, 0.864188f}, -{-0.295242f, 0.000000f, 0.955423f}, -{-0.309017f, 0.500000f, 0.809017f}, -{-0.162460f, 0.262866f, 0.951056f}, -{0.000000f, 0.000000f, 1.000000f}, -{0.000000f, 0.850651f, 0.525731f}, -{-0.147621f, 0.716567f, 0.681718f}, -{0.147621f, 0.716567f, 0.681718f}, -{0.000000f, 0.525731f, 0.850651f}, -{0.309017f, 0.500000f, 0.809017f}, -{0.525731f, 0.000000f, 0.850651f}, -{0.295242f, 0.000000f, 0.955423f}, -{0.442863f, 0.238856f, 0.864188f}, -{0.162460f, 0.262866f, 0.951056f}, -{-0.681718f, 0.147621f, 0.716567f}, -{-0.809017f, 0.309017f, 0.500000f}, -{-0.587785f, 0.425325f, 0.688191f}, -{-0.850651f, 0.525731f, 0.000000f}, -{-0.864188f, 0.442863f, 0.238856f}, -{-0.716567f, 0.681718f, 0.147621f}, -{-0.688191f, 0.587785f, 0.425325f}, -{-0.500000f, 0.809017f, 0.309017f}, -{-0.238856f, 0.864188f, 0.442863f}, -{-0.425325f, 0.688191f, 0.587785f}, -{-0.716567f, 0.681718f, -0.147621f}, -{-0.500000f, 0.809017f, -0.309017f}, -{-0.525731f, 0.850651f, 0.000000f}, -{0.000000f, 0.850651f, -0.525731f}, -{-0.238856f, 0.864188f, -0.442863f}, -{0.000000f, 0.955423f, -0.295242f}, -{-0.262866f, 0.951056f, -0.162460f}, -{0.000000f, 1.000000f, 0.000000f}, -{0.000000f, 0.955423f, 0.295242f}, -{-0.262866f, 0.951056f, 0.162460f}, -{0.238856f, 0.864188f, 0.442863f}, -{0.262866f, 0.951056f, 0.162460f}, -{0.500000f, 0.809017f, 0.309017f}, -{0.238856f, 0.864188f, -0.442863f}, -{0.262866f, 0.951056f, -0.162460f}, -{0.500000f, 0.809017f, -0.309017f}, -{0.850651f, 0.525731f, 0.000000f}, -{0.716567f, 0.681718f, 0.147621f}, -{0.716567f, 0.681718f, -0.147621f}, -{0.525731f, 0.850651f, 0.000000f}, -{0.425325f, 0.688191f, 0.587785f}, -{0.864188f, 0.442863f, 0.238856f}, -{0.688191f, 0.587785f, 0.425325f}, -{0.809017f, 0.309017f, 0.500000f}, -{0.681718f, 0.147621f, 0.716567f}, -{0.587785f, 0.425325f, 0.688191f}, -{0.955423f, 0.295242f, 0.000000f}, -{1.000000f, 0.000000f, 0.000000f}, -{0.951056f, 0.162460f, 0.262866f}, -{0.850651f, -0.525731f, 0.000000f}, -{0.955423f, -0.295242f, 0.000000f}, -{0.864188f, -0.442863f, 0.238856f}, -{0.951056f, -0.162460f, 0.262866f}, -{0.809017f, -0.309017f, 0.500000f}, -{0.681718f, -0.147621f, 0.716567f}, -{0.850651f, 0.000000f, 0.525731f}, -{0.864188f, 0.442863f, -0.238856f}, -{0.809017f, 0.309017f, -0.500000f}, -{0.951056f, 0.162460f, -0.262866f}, -{0.525731f, 0.000000f, -0.850651f}, -{0.681718f, 0.147621f, -0.716567f}, -{0.681718f, -0.147621f, -0.716567f}, -{0.850651f, 0.000000f, -0.525731f}, -{0.809017f, -0.309017f, -0.500000f}, -{0.864188f, -0.442863f, -0.238856f}, -{0.951056f, -0.162460f, -0.262866f}, -{0.147621f, 0.716567f, -0.681718f}, -{0.309017f, 0.500000f, -0.809017f}, -{0.425325f, 0.688191f, -0.587785f}, -{0.442863f, 0.238856f, -0.864188f}, -{0.587785f, 0.425325f, -0.688191f}, -{0.688191f, 0.587785f, -0.425325f}, -{-0.147621f, 0.716567f, -0.681718f}, -{-0.309017f, 0.500000f, -0.809017f}, -{0.000000f, 0.525731f, -0.850651f}, -{-0.525731f, 0.000000f, -0.850651f}, -{-0.442863f, 0.238856f, -0.864188f}, -{-0.295242f, 0.000000f, -0.955423f}, -{-0.162460f, 0.262866f, -0.951056f}, -{0.000000f, 0.000000f, -1.000000f}, -{0.295242f, 0.000000f, -0.955423f}, -{0.162460f, 0.262866f, -0.951056f}, -{-0.442863f, -0.238856f, -0.864188f}, -{-0.309017f, -0.500000f, -0.809017f}, -{-0.162460f, -0.262866f, -0.951056f}, -{0.000000f, -0.850651f, -0.525731f}, -{-0.147621f, -0.716567f, -0.681718f}, -{0.147621f, -0.716567f, -0.681718f}, -{0.000000f, -0.525731f, -0.850651f}, -{0.309017f, -0.500000f, -0.809017f}, -{0.442863f, -0.238856f, -0.864188f}, -{0.162460f, -0.262866f, -0.951056f}, -{0.238856f, -0.864188f, -0.442863f}, -{0.500000f, -0.809017f, -0.309017f}, -{0.425325f, -0.688191f, -0.587785f}, -{0.716567f, -0.681718f, -0.147621f}, -{0.688191f, -0.587785f, -0.425325f}, -{0.587785f, -0.425325f, -0.688191f}, -{0.000000f, -0.955423f, -0.295242f}, -{0.000000f, -1.000000f, 0.000000f}, -{0.262866f, -0.951056f, -0.162460f}, -{0.000000f, -0.850651f, 0.525731f}, -{0.000000f, -0.955423f, 0.295242f}, -{0.238856f, -0.864188f, 0.442863f}, -{0.262866f, -0.951056f, 0.162460f}, -{0.500000f, -0.809017f, 0.309017f}, -{0.716567f, -0.681718f, 0.147621f}, -{0.525731f, -0.850651f, 0.000000f}, -{-0.238856f, -0.864188f, -0.442863f}, -{-0.500000f, -0.809017f, -0.309017f}, -{-0.262866f, -0.951056f, -0.162460f}, -{-0.850651f, -0.525731f, 0.000000f}, -{-0.716567f, -0.681718f, -0.147621f}, -{-0.716567f, -0.681718f, 0.147621f}, -{-0.525731f, -0.850651f, 0.000000f}, -{-0.500000f, -0.809017f, 0.309017f}, -{-0.238856f, -0.864188f, 0.442863f}, -{-0.262866f, -0.951056f, 0.162460f}, -{-0.864188f, -0.442863f, 0.238856f}, -{-0.809017f, -0.309017f, 0.500000f}, -{-0.688191f, -0.587785f, 0.425325f}, -{-0.681718f, -0.147621f, 0.716567f}, -{-0.442863f, -0.238856f, 0.864188f}, -{-0.587785f, -0.425325f, 0.688191f}, -{-0.309017f, -0.500000f, 0.809017f}, -{-0.147621f, -0.716567f, 0.681718f}, -{-0.425325f, -0.688191f, 0.587785f}, -{-0.162460f, -0.262866f, 0.951056f}, -{0.442863f, -0.238856f, 0.864188f}, -{0.162460f, -0.262866f, 0.951056f}, -{0.309017f, -0.500000f, 0.809017f}, -{0.147621f, -0.716567f, 0.681718f}, -{0.000000f, -0.525731f, 0.850651f}, -{0.425325f, -0.688191f, 0.587785f}, -{0.587785f, -0.425325f, 0.688191f}, -{0.688191f, -0.587785f, 0.425325f}, -{-0.955423f, 0.295242f, 0.000000f}, -{-0.951056f, 0.162460f, 0.262866f}, -{-1.000000f, 0.000000f, 0.000000f}, -{-0.850651f, 0.000000f, 0.525731f}, -{-0.955423f, -0.295242f, 0.000000f}, -{-0.951056f, -0.162460f, 0.262866f}, -{-0.864188f, 0.442863f, -0.238856f}, -{-0.951056f, 0.162460f, -0.262866f}, -{-0.809017f, 0.309017f, -0.500000f}, -{-0.864188f, -0.442863f, -0.238856f}, -{-0.951056f, -0.162460f, -0.262866f}, -{-0.809017f, -0.309017f, -0.500000f}, -{-0.681718f, 0.147621f, -0.716567f}, -{-0.681718f, -0.147621f, -0.716567f}, -{-0.850651f, 0.000000f, -0.525731f}, -{-0.688191f, 0.587785f, -0.425325f}, -{-0.587785f, 0.425325f, -0.688191f}, -{-0.425325f, 0.688191f, -0.587785f}, -{-0.425325f, -0.688191f, -0.587785f}, -{-0.587785f, -0.425325f, -0.688191f}, -{-0.688191f, -0.587785f, -0.425325f}, -}; - md2_t md2_models[NUMSPRITES]; md2_t md2_playermodels[MAXSKINS]; @@ -245,36 +82,9 @@ md2_t md2_playermodels[MAXSKINS]; /* * free model */ -static void md2_freeModel (md2_model_t *model) +static void md2_freeModel (model_t *model) { - if (model) - { - if (model->skins) - free(model->skins); - - if (model->texCoords) - free(model->texCoords); - - if (model->triangles) - free(model->triangles); - - if (model->frames) - { - size_t i; - - for (i = 0; i < model->header.numFrames; i++) - { - if (model->frames[i].vertices) - free(model->frames[i].vertices); - } - free(model->frames); - } - - if (model->glCommandBuffer) - free(model->glCommandBuffer); - - free(model); - } + UnloadModel(model); } @@ -282,157 +92,13 @@ static void md2_freeModel (md2_model_t *model) // load model // // Hurdler: the current path is the Legacy.exe path -static md2_model_t *md2_readModel(const char *filename) +static model_t *md2_readModel(const char *filename) { - FILE *file; - md2_model_t *model; - UINT8 buffer[MD2_MAX_FRAMESIZE]; - size_t i; - - model = calloc(1, sizeof (*model)); - if (model == NULL) - return 0; - //Filename checking fixed ~Monster Iestyn and Golden - file = fopen(va("%s"PATHSEP"%s", srb2home, filename), "rb"); - if (!file) - { - free(model); - return 0; - } - - // initialize model and read header - - if (fread(&model->header, sizeof (model->header), 1, file) != 1 - || model->header.magic != MD2_IDENT - || model->header.version != MD2_VERSION) - { - fclose(file); - free(model); - return 0; - } - - model->header.numSkins = 1; - -#define MD2LIMITCHECK(field, max, msgname) \ - if (field > max) \ - { \ - CONS_Alert(CONS_ERROR, "md2_readModel: %s has too many " msgname " (# found: %d, maximum: %d)\n", filename, field, max); \ - md2_freeModel (model); \ - fclose(file); \ - return 0; \ - } - - // Uncomment if these are actually needed -// MD2LIMITCHECK(model->header.numSkins, MD2_MAX_SKINS, "skins") -// MD2LIMITCHECK(model->header.numTexCoords, MD2_MAX_TEXCOORDS, "texture coordinates") - MD2LIMITCHECK(model->header.numTriangles, MD2_MAX_TRIANGLES, "triangles") - MD2LIMITCHECK(model->header.numFrames, MD2_MAX_FRAMES, "frames") - MD2LIMITCHECK(model->header.numVertices, MD2_MAX_VERTICES, "vertices") - -#undef MD2LIMITCHECK - - // read skins - fseek(file, model->header.offsetSkins, SEEK_SET); - if (model->header.numSkins > 0) - { - model->skins = calloc(sizeof (md2_skin_t), model->header.numSkins); - if (!model->skins || model->header.numSkins != - fread(model->skins, sizeof (md2_skin_t), model->header.numSkins, file)) - { - md2_freeModel (model); - fclose(file); - return 0; - } - } - - // read texture coordinates - fseek(file, model->header.offsetTexCoords, SEEK_SET); - if (model->header.numTexCoords > 0) - { - model->texCoords = calloc(sizeof (md2_textureCoordinate_t), model->header.numTexCoords); - if (!model->texCoords || model->header.numTexCoords != - fread(model->texCoords, sizeof (md2_textureCoordinate_t), model->header.numTexCoords, file)) - { - md2_freeModel (model); - fclose(file); - return 0; - } - } - - // read triangles - fseek(file, model->header.offsetTriangles, SEEK_SET); - if (model->header.numTriangles > 0) - { - model->triangles = calloc(sizeof (md2_triangle_t), model->header.numTriangles); - if (!model->triangles || model->header.numTriangles != - fread(model->triangles, sizeof (md2_triangle_t), model->header.numTriangles, file)) - { - md2_freeModel (model); - fclose(file); - return 0; - } - } - - // read alias frames - fseek(file, model->header.offsetFrames, SEEK_SET); - if (model->header.numFrames > 0) - { - model->frames = calloc(sizeof (md2_frame_t), model->header.numFrames); - if (!model->frames) - { - md2_freeModel (model); - fclose(file); - return 0; - } - - for (i = 0; i < model->header.numFrames; i++) - { - md2_alias_frame_t *frame = (md2_alias_frame_t *)(void *)buffer; - size_t j; - - model->frames[i].vertices = calloc(sizeof (md2_triangleVertex_t), model->header.numVertices); - if (!model->frames[i].vertices || model->header.frameSize != - fread(frame, 1, model->header.frameSize, file)) - { - md2_freeModel (model); - fclose(file); - return 0; - } - - strcpy(model->frames[i].name, frame->name); - for (j = 0; j < model->header.numVertices; j++) - { - model->frames[i].vertices[j].vertex[0] = (float) ((INT32) frame->alias_vertices[j].vertex[0]) * frame->scale[0] + frame->translate[0]; - model->frames[i].vertices[j].vertex[2] = -1* ((float) ((INT32) frame->alias_vertices[j].vertex[1]) * frame->scale[1] + frame->translate[1]); - model->frames[i].vertices[j].vertex[1] = (float) ((INT32) frame->alias_vertices[j].vertex[2]) * frame->scale[2] + frame->translate[2]; - model->frames[i].vertices[j].normal[0] = avertexnormals[frame->alias_vertices[j].lightNormalIndex][0]; - model->frames[i].vertices[j].normal[1] = avertexnormals[frame->alias_vertices[j].lightNormalIndex][1]; - model->frames[i].vertices[j].normal[2] = avertexnormals[frame->alias_vertices[j].lightNormalIndex][2]; - } - } - } - - // read gl commands - fseek(file, model->header.offsetGlCommands, SEEK_SET); - if (model->header.numGlCommands) - { - model->glCommandBuffer = calloc(sizeof (INT32), model->header.numGlCommands); - if (!model->glCommandBuffer || model->header.numGlCommands != - fread(model->glCommandBuffer, sizeof (INT32), model->header.numGlCommands, file)) - { - md2_freeModel (model); - fclose(file); - return 0; - } - } - - fclose(file); - - return model; + return LoadModel(va("%s"PATHSEP"%s", srb2home, filename), PU_STATIC); } -static inline void md2_printModelInfo (md2_model_t *model) +static inline void md2_printModelInfo (model_t *model) { #if 0 INT32 i; @@ -933,7 +599,7 @@ void HWR_AddSpriteMD2(size_t spritenum) // For MD2s that were added after startu return; } - // Check for any MD2s that match the names of player skins! + // Check for any MD2s that match the names of sprite names! while (fscanf(f, "%19s %31s %f %f", name, filename, &scale, &offset) == 4) { if (stricmp(name, sprnames[spritenum]) == 0) @@ -1269,10 +935,9 @@ void HWR_DrawMD2(gr_vissprite_t *spr) // Look at HWR_ProjectSprite for more { GLPatch_t *gpatch; - INT32 *buff; INT32 durs = spr->mobj->state->tics; INT32 tics = spr->mobj->tics; - md2_frame_t *curr, *next = NULL; + mdlframe_t *curr, *next = NULL; const UINT8 flip = (UINT8)((spr->mobj->eflags & MFE_VERTICALFLIP) == MFE_VERTICALFLIP); spritedef_t *sprdef; spriteframe_t *sprframe; @@ -1362,9 +1027,9 @@ void HWR_DrawMD2(gr_vissprite_t *spr) } //FIXME: this is not yet correct - frame = (spr->mobj->frame & FF_FRAMEMASK) % md2->model->header.numFrames; - buff = md2->model->glCommandBuffer; - curr = &md2->model->frames[frame]; + frame = (spr->mobj->frame & FF_FRAMEMASK) % md2->model->meshes[0].numFrames; + curr = &md2->model->meshes[0].frames[frame]; +#if 0 if (cv_grmd2.value == 1 && tics <= durs) { // frames are handled differently for states with FF_ANIMATE, so get the next frame differently for the interpolation @@ -1414,6 +1079,17 @@ void HWR_DrawMD2(gr_vissprite_t *spr) p.angley = FIXED_TO_FLOAT(anglef); } p.anglex = 0.0f; + p.anglez = 0.0f; + if (spr->mobj->standingslope) + { + fixed_t tempz = spr->mobj->standingslope->normal.z; + fixed_t tempy = spr->mobj->standingslope->normal.y; + fixed_t tempx = spr->mobj->standingslope->normal.x; + fixed_t tempangle = AngleFixed(R_PointToAngle2(0, 0, FixedSqrt(FixedMul(tempy, tempy) + FixedMul(tempz, tempz)), tempx)); + p.anglez = FIXED_TO_FLOAT(tempangle); + tempangle = -AngleFixed(R_PointToAngle2(0, 0, tempz, tempy)); + p.anglex = FIXED_TO_FLOAT(tempangle); + } color[0] = Surf.FlatColor.s.red; color[1] = Surf.FlatColor.s.green; @@ -1425,7 +1101,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) p.flip = atransform.flip; - HWD.pfnDrawMD2i(buff, curr, durs, tics, next, &p, finalscale, flip, color); + HWD.pfnDrawModel(md2->model, curr, durs, tics, next, &p, finalscale, flip, color); } } diff --git a/src/hardware/hw_md2.h b/src/hardware/hw_md2.h index 299d12400..57d8026b9 100644 --- a/src/hardware/hw_md2.h +++ b/src/hardware/hw_md2.h @@ -22,97 +22,7 @@ #define _HW_MD2_H_ #include "hw_glob.h" - -// magic number "IDP2" or 844121161 -#define MD2_IDENT (INT32)(('2' << 24) + ('P' << 16) + ('D' << 8) + 'I') -// model version -#define MD2_VERSION 8 - -#define MD2_MAX_TRIANGLES 8192 -#define MD2_MAX_VERTICES 4096 -#define MD2_MAX_TEXCOORDS 4096 -#define MD2_MAX_FRAMES 512 -#define MD2_MAX_SKINS 32 -#define MD2_MAX_FRAMESIZE (MD2_MAX_VERTICES * 4 + 128) - -#if defined(_MSC_VER) -#pragma pack(1) -#endif -typedef struct -{ - UINT32 magic; - UINT32 version; - UINT32 skinWidth; - UINT32 skinHeight; - UINT32 frameSize; - UINT32 numSkins; - UINT32 numVertices; - UINT32 numTexCoords; - UINT32 numTriangles; - UINT32 numGlCommands; - UINT32 numFrames; - UINT32 offsetSkins; - UINT32 offsetTexCoords; - UINT32 offsetTriangles; - UINT32 offsetFrames; - UINT32 offsetGlCommands; - UINT32 offsetEnd; -} ATTRPACK md2_header_t; //NOTE: each of md2_header's members are 4 unsigned bytes - -typedef struct -{ - UINT8 vertex[3]; - UINT8 lightNormalIndex; -} ATTRPACK md2_alias_triangleVertex_t; - -typedef struct -{ - float vertex[3]; - float normal[3]; -} ATTRPACK md2_triangleVertex_t; - -typedef struct -{ - INT16 vertexIndices[3]; - INT16 textureIndices[3]; -} ATTRPACK md2_triangle_t; - -typedef struct -{ - INT16 s, t; -} ATTRPACK md2_textureCoordinate_t; - -typedef struct -{ - float scale[3]; - float translate[3]; - char name[16]; - md2_alias_triangleVertex_t alias_vertices[1]; -} ATTRPACK md2_alias_frame_t; - -typedef struct -{ - char name[16]; - md2_triangleVertex_t *vertices; -} ATTRPACK md2_frame_t; - -typedef char md2_skin_t[64]; - -typedef struct -{ - float s, t; - INT32 vertexIndex; -} ATTRPACK md2_glCommandVertex_t; - -typedef struct -{ - md2_header_t header; - md2_skin_t *skins; - md2_textureCoordinate_t *texCoords; - md2_triangle_t *triangles; - md2_frame_t *frames; - INT32 *glCommandBuffer; -} ATTRPACK md2_model_t; +#include "hw_model.h" #if defined(_MSC_VER) #pragma pack() @@ -123,7 +33,7 @@ typedef struct char filename[32]; float scale; float offset; - md2_model_t *model; + model_t *model; void *grpatch; void *blendgrpatch; boolean notfound; diff --git a/src/hardware/hw_md2load.c b/src/hardware/hw_md2load.c new file mode 100644 index 000000000..3b083fee4 --- /dev/null +++ b/src/hardware/hw_md2load.c @@ -0,0 +1,520 @@ +/* + From the 'Wizard2' engine by Spaddlewit Inc. ( http://www.spaddlewit.com ) + An experimental work-in-progress. + + Donated to Sonic Team Junior and adapted to work with + Sonic Robo Blast 2. The license of this code matches whatever + the licensing is for Sonic Robo Blast 2. +*/ + +#include +#include +#include +#include "../doomdef.h" +#include "hw_md2load.h" +#include "hw_model.h" +#include "../z_zone.h" + +#define NUMVERTEXNORMALS 162 + +// Quake 2 normals are indexed. Use avertexnormals[normalindex][x/y/z] and +// you'll have your normals. +float avertexnormals[NUMVERTEXNORMALS][3] = { +{-0.525731f, 0.000000f, 0.850651f}, +{-0.442863f, 0.238856f, 0.864188f}, +{-0.295242f, 0.000000f, 0.955423f}, +{-0.309017f, 0.500000f, 0.809017f}, +{-0.162460f, 0.262866f, 0.951056f}, +{0.000000f, 0.000000f, 1.000000f}, +{0.000000f, 0.850651f, 0.525731f}, +{-0.147621f, 0.716567f, 0.681718f}, +{0.147621f, 0.716567f, 0.681718f}, +{0.000000f, 0.525731f, 0.850651f}, +{0.309017f, 0.500000f, 0.809017f}, +{0.525731f, 0.000000f, 0.850651f}, +{0.295242f, 0.000000f, 0.955423f}, +{0.442863f, 0.238856f, 0.864188f}, +{0.162460f, 0.262866f, 0.951056f}, +{-0.681718f, 0.147621f, 0.716567f}, +{-0.809017f, 0.309017f, 0.500000f}, +{-0.587785f, 0.425325f, 0.688191f}, +{-0.850651f, 0.525731f, 0.000000f}, +{-0.864188f, 0.442863f, 0.238856f}, +{-0.716567f, 0.681718f, 0.147621f}, +{-0.688191f, 0.587785f, 0.425325f}, +{-0.500000f, 0.809017f, 0.309017f}, +{-0.238856f, 0.864188f, 0.442863f}, +{-0.425325f, 0.688191f, 0.587785f}, +{-0.716567f, 0.681718f, -0.147621f}, +{-0.500000f, 0.809017f, -0.309017f}, +{-0.525731f, 0.850651f, 0.000000f}, +{0.000000f, 0.850651f, -0.525731f}, +{-0.238856f, 0.864188f, -0.442863f}, +{0.000000f, 0.955423f, -0.295242f}, +{-0.262866f, 0.951056f, -0.162460f}, +{0.000000f, 1.000000f, 0.000000f}, +{0.000000f, 0.955423f, 0.295242f}, +{-0.262866f, 0.951056f, 0.162460f}, +{0.238856f, 0.864188f, 0.442863f}, +{0.262866f, 0.951056f, 0.162460f}, +{0.500000f, 0.809017f, 0.309017f}, +{0.238856f, 0.864188f, -0.442863f}, +{0.262866f, 0.951056f, -0.162460f}, +{0.500000f, 0.809017f, -0.309017f}, +{0.850651f, 0.525731f, 0.000000f}, +{0.716567f, 0.681718f, 0.147621f}, +{0.716567f, 0.681718f, -0.147621f}, +{0.525731f, 0.850651f, 0.000000f}, +{0.425325f, 0.688191f, 0.587785f}, +{0.864188f, 0.442863f, 0.238856f}, +{0.688191f, 0.587785f, 0.425325f}, +{0.809017f, 0.309017f, 0.500000f}, +{0.681718f, 0.147621f, 0.716567f}, +{0.587785f, 0.425325f, 0.688191f}, +{0.955423f, 0.295242f, 0.000000f}, +{1.000000f, 0.000000f, 0.000000f}, +{0.951056f, 0.162460f, 0.262866f}, +{0.850651f, -0.525731f, 0.000000f}, +{0.955423f, -0.295242f, 0.000000f}, +{0.864188f, -0.442863f, 0.238856f}, +{0.951056f, -0.162460f, 0.262866f}, +{0.809017f, -0.309017f, 0.500000f}, +{0.681718f, -0.147621f, 0.716567f}, +{0.850651f, 0.000000f, 0.525731f}, +{0.864188f, 0.442863f, -0.238856f}, +{0.809017f, 0.309017f, -0.500000f}, +{0.951056f, 0.162460f, -0.262866f}, +{0.525731f, 0.000000f, -0.850651f}, +{0.681718f, 0.147621f, -0.716567f}, +{0.681718f, -0.147621f, -0.716567f}, +{0.850651f, 0.000000f, -0.525731f}, +{0.809017f, -0.309017f, -0.500000f}, +{0.864188f, -0.442863f, -0.238856f}, +{0.951056f, -0.162460f, -0.262866f}, +{0.147621f, 0.716567f, -0.681718f}, +{0.309017f, 0.500000f, -0.809017f}, +{0.425325f, 0.688191f, -0.587785f}, +{0.442863f, 0.238856f, -0.864188f}, +{0.587785f, 0.425325f, -0.688191f}, +{0.688191f, 0.587785f, -0.425325f}, +{-0.147621f, 0.716567f, -0.681718f}, +{-0.309017f, 0.500000f, -0.809017f}, +{0.000000f, 0.525731f, -0.850651f}, +{-0.525731f, 0.000000f, -0.850651f}, +{-0.442863f, 0.238856f, -0.864188f}, +{-0.295242f, 0.000000f, -0.955423f}, +{-0.162460f, 0.262866f, -0.951056f}, +{0.000000f, 0.000000f, -1.000000f}, +{0.295242f, 0.000000f, -0.955423f}, +{0.162460f, 0.262866f, -0.951056f}, +{-0.442863f, -0.238856f, -0.864188f}, +{-0.309017f, -0.500000f, -0.809017f}, +{-0.162460f, -0.262866f, -0.951056f}, +{0.000000f, -0.850651f, -0.525731f}, +{-0.147621f, -0.716567f, -0.681718f}, +{0.147621f, -0.716567f, -0.681718f}, +{0.000000f, -0.525731f, -0.850651f}, +{0.309017f, -0.500000f, -0.809017f}, +{0.442863f, -0.238856f, -0.864188f}, +{0.162460f, -0.262866f, -0.951056f}, +{0.238856f, -0.864188f, -0.442863f}, +{0.500000f, -0.809017f, -0.309017f}, +{0.425325f, -0.688191f, -0.587785f}, +{0.716567f, -0.681718f, -0.147621f}, +{0.688191f, -0.587785f, -0.425325f}, +{0.587785f, -0.425325f, -0.688191f}, +{0.000000f, -0.955423f, -0.295242f}, +{0.000000f, -1.000000f, 0.000000f}, +{0.262866f, -0.951056f, -0.162460f}, +{0.000000f, -0.850651f, 0.525731f}, +{0.000000f, -0.955423f, 0.295242f}, +{0.238856f, -0.864188f, 0.442863f}, +{0.262866f, -0.951056f, 0.162460f}, +{0.500000f, -0.809017f, 0.309017f}, +{0.716567f, -0.681718f, 0.147621f}, +{0.525731f, -0.850651f, 0.000000f}, +{-0.238856f, -0.864188f, -0.442863f}, +{-0.500000f, -0.809017f, -0.309017f}, +{-0.262866f, -0.951056f, -0.162460f}, +{-0.850651f, -0.525731f, 0.000000f}, +{-0.716567f, -0.681718f, -0.147621f}, +{-0.716567f, -0.681718f, 0.147621f}, +{-0.525731f, -0.850651f, 0.000000f}, +{-0.500000f, -0.809017f, 0.309017f}, +{-0.238856f, -0.864188f, 0.442863f}, +{-0.262866f, -0.951056f, 0.162460f}, +{-0.864188f, -0.442863f, 0.238856f}, +{-0.809017f, -0.309017f, 0.500000f}, +{-0.688191f, -0.587785f, 0.425325f}, +{-0.681718f, -0.147621f, 0.716567f}, +{-0.442863f, -0.238856f, 0.864188f}, +{-0.587785f, -0.425325f, 0.688191f}, +{-0.309017f, -0.500000f, 0.809017f}, +{-0.147621f, -0.716567f, 0.681718f}, +{-0.425325f, -0.688191f, 0.587785f}, +{-0.162460f, -0.262866f, 0.951056f}, +{0.442863f, -0.238856f, 0.864188f}, +{0.162460f, -0.262866f, 0.951056f}, +{0.309017f, -0.500000f, 0.809017f}, +{0.147621f, -0.716567f, 0.681718f}, +{0.000000f, -0.525731f, 0.850651f}, +{0.425325f, -0.688191f, 0.587785f}, +{0.587785f, -0.425325f, 0.688191f}, +{0.688191f, -0.587785f, 0.425325f}, +{-0.955423f, 0.295242f, 0.000000f}, +{-0.951056f, 0.162460f, 0.262866f}, +{-1.000000f, 0.000000f, 0.000000f}, +{-0.850651f, 0.000000f, 0.525731f}, +{-0.955423f, -0.295242f, 0.000000f}, +{-0.951056f, -0.162460f, 0.262866f}, +{-0.864188f, 0.442863f, -0.238856f}, +{-0.951056f, 0.162460f, -0.262866f}, +{-0.809017f, 0.309017f, -0.500000f}, +{-0.864188f, -0.442863f, -0.238856f}, +{-0.951056f, -0.162460f, -0.262866f}, +{-0.809017f, -0.309017f, -0.500000f}, +{-0.681718f, 0.147621f, -0.716567f}, +{-0.681718f, -0.147621f, -0.716567f}, +{-0.850651f, 0.000000f, -0.525731f}, +{-0.688191f, 0.587785f, -0.425325f}, +{-0.587785f, 0.425325f, -0.688191f}, +{-0.425325f, 0.688191f, -0.587785f}, +{-0.425325f, -0.688191f, -0.587785f}, +{-0.587785f, -0.425325f, -0.688191f}, +{-0.688191f, -0.587785f, -0.425325f}, +}; + +typedef struct +{ + int ident; // A "magic number" that's used to identify the .md2 file + int version; // The version of the file, always 8 + int skinwidth; // Width of the skin(s) in pixels + int skinheight; // Height of the skin(s) in pixels + int framesize; // Size of each frame in bytes + int numSkins; // Number of skins with the model + int numXYZ; // Number of vertices in each frame + int numST; // Number of texture coordinates in each frame. + int numTris; // Number of triangles in each frame + int numGLcmds; // Number of dwords (4 bytes) in the gl command list. + int numFrames; // Number of frames + int offsetSkins; // Offset, in bytes from the start of the file, to the list of skin names. + int offsetST; // Offset, in bytes from the start of the file, to the list of texture coordinates + int offsetTris; // Offset, in bytes from the start of the file, to the list of triangles + int offsetFrames; // Offset, in bytes from the start of the file, to the list of frames + int offsetGLcmds; // Offset, in bytes from the start of the file, to the list of gl commands + int offsetEnd; // Offset, in bytes from the start of the file, to the end of the file (filesize) +} md2header_t; + +typedef struct +{ + unsigned short meshIndex[3]; // indices into the array of vertices in each frames + unsigned short stIndex[3]; // indices into the array of texture coordinates +} md2triangle_t; + +typedef struct +{ + short s; + short t; +} md2texcoord_t; + +typedef struct +{ + unsigned char v[3]; // Scaled vertices. You'll need to multiply them with scale[x] to make them normal. + unsigned char lightNormalIndex; // Index to the array of normals +} md2vertex_t; + +typedef struct +{ + float scale[3]; // Used by the v member in the md2framePoint structure + float translate[3]; // Used by the v member in the md2framePoint structure + char name[16]; // Name of the frame +} md2frame_t; + +// Load the model +model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) +{ + useFloat = true; // Right now we always useFloat = true, because the GL subsystem needs some work for the other option to work. + + model_t *retModel = NULL; + md2header_t *header; + + FILE *f = fopen(fileName, "rb"); + + if (!f) + return NULL; + + retModel = (model_t*)Z_Calloc(sizeof(model_t), ztag, 0); + + size_t fileLen; + int i, j; + + size_t namelen; + char *texturefilename; + const char *texPos = strchr(fileName, '/'); + + if (texPos) + { + texPos++; + namelen = strlen(texPos) + 1; + texturefilename = (char*)Z_Malloc(namelen, PU_CACHE, 0); + strcpy(texturefilename, texPos); + } + else + { + namelen = strlen(fileName) + 1; + texturefilename = (char*)Z_Malloc(namelen, PU_CACHE, 0); + strcpy(texturefilename, fileName); + } + + texturefilename[namelen-2] = 'z'; + texturefilename[namelen-3] = 'u'; + texturefilename[namelen-4] = 'b'; + + // find length of file + fseek(f, 0, SEEK_END); + fileLen = ftell(f); + fseek(f, 0, SEEK_SET); + + // read in file + char *buffer = malloc(fileLen); + fread(buffer, fileLen, 1, f); + fclose(f); + + // get pointer to file header + header = (md2header_t*)buffer; + + retModel->numMeshes = 1; // MD2 only has one mesh + retModel->meshes = (mesh_t*)Z_Calloc(sizeof(mesh_t) * retModel->numMeshes, ztag, 0); + retModel->meshes[0].numFrames = header->numFrames; + const float WUNITS = 1.0f; + float dataScale = WUNITS; + + // Tris and ST are simple structures that can be straight-copied + md2triangle_t *tris = (md2triangle_t*)&buffer[header->offsetTris]; + md2texcoord_t *texcoords = (md2texcoord_t*)&buffer[header->offsetST]; + md2frame_t *frames = (md2frame_t*)&buffer[header->offsetFrames]; + + // Read in textures + retModel->numMaterials = header->numSkins; + + if (retModel->numMaterials <= 0) // Always at least one skin, duh + retModel->numMaterials = 1; + + retModel->materials = (material_t*)Z_Calloc(sizeof(material_t)*retModel->numMaterials, ztag, 0); + + int t; + for (t = 0; t < retModel->numMaterials; t++) + { + retModel->materials[t].ambient[0] = 0.8f; + retModel->materials[t].ambient[1] = 0.8f; + retModel->materials[t].ambient[2] = 0.8f; + retModel->materials[t].ambient[3] = 1.0f; + retModel->materials[t].diffuse[0] = 0.8f; + retModel->materials[t].diffuse[1] = 0.8f; + retModel->materials[t].diffuse[2] = 0.8f; + retModel->materials[t].diffuse[3] = 1.0f; + retModel->materials[t].emissive[0] = 0.0f; + retModel->materials[t].emissive[1] = 0.0f; + retModel->materials[t].emissive[2] = 0.0f; + retModel->materials[t].emissive[3] = 1.0f; + retModel->materials[t].specular[0] = 0.0f; + retModel->materials[t].specular[1] = 0.0f; + retModel->materials[t].specular[2] = 0.0f; + retModel->materials[t].specular[3] = 1.0f; + retModel->materials[t].shininess = 0.0f; + retModel->materials[t].spheremap = false; + +/* retModel->materials[t].texture = Texture::ReadTexture((char*)texturefilename, ZT_TEXTURE); + + if (!systemSucks) + { + // Check for a normal map...?? + char openfilename[1024]; + char normalMapName[1024]; + strcpy(normalMapName, texturefilename); + size_t len = strlen(normalMapName); + char *ptr = &normalMapName[len]; + ptr--; // z + ptr--; // u + ptr--; // b + ptr--; // . + *ptr++ = '_'; + *ptr++ = 'n'; + *ptr++ = '.'; + *ptr++ = 'b'; + *ptr++ = 'u'; + *ptr++ = 'z'; + *ptr++ = '\0'; + + sprintf(openfilename, "%s/%s", "textures", normalMapName); + // Convert backslashes to forward slashes + for (int k = 0; k < 1024; k++) + { + if (openfilename[k] == '\0') + break; + + if (openfilename[k] == '\\') + openfilename[k] = '/'; + } + + Resource::resource_t *res = Resource::Open(openfilename); + if (res) + { + Resource::Close(res); + retModel->materials[t].lightmap = Texture::ReadTexture(normalMapName, ZT_TEXTURE); + } + }*/ + } + + retModel->meshes[0].numTriangles = header->numTris; + + if (!useFloat) // Decompress to MD3 'tinyframe' space + { + dataScale = 0.015624f; // 1 / 64.0f + retModel->meshes[0].tinyframes = (tinyframe_t*)Z_Calloc(sizeof(tinyframe_t)*header->numFrames, ztag, 0); + retModel->meshes[0].numVertices = header->numXYZ; + retModel->meshes[0].uvs = (float*)Z_Malloc (sizeof(float)*2*retModel->meshes[0].numVertices, ztag, 0); + + byte *ptr = (byte*)frames; + for (i = 0; i < header->numFrames; i++, ptr += header->framesize) + { + md2frame_t *framePtr = (md2frame_t*)ptr; + retModel->meshes[0].tinyframes[i].vertices = (short*)Z_Malloc(sizeof(short)*3*header->numXYZ, ztag, 0); + retModel->meshes[0].tinyframes[i].normals = (char*)Z_Malloc(sizeof(char)*3*header->numXYZ, ztag, 0); + +// if (retModel->materials[0].lightmap) +// retModel->meshes[0].tinyframes[i].tangents = (char*)malloc(sizeof(char));//(char*)Z_Malloc(sizeof(char)*3*header->numVerts, ztag); + retModel->meshes[0].indices = (unsigned short*)Z_Malloc(sizeof(unsigned short) * 3 * header->numTris, ztag, 0); + + short *vertptr = retModel->meshes[0].tinyframes[i].vertices; + char *normptr = retModel->meshes[0].tinyframes[i].normals; + +// char *tanptr = retModel->meshes[0].tinyframes[i].tangents; + retModel->meshes[0].tinyframes[i].material = &retModel->materials[0]; + + framePtr++; // Advance to vertex list + md2vertex_t *vertex = (md2vertex_t*)framePtr; + framePtr--; + for (j = 0; j < header->numXYZ; j++, vertex++) + { + *vertptr = (short)(((vertex->v[1] * framePtr->scale[1]) + framePtr->translate[1]) / dataScale); + vertptr++; + *vertptr = (short)(((vertex->v[2] * framePtr->scale[2]) + framePtr->translate[2]) / dataScale); + vertptr++; + *vertptr = (short)(((vertex->v[0] * framePtr->scale[0]) + framePtr->translate[0]) / dataScale); + vertptr++; + + // Normal + *normptr++ = (byte)(avertexnormals[vertex->lightNormalIndex][1] * 127); + *normptr++ = (byte)(avertexnormals[vertex->lightNormalIndex][2] * 127); + *normptr++ = (byte)(avertexnormals[vertex->lightNormalIndex][0] * 127); + } + } + + // This doesn't need to be done every frame! + md2triangle_t *trisPtr = tris; + unsigned short *indexptr = retModel->meshes[0].indices; + float *uvptr = (float*)retModel->meshes[0].uvs; + for (j = 0; j < header->numTris; j++, trisPtr++) + { + *indexptr = trisPtr->meshIndex[0]; + indexptr++; + *indexptr = trisPtr->meshIndex[2]; + indexptr++; + *indexptr = trisPtr->meshIndex[1]; + indexptr++; + + uvptr[trisPtr->meshIndex[1] * 2] = texcoords[trisPtr->stIndex[1]].s / (float)header->skinwidth; + uvptr[trisPtr->meshIndex[1] * 2 + 1] = (texcoords[trisPtr->stIndex[1]].t / (float)header->skinheight); + uvptr[trisPtr->meshIndex[2] * 2] = texcoords[trisPtr->stIndex[2]].s / (float)header->skinwidth; + uvptr[trisPtr->meshIndex[2] * 2 + 1] = (texcoords[trisPtr->stIndex[2]].t / (float)header->skinheight); + uvptr[trisPtr->meshIndex[0] * 2] = texcoords[trisPtr->stIndex[0]].s / (float)header->skinwidth; + uvptr[trisPtr->meshIndex[0] * 2 + 1] = (texcoords[trisPtr->stIndex[0]].t / (float)header->skinheight); + } + } + else // Full float loading method + { + retModel->meshes[0].numVertices = header->numTris*3; + retModel->meshes[0].frames = (mdlframe_t*)Z_Calloc(sizeof(mdlframe_t)*header->numFrames, ztag, 0); + retModel->meshes[0].uvs = (float*)Z_Malloc(sizeof(float)*2*retModel->meshes[0].numVertices, ztag, 0); + + md2triangle_t *trisPtr = tris; + float *uvptr = retModel->meshes[0].uvs; + for (i = 0; i < retModel->meshes[0].numTriangles; i++, trisPtr++) + { + *uvptr++ = texcoords[trisPtr->stIndex[0]].s / (float)header->skinwidth; + *uvptr++ = (texcoords[trisPtr->stIndex[0]].t / (float)header->skinheight); + *uvptr++ = texcoords[trisPtr->stIndex[1]].s / (float)header->skinwidth; + *uvptr++ = (texcoords[trisPtr->stIndex[1]].t / (float)header->skinheight); + *uvptr++ = texcoords[trisPtr->stIndex[2]].s / (float)header->skinwidth; + *uvptr++ = (texcoords[trisPtr->stIndex[2]].t / (float)header->skinheight); + } + + byte *ptr = (byte*)frames; + for (i = 0; i < header->numFrames; i++, ptr += header->framesize) + { + md2frame_t *framePtr = (md2frame_t*)ptr; + retModel->meshes[0].frames[i].normals = (float*)Z_Malloc(sizeof(float)*3*header->numTris*3, ztag, 0); + retModel->meshes[0].frames[i].vertices = (float*)Z_Malloc(sizeof(float)*3*header->numTris*3, ztag, 0); +// if (retModel->materials[0].lightmap) +// retModel->meshes[0].frames[i].tangents = (float*)malloc(sizeof(float));//(float*)Z_Malloc(sizeof(float)*3*header->numTris*3, ztag); + float *vertptr, *normptr; + normptr = (float*)retModel->meshes[0].frames[i].normals; + vertptr = (float*)retModel->meshes[0].frames[i].vertices; + trisPtr = tris; + + retModel->meshes[0].frames[i].material = &retModel->materials[0]; + + framePtr++; // Advance to vertex list + md2vertex_t *vertex = (md2vertex_t*)framePtr; + framePtr--; + for (j = 0; j < header->numTris; j++, trisPtr++) + { + *vertptr = ((vertex[trisPtr->meshIndex[0]].v[0] * framePtr->scale[0]) + framePtr->translate[0]) * WUNITS; + vertptr++; + *vertptr = ((vertex[trisPtr->meshIndex[0]].v[2] * framePtr->scale[2]) + framePtr->translate[2]) * WUNITS; + vertptr++; + *vertptr = -1.0f * ((vertex[trisPtr->meshIndex[0]].v[1] * framePtr->scale[1]) + framePtr->translate[1]) * WUNITS; + vertptr++; + + *vertptr = ((vertex[trisPtr->meshIndex[1]].v[0] * framePtr->scale[0]) + framePtr->translate[0]) * WUNITS; + vertptr++; + *vertptr = ((vertex[trisPtr->meshIndex[1]].v[2] * framePtr->scale[2]) + framePtr->translate[2]) * WUNITS; + vertptr++; + *vertptr = -1.0f * ((vertex[trisPtr->meshIndex[1]].v[1] * framePtr->scale[1]) + framePtr->translate[1]) * WUNITS; + vertptr++; + + *vertptr = ((vertex[trisPtr->meshIndex[2]].v[0] * framePtr->scale[0]) + framePtr->translate[0]) * WUNITS; + vertptr++; + *vertptr = ((vertex[trisPtr->meshIndex[2]].v[2] * framePtr->scale[2]) + framePtr->translate[2]) * WUNITS; + vertptr++; + *vertptr = -1.0f * ((vertex[trisPtr->meshIndex[2]].v[1] * framePtr->scale[1]) + framePtr->translate[1]) * WUNITS; + vertptr++; + + *normptr++ = avertexnormals[vertex[trisPtr->meshIndex[0]].lightNormalIndex][0]; + *normptr++ = avertexnormals[vertex[trisPtr->meshIndex[0]].lightNormalIndex][1]; + *normptr++ = avertexnormals[vertex[trisPtr->meshIndex[0]].lightNormalIndex][2]; + + *normptr++ = avertexnormals[vertex[trisPtr->meshIndex[1]].lightNormalIndex][0]; + *normptr++ = avertexnormals[vertex[trisPtr->meshIndex[1]].lightNormalIndex][1]; + *normptr++ = avertexnormals[vertex[trisPtr->meshIndex[1]].lightNormalIndex][2]; + + *normptr++ = avertexnormals[vertex[trisPtr->meshIndex[2]].lightNormalIndex][0]; + *normptr++ = avertexnormals[vertex[trisPtr->meshIndex[2]].lightNormalIndex][1]; + *normptr++ = avertexnormals[vertex[trisPtr->meshIndex[2]].lightNormalIndex][2]; + } + /* + // Rotate MD2 by 90 degrees in code BLAAHH + vector_t *normVecptr = (vector_t*)retModel->meshes[0].frames[i].normals; + vector_t *vertVecptr = (vector_t*)retModel->meshes[0].frames[i].vertices; + for (j = 0; j < header->numTris * 3; j++, normVecptr++, vertVecptr++) + { + VectorRotate(normVecptr, &vectorYaxis, -90.0f); + VectorRotate(vertVecptr, &vectorYaxis, -90.0f); + }*/ + } + } + + free(buffer); + return retModel; +} diff --git a/src/hardware/hw_md2load.h b/src/hardware/hw_md2load.h new file mode 100644 index 000000000..1662d6471 --- /dev/null +++ b/src/hardware/hw_md2load.h @@ -0,0 +1,19 @@ +/* + From the 'Wizard2' engine by Spaddlewit Inc. ( http://www.spaddlewit.com ) + An experimental work-in-progress. + + Donated to Sonic Team Junior and adapted to work with + Sonic Robo Blast 2. The license of this code matches whatever + the licensing is for Sonic Robo Blast 2. +*/ + +#ifndef _HW_MD2LOAD_H_ +#define _HW_MD2LOAD_H_ + +#include "hw_model.h" +#include "../doomtype.h" + +// Load the Model +model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat); + +#endif diff --git a/src/hardware/hw_md3load.c b/src/hardware/hw_md3load.c new file mode 100644 index 000000000..bac799cdb --- /dev/null +++ b/src/hardware/hw_md3load.c @@ -0,0 +1,489 @@ +/* + From the 'Wizard2' engine by Spaddlewit Inc. ( http://www.spaddlewit.com ) + An experimental work-in-progress. + + Donated to Sonic Team Junior and adapted to work with + Sonic Robo Blast 2. The license of this code matches whatever + the licensing is for Sonic Robo Blast 2. +*/ + +#include +#include +#include +#include "../doomdef.h" +#include "hw_md3load.h" +#include "hw_model.h" +#include "../z_zone.h" + +typedef struct +{ + int ident; // A "magic number" that's used to identify the .md3 file + int version; // The version of the file, always 15 + char name[64]; + int flags; + int numFrames; // Number of frames + int numTags; + int numSurfaces; + int numSkins; // Number of skins with the model + int offsetFrames; + int offsetTags; + int offsetSurfaces; + int offsetEnd; // Offset, in bytes from the start of the file, to the end of the file (filesize) +} md3modelHeader; + +typedef struct +{ + float minBounds[3]; // First corner of the bounding box + float maxBounds[3]; // Second corner of the bounding box + float localOrigin[3]; // Local origin, usually (0, 0, 0) + float radius; // Radius of bounding sphere + char name[16]; // Name of frame +} md3Frame; + +typedef struct +{ + char name[64]; // Name of tag + float origin[3]; // Coordinates of tag + float axis[9]; // Orientation of tag object +} md3Tag; + +typedef struct +{ + int ident; + char name[64]; // Name of this surface + int flags; + int numFrames; // # of keyframes + int numShaders; // # of shaders + int numVerts; // # of vertices + int numTriangles; // # of triangles + int offsetTriangles; // Relative offset from start of this struct to where the list of Triangles start + int offsetShaders; // Relative offset from start of this struct to where the list of Shaders start + int offsetST; // Relative offset from start of this struct to where the list of tex coords start + int offsetXYZNormal; // Relative offset from start of this struct to where the list of vertices start + int offsetEnd; // Relative offset from start of this struct to where this surface ends +} md3Surface; + +typedef struct +{ + char name[64]; // Name of this shader + int shaderIndex; // Shader index number +} md3Shader; + +typedef struct +{ + int index[3]; // List of offset values into the list of Vertex objects that constitute the corners of the Triangle object. +} md3Triangle; + +typedef struct +{ + float st[2]; +} md3TexCoord; + +typedef struct +{ + short x, y, z, n; +} md3Vertex; + +static float latlnglookup[256][256][3]; + +static void GetNormalFromLatLong(short latlng, float *out) +{ + float *lookup = latlnglookup[(unsigned char)(latlng >> 8)][(unsigned char)(latlng & 255)]; + + out[0] = *lookup++; + out[1] = *lookup++; + out[2] = *lookup++; +} + +static void NormalToLatLng(float *n, short *out) +{ + // Special cases + if (0.0f == n[0] && 0.0f == n[1]) + { + if (n[2] > 0.0f) + *out = 0; + else + *out = 128; + } + else + { + char x, y; + + x = (char)(57.2957795f * (atan2(n[1], n[0])) * (255.0f / 360.0f)); + y = (char)(57.2957795f * (acos(n[2])) * (255.0f / 360.0f)); + + *out = (x << 8) + y; + } +} + +static inline void LatLngToNormal(short n, float *out) +{ + const float PI = (3.1415926535897932384626433832795f); + float lat = (float)(n >> 8); + float lng = (float)(n & 255); + + lat *= PI / 128.0f; + lng *= PI / 128.0f; + + out[0] = cosf(lat) * sinf(lng); + out[1] = sinf(lat) * sinf(lng); + out[2] = cosf(lng); +} + +static void LatLngInit(void) +{ + int i, j; + for (i = 0; i < 256; i++) + { + for (j = 0; j < 256; j++) + LatLngToNormal((short)((i << 8) + j), latlnglookup[i][j]); + } +} + +static bool latlnginit = false; + +model_t *MD3_LoadModel(const char *fileName, int ztag, boolean useFloat) +{ + useFloat = true; // Right now we always useFloat = true, because the GL subsystem needs some work for the other option to work. + + if (!latlnginit) + { + LatLngInit(); + latlnginit = true; + } + + const float WUNITS = 1.0f; + model_t *retModel = NULL; + + FILE *f = fopen(fileName, "rb"); + + if (!f) + return NULL; + + retModel = (model_t*)Z_Calloc(sizeof(model_t), ztag, 0); + + md3modelHeader *mdh; + + // find length of file + fseek(f, 0, SEEK_END); + long fileLen = ftell(f); + fseek(f, 0, SEEK_SET); + + // read in file + char *buffer = malloc(fileLen); + fread(buffer, fileLen, 1, f); + fclose(f); + + // get pointer to file header + mdh = (md3modelHeader*)buffer; + + retModel->numMeshes = mdh->numSurfaces; + + retModel->numMaterials = 0; + int surfEnd = 0; + int i; + for (i = 0; i < mdh->numSurfaces; i++) + { + md3Surface *mdS = (md3Surface*)&buffer[mdh->offsetSurfaces]; + surfEnd += mdS->offsetEnd; + + retModel->numMaterials += mdS->numShaders; + } + + // Initialize materials + if (retModel->numMaterials <= 0) // Always at least one skin, duh + retModel->numMaterials = 1; + + retModel->materials = (material_t*)Z_Calloc(sizeof(material_t)*retModel->numMaterials, ztag, 0); + + int t; + for (t = 0; t < retModel->numMaterials; t++) + { + retModel->materials[t].ambient[0] = 0.3686f; + retModel->materials[t].ambient[1] = 0.3684f; + retModel->materials[t].ambient[2] = 0.3684f; + retModel->materials[t].ambient[3] = 1.0f; + retModel->materials[t].diffuse[0] = 0.8863f; + retModel->materials[t].diffuse[1] = 0.8850f; + retModel->materials[t].diffuse[2] = 0.8850f; + retModel->materials[t].diffuse[3] = 1.0f; + retModel->materials[t].emissive[0] = 0.0f; + retModel->materials[t].emissive[1] = 0.0f; + retModel->materials[t].emissive[2] = 0.0f; + retModel->materials[t].emissive[3] = 1.0f; + retModel->materials[t].specular[0] = 0.4902f; + retModel->materials[t].specular[1] = 0.4887f; + retModel->materials[t].specular[2] = 0.4887f; + retModel->materials[t].specular[3] = 1.0f; + retModel->materials[t].shininess = 25.0f; + retModel->materials[t].spheremap = false; + } + + retModel->meshes = (mesh_t*)Z_Calloc(sizeof(mesh_t)*retModel->numMeshes, ztag, 0); + + int matCount = 0; + for (i = 0, surfEnd = 0; i < mdh->numSurfaces; i++) + { + md3Surface *mdS = (md3Surface*)&buffer[mdh->offsetSurfaces + surfEnd]; + surfEnd += mdS->offsetEnd; + + md3Shader *mdShader = (md3Shader*)((char*)mdS + mdS->offsetShaders); + int j; + for (j = 0; j < mdS->numShaders; j++, matCount++) + { + size_t len = strlen(mdShader[j].name); + mdShader[j].name[len-1] = 'z'; + mdShader[j].name[len-2] = 'u'; + mdShader[j].name[len-3] = 'b'; + + // Load material +/* retModel->materials[matCount].texture = Texture::ReadTexture(mdShader[j].name, ZT_TEXTURE); + + if (!systemSucks) + { + // Check for a normal map...?? + char openfilename[1024]; + char normalMapName[1024]; + strcpy(normalMapName, mdShader[j].name); + len = strlen(normalMapName); + char *ptr = &normalMapName[len]; + ptr--; // z + ptr--; // u + ptr--; // b + ptr--; // . + *ptr++ = '_'; + *ptr++ = 'n'; + *ptr++ = '.'; + *ptr++ = 'b'; + *ptr++ = 'u'; + *ptr++ = 'z'; + *ptr++ = '\0'; + + sprintf(openfilename, "%s/%s", "textures", normalMapName); + // Convert backslashes to forward slashes + for (int k = 0; k < 1024; k++) + { + if (openfilename[k] == '\0') + break; + + if (openfilename[k] == '\\') + openfilename[k] = '/'; + } + + Resource::resource_t *res = Resource::Open(openfilename); + if (res) + { + Resource::Close(res); + retModel->materials[matCount].lightmap = Texture::ReadTexture(normalMapName, ZT_TEXTURE); + } + }*/ + } + + retModel->meshes[i].numFrames = mdS->numFrames; + retModel->meshes[i].numTriangles = mdS->numTriangles; + + if (!useFloat) // 'tinyframe' mode with indices + { + float tempNormal[3]; + retModel->meshes[i].tinyframes = (tinyframe_t*)Z_Calloc(sizeof(tinyframe_t)*mdS->numFrames, ztag, 0); + retModel->meshes[i].numVertices = mdS->numVerts; + retModel->meshes[i].uvs = (float*)Z_Malloc(sizeof(float)*2*mdS->numVerts, ztag, 0); + for (j = 0; j < mdS->numFrames; j++) + { + md3Vertex *mdV = (md3Vertex*)((char*)mdS + mdS->offsetXYZNormal + (mdS->numVerts*j*sizeof(md3Vertex))); + retModel->meshes[i].tinyframes[j].vertices = (short*)Z_Malloc(sizeof(short)*3*mdS->numVerts, ztag, 0); + retModel->meshes[i].tinyframes[j].normals = (char*)Z_Malloc(sizeof(char)*3*mdS->numVerts, ztag, 0); + +// if (retModel->materials[0].lightmap) +// retModel->meshes[i].tinyframes[j].tangents = (char*)malloc(sizeof(char));//(char*)Z_Malloc(sizeof(char)*3*mdS->numVerts, ztag); + retModel->meshes[i].indices = (unsigned short*)Z_Malloc(sizeof(unsigned short) * 3 * mdS->numTriangles, ztag, 0); + short *vertptr = retModel->meshes[i].tinyframes[j].vertices; + char *normptr = retModel->meshes[i].tinyframes[j].normals; + +// char *tanptr = retModel->meshes[i].tinyframes[j].tangents; + retModel->meshes[i].tinyframes[j].material = &retModel->materials[i]; + + int k; + for (k = 0; k < mdS->numVerts; k++) + { + // Vertex + *vertptr = mdV[k].y; + vertptr++; + *vertptr = mdV[k].z; + vertptr++; + *vertptr = mdV[k].x; + vertptr++; + + // Normal + GetNormalFromLatLong(mdV[k].n, tempNormal); + *normptr = (byte)(tempNormal[1] * 127); + normptr++; + *normptr = (byte)(tempNormal[2] * 127); + normptr++; + *normptr = (byte)(tempNormal[0] * 127); + normptr++; + } + } + + float *uvptr = (float*)retModel->meshes[i].uvs; + md3TexCoord *mdST = (md3TexCoord*)((char*)mdS + mdS->offsetST); + for (j = 0; j < mdS->numVerts; j++) + { + *uvptr = mdST[j].st[0]; + uvptr++; + *uvptr = 1.0f - mdST[j].st[1]; + uvptr++; + } + + unsigned short *indexptr = retModel->meshes[i].indices; + md3Triangle *mdT = (md3Triangle*)((char*)mdS + mdS->offsetTriangles); + for (j = 0; j < mdS->numTriangles; j++, mdT++) + { + // Indices + *indexptr = (unsigned short)mdT->index[0]; + indexptr++; + *indexptr = (unsigned short)mdT->index[2]; + indexptr++; + *indexptr = (unsigned short)mdT->index[1]; + indexptr++; + } + } + else // Traditional full-float loading method + { + retModel->meshes[i].numVertices = mdS->numTriangles * 3;//mdS->numVerts; + float dataScale = 0.015624f * WUNITS; + float tempNormal[3]; + retModel->meshes[i].frames = (mdlframe_t*)Z_Calloc(sizeof(mdlframe_t)*mdS->numFrames, ztag, 0); + retModel->meshes[i].uvs = (float*)Z_Malloc(sizeof(float)*2*mdS->numTriangles*3, ztag, 0); + + for (j = 0; j < mdS->numFrames; j++) + { + md3Vertex *mdV = (md3Vertex*)((char*)mdS + mdS->offsetXYZNormal + (mdS->numVerts*j*sizeof(md3Vertex))); + retModel->meshes[i].frames[j].vertices = (float*)Z_Malloc(sizeof(float)*3*mdS->numTriangles*3, ztag, 0); + retModel->meshes[i].frames[j].normals = (float*)Z_Malloc(sizeof(float)*3*mdS->numTriangles*3, ztag, 0); +// if (retModel->materials[i].lightmap) +// retModel->meshes[i].frames[j].tangents = (float*)malloc(sizeof(float));//(float*)Z_Malloc(sizeof(float)*3*mdS->numTriangles*3, ztag); + float *vertptr = retModel->meshes[i].frames[j].vertices; + float *normptr = retModel->meshes[i].frames[j].normals; + retModel->meshes[i].frames[j].material = &retModel->materials[i]; + + int k; + md3Triangle *mdT = (md3Triangle*)((char*)mdS + mdS->offsetTriangles); + + for (k = 0; k < mdS->numTriangles; k++) + { + // Vertex 1 + *vertptr = mdV[mdT->index[0]].x * dataScale; + vertptr++; + *vertptr = mdV[mdT->index[0]].z * dataScale; + vertptr++; + *vertptr = mdV[mdT->index[0]].y * dataScale; + vertptr++; + + GetNormalFromLatLong(mdV[mdT->index[0]].n, tempNormal); + *normptr = tempNormal[1]; + normptr++; + *normptr = tempNormal[2]; + normptr++; + *normptr = tempNormal[0]; + normptr++; + + // Vertex 2 + *vertptr = mdV[mdT->index[2]].x * dataScale; + vertptr++; + *vertptr = mdV[mdT->index[2]].z * dataScale; + vertptr++; + *vertptr = mdV[mdT->index[2]].y * dataScale; + vertptr++; + + GetNormalFromLatLong(mdV[mdT->index[2]].n, tempNormal); + *normptr = tempNormal[1]; + normptr++; + *normptr = tempNormal[2]; + normptr++; + *normptr = tempNormal[0]; + normptr++; + + // Vertex 3 + *vertptr = mdV[mdT->index[1]].x * dataScale; + vertptr++; + *vertptr = mdV[mdT->index[1]].z * dataScale; + vertptr++; + *vertptr = mdV[mdT->index[1]].y * dataScale; + vertptr++; + + GetNormalFromLatLong(mdV[mdT->index[1]].n, tempNormal); + *normptr = tempNormal[1]; + normptr++; + *normptr = tempNormal[2]; + normptr++; + *normptr = tempNormal[0]; + normptr++; + + mdT++; // Advance to next triangle + } + } + + md3TexCoord *mdST = (md3TexCoord*)((char*)mdS + mdS->offsetST); + float *uvptr = (float*)retModel->meshes[i].uvs; + int k; + md3Triangle *mdT = (md3Triangle*)((char*)mdS + mdS->offsetTriangles); + + for (k = 0; k < mdS->numTriangles; k++) + { + *uvptr = mdST[mdT->index[0]].st[0]; + uvptr++; + *uvptr = mdST[mdT->index[0]].st[1]; + uvptr++; + + *uvptr = mdST[mdT->index[2]].st[0]; + uvptr++; + *uvptr = mdST[mdT->index[2]].st[1]; + uvptr++; + + *uvptr = mdST[mdT->index[1]].st[0]; + uvptr++; + *uvptr = mdST[mdT->index[1]].st[1]; + uvptr++; + + mdT++; // Advance to next triangle + } + } + } + /* + // Tags? + retModel->numTags = mdh->numTags; + retModel->maxNumFrames = mdh->numFrames; + retModel->tags = (tag_t*)Z_Calloc(sizeof(tag_t) * retModel->numTags * mdh->numFrames, ztag); + md3Tag *mdTag = (md3Tag*)&buffer[mdh->offsetTags]; + tag_t *curTag = retModel->tags; + for (i = 0; i < mdh->numFrames; i++) + { + int j; + for (j = 0; j < retModel->numTags; j++, mdTag++) + { + strcpys(curTag->name, mdTag->name, sizeof(curTag->name) / sizeof(char)); + curTag->transform.m[0][0] = mdTag->axis[0]; + curTag->transform.m[0][1] = mdTag->axis[1]; + curTag->transform.m[0][2] = mdTag->axis[2]; + curTag->transform.m[1][0] = mdTag->axis[3]; + curTag->transform.m[1][1] = mdTag->axis[4]; + curTag->transform.m[1][2] = mdTag->axis[5]; + curTag->transform.m[2][0] = mdTag->axis[6]; + curTag->transform.m[2][1] = mdTag->axis[7]; + curTag->transform.m[2][2] = mdTag->axis[8]; + curTag->transform.m[3][0] = mdTag->origin[0] * WUNITS; + curTag->transform.m[3][1] = mdTag->origin[1] * WUNITS; + curTag->transform.m[3][2] = mdTag->origin[2] * WUNITS; + curTag->transform.m[3][3] = 1.0f; + + Matrix::Rotate(&curTag->transform, 90.0f, &Vector::Xaxis); + curTag++; + } + }*/ + + + free(buffer); + + return retModel; +} diff --git a/src/hardware/hw_md3load.h b/src/hardware/hw_md3load.h new file mode 100644 index 000000000..c0e0522ff --- /dev/null +++ b/src/hardware/hw_md3load.h @@ -0,0 +1,19 @@ +/* + From the 'Wizard2' engine by Spaddlewit Inc. ( http://www.spaddlewit.com ) + An experimental work-in-progress. + + Donated to Sonic Team Junior and adapted to work with + Sonic Robo Blast 2. The license of this code matches whatever + the licensing is for Sonic Robo Blast 2. +*/ + +#ifndef _HW_MD3LOAD_H_ +#define _HW_MD3LOAD_H_ + +#include "hw_model.h" +#include "../doomtype.h" + +// Load the Model +model_t *MD3_LoadModel(const char *fileName, int ztag, boolean useFloat); + +#endif diff --git a/src/hardware/hw_model.c b/src/hardware/hw_model.c new file mode 100644 index 000000000..73b2b484b --- /dev/null +++ b/src/hardware/hw_model.c @@ -0,0 +1,706 @@ +/* + From the 'Wizard2' engine by Spaddlewit Inc. ( http://www.spaddlewit.com ) + An experimental work-in-progress. + + Donated to Sonic Team Junior and adapted to work with + Sonic Robo Blast 2. The license of this code matches whatever + the licensing is for Sonic Robo Blast 2. +*/ + +#include "../z_zone.h" +#include "../doomdef.h" +#include "hw_model.h" +#include "hw_md2load.h" +#include "hw_md3load.h" +#include "u_list.h" +#include + +static float PI = (3.1415926535897932384626433832795f); +float U_Deg2Rad(float deg) +{ + return deg * ((float)PI / 180.0f); +} + +vector_t vectorXaxis = { 1.0f, 0.0f, 0.0f }; +vector_t vectorYaxis = { 0.0f, 1.0f, 0.0f }; +vector_t vectorZaxis = { 0.0f, 0.0f, 1.0f }; + +void VectorRotate(vector_t *rotVec, const vector_t *axisVec, float angle) +{ + angle = U_Deg2Rad(angle); + + // Rotate the point (x,y,z) around the vector (u,v,w) + float ux = axisVec->x * rotVec->x; + float uy = axisVec->x * rotVec->y; + float uz = axisVec->x * rotVec->z; + float vx = axisVec->y * rotVec->x; + float vy = axisVec->y * rotVec->y; + float vz = axisVec->y * rotVec->z; + float wx = axisVec->z * rotVec->x; + float wy = axisVec->z * rotVec->y; + float wz = axisVec->z * rotVec->z; + float sa = sinf(angle); + float ca = cosf(angle); + + rotVec->x = axisVec->x*(ux + vy + wz) + (rotVec->x*(axisVec->y*axisVec->y + axisVec->z*axisVec->z) - axisVec->x*(vy + wz))*ca + (-wy + vz)*sa; + rotVec->y = axisVec->y*(ux + vy + wz) + (rotVec->y*(axisVec->x*axisVec->x + axisVec->z*axisVec->z) - axisVec->y*(ux + wz))*ca + (wx - uz)*sa; + rotVec->z = axisVec->z*(ux + vy + wz) + (rotVec->z*(axisVec->x*axisVec->x + axisVec->y*axisVec->y) - axisVec->z*(ux + vy))*ca + (-vx + uy)*sa; +} + +void CreateVBOTiny(mesh_t *mesh, tinyframe_t *frame) +{ + return; +/* int bufferSize = sizeof(VBO::vbotiny_t)*mesh->numTriangles*3; + VBO::vbotiny_t *buffer = (VBO::vbotiny_t*)Z_Malloc(bufferSize, PU_STATIC, 0); + VBO::vbotiny_t *bufPtr = buffer; + + short *vertPtr = frame->vertices; + char *normPtr = frame->normals; + float *uvPtr = mesh->uvs; + char *tanPtr = frame->tangents; + + int i; + for (i = 0; i < mesh->numTriangles*3; i++) + { + bufPtr->x = *vertPtr++; + bufPtr->y = *vertPtr++; + bufPtr->z = *vertPtr++; + + bufPtr->nx = (*normPtr++) * 127; + bufPtr->ny = (*normPtr++) * 127; + bufPtr->nz = (*normPtr++) * 127; + + bufPtr->s0 = *uvPtr++; + bufPtr->t0 = *uvPtr++; + + if (tanPtr) + { + bufPtr->tanx = *tanPtr++; + bufPtr->tany = *tanPtr++; + bufPtr->tanz = *tanPtr++; + } + + bufPtr++; + } + + bglGenBuffers(1, &frame->vboID); + bglBindBuffer(BGL_ARRAY_BUFFER, frame->vboID); + bglBufferData(BGL_ARRAY_BUFFER, bufferSize, buffer, BGL_STATIC_DRAW); + Z_Free(buffer);*/ +} + +void CreateVBO(mesh_t *mesh, mdlframe_t *frame) +{ + return; +/* int bufferSize = sizeof(VBO::vbo64_t)*mesh->numTriangles*3; + VBO::vbo64_t *buffer = (VBO::vbo64_t*)Z_Malloc(bufferSize, PU_STATIC, 0); + VBO::vbo64_t *bufPtr = buffer; + + float *vertPtr = frame->vertices; + float *normPtr = frame->normals; + float *tanPtr = frame->tangents; + float *uvPtr = mesh->uvs; + float *lightPtr = mesh->lightuvs; + byte *colorPtr = frame->colors; + + int i; + for (i = 0; i < mesh->numTriangles*3; i++) + { + bufPtr->x = *vertPtr++; + bufPtr->y = *vertPtr++; + bufPtr->z = *vertPtr++; + + bufPtr->nx = *normPtr++; + bufPtr->ny = *normPtr++; + bufPtr->nz = *normPtr++; + + bufPtr->s0 = *uvPtr++; + bufPtr->t0 = *uvPtr++; + + if (tanPtr != NULL) + { + bufPtr->tan0 = *tanPtr++; + bufPtr->tan1 = *tanPtr++; + bufPtr->tan2 = *tanPtr++; + } + + if (lightPtr != NULL) + { + bufPtr->s1 = *lightPtr++; + bufPtr->t1 = *lightPtr++; + } + + if (colorPtr) + { + bufPtr->r = *colorPtr++; + bufPtr->g = *colorPtr++; + bufPtr->b = *colorPtr++; + bufPtr->a = *colorPtr++; + } + else + { + bufPtr->r = 255; + bufPtr->g = 255; + bufPtr->b = 255; + bufPtr->a = 255; + } + + bufPtr++; + } + + bglGenBuffers(1, &frame->vboID); + bglBindBuffer(BGL_ARRAY_BUFFER, frame->vboID); + bglBufferData(BGL_ARRAY_BUFFER, bufferSize, buffer, BGL_STATIC_DRAW); + Z_Free(buffer);*/ +} + +void UnloadModel(model_t *model) +{ + // Wouldn't it be great if C just had destructors? + int i; + for (i = 0; i < model->numMeshes; i++) + { + mesh_t *mesh = &model->meshes[i]; + + if (mesh->frames) + { + int j; + for (j = 0; j < mesh->numFrames; j++) + { + if (mesh->frames[j].normals) + Z_Free(mesh->frames[j].normals); + + if (mesh->frames[j].tangents) + Z_Free(mesh->frames[j].tangents); + + if (mesh->frames[j].vertices) + Z_Free(mesh->frames[j].vertices); + + if (mesh->frames[j].colors) + Z_Free(mesh->frames[j].colors); + } + + Z_Free(mesh->frames); + } + else if (mesh->tinyframes) + { + int j; + for (j = 0; j < mesh->numFrames; j++) + { + if (mesh->tinyframes[j].normals) + Z_Free(mesh->tinyframes[j].normals); + + if (mesh->tinyframes[j].tangents) + Z_Free(mesh->tinyframes[j].tangents); + + if (mesh->tinyframes[j].vertices) + Z_Free(mesh->tinyframes[j].vertices); + } + + if (mesh->indices) + Z_Free(mesh->indices); + + Z_Free(mesh->tinyframes); + } + + if (mesh->uvs) + Z_Free(mesh->uvs); + + if (mesh->lightuvs) + Z_Free(mesh->lightuvs); + } + + if (model->meshes) + Z_Free(model->meshes); + + if (model->tags) + Z_Free(model->tags); + + if (model->materials) + Z_Free(model->materials); + + DeleteVBOs(model); + Z_Free(model); +} + +tag_t *GetTagByName(model_t *model, char *name, int frame) +{ + if (frame < model->maxNumFrames) + { + tag_t *iterator = &model->tags[frame * model->numTags]; + + int i; + for (i = 0; i < model->numTags; i++) + { + if (!stricmp(iterator[i].name, name)) + return &iterator[i]; + } + } + + return NULL; +} + +// +// LoadModel +// +// Load a model and +// convert it to the +// internal format. +// +model_t *LoadModel(const char *filename, int ztag) +{ + model_t *model; + + // What type of file? + const char *extension = NULL; + int i; + for (i = (int)strlen(filename)-1; i >= 0; i--) + { + if (filename[i] != '.') + continue; + + extension = &filename[i]; + break; + } + + if (!extension) + { + CONS_Printf("Model %s is lacking a file extension, unable to determine type!\n", filename); + return NULL; + } + + if (!strcmp(extension, ".md3")) + { + if (!(model = MD3_LoadModel(filename, ztag, false))) + return NULL; + } + else if (!strcmp(extension, ".md3s")) // MD3 that will be converted in memory to use full floats + { + if (!(model = MD3_LoadModel(filename, ztag, true))) + return NULL; + } + else if (!strcmp(extension, ".md2")) + { + if (!(model = MD2_LoadModel(filename, ztag, false))) + return NULL; + } + else if (!strcmp(extension, ".md2s")) + { + if (!(model = MD2_LoadModel(filename, ztag, true))) + return NULL; + } + else + { + CONS_Printf("Unknown model format: %s\n", extension); + return NULL; + } + + model->mdlFilename = (char*)Z_Malloc(strlen(filename)+1, ztag, 0); + strcpy(model->mdlFilename, filename); + + Optimize(model); + GeneratePolygonNormals(model, ztag); + + // Default material properties + for (i = 0 ; i < model->numMaterials; i++) + { + material_t *material = &model->materials[i]; + material->ambient[0] = 0.7686f; + material->ambient[1] = 0.7686f; + material->ambient[2] = 0.7686f; + material->ambient[3] = 1.0f; + material->diffuse[0] = 0.5863f; + material->diffuse[1] = 0.5863f; + material->diffuse[2] = 0.5863f; + material->diffuse[3] = 1.0f; + material->specular[0] = 0.4902f; + material->specular[1] = 0.4902f; + material->specular[2] = 0.4902f; + material->specular[3] = 1.0f; + material->shininess = 25.0f; + } + + CONS_Printf("Generating VBOs for %s\n", filename); + for (i = 0; i < model->numMeshes; i++) + { + mesh_t *mesh = &model->meshes[i]; + + if (mesh->frames) + { + int j; + for (j = 0; j < model->meshes[i].numFrames; j++) + { + mdlframe_t *frame = &mesh->frames[j]; + frame->vboID = 0; + CreateVBO(mesh, frame); + } + } + else if (mesh->tinyframes) + { + int j; + for (j = 0; j < model->meshes[i].numFrames; j++) + { + tinyframe_t *frame = &mesh->tinyframes[j]; + frame->vboID = 0; + CreateVBOTiny(mesh, frame); + } + } + } + + return model; +} + +// +// GenerateVertexNormals +// +// Creates a new normal for a vertex using the average of all of the polygons it belongs to. +// +void GenerateVertexNormals(model_t *model) +{ + int i; + for (i = 0; i < model->numMeshes; i++) + { + mesh_t *mesh = &model->meshes[i]; + + if (!mesh->frames) + continue; + + int j; + for (j = 0; j < mesh->numFrames; j++) + { + mdlframe_t *frame = &mesh->frames[j]; + int memTag = PU_STATIC; + float *newNormals = (float*)Z_Malloc(sizeof(float)*3*mesh->numTriangles*3, memTag, 0); + M_Memcpy(newNormals, frame->normals, sizeof(float)*3*mesh->numTriangles*3); + +/* if (!systemSucks) + { + memTag = Z_GetTag(frame->tangents); + float *newTangents = (float*)Z_Malloc(sizeof(float)*3*mesh->numTriangles*3, memTag); + M_Memcpy(newTangents, frame->tangents, sizeof(float)*3*mesh->numTriangles*3); + }*/ + + int k; + float *vertPtr = frame->vertices; + for (k = 0; k < mesh->numVertices; k++) + { + float x, y, z; + x = *vertPtr++; + y = *vertPtr++; + z = *vertPtr++; + + int vCount = 0; + vector_t normal; + normal.x = normal.y = normal.z = 0; + int l; + float *testPtr = frame->vertices; + for (l = 0; l < mesh->numVertices; l++) + { + float testX, testY, testZ; + testX = *testPtr++; + testY = *testPtr++; + testZ = *testPtr++; + + if (x != testX || y != testY || z != testZ) + continue; + + // Found a vertex match! Add it... + normal.x += frame->normals[3 * l + 0]; + normal.y += frame->normals[3 * l + 1]; + normal.z += frame->normals[3 * l + 2]; + vCount++; + } + + if (vCount > 1) + { +// Vector::Normalize(&normal); + newNormals[3 * k + 0] = (float)normal.x; + newNormals[3 * k + 1] = (float)normal.y; + newNormals[3 * k + 2] = (float)normal.z; + +/* if (!systemSucks) + { + Vector::vector_t tangent; + Vector::Tangent(&normal, &tangent); + newTangents[3 * k + 0] = tangent.x; + newTangents[3 * k + 1] = tangent.y; + newTangents[3 * k + 2] = tangent.z; + }*/ + } + } + + float *oldNormals = frame->normals; + frame->normals = newNormals; + Z_Free(oldNormals); + +/* if (!systemSucks) + { + float *oldTangents = frame->tangents; + frame->tangents = newTangents; + Z_Free(oldTangents); + }*/ + } + } +} + +typedef struct materiallist_s +{ + struct materiallist_s *next; + struct materiallist_s *prev; + material_t *material; +} materiallist_t; + +static bool AddMaterialToList(materiallist_t **head, material_t *material) +{ + materiallist_t *node; + for (node = *head; node; node = node->next) + { + if (node->material == material) + return false; + } + + // Didn't find it, so add to the list + materiallist_t *newMatNode = (materiallist_t*)Z_Malloc(sizeof(materiallist_t), PU_CACHE, 0); + newMatNode->material = material; + ListAdd(newMatNode, (listitem_t**)head); + return true; +} + +// +// Optimize +// +// Groups triangles from meshes in the model +// Only works for models with 1 frame +// +void Optimize(model_t *model) +{ + if (model->numMeshes <= 1) + return; // No need + + int numMeshes = 0; + int i; + materiallist_t *matListHead = NULL; + for (i = 0; i < model->numMeshes; i++) + { + mesh_t *curMesh = &model->meshes[i]; + + if (curMesh->numFrames > 1) + return; // Can't optimize models with > 1 frame + + if (!curMesh->frames) + return; // Don't optimize tinyframe models (no need) + + // We are condensing to 1 mesh per material, so + // the # of materials we use will be the new + // # of meshes + if (AddMaterialToList(&matListHead, curMesh->frames[0].material)) + numMeshes++; + } + + int memTag = PU_STATIC; + mesh_t *newMeshes = (mesh_t*)Z_Calloc(sizeof(mesh_t) * numMeshes, memTag, 0); + + i = 0; + materiallist_t *node; + for (node = matListHead; node; node = node->next) + { + material_t *curMat = node->material; + mesh_t *newMesh = &newMeshes[i]; + + // Find all triangles with this material and count them + int numTriangles = 0; + int j; + for (j = 0; j < model->numMeshes; j++) + { + mesh_t *curMesh = &model->meshes[j]; + + if (curMesh->frames[0].material == curMat) + numTriangles += curMesh->numTriangles; + } + + newMesh->numFrames = 1; + newMesh->numTriangles = numTriangles; + newMesh->numVertices = numTriangles * 3; + newMesh->uvs = (float*)Z_Malloc(sizeof(float)*2*numTriangles*3, memTag, 0); +// if (node->material->lightmap) +// newMesh->lightuvs = (float*)Z_Malloc(sizeof(float)*2*numTriangles*3, memTag, 0); + newMesh->frames = (mdlframe_t*)Z_Calloc(sizeof(mdlframe_t), memTag, 0); + mdlframe_t *curFrame = &newMesh->frames[0]; + + curFrame->material = curMat; + curFrame->normals = (float*)Z_Malloc(sizeof(float)*3*numTriangles*3, memTag, 0); +// if (!systemSucks) +// curFrame->tangents = (float*)Z_Malloc(sizeof(float)*3*numTriangles*3, memTag, 0); + curFrame->vertices = (float*)Z_Malloc(sizeof(float)*3*numTriangles*3, memTag, 0); + curFrame->colors = (byte*)Z_Malloc(sizeof(byte)*4*numTriangles*3, memTag, 0); + + // Now traverse the meshes of the model, adding in + // vertices/normals/uvs that match the current material + int uvCount = 0; + int vertCount = 0; + int colorCount = 0; + for (j = 0; j < model->numMeshes; j++) + { + mesh_t *curMesh = &model->meshes[j]; + + if (curMesh->frames[0].material == curMat) + { + float *dest; + float *src; + + M_Memcpy(&newMesh->uvs[uvCount], + curMesh->uvs, + sizeof(float)*2*curMesh->numTriangles*3); + +/* if (node->material->lightmap) + { + M_Memcpy(&newMesh->lightuvs[uvCount], + curMesh->lightuvs, + sizeof(float)*2*curMesh->numTriangles*3); + }*/ + uvCount += 2*curMesh->numTriangles*3; + + dest = (float*)newMesh->frames[0].vertices; + src = (float*)curMesh->frames[0].vertices; + M_Memcpy(&dest[vertCount], + src, + sizeof(float)*3*curMesh->numTriangles*3); + + dest = (float*)newMesh->frames[0].normals; + src = (float*)curMesh->frames[0].normals; + M_Memcpy(&dest[vertCount], + src, + sizeof(float)*3*curMesh->numTriangles*3); + +/* if (!systemSucks) + { + dest = (float*)newMesh->frames[0].tangents; + src = (float*)curMesh->frames[0].tangents; + M_Memcpy(&dest[vertCount], + src, + sizeof(float)*3*curMesh->numTriangles*3); + }*/ + + vertCount += 3 * curMesh->numTriangles * 3; + + byte *destByte; + byte *srcByte; + destByte = (byte*)newMesh->frames[0].colors; + srcByte = (byte*)curMesh->frames[0].colors; + + if (srcByte) + { + M_Memcpy(&destByte[colorCount], + srcByte, + sizeof(byte)*4*curMesh->numTriangles*3); + } + else + { + memset(&destByte[colorCount], + 255, + sizeof(byte)*4*curMesh->numTriangles*3); + } + + colorCount += 4 * curMesh->numTriangles * 3; + } + } + + i++; + } + + CONS_Printf("Model::Optimize(): Model reduced from %d to %d meshes.\n", model->numMeshes, numMeshes); + model->meshes = newMeshes; + model->numMeshes = numMeshes; +} + +void GeneratePolygonNormals(model_t *model, int ztag) +{ + int i; + for (i = 0; i < model->numMeshes; i++) + { + mesh_t *mesh = &model->meshes[i]; + + if (!mesh->frames) + continue; + + int j; + for (j = 0; j < mesh->numFrames; j++) + { + mdlframe_t *frame = &mesh->frames[j]; + + frame->polyNormals = (vector_t*)Z_Malloc(sizeof(vector_t) * mesh->numTriangles, ztag, 0); + + const float *vertices = frame->vertices; + vector_t *polyNormals = frame->polyNormals; + int k; + for (k = 0; k < mesh->numTriangles; k++) + { +// Vector::Normal(vertices, polyNormals); + vertices += 3 * 3; + polyNormals++; + } + } + } +} + +// +// Reload +// +// Reload VBOs +// +void Reload(void) +{ +/* model_t *node; + for (node = modelHead; node; node = node->next) + { + int i; + for (i = 0; i < node->numMeshes; i++) + { + mesh_t *mesh = &node->meshes[i]; + + if (mesh->frames) + { + int j; + for (j = 0; j < mesh->numFrames; j++) + CreateVBO(mesh, &mesh->frames[j]); + } + else if (mesh->tinyframes) + { + int j; + for (j = 0; j < mesh->numFrames; j++) + CreateVBO(mesh, &mesh->tinyframes[j]); + } + } + }*/ +} + +void DeleteVBOs(model_t *model) +{ +/* for (int i = 0; i < model->numMeshes; i++) + { + mesh_t *mesh = &model->meshes[i]; + + if (mesh->frames) + { + for (int j = 0; j < mesh->numFrames; j++) + { + mdlframe_t *frame = &mesh->frames[j]; + if (!frame->vboID) + continue; + bglDeleteBuffers(1, &frame->vboID); + frame->vboID = 0; + } + } + else if (mesh->tinyframes) + { + for (int j = 0; j < mesh->numFrames; j++) + { + tinyframe_t *frame = &mesh->tinyframes[j]; + if (!frame->vboID) + continue; + bglDeleteBuffers(1, &frame->vboID); + frame->vboID = 0; + } + } + }*/ +} diff --git a/src/hardware/hw_model.h b/src/hardware/hw_model.h new file mode 100644 index 000000000..ed7e41a55 --- /dev/null +++ b/src/hardware/hw_model.h @@ -0,0 +1,104 @@ +/* + From the 'Wizard2' engine by Spaddlewit Inc. ( http://www.spaddlewit.com ) + An experimental work-in-progress. + + Donated to Sonic Team Junior and adapted to work with + Sonic Robo Blast 2. The license of this code matches whatever + the licensing is for Sonic Robo Blast 2. +*/ + +#ifndef _HW_MODEL_H_ +#define _HW_MODEL_H_ + +#include "../doomtype.h" + +typedef struct +{ + float x, y, z; +} vector_t; + +extern vector_t vectorXaxis; +extern vector_t vectorYaxis; +extern vector_t vectorZaxis; + +void VectorRotate(vector_t *rotVec, const vector_t *axisVec, float angle); + +typedef struct +{ + float ambient[4], diffuse[4], specular[4], emissive[4]; + float shininess; + bool spheremap; +// Texture::texture_t *texture; +// Texture::texture_t *lightmap; +} material_t; + +typedef struct +{ + material_t *material; // Pointer to the allocated 'materials' list in model_t + float *vertices; + float *normals; + float *tangents; + byte *colors; + unsigned int vboID; + vector_t *polyNormals; +} mdlframe_t; + +typedef struct +{ + material_t *material; + short *vertices; + char *normals; + char *tangents; + unsigned int vboID; +} tinyframe_t; + +// Equivalent to MD3's many 'surfaces' +typedef struct mesh_s +{ + int numVertices; + int numTriangles; + + float *uvs; + float *lightuvs; + + int numFrames; + mdlframe_t *frames; + tinyframe_t *tinyframes; + unsigned short *indices; +} mesh_t; + +typedef struct tag_s +{ + char name[64]; +// matrix_t transform; +} tag_t; + +typedef struct model_s +{ + int maxNumFrames; + + int numMaterials; + material_t *materials; + int numMeshes; + mesh_t *meshes; + int numTags; + tag_t *tags; + + char *mdlFilename; + boolean unloaded; +} model_t; + +extern int numModels; +extern model_t *modelHead; + +tag_t *GetTagByName(model_t *model, char *name, int frame); +model_t *LoadModel(const char *filename, int ztag); +void UnloadModel(model_t *model); +void Optimize(model_t *model); +void GenerateVertexNormals(model_t *model); +void GeneratePolygonNormals(model_t *model, int ztag); +void CreateVBOTiny(mesh_t *mesh, tinyframe_t *frame); +void CreateVBO(mesh_t *mesh, mdlframe_t *frame); +void DeleteVBOs(model_t *model); + +#endif diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 2d9f42192..4cd12b7ea 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -245,6 +245,12 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...) #define pglColor4f glColor4f #define pglColor4fv glColor4fv #define pglTexCoord2f glTexCoord2f +#define pglVertexPointer glVertexPointer +#define pglNormalPointer glNormalPointer +#define pglTexCoordPointer glTexCoordPointer +#define pglDrawArrays glDrawArrays +#define pglEnableClientState glEnableClientState +#define pglDisableClientState pglDisableClientState /* Lighting */ #define pglShadeModel glShadeModel @@ -357,6 +363,18 @@ typedef void (APIENTRY * PFNglColor4fv) (const GLfloat *v); static PFNglColor4fv pglColor4fv; typedef void (APIENTRY * PFNglTexCoord2f) (GLfloat s, GLfloat t); static PFNglTexCoord2f pglTexCoord2f; +typedef void (APIENTRY * PFNglVertexPointer) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +static PFNglVertexPointer pglVertexPointer; +typedef void (APIENTRY * PFNglNormalPointer) (GLenum type, GLsizei stride, const GLvoid *pointer); +static PFNglNormalPointer pglNormalPointer; +typedef void (APIENTRY * PFNglTexCoordPointer) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +static PFNglTexCoordPointer pglTexCoordPointer; +typedef void (APIENTRY * PFNglDrawArrays) (GLenum mode, GLint first, GLsizei count); +static PFNglDrawArrays pglDrawArrays; +typedef void (APIENTRY * PFNglEnableClientState) (GLenum cap); +static PFNglEnableClientState pglEnableClientState; +typedef void (APIENTRY * PFNglDisableClientState) (GLenum cap); +static PFNglDisableClientState pglDisableClientState; /* Lighting */ typedef void (APIENTRY * PFNglShadeModel) (GLenum mode); @@ -495,6 +513,12 @@ boolean SetupGLfunc(void) GETOPENGLFUNC(pglColor4f , glColor4f) GETOPENGLFUNC(pglColor4fv , glColor4fv) GETOPENGLFUNC(pglTexCoord2f , glTexCoord2f) + GETOPENGLFUNC(pglVertexPointer, glVertexPointer) + GETOPENGLFUNC(pglNormalPointer, glNormalPointer) + GETOPENGLFUNC(pglTexCoordPointer, glTexCoordPointer) + GETOPENGLFUNC(pglDrawArrays, glDrawArrays) + GETOPENGLFUNC(pglEnableClientState, glEnableClientState) + GETOPENGLFUNC(pglDisableClientState, glDisableClientState) GETOPENGLFUNC(pglShadeModel , glShadeModel) GETOPENGLFUNC(pglLightfv, glLightfv) @@ -1878,14 +1902,15 @@ EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value) } } -static void DrawMD2Ex(INT32 *gl_cmd_buffer, md2_frame_t *frame, INT32 duration, INT32 tics, md2_frame_t *nextframe, FTransform *pos, float scale, UINT8 flipped, UINT8 *color) -{ +static void DrawModelEx(model_t *model, mdlframe_t *frame, INT32 duration, INT32 tics, mdlframe_t *nextframe, FTransform *pos, float scale, UINT8 flipped, UINT8 *color) +{ INT32 val, count, pindex; GLfloat s, t; GLfloat ambient[4]; GLfloat diffuse[4]; float pol = 0.0f; + scale *= 0.5f; float scalex = scale, scaley = scale, scalez = scale; // Because Otherwise, scaling the screen negatively vertically breaks the lighting @@ -1963,68 +1988,107 @@ static void DrawMD2Ex(INT32 *gl_cmd_buffer, md2_frame_t *frame, INT32 duration, pglRotatef(pos->angley, 0.0f, -1.0f, 0.0f); pglRotatef(pos->anglex, -1.0f, 0.0f, 0.0f); - val = *gl_cmd_buffer++; + pglScalef(scalex, scaley, scalez); - while (val != 0) + mesh_t *mesh = &model->meshes[0]; + + if (!nextframe || pol == 0.0f) { - if (val < 0) + // Zoom! Take advantage of just shoving the entire arrays to the GPU. + pglEnableClientState(GL_VERTEX_ARRAY); + pglEnableClientState(GL_TEXTURE_COORD_ARRAY); + pglEnableClientState(GL_NORMAL_ARRAY); + pglVertexPointer(3, GL_FLOAT, 0, frame->vertices); + pglNormalPointer(GL_FLOAT, 0, frame->normals); + pglTexCoordPointer(2, GL_FLOAT, 0, mesh->uvs); + pglDrawArrays(GL_TRIANGLES, 0, mesh->numTriangles * 3); + pglDisableClientState(GL_NORMAL_ARRAY); + pglDisableClientState(GL_TEXTURE_COORD_ARRAY); + pglDisableClientState(GL_TEXTURE_COORD_ARRAY); + /* + pglBegin(GL_TRIANGLES); + + int i = 0; + float *uvPtr = mesh->uvs; + float *frameVert = frame->vertices; + float *frameNormal = frame->normals; + for (i = 0; i < mesh->numTriangles; i++) { - pglBegin(GL_TRIANGLE_FAN); - count = -val; - } - else - { - pglBegin(GL_TRIANGLE_STRIP); - count = val; + float uvx = *uvPtr++; + float uvy = *uvPtr++; + + // Interpolate + float px1 = *frameVert++; + float py1 = *frameVert++; + float pz1 = *frameVert++; + float nx1 = *frameNormal++; + float ny1 = *frameNormal++; + float nz1 = *frameNormal++; + + pglTexCoord2f(uvx, uvy); + pglNormal3f(nx1, ny1, nz1); + pglVertex3f(px1, py1, pz1); } - while (count--) + pglEnd();*/ + } + else + { + // Dangit, I soooo want to do this in a GLSL shader... + pglBegin(GL_TRIANGLES); + + int i = 0; + float *uvPtr = mesh->uvs; + float *frameVert = frame->vertices; + float *frameNormal = frame->normals; + float *nextFrameVert = nextframe->vertices; + float *nextFrameNormal = frame->normals; + for (i = 0; i < mesh->numTriangles; i++) { - s = *(float *) gl_cmd_buffer++; - t = *(float *) gl_cmd_buffer++; - pindex = *gl_cmd_buffer++; + float uvx = *uvPtr++; + float uvy = *uvPtr++; - pglTexCoord2f(s, t); + // Interpolate + float px1 = *frameVert++; + float px2 = *nextFrameVert++; + float py1 = *frameVert++; + float py2 = *nextFrameVert++; + float pz1 = *frameVert++; + float pz2 = *nextFrameVert++; + float nx1 = *frameNormal++; + float nx2 = *nextFrameNormal++; + float ny1 = *frameNormal++; + float ny2 = *nextFrameNormal++; + float nz1 = *frameNormal++; + float nz2 = *nextFrameNormal++; - if (!nextframe || pol == 0.0f) - { - pglNormal3f(frame->vertices[pindex].normal[0], - frame->vertices[pindex].normal[1], - frame->vertices[pindex].normal[2]); - - pglVertex3f(frame->vertices[pindex].vertex[0]*scalex/2.0f, - frame->vertices[pindex].vertex[1]*scaley/2.0f, - frame->vertices[pindex].vertex[2]*scalez/2.0f); - } - else - { - // Interpolate - float px1 = frame->vertices[pindex].vertex[0]*scalex/2.0f; - float px2 = nextframe->vertices[pindex].vertex[0]*scalex/2.0f; - float py1 = frame->vertices[pindex].vertex[1]*scaley/2.0f; - float py2 = nextframe->vertices[pindex].vertex[1]*scaley/2.0f; - float pz1 = frame->vertices[pindex].vertex[2]*scalez/2.0f; - float pz2 = nextframe->vertices[pindex].vertex[2]*scalez/2.0f; - float nx1 = frame->vertices[pindex].normal[0]; - float nx2 = nextframe->vertices[pindex].normal[0]; - float ny1 = frame->vertices[pindex].normal[1]; - float ny2 = nextframe->vertices[pindex].normal[1]; - float nz1 = frame->vertices[pindex].normal[2]; - float nz2 = nextframe->vertices[pindex].normal[2]; - - pglNormal3f((nx1 + pol * (nx2 - nx1)), - (ny1 + pol * (ny2 - ny1)), - (nz1 + pol * (nz2 - nz1))); - pglVertex3f((px1 + pol * (px2 - px1)), - (py1 + pol * (py2 - py1)), - (pz1 + pol * (pz2 - pz1))); - } + pglTexCoord2f(uvx, uvy); + pglNormal3f((nx1 + pol * (nx2 - nx1)), + (ny1 + pol * (ny2 - ny1)), + (nz1 + pol * (nz2 - nz1))); + pglVertex3f((px1 + pol * (px2 - px1)), + (py1 + pol * (py2 - py1)), + (pz1 + pol * (pz2 - pz1))); } pglEnd(); - - val = *gl_cmd_buffer++; } + +/* if (lightType != LIGHT_NONE) + { + glVertexAttribPointer(program->slots[Shaders::A_NORMAL_SLOT], 3, BGL_FLOAT, BGL_FALSE, 0, frame->normals); + // if (normalmapped) + // bglVertexAttribPointer(program->slots[Shaders::A_TANGENT_SLOT], 3, BGL_FLOAT, BGL_FALSE, 0, frame->tangents); + } + + if (frame->colors) + glVertexAttribPointer(program->slots[Shaders::A_COLOR_SLOT], 4, GL_UNSIGNED_BYTE, BGL_TRUE, 0, frame->colors); + else + { + SetGlobalWhiteColorArray(mesh->numTriangles * 3); + glVertexAttribPointer(program->slots[Shaders::A_COLOR_SLOT], 3, BGL_UNSIGNED_BYTE, BGL_TRUE, 0, globalWhiteColorArray); + } + */ pglPopMatrix(); // should be the same as glLoadIdentity if (color) pglDisable(GL_LIGHTING); @@ -2035,17 +2099,11 @@ static void DrawMD2Ex(INT32 *gl_cmd_buffer, md2_frame_t *frame, INT32 duration, // -----------------+ // HWRAPI DrawMD2 : Draw an MD2 model with glcommands // -----------------+ -EXPORT void HWRAPI(DrawMD2i) (INT32 *gl_cmd_buffer, md2_frame_t *frame, INT32 duration, INT32 tics, md2_frame_t *nextframe, FTransform *pos, float scale, UINT8 flipped, UINT8 *color) +EXPORT void HWRAPI(DrawModel) (model_t *model, mdlframe_t *frame, INT32 duration, INT32 tics, mdlframe_t *nextframe, FTransform *pos, float scale, UINT8 flipped, UINT8 *color) { - DrawMD2Ex(gl_cmd_buffer, frame, duration, tics, nextframe, pos, scale, flipped, color); + DrawModelEx(model, frame, duration, tics, nextframe, pos, scale, flipped, color); } -EXPORT void HWRAPI(DrawMD2) (INT32 *gl_cmd_buffer, md2_frame_t *frame, FTransform *pos, float scale) -{ - DrawMD2Ex(gl_cmd_buffer, frame, 0, 0, NULL, pos, scale, false, NULL); -} - - // -----------------+ // SetTransform : // -----------------+ diff --git a/src/hardware/u_list.c b/src/hardware/u_list.c new file mode 100644 index 000000000..dc49a74e7 --- /dev/null +++ b/src/hardware/u_list.c @@ -0,0 +1,230 @@ +/* + From the 'Wizard2' engine by Spaddlewit Inc. ( http://www.spaddlewit.com ) + An experimental work-in-progress. + + Donated to Sonic Team Junior and adapted to work with + Sonic Robo Blast 2. The license of this code matches whatever + the licensing is for Sonic Robo Blast 2. +*/ + +#include "u_list.h" +#include "../z_zone.h" + +// Utility for managing +// structures in a linked +// list. +// +// Struct must have "next" and "prev" pointers +// as its first two variables. +// + +// +// ListAdd +// +// Adds an item to the list +// +void ListAdd(void *pItem, listitem_t **itemHead) +{ + listitem_t *item = (listitem_t*)pItem; + + if (*itemHead == NULL) + { + *itemHead = item; + (*itemHead)->prev = (*itemHead)->next = NULL; + } + else + { + listitem_t *tail; + tail = *itemHead; + + while (tail->next != NULL) + tail = tail->next; + + tail->next = item; + + tail->next->prev = tail; + + item->next = NULL; + } +} + +// +// ListAddFront +// +// Adds an item to the front of the list +// (This is much faster) +// +void ListAddFront(void *pItem, listitem_t **itemHead) +{ + listitem_t *item = (listitem_t*)pItem; + + if (*itemHead == NULL) + { + *itemHead = item; + (*itemHead)->prev = (*itemHead)->next = NULL; + } + else + { + (*itemHead)->prev = item; + item->next = (*itemHead); + item->prev = NULL; + *itemHead = item; + } +} + +// +// ListAddBefore +// +// Adds an item before the item specified in the list +// +void ListAddBefore(void *pItem, void *pSpot, listitem_t **itemHead) +{ + listitem_t *item = (listitem_t*)pItem; + listitem_t *spot = (listitem_t*)pSpot; + + listitem_t *prev = spot->prev; + + if (!prev) + ListAddFront(pItem, itemHead); + else + { + item->next = spot; + spot->prev = item; + item->prev = prev; + prev->next = item; + } +} + +// +// ListAddAfter +// +// Adds an item after the item specified in the list +// +void ListAddAfter(void *pItem, void *pSpot, listitem_t **itemHead) +{ + listitem_t *item = (listitem_t*)pItem; + listitem_t *spot = (listitem_t*)pSpot; + + listitem_t *next = spot->next; + + if (!next) + ListAdd(pItem, itemHead); + else + { + item->prev = spot; + spot->next = item; + item->next = next; + next->prev = item; + } +} + +// +// ListRemove +// +// Take an item out of the list and free its memory. +// +void ListRemove(void *pItem, listitem_t **itemHead) +{ + listitem_t *item = (listitem_t*)pItem; + + if (item == *itemHead) // Start of list + { + *itemHead = item->next; + + if (*itemHead) + (*itemHead)->prev = NULL; + } + else if (item->next == NULL) // end of list + { + item->prev->next = NULL; + } + else // Somewhere in between + { + item->prev->next = item->next; + item->next->prev = item->prev; + } + + Z_Free (item); +} + +// +// ListRemoveAll +// +// Removes all items from the list, freeing their memory. +// +void ListRemoveAll(listitem_t **itemHead) +{ + listitem_t *item; + listitem_t *next; + for (item = *itemHead; item; item = next) + { + next = item->next; + ListRemove(item, itemHead); + } +} + +// +// ListRemoveNoFree +// +// Take an item out of the list, but don't free its memory. +// +void ListRemoveNoFree(void *pItem, listitem_t **itemHead) +{ + listitem_t *item = (listitem_t*)pItem; + + if (item == *itemHead) // Start of list + { + *itemHead = item->next; + + if (*itemHead) + (*itemHead)->prev = NULL; + } + else if (item->next == NULL) // end of list + { + item->prev->next = NULL; + } + else // Somewhere in between + { + item->prev->next = item->next; + item->next->prev = item->prev; + } +} + +// +// ListGetCount +// +// Counts the # of items in a list +// Should not be used in performance-minded code +// +unsigned int ListGetCount(void *itemHead) +{ + listitem_t *item = (listitem_t*)itemHead; + + unsigned int count = 0; + for (; item; item = item->next) + count++; + + return count; +} + +// +// ListGetByIndex +// +// Gets an item in the list by its index +// Should not be used in performance-minded code +// +listitem_t *ListGetByIndex(void *itemHead, unsigned int index) +{ + listitem_t *head = (listitem_t*)itemHead; + unsigned int count = 0; + listitem_t *node; + for (node = head; node; node = node->next) + { + if (count == index) + return node; + + count++; + } + + return NULL; +} diff --git a/src/hardware/u_list.h b/src/hardware/u_list.h new file mode 100644 index 000000000..7e9a3cabd --- /dev/null +++ b/src/hardware/u_list.h @@ -0,0 +1,29 @@ +/* + From the 'Wizard2' engine by Spaddlewit Inc. ( http://www.spaddlewit.com ) + An experimental work-in-progress. + + Donated to Sonic Team Junior and adapted to work with + Sonic Robo Blast 2. The license of this code matches whatever + the licensing is for Sonic Robo Blast 2. +*/ + +#ifndef _U_LIST_H_ +#define _U_LIST_H_ + +typedef struct listitem_s +{ + struct listitem_s *next; + struct listitem_s *prev; +} listitem_t; + +void ListAdd(void *pItem, listitem_t **itemHead); +void ListAddFront(void *pItem, listitem_t **itemHead); +void ListAddBefore(void *pItem, void *pSpot, listitem_t **itemHead); +void ListAddAfter(void *pItem, void *pSpot, listitem_t **itemHead); +void ListRemove(void *pItem, listitem_t **itemHead); +void ListRemoveAll(listitem_t **itemHead); +void ListRemoveNoFree(void *pItem, listitem_t **itemHead); +unsigned int ListGetCount(void *itemHead); +listitem_t *ListGetByIndex(void *itemHead, unsigned int index); + +#endif diff --git a/src/sdl/Srb2SDL-vc10.vcxproj b/src/sdl/Srb2SDL-vc10.vcxproj index 3e4a9ebb1..2c33379ed 100644 --- a/src/sdl/Srb2SDL-vc10.vcxproj +++ b/src/sdl/Srb2SDL-vc10.vcxproj @@ -151,6 +151,10 @@ + + + + @@ -288,8 +292,12 @@ + + + + @@ -297,7 +305,7 @@ - + diff --git a/src/sdl/Srb2SDL-vc10.vcxproj.filters b/src/sdl/Srb2SDL-vc10.vcxproj.filters index ac0b03177..525a55393 100644 --- a/src/sdl/Srb2SDL-vc10.vcxproj.filters +++ b/src/sdl/Srb2SDL-vc10.vcxproj.filters @@ -246,6 +246,18 @@ Hw_Hardware + + Hw_Hardware + + + Hw_Hardware + + + Hw_Hardware + + + Hw_Hardware + I_Interface @@ -621,9 +633,21 @@ Hw_Hardware + + Hw_Hardware + + + Hw_Hardware + + + Hw_Hardware + Hw_Hardware + + Hw_Hardware + I_Interface diff --git a/src/sdl/hwsym_sdl.c b/src/sdl/hwsym_sdl.c index 05ac6450e..7962e01b1 100644 --- a/src/sdl/hwsym_sdl.c +++ b/src/sdl/hwsym_sdl.c @@ -87,8 +87,7 @@ void *hwSym(const char *funcName,void *handle) GETFUNC(ClearMipMapCache); GETFUNC(SetSpecialState); GETFUNC(GetTextureUsed); - GETFUNC(DrawMD2); - GETFUNC(DrawMD2i); + GETFUNC(DrawModel); GETFUNC(SetTransform); GETFUNC(GetRenderVersion); #ifdef SHUFFLE diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 2c199c2d0..6ce11fc74 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1483,8 +1483,7 @@ void I_StartupGraphics(void) HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL); HWD.pfnSetPalette = hwSym("SetPalette",NULL); HWD.pfnGetTextureUsed = hwSym("GetTextureUsed",NULL); - HWD.pfnDrawMD2 = hwSym("DrawMD2",NULL); - HWD.pfnDrawMD2i = hwSym("DrawMD2i",NULL); + HWD.pfnDrawModel = hwSym("DrawModel",NULL); HWD.pfnSetTransform = hwSym("SetTransform",NULL); HWD.pfnGetRenderVersion = hwSym("GetRenderVersion",NULL); #ifdef SHUFFLE diff --git a/src/win32/Srb2win-vc10.vcxproj b/src/win32/Srb2win-vc10.vcxproj index 5bfa29b8c..3056b975a 100644 --- a/src/win32/Srb2win-vc10.vcxproj +++ b/src/win32/Srb2win-vc10.vcxproj @@ -124,7 +124,11 @@ + + + + @@ -132,7 +136,7 @@ - + @@ -287,6 +291,10 @@ + + + + diff --git a/src/win32/Srb2win-vc10.vcxproj.filters b/src/win32/Srb2win-vc10.vcxproj.filters index d20dd672b..1a2a7f80d 100644 --- a/src/win32/Srb2win-vc10.vcxproj.filters +++ b/src/win32/Srb2win-vc10.vcxproj.filters @@ -108,9 +108,21 @@ Hw_Hardware + + Hw_Hardware + + + Hw_Hardware + + + Hw_Hardware + Hw_Hardware + + Hw_Hardware + Hw_Hardware @@ -506,6 +518,15 @@ Hw_Hardware + + Hw_Hardware + + + Hw_Hardware + + + Hw_Hardware + Hw_Hardware @@ -515,6 +536,9 @@ Hw_Hardware + + Hw_Hardware + BLUA diff --git a/src/win32/win_dll.c b/src/win32/win_dll.c index 71eda0437..bc67f04a5 100644 --- a/src/win32/win_dll.c +++ b/src/win32/win_dll.c @@ -109,8 +109,7 @@ static loadfunc_t hwdFuncTable[] = { {"GClipRect@20", &hwdriver.pfnGClipRect}, {"ClearMipMapCache@0", &hwdriver.pfnClearMipMapCache}, {"SetSpecialState@8", &hwdriver.pfnSetSpecialState}, - {"DrawMD2@16", &hwdriver.pfnDrawMD2}, - {"DrawMD2i@36", &hwdriver.pfnDrawMD2i}, + {"DrawModel@16", &hwdriver.pfnDrawModel}, {"SetTransform@4", &hwdriver.pfnSetTransform}, {"GetTextureUsed@0", &hwdriver.pfnGetTextureUsed}, {"GetRenderVersion@0", &hwdriver.pfnGetRenderVersion}, @@ -140,8 +139,7 @@ static loadfunc_t hwdFuncTable[] = { {"GClipRect", &hwdriver.pfnGClipRect}, {"ClearMipMapCache", &hwdriver.pfnClearMipMapCache}, {"SetSpecialState", &hwdriver.pfnSetSpecialState}, - {"DrawMD2", &hwdriver.pfnDrawMD2}, - {"DrawMD2i", &hwdriver.pfnDrawMD2i}, + {"DrawModel", &hwdriver.pfnDrawModel}, {"SetTransform", &hwdriver.pfnSetTransform}, {"GetTextureUsed", &hwdriver.pfnGetTextureUsed}, {"GetRenderVersion", &hwdriver.pfnGetRenderVersion}, From 76dabd5e9d057d08e96985c90ab53fc2864ef441 Mon Sep 17 00:00:00 2001 From: Arthur Date: Sun, 16 Dec 2018 12:04:10 -0500 Subject: [PATCH 03/74] Support for 'tinyframes', and lots more optimization --- src/hardware/hw_drv.h | 2 +- src/hardware/hw_md2.c | 5 +- src/hardware/hw_md2load.c | 16 +-- src/hardware/hw_md3load.c | 68 +++++---- src/hardware/r_opengl/r_opengl.c | 228 +++++++++++++++++++------------ 5 files changed, 183 insertions(+), 136 deletions(-) diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index 0afd6d272..7b45b0974 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -58,7 +58,7 @@ EXPORT void HWRAPI(ClearMipMapCache) (void); EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value); //Hurdler: added for new development -EXPORT void HWRAPI(DrawModel) (model_t *model, mdlframe_t *frame, INT32 duration, INT32 tics, mdlframe_t *nextframe, FTransform *pos, float scale, UINT8 flipped, UINT8 *color); +EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 *color); EXPORT void HWRAPI(SetTransform) (FTransform *ptransform); EXPORT INT32 HWRAPI(GetTextureUsed) (void); EXPORT INT32 HWRAPI(GetRenderVersion) (void); diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index e323f1a41..a0d86e9f7 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -887,7 +887,8 @@ void HWR_DrawMD2(gr_vissprite_t *spr) FSurfaceInfo Surf; char filename[64]; - INT32 frame; + INT32 frame = 0; + INT32 nextFrame = -1; FTransform p; md2_t *md2; UINT8 color[4]; @@ -1101,7 +1102,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) p.flip = atransform.flip; - HWD.pfnDrawModel(md2->model, curr, durs, tics, next, &p, finalscale, flip, color); + HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, finalscale, flip, color); } } diff --git a/src/hardware/hw_md2load.c b/src/hardware/hw_md2load.c index 3b083fee4..998dc70b6 100644 --- a/src/hardware/hw_md2load.c +++ b/src/hardware/hw_md2load.c @@ -233,8 +233,6 @@ typedef struct // Load the model model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) { - useFloat = true; // Right now we always useFloat = true, because the GL subsystem needs some work for the other option to work. - model_t *retModel = NULL; md2header_t *header; @@ -397,17 +395,17 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) framePtr--; for (j = 0; j < header->numXYZ; j++, vertex++) { - *vertptr = (short)(((vertex->v[1] * framePtr->scale[1]) + framePtr->translate[1]) / dataScale); + *vertptr = (short)(((vertex->v[0] * framePtr->scale[0]) + framePtr->translate[0]) / dataScale); vertptr++; *vertptr = (short)(((vertex->v[2] * framePtr->scale[2]) + framePtr->translate[2]) / dataScale); vertptr++; - *vertptr = (short)(((vertex->v[0] * framePtr->scale[0]) + framePtr->translate[0]) / dataScale); + *vertptr = -1.0f * (short)(((vertex->v[1] * framePtr->scale[1]) + framePtr->translate[1]) / dataScale); vertptr++; // Normal + *normptr++ = (byte)(avertexnormals[vertex->lightNormalIndex][0] * 127); *normptr++ = (byte)(avertexnormals[vertex->lightNormalIndex][1] * 127); *normptr++ = (byte)(avertexnormals[vertex->lightNormalIndex][2] * 127); - *normptr++ = (byte)(avertexnormals[vertex->lightNormalIndex][0] * 127); } } @@ -419,17 +417,17 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) { *indexptr = trisPtr->meshIndex[0]; indexptr++; - *indexptr = trisPtr->meshIndex[2]; - indexptr++; *indexptr = trisPtr->meshIndex[1]; indexptr++; + *indexptr = trisPtr->meshIndex[2]; + indexptr++; + uvptr[trisPtr->meshIndex[0] * 2] = texcoords[trisPtr->stIndex[0]].s / (float)header->skinwidth; + uvptr[trisPtr->meshIndex[0] * 2 + 1] = (texcoords[trisPtr->stIndex[0]].t / (float)header->skinheight); uvptr[trisPtr->meshIndex[1] * 2] = texcoords[trisPtr->stIndex[1]].s / (float)header->skinwidth; uvptr[trisPtr->meshIndex[1] * 2 + 1] = (texcoords[trisPtr->stIndex[1]].t / (float)header->skinheight); uvptr[trisPtr->meshIndex[2] * 2] = texcoords[trisPtr->stIndex[2]].s / (float)header->skinwidth; uvptr[trisPtr->meshIndex[2] * 2 + 1] = (texcoords[trisPtr->stIndex[2]].t / (float)header->skinheight); - uvptr[trisPtr->meshIndex[0] * 2] = texcoords[trisPtr->stIndex[0]].s / (float)header->skinwidth; - uvptr[trisPtr->meshIndex[0] * 2 + 1] = (texcoords[trisPtr->stIndex[0]].t / (float)header->skinheight); } } else // Full float loading method diff --git a/src/hardware/hw_md3load.c b/src/hardware/hw_md3load.c index bac799cdb..87a2f6ed1 100644 --- a/src/hardware/hw_md3load.c +++ b/src/hardware/hw_md3load.c @@ -144,8 +144,6 @@ static bool latlnginit = false; model_t *MD3_LoadModel(const char *fileName, int ztag, boolean useFloat) { - useFloat = true; // Right now we always useFloat = true, because the GL subsystem needs some work for the other option to work. - if (!latlnginit) { LatLngInit(); @@ -307,20 +305,20 @@ model_t *MD3_LoadModel(const char *fileName, int ztag, boolean useFloat) for (k = 0; k < mdS->numVerts; k++) { // Vertex - *vertptr = mdV[k].y; + *vertptr = mdV[k].x; vertptr++; *vertptr = mdV[k].z; vertptr++; - *vertptr = mdV[k].x; + *vertptr = 1.0f - mdV[k].y; vertptr++; // Normal GetNormalFromLatLong(mdV[k].n, tempNormal); - *normptr = (byte)(tempNormal[1] * 127); + *normptr = (byte)(tempNormal[0] * 127); normptr++; *normptr = (byte)(tempNormal[2] * 127); normptr++; - *normptr = (byte)(tempNormal[0] * 127); + *normptr = (byte)(tempNormal[1] * 127); normptr++; } } @@ -331,7 +329,7 @@ model_t *MD3_LoadModel(const char *fileName, int ztag, boolean useFloat) { *uvptr = mdST[j].st[0]; uvptr++; - *uvptr = 1.0f - mdST[j].st[1]; + *uvptr = mdST[j].st[1]; uvptr++; } @@ -342,10 +340,10 @@ model_t *MD3_LoadModel(const char *fileName, int ztag, boolean useFloat) // Indices *indexptr = (unsigned short)mdT->index[0]; indexptr++; - *indexptr = (unsigned short)mdT->index[2]; - indexptr++; *indexptr = (unsigned short)mdT->index[1]; indexptr++; + *indexptr = (unsigned short)mdT->index[2]; + indexptr++; } } else // Traditional full-float loading method @@ -377,48 +375,48 @@ model_t *MD3_LoadModel(const char *fileName, int ztag, boolean useFloat) vertptr++; *vertptr = mdV[mdT->index[0]].z * dataScale; vertptr++; - *vertptr = mdV[mdT->index[0]].y * dataScale; + *vertptr = 1.0f - mdV[mdT->index[0]].y * dataScale; vertptr++; GetNormalFromLatLong(mdV[mdT->index[0]].n, tempNormal); - *normptr = tempNormal[1]; + *normptr = tempNormal[0]; normptr++; *normptr = tempNormal[2]; normptr++; - *normptr = tempNormal[0]; + *normptr = tempNormal[1]; normptr++; // Vertex 2 - *vertptr = mdV[mdT->index[2]].x * dataScale; - vertptr++; - *vertptr = mdV[mdT->index[2]].z * dataScale; - vertptr++; - *vertptr = mdV[mdT->index[2]].y * dataScale; - vertptr++; - - GetNormalFromLatLong(mdV[mdT->index[2]].n, tempNormal); - *normptr = tempNormal[1]; - normptr++; - *normptr = tempNormal[2]; - normptr++; - *normptr = tempNormal[0]; - normptr++; - - // Vertex 3 *vertptr = mdV[mdT->index[1]].x * dataScale; vertptr++; *vertptr = mdV[mdT->index[1]].z * dataScale; vertptr++; - *vertptr = mdV[mdT->index[1]].y * dataScale; + *vertptr = 1.0f - mdV[mdT->index[1]].y * dataScale; vertptr++; GetNormalFromLatLong(mdV[mdT->index[1]].n, tempNormal); - *normptr = tempNormal[1]; + *normptr = tempNormal[0]; normptr++; *normptr = tempNormal[2]; normptr++; + *normptr = tempNormal[1]; + normptr++; + + // Vertex 3 + *vertptr = mdV[mdT->index[2]].x * dataScale; + vertptr++; + *vertptr = mdV[mdT->index[2]].z * dataScale; + vertptr++; + *vertptr = 1.0f - mdV[mdT->index[2]].y * dataScale; + vertptr++; + + GetNormalFromLatLong(mdV[mdT->index[2]].n, tempNormal); *normptr = tempNormal[0]; normptr++; + *normptr = tempNormal[2]; + normptr++; + *normptr = tempNormal[1]; + normptr++; mdT++; // Advance to next triangle } @@ -436,16 +434,16 @@ model_t *MD3_LoadModel(const char *fileName, int ztag, boolean useFloat) *uvptr = mdST[mdT->index[0]].st[1]; uvptr++; - *uvptr = mdST[mdT->index[2]].st[0]; - uvptr++; - *uvptr = mdST[mdT->index[2]].st[1]; - uvptr++; - *uvptr = mdST[mdT->index[1]].st[0]; uvptr++; *uvptr = mdST[mdT->index[1]].st[1]; uvptr++; + *uvptr = mdST[mdT->index[2]].st[0]; + uvptr++; + *uvptr = mdST[mdT->index[2]].st[1]; + uvptr++; + mdT++; // Advance to next triangle } } diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 4cd12b7ea..7362ebbe6 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -241,14 +241,18 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...) #define pglBegin glBegin #define pglEnd glEnd #define pglVertex3f glVertex3f +#define pglVertex3sv glVertex3sv #define pglNormal3f glNormal3f +#define pglNormal3bv glNormal3bv #define pglColor4f glColor4f #define pglColor4fv glColor4fv #define pglTexCoord2f glTexCoord2f +#define pglTexCoord2fv glTexCoord2fv #define pglVertexPointer glVertexPointer #define pglNormalPointer glNormalPointer #define pglTexCoordPointer glTexCoordPointer #define pglDrawArrays glDrawArrays +#define pglDrawElements glDrawElements #define pglEnableClientState glEnableClientState #define pglDisableClientState pglDisableClientState @@ -355,14 +359,20 @@ typedef void (APIENTRY * PFNglEnd) (void); static PFNglEnd pglEnd; typedef void (APIENTRY * PFNglVertex3f) (GLfloat x, GLfloat y, GLfloat z); static PFNglVertex3f pglVertex3f; +typedef void (APIENTRY * PFNglVertex3sv) (const GLshort *v); +static PFNglVertex3sv pglVertex3sv; typedef void (APIENTRY * PFNglNormal3f) (GLfloat x, GLfloat y, GLfloat z); static PFNglNormal3f pglNormal3f; +typedef void (APIENTRY * PFNglNormal3bv)(const GLbyte *v); +static PFNglNormal3bv pglNormal3bv; typedef void (APIENTRY * PFNglColor4f) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); static PFNglColor4f pglColor4f; typedef void (APIENTRY * PFNglColor4fv) (const GLfloat *v); static PFNglColor4fv pglColor4fv; typedef void (APIENTRY * PFNglTexCoord2f) (GLfloat s, GLfloat t); static PFNglTexCoord2f pglTexCoord2f; +typedef void (APIENTRY * PFNglTexCoord2fv) (const GLfloat *v); +static PFNglTexCoord2fv pglTexCoord2fv; typedef void (APIENTRY * PFNglVertexPointer) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); static PFNglVertexPointer pglVertexPointer; typedef void (APIENTRY * PFNglNormalPointer) (GLenum type, GLsizei stride, const GLvoid *pointer); @@ -371,6 +381,8 @@ typedef void (APIENTRY * PFNglTexCoordPointer) (GLint size, GLenum type, GLsizei static PFNglTexCoordPointer pglTexCoordPointer; typedef void (APIENTRY * PFNglDrawArrays) (GLenum mode, GLint first, GLsizei count); static PFNglDrawArrays pglDrawArrays; +typedef void (APIENTRY * PFNglDrawElements) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices); +static PFNglDrawElements pglDrawElements; typedef void (APIENTRY * PFNglEnableClientState) (GLenum cap); static PFNglEnableClientState pglEnableClientState; typedef void (APIENTRY * PFNglDisableClientState) (GLenum cap); @@ -509,14 +521,18 @@ boolean SetupGLfunc(void) GETOPENGLFUNC(pglBegin , glBegin) GETOPENGLFUNC(pglEnd , glEnd) GETOPENGLFUNC(pglVertex3f , glVertex3f) + GETOPENGLFUNC(pglVertex3sv, glVertex3sv) GETOPENGLFUNC(pglNormal3f , glNormal3f) + GETOPENGLFUNC(pglNormal3bv, glNomral3bv) GETOPENGLFUNC(pglColor4f , glColor4f) GETOPENGLFUNC(pglColor4fv , glColor4fv) GETOPENGLFUNC(pglTexCoord2f , glTexCoord2f) + GETOPENGLFUNC(pglTexCoord2fv, glTexCoord2fv) GETOPENGLFUNC(pglVertexPointer, glVertexPointer) GETOPENGLFUNC(pglNormalPointer, glNormalPointer) GETOPENGLFUNC(pglTexCoordPointer, glTexCoordPointer) GETOPENGLFUNC(pglDrawArrays, glDrawArrays) + GETOPENGLFUNC(pglDrawElements, glDrawElements) GETOPENGLFUNC(pglEnableClientState, glEnableClientState) GETOPENGLFUNC(pglDisableClientState, glDisableClientState) @@ -1902,7 +1918,7 @@ EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value) } } -static void DrawModelEx(model_t *model, mdlframe_t *frame, INT32 duration, INT32 tics, mdlframe_t *nextframe, FTransform *pos, float scale, UINT8 flipped, UINT8 *color) +static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 *color) { INT32 val, count, pindex; GLfloat s, t; @@ -1990,105 +2006,139 @@ static void DrawModelEx(model_t *model, mdlframe_t *frame, INT32 duration, INT32 pglScalef(scalex, scaley, scalez); - mesh_t *mesh = &model->meshes[0]; + boolean useTinyFrames = model->meshes[0].tinyframes != NULL; - if (!nextframe || pol == 0.0f) + if (useTinyFrames) + pglScalef(1 / 64.0f, 1 / 64.0f, 1 / 64.0f); + + for (int i = 0; i < model->numMeshes; i++) { - // Zoom! Take advantage of just shoving the entire arrays to the GPU. - pglEnableClientState(GL_VERTEX_ARRAY); - pglEnableClientState(GL_TEXTURE_COORD_ARRAY); - pglEnableClientState(GL_NORMAL_ARRAY); - pglVertexPointer(3, GL_FLOAT, 0, frame->vertices); - pglNormalPointer(GL_FLOAT, 0, frame->normals); - pglTexCoordPointer(2, GL_FLOAT, 0, mesh->uvs); - pglDrawArrays(GL_TRIANGLES, 0, mesh->numTriangles * 3); - pglDisableClientState(GL_NORMAL_ARRAY); - pglDisableClientState(GL_TEXTURE_COORD_ARRAY); - pglDisableClientState(GL_TEXTURE_COORD_ARRAY); - /* - pglBegin(GL_TRIANGLES); + mesh_t *mesh = &model->meshes[i]; - int i = 0; - float *uvPtr = mesh->uvs; - float *frameVert = frame->vertices; - float *frameNormal = frame->normals; - for (i = 0; i < mesh->numTriangles; i++) + if (useTinyFrames) { - float uvx = *uvPtr++; - float uvy = *uvPtr++; + tinyframe_t *frame = &mesh->tinyframes[frameIndex % mesh->numFrames]; + tinyframe_t *nextframe = NULL; - // Interpolate - float px1 = *frameVert++; - float py1 = *frameVert++; - float pz1 = *frameVert++; - float nx1 = *frameNormal++; - float ny1 = *frameNormal++; - float nz1 = *frameNormal++; + if (nextFrameIndex != -1) + nextframe = &mesh->tinyframes[nextFrameIndex % mesh->numFrames]; - pglTexCoord2f(uvx, uvy); - pglNormal3f(nx1, ny1, nz1); - pglVertex3f(px1, py1, pz1); + if (!nextframe || pol == 0.0f) + { + pglEnableClientState(GL_VERTEX_ARRAY); + pglEnableClientState(GL_TEXTURE_COORD_ARRAY); + pglEnableClientState(GL_NORMAL_ARRAY); + pglVertexPointer(3, GL_SHORT, 0, frame->vertices); + pglNormalPointer(GL_BYTE, 0, frame->normals); + pglTexCoordPointer(2, GL_FLOAT, 0, mesh->uvs); + pglDrawElements(GL_TRIANGLES, mesh->numTriangles * 3, GL_UNSIGNED_SHORT, mesh->indices); + pglDisableClientState(GL_NORMAL_ARRAY); + pglDisableClientState(GL_TEXTURE_COORD_ARRAY); + pglDisableClientState(GL_TEXTURE_COORD_ARRAY); + } + else + { + // Dangit, I soooo want to do this in a GLSL shader... + pglBegin(GL_TRIANGLES); + + short *buffer = malloc(mesh->numVertices * sizeof(short)); + short *vertPtr = buffer; + char *normBuffer = malloc(mesh->numVertices * sizeof(char)); + char *normPtr = normBuffer; + + int j = 0; + for (j = 0; j < mesh->numVertices; j++) + { + // Interpolate + *vertPtr++ = (short)(frame->vertices[j] + (pol * (nextframe->vertices[j] - frame->vertices[j]))); + *normPtr++ = (short)(frame->normals[j] + (pol * (nextframe->normals[j] - frame->normals[j]))); + } + + float *uvPtr = mesh->uvs; + vertPtr = buffer; + normPtr = normBuffer; + for (j = 0; j < mesh->numTriangles; j++) + { + pglTexCoord2fv(uvPtr); + pglNormal3bv(normPtr); + pglVertex3sv(vertPtr); + + uvPtr += 2; + normPtr += 3; + vertPtr += 3; + } + + free(buffer); + free(normBuffer); + + pglEnd(); + } } - - pglEnd();*/ - } - else - { - // Dangit, I soooo want to do this in a GLSL shader... - pglBegin(GL_TRIANGLES); - - int i = 0; - float *uvPtr = mesh->uvs; - float *frameVert = frame->vertices; - float *frameNormal = frame->normals; - float *nextFrameVert = nextframe->vertices; - float *nextFrameNormal = frame->normals; - for (i = 0; i < mesh->numTriangles; i++) + else { - float uvx = *uvPtr++; - float uvy = *uvPtr++; + mdlframe_t *frame = &mesh->frames[frameIndex % mesh->numFrames]; + mdlframe_t *nextframe = NULL; - // Interpolate - float px1 = *frameVert++; - float px2 = *nextFrameVert++; - float py1 = *frameVert++; - float py2 = *nextFrameVert++; - float pz1 = *frameVert++; - float pz2 = *nextFrameVert++; - float nx1 = *frameNormal++; - float nx2 = *nextFrameNormal++; - float ny1 = *frameNormal++; - float ny2 = *nextFrameNormal++; - float nz1 = *frameNormal++; - float nz2 = *nextFrameNormal++; + if (nextFrameIndex != -1) + nextframe = &mesh->frames[nextFrameIndex % mesh->numFrames]; - pglTexCoord2f(uvx, uvy); - pglNormal3f((nx1 + pol * (nx2 - nx1)), - (ny1 + pol * (ny2 - ny1)), - (nz1 + pol * (nz2 - nz1))); - pglVertex3f((px1 + pol * (px2 - px1)), - (py1 + pol * (py2 - py1)), - (pz1 + pol * (pz2 - pz1))); + if (!nextframe || pol == 0.0f) + { + // Zoom! Take advantage of just shoving the entire arrays to the GPU. + pglEnableClientState(GL_VERTEX_ARRAY); + pglEnableClientState(GL_TEXTURE_COORD_ARRAY); + pglEnableClientState(GL_NORMAL_ARRAY); + pglVertexPointer(3, GL_FLOAT, 0, frame->vertices); + pglNormalPointer(GL_FLOAT, 0, frame->normals); + pglTexCoordPointer(2, GL_FLOAT, 0, mesh->uvs); + pglDrawArrays(GL_TRIANGLES, 0, mesh->numTriangles * 3); + pglDisableClientState(GL_NORMAL_ARRAY); + pglDisableClientState(GL_TEXTURE_COORD_ARRAY); + pglDisableClientState(GL_TEXTURE_COORD_ARRAY); + } + else + { + // Dangit, I soooo want to do this in a GLSL shader... + pglBegin(GL_TRIANGLES); + + int j = 0; + float *uvPtr = mesh->uvs; + float *frameVert = frame->vertices; + float *frameNormal = frame->normals; + float *nextFrameVert = nextframe->vertices; + float *nextFrameNormal = frame->normals; + for (j = 0; j < mesh->numTriangles; j++) + { + // Interpolate + float px1 = *frameVert++; + float px2 = *nextFrameVert++; + float py1 = *frameVert++; + float py2 = *nextFrameVert++; + float pz1 = *frameVert++; + float pz2 = *nextFrameVert++; + float nx1 = *frameNormal++; + float nx2 = *nextFrameNormal++; + float ny1 = *frameNormal++; + float ny2 = *nextFrameNormal++; + float nz1 = *frameNormal++; + float nz2 = *nextFrameNormal++; + + pglTexCoord2fv(uvPtr); + pglNormal3f((nx1 + pol * (nx2 - nx1)), + (ny1 + pol * (ny2 - ny1)), + (nz1 + pol * (nz2 - nz1))); + pglVertex3f((px1 + pol * (px2 - px1)), + (py1 + pol * (py2 - py1)), + (pz1 + pol * (pz2 - pz1))); + + uvPtr++; + } + + pglEnd(); + } } - - pglEnd(); } -/* if (lightType != LIGHT_NONE) - { - glVertexAttribPointer(program->slots[Shaders::A_NORMAL_SLOT], 3, BGL_FLOAT, BGL_FALSE, 0, frame->normals); - // if (normalmapped) - // bglVertexAttribPointer(program->slots[Shaders::A_TANGENT_SLOT], 3, BGL_FLOAT, BGL_FALSE, 0, frame->tangents); - } - - if (frame->colors) - glVertexAttribPointer(program->slots[Shaders::A_COLOR_SLOT], 4, GL_UNSIGNED_BYTE, BGL_TRUE, 0, frame->colors); - else - { - SetGlobalWhiteColorArray(mesh->numTriangles * 3); - glVertexAttribPointer(program->slots[Shaders::A_COLOR_SLOT], 3, BGL_UNSIGNED_BYTE, BGL_TRUE, 0, globalWhiteColorArray); - } - */ pglPopMatrix(); // should be the same as glLoadIdentity if (color) pglDisable(GL_LIGHTING); @@ -2099,9 +2149,9 @@ static void DrawModelEx(model_t *model, mdlframe_t *frame, INT32 duration, INT32 // -----------------+ // HWRAPI DrawMD2 : Draw an MD2 model with glcommands // -----------------+ -EXPORT void HWRAPI(DrawModel) (model_t *model, mdlframe_t *frame, INT32 duration, INT32 tics, mdlframe_t *nextframe, FTransform *pos, float scale, UINT8 flipped, UINT8 *color) +EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 *color) { - DrawModelEx(model, frame, duration, tics, nextframe, pos, scale, flipped, color); + DrawModelEx(model, frameIndex, duration, tics, nextFrameIndex, pos, scale, flipped, color); } // -----------------+ From 4713200fb5e2a880b4fe165b329d9c33ebc064ef Mon Sep 17 00:00:00 2001 From: Arthur Date: Sun, 16 Dec 2018 12:07:11 -0500 Subject: [PATCH 04/74] push test --- 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 a0d86e9f7..a383c1795 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1053,7 +1053,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) } } - //Hurdler: it seems there is still a small problem with mobj angle + // Hurdler: it seems there is still a small problem with mobj angle p.x = FIXED_TO_FLOAT(spr->mobj->x); p.y = FIXED_TO_FLOAT(spr->mobj->y)+md2->offset; From 427675849116fc9eaa03ce551b3bdd354587ace1 Mon Sep 17 00:00:00 2001 From: Arthur Date: Sun, 16 Dec 2018 15:24:17 -0500 Subject: [PATCH 05/74] Remove CONS_Printf message that isn't even doing what it says it is! --- src/hardware/hw_model.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/hw_model.c b/src/hardware/hw_model.c index 73b2b484b..495c8c109 100644 --- a/src/hardware/hw_model.c +++ b/src/hardware/hw_model.c @@ -320,7 +320,7 @@ model_t *LoadModel(const char *filename, int ztag) material->shininess = 25.0f; } - CONS_Printf("Generating VBOs for %s\n", filename); +// CONS_Printf("Generating VBOs for %s\n", filename); for (i = 0; i < model->numMeshes; i++) { mesh_t *mesh = &model->meshes[i]; From 980803e0c0e7cdaa29fbd0133411d2caa29e4d38 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Tue, 18 Dec 2018 17:57:39 -0500 Subject: [PATCH 06/74] Add MD2/MD3 files to makefile --- src/Makefile | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/Makefile b/src/Makefile index fbf75f26c..4f106741b 100644 --- a/src/Makefile +++ b/src/Makefile @@ -274,7 +274,8 @@ ifndef DC endif OPTS+=-DHWRENDER OBJS+=$(OBJDIR)/hw_bsp.o $(OBJDIR)/hw_draw.o $(OBJDIR)/hw_light.o \ - $(OBJDIR)/hw_main.o $(OBJDIR)/hw_clip.o $(OBJDIR)/hw_md2.o $(OBJDIR)/hw_cache.o $(OBJDIR)/hw_trick.o + $(OBJDIR)/hw_main.o $(OBJDIR)/hw_clip.o $(OBJDIR)/hw_md2.o $(OBJDIR)/hw_cache.o $(OBJDIR)/hw_trick.o \ + $(OBJDIR)/hw_md2load.o $(OBJDIR)/hw_md3load.o $(OBJDIR)/hw_model.o $(OBJDIR)/u_list.o endif ifdef NOHS @@ -723,16 +724,18 @@ ifdef MINGW $(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \ doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \ command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \ - hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h am_map.h \ - d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ + hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \ + hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \ + am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ else $(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \ doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \ command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \ - hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h am_map.h \ - d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ + hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \ + hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \ + am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h $(CC) $(CFLAGS) $(WFLAGS) -I/usr/X11R6/include -c $< -o $@ endif @@ -884,24 +887,27 @@ ifndef NOHW $(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \ doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \ command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \ - hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h am_map.h \ - d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ + hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \ + hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \ + am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h $(CC) $(CFLAGS) $(WFLAGS) -D_WINDOWS -mwindows -c $< -o $@ $(OBJDIR)/ogl_win.o: hardware/r_opengl/ogl_win.c hardware/r_opengl/r_opengl.h \ doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \ command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \ - hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h am_map.h \ - d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ + hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \ + hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \ + am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h $(CC) $(CFLAGS) $(WFLAGS) -D_WINDOWS -mwindows -c $< -o $@ $(OBJDIR)/r_minigl.o: hardware/r_minigl/r_minigl.c hardware/r_opengl/r_opengl.h \ doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \ command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \ - hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h am_map.h \ - d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ + hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \ + hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \ + am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h $(CC) $(CFLAGS) $(WFLAGS) -D_WINDOWS -mwindows -c $< -o $@ endif From 3dbda54d3caff8d9e83f9ff9c39de0e09bd53751 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Tue, 18 Dec 2018 19:17:33 -0500 Subject: [PATCH 07/74] GCC compile fixes --- src/hardware/hw_md2.c | 102 +------------------------------ src/hardware/hw_md3load.c | 8 ++- src/hardware/hw_model.c | 19 ++++-- src/hardware/hw_model.h | 2 +- src/hardware/r_opengl/r_opengl.c | 10 ++- 5 files changed, 25 insertions(+), 116 deletions(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index a383c1795..c1856a2c5 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -82,10 +82,12 @@ md2_t md2_playermodels[MAXSKINS]; /* * free model */ +#if 0 static void md2_freeModel (model_t *model) { UnloadModel(model); } +#endif // @@ -887,11 +889,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) FSurfaceInfo Surf; char filename[64]; - INT32 frame = 0; - INT32 nextFrame = -1; - FTransform p; md2_t *md2; - UINT8 color[4]; if (!cv_grmd2.value) return; @@ -936,17 +934,6 @@ void HWR_DrawMD2(gr_vissprite_t *spr) // Look at HWR_ProjectSprite for more { GLPatch_t *gpatch; - INT32 durs = spr->mobj->state->tics; - INT32 tics = spr->mobj->tics; - mdlframe_t *curr, *next = NULL; - const UINT8 flip = (UINT8)((spr->mobj->eflags & MFE_VERTICALFLIP) == MFE_VERTICALFLIP); - spritedef_t *sprdef; - spriteframe_t *sprframe; - float finalscale; - - // Apparently people don't like jump frames like that, so back it goes - //if (tics > durs) - //durs = tics; if (spr->mobj->flags2 & MF2_SHADOW) Surf.FlatColor.s.alpha = 0x40; @@ -988,7 +975,6 @@ void HWR_DrawMD2(gr_vissprite_t *spr) } } //HWD.pfnSetBlend(blend); // This seems to actually break translucency? - finalscale = md2->scale; //Hurdler: arf, I don't like that implementation at all... too much crappy gpatch = md2->grpatch; if (!gpatch || !gpatch->mipmap.grInfo.format || !gpatch->mipmap.downloaded) @@ -1019,90 +1005,6 @@ void HWR_DrawMD2(gr_vissprite_t *spr) gpatch = W_CachePatchNum(spr->patchlumpnum, PU_CACHE); HWR_GetMappedPatch(gpatch, spr->colormap); } - - if (spr->mobj->frame & FF_ANIMATE) - { - // set duration and tics to be the correct values for FF_ANIMATE states - durs = spr->mobj->state->var2; - tics = spr->mobj->anim_duration; - } - - //FIXME: this is not yet correct - frame = (spr->mobj->frame & FF_FRAMEMASK) % md2->model->meshes[0].numFrames; - curr = &md2->model->meshes[0].frames[frame]; -#if 0 - if (cv_grmd2.value == 1 && tics <= durs) - { - // frames are handled differently for states with FF_ANIMATE, so get the next frame differently for the interpolation - if (spr->mobj->frame & FF_ANIMATE) - { - UINT32 nextframe = (spr->mobj->frame & FF_FRAMEMASK) + 1; - if (nextframe >= (UINT32)spr->mobj->state->var1) - nextframe = (spr->mobj->state->frame & FF_FRAMEMASK); - nextframe %= md2->model->header.numFrames; - next = &md2->model->frames[nextframe]; - } - else - { - if (spr->mobj->state->nextstate != S_NULL && states[spr->mobj->state->nextstate].sprite != SPR_NULL - && !(spr->mobj->player && (spr->mobj->state->nextstate == S_PLAY_TAP1 || spr->mobj->state->nextstate == S_PLAY_TAP2) && spr->mobj->state == &states[S_PLAY_STND])) - { - const UINT32 nextframe = (states[spr->mobj->state->nextstate].frame & FF_FRAMEMASK) % md2->model->header.numFrames; - next = &md2->model->frames[nextframe]; - } - } - } - - // Hurdler: it seems there is still a small problem with mobj angle - p.x = FIXED_TO_FLOAT(spr->mobj->x); - p.y = FIXED_TO_FLOAT(spr->mobj->y)+md2->offset; - - if (spr->mobj->eflags & MFE_VERTICALFLIP) - p.z = FIXED_TO_FLOAT(spr->mobj->z + spr->mobj->height); - else - p.z = FIXED_TO_FLOAT(spr->mobj->z); - - if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) - sprdef = &((skin_t *)spr->mobj->skin)->spritedef; - else - sprdef = &sprites[spr->mobj->sprite]; - - sprframe = &sprdef->spriteframes[spr->mobj->frame & FF_FRAMEMASK]; - - if (sprframe->rotate) - { - const fixed_t anglef = AngleFixed(spr->mobj->angle); - p.angley = FIXED_TO_FLOAT(anglef); - } - else - { - const fixed_t anglef = AngleFixed((R_PointToAngle(spr->mobj->x, spr->mobj->y))-ANGLE_180); - p.angley = FIXED_TO_FLOAT(anglef); - } - p.anglex = 0.0f; - p.anglez = 0.0f; - if (spr->mobj->standingslope) - { - fixed_t tempz = spr->mobj->standingslope->normal.z; - fixed_t tempy = spr->mobj->standingslope->normal.y; - fixed_t tempx = spr->mobj->standingslope->normal.x; - fixed_t tempangle = AngleFixed(R_PointToAngle2(0, 0, FixedSqrt(FixedMul(tempy, tempy) + FixedMul(tempz, tempz)), tempx)); - p.anglez = FIXED_TO_FLOAT(tempangle); - tempangle = -AngleFixed(R_PointToAngle2(0, 0, tempz, tempy)); - p.anglex = FIXED_TO_FLOAT(tempangle); - } - - color[0] = Surf.FlatColor.s.red; - color[1] = Surf.FlatColor.s.green; - color[2] = Surf.FlatColor.s.blue; - color[3] = Surf.FlatColor.s.alpha; - - // SRB2CBTODO: MD2 scaling support - finalscale *= FIXED_TO_FLOAT(spr->mobj->scale); - - p.flip = atransform.flip; - - HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, finalscale, flip, color); } } diff --git a/src/hardware/hw_md3load.c b/src/hardware/hw_md3load.c index 87a2f6ed1..1f1763ebd 100644 --- a/src/hardware/hw_md3load.c +++ b/src/hardware/hw_md3load.c @@ -95,6 +95,7 @@ static void GetNormalFromLatLong(short latlng, float *out) out[2] = *lookup++; } +#if 0 static void NormalToLatLng(float *n, short *out) { // Special cases @@ -115,6 +116,7 @@ static void NormalToLatLng(float *n, short *out) *out = (x << 8) + y; } } +#endif static inline void LatLngToNormal(short n, float *out) { @@ -140,7 +142,7 @@ static void LatLngInit(void) } } -static bool latlnginit = false; +static boolean latlnginit = false; model_t *MD3_LoadModel(const char *fileName, int ztag, boolean useFloat) { @@ -218,7 +220,7 @@ model_t *MD3_LoadModel(const char *fileName, int ztag, boolean useFloat) } retModel->meshes = (mesh_t*)Z_Calloc(sizeof(mesh_t)*retModel->numMeshes, ztag, 0); - + int matCount = 0; for (i = 0, surfEnd = 0; i < mdh->numSurfaces; i++) { @@ -236,7 +238,7 @@ model_t *MD3_LoadModel(const char *fileName, int ztag, boolean useFloat) // Load material /* retModel->materials[matCount].texture = Texture::ReadTexture(mdShader[j].name, ZT_TEXTURE); - + if (!systemSucks) { // Check for a normal map...?? diff --git a/src/hardware/hw_model.c b/src/hardware/hw_model.c index 495c8c109..f0c6f283b 100644 --- a/src/hardware/hw_model.c +++ b/src/hardware/hw_model.c @@ -16,7 +16,7 @@ #include static float PI = (3.1415926535897932384626433832795f); -float U_Deg2Rad(float deg) +static float U_Deg2Rad(float deg) { return deg * ((float)PI / 180.0f); } @@ -49,11 +49,13 @@ void VectorRotate(vector_t *rotVec, const vector_t *axisVec, float angle) void CreateVBOTiny(mesh_t *mesh, tinyframe_t *frame) { + (void)mesh; + (void)frame; return; /* int bufferSize = sizeof(VBO::vbotiny_t)*mesh->numTriangles*3; VBO::vbotiny_t *buffer = (VBO::vbotiny_t*)Z_Malloc(bufferSize, PU_STATIC, 0); VBO::vbotiny_t *bufPtr = buffer; - + short *vertPtr = frame->vertices; char *normPtr = frame->normals; float *uvPtr = mesh->uvs; @@ -91,6 +93,8 @@ void CreateVBOTiny(mesh_t *mesh, tinyframe_t *frame) void CreateVBO(mesh_t *mesh, mdlframe_t *frame) { + (void)mesh; + (void)frame; return; /* int bufferSize = sizeof(VBO::vbo64_t)*mesh->numTriangles*3; VBO::vbo64_t *buffer = (VBO::vbo64_t*)Z_Malloc(bufferSize, PU_STATIC, 0); @@ -161,7 +165,7 @@ void UnloadModel(model_t *model) for (i = 0; i < model->numMeshes; i++) { mesh_t *mesh = &model->meshes[i]; - + if (mesh->frames) { int j; @@ -450,7 +454,7 @@ typedef struct materiallist_s material_t *material; } materiallist_t; -static bool AddMaterialToList(materiallist_t **head, material_t *material) +static boolean AddMaterialToList(materiallist_t **head, material_t *material) { materiallist_t *node; for (node = *head; node; node = node->next) @@ -619,7 +623,7 @@ void GeneratePolygonNormals(model_t *model, int ztag) for (i = 0; i < model->numMeshes; i++) { mesh_t *mesh = &model->meshes[i]; - + if (!mesh->frames) continue; @@ -648,7 +652,8 @@ void GeneratePolygonNormals(model_t *model, int ztag) // // Reload VBOs // -void Reload(void) +#if 0 +static void Reload(void) { /* model_t *node; for (node = modelHead; node; node = node->next) @@ -673,9 +678,11 @@ void Reload(void) } }*/ } +#endif void DeleteVBOs(model_t *model) { + (void)model; /* for (int i = 0; i < model->numMeshes; i++) { mesh_t *mesh = &model->meshes[i]; diff --git a/src/hardware/hw_model.h b/src/hardware/hw_model.h index ed7e41a55..34e83731f 100644 --- a/src/hardware/hw_model.h +++ b/src/hardware/hw_model.h @@ -27,7 +27,7 @@ typedef struct { float ambient[4], diffuse[4], specular[4], emissive[4]; float shininess; - bool spheremap; + boolean spheremap; // Texture::texture_t *texture; // Texture::texture_t *lightmap; } material_t; diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 7362ebbe6..6874e2ec9 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1919,9 +1919,7 @@ EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value) } static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 *color) -{ - INT32 val, count, pindex; - GLfloat s, t; +{ GLfloat ambient[4]; GLfloat diffuse[4]; @@ -2059,9 +2057,9 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 normPtr = normBuffer; for (j = 0; j < mesh->numTriangles; j++) { - pglTexCoord2fv(uvPtr); - pglNormal3bv(normPtr); - pglVertex3sv(vertPtr); + pglTexCoord2fv((const GLfloat*) uvPtr); + pglNormal3bv((const GLbyte*) normPtr); + pglVertex3sv((const GLshort*) vertPtr); uvPtr += 2; normPtr += 3; From 6b2f4b5858ffe1acf176342fa3351662ecdc9a80 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Tue, 18 Dec 2018 19:31:30 -0500 Subject: [PATCH 08/74] Buildbot fixes (changed byte types to char; mixed d&c) --- src/hardware/hw_md2load.c | 89 ++++++++++++++++----------- src/hardware/hw_md3load.c | 86 +++++++++++++++----------- src/hardware/hw_model.c | 102 ++++++++++++++++++------------- src/hardware/hw_model.h | 2 +- src/hardware/r_opengl/r_opengl.c | 45 +++++++++----- 5 files changed, 197 insertions(+), 127 deletions(-) diff --git a/src/hardware/hw_md2load.c b/src/hardware/hw_md2load.c index 998dc70b6..1fdfefb97 100644 --- a/src/hardware/hw_md2load.c +++ b/src/hardware/hw_md2load.c @@ -17,7 +17,7 @@ #define NUMVERTEXNORMALS 162 -// Quake 2 normals are indexed. Use avertexnormals[normalindex][x/y/z] and +// Quake 2 normals are indexed. Use avertexnormals[normalindex][x/y/z] and // you'll have your normals. float avertexnormals[NUMVERTEXNORMALS][3] = { {-0.525731f, 0.000000f, 0.850651f}, @@ -195,9 +195,9 @@ typedef struct int numXYZ; // Number of vertices in each frame int numST; // Number of texture coordinates in each frame. int numTris; // Number of triangles in each frame - int numGLcmds; // Number of dwords (4 bytes) in the gl command list. + int numGLcmds; // Number of dwords (4 bytes) in the gl command list. int numFrames; // Number of frames - int offsetSkins; // Offset, in bytes from the start of the file, to the list of skin names. + int offsetSkins; // Offset, in bytes from the start of the file, to the list of skin names. int offsetST; // Offset, in bytes from the start of the file, to the list of texture coordinates int offsetTris; // Offset, in bytes from the start of the file, to the list of triangles int offsetFrames; // Offset, in bytes from the start of the file, to the list of frames @@ -236,6 +236,20 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) model_t *retModel = NULL; md2header_t *header; + size_t fileLen; + int i, j, t; + + size_t namelen; + char *texturefilename, *buffer; + const char *texPos; + + const float WUNITS = 1.0f; + float dataScale; + + md2triangle_t *tris; + md2texcoord_t *texcoords; + md2frame_t *frames; + FILE *f = fopen(fileName, "rb"); if (!f) @@ -243,12 +257,7 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) retModel = (model_t*)Z_Calloc(sizeof(model_t), ztag, 0); - size_t fileLen; - int i, j; - - size_t namelen; - char *texturefilename; - const char *texPos = strchr(fileName, '/'); + texPos = strchr(fileName, '/'); if (texPos) { @@ -274,7 +283,7 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) fseek(f, 0, SEEK_SET); // read in file - char *buffer = malloc(fileLen); + buffer = malloc(fileLen); fread(buffer, fileLen, 1, f); fclose(f); @@ -284,13 +293,13 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) retModel->numMeshes = 1; // MD2 only has one mesh retModel->meshes = (mesh_t*)Z_Calloc(sizeof(mesh_t) * retModel->numMeshes, ztag, 0); retModel->meshes[0].numFrames = header->numFrames; - const float WUNITS = 1.0f; - float dataScale = WUNITS; + + dataScale = WUNITS; // Tris and ST are simple structures that can be straight-copied - md2triangle_t *tris = (md2triangle_t*)&buffer[header->offsetTris]; - md2texcoord_t *texcoords = (md2texcoord_t*)&buffer[header->offsetST]; - md2frame_t *frames = (md2frame_t*)&buffer[header->offsetFrames]; + tris = (md2triangle_t*)&buffer[header->offsetTris]; + texcoords = (md2texcoord_t*)&buffer[header->offsetST]; + frames = (md2frame_t*)&buffer[header->offsetFrames]; // Read in textures retModel->numMaterials = header->numSkins; @@ -300,7 +309,6 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) retModel->materials = (material_t*)Z_Calloc(sizeof(material_t)*retModel->numMaterials, ztag, 0); - int t; for (t = 0; t < retModel->numMaterials; t++) { retModel->materials[t].ambient[0] = 0.8f; @@ -327,6 +335,7 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) if (!systemSucks) { // Check for a normal map...?? + Resource::resource_t *res char openfilename[1024]; char normalMapName[1024]; strcpy(normalMapName, texturefilename); @@ -355,7 +364,7 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) openfilename[k] = '/'; } - Resource::resource_t *res = Resource::Open(openfilename); + res = Resource::Open(openfilename); if (res) { Resource::Close(res); @@ -368,15 +377,24 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) if (!useFloat) // Decompress to MD3 'tinyframe' space { + char *ptr = (char*)frames; + md2triangle_t *trisPtr; + unsigned short *indexptr; + float *uvptr; + dataScale = 0.015624f; // 1 / 64.0f retModel->meshes[0].tinyframes = (tinyframe_t*)Z_Calloc(sizeof(tinyframe_t)*header->numFrames, ztag, 0); retModel->meshes[0].numVertices = header->numXYZ; retModel->meshes[0].uvs = (float*)Z_Malloc (sizeof(float)*2*retModel->meshes[0].numVertices, ztag, 0); - byte *ptr = (byte*)frames; for (i = 0; i < header->numFrames; i++, ptr += header->framesize) { + short *vertptr; + char *normptr; + //char *tanptr; md2frame_t *framePtr = (md2frame_t*)ptr; + md2vertex_t *vertex; + retModel->meshes[0].tinyframes[i].vertices = (short*)Z_Malloc(sizeof(short)*3*header->numXYZ, ztag, 0); retModel->meshes[0].tinyframes[i].normals = (char*)Z_Malloc(sizeof(char)*3*header->numXYZ, ztag, 0); @@ -384,14 +402,14 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) // retModel->meshes[0].tinyframes[i].tangents = (char*)malloc(sizeof(char));//(char*)Z_Malloc(sizeof(char)*3*header->numVerts, ztag); retModel->meshes[0].indices = (unsigned short*)Z_Malloc(sizeof(unsigned short) * 3 * header->numTris, ztag, 0); - short *vertptr = retModel->meshes[0].tinyframes[i].vertices; - char *normptr = retModel->meshes[0].tinyframes[i].normals; + vertptr = retModel->meshes[0].tinyframes[i].vertices; + normptr = retModel->meshes[0].tinyframes[i].normals; -// char *tanptr = retModel->meshes[0].tinyframes[i].tangents; +// tanptr = retModel->meshes[0].tinyframes[i].tangents; retModel->meshes[0].tinyframes[i].material = &retModel->materials[0]; framePtr++; // Advance to vertex list - md2vertex_t *vertex = (md2vertex_t*)framePtr; + vertex = (md2vertex_t*)framePtr; framePtr--; for (j = 0; j < header->numXYZ; j++, vertex++) { @@ -403,16 +421,16 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) vertptr++; // Normal - *normptr++ = (byte)(avertexnormals[vertex->lightNormalIndex][0] * 127); - *normptr++ = (byte)(avertexnormals[vertex->lightNormalIndex][1] * 127); - *normptr++ = (byte)(avertexnormals[vertex->lightNormalIndex][2] * 127); + *normptr++ = (char)(avertexnormals[vertex->lightNormalIndex][0] * 127); + *normptr++ = (char)(avertexnormals[vertex->lightNormalIndex][1] * 127); + *normptr++ = (char)(avertexnormals[vertex->lightNormalIndex][2] * 127); } } // This doesn't need to be done every frame! - md2triangle_t *trisPtr = tris; - unsigned short *indexptr = retModel->meshes[0].indices; - float *uvptr = (float*)retModel->meshes[0].uvs; + trisPtr = tris; + indexptr = retModel->meshes[0].indices; + uvptr = (float*)retModel->meshes[0].uvs; for (j = 0; j < header->numTris; j++, trisPtr++) { *indexptr = trisPtr->meshIndex[0]; @@ -432,12 +450,14 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) } else // Full float loading method { + md2triangle_t *trisPtr = tris; + float *uvptr = retModel->meshes[0].uvs; + char *ptr = (char*)frames; + retModel->meshes[0].numVertices = header->numTris*3; retModel->meshes[0].frames = (mdlframe_t*)Z_Calloc(sizeof(mdlframe_t)*header->numFrames, ztag, 0); retModel->meshes[0].uvs = (float*)Z_Malloc(sizeof(float)*2*retModel->meshes[0].numVertices, ztag, 0); - md2triangle_t *trisPtr = tris; - float *uvptr = retModel->meshes[0].uvs; for (i = 0; i < retModel->meshes[0].numTriangles; i++, trisPtr++) { *uvptr++ = texcoords[trisPtr->stIndex[0]].s / (float)header->skinwidth; @@ -448,23 +468,24 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) *uvptr++ = (texcoords[trisPtr->stIndex[2]].t / (float)header->skinheight); } - byte *ptr = (byte*)frames; for (i = 0; i < header->numFrames; i++, ptr += header->framesize) { + md2vertex_t *vertex; md2frame_t *framePtr = (md2frame_t*)ptr; + float *vertptr, *normptr; retModel->meshes[0].frames[i].normals = (float*)Z_Malloc(sizeof(float)*3*header->numTris*3, ztag, 0); retModel->meshes[0].frames[i].vertices = (float*)Z_Malloc(sizeof(float)*3*header->numTris*3, ztag, 0); // if (retModel->materials[0].lightmap) // retModel->meshes[0].frames[i].tangents = (float*)malloc(sizeof(float));//(float*)Z_Malloc(sizeof(float)*3*header->numTris*3, ztag); - float *vertptr, *normptr; + normptr = (float*)retModel->meshes[0].frames[i].normals; vertptr = (float*)retModel->meshes[0].frames[i].vertices; trisPtr = tris; - + retModel->meshes[0].frames[i].material = &retModel->materials[0]; framePtr++; // Advance to vertex list - md2vertex_t *vertex = (md2vertex_t*)framePtr; + vertex = (md2vertex_t*)framePtr; framePtr--; for (j = 0; j < header->numTris; j++, trisPtr++) { diff --git a/src/hardware/hw_md3load.c b/src/hardware/hw_md3load.c index 1f1763ebd..35c6abf29 100644 --- a/src/hardware/hw_md3load.c +++ b/src/hardware/hw_md3load.c @@ -146,31 +146,36 @@ static boolean latlnginit = false; model_t *MD3_LoadModel(const char *fileName, int ztag, boolean useFloat) { + const float WUNITS = 1.0f; + model_t *retModel = NULL; + md3modelHeader *mdh; + long fileLen; + char *buffer; + int surfEnd; + int i, t; + int matCount; + FILE *f; + if (!latlnginit) { LatLngInit(); latlnginit = true; } - const float WUNITS = 1.0f; - model_t *retModel = NULL; - - FILE *f = fopen(fileName, "rb"); + f = fopen(fileName, "rb"); if (!f) return NULL; retModel = (model_t*)Z_Calloc(sizeof(model_t), ztag, 0); - md3modelHeader *mdh; - // find length of file fseek(f, 0, SEEK_END); - long fileLen = ftell(f); + fileLen = ftell(f); fseek(f, 0, SEEK_SET); // read in file - char *buffer = malloc(fileLen); + buffer = malloc(fileLen); fread(buffer, fileLen, 1, f); fclose(f); @@ -180,8 +185,7 @@ model_t *MD3_LoadModel(const char *fileName, int ztag, boolean useFloat) retModel->numMeshes = mdh->numSurfaces; retModel->numMaterials = 0; - int surfEnd = 0; - int i; + surfEnd = 0; for (i = 0; i < mdh->numSurfaces; i++) { md3Surface *mdS = (md3Surface*)&buffer[mdh->offsetSurfaces]; @@ -196,7 +200,6 @@ model_t *MD3_LoadModel(const char *fileName, int ztag, boolean useFloat) retModel->materials = (material_t*)Z_Calloc(sizeof(material_t)*retModel->numMaterials, ztag, 0); - int t; for (t = 0; t < retModel->numMaterials; t++) { retModel->materials[t].ambient[0] = 0.3686f; @@ -221,14 +224,16 @@ model_t *MD3_LoadModel(const char *fileName, int ztag, boolean useFloat) retModel->meshes = (mesh_t*)Z_Calloc(sizeof(mesh_t)*retModel->numMeshes, ztag, 0); - int matCount = 0; + matCount = 0; for (i = 0, surfEnd = 0; i < mdh->numSurfaces; i++) { + int j; + md3Shader *mdShader; md3Surface *mdS = (md3Surface*)&buffer[mdh->offsetSurfaces + surfEnd]; surfEnd += mdS->offsetEnd; - md3Shader *mdShader = (md3Shader*)((char*)mdS + mdS->offsetShaders); - int j; + mdShader = (md3Shader*)((char*)mdS + mdS->offsetShaders); + for (j = 0; j < mdS->numShaders; j++, matCount++) { size_t len = strlen(mdShader[j].name); @@ -285,11 +290,20 @@ model_t *MD3_LoadModel(const char *fileName, int ztag, boolean useFloat) if (!useFloat) // 'tinyframe' mode with indices { float tempNormal[3]; + float *uvptr; + md3TexCoord *mdST; + unsigned short *indexptr; + md3Triangle *mdT; + retModel->meshes[i].tinyframes = (tinyframe_t*)Z_Calloc(sizeof(tinyframe_t)*mdS->numFrames, ztag, 0); retModel->meshes[i].numVertices = mdS->numVerts; retModel->meshes[i].uvs = (float*)Z_Malloc(sizeof(float)*2*mdS->numVerts, ztag, 0); for (j = 0; j < mdS->numFrames; j++) { + short *vertptr; + char *normptr; + // char *tanptr; + int k; md3Vertex *mdV = (md3Vertex*)((char*)mdS + mdS->offsetXYZNormal + (mdS->numVerts*j*sizeof(md3Vertex))); retModel->meshes[i].tinyframes[j].vertices = (short*)Z_Malloc(sizeof(short)*3*mdS->numVerts, ztag, 0); retModel->meshes[i].tinyframes[j].normals = (char*)Z_Malloc(sizeof(char)*3*mdS->numVerts, ztag, 0); @@ -297,13 +311,12 @@ model_t *MD3_LoadModel(const char *fileName, int ztag, boolean useFloat) // if (retModel->materials[0].lightmap) // retModel->meshes[i].tinyframes[j].tangents = (char*)malloc(sizeof(char));//(char*)Z_Malloc(sizeof(char)*3*mdS->numVerts, ztag); retModel->meshes[i].indices = (unsigned short*)Z_Malloc(sizeof(unsigned short) * 3 * mdS->numTriangles, ztag, 0); - short *vertptr = retModel->meshes[i].tinyframes[j].vertices; - char *normptr = retModel->meshes[i].tinyframes[j].normals; + vertptr = retModel->meshes[i].tinyframes[j].vertices; + normptr = retModel->meshes[i].tinyframes[j].normals; -// char *tanptr = retModel->meshes[i].tinyframes[j].tangents; +// tanptr = retModel->meshes[i].tinyframes[j].tangents; retModel->meshes[i].tinyframes[j].material = &retModel->materials[i]; - int k; for (k = 0; k < mdS->numVerts; k++) { // Vertex @@ -316,17 +329,17 @@ model_t *MD3_LoadModel(const char *fileName, int ztag, boolean useFloat) // Normal GetNormalFromLatLong(mdV[k].n, tempNormal); - *normptr = (byte)(tempNormal[0] * 127); + *normptr = (char)(tempNormal[0] * 127); normptr++; - *normptr = (byte)(tempNormal[2] * 127); + *normptr = (char)(tempNormal[2] * 127); normptr++; - *normptr = (byte)(tempNormal[1] * 127); + *normptr = (char)(tempNormal[1] * 127); normptr++; } } - float *uvptr = (float*)retModel->meshes[i].uvs; - md3TexCoord *mdST = (md3TexCoord*)((char*)mdS + mdS->offsetST); + uvptr = (float*)retModel->meshes[i].uvs; + mdST = (md3TexCoord*)((char*)mdS + mdS->offsetST); for (j = 0; j < mdS->numVerts; j++) { *uvptr = mdST[j].st[0]; @@ -335,8 +348,8 @@ model_t *MD3_LoadModel(const char *fileName, int ztag, boolean useFloat) uvptr++; } - unsigned short *indexptr = retModel->meshes[i].indices; - md3Triangle *mdT = (md3Triangle*)((char*)mdS + mdS->offsetTriangles); + indexptr = retModel->meshes[i].indices; + mdT = (md3Triangle*)((char*)mdS + mdS->offsetTriangles); for (j = 0; j < mdS->numTriangles; j++, mdT++) { // Indices @@ -350,25 +363,31 @@ model_t *MD3_LoadModel(const char *fileName, int ztag, boolean useFloat) } else // Traditional full-float loading method { - retModel->meshes[i].numVertices = mdS->numTriangles * 3;//mdS->numVerts; float dataScale = 0.015624f * WUNITS; float tempNormal[3]; + md3TexCoord *mdST; + md3Triangle *mdT; + float *uvptr; + int k; + + retModel->meshes[i].numVertices = mdS->numTriangles * 3;//mdS->numVerts; retModel->meshes[i].frames = (mdlframe_t*)Z_Calloc(sizeof(mdlframe_t)*mdS->numFrames, ztag, 0); retModel->meshes[i].uvs = (float*)Z_Malloc(sizeof(float)*2*mdS->numTriangles*3, ztag, 0); for (j = 0; j < mdS->numFrames; j++) { + float *vertptr; + float *normptr; md3Vertex *mdV = (md3Vertex*)((char*)mdS + mdS->offsetXYZNormal + (mdS->numVerts*j*sizeof(md3Vertex))); retModel->meshes[i].frames[j].vertices = (float*)Z_Malloc(sizeof(float)*3*mdS->numTriangles*3, ztag, 0); retModel->meshes[i].frames[j].normals = (float*)Z_Malloc(sizeof(float)*3*mdS->numTriangles*3, ztag, 0); // if (retModel->materials[i].lightmap) // retModel->meshes[i].frames[j].tangents = (float*)malloc(sizeof(float));//(float*)Z_Malloc(sizeof(float)*3*mdS->numTriangles*3, ztag); - float *vertptr = retModel->meshes[i].frames[j].vertices; - float *normptr = retModel->meshes[i].frames[j].normals; + vertptr = retModel->meshes[i].frames[j].vertices; + normptr = retModel->meshes[i].frames[j].normals; retModel->meshes[i].frames[j].material = &retModel->materials[i]; - int k; - md3Triangle *mdT = (md3Triangle*)((char*)mdS + mdS->offsetTriangles); + mdT = (md3Triangle*)((char*)mdS + mdS->offsetTriangles); for (k = 0; k < mdS->numTriangles; k++) { @@ -424,10 +443,9 @@ model_t *MD3_LoadModel(const char *fileName, int ztag, boolean useFloat) } } - md3TexCoord *mdST = (md3TexCoord*)((char*)mdS + mdS->offsetST); - float *uvptr = (float*)retModel->meshes[i].uvs; - int k; - md3Triangle *mdT = (md3Triangle*)((char*)mdS + mdS->offsetTriangles); + mdST = (md3TexCoord*)((char*)mdS + mdS->offsetST); + uvptr = (float*)retModel->meshes[i].uvs; + mdT = (md3Triangle*)((char*)mdS + mdS->offsetTriangles); for (k = 0; k < mdS->numTriangles; k++) { diff --git a/src/hardware/hw_model.c b/src/hardware/hw_model.c index f0c6f283b..828339563 100644 --- a/src/hardware/hw_model.c +++ b/src/hardware/hw_model.c @@ -27,20 +27,22 @@ vector_t vectorZaxis = { 0.0f, 0.0f, 1.0f }; void VectorRotate(vector_t *rotVec, const vector_t *axisVec, float angle) { + float ux, uy, uz, vx, vy, vz, wx, wy, wz, sa, ca; + angle = U_Deg2Rad(angle); // Rotate the point (x,y,z) around the vector (u,v,w) - float ux = axisVec->x * rotVec->x; - float uy = axisVec->x * rotVec->y; - float uz = axisVec->x * rotVec->z; - float vx = axisVec->y * rotVec->x; - float vy = axisVec->y * rotVec->y; - float vz = axisVec->y * rotVec->z; - float wx = axisVec->z * rotVec->x; - float wy = axisVec->z * rotVec->y; - float wz = axisVec->z * rotVec->z; - float sa = sinf(angle); - float ca = cosf(angle); + ux = axisVec->x * rotVec->x; + uy = axisVec->x * rotVec->y; + uz = axisVec->x * rotVec->z; + vx = axisVec->y * rotVec->x; + vy = axisVec->y * rotVec->y; + vz = axisVec->y * rotVec->z; + wx = axisVec->z * rotVec->x; + wy = axisVec->z * rotVec->y; + wz = axisVec->z * rotVec->z; + sa = sinf(angle); + ca = cosf(angle); rotVec->x = axisVec->x*(ux + vy + wz) + (rotVec->x*(axisVec->y*axisVec->y + axisVec->z*axisVec->z) - axisVec->x*(vy + wz))*ca + (-wy + vz)*sa; rotVec->y = axisVec->y*(ux + vy + wz) + (rotVec->y*(axisVec->x*axisVec->x + axisVec->z*axisVec->z) - axisVec->y*(ux + wz))*ca + (wx - uz)*sa; @@ -105,7 +107,7 @@ void CreateVBO(mesh_t *mesh, mdlframe_t *frame) float *tanPtr = frame->tangents; float *uvPtr = mesh->uvs; float *lightPtr = mesh->lightuvs; - byte *colorPtr = frame->colors; + char *colorPtr = frame->colors; int i; for (i = 0; i < mesh->numTriangles*3; i++) @@ -364,17 +366,22 @@ void GenerateVertexNormals(model_t *model) int i; for (i = 0; i < model->numMeshes; i++) { + int j; + mesh_t *mesh = &model->meshes[i]; if (!mesh->frames) continue; - int j; for (j = 0; j < mesh->numFrames; j++) { mdlframe_t *frame = &mesh->frames[j]; int memTag = PU_STATIC; float *newNormals = (float*)Z_Malloc(sizeof(float)*3*mesh->numTriangles*3, memTag, 0); + int k; + float *vertPtr = frame->vertices; + float *oldNormals; + M_Memcpy(newNormals, frame->normals, sizeof(float)*3*mesh->numTriangles*3); /* if (!systemSucks) @@ -384,20 +391,20 @@ void GenerateVertexNormals(model_t *model) M_Memcpy(newTangents, frame->tangents, sizeof(float)*3*mesh->numTriangles*3); }*/ - int k; - float *vertPtr = frame->vertices; for (k = 0; k < mesh->numVertices; k++) { float x, y, z; + int vCount = 0; + vector_t normal; + int l; + float *testPtr = frame->vertices; + x = *vertPtr++; y = *vertPtr++; z = *vertPtr++; - int vCount = 0; - vector_t normal; normal.x = normal.y = normal.z = 0; - int l; - float *testPtr = frame->vertices; + for (l = 0; l < mesh->numVertices; l++) { float testX, testY, testZ; @@ -433,7 +440,7 @@ void GenerateVertexNormals(model_t *model) } } - float *oldNormals = frame->normals; + oldNormals = frame->normals; frame->normals = newNormals; Z_Free(oldNormals); @@ -456,7 +463,7 @@ typedef struct materiallist_s static boolean AddMaterialToList(materiallist_t **head, material_t *material) { - materiallist_t *node; + materiallist_t *node, *newMatNode; for (node = *head; node; node = node->next) { if (node->material == material) @@ -464,7 +471,7 @@ static boolean AddMaterialToList(materiallist_t **head, material_t *material) } // Didn't find it, so add to the list - materiallist_t *newMatNode = (materiallist_t*)Z_Malloc(sizeof(materiallist_t), PU_CACHE, 0); + newMatNode = (materiallist_t*)Z_Malloc(sizeof(materiallist_t), PU_CACHE, 0); newMatNode->material = material; ListAdd(newMatNode, (listitem_t**)head); return true; @@ -478,12 +485,16 @@ static boolean AddMaterialToList(materiallist_t **head, material_t *material) // void Optimize(model_t *model) { - if (model->numMeshes <= 1) - return; // No need - int numMeshes = 0; int i; materiallist_t *matListHead = NULL; + int memTag; + mesh_t *newMeshes; + materiallist_t *node; + + if (model->numMeshes <= 1) + return; // No need + for (i = 0; i < model->numMeshes; i++) { mesh_t *curMesh = &model->meshes[i]; @@ -501,15 +512,18 @@ void Optimize(model_t *model) numMeshes++; } - int memTag = PU_STATIC; - mesh_t *newMeshes = (mesh_t*)Z_Calloc(sizeof(mesh_t) * numMeshes, memTag, 0); + memTag = PU_STATIC; + newMeshes = (mesh_t*)Z_Calloc(sizeof(mesh_t) * numMeshes, memTag, 0); i = 0; - materiallist_t *node; for (node = matListHead; node; node = node->next) { material_t *curMat = node->material; mesh_t *newMesh = &newMeshes[i]; + mdlframe_t *curFrame; + int uvCount; + int vertCount; + int colorCount; // Find all triangles with this material and count them int numTriangles = 0; @@ -529,20 +543,20 @@ void Optimize(model_t *model) // if (node->material->lightmap) // newMesh->lightuvs = (float*)Z_Malloc(sizeof(float)*2*numTriangles*3, memTag, 0); newMesh->frames = (mdlframe_t*)Z_Calloc(sizeof(mdlframe_t), memTag, 0); - mdlframe_t *curFrame = &newMesh->frames[0]; + curFrame = &newMesh->frames[0]; curFrame->material = curMat; curFrame->normals = (float*)Z_Malloc(sizeof(float)*3*numTriangles*3, memTag, 0); // if (!systemSucks) // curFrame->tangents = (float*)Z_Malloc(sizeof(float)*3*numTriangles*3, memTag, 0); curFrame->vertices = (float*)Z_Malloc(sizeof(float)*3*numTriangles*3, memTag, 0); - curFrame->colors = (byte*)Z_Malloc(sizeof(byte)*4*numTriangles*3, memTag, 0); + curFrame->colors = (char*)Z_Malloc(sizeof(char)*4*numTriangles*3, memTag, 0); // Now traverse the meshes of the model, adding in // vertices/normals/uvs that match the current material - int uvCount = 0; - int vertCount = 0; - int colorCount = 0; + uvCount = 0; + vertCount = 0; + colorCount = 0; for (j = 0; j < model->numMeshes; j++) { mesh_t *curMesh = &model->meshes[j]; @@ -551,6 +565,8 @@ void Optimize(model_t *model) { float *dest; float *src; + char *destByte; + char *srcByte; M_Memcpy(&newMesh->uvs[uvCount], curMesh->uvs, @@ -587,22 +603,20 @@ void Optimize(model_t *model) vertCount += 3 * curMesh->numTriangles * 3; - byte *destByte; - byte *srcByte; - destByte = (byte*)newMesh->frames[0].colors; - srcByte = (byte*)curMesh->frames[0].colors; + destByte = (char*)newMesh->frames[0].colors; + srcByte = (char*)curMesh->frames[0].colors; if (srcByte) { M_Memcpy(&destByte[colorCount], srcByte, - sizeof(byte)*4*curMesh->numTriangles*3); + sizeof(char)*4*curMesh->numTriangles*3); } else { memset(&destByte[colorCount], 255, - sizeof(byte)*4*curMesh->numTriangles*3); + sizeof(char)*4*curMesh->numTriangles*3); } colorCount += 4 * curMesh->numTriangles * 3; @@ -622,21 +636,23 @@ void GeneratePolygonNormals(model_t *model, int ztag) int i; for (i = 0; i < model->numMeshes; i++) { + int j; mesh_t *mesh = &model->meshes[i]; if (!mesh->frames) continue; - int j; for (j = 0; j < mesh->numFrames; j++) { + int k; mdlframe_t *frame = &mesh->frames[j]; + const float *vertices = frame->vertices; + vector_t *polyNormals; frame->polyNormals = (vector_t*)Z_Malloc(sizeof(vector_t) * mesh->numTriangles, ztag, 0); - const float *vertices = frame->vertices; - vector_t *polyNormals = frame->polyNormals; - int k; + polyNormals = frame->polyNormals; + for (k = 0; k < mesh->numTriangles; k++) { // Vector::Normal(vertices, polyNormals); diff --git a/src/hardware/hw_model.h b/src/hardware/hw_model.h index 34e83731f..1803f4c5c 100644 --- a/src/hardware/hw_model.h +++ b/src/hardware/hw_model.h @@ -38,7 +38,7 @@ typedef struct float *vertices; float *normals; float *tangents; - byte *colors; + char *colors; unsigned int vboID; vector_t *polyNormals; } mdlframe_t; diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 6874e2ec9..828ec8d83 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1924,14 +1924,19 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 GLfloat diffuse[4]; float pol = 0.0f; - scale *= 0.5f; float scalex = scale, scaley = scale, scalez = scale; + boolean useTinyFrames; + + int i; + // Because Otherwise, scaling the screen negatively vertically breaks the lighting #ifndef KOS_GL_COMPATIBILITY GLfloat LightPos[] = {0.0f, 1.0f, 0.0f, 0.0f}; #endif + scale *= 0.5f; + if (duration != 0 && duration != -1 && tics != -1) // don't interpolate if instantaneous or infinite in length { UINT32 newtime = (duration - tics); // + 1; @@ -2004,12 +2009,12 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 pglScalef(scalex, scaley, scalez); - boolean useTinyFrames = model->meshes[0].tinyframes != NULL; + useTinyFrames = model->meshes[0].tinyframes != NULL; if (useTinyFrames) pglScalef(1 / 64.0f, 1 / 64.0f, 1 / 64.0f); - for (int i = 0; i < model->numMeshes; i++) + for (i = 0; i < model->numMeshes; i++) { mesh_t *mesh = &model->meshes[i]; @@ -2036,15 +2041,19 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 } else { + short *buffer, *vertPtr; + char *normBuffer, *normPtr; + float *uvPtr; + int j = 0; + // Dangit, I soooo want to do this in a GLSL shader... pglBegin(GL_TRIANGLES); - short *buffer = malloc(mesh->numVertices * sizeof(short)); - short *vertPtr = buffer; - char *normBuffer = malloc(mesh->numVertices * sizeof(char)); - char *normPtr = normBuffer; + buffer = malloc(mesh->numVertices * sizeof(short)); + vertPtr = buffer; + normBuffer = malloc(mesh->numVertices * sizeof(char)); + normPtr = normBuffer; - int j = 0; for (j = 0; j < mesh->numVertices; j++) { // Interpolate @@ -2052,7 +2061,7 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 *normPtr++ = (short)(frame->normals[j] + (pol * (nextframe->normals[j] - frame->normals[j]))); } - float *uvPtr = mesh->uvs; + uvPtr = mesh->uvs; vertPtr = buffer; normPtr = normBuffer; for (j = 0; j < mesh->numTriangles; j++) @@ -2096,15 +2105,21 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 } else { + int j = 0; + float *uvPtr; + float *frameVert; + float *frameNormal; + float *nextFrameVert; + float *nextFrameNormal; + // Dangit, I soooo want to do this in a GLSL shader... pglBegin(GL_TRIANGLES); - int j = 0; - float *uvPtr = mesh->uvs; - float *frameVert = frame->vertices; - float *frameNormal = frame->normals; - float *nextFrameVert = nextframe->vertices; - float *nextFrameNormal = frame->normals; + uvPtr = mesh->uvs; + frameVert = frame->vertices; + frameNormal = frame->normals; + nextFrameVert = nextframe->vertices; + nextFrameNormal = frame->normals; for (j = 0; j < mesh->numTriangles; j++) { // Interpolate From c84414132290fe6889ea72e54604e107eceb80c0 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Tue, 18 Dec 2018 20:36:39 -0500 Subject: [PATCH 09/74] Add new model files to CMake --- src/CMakeLists.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4a9ef5ba8..7e69603e0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -393,7 +393,11 @@ if(${SRB2_CONFIG_HWRENDER}) ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_light.c ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_main.c ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md2.c + ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md2load.c + ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md3load.c + ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_model.c ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_trick.c + ${CMAKE_CURRENT_SOURCE_DIR}/hardware/u_list.c ) set (SRB2_HWRENDER_HEADERS @@ -407,6 +411,10 @@ if(${SRB2_CONFIG_HWRENDER}) ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_light.h ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_main.h ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md2.h + ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md2load.h + ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md3load.h + ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_model.h + ${CMAKE_CURRENT_SOURCE_DIR}/hardware/u_list.h ) set(SRB2_R_OPENGL_SOURCES From 3a45b169eb93af53ad36b7ce7ed4ebf3f123fa2e Mon Sep 17 00:00:00 2001 From: mazmazz Date: Tue, 18 Dec 2018 20:41:08 -0500 Subject: [PATCH 10/74] Ignore fread return value (buildbot error) --- src/hardware/hw_md2load.c | 5 ++++- src/hardware/hw_md3load.c | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/hardware/hw_md2load.c b/src/hardware/hw_md2load.c index 1fdfefb97..ff195dda5 100644 --- a/src/hardware/hw_md2load.c +++ b/src/hardware/hw_md2load.c @@ -237,6 +237,7 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) md2header_t *header; size_t fileLen; + size_t fileReadLen; int i, j, t; size_t namelen; @@ -284,9 +285,11 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) // read in file buffer = malloc(fileLen); - fread(buffer, fileLen, 1, f); + fileReadLen = fread(buffer, fileLen, 1, f); fclose(f); + (void)fileReadLen; // intentionally ignore return value, per buildbot + // get pointer to file header header = (md2header_t*)buffer; diff --git a/src/hardware/hw_md3load.c b/src/hardware/hw_md3load.c index 35c6abf29..53f6034c0 100644 --- a/src/hardware/hw_md3load.c +++ b/src/hardware/hw_md3load.c @@ -150,6 +150,7 @@ model_t *MD3_LoadModel(const char *fileName, int ztag, boolean useFloat) model_t *retModel = NULL; md3modelHeader *mdh; long fileLen; + long fileReadLen; char *buffer; int surfEnd; int i, t; @@ -176,9 +177,11 @@ model_t *MD3_LoadModel(const char *fileName, int ztag, boolean useFloat) // read in file buffer = malloc(fileLen); - fread(buffer, fileLen, 1, f); + fileReadLen = fread(buffer, fileLen, 1, f); fclose(f); + (void)fileReadLen; // intentionally ignore return value, per buildbot + // get pointer to file header mdh = (md3modelHeader*)buffer; From 8d10a0b1059c2b4ceff68d49acdabad5f0b7bda9 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Tue, 18 Dec 2018 21:53:30 -0500 Subject: [PATCH 11/74] Add model sources to sdl1.2 VC project --- src/sdl12/Srb2SDL-vc10.vcxproj | 44 ++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/sdl12/Srb2SDL-vc10.vcxproj b/src/sdl12/Srb2SDL-vc10.vcxproj index 958cd7d02..9c550a092 100644 --- a/src/sdl12/Srb2SDL-vc10.vcxproj +++ b/src/sdl12/Srb2SDL-vc10.vcxproj @@ -755,6 +755,36 @@ %(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) %(PreprocessorDefinitions) @@ -765,6 +795,16 @@ %(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) %(PreprocessorDefinitions) @@ -1329,7 +1369,11 @@ + + + + From 65543545c6b2ccc3c32f44e459626de223a1c520 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Tue, 18 Dec 2018 22:50:00 -0500 Subject: [PATCH 12/74] hw_md2 merge errors --- src/hardware/hw_defs.h | 5 +- src/hardware/hw_md2.c | 127 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 126 insertions(+), 6 deletions(-) diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index c05ff3e79..ece627d3c 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -104,11 +104,12 @@ typedef struct typedef struct { FLOAT x,y,z; // position - FLOAT anglex,angley; // aimingangle / viewangle + FLOAT anglex,angley,anglez; // aimingangle / viewangle FLOAT scalex,scaley,scalez; FLOAT fovxangle, fovyangle; - INT32 splitscreen; + UINT8 splitscreen; boolean flip; // screenflip + boolean mirror; // SRB2Kart: Encore Mode } FTransform; // Transformed vector, as passed to HWR API diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index c1856a2c5..eca99e173 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -40,8 +40,8 @@ #include "../w_wad.h" #include "../z_zone.h" #include "../r_things.h" -// #include "../r_draw.h" -// #include "../p_tick.h" +#include "../r_draw.h" +#include "../p_tick.h" #include "hw_model.h" #include "hw_main.h" @@ -815,11 +815,13 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, return; } -static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, const UINT8 *colormap, skincolors_t color) +static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT32 skinnum, const UINT8 *colormap, skincolors_t color) { // mostly copied from HWR_GetMappedPatch, hence the similarities and comment GLMipmap_t *grmip, *newmip; + (void)skinnum; + if (colormap == colormaps || colormap == NULL) { // Don't do any blending @@ -889,7 +891,11 @@ void HWR_DrawMD2(gr_vissprite_t *spr) FSurfaceInfo Surf; char filename[64]; + INT32 frame = 0; + INT32 nextFrame = -1; + FTransform p; md2_t *md2; + UINT8 color[4]; if (!cv_grmd2.value) return; @@ -934,6 +940,16 @@ void HWR_DrawMD2(gr_vissprite_t *spr) // Look at HWR_ProjectSprite for more { GLPatch_t *gpatch; + INT32 durs = spr->mobj->state->tics; + INT32 tics = spr->mobj->tics; + const UINT8 flip = (UINT8)((spr->mobj->eflags & MFE_VERTICALFLIP) == MFE_VERTICALFLIP); + spritedef_t *sprdef; + spriteframe_t *sprframe; + float finalscale; + + // Apparently people don't like jump frames like that, so back it goes + //if (tics > durs) + //durs = tics; if (spr->mobj->flags2 & MF2_SHADOW) Surf.FlatColor.s.alpha = 0x40; @@ -975,6 +991,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) } } //HWD.pfnSetBlend(blend); // This seems to actually break translucency? + finalscale = md2->scale; //Hurdler: arf, I don't like that implementation at all... too much crappy gpatch = md2->grpatch; if (!gpatch || !gpatch->mipmap.grInfo.format || !gpatch->mipmap.downloaded) @@ -991,7 +1008,25 @@ void HWR_DrawMD2(gr_vissprite_t *spr) md2->blendgrpatch && ((GLPatch_t *)md2->blendgrpatch)->mipmap.grInfo.format && gpatch->width == ((GLPatch_t *)md2->blendgrpatch)->width && gpatch->height == ((GLPatch_t *)md2->blendgrpatch)->height) { - HWR_GetBlendedTexture(gpatch, (GLPatch_t *)md2->blendgrpatch, spr->colormap, (skincolors_t)spr->mobj->color); + INT32 skinnum; + if ((spr->mobj->flags & MF_BOSS) && (spr->mobj->flags2 & MF2_FRET) && (leveltime & 1)) // Bosses "flash" + { + if (spr->mobj->type == MT_CYBRAKDEMON) + skinnum = TC_ALLWHITE; + else if (spr->mobj->type == MT_METALSONIC_BATTLE) + skinnum = TC_METALSONIC; + else + skinnum = TC_BOSS; + } + else if (spr->mobj->color) + { + if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) + { + skinnum = (INT32)((skin_t*)spr->mobj->skin-skins); + } + else skinnum = TC_DEFAULT; + } + HWR_GetBlendedTexture(gpatch, (GLPatch_t *)md2->blendgrpatch, skinnum, spr->colormap, (skincolors_t)spr->mobj->color); } else { @@ -1005,6 +1040,90 @@ void HWR_DrawMD2(gr_vissprite_t *spr) gpatch = W_CachePatchNum(spr->patchlumpnum, PU_CACHE); HWR_GetMappedPatch(gpatch, spr->colormap); } + + if (spr->mobj->frame & FF_ANIMATE) + { + // set duration and tics to be the correct values for FF_ANIMATE states + durs = spr->mobj->state->var2; + tics = spr->mobj->anim_duration; + } + + //FIXME: this is not yet correct + frame = (spr->mobj->frame & FF_FRAMEMASK) % md2->model->meshes[0].numFrames; +#if 0 + if (cv_grmd2.value == 1 && tics <= durs) + { + // frames are handled differently for states with FF_ANIMATE, so get the next frame differently for the interpolation + if (spr->mobj->frame & FF_ANIMATE) + { + UINT32 nextframe = (spr->mobj->frame & FF_FRAMEMASK) + 1; + if (nextframe >= (UINT32)spr->mobj->state->var1) + nextframe = (spr->mobj->state->frame & FF_FRAMEMASK); + nextframe %= md2->model->header.numFrames; + next = &md2->model->frames[nextframe]; + } + else + { + if (spr->mobj->state->nextstate != S_NULL && states[spr->mobj->state->nextstate].sprite != SPR_NULL) + { + const UINT32 nextframe = (states[spr->mobj->state->nextstate].frame & FF_FRAMEMASK) % md2->model->header.numFrames; + next = &md2->model->frames[nextframe]; + } + } + } +#endif + + //Hurdler: it seems there is still a small problem with mobj angle + p.x = FIXED_TO_FLOAT(spr->mobj->x); + p.y = FIXED_TO_FLOAT(spr->mobj->y)+md2->offset; + + if (spr->mobj->eflags & MFE_VERTICALFLIP) + p.z = FIXED_TO_FLOAT(spr->mobj->z + spr->mobj->height); + else + p.z = FIXED_TO_FLOAT(spr->mobj->z); + + if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) + sprdef = &((skin_t *)spr->mobj->skin)->spritedef; + else + sprdef = &sprites[spr->mobj->sprite]; + + sprframe = &sprdef->spriteframes[spr->mobj->frame & FF_FRAMEMASK]; + + if (sprframe->rotate) + { + const fixed_t anglef = AngleFixed(spr->mobj->angle); + p.angley = FIXED_TO_FLOAT(anglef); + } + else + { + const fixed_t anglef = AngleFixed((R_PointToAngle(spr->mobj->x, spr->mobj->y))-ANGLE_180); + p.angley = FIXED_TO_FLOAT(anglef); + } + p.anglex = 0.0f; + p.anglez = 0.0f; + if (spr->mobj->standingslope) + { + fixed_t tempz = spr->mobj->standingslope->normal.z; + fixed_t tempy = spr->mobj->standingslope->normal.y; + fixed_t tempx = spr->mobj->standingslope->normal.x; + fixed_t tempangle = AngleFixed(R_PointToAngle2(0, 0, FixedSqrt(FixedMul(tempy, tempy) + FixedMul(tempz, tempz)), tempx)); + p.anglez = FIXED_TO_FLOAT(tempangle); + tempangle = -AngleFixed(R_PointToAngle2(0, 0, tempz, tempy)); + p.anglex = FIXED_TO_FLOAT(tempangle); + } + + color[0] = Surf.FlatColor.s.red; + color[1] = Surf.FlatColor.s.green; + color[2] = Surf.FlatColor.s.blue; + color[3] = Surf.FlatColor.s.alpha; + + // SRB2CBTODO: MD2 scaling support + finalscale *= FIXED_TO_FLOAT(spr->mobj->scale); + + p.flip = atransform.flip; + p.mirror = atransform.mirror; + + HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, finalscale, flip, color); } } From 45f0f725cd99d0f4a7020a7a45d723319553ac39 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Tue, 18 Dec 2018 23:44:38 -0500 Subject: [PATCH 13/74] More hw_md2 merge errors; re-enable interpolation code block --- src/hardware/hw_md2.c | 30 +++++------------------------- 1 file changed, 5 insertions(+), 25 deletions(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index eca99e173..81ac492d9 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -815,13 +815,11 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, return; } -static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT32 skinnum, const UINT8 *colormap, skincolors_t color) +static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, const UINT8 *colormap, skincolors_t color) { // mostly copied from HWR_GetMappedPatch, hence the similarities and comment GLMipmap_t *grmip, *newmip; - (void)skinnum; - if (colormap == colormaps || colormap == NULL) { // Don't do any blending @@ -1008,25 +1006,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) md2->blendgrpatch && ((GLPatch_t *)md2->blendgrpatch)->mipmap.grInfo.format && gpatch->width == ((GLPatch_t *)md2->blendgrpatch)->width && gpatch->height == ((GLPatch_t *)md2->blendgrpatch)->height) { - INT32 skinnum; - if ((spr->mobj->flags & MF_BOSS) && (spr->mobj->flags2 & MF2_FRET) && (leveltime & 1)) // Bosses "flash" - { - if (spr->mobj->type == MT_CYBRAKDEMON) - skinnum = TC_ALLWHITE; - else if (spr->mobj->type == MT_METALSONIC_BATTLE) - skinnum = TC_METALSONIC; - else - skinnum = TC_BOSS; - } - else if (spr->mobj->color) - { - if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) - { - skinnum = (INT32)((skin_t*)spr->mobj->skin-skins); - } - else skinnum = TC_DEFAULT; - } - HWR_GetBlendedTexture(gpatch, (GLPatch_t *)md2->blendgrpatch, skinnum, spr->colormap, (skincolors_t)spr->mobj->color); + HWR_GetBlendedTexture(gpatch, (GLPatch_t *)md2->blendgrpatch, spr->colormap, (skincolors_t)spr->mobj->color); } else { @@ -1050,7 +1030,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) //FIXME: this is not yet correct frame = (spr->mobj->frame & FF_FRAMEMASK) % md2->model->meshes[0].numFrames; -#if 0 + if (cv_grmd2.value == 1 && tics <= durs) { // frames are handled differently for states with FF_ANIMATE, so get the next frame differently for the interpolation @@ -1064,14 +1044,14 @@ void HWR_DrawMD2(gr_vissprite_t *spr) } else { - if (spr->mobj->state->nextstate != S_NULL && states[spr->mobj->state->nextstate].sprite != SPR_NULL) + if (spr->mobj->state->nextstate != S_NULL && states[spr->mobj->state->nextstate].sprite != SPR_NULL + && !(spr->mobj->player && (spr->mobj->state->nextstate == S_PLAY_TAP1 || spr->mobj->state->nextstate == S_PLAY_TAP2) && spr->mobj->state == &states[S_PLAY_STND])) { const UINT32 nextframe = (states[spr->mobj->state->nextstate].frame & FF_FRAMEMASK) % md2->model->header.numFrames; next = &md2->model->frames[nextframe]; } } } -#endif //Hurdler: it seems there is still a small problem with mobj angle p.x = FIXED_TO_FLOAT(spr->mobj->x); From 98d18509e6c078749d64a0797d4a9d76db4b5eaa Mon Sep 17 00:00:00 2001 From: mazmazz Date: Wed, 19 Dec 2018 00:17:51 -0500 Subject: [PATCH 14/74] Hide/add Kart FTransform mirror and anglez behind ifdef --- src/hardware/hw_defs.h | 11 ++++++++++ src/hardware/hw_md2.c | 7 +++++- src/hardware/r_opengl/r_opengl.c | 37 ++++++++++++++++++++++++++------ 3 files changed, 47 insertions(+), 8 deletions(-) diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index ece627d3c..f9ae9c430 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -101,15 +101,26 @@ typedef struct //Hurdler: Transform (coords + angles) //BP: transform order : scale(rotation_x(rotation_y(translation(v)))) + +// Kart features +//#define USE_FTRANSFORM_ANGLEZ +//#define USE_FTRANSFORM_MIRROR + typedef struct { FLOAT x,y,z; // position +#ifdef USE_FTRANSFORM_ANGLEZ FLOAT anglex,angley,anglez; // aimingangle / viewangle +#else + FLOAT anglex,angley; // aimingangle / viewangle +#endif FLOAT scalex,scaley,scalez; FLOAT fovxangle, fovyangle; UINT8 splitscreen; boolean flip; // screenflip +#ifdef USE_FTRANSFORM_MIRROR boolean mirror; // SRB2Kart: Encore Mode +#endif } FTransform; // Transformed vector, as passed to HWR API diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 81ac492d9..032594f22 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1080,6 +1080,8 @@ void HWR_DrawMD2(gr_vissprite_t *spr) p.angley = FIXED_TO_FLOAT(anglef); } p.anglex = 0.0f; +#ifdef USE_FTRANSFORM_ANGLEZ + // Slope rotation from Kart p.anglez = 0.0f; if (spr->mobj->standingslope) { @@ -1091,6 +1093,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) tempangle = -AngleFixed(R_PointToAngle2(0, 0, tempz, tempy)); p.anglex = FIXED_TO_FLOAT(tempangle); } +#endif color[0] = Surf.FlatColor.s.red; color[1] = Surf.FlatColor.s.green; @@ -1101,7 +1104,9 @@ void HWR_DrawMD2(gr_vissprite_t *spr) finalscale *= FIXED_TO_FLOAT(spr->mobj->scale); p.flip = atransform.flip; - p.mirror = atransform.mirror; +#ifdef USE_FTRANSFORM_MIRROR + p.mirror = atransform.mirror; // from Kart +#endif HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, finalscale, flip, color); } diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 828ec8d83..5f21ec7ed 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -112,10 +112,10 @@ static GLint viewport[4]; // These need to start at 0 and be set to their number, and be reset to 0 when deleted so that intel GPUs // can know when the textures aren't there, as textures are always considered resident in their virtual memory // TODO: Store them in a more normal way -#define SCRTEX_SCREENTEXTURE 65535 -#define SCRTEX_STARTSCREENWIPE 65534 -#define SCRTEX_ENDSCREENWIPE 65533 -#define SCRTEX_FINALSCREENTEXTURE 65532 +#define SCRTEX_SCREENTEXTURE 4294967295U +#define SCRTEX_STARTSCREENWIPE 4294967294U +#define SCRTEX_ENDSCREENWIPE 4294967293U +#define SCRTEX_FINALSCREENTEXTURE 4294967292U static GLuint screentexture = 0; static GLuint startScreenWipe = 0; static GLuint endScreenWipe = 0; @@ -1971,6 +1971,19 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 pglEnable(GL_CULL_FACE); +#ifdef USE_FTRANSFORM_MIRROR + // flipped is if the object is flipped + // pos->flip is if the screen is flipped vertically + // pos->mirror is if the screen is flipped horizontally + // XOR all the flips together to figure out what culling to use! + { + boolean reversecull = (flipped ^ pos->flip ^ pos->mirror); + if (reversecull) + pglCullFace(GL_FRONT); + else + pglCullFace(GL_BACK); + } +#else // pos->flip is if the screen is flipped too if (flipped != pos->flip) // If either are active, but not both, invert the model's culling { @@ -1980,6 +1993,7 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 { pglCullFace(GL_BACK); } +#endif #ifndef KOS_GL_COMPATIBILITY pglLightfv(GL_LIGHT0, GL_POSITION, LightPos); @@ -2004,8 +2018,11 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 pglTranslatef(pos->x, pos->z, pos->y); if (flipped) scaley = -scaley; - pglRotatef(pos->angley, 0.0f, -1.0f, 0.0f); +#ifdef USE_FTRANSFORM_ANGLEZ + pglRotatef(pos->anglez, 0.0f, 0.0f, -1.0f); // rotate by slope from Kart +#endif pglRotatef(pos->anglex, -1.0f, 0.0f, 0.0f); + pglRotatef(pos->angley, 0.0f, -1.0f, 0.0f); pglScalef(scalex, scaley, scalez); @@ -2172,13 +2189,19 @@ EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, // -----------------+ EXPORT void HWRAPI(SetTransform) (FTransform *stransform) { - static INT32 special_splitscreen; + static boolean special_splitscreen; pglLoadIdentity(); if (stransform) { // keep a trace of the transformation for md2 memcpy(&md2_transform, stransform, sizeof (md2_transform)); +#ifdef USE_FTRANSFORM_MIRROR + // mirroring from Kart + if (stransform->mirror) + pglScalef(-stransform->scalex, stransform->scaley, -stransform->scalez); + else +#endif if (stransform->flip) pglScalef(stransform->scalex, -stransform->scaley, -stransform->scalez); else @@ -2190,7 +2213,7 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform) pglMatrixMode(GL_PROJECTION); pglLoadIdentity(); - special_splitscreen = (stransform->splitscreen && stransform->fovxangle == 90.0f); + special_splitscreen = (stransform->splitscreen == 1 && stransform->fovxangle == 90.0f); if (special_splitscreen) GLPerspective(53.13l, 2*ASPECT_RATIO); // 53.13 = 2*atan(0.5) else From c4f5bdc3479dacbdcf303bb6afd7668ecc4f2369 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Wed, 19 Dec 2018 00:38:00 -0500 Subject: [PATCH 15/74] Adapt re-enabled DrawMD2 code block for meshes --- src/hardware/hw_md2.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 032594f22..18b30a4f5 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -940,6 +940,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) GLPatch_t *gpatch; INT32 durs = spr->mobj->state->tics; INT32 tics = spr->mobj->tics; + //mdlframe_t *next = NULL; const UINT8 flip = (UINT8)((spr->mobj->eflags & MFE_VERTICALFLIP) == MFE_VERTICALFLIP); spritedef_t *sprdef; spriteframe_t *sprframe; @@ -1036,19 +1037,19 @@ void HWR_DrawMD2(gr_vissprite_t *spr) // frames are handled differently for states with FF_ANIMATE, so get the next frame differently for the interpolation if (spr->mobj->frame & FF_ANIMATE) { - UINT32 nextframe = (spr->mobj->frame & FF_FRAMEMASK) + 1; - if (nextframe >= (UINT32)spr->mobj->state->var1) - nextframe = (spr->mobj->state->frame & FF_FRAMEMASK); - nextframe %= md2->model->header.numFrames; - next = &md2->model->frames[nextframe]; + nextFrame = (spr->mobj->frame & FF_FRAMEMASK) + 1; + if (nextFrame >= spr->mobj->state->var1) + nextFrame = (spr->mobj->state->frame & FF_FRAMEMASK); + nextFrame %= md2->model->meshes[0].numFrames; + //next = &md2->model->meshes[0].frames[nextFrame]; } else { if (spr->mobj->state->nextstate != S_NULL && states[spr->mobj->state->nextstate].sprite != SPR_NULL && !(spr->mobj->player && (spr->mobj->state->nextstate == S_PLAY_TAP1 || spr->mobj->state->nextstate == S_PLAY_TAP2) && spr->mobj->state == &states[S_PLAY_STND])) { - const UINT32 nextframe = (states[spr->mobj->state->nextstate].frame & FF_FRAMEMASK) % md2->model->header.numFrames; - next = &md2->model->frames[nextframe]; + nextFrame = (states[spr->mobj->state->nextstate].frame & FF_FRAMEMASK) % md2->model->meshes[0].numFrames; + //next = &md2->model->meshes[0].frames[nextFrame]; } } } From 90bd80d17a45eefa897a7275c16559c04aea0fc2 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Wed, 19 Dec 2018 01:57:54 -0500 Subject: [PATCH 16/74] Interpolation fix attempt? * Fix pglNormal3bv pointer because typo --- src/hardware/r_opengl/r_opengl.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 5f21ec7ed..7bb8442e4 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -523,7 +523,7 @@ boolean SetupGLfunc(void) GETOPENGLFUNC(pglVertex3f , glVertex3f) GETOPENGLFUNC(pglVertex3sv, glVertex3sv) GETOPENGLFUNC(pglNormal3f , glNormal3f) - GETOPENGLFUNC(pglNormal3bv, glNomral3bv) + GETOPENGLFUNC(pglNormal3bv, glNormal3bv) GETOPENGLFUNC(pglColor4f , glColor4f) GETOPENGLFUNC(pglColor4fv , glColor4fv) GETOPENGLFUNC(pglTexCoord2f , glTexCoord2f) @@ -2075,7 +2075,7 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 { // Interpolate *vertPtr++ = (short)(frame->vertices[j] + (pol * (nextframe->vertices[j] - frame->vertices[j]))); - *normPtr++ = (short)(frame->normals[j] + (pol * (nextframe->normals[j] - frame->normals[j]))); + *normPtr++ = (char)(frame->normals[j] + (pol * (nextframe->normals[j] - frame->normals[j]))); } uvPtr = mesh->uvs; @@ -2083,9 +2083,9 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 normPtr = normBuffer; for (j = 0; j < mesh->numTriangles; j++) { - pglTexCoord2fv((const GLfloat*) uvPtr); - pglNormal3bv((const GLbyte*) normPtr); - pglVertex3sv((const GLshort*) vertPtr); + pglTexCoord2fv(uvPtr); + pglNormal3bv((signed char*) normPtr); + pglVertex3sv(vertPtr); uvPtr += 2; normPtr += 3; From 59826860ab41bdb2d01f7ece21a4c9d5e4797f91 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Wed, 19 Dec 2018 10:33:13 -0500 Subject: [PATCH 17/74] Ifdef nextFrame handling under USE_MODEL_NEXTFRAME --- src/hardware/hw_defs.h | 3 +++ src/hardware/hw_md2.c | 2 ++ 2 files changed, 5 insertions(+) diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index f9ae9c430..4fbd8d081 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -106,6 +106,9 @@ typedef struct //#define USE_FTRANSFORM_ANGLEZ //#define USE_FTRANSFORM_MIRROR +// Vanilla features +#define USE_MODEL_NEXTFRAME + typedef struct { FLOAT x,y,z; // position diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 18b30a4f5..e78812fa0 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1032,6 +1032,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) //FIXME: this is not yet correct frame = (spr->mobj->frame & FF_FRAMEMASK) % md2->model->meshes[0].numFrames; +#ifdef USE_MODEL_NEXTFRAME if (cv_grmd2.value == 1 && tics <= durs) { // frames are handled differently for states with FF_ANIMATE, so get the next frame differently for the interpolation @@ -1053,6 +1054,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) } } } +#endif //Hurdler: it seems there is still a small problem with mobj angle p.x = FIXED_TO_FLOAT(spr->mobj->x); From 4728ad97ebba1631bc1bc3456f8bf5e779870aae Mon Sep 17 00:00:00 2001 From: AJ Freda Date: Wed, 19 Dec 2018 20:52:47 -0500 Subject: [PATCH 18/74] Fixed a few unnoticable mistakes [vanilla] --- src/hardware/hw_md2load.c | 3 +- src/hardware/r_opengl/r_opengl.c | 75 ++++++++++++-------------------- 2 files changed, 31 insertions(+), 47 deletions(-) diff --git a/src/hardware/hw_md2load.c b/src/hardware/hw_md2load.c index ff195dda5..49fdbf8ab 100644 --- a/src/hardware/hw_md2load.c +++ b/src/hardware/hw_md2load.c @@ -454,12 +454,13 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) else // Full float loading method { md2triangle_t *trisPtr = tris; - float *uvptr = retModel->meshes[0].uvs; + float *uvptr; char *ptr = (char*)frames; retModel->meshes[0].numVertices = header->numTris*3; retModel->meshes[0].frames = (mdlframe_t*)Z_Calloc(sizeof(mdlframe_t)*header->numFrames, ztag, 0); retModel->meshes[0].uvs = (float*)Z_Malloc(sizeof(float)*2*retModel->meshes[0].numVertices, ztag, 0); + uvptr = retModel->meshes[0].uvs; for (i = 0; i < retModel->meshes[0].numTriangles; i++, trisPtr++) { diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 7bb8442e4..c0b6d2a7c 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1924,6 +1924,7 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 GLfloat diffuse[4]; float pol = 0.0f; + scale *= 0.5f; float scalex = scale, scaley = scale, scalez = scale; boolean useTinyFrames; @@ -1935,8 +1936,6 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 GLfloat LightPos[] = {0.0f, 1.0f, 0.0f, 0.0f}; #endif - scale *= 0.5f; - if (duration != 0 && duration != -1 && tics != -1) // don't interpolate if instantaneous or infinite in length { UINT32 newtime = (duration - tics); // + 1; @@ -2054,22 +2053,16 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 pglDrawElements(GL_TRIANGLES, mesh->numTriangles * 3, GL_UNSIGNED_SHORT, mesh->indices); pglDisableClientState(GL_NORMAL_ARRAY); pglDisableClientState(GL_TEXTURE_COORD_ARRAY); - pglDisableClientState(GL_TEXTURE_COORD_ARRAY); + pglDisableClientState(GL_VERTEX_ARRAY); } else { - short *buffer, *vertPtr; - char *normBuffer, *normPtr; - float *uvPtr; - int j = 0; - // Dangit, I soooo want to do this in a GLSL shader... - pglBegin(GL_TRIANGLES); - - buffer = malloc(mesh->numVertices * sizeof(short)); - vertPtr = buffer; - normBuffer = malloc(mesh->numVertices * sizeof(char)); - normPtr = normBuffer; + short *buffer = malloc(mesh->numVertices * sizeof(short) * 3); + short *vertPtr = buffer; + char *normBuffer = malloc(mesh->numVertices * sizeof(char) * 3); + char *normPtr = normBuffer; + int j = 0; for (j = 0; j < mesh->numVertices; j++) { @@ -2078,24 +2071,19 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 *normPtr++ = (char)(frame->normals[j] + (pol * (nextframe->normals[j] - frame->normals[j]))); } - uvPtr = mesh->uvs; - vertPtr = buffer; - normPtr = normBuffer; - for (j = 0; j < mesh->numTriangles; j++) - { - pglTexCoord2fv(uvPtr); - pglNormal3bv((signed char*) normPtr); - pglVertex3sv(vertPtr); - - uvPtr += 2; - normPtr += 3; - vertPtr += 3; - } + pglEnableClientState(GL_VERTEX_ARRAY); + pglEnableClientState(GL_TEXTURE_COORD_ARRAY); + pglEnableClientState(GL_NORMAL_ARRAY); + pglVertexPointer(3, GL_SHORT, 0, buffer); + pglNormalPointer(GL_BYTE, 0, normBuffer); + pglTexCoordPointer(2, GL_FLOAT, 0, mesh->uvs); + pglDrawElements(GL_TRIANGLES, mesh->numTriangles * 3, GL_UNSIGNED_SHORT, mesh->indices); + pglDisableClientState(GL_NORMAL_ARRAY); + pglDisableClientState(GL_TEXTURE_COORD_ARRAY); + pglDisableClientState(GL_VERTEX_ARRAY); free(buffer); free(normBuffer); - - pglEnd(); } } else @@ -2118,39 +2106,34 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 pglDrawArrays(GL_TRIANGLES, 0, mesh->numTriangles * 3); pglDisableClientState(GL_NORMAL_ARRAY); pglDisableClientState(GL_TEXTURE_COORD_ARRAY); - pglDisableClientState(GL_TEXTURE_COORD_ARRAY); + pglDisableClientState(GL_VERTEX_ARRAY); } else { int j = 0; - float *uvPtr; - float *frameVert; - float *frameNormal; - float *nextFrameVert; - float *nextFrameNormal; + float *uvPtr = mesh->uvs; + float *frameVert = frame->vertices; + float *frameNormal = frame->normals; + float *nextFrameVert = nextframe->vertices; + float *nextFrameNormal = nextframe->normals; // Dangit, I soooo want to do this in a GLSL shader... pglBegin(GL_TRIANGLES); - uvPtr = mesh->uvs; - frameVert = frame->vertices; - frameNormal = frame->normals; - nextFrameVert = nextframe->vertices; - nextFrameNormal = frame->normals; - for (j = 0; j < mesh->numTriangles; j++) + for (j = 0; j < mesh->numTriangles * 3; j++) { // Interpolate float px1 = *frameVert++; - float px2 = *nextFrameVert++; float py1 = *frameVert++; - float py2 = *nextFrameVert++; float pz1 = *frameVert++; + float px2 = *nextFrameVert++; + float py2 = *nextFrameVert++; float pz2 = *nextFrameVert++; float nx1 = *frameNormal++; - float nx2 = *nextFrameNormal++; float ny1 = *frameNormal++; - float ny2 = *nextFrameNormal++; float nz1 = *frameNormal++; + float nx2 = *nextFrameNormal++; + float ny2 = *nextFrameNormal++; float nz2 = *nextFrameNormal++; pglTexCoord2fv(uvPtr); @@ -2161,7 +2144,7 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 (py1 + pol * (py2 - py1)), (pz1 + pol * (pz2 - pz1))); - uvPtr++; + uvPtr += 2; } pglEnd(); From 6c5bb7f541b55f81180454b4b91612c112a20f56 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Wed, 19 Dec 2018 20:56:58 -0500 Subject: [PATCH 19/74] Small Mixed D&C fix --- src/hardware/r_opengl/r_opengl.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index c0b6d2a7c..fec8c33a3 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1924,8 +1924,8 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 GLfloat diffuse[4]; float pol = 0.0f; - scale *= 0.5f; - float scalex = scale, scaley = scale, scalez = scale; + + float scalex, scaley, scalez; boolean useTinyFrames; @@ -1936,6 +1936,9 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 GLfloat LightPos[] = {0.0f, 1.0f, 0.0f, 0.0f}; #endif + scale *= 0.5f; + scalex = scaley = scalez = scale; + if (duration != 0 && duration != -1 && tics != -1) // don't interpolate if instantaneous or infinite in length { UINT32 newtime = (duration - tics); // + 1; From b19252651fdbfde662ca9e76c8b1742bdde19e8c Mon Sep 17 00:00:00 2001 From: Arthur Date: Sun, 23 Dec 2018 17:00:11 -0500 Subject: [PATCH 20/74] Removed all glBegin/glEnd references MD2/MD3 now works, with the exception of WAD textures for some odd reason --- src/hardware/hw_drv.h | 4 - src/hardware/hw_main.c | 2 - src/hardware/hw_md2load.c | 250 +++---- src/hardware/r_opengl/r_opengl.c | 885 ++++++++----------------- src/hardware/r_opengl/r_opengl.h | 2 - src/sdl/hwsym_sdl.c | 2 - src/sdl/i_video.c | 2 - src/win32/Srb2win-vc10.vcxproj.filters | 16 +- 8 files changed, 386 insertions(+), 777 deletions(-) diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index 7b45b0974..c1ece091a 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -63,10 +63,8 @@ EXPORT void HWRAPI(SetTransform) (FTransform *ptransform); EXPORT INT32 HWRAPI(GetTextureUsed) (void); EXPORT INT32 HWRAPI(GetRenderVersion) (void); -#ifdef SHUFFLE #define SCREENVERTS 10 EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]); -#endif EXPORT void HWRAPI(FlushScreenTextures) (void); EXPORT void HWRAPI(StartScreenWipe) (void); EXPORT void HWRAPI(EndScreenWipe) (void); @@ -105,9 +103,7 @@ struct hwdriver_s #ifndef HAVE_SDL Shutdown pfnShutdown; #endif -#ifdef SHUFFLE PostImgRedraw pfnPostImgRedraw; -#endif FlushScreenTextures pfnFlushScreenTextures; StartScreenWipe pfnStartScreenWipe; EndScreenWipe pfnEndScreenWipe; diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index fb5e2a716..e1d5d99a7 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -6637,7 +6637,6 @@ void HWR_DoPostProcessor(player_t *player) if (splitscreen) // Not supported in splitscreen - someone want to add support? return; -#ifdef SHUFFLE // Drunken vision! WooOOooo~ if (*type == postimg_water || *type == postimg_heat) { @@ -6680,7 +6679,6 @@ void HWR_DoPostProcessor(player_t *player) HWD.pfnMakeScreenTexture(); } // Flipping of the screen isn't done here anymore -#endif // SHUFFLE } void HWR_StartScreenWipe(void) diff --git a/src/hardware/hw_md2load.c b/src/hardware/hw_md2load.c index 49fdbf8ab..d29414b0f 100644 --- a/src/hardware/hw_md2load.c +++ b/src/hardware/hw_md2load.c @@ -17,7 +17,7 @@ #define NUMVERTEXNORMALS 162 -// Quake 2 normals are indexed. Use avertexnormals[normalindex][x/y/z] and +// Quake 2 normals are indexed. Use avertexnormals[normalindex][x/y/z] and // you'll have your normals. float avertexnormals[NUMVERTEXNORMALS][3] = { {-0.525731f, 0.000000f, 0.850651f}, @@ -186,71 +186,57 @@ float avertexnormals[NUMVERTEXNORMALS][3] = { typedef struct { - int ident; // A "magic number" that's used to identify the .md2 file - int version; // The version of the file, always 8 - int skinwidth; // Width of the skin(s) in pixels - int skinheight; // Height of the skin(s) in pixels - int framesize; // Size of each frame in bytes - int numSkins; // Number of skins with the model - int numXYZ; // Number of vertices in each frame - int numST; // Number of texture coordinates in each frame. - int numTris; // Number of triangles in each frame - int numGLcmds; // Number of dwords (4 bytes) in the gl command list. - int numFrames; // Number of frames - int offsetSkins; // Offset, in bytes from the start of the file, to the list of skin names. - int offsetST; // Offset, in bytes from the start of the file, to the list of texture coordinates - int offsetTris; // Offset, in bytes from the start of the file, to the list of triangles - int offsetFrames; // Offset, in bytes from the start of the file, to the list of frames - int offsetGLcmds; // Offset, in bytes from the start of the file, to the list of gl commands - int offsetEnd; // Offset, in bytes from the start of the file, to the end of the file (filesize) + int ident; // A "magic number" that's used to identify the .md2 file + int version; // The version of the file, always 8 + int skinwidth; // Width of the skin(s) in pixels + int skinheight; // Height of the skin(s) in pixels + int framesize; // Size of each frame in bytes + int numSkins; // Number of skins with the model + int numXYZ; // Number of vertices in each frame + int numST; // Number of texture coordinates in each frame. + int numTris; // Number of triangles in each frame + int numGLcmds; // Number of dwords (4 bytes) in the gl command list. + int numFrames; // Number of frames + int offsetSkins; // Offset, in bytes from the start of the file, to the list of skin names. + int offsetST; // Offset, in bytes from the start of the file, to the list of texture coordinates + int offsetTris; // Offset, in bytes from the start of the file, to the list of triangles + int offsetFrames; // Offset, in bytes from the start of the file, to the list of frames + int offsetGLcmds; // Offset, in bytes from the start of the file, to the list of gl commands + int offsetEnd; // Offset, in bytes from the start of the file, to the end of the file (filesize) } md2header_t; typedef struct { - unsigned short meshIndex[3]; // indices into the array of vertices in each frames - unsigned short stIndex[3]; // indices into the array of texture coordinates + unsigned short meshIndex[3]; // indices into the array of vertices in each frames + unsigned short stIndex[3]; // indices into the array of texture coordinates } md2triangle_t; typedef struct { - short s; - short t; + short s; + short t; } md2texcoord_t; typedef struct { - unsigned char v[3]; // Scaled vertices. You'll need to multiply them with scale[x] to make them normal. - unsigned char lightNormalIndex; // Index to the array of normals + unsigned char v[3]; // Scaled vertices. You'll need to multiply them with scale[x] to make them normal. + unsigned char lightNormalIndex; // Index to the array of normals } md2vertex_t; typedef struct { - float scale[3]; // Used by the v member in the md2framePoint structure - float translate[3]; // Used by the v member in the md2framePoint structure - char name[16]; // Name of the frame + float scale[3]; // Used by the v member in the md2framePoint structure + float translate[3]; // Used by the v member in the md2framePoint structure + char name[16]; // Name of the frame } md2frame_t; // Load the model model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) { + useFloat = true; model_t *retModel = NULL; md2header_t *header; - size_t fileLen; - size_t fileReadLen; - int i, j, t; - - size_t namelen; - char *texturefilename, *buffer; - const char *texPos; - - const float WUNITS = 1.0f; - float dataScale; - - md2triangle_t *tris; - md2texcoord_t *texcoords; - md2frame_t *frames; - FILE *f = fopen(fileName, "rb"); if (!f) @@ -258,7 +244,13 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) retModel = (model_t*)Z_Calloc(sizeof(model_t), ztag, 0); - texPos = strchr(fileName, '/'); + size_t fileLen; + + int i, j; + + size_t namelen; + char *texturefilename; + const char *texPos = strchr(fileName, '/'); if (texPos) { @@ -274,9 +266,9 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) strcpy(texturefilename, fileName); } - texturefilename[namelen-2] = 'z'; - texturefilename[namelen-3] = 'u'; - texturefilename[namelen-4] = 'b'; + texturefilename[namelen - 2] = 'z'; + texturefilename[namelen - 3] = 'u'; + texturefilename[namelen - 4] = 'b'; // find length of file fseek(f, 0, SEEK_END); @@ -284,25 +276,23 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) fseek(f, 0, SEEK_SET); // read in file - buffer = malloc(fileLen); - fileReadLen = fread(buffer, fileLen, 1, f); + char *buffer = malloc(fileLen); + fread(buffer, fileLen, 1, f); fclose(f); - (void)fileReadLen; // intentionally ignore return value, per buildbot - // get pointer to file header header = (md2header_t*)buffer; retModel->numMeshes = 1; // MD2 only has one mesh retModel->meshes = (mesh_t*)Z_Calloc(sizeof(mesh_t) * retModel->numMeshes, ztag, 0); retModel->meshes[0].numFrames = header->numFrames; - - dataScale = WUNITS; + const float WUNITS = 1.0f; + float dataScale = WUNITS; // Tris and ST are simple structures that can be straight-copied - tris = (md2triangle_t*)&buffer[header->offsetTris]; - texcoords = (md2texcoord_t*)&buffer[header->offsetST]; - frames = (md2frame_t*)&buffer[header->offsetFrames]; + md2triangle_t *tris = (md2triangle_t*)&buffer[header->offsetTris]; + md2texcoord_t *texcoords = (md2texcoord_t*)&buffer[header->offsetST]; + md2frame_t *frames = (md2frame_t*)&buffer[header->offsetFrames]; // Read in textures retModel->numMaterials = header->numSkins; @@ -312,6 +302,7 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) retModel->materials = (material_t*)Z_Calloc(sizeof(material_t)*retModel->numMaterials, ztag, 0); + int t; for (t = 0; t < retModel->numMaterials; t++) { retModel->materials[t].ambient[0] = 0.8f; @@ -333,86 +324,76 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) retModel->materials[t].shininess = 0.0f; retModel->materials[t].spheremap = false; -/* retModel->materials[t].texture = Texture::ReadTexture((char*)texturefilename, ZT_TEXTURE); + /* retModel->materials[t].texture = Texture::ReadTexture((char*)texturefilename, ZT_TEXTURE); - if (!systemSucks) - { - // Check for a normal map...?? - Resource::resource_t *res - char openfilename[1024]; - char normalMapName[1024]; - strcpy(normalMapName, texturefilename); - size_t len = strlen(normalMapName); - char *ptr = &normalMapName[len]; - ptr--; // z - ptr--; // u - ptr--; // b - ptr--; // . - *ptr++ = '_'; - *ptr++ = 'n'; - *ptr++ = '.'; - *ptr++ = 'b'; - *ptr++ = 'u'; - *ptr++ = 'z'; - *ptr++ = '\0'; + if (!systemSucks) + { + // Check for a normal map...?? + char openfilename[1024]; + char normalMapName[1024]; + strcpy(normalMapName, texturefilename); + size_t len = strlen(normalMapName); + char *ptr = &normalMapName[len]; + ptr--; // z + ptr--; // u + ptr--; // b + ptr--; // . + *ptr++ = '_'; + *ptr++ = 'n'; + *ptr++ = '.'; + *ptr++ = 'b'; + *ptr++ = 'u'; + *ptr++ = 'z'; + *ptr++ = '\0'; - sprintf(openfilename, "%s/%s", "textures", normalMapName); - // Convert backslashes to forward slashes - for (int k = 0; k < 1024; k++) - { - if (openfilename[k] == '\0') - break; + sprintf(openfilename, "%s/%s", "textures", normalMapName); + // Convert backslashes to forward slashes + for (int k = 0; k < 1024; k++) + { + if (openfilename[k] == '\0') + break; - if (openfilename[k] == '\\') - openfilename[k] = '/'; - } + if (openfilename[k] == '\\') + openfilename[k] = '/'; + } - res = Resource::Open(openfilename); - if (res) - { - Resource::Close(res); - retModel->materials[t].lightmap = Texture::ReadTexture(normalMapName, ZT_TEXTURE); - } - }*/ + Resource::resource_t *res = Resource::Open(openfilename); + if (res) + { + Resource::Close(res); + retModel->materials[t].lightmap = Texture::ReadTexture(normalMapName, ZT_TEXTURE); + } + }*/ } retModel->meshes[0].numTriangles = header->numTris; if (!useFloat) // Decompress to MD3 'tinyframe' space { - char *ptr = (char*)frames; - md2triangle_t *trisPtr; - unsigned short *indexptr; - float *uvptr; - dataScale = 0.015624f; // 1 / 64.0f retModel->meshes[0].tinyframes = (tinyframe_t*)Z_Calloc(sizeof(tinyframe_t)*header->numFrames, ztag, 0); retModel->meshes[0].numVertices = header->numXYZ; - retModel->meshes[0].uvs = (float*)Z_Malloc (sizeof(float)*2*retModel->meshes[0].numVertices, ztag, 0); + retModel->meshes[0].uvs = (float*)Z_Malloc(sizeof(float) * 2 * retModel->meshes[0].numVertices, ztag, 0); + byte *ptr = (byte*)frames; for (i = 0; i < header->numFrames; i++, ptr += header->framesize) { - short *vertptr; - char *normptr; - //char *tanptr; md2frame_t *framePtr = (md2frame_t*)ptr; - md2vertex_t *vertex; + retModel->meshes[0].tinyframes[i].vertices = (short*)Z_Malloc(sizeof(short) * 3 * header->numXYZ, ztag, 0); + retModel->meshes[0].tinyframes[i].normals = (char*)Z_Malloc(sizeof(char) * 3 * header->numXYZ, ztag, 0); - retModel->meshes[0].tinyframes[i].vertices = (short*)Z_Malloc(sizeof(short)*3*header->numXYZ, ztag, 0); - retModel->meshes[0].tinyframes[i].normals = (char*)Z_Malloc(sizeof(char)*3*header->numXYZ, ztag, 0); - -// if (retModel->materials[0].lightmap) -// retModel->meshes[0].tinyframes[i].tangents = (char*)malloc(sizeof(char));//(char*)Z_Malloc(sizeof(char)*3*header->numVerts, ztag); + // if (retModel->materials[0].lightmap) + // retModel->meshes[0].tinyframes[i].tangents = (char*)malloc(sizeof(char));//(char*)Z_Malloc(sizeof(char)*3*header->numVerts, ztag); retModel->meshes[0].indices = (unsigned short*)Z_Malloc(sizeof(unsigned short) * 3 * header->numTris, ztag, 0); - vertptr = retModel->meshes[0].tinyframes[i].vertices; - normptr = retModel->meshes[0].tinyframes[i].normals; + short *vertptr = retModel->meshes[0].tinyframes[i].vertices; + char *normptr = retModel->meshes[0].tinyframes[i].normals; -// tanptr = retModel->meshes[0].tinyframes[i].tangents; + // char *tanptr = retModel->meshes[0].tinyframes[i].tangents; retModel->meshes[0].tinyframes[i].material = &retModel->materials[0]; framePtr++; // Advance to vertex list - vertex = (md2vertex_t*)framePtr; + md2vertex_t *vertex = (md2vertex_t*)framePtr; framePtr--; for (j = 0; j < header->numXYZ; j++, vertex++) { @@ -425,15 +406,15 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) // Normal *normptr++ = (char)(avertexnormals[vertex->lightNormalIndex][0] * 127); - *normptr++ = (char)(avertexnormals[vertex->lightNormalIndex][1] * 127); *normptr++ = (char)(avertexnormals[vertex->lightNormalIndex][2] * 127); + *normptr++ = (char)(avertexnormals[vertex->lightNormalIndex][1] * 127); } } // This doesn't need to be done every frame! - trisPtr = tris; - indexptr = retModel->meshes[0].indices; - uvptr = (float*)retModel->meshes[0].uvs; + md2triangle_t *trisPtr = tris; + unsigned short *indexptr = retModel->meshes[0].indices; + float *uvptr = (float*)retModel->meshes[0].uvs; for (j = 0; j < header->numTris; j++, trisPtr++) { *indexptr = trisPtr->meshIndex[0]; @@ -453,15 +434,12 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) } else // Full float loading method { - md2triangle_t *trisPtr = tris; - float *uvptr; - char *ptr = (char*)frames; - - retModel->meshes[0].numVertices = header->numTris*3; + retModel->meshes[0].numVertices = header->numTris * 3; retModel->meshes[0].frames = (mdlframe_t*)Z_Calloc(sizeof(mdlframe_t)*header->numFrames, ztag, 0); - retModel->meshes[0].uvs = (float*)Z_Malloc(sizeof(float)*2*retModel->meshes[0].numVertices, ztag, 0); - uvptr = retModel->meshes[0].uvs; + retModel->meshes[0].uvs = (float*)Z_Malloc(sizeof(float) * 2 * retModel->meshes[0].numVertices, ztag, 0); + md2triangle_t *trisPtr = tris; + float *uvptr = retModel->meshes[0].uvs; for (i = 0; i < retModel->meshes[0].numTriangles; i++, trisPtr++) { *uvptr++ = texcoords[trisPtr->stIndex[0]].s / (float)header->skinwidth; @@ -472,16 +450,15 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) *uvptr++ = (texcoords[trisPtr->stIndex[2]].t / (float)header->skinheight); } + byte *ptr = (byte*)frames; for (i = 0; i < header->numFrames; i++, ptr += header->framesize) { - md2vertex_t *vertex; md2frame_t *framePtr = (md2frame_t*)ptr; + retModel->meshes[0].frames[i].normals = (float*)Z_Malloc(sizeof(float) * 3 * header->numTris * 3, ztag, 0); + retModel->meshes[0].frames[i].vertices = (float*)Z_Malloc(sizeof(float) * 3 * header->numTris * 3, ztag, 0); + // if (retModel->materials[0].lightmap) + // retModel->meshes[0].frames[i].tangents = (float*)malloc(sizeof(float));//(float*)Z_Malloc(sizeof(float)*3*header->numTris*3, ztag); float *vertptr, *normptr; - retModel->meshes[0].frames[i].normals = (float*)Z_Malloc(sizeof(float)*3*header->numTris*3, ztag, 0); - retModel->meshes[0].frames[i].vertices = (float*)Z_Malloc(sizeof(float)*3*header->numTris*3, ztag, 0); -// if (retModel->materials[0].lightmap) -// retModel->meshes[0].frames[i].tangents = (float*)malloc(sizeof(float));//(float*)Z_Malloc(sizeof(float)*3*header->numTris*3, ztag); - normptr = (float*)retModel->meshes[0].frames[i].normals; vertptr = (float*)retModel->meshes[0].frames[i].vertices; trisPtr = tris; @@ -489,7 +466,7 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) retModel->meshes[0].frames[i].material = &retModel->materials[0]; framePtr++; // Advance to vertex list - vertex = (md2vertex_t*)framePtr; + md2vertex_t *vertex = (md2vertex_t*)framePtr; framePtr--; for (j = 0; j < header->numTris; j++, trisPtr++) { @@ -515,26 +492,17 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) vertptr++; *normptr++ = avertexnormals[vertex[trisPtr->meshIndex[0]].lightNormalIndex][0]; - *normptr++ = avertexnormals[vertex[trisPtr->meshIndex[0]].lightNormalIndex][1]; *normptr++ = avertexnormals[vertex[trisPtr->meshIndex[0]].lightNormalIndex][2]; + *normptr++ = avertexnormals[vertex[trisPtr->meshIndex[0]].lightNormalIndex][1]; *normptr++ = avertexnormals[vertex[trisPtr->meshIndex[1]].lightNormalIndex][0]; - *normptr++ = avertexnormals[vertex[trisPtr->meshIndex[1]].lightNormalIndex][1]; *normptr++ = avertexnormals[vertex[trisPtr->meshIndex[1]].lightNormalIndex][2]; + *normptr++ = avertexnormals[vertex[trisPtr->meshIndex[1]].lightNormalIndex][1]; *normptr++ = avertexnormals[vertex[trisPtr->meshIndex[2]].lightNormalIndex][0]; - *normptr++ = avertexnormals[vertex[trisPtr->meshIndex[2]].lightNormalIndex][1]; *normptr++ = avertexnormals[vertex[trisPtr->meshIndex[2]].lightNormalIndex][2]; + *normptr++ = avertexnormals[vertex[trisPtr->meshIndex[2]].lightNormalIndex][1]; } - /* - // Rotate MD2 by 90 degrees in code BLAAHH - vector_t *normVecptr = (vector_t*)retModel->meshes[0].frames[i].normals; - vector_t *vertVecptr = (vector_t*)retModel->meshes[0].frames[i].vertices; - for (j = 0; j < header->numTris * 3; j++, normVecptr++, vertVecptr++) - { - VectorRotate(normVecptr, &vectorYaxis, -90.0f); - VectorRotate(vertVecptr, &vectorYaxis, -90.0f); - }*/ } } diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index fec8c33a3..4f77680d9 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -29,11 +29,6 @@ #include #include -#ifndef SHUFFLE -#ifndef KOS_GL_COMPATIBILITY -#define SHUFFLE -#endif -#endif #include "r_opengl.h" #if defined (HWRENDER) && !defined (NOROPENGL) @@ -83,9 +78,7 @@ GLint screen_height = 0; GLbyte screen_depth = 0; GLint textureformatGL = 0; GLint maximumAnisotropy = 0; -#ifndef KOS_GL_COMPATIBILITY static GLboolean MipMap = GL_FALSE; -#endif static GLint min_filter = GL_LINEAR; static GLint mag_filter = GL_LINEAR; static GLint anisotropic_filter = 0; @@ -94,11 +87,9 @@ static FTransform md2_transform; const GLubyte *gl_extensions = NULL; //Hurdler: 04/10/2000: added for the kick ass coronas as Boris wanted;-) -#ifndef MINI_GL_COMPATIBILITY static GLdouble modelMatrix[16]; static GLdouble projMatrix[16]; static GLint viewport[4]; -#endif #ifdef USE_PALETTED_TEXTURE @@ -167,11 +158,6 @@ float byteasfloat(UINT8 fbyte) static I_Error_t I_Error_GL = NULL; -#ifndef MINI_GL_COMPATIBILITY -static boolean gl13 = false; // whether we can use opengl 1.3 functions -#endif - - // -----------------+ // DBG_Printf : Output error messages to debug log if DEBUG_TO_FILE is defined, // : else do nothing @@ -207,14 +193,10 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...) #define pglScissor glScissor #define pglEnable glEnable #define pglDisable glDisable -#ifndef MINI_GL_COMPATIBILITY #define pglGetDoublev glGetDoublev -#endif //glGetIntegerv //glGetString -#ifdef KOS_GL_COMPATIBILITY #define pglHint glHint -#endif /* Depth Buffer */ #define pglClearDepth glClearDepth @@ -228,11 +210,8 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...) #define pglPushMatrix glPushMatrix #define pglPopMatrix glPopMatrix #define pglLoadIdentity glLoadIdentity -#ifdef MINI_GL_COMPATIBILITY #define pglMultMatrixf glMultMatrixf -#else #define pglMultMatrixd glMultMatrixd -#endif #define pglRotatef glRotatef #define pglScalef glScalef #define pglTranslatef glTranslatef @@ -241,6 +220,7 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...) #define pglBegin glBegin #define pglEnd glEnd #define pglVertex3f glVertex3f +#define pglVertex3fv glVertex3fv #define pglVertex3sv glVertex3sv #define pglNormal3f glNormal3f #define pglNormal3bv glNormal3bv @@ -254,7 +234,8 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...) #define pglDrawArrays glDrawArrays #define pglDrawElements glDrawElements #define pglEnableClientState glEnableClientState -#define pglDisableClientState pglDisableClientState +#define pglDisableClientState glDisableClientState +#define pglClientActiveTexture glClientActiveTexture /* Lighting */ #define pglShadeModel glShadeModel @@ -280,10 +261,8 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...) #define pglDeleteTextures glDeleteTextures #define pglBindTexture glBindTexture /* texture mapping */ //GL_EXT_copy_texture -#ifndef KOS_GL_COMPATIBILITY #define pglCopyTexImage2D glCopyTexImage2D #define pglCopyTexSubImage2D glCopyTexSubImage2D -#endif #else //!STATIC_OPENGL @@ -310,10 +289,8 @@ typedef void (APIENTRY * PFNglEnable) (GLenum cap); static PFNglEnable pglEnable; typedef void (APIENTRY * PFNglDisable) (GLenum cap); static PFNglDisable pglDisable; -#ifndef MINI_GL_COMPATIBILITY typedef void (APIENTRY * PFNglGetDoublev) (GLenum pname, GLdouble *params); static PFNglGetDoublev pglGetDoublev; -#endif //glGetIntegerv //glGetString @@ -338,13 +315,10 @@ typedef void (APIENTRY * PFNglPopMatrix) (void); static PFNglPopMatrix pglPopMatrix; typedef void (APIENTRY * PFNglLoadIdentity) (void); static PFNglLoadIdentity pglLoadIdentity; -#ifdef MINI_GL_COMPATIBILITY typedef void (APIENTRY * PFNglMultMatrixf) (const GLfloat *m); static PFNglMultMatrixf pglMultMatrixf; -#else typedef void (APIENTRY * PFNglMultMatrixd) (const GLdouble *m); static PFNglMultMatrixd pglMultMatrixd; -#endif typedef void (APIENTRY * PFNglRotatef) (GLfloat angle, GLfloat x, GLfloat y, GLfloat z); static PFNglRotatef pglRotatef; typedef void (APIENTRY * PFNglScalef) (GLfloat x, GLfloat y, GLfloat z); @@ -359,6 +333,8 @@ typedef void (APIENTRY * PFNglEnd) (void); static PFNglEnd pglEnd; typedef void (APIENTRY * PFNglVertex3f) (GLfloat x, GLfloat y, GLfloat z); static PFNglVertex3f pglVertex3f; +typedef void (APIENTRY * PFNglVertex3fv)(const GLfloat *v); +static PFNglVertex3fv pglVertex3fv; typedef void (APIENTRY * PFNglVertex3sv) (const GLshort *v); static PFNglVertex3sv pglVertex3sv; typedef void (APIENTRY * PFNglNormal3f) (GLfloat x, GLfloat y, GLfloat z); @@ -434,15 +410,16 @@ static PFNglCopyTexSubImage2D pglCopyTexSubImage2D; typedef GLint (APIENTRY * PFNgluBuild2DMipmaps) (GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *data); static PFNgluBuild2DMipmaps pgluBuild2DMipmaps; -#ifndef MINI_GL_COMPATIBILITY /* 1.3 functions for multitexturing */ typedef void (APIENTRY *PFNglActiveTexture) (GLenum); static PFNglActiveTexture pglActiveTexture; typedef void (APIENTRY *PFNglMultiTexCoord2f) (GLenum, GLfloat, GLfloat); static PFNglMultiTexCoord2f pglMultiTexCoord2f; -#endif +typedef void (APIENTRY *PFNglMultiTexCoord2fv) (GLenum target, const GLfloat *v); +static PFNglMultiTexCoord2fv pglMultiTexCoord2fv; +typedef void (APIENTRY *PFNglClientActiveTexture) (GLenum); +static PFNglClientActiveTexture pglClientActiveTexture; -#ifndef MINI_GL_COMPATIBILITY /* 1.2 Parms */ /* GL_CLAMP_TO_EDGE_EXT */ #ifndef GL_CLAMP_TO_EDGE @@ -463,14 +440,6 @@ static PFNglMultiTexCoord2f pglMultiTexCoord2f; #define GL_TEXTURE1 0x84C1 #endif -#endif - -#ifdef MINI_GL_COMPATIBILITY -#undef GL_CLAMP_TO_EDGE -#undef GL_TEXTURE_MIN_LOD -#undef GL_TEXTURE_MAX_LOD -#endif - boolean SetupGLfunc(void) { #ifndef STATIC_OPENGL @@ -493,9 +462,7 @@ boolean SetupGLfunc(void) GETOPENGLFUNC(pglScissor , glScissor) GETOPENGLFUNC(pglEnable , glEnable) GETOPENGLFUNC(pglDisable , glDisable) -#ifndef MINI_GL_COMPATIBILITY GETOPENGLFUNC(pglGetDoublev , glGetDoublev) -#endif GETOPENGLFUNC(pglGetIntegerv , glGetIntegerv) GETOPENGLFUNC(pglGetString , glGetString) @@ -509,11 +476,8 @@ boolean SetupGLfunc(void) GETOPENGLFUNC(pglPushMatrix , glPushMatrix) GETOPENGLFUNC(pglPopMatrix , glPopMatrix) GETOPENGLFUNC(pglLoadIdentity , glLoadIdentity) -#ifdef MINI_GL_COMPATIBILITY GETOPENGLFUNC(pglMultMatrixf , glMultMatrixf) -#else GETOPENGLFUNC(pglMultMatrixd , glMultMatrixd) -#endif GETOPENGLFUNC(pglRotatef , glRotatef) GETOPENGLFUNC(pglScalef , glScalef) GETOPENGLFUNC(pglTranslatef , glTranslatef) @@ -521,6 +485,7 @@ boolean SetupGLfunc(void) GETOPENGLFUNC(pglBegin , glBegin) GETOPENGLFUNC(pglEnd , glEnd) GETOPENGLFUNC(pglVertex3f , glVertex3f) + GETOPENGLFUNC(pglVertex3fv, glVertex3fv) GETOPENGLFUNC(pglVertex3sv, glVertex3sv) GETOPENGLFUNC(pglNormal3f , glNormal3f) GETOPENGLFUNC(pglNormal3bv, glNormal3bv) @@ -535,6 +500,9 @@ boolean SetupGLfunc(void) GETOPENGLFUNC(pglDrawElements, glDrawElements) GETOPENGLFUNC(pglEnableClientState, glEnableClientState) GETOPENGLFUNC(pglDisableClientState, glDisableClientState) + GETOPENGLFUNC(pglClientActiveTexture, glClientActiveTexture) + if (!pglClientActiveTexture) + GETOPENGLFUNC(pglClientActiveTexture, glClientActiveTextureARB) GETOPENGLFUNC(pglShadeModel , glShadeModel) GETOPENGLFUNC(pglLightfv, glLightfv) @@ -566,47 +534,15 @@ boolean SetupGLfunc(void) } // This has to be done after the context is created so the version number can be obtained +// This is stupid -- even some of the oldest usable OpenGL hardware today supports 1.3-level featureset. boolean SetupGLFunc13(void) { -#ifdef MINI_GL_COMPATIBILITY - return false; -#else - const GLubyte *version = pglGetString(GL_VERSION); - int glmajor, glminor; - - gl13 = false; - // Parse the GL version - if (version != NULL) - { - if (sscanf((const char*)version, "%d.%d", &glmajor, &glminor) == 2) - { - // Look, we gotta prepare for the inevitable arrival of GL 2.0 code... - if (glmajor == 1 && glminor >= 3) - gl13 = true; - else if (glmajor > 1) - gl13 = true; - } - } - - if (gl13) - { - pglActiveTexture = GetGLFunc("glActiveTexture"); - pglMultiTexCoord2f = GetGLFunc("glMultiTexCoord2f"); - } - else if (isExtAvailable("GL_ARB_multitexture", gl_extensions)) - { - // Get the functions - pglActiveTexture = GetGLFunc("glActiveTextureARB"); - pglMultiTexCoord2f = GetGLFunc("glMultiTexCoord2fARB"); - - gl13 = true; // This is now true, so the new fade mask stuff can be done, if OpenGL version is less than 1.3, it still uses the old fade stuff. - DBG_Printf("GL_ARB_multitexture support: enabled\n"); - - } - else - DBG_Printf("GL_ARB_multitexture support: disabled\n"); + pglActiveTexture = GetGLFunc("glActiveTexture"); + pglMultiTexCoord2f = GetGLFunc("glMultiTexCoord2f"); + pglClientActiveTexture = GetGLFunc("glClientActiveTexture"); + pglMultiTexCoord2fv = GetGLFunc("glMultiTexCoord2fv"); + return true; -#endif } // -----------------+ @@ -624,11 +560,7 @@ static void SetNoTexture(void) static void GLPerspective(GLdouble fovy, GLdouble aspect) { -#ifdef MINI_GL_COMPATIBILITY - GLfloat m[4][4] = -#else GLdouble m[4][4] = -#endif { { 1.0f, 0.0f, 0.0f, 0.0f}, { 0.0f, 1.0f, 0.0f, 0.0f}, @@ -651,14 +583,10 @@ static void GLPerspective(GLdouble fovy, GLdouble aspect) m[1][1] = cotangent; m[2][2] = -(zFar + zNear) / deltaZ; m[3][2] = -2.0f * zNear * zFar / deltaZ; -#ifdef MINI_GL_COMPATIBILITY - pglMultMatrixf(&m[0][0]); -#else + pglMultMatrixd(&m[0][0]); -#endif } -#ifndef MINI_GL_COMPATIBILITY static void GLProject(GLdouble objX, GLdouble objY, GLdouble objZ, GLdouble* winX, GLdouble* winY, GLdouble* winZ) { @@ -698,7 +626,6 @@ static void GLProject(GLdouble objX, GLdouble objY, GLdouble objZ, *winY=in[1]; *winZ=in[2]; } -#endif // -----------------+ // SetModelView : @@ -729,10 +656,8 @@ void SetModelView(GLint w, GLint h) //pglScalef(1.0f, 320.0f/200.0f, 1.0f); // gr_scalefrustum (ORIGINAL_ASPECT) // added for new coronas' code (without depth buffer) -#ifndef MINI_GL_COMPATIBILITY pglGetIntegerv(GL_VIEWPORT, viewport); pglGetDoublev(GL_PROJECTION_MATRIX, projMatrix); -#endif } @@ -757,17 +682,15 @@ void SetStates(void) //pglShadeModel(GL_FLAT); pglEnable(GL_TEXTURE_2D); // two-dimensional texturing -#ifndef KOS_GL_COMPATIBILITY + pglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); pglAlphaFunc(GL_NOTEQUAL, 0.0f); -#endif + //pglBlendFunc(GL_ONE, GL_ZERO); // copy pixel to frame buffer (opaque) pglEnable(GL_BLEND); // enable color blending -#ifndef KOS_GL_COMPATIBILITY pglColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); -#endif //pglDisable(GL_DITHER); // faB: ??? (undocumented in OpenGL 1.1) // Hurdler: yes, it is! @@ -792,9 +715,7 @@ void SetStates(void) //tex_downloaded = NOTEXTURE_NUM; //pglTexImage2D(GL_TEXTURE_2D, 0, 4, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, Data); -#ifndef KOS_GL_COMPATIBILITY pglPolygonOffset(-1.0f, -1.0f); -#endif //pglEnable(GL_CULL_FACE); //pglCullFace(GL_FRONT); @@ -815,9 +736,7 @@ void SetStates(void) // bp : when no t&l :) pglLoadIdentity(); pglScalef(1.0f, 1.0f, -1.0f); -#ifndef MINI_GL_COMPATIBILITY pglGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix); // added for new coronas' code (without depth buffer) -#endif } @@ -921,14 +840,6 @@ EXPORT void HWRAPI(ClearMipMapCache) (void) EXPORT void HWRAPI(ReadRect) (INT32 x, INT32 y, INT32 width, INT32 height, INT32 dst_stride, UINT16 * dst_data) { -#ifdef KOS_GL_COMPATIBILITY - (void)x; - (void)y; - (void)width; - (void)height; - (void)dst_stride; - (void)dst_data; -#else INT32 i; // DBG_Printf ("ReadRect()\n"); if (dst_stride == width*3) @@ -970,7 +881,6 @@ EXPORT void HWRAPI(ReadRect) (INT32 x, INT32 y, INT32 width, INT32 height, } free(image); } -#endif } @@ -991,10 +901,8 @@ EXPORT void HWRAPI(GClipRect) (INT32 minx, INT32 miny, INT32 maxx, INT32 maxy, f pglMatrixMode(GL_MODELVIEW); // added for new coronas' code (without depth buffer) -#ifndef MINI_GL_COMPATIBILITY pglGetIntegerv(GL_VIEWPORT, viewport); pglGetDoublev(GL_PROJECTION_MATRIX, projMatrix); -#endif } @@ -1041,12 +949,9 @@ EXPORT void HWRAPI(Draw2DLine) (F2DCoord * v1, GLRGBAFloat c; // DBG_Printf ("DrawLine() (%f %f %f) %d\n", v1->x, -v1->y, -v1->z, v1->argb); -#ifdef MINI_GL_COMPATIBILITY - GLfloat px1, px2, px3, px4; - GLfloat py1, py2, py3, py4; + GLfloat p[12]; GLfloat dx, dy; GLfloat angle; -#endif // BP: we should reflect the new state in our variable //SetBlend(PF_Modulated|PF_NoTexture); @@ -1058,33 +963,24 @@ EXPORT void HWRAPI(Draw2DLine) (F2DCoord * v1, c.blue = byte2float[Color.s.blue]; c.alpha = byte2float[Color.s.alpha]; -#ifndef MINI_GL_COMPATIBILITY - pglColor4fv(&c.red); // is in RGBA float format - pglBegin(GL_LINES); - pglVertex3f(v1->x, -v1->y, 1.0f); - pglVertex3f(v2->x, -v2->y, 1.0f); - pglEnd(); -#else + // This is the preferred, 'modern' way of rendering lines -- creating a polygon. if (v2->x != v1->x) angle = (float)atan((v2->y-v1->y)/(v2->x-v1->x)); else - angle = N_PI_DEMI; + angle = (float)N_PI_DEMI; dx = (float)sin(angle) / (float)screen_width; dy = (float)cos(angle) / (float)screen_height; - px1 = v1->x - dx; py1 = v1->y + dy; - px2 = v2->x - dx; py2 = v2->y + dy; - px3 = v2->x + dx; py3 = v2->y - dy; - px4 = v1->x + dx; py4 = v1->y - dy; + p[0] = v1->x - dx; p[1] = -(v1->y + dy); p[2] = 1; + p[3] = v2->x - dx; p[4] = -(v2->y + dy); p[5] = 1; + p[6] = v2->x + dx; p[7] = -(v2->y - dy); p[8] = 1; + p[9] = v1->x + dx; p[10] = -(v1->y - dy); p[11] = 1; - pglColor4f(c.red, c.green, c.blue, c.alpha); - pglBegin(GL_TRIANGLE_FAN); - pglVertex3f(px1, -py1, 1); - pglVertex3f(px2, -py2, 1); - pglVertex3f(px3, -py3, 1); - pglVertex3f(px4, -py4, 1); - pglEnd(); -#endif + pglColor4fv(&c.red); // is in RGBA float format + pglEnableClientState(GL_VERTEX_ARRAY); + pglVertexPointer(3, GL_FLOAT, 0, p); + pglDrawArrays(GL_TRIANGLE_FAN, 0, 4); + pglDisableClientState(GL_VERTEX_ARRAY); pglEnable(GL_TEXTURE_2D); } @@ -1114,60 +1010,42 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags) switch (PolyFlags & PF_Blending) { case PF_Translucent & PF_Blending: pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency -#ifndef KOS_GL_COMPATIBILITY pglAlphaFunc(GL_NOTEQUAL, 0.0f); -#endif break; case PF_Masked & PF_Blending: // Hurdler: does that mean lighting is only made by alpha src? // it sounds ok, but not for polygonsmooth pglBlendFunc(GL_SRC_ALPHA, GL_ZERO); // 0 alpha = holes in texture -#ifndef KOS_GL_COMPATIBILITY pglAlphaFunc(GL_GREATER, 0.5f); -#endif break; case PF_Additive & PF_Blending: -#ifdef ATI_RAGE_PRO_COMPATIBILITY - pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency -#else pglBlendFunc(GL_SRC_ALPHA, GL_ONE); // src * alpha + dest -#endif -#ifndef KOS_GL_COMPATIBILITY pglAlphaFunc(GL_NOTEQUAL, 0.0f); -#endif break; case PF_Environment & PF_Blending: pglBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); -#ifndef KOS_GL_COMPATIBILITY pglAlphaFunc(GL_NOTEQUAL, 0.0f); -#endif break; case PF_Substractive & PF_Blending: // good for shadow - // not realy but what else ? + // not really but what else ? pglBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR); -#ifndef KOS_GL_COMPATIBILITY pglAlphaFunc(GL_NOTEQUAL, 0.0f); -#endif break; case PF_Fog & PF_Fog: // Sryder: Fog // multiplies input colour by input alpha, and destination colour by input colour, then adds them pglBlendFunc(GL_SRC_ALPHA, GL_SRC_COLOR); -#ifndef KOS_GL_COMPATIBILITY pglAlphaFunc(GL_NOTEQUAL, 0.0f); -#endif break; default : // must be 0, otherwise it's an error // No blending pglBlendFunc(GL_ONE, GL_ZERO); // the same as no blending -#ifndef KOS_GL_COMPATIBILITY pglAlphaFunc(GL_GREATER, 0.5f); -#endif break; } } -#ifndef KOS_GL_COMPATIBILITY + if (Xor & PF_NoAlphaTest) { if (PolyFlags & PF_NoAlphaTest) @@ -1183,7 +1061,7 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags) else pglDisable(GL_POLYGON_OFFSET_FILL); } -#endif + if (Xor&PF_NoDepthTest) { if (PolyFlags & PF_NoDepthTest) @@ -1210,10 +1088,6 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags) pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); } -#ifdef KOS_GL_COMPATIBILITY - if (Xor&PF_Modulated && !(PolyFlags & PF_Modulated)) - pglColor4f(1.0f, 1.0f, 1.0f, 1.0f); -#else if (Xor&PF_Modulated) { #if defined (__unix__) || defined (UNIXCOMMON) @@ -1233,7 +1107,6 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags) pglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); } } -#endif if (Xor & PF_Occlude) // depth test but (no) depth write { @@ -1287,11 +1160,7 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo) else { // Download a mipmap -#ifdef KOS_GL_COMPATIBILITY - static GLushort tex[2048*2048]; -#else static RGBA_t tex[2048*2048]; -#endif const GLvoid *ptex = tex; INT32 w, h; @@ -1310,102 +1179,7 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo) } else #endif -#ifdef KOS_GL_COMPATIBILITY - if ((pTexInfo->grInfo.format == GR_TEXFMT_P_8) || - (pTexInfo->grInfo.format == GR_TEXFMT_AP_88)) - { - const GLubyte *pImgData = (const GLubyte *)pTexInfo->grInfo.data; - INT32 i, j; - for (j = 0; j < h; j++) - { - for (i = 0; i < w; i++) - { - if ((*pImgData == HWR_PATCHES_CHROMAKEY_COLORINDEX) && - (pTexInfo->flags & TF_CHROMAKEYED)) - { - tex[w*j+i] = 0; - } - else - { - if (pTexInfo->grInfo.format == GR_TEXFMT_AP_88 && !(pTexInfo->flags & TF_CHROMAKEYED)) - tex[w*j+i] = 0; - else - tex[w*j+i] = (myPaletteData[*pImgData].s.alpha>>4)<<12; - - tex[w*j+i] |= (myPaletteData[*pImgData].s.red >>4)<<8; - tex[w*j+i] |= (myPaletteData[*pImgData].s.green>>4)<<4; - tex[w*j+i] |= (myPaletteData[*pImgData].s.blue >>4); - } - - pImgData++; - - if (pTexInfo->grInfo.format == GR_TEXFMT_AP_88) - { - if (!(pTexInfo->flags & TF_CHROMAKEYED)) - tex[w*j+i] |= ((*pImgData)>>4)<<12; - pImgData++; - } - - } - } - } - else if (pTexInfo->grInfo.format == GR_RGBA) - { - // corona test : passed as ARGB 8888, which is not in glide formats - // Hurdler: not used for coronas anymore, just for dynamic lighting - const RGBA_t *pImgData = (const RGBA_t *)pTexInfo->grInfo.data; - INT32 i, j; - - for (j = 0; j < h; j++) - { - for (i = 0; i < w; i++) - { - tex[w*j+i] = (pImgData->s.alpha>>4)<<12; - tex[w*j+i] |= (pImgData->s.red >>4)<<8; - tex[w*j+i] |= (pImgData->s.green>>4)<<4; - tex[w*j+i] |= (pImgData->s.blue >>4); - pImgData++; - } - } - } - else if (pTexInfo->grInfo.format == GR_TEXFMT_ALPHA_INTENSITY_88) - { - const GLubyte *pImgData = (const GLubyte *)pTexInfo->grInfo.data; - INT32 i, j; - - for (j = 0; j < h; j++) - { - for (i = 0; i < w; i++) - { - const GLubyte sID = (*pImgData)>>4; - tex[w*j+i] = sID<<8 | sID<<4 | sID; - pImgData++; - tex[w*j+i] |= ((*pImgData)>>4)<<12; - pImgData++; - } - } - } - else if (pTexInfo->grInfo.format == GR_TEXFMT_ALPHA_8) // Used for fade masks - { - const GLubyte *pImgData = (const GLubyte *)pTexInfo->grInfo.data; - INT32 i, j; - - for (j = 0; j < h; j++) - { - for (i = 0; i < w; i++) - { - tex[w*j+i] = (pImgData>>4)<<12; - tex[w*j+i] |= (255>>4)<<8; - tex[w*j+i] |= (255>>4)<<4; - tex[w*j+i] |= (255>>4); - pImgData++; - } - } - } - else - DBG_Printf ("SetTexture(bad format) %ld\n", pTexInfo->grInfo.format); -#else if ((pTexInfo->grInfo.format == GR_TEXFMT_P_8) || (pTexInfo->grInfo.format == GR_TEXFMT_AP_88)) { @@ -1488,7 +1262,6 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo) } else DBG_Printf ("SetTexture(bad format) %ld\n", pTexInfo->grInfo.format); -#endif pTexInfo->downloaded = NextTexAvail++; tex_downloaded = pTexInfo->downloaded; @@ -1497,13 +1270,8 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo) // disable texture filtering on any texture that has holes so there's no dumb borders or blending issues if (pTexInfo->flags & TF_TRANSPARENT) { -#ifdef KOS_GL_COMPATIBILITY - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NONE); - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NONE); -#else pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); -#endif } else { @@ -1511,29 +1279,6 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo) pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter); } -#ifdef KOS_GL_COMPATIBILITY - pglTexImage2D(GL_TEXTURE_2D, 0, GL_ARGB4444, w, h, 0, GL_ARGB4444, GL_UNSIGNED_BYTE, ptex); -#else -#ifdef MINI_GL_COMPATIBILITY - //if (pTexInfo->grInfo.format == GR_TEXFMT_ALPHA_INTENSITY_88) - //pglTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); - //else - if (MipMap) - pgluBuild2DMipmaps(GL_TEXTURE_2D, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex); - else - pglTexImage2D(GL_TEXTURE_2D, 0, 4, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); -#else -#ifdef USE_PALETTED_TEXTURE - //Hurdler: not really supported and not tested recently - if (glColorTableEXT && - (pTexInfo->grInfo.format == GR_TEXFMT_P_8) && - !(pTexInfo->flags & TF_CHROMAKEYED)) - { - glColorTableEXT(GL_TEXTURE_2D, GL_RGB8, 256, GL_RGB, GL_UNSIGNED_BYTE, palette_tex); - pglTexImage2D(GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, w, h, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, pTexInfo->grInfo.data); - } - else -#endif if (pTexInfo->grInfo.format == GR_TEXFMT_ALPHA_INTENSITY_88) { //pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); @@ -1593,8 +1338,6 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo) else pglTexImage2D(GL_TEXTURE_2D, 0, textureformatGL, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); } -#endif -#endif if (pTexInfo->flags & TF_WRAPX) pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); @@ -1618,19 +1361,6 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo) else // initialisation de la liste gr_cachetail = gr_cachehead = pTexInfo; } -#ifdef MINI_GL_COMPATIBILITY - switch (pTexInfo->flags) - { - case 0 : - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - break; - default: - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - break; - } -#endif } @@ -1644,18 +1374,11 @@ EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FBITFIELD PolyFlags) { FUINT i; -#ifndef MINI_GL_COMPATIBILITY FUINT j; -#endif GLRGBAFloat c = {0,0,0,0}; -#ifdef MINI_GL_COMPATIBILITY - if (PolyFlags & PF_Corona) - PolyFlags &= ~PF_NoDepthTest; -#else if ((PolyFlags & PF_Corona) && (oglflags & GLF_NOZBUFREAD)) PolyFlags &= ~(PF_NoDepthTest|PF_Corona); -#endif SetBlend(PolyFlags); //TODO: inline (#pragma..) @@ -1677,16 +1400,11 @@ EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, c.alpha = byte2float[pSurf->FlatColor.s.alpha]; } -#ifdef MINI_GL_COMPATIBILITY - pglColor4f(c.red, c.green, c.blue, c.alpha); -#else pglColor4fv(&c.red); // is in RGBA float format -#endif } // this test is added for new coronas' code (without depth buffer) // I think I should do a separate function for drawing coronas, so it will be a little faster -#ifndef MINI_GL_COMPATIBILITY if (PolyFlags & PF_Corona) // check to see if we need to draw the corona { //rem: all 8 (or 8.0f) values are hard coded: it can be changed to a higher value @@ -1733,19 +1451,17 @@ EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, c.alpha *= scalef; // change the alpha value (it seems better than changing the size of the corona) pglColor4fv(&c.red); } -#endif + if (PolyFlags & PF_MD2) return; - pglBegin(GL_TRIANGLE_FAN); - for (i = 0; i < iNumPts; i++) - { - pglTexCoord2f(pOutVerts[i].sow, pOutVerts[i].tow); - //Hurdler: test code: -pOutVerts[i].z => pOutVerts[i].z - pglVertex3f(pOutVerts[i].x, pOutVerts[i].y, pOutVerts[i].z); - //pglVertex3f(pOutVerts[i].x, pOutVerts[i].y, -pOutVerts[i].z); - } - pglEnd(); + pglEnableClientState(GL_VERTEX_ARRAY); + pglEnableClientState(GL_TEXTURE_COORD_ARRAY); + pglVertexPointer(3, GL_FLOAT, sizeof(FOutVector), &pOutVerts[0].x); + pglTexCoordPointer(2, GL_FLOAT, sizeof(FOutVector), &pOutVerts[0].sow); + pglDrawArrays(GL_TRIANGLE_FAN, 0, iNumPts); + pglDisableClientState(GL_TEXTURE_COORD_ARRAY); + pglDisableClientState(GL_VERTEX_ARRAY); if (PolyFlags & PF_RemoveYWrap) pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); @@ -1827,41 +1543,15 @@ EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value) break; case HWD_SET_POLYGON_SMOOTH: -#ifdef KOS_GL_COMPATIBILITY // GL_POLYGON_SMOOTH_HINT - if (Value) - pglHint(GL_POLYGON_SMOOTH_HINT,GL_NICEST); - else - pglHint(GL_POLYGON_SMOOTH_HINT,GL_FASTEST); -#else if (Value) pglEnable(GL_POLYGON_SMOOTH); else pglDisable(GL_POLYGON_SMOOTH); -#endif break; case HWD_SET_TEXTUREFILTERMODE: switch (Value) { -#ifdef KOS_GL_COMPATIBILITY - case HWD_SET_TEXTUREFILTER_TRILINEAR: - case HWD_SET_TEXTUREFILTER_BILINEAR: - min_filter = mag_filter = GL_FILTER_BILINEAR; - break; - case HWD_SET_TEXTUREFILTER_POINTSAMPLED: - min_filter = mag_filter = GL_FILTER_NONE; - case HWD_SET_TEXTUREFILTER_MIXED1: - min_filter = GL_FILTER_NONE; - mag_filter = GL_LINEAR; - case HWD_SET_TEXTUREFILTER_MIXED2: - min_filter = GL_LINEAR; - mag_filter = GL_FILTER_NONE; - break; - case HWD_SET_TEXTUREFILTER_MIXED3: - min_filter = GL_FILTER_BILINEAR; - mag_filter = GL_FILTER_NONE; - break; -#elif !defined (MINI_GL_COMPATIBILITY) case HWD_SET_TEXTUREFILTER_TRILINEAR: min_filter = GL_LINEAR_MIPMAP_LINEAR; mag_filter = GL_LINEAR; @@ -1890,14 +1580,9 @@ EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value) mag_filter = GL_NEAREST; MipMap = GL_TRUE; break; -#endif default: -#ifdef KOS_GL_COMPATIBILITY - min_filter = mag_filter = GL_FILTER_NONE; -#else mag_filter = GL_LINEAR; min_filter = GL_NEAREST; -#endif } if (!pgluBuild2DMipmaps) { @@ -1918,26 +1603,64 @@ EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value) } } +static float *vertBuffer = NULL; +static float *normBuffer = NULL; +static size_t lerpBufferSize = 0; +static short *vertTinyBuffer = NULL; +static char *normTinyBuffer = NULL; +static size_t lerpTinyBufferSize = 0; + +// Static temporary buffer for doing frame interpolation +// 'size' is the vertex size +static void AllocLerpBuffer(size_t size) +{ + if (lerpBufferSize >= size) + return; + + if (vertBuffer != NULL) + free(vertBuffer); + + if (normBuffer != NULL) + free(normBuffer); + + lerpBufferSize = size; + vertBuffer = malloc(lerpBufferSize); + normBuffer = malloc(lerpBufferSize); +} + +// Static temporary buffer for doing frame interpolation +// 'size' is the vertex size +static void AllocLerpTinyBuffer(size_t size) +{ + if (lerpTinyBufferSize >= size) + return; + + if (vertTinyBuffer != NULL) + free(vertTinyBuffer); + + if (normTinyBuffer != NULL) + free(normTinyBuffer); + + lerpTinyBufferSize = size; + vertTinyBuffer = malloc(lerpTinyBufferSize); + normTinyBuffer = malloc(lerpTinyBufferSize / 2); +} + static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 *color) { GLfloat ambient[4]; GLfloat diffuse[4]; float pol = 0.0f; - - float scalex, scaley, scalez; + scale *= 0.5f; + float scalex = scale, scaley = scale, scalez = scale; boolean useTinyFrames; int i; // Because Otherwise, scaling the screen negatively vertically breaks the lighting -#ifndef KOS_GL_COMPATIBILITY GLfloat LightPos[] = {0.0f, 1.0f, 0.0f, 0.0f}; -#endif - - scale *= 0.5f; - scalex = scaley = scalez = scale; if (duration != 0 && duration != -1 && tics != -1) // don't interpolate if instantaneous or infinite in length { @@ -1997,9 +1720,7 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 } #endif -#ifndef KOS_GL_COMPATIBILITY pglLightfv(GL_LIGHT0, GL_POSITION, LightPos); -#endif pglShadeModel(GL_SMOOTH); if (color) @@ -2033,6 +1754,10 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 if (useTinyFrames) pglScalef(1 / 64.0f, 1 / 64.0f, 1 / 64.0f); + pglEnableClientState(GL_VERTEX_ARRAY); + pglEnableClientState(GL_TEXTURE_COORD_ARRAY); + pglEnableClientState(GL_NORMAL_ARRAY); + for (i = 0; i < model->numMeshes; i++) { mesh_t *mesh = &model->meshes[i]; @@ -2047,46 +1772,30 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 if (!nextframe || pol == 0.0f) { - pglEnableClientState(GL_VERTEX_ARRAY); - pglEnableClientState(GL_TEXTURE_COORD_ARRAY); - pglEnableClientState(GL_NORMAL_ARRAY); pglVertexPointer(3, GL_SHORT, 0, frame->vertices); pglNormalPointer(GL_BYTE, 0, frame->normals); pglTexCoordPointer(2, GL_FLOAT, 0, mesh->uvs); pglDrawElements(GL_TRIANGLES, mesh->numTriangles * 3, GL_UNSIGNED_SHORT, mesh->indices); - pglDisableClientState(GL_NORMAL_ARRAY); - pglDisableClientState(GL_TEXTURE_COORD_ARRAY); - pglDisableClientState(GL_VERTEX_ARRAY); } else { // Dangit, I soooo want to do this in a GLSL shader... - short *buffer = malloc(mesh->numVertices * sizeof(short) * 3); - short *vertPtr = buffer; - char *normBuffer = malloc(mesh->numVertices * sizeof(char) * 3); - char *normPtr = normBuffer; + AllocLerpTinyBuffer(mesh->numVertices * sizeof(short) * 3); + short *vertPtr = vertTinyBuffer; + char *normPtr = normTinyBuffer; int j = 0; - for (j = 0; j < mesh->numVertices; j++) + for (j = 0; j < mesh->numVertices * 3; j++) { // Interpolate *vertPtr++ = (short)(frame->vertices[j] + (pol * (nextframe->vertices[j] - frame->vertices[j]))); *normPtr++ = (char)(frame->normals[j] + (pol * (nextframe->normals[j] - frame->normals[j]))); } - pglEnableClientState(GL_VERTEX_ARRAY); - pglEnableClientState(GL_TEXTURE_COORD_ARRAY); - pglEnableClientState(GL_NORMAL_ARRAY); - pglVertexPointer(3, GL_SHORT, 0, buffer); - pglNormalPointer(GL_BYTE, 0, normBuffer); + pglVertexPointer(3, GL_SHORT, 0, vertTinyBuffer); + pglNormalPointer(GL_BYTE, 0, normTinyBuffer); pglTexCoordPointer(2, GL_FLOAT, 0, mesh->uvs); pglDrawElements(GL_TRIANGLES, mesh->numTriangles * 3, GL_UNSIGNED_SHORT, mesh->indices); - pglDisableClientState(GL_NORMAL_ARRAY); - pglDisableClientState(GL_TEXTURE_COORD_ARRAY); - pglDisableClientState(GL_VERTEX_ARRAY); - - free(buffer); - free(normBuffer); } } else @@ -2100,61 +1809,38 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 if (!nextframe || pol == 0.0f) { // Zoom! Take advantage of just shoving the entire arrays to the GPU. - pglEnableClientState(GL_VERTEX_ARRAY); - pglEnableClientState(GL_TEXTURE_COORD_ARRAY); - pglEnableClientState(GL_NORMAL_ARRAY); pglVertexPointer(3, GL_FLOAT, 0, frame->vertices); pglNormalPointer(GL_FLOAT, 0, frame->normals); pglTexCoordPointer(2, GL_FLOAT, 0, mesh->uvs); pglDrawArrays(GL_TRIANGLES, 0, mesh->numTriangles * 3); - pglDisableClientState(GL_NORMAL_ARRAY); - pglDisableClientState(GL_TEXTURE_COORD_ARRAY); - pglDisableClientState(GL_VERTEX_ARRAY); } else { - int j = 0; - float *uvPtr = mesh->uvs; - float *frameVert = frame->vertices; - float *frameNormal = frame->normals; - float *nextFrameVert = nextframe->vertices; - float *nextFrameNormal = nextframe->normals; - // Dangit, I soooo want to do this in a GLSL shader... - pglBegin(GL_TRIANGLES); + AllocLerpBuffer(mesh->numVertices * sizeof(float) * 3); + float *vertPtr = vertBuffer; + float *normPtr = normBuffer; + int j = 0; - for (j = 0; j < mesh->numTriangles * 3; j++) + for (j = 0; j < mesh->numVertices * 3; j++) { // Interpolate - float px1 = *frameVert++; - float py1 = *frameVert++; - float pz1 = *frameVert++; - float px2 = *nextFrameVert++; - float py2 = *nextFrameVert++; - float pz2 = *nextFrameVert++; - float nx1 = *frameNormal++; - float ny1 = *frameNormal++; - float nz1 = *frameNormal++; - float nx2 = *nextFrameNormal++; - float ny2 = *nextFrameNormal++; - float nz2 = *nextFrameNormal++; - - pglTexCoord2fv(uvPtr); - pglNormal3f((nx1 + pol * (nx2 - nx1)), - (ny1 + pol * (ny2 - ny1)), - (nz1 + pol * (nz2 - nz1))); - pglVertex3f((px1 + pol * (px2 - px1)), - (py1 + pol * (py2 - py1)), - (pz1 + pol * (pz2 - pz1))); - - uvPtr += 2; + *vertPtr++ = frame->vertices[j] + (pol * (nextframe->vertices[j] - frame->vertices[j])); + *normPtr++ = frame->normals[j] + (pol * (nextframe->normals[j] - frame->normals[j])); } - pglEnd(); + pglVertexPointer(3, GL_FLOAT, 0, vertBuffer); + pglNormalPointer(GL_FLOAT, 0, normBuffer); + pglTexCoordPointer(2, GL_FLOAT, 0, mesh->uvs); + pglDrawArrays(GL_TRIANGLES, 0, mesh->numVertices); } } } + pglDisableClientState(GL_NORMAL_ARRAY); + pglDisableClientState(GL_TEXTURE_COORD_ARRAY); + pglDisableClientState(GL_VERTEX_ARRAY); + pglPopMatrix(); // should be the same as glLoadIdentity if (color) pglDisable(GL_LIGHTING); @@ -2204,9 +1890,7 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform) GLPerspective(53.13l, 2*ASPECT_RATIO); // 53.13 = 2*atan(0.5) else GLPerspective(stransform->fovxangle, ASPECT_RATIO); -#ifndef MINI_GL_COMPATIBILITY pglGetDoublev(GL_PROJECTION_MATRIX, projMatrix); // added for new coronas' code (without depth buffer) -#endif pglMatrixMode(GL_MODELVIEW); } else @@ -2220,15 +1904,11 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform) else //Hurdler: is "fov" correct? GLPerspective(fov, ASPECT_RATIO); -#ifndef MINI_GL_COMPATIBILITY pglGetDoublev(GL_PROJECTION_MATRIX, projMatrix); // added for new coronas' code (without depth buffer) -#endif pglMatrixMode(GL_MODELVIEW); } -#ifndef MINI_GL_COMPATIBILITY pglGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix); // added for new coronas' code (without depth buffer) -#endif } EXPORT INT32 HWRAPI(GetTextureUsed) (void) @@ -2249,7 +1929,6 @@ EXPORT INT32 HWRAPI(GetRenderVersion) (void) return VERSION; } -#ifdef SHUFFLE EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]) { INT32 x, y; @@ -2269,16 +1948,25 @@ EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]) pglDisable(GL_DEPTH_TEST); pglDisable(GL_BLEND); - pglBegin(GL_QUADS); + + const float blackBack[16] = + { + -16.0f, -16.0f, 6.0f, + -16.0f, 16.0f, 6.0f, + 16.0f, 16.0f, 6.0f, + 16.0f, -16.0f, 6.0f + }; + + pglEnableClientState(GL_VERTEX_ARRAY); // Draw a black square behind the screen texture, // so nothing shows through the edges pglColor4f(1.0f, 1.0f, 1.0f, 1.0f); - pglVertex3f(-16.0f, -16.0f, 6.0f); - pglVertex3f(-16.0f, 16.0f, 6.0f); - pglVertex3f(16.0f, 16.0f, 6.0f); - pglVertex3f(16.0f, -16.0f, 6.0f); + + pglVertexPointer(3, GL_FLOAT, 0, blackBack); + pglDrawArrays(GL_TRIANGLE_FAN, 0, 4); + pglEnableClientState(GL_TEXTURE_COORD_ARRAY); for(x=0;x #include -#ifndef MINI_GL_COMPATIBILITY #ifdef STATIC_OPENGL // Because of the 1.3 functions, you'll need GLext to compile it if static #define GL_GLEXT_PROTOTYPES #include #endif #endif -#endif #define _CREATE_DLL_ // necessary for Unix AND Windows #include "../../doomdef.h" diff --git a/src/sdl/hwsym_sdl.c b/src/sdl/hwsym_sdl.c index 7962e01b1..9f844c623 100644 --- a/src/sdl/hwsym_sdl.c +++ b/src/sdl/hwsym_sdl.c @@ -90,9 +90,7 @@ void *hwSym(const char *funcName,void *handle) GETFUNC(DrawModel); GETFUNC(SetTransform); GETFUNC(GetRenderVersion); -#ifdef SHUFFLE GETFUNC(PostImgRedraw); -#endif //SHUFFLE GETFUNC(FlushScreenTextures); GETFUNC(StartScreenWipe); GETFUNC(EndScreenWipe); diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 6ce11fc74..543499b09 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1486,9 +1486,7 @@ void I_StartupGraphics(void) HWD.pfnDrawModel = hwSym("DrawModel",NULL); HWD.pfnSetTransform = hwSym("SetTransform",NULL); HWD.pfnGetRenderVersion = hwSym("GetRenderVersion",NULL); -#ifdef SHUFFLE HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL); -#endif HWD.pfnFlushScreenTextures=hwSym("FlushScreenTextures",NULL); HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL); HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL); diff --git a/src/win32/Srb2win-vc10.vcxproj.filters b/src/win32/Srb2win-vc10.vcxproj.filters index 1a2a7f80d..8f6077969 100644 --- a/src/win32/Srb2win-vc10.vcxproj.filters +++ b/src/win32/Srb2win-vc10.vcxproj.filters @@ -108,21 +108,9 @@ Hw_Hardware - - Hw_Hardware - - - Hw_Hardware - - - Hw_Hardware - Hw_Hardware - - Hw_Hardware - Hw_Hardware @@ -465,6 +453,10 @@ M_Misc + + + + From b1756297480ad6c87fcd097cf11747582c473913 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Wed, 26 Dec 2018 23:15:28 -0500 Subject: [PATCH 21/74] Fix floating point comparisons --- src/hardware/hw_model.c | 4 +++- src/hardware/r_opengl/r_opengl.c | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/hardware/hw_model.c b/src/hardware/hw_model.c index 828339563..394b0f899 100644 --- a/src/hardware/hw_model.c +++ b/src/hardware/hw_model.c @@ -412,7 +412,9 @@ void GenerateVertexNormals(model_t *model) testY = *testPtr++; testZ = *testPtr++; - if (x != testX || y != testY || z != testZ) + if (fabsf(x - testX) > FLT_EPSILON + || fabsf(y - testY) > FLT_EPSILON + || fabsf(z - testZ) > FLT_EPSILON) continue; // Found a vertex match! Add it... diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index e50df8025..e8f2720ec 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -965,7 +965,7 @@ EXPORT void HWRAPI(Draw2DLine) (F2DCoord * v1, c.alpha = byte2float[Color.s.alpha]; // This is the preferred, 'modern' way of rendering lines -- creating a polygon. - if (v2->x != v1->x) + if (fabsf(v2->x - v1->x) > FLT_EPSILON) angle = (float)atan((v2->y-v1->y)/(v2->x-v1->x)); else angle = (float)N_PI_DEMI; @@ -1771,7 +1771,7 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 if (nextFrameIndex != -1) nextframe = &mesh->tinyframes[nextFrameIndex % mesh->numFrames]; - if (!nextframe || pol == 0.0f) + if (!nextframe || fpclassify(pol) == FP_ZERO) { pglVertexPointer(3, GL_SHORT, 0, frame->vertices); pglNormalPointer(GL_BYTE, 0, frame->normals); @@ -2154,6 +2154,8 @@ EXPORT void HWRAPI(DoScreenWipe)(float alpha) INT32 fademaskdownloaded = tex_downloaded; // the fade mask that has been set + (void)alpha; + // Use a power of two texture, dammit if(screen_width <= 1024) texsize = 1024; From 036e44aa21e240ce5d124b7525639cc4ab4ac71d Mon Sep 17 00:00:00 2001 From: mazmazz Date: Wed, 26 Dec 2018 23:31:55 -0500 Subject: [PATCH 22/74] Mixed D&C fixes --- src/hardware/hw_md2load.c | 99 ++++++++++++++++++++------- src/hardware/r_opengl/r_opengl.c | 112 ++++++++++++++++++++----------- 2 files changed, 144 insertions(+), 67 deletions(-) diff --git a/src/hardware/hw_md2load.c b/src/hardware/hw_md2load.c index d29414b0f..1d0e4f361 100644 --- a/src/hardware/hw_md2load.c +++ b/src/hardware/hw_md2load.c @@ -17,7 +17,7 @@ #define NUMVERTEXNORMALS 162 -// Quake 2 normals are indexed. Use avertexnormals[normalindex][x/y/z] and +// Quake 2 normals are indexed. Use avertexnormals[normalindex][x/y/z] and // you'll have your normals. float avertexnormals[NUMVERTEXNORMALS][3] = { {-0.525731f, 0.000000f, 0.850651f}, @@ -195,9 +195,9 @@ typedef struct int numXYZ; // Number of vertices in each frame int numST; // Number of texture coordinates in each frame. int numTris; // Number of triangles in each frame - int numGLcmds; // Number of dwords (4 bytes) in the gl command list. + int numGLcmds; // Number of dwords (4 bytes) in the gl command list. int numFrames; // Number of frames - int offsetSkins; // Offset, in bytes from the start of the file, to the list of skin names. + int offsetSkins; // Offset, in bytes from the start of the file, to the list of skin names. int offsetST; // Offset, in bytes from the start of the file, to the list of texture coordinates int offsetTris; // Offset, in bytes from the start of the file, to the list of triangles int offsetFrames; // Offset, in bytes from the start of the file, to the list of frames @@ -233,10 +233,36 @@ typedef struct // Load the model model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) { - useFloat = true; model_t *retModel = NULL; md2header_t *header; + size_t fileLen; + int i, j; + size_t namelen; + char *texturefilename; + const char *texPos; + + char *buffer; + + const float WUNITS = 1.0f; + float dataScale = WUNITS; + + int t; + + // MD2 currently does not work with tinyframes, so force useFloat = true + // + // + // the UV coordinates in MD2 are not compatible with glDrawElements like MD3 is. So they need to be loaded as full float. + // + // MD2 is intended to be draw in triangle strips and fans + // not very compatible with a modern GL implementation, either + // so the idea would be to full float expand it, and put it in a vertex buffer object + // I'm sure there's a way to convert the UVs to 'tinyframes', but maybe that's a job for someone else. + // You'd have to decompress the model, then recompress, reindexing the triangles and weeding out duplicate coordinates + // I already have the decompression work done + + useFloat = true; + FILE *f = fopen(fileName, "rb"); if (!f) @@ -244,13 +270,13 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) retModel = (model_t*)Z_Calloc(sizeof(model_t), ztag, 0); - size_t fileLen; + //size_t fileLen; - int i, j; + //int i, j; - size_t namelen; - char *texturefilename; - const char *texPos = strchr(fileName, '/'); + //size_t namelen; + //char *texturefilename; + texPos = strchr(fileName, '/'); if (texPos) { @@ -276,7 +302,7 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) fseek(f, 0, SEEK_SET); // read in file - char *buffer = malloc(fileLen); + buffer = malloc(fileLen); fread(buffer, fileLen, 1, f); fclose(f); @@ -286,8 +312,8 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) retModel->numMeshes = 1; // MD2 only has one mesh retModel->meshes = (mesh_t*)Z_Calloc(sizeof(mesh_t) * retModel->numMeshes, ztag, 0); retModel->meshes[0].numFrames = header->numFrames; - const float WUNITS = 1.0f; - float dataScale = WUNITS; + // const float WUNITS = 1.0f; + // float dataScale = WUNITS; // Tris and ST are simple structures that can be straight-copied md2triangle_t *tris = (md2triangle_t*)&buffer[header->offsetTris]; @@ -302,7 +328,7 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) retModel->materials = (material_t*)Z_Calloc(sizeof(material_t)*retModel->numMaterials, ztag, 0); - int t; + // int t; for (t = 0; t < retModel->numMaterials; t++) { retModel->materials[t].ambient[0] = 0.8f; @@ -370,14 +396,26 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) if (!useFloat) // Decompress to MD3 'tinyframe' space { + byte *ptr; + + md2triangle_t *trisPtr; + unsigned short *indexptr; + float *uvptr; + dataScale = 0.015624f; // 1 / 64.0f retModel->meshes[0].tinyframes = (tinyframe_t*)Z_Calloc(sizeof(tinyframe_t)*header->numFrames, ztag, 0); retModel->meshes[0].numVertices = header->numXYZ; retModel->meshes[0].uvs = (float*)Z_Malloc(sizeof(float) * 2 * retModel->meshes[0].numVertices, ztag, 0); - byte *ptr = (byte*)frames; + ptr = (byte*)frames; for (i = 0; i < header->numFrames; i++, ptr += header->framesize) { + short *vertptr; + char *normptr; + // char *tanptr; + + md2vertex_t *vertex; + md2frame_t *framePtr = (md2frame_t*)ptr; retModel->meshes[0].tinyframes[i].vertices = (short*)Z_Malloc(sizeof(short) * 3 * header->numXYZ, ztag, 0); retModel->meshes[0].tinyframes[i].normals = (char*)Z_Malloc(sizeof(char) * 3 * header->numXYZ, ztag, 0); @@ -386,14 +424,14 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) // retModel->meshes[0].tinyframes[i].tangents = (char*)malloc(sizeof(char));//(char*)Z_Malloc(sizeof(char)*3*header->numVerts, ztag); retModel->meshes[0].indices = (unsigned short*)Z_Malloc(sizeof(unsigned short) * 3 * header->numTris, ztag, 0); - short *vertptr = retModel->meshes[0].tinyframes[i].vertices; - char *normptr = retModel->meshes[0].tinyframes[i].normals; + vertptr = retModel->meshes[0].tinyframes[i].vertices; + normptr = retModel->meshes[0].tinyframes[i].normals; - // char *tanptr = retModel->meshes[0].tinyframes[i].tangents; + // tanptr = retModel->meshes[0].tinyframes[i].tangents; retModel->meshes[0].tinyframes[i].material = &retModel->materials[0]; framePtr++; // Advance to vertex list - md2vertex_t *vertex = (md2vertex_t*)framePtr; + vertex = (md2vertex_t*)framePtr; framePtr--; for (j = 0; j < header->numXYZ; j++, vertex++) { @@ -412,9 +450,9 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) } // This doesn't need to be done every frame! - md2triangle_t *trisPtr = tris; - unsigned short *indexptr = retModel->meshes[0].indices; - float *uvptr = (float*)retModel->meshes[0].uvs; + trisPtr = tris; + indexptr = retModel->meshes[0].indices; + uvptr = (float*)retModel->meshes[0].uvs; for (j = 0; j < header->numTris; j++, trisPtr++) { *indexptr = trisPtr->meshIndex[0]; @@ -434,12 +472,17 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) } else // Full float loading method { + md2triangle_t *trisPtr; + float *uvptr; + + byte *ptr; + retModel->meshes[0].numVertices = header->numTris * 3; retModel->meshes[0].frames = (mdlframe_t*)Z_Calloc(sizeof(mdlframe_t)*header->numFrames, ztag, 0); retModel->meshes[0].uvs = (float*)Z_Malloc(sizeof(float) * 2 * retModel->meshes[0].numVertices, ztag, 0); - md2triangle_t *trisPtr = tris; - float *uvptr = retModel->meshes[0].uvs; + trisPtr = tris; + uvptr = retModel->meshes[0].uvs; for (i = 0; i < retModel->meshes[0].numTriangles; i++, trisPtr++) { *uvptr++ = texcoords[trisPtr->stIndex[0]].s / (float)header->skinwidth; @@ -450,15 +493,19 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) *uvptr++ = (texcoords[trisPtr->stIndex[2]].t / (float)header->skinheight); } - byte *ptr = (byte*)frames; + ptr = (byte*)frames; for (i = 0; i < header->numFrames; i++, ptr += header->framesize) { + float *vertptr, *normptr; + + md2vertex_t *vertex; + md2frame_t *framePtr = (md2frame_t*)ptr; retModel->meshes[0].frames[i].normals = (float*)Z_Malloc(sizeof(float) * 3 * header->numTris * 3, ztag, 0); retModel->meshes[0].frames[i].vertices = (float*)Z_Malloc(sizeof(float) * 3 * header->numTris * 3, ztag, 0); // if (retModel->materials[0].lightmap) // retModel->meshes[0].frames[i].tangents = (float*)malloc(sizeof(float));//(float*)Z_Malloc(sizeof(float)*3*header->numTris*3, ztag); - float *vertptr, *normptr; + //float *vertptr, *normptr; normptr = (float*)retModel->meshes[0].frames[i].normals; vertptr = (float*)retModel->meshes[0].frames[i].vertices; trisPtr = tris; @@ -466,7 +513,7 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) retModel->meshes[0].frames[i].material = &retModel->materials[0]; framePtr++; // Advance to vertex list - md2vertex_t *vertex = (md2vertex_t*)framePtr; + vertex = (md2vertex_t*)framePtr; framePtr--; for (j = 0; j < header->numTris; j++, trisPtr++) { diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index e8f2720ec..6ff5d770b 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1653,8 +1653,7 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 GLfloat diffuse[4]; float pol = 0.0f; - scale *= 0.5f; - float scalex = scale, scaley = scale, scalez = scale; + float scalex, scaley, scalez; boolean useTinyFrames; @@ -1663,6 +1662,12 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 // Because Otherwise, scaling the screen negatively vertically breaks the lighting GLfloat LightPos[] = {0.0f, 1.0f, 0.0f, 0.0f}; + // Affect input model scaling + scale *= 0.5f; + scalex = scale; + scaley = scale; + scalez = scale; + if (duration != 0 && duration != -1 && tics != -1) // don't interpolate if instantaneous or infinite in length { UINT32 newtime = (duration - tics); // + 1; @@ -1780,11 +1785,15 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 } else { + short *vertPtr; + char *normPtr; + int j; + // Dangit, I soooo want to do this in a GLSL shader... AllocLerpTinyBuffer(mesh->numVertices * sizeof(short) * 3); - short *vertPtr = vertTinyBuffer; - char *normPtr = normTinyBuffer; - int j = 0; + vertPtr = vertTinyBuffer; + normPtr = normTinyBuffer; + j = 0; for (j = 0; j < mesh->numVertices * 3; j++) { @@ -1817,10 +1826,13 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 } else { + float *vertPtr; + float *normPtr; + // Dangit, I soooo want to do this in a GLSL shader... AllocLerpBuffer(mesh->numVertices * sizeof(float) * 3); - float *vertPtr = vertBuffer; - float *normPtr = normBuffer; + vertPtr = vertBuffer; + normPtr = normBuffer; int j = 0; for (j = 0; j < mesh->numVertices * 3; j++) @@ -1939,6 +1951,14 @@ EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]) float xfix, yfix; INT32 texsize = 2048; + const float blackBack[16] = + { + -16.0f, -16.0f, 6.0f, + -16.0f, 16.0f, 6.0f, + 16.0f, 16.0f, 6.0f, + 16.0f, -16.0f, 6.0f + }; + // Use a power of two texture, dammit if(screen_width <= 1024) texsize = 1024; @@ -1952,13 +1972,7 @@ EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]) pglDisable(GL_DEPTH_TEST); pglDisable(GL_BLEND); - const float blackBack[16] = - { - -16.0f, -16.0f, 6.0f, - -16.0f, 16.0f, 6.0f, - 16.0f, 16.0f, 6.0f, - 16.0f, -16.0f, 6.0f - }; + // const float blackBack[16] pglEnableClientState(GL_VERTEX_ARRAY); @@ -1974,6 +1988,9 @@ EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]) { for(y=0;y Date: Wed, 26 Dec 2018 23:40:29 -0500 Subject: [PATCH 23/74] byte -> char --- src/hardware/hw_md2load.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hardware/hw_md2load.c b/src/hardware/hw_md2load.c index 1d0e4f361..84b1bc531 100644 --- a/src/hardware/hw_md2load.c +++ b/src/hardware/hw_md2load.c @@ -396,7 +396,7 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) if (!useFloat) // Decompress to MD3 'tinyframe' space { - byte *ptr; + char *ptr; md2triangle_t *trisPtr; unsigned short *indexptr; @@ -407,7 +407,7 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) retModel->meshes[0].numVertices = header->numXYZ; retModel->meshes[0].uvs = (float*)Z_Malloc(sizeof(float) * 2 * retModel->meshes[0].numVertices, ztag, 0); - ptr = (byte*)frames; + ptr = (char*)frames; for (i = 0; i < header->numFrames; i++, ptr += header->framesize) { short *vertptr; @@ -475,7 +475,7 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) md2triangle_t *trisPtr; float *uvptr; - byte *ptr; + char *ptr; retModel->meshes[0].numVertices = header->numTris * 3; retModel->meshes[0].frames = (mdlframe_t*)Z_Calloc(sizeof(mdlframe_t)*header->numFrames, ztag, 0); @@ -493,7 +493,7 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) *uvptr++ = (texcoords[trisPtr->stIndex[2]].t / (float)header->skinheight); } - ptr = (byte*)frames; + ptr = (char*)frames; for (i = 0; i < header->numFrames; i++, ptr += header->framesize) { float *vertptr, *normptr; From 5ec40cf906bf42df28103881d8ae90c733f7fdae Mon Sep 17 00:00:00 2001 From: mazmazz Date: Wed, 26 Dec 2018 23:50:35 -0500 Subject: [PATCH 24/74] More mixed d&c fixes --- src/hardware/hw_md2load.c | 14 ++++++++++---- src/hardware/r_opengl/r_opengl.c | 3 ++- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/hardware/hw_md2load.c b/src/hardware/hw_md2load.c index 84b1bc531..ddf89f8db 100644 --- a/src/hardware/hw_md2load.c +++ b/src/hardware/hw_md2load.c @@ -233,6 +233,8 @@ typedef struct // Load the model model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) { + FILE *f; + model_t *retModel = NULL; md2header_t *header; @@ -247,6 +249,10 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) const float WUNITS = 1.0f; float dataScale = WUNITS; + md2triangle_t *tris; + md2texcoord_t *texcoords; + md2frame_t *frames; + int t; // MD2 currently does not work with tinyframes, so force useFloat = true @@ -263,7 +269,7 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) useFloat = true; - FILE *f = fopen(fileName, "rb"); + f = fopen(fileName, "rb"); if (!f) return NULL; @@ -316,9 +322,9 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) // float dataScale = WUNITS; // Tris and ST are simple structures that can be straight-copied - md2triangle_t *tris = (md2triangle_t*)&buffer[header->offsetTris]; - md2texcoord_t *texcoords = (md2texcoord_t*)&buffer[header->offsetST]; - md2frame_t *frames = (md2frame_t*)&buffer[header->offsetFrames]; + tris = (md2triangle_t*)&buffer[header->offsetTris]; + texcoords = (md2texcoord_t*)&buffer[header->offsetST]; + frames = (md2frame_t*)&buffer[header->offsetFrames]; // Read in textures retModel->numMaterials = header->numSkins; diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 6ff5d770b..d7657c1b2 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1828,12 +1828,13 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 { float *vertPtr; float *normPtr; + int j = 0; // Dangit, I soooo want to do this in a GLSL shader... AllocLerpBuffer(mesh->numVertices * sizeof(float) * 3); vertPtr = vertBuffer; normPtr = normBuffer; - int j = 0; + //int j = 0; for (j = 0; j < mesh->numVertices * 3; j++) { From 8c3e6642a7a6ac6e7837eab50cd4ffa18ff835e6 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Thu, 27 Dec 2018 00:01:51 -0500 Subject: [PATCH 25/74] Ignored fread fix --- src/hardware/hw_md2load.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/hw_md2load.c b/src/hardware/hw_md2load.c index ddf89f8db..3805deffb 100644 --- a/src/hardware/hw_md2load.c +++ b/src/hardware/hw_md2load.c @@ -309,7 +309,7 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) // read in file buffer = malloc(fileLen); - fread(buffer, fileLen, 1, f); + if (fread(buffer, fileLen, 1, f)) { } // squash ignored fread error fclose(f); // get pointer to file header From 0978732ecd23558e01bed60e0a1b0dc687587824 Mon Sep 17 00:00:00 2001 From: Arthur Date: Mon, 24 Dec 2018 12:08:00 -0500 Subject: [PATCH 26/74] boolean fix for VS add GL_NORMALIZE --- src/hardware/r_opengl/r_opengl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index d7657c1b2..6e23224da 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1701,6 +1701,7 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 } pglEnable(GL_CULL_FACE); + pglEnable(GL_NORMALIZE); #ifdef USE_FTRANSFORM_MIRROR // flipped is if the object is flipped @@ -1860,6 +1861,7 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 pglDisable(GL_LIGHTING); pglShadeModel(GL_FLAT); pglDisable(GL_CULL_FACE); + pglDisable(GL_NORMALIZE); } // -----------------+ From a812acc3d46362670e44ea197d74410318b8dad7 Mon Sep 17 00:00:00 2001 From: Arthur Date: Tue, 25 Dec 2018 21:28:51 -0500 Subject: [PATCH 27/74] Removed unused PF_Md2 flag More OpenGL performance increase by making assumptions about client state --- src/hardware/hw_defs.h | 2 +- src/hardware/r_opengl/r_opengl.c | 138 ++++++++++++------------------- src/hardware/r_opengl/r_opengl.h | 2 + 3 files changed, 56 insertions(+), 86 deletions(-) diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index 4fbd8d081..5a7aa731a 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -166,7 +166,7 @@ enum EPolyFlags // When set, pass the color constant into the FSurfaceInfo -> FlatColor PF_NoTexture = 0x00002000, // Use the small white texture PF_Corona = 0x00004000, // Tell the rendrer we are drawing a corona - PF_MD2 = 0x00008000, // Tell the rendrer we are drawing an MD2 + PF_Unused = 0x00008000, // Unused PF_RemoveYWrap = 0x00010000, // Force clamp texture on Y PF_ForceWrapX = 0x00020000, // Force repeat texture on X PF_ForceWrapY = 0x00040000, // Force repeat texture on Y diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 6e23224da..bbe448bdc 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -42,6 +42,7 @@ struct GLRGBAFloat GLfloat alpha; }; typedef struct GLRGBAFloat GLRGBAFloat; +static const float white[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; // ========================================================================== // CONSTANTS @@ -937,6 +938,8 @@ EXPORT void HWRAPI(ClearBuffer) (FBOOLEAN ColorMask, SetBlend(DepthMask ? PF_Occlude | CurrentPolyFlags : CurrentPolyFlags&~PF_Occlude); pglClear(ClearMask); + pglEnableClientState(GL_VERTEX_ARRAY); // We always use this one + pglEnableClientState(GL_TEXTURE_COORD_ARRAY); // And mostly this one, too } @@ -977,12 +980,12 @@ EXPORT void HWRAPI(Draw2DLine) (F2DCoord * v1, p[6] = v2->x + dx; p[7] = -(v2->y - dy); p[8] = 1; p[9] = v1->x + dx; p[10] = -(v1->y - dy); p[11] = 1; + pglDisableClientState(GL_TEXTURE_COORD_ARRAY); pglColor4fv(&c.red); // is in RGBA float format - pglEnableClientState(GL_VERTEX_ARRAY); pglVertexPointer(3, GL_FLOAT, 0, p); pglDrawArrays(GL_TRIANGLE_FAN, 0, 4); - pglDisableClientState(GL_VERTEX_ARRAY); + pglEnableClientState(GL_TEXTURE_COORD_ARRAY); pglEnable(GL_TEXTURE_2D); } @@ -1095,7 +1098,7 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags) if (oglflags & GLF_NOTEXENV) { if (!(PolyFlags & PF_Modulated)) - pglColor4f(1.0f, 1.0f, 1.0f, 1.0f); + pglColor4fv(white); } else #endif @@ -1453,16 +1456,9 @@ EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, pglColor4fv(&c.red); } - if (PolyFlags & PF_MD2) - return; - - pglEnableClientState(GL_VERTEX_ARRAY); - pglEnableClientState(GL_TEXTURE_COORD_ARRAY); pglVertexPointer(3, GL_FLOAT, sizeof(FOutVector), &pOutVerts[0].x); pglTexCoordPointer(2, GL_FLOAT, sizeof(FOutVector), &pOutVerts[0].sow); pglDrawArrays(GL_TRIANGLE_FAN, 0, iNumPts); - pglDisableClientState(GL_TEXTURE_COORD_ARRAY); - pglDisableClientState(GL_VERTEX_ARRAY); if (PolyFlags & PF_RemoveYWrap) pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); @@ -1761,8 +1757,6 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 if (useTinyFrames) pglScalef(1 / 64.0f, 1 / 64.0f, 1 / 64.0f); - pglEnableClientState(GL_VERTEX_ARRAY); - pglEnableClientState(GL_TEXTURE_COORD_ARRAY); pglEnableClientState(GL_NORMAL_ARRAY); for (i = 0; i < model->numMeshes; i++) @@ -1853,8 +1847,6 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 } pglDisableClientState(GL_NORMAL_ARRAY); - pglDisableClientState(GL_TEXTURE_COORD_ARRAY); - pglDisableClientState(GL_VERTEX_ARRAY); pglPopMatrix(); // should be the same as glLoadIdentity if (color) @@ -1977,65 +1969,59 @@ EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]) // const float blackBack[16] - pglEnableClientState(GL_VERTEX_ARRAY); + // Draw a black square behind the screen texture, + // so nothing shows through the edges + pglColor4fv(white); - // Draw a black square behind the screen texture, - // so nothing shows through the edges - pglColor4f(1.0f, 1.0f, 1.0f, 1.0f); + pglVertexPointer(3, GL_FLOAT, 0, blackBack); + pglDrawArrays(GL_TRIANGLE_FAN, 0, 4); - pglVertexPointer(3, GL_FLOAT, 0, blackBack); - pglDrawArrays(GL_TRIANGLE_FAN, 0, 4); - - pglEnableClientState(GL_TEXTURE_COORD_ARRAY); - for(x=0;x Date: Wed, 26 Dec 2018 10:58:37 -0500 Subject: [PATCH 28/74] Removed gr_voodoocompatibility as even low-power mobile devices do not have this limitation No longer using byte2float in DrawPolygon -- use the surface color data directly Vertex Buffer Objects for non-interpolated model frames Removed some old unused paletted texture stuff --- src/d_main.c | 3 - src/doomtype.h | 16 +- src/hardware/hw_cache.c | 61 ------- src/hardware/hw_defs.h | 2 - src/hardware/hw_drv.h | 2 + src/hardware/hw_main.c | 5 - src/hardware/hw_main.h | 2 - src/hardware/hw_md2.c | 1 + src/hardware/hw_model.c | 138 ---------------- src/hardware/r_opengl/r_opengl.c | 267 ++++++++++++++++++++++++------- src/hardware/r_opengl/r_vbo.h | 52 ++++++ src/r_main.c | 1 - src/sdl/hwsym_sdl.c | 1 + src/sdl/i_video.c | 1 + src/v_video.c | 1 - src/w_wad.c | 4 +- 16 files changed, 276 insertions(+), 281 deletions(-) create mode 100644 src/hardware/r_opengl/r_vbo.h diff --git a/src/d_main.c b/src/d_main.c index dd2cfe0e5..859ac03c6 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -533,9 +533,6 @@ void D_SRB2Loop(void) if (dedicated) server = true; - if (M_CheckParm("-voodoo")) // 256x256 Texture Limiter - COM_BufAddText("gr_voodoocompatibility on\n"); - // Pushing of + parameters is now done back in D_SRB2Main, not here. CONS_Printf("I_StartupKeyboard()...\n"); diff --git a/src/doomtype.h b/src/doomtype.h index b44e32e46..dd4268cdf 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -366,16 +366,18 @@ size_t strlcpy(char *dst, const char *src, size_t siz); /* Miscellaneous types that don't fit anywhere else (Can this be changed?) */ +typedef struct +{ + UINT8 red; + UINT8 green; + UINT8 blue; + UINT8 alpha; +} byteColor_t; + union FColorRGBA { UINT32 rgba; - struct - { - UINT8 red; - UINT8 green; - UINT8 blue; - UINT8 alpha; - } s; + byteColor_t s; } ATTRPACK; typedef union FColorRGBA RGBA_t; diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 78fc31afc..d49531bdf 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -241,43 +241,6 @@ static void HWR_ResizeBlock(INT32 originalwidth, INT32 originalheight, if (blockheight < 1) I_Error("3D GenerateTexture : too small"); } - else if (cv_voodoocompatibility.value) - { - if (originalwidth > 256 || originalheight > 256) - { - blockwidth = 256; - while (originalwidth < blockwidth) - blockwidth >>= 1; - if (blockwidth < 1) - I_Error("3D GenerateTexture : too small"); - - blockheight = 256; - while (originalheight < blockheight) - blockheight >>= 1; - if (blockheight < 1) - I_Error("3D GenerateTexture : too small"); - } - else - { - //size up to nearest power of 2 - blockwidth = 1; - while (blockwidth < originalwidth) - blockwidth <<= 1; - // scale down the original graphics to fit in 256 - if (blockwidth > 256) - blockwidth = 256; - //I_Error("3D GenerateTexture : too big"); - - //size up to nearest power of 2 - blockheight = 1; - while (blockheight < originalheight) - blockheight <<= 1; - // scale down the original graphics to fit in 256 - if (blockheight > 256) - blockheight = 255; - //I_Error("3D GenerateTexture : too big"); - } - } else { //size up to nearest power of 2 @@ -508,18 +471,6 @@ void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipm newwidth = blockwidth; newheight = blockheight; } - else if (cv_voodoocompatibility.value) // Only scales down textures that exceed 256x256. - { - // no rounddown, do not size up patches, so they don't look 'scaled' - newwidth = min(grPatch->width, blockwidth); - newheight = min(grPatch->height, blockheight); - - if (newwidth > 256 || newheight > 256) - { - newwidth = blockwidth; - newheight = blockheight; - } - } else { // no rounddown, do not size up patches, so they don't look 'scaled' @@ -935,18 +886,6 @@ GLPatch_t *HWR_GetPic(lumpnum_t lumpnum) newwidth = blockwidth; newheight = blockheight; } - else if (cv_voodoocompatibility.value) // Only scales down textures that exceed 256x256. - { - // no rounddown, do not size up patches, so they don't look 'scaled' - newwidth = min(SHORT(pic->width),blockwidth); - newheight = min(SHORT(pic->height),blockheight); - - if (newwidth > 256 || newheight > 256) - { - newwidth = blockwidth; - newheight = blockheight; - } - } else { // no rounddown, do not size up patches, so they don't look 'scaled' diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index 5a7aa731a..df0f39ece 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -224,8 +224,6 @@ enum hwdsetspecialstate HWD_SET_FOG_COLOR, HWD_SET_FOG_DENSITY, HWD_SET_FOV, - HWD_SET_POLYGON_SMOOTH, - HWD_SET_PALETTECOLOR, HWD_SET_TEXTUREFILTERMODE, HWD_SET_TEXTUREANISOTROPICMODE, HWD_NUMSTATE diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index c1ece091a..e1d050cf8 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -59,6 +59,7 @@ EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value); //Hurdler: added for new development EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 *color); +EXPORT void HWRAPI(CreateModelVBOs) (model_t *model); EXPORT void HWRAPI(SetTransform) (FTransform *ptransform); EXPORT INT32 HWRAPI(GetTextureUsed) (void); EXPORT INT32 HWRAPI(GetRenderVersion) (void); @@ -94,6 +95,7 @@ struct hwdriver_s ClearMipMapCache pfnClearMipMapCache; SetSpecialState pfnSetSpecialState;//Hurdler: added for backward compatibility DrawModel pfnDrawModel; + CreateModelVBOs pfnCreateModelVBOs; SetTransform pfnSetTransform; GetTextureUsed pfnGetTextureUsed; GetRenderVersion pfnGetRenderVersion; diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 95593394f..617bc1cf3 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -6606,11 +6606,6 @@ static void HWR_RenderWall(wallVert3D *wallVerts, FSurfaceInfo *pSurf, FBITFIE #endif } -void HWR_SetPaletteColor(INT32 palcolor) -{ - HWD.pfnSetSpecialState(HWD_SET_PALETTECOLOR, palcolor); -} - INT32 HWR_GetTextureUsed(void) { return HWD.pfnGetTextureUsed(); diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index 59042cf3b..4fee9dee9 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -58,7 +58,6 @@ void HWR_AddCommands(void); void HWR_CorrectSWTricks(void); void transform(float *cx, float *cy, float *cz); FBITFIELD HWR_TranstableToAlpha(INT32 transtablenum, FSurfaceInfo *pSurf); -void HWR_SetPaletteColor(INT32 palcolor); INT32 HWR_GetTextureUsed(void); void HWR_DoPostProcessor(player_t *player); void HWR_StartScreenWipe(void); @@ -92,7 +91,6 @@ extern consvar_t cv_grgammablue; extern consvar_t cv_grfiltermode; extern consvar_t cv_granisotropicmode; extern consvar_t cv_grcorrecttricks; -extern consvar_t cv_voodoocompatibility; extern consvar_t cv_grfovchange; extern consvar_t cv_grsolvetjoin; diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index e78812fa0..0cd4e97e2 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -981,6 +981,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) if (md2->model) { md2_printModelInfo(md2->model); + HWD.pfnCreateModelVBOs(md2->model); } else { diff --git a/src/hardware/hw_model.c b/src/hardware/hw_model.c index 394b0f899..2c36f9744 100644 --- a/src/hardware/hw_model.c +++ b/src/hardware/hw_model.c @@ -49,117 +49,6 @@ void VectorRotate(vector_t *rotVec, const vector_t *axisVec, float angle) rotVec->z = axisVec->z*(ux + vy + wz) + (rotVec->z*(axisVec->x*axisVec->x + axisVec->y*axisVec->y) - axisVec->z*(ux + vy))*ca + (-vx + uy)*sa; } -void CreateVBOTiny(mesh_t *mesh, tinyframe_t *frame) -{ - (void)mesh; - (void)frame; - return; -/* int bufferSize = sizeof(VBO::vbotiny_t)*mesh->numTriangles*3; - VBO::vbotiny_t *buffer = (VBO::vbotiny_t*)Z_Malloc(bufferSize, PU_STATIC, 0); - VBO::vbotiny_t *bufPtr = buffer; - - short *vertPtr = frame->vertices; - char *normPtr = frame->normals; - float *uvPtr = mesh->uvs; - char *tanPtr = frame->tangents; - - int i; - for (i = 0; i < mesh->numTriangles*3; i++) - { - bufPtr->x = *vertPtr++; - bufPtr->y = *vertPtr++; - bufPtr->z = *vertPtr++; - - bufPtr->nx = (*normPtr++) * 127; - bufPtr->ny = (*normPtr++) * 127; - bufPtr->nz = (*normPtr++) * 127; - - bufPtr->s0 = *uvPtr++; - bufPtr->t0 = *uvPtr++; - - if (tanPtr) - { - bufPtr->tanx = *tanPtr++; - bufPtr->tany = *tanPtr++; - bufPtr->tanz = *tanPtr++; - } - - bufPtr++; - } - - bglGenBuffers(1, &frame->vboID); - bglBindBuffer(BGL_ARRAY_BUFFER, frame->vboID); - bglBufferData(BGL_ARRAY_BUFFER, bufferSize, buffer, BGL_STATIC_DRAW); - Z_Free(buffer);*/ -} - -void CreateVBO(mesh_t *mesh, mdlframe_t *frame) -{ - (void)mesh; - (void)frame; - return; -/* int bufferSize = sizeof(VBO::vbo64_t)*mesh->numTriangles*3; - VBO::vbo64_t *buffer = (VBO::vbo64_t*)Z_Malloc(bufferSize, PU_STATIC, 0); - VBO::vbo64_t *bufPtr = buffer; - - float *vertPtr = frame->vertices; - float *normPtr = frame->normals; - float *tanPtr = frame->tangents; - float *uvPtr = mesh->uvs; - float *lightPtr = mesh->lightuvs; - char *colorPtr = frame->colors; - - int i; - for (i = 0; i < mesh->numTriangles*3; i++) - { - bufPtr->x = *vertPtr++; - bufPtr->y = *vertPtr++; - bufPtr->z = *vertPtr++; - - bufPtr->nx = *normPtr++; - bufPtr->ny = *normPtr++; - bufPtr->nz = *normPtr++; - - bufPtr->s0 = *uvPtr++; - bufPtr->t0 = *uvPtr++; - - if (tanPtr != NULL) - { - bufPtr->tan0 = *tanPtr++; - bufPtr->tan1 = *tanPtr++; - bufPtr->tan2 = *tanPtr++; - } - - if (lightPtr != NULL) - { - bufPtr->s1 = *lightPtr++; - bufPtr->t1 = *lightPtr++; - } - - if (colorPtr) - { - bufPtr->r = *colorPtr++; - bufPtr->g = *colorPtr++; - bufPtr->b = *colorPtr++; - bufPtr->a = *colorPtr++; - } - else - { - bufPtr->r = 255; - bufPtr->g = 255; - bufPtr->b = 255; - bufPtr->a = 255; - } - - bufPtr++; - } - - bglGenBuffers(1, &frame->vboID); - bglBindBuffer(BGL_ARRAY_BUFFER, frame->vboID); - bglBufferData(BGL_ARRAY_BUFFER, bufferSize, buffer, BGL_STATIC_DRAW); - Z_Free(buffer);*/ -} - void UnloadModel(model_t *model) { // Wouldn't it be great if C just had destructors? @@ -326,33 +215,6 @@ model_t *LoadModel(const char *filename, int ztag) material->shininess = 25.0f; } -// CONS_Printf("Generating VBOs for %s\n", filename); - for (i = 0; i < model->numMeshes; i++) - { - mesh_t *mesh = &model->meshes[i]; - - if (mesh->frames) - { - int j; - for (j = 0; j < model->meshes[i].numFrames; j++) - { - mdlframe_t *frame = &mesh->frames[j]; - frame->vboID = 0; - CreateVBO(mesh, frame); - } - } - else if (mesh->tinyframes) - { - int j; - for (j = 0; j < model->meshes[i].numFrames; j++) - { - tinyframe_t *frame = &mesh->tinyframes[j]; - frame->vboID = 0; - CreateVBOTiny(mesh, frame); - } - } - } - return model; } diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index bbe448bdc..d4d00741b 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -30,6 +30,7 @@ #include #include #include "r_opengl.h" +#include "r_vbo.h" #if defined (HWRENDER) && !defined (NOROPENGL) // for KOS: GL_TEXTURE_ENV, glAlphaFunc, glColorMask, glPolygonOffset, glReadPixels, GL_ALPHA_TEST, GL_POLYGON_OFFSET_FILL @@ -42,7 +43,7 @@ struct GLRGBAFloat GLfloat alpha; }; typedef struct GLRGBAFloat GLRGBAFloat; -static const float white[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; +static const GLubyte white[4] = { 255, 255, 255, 255 }; // ========================================================================== // CONSTANTS @@ -227,6 +228,8 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...) #define pglNormal3bv glNormal3bv #define pglColor4f glColor4f #define pglColor4fv glColor4fv +#define pglColor4ub glColor4ub +#define pglColor4ubv glColor4ubv #define pglTexCoord2f glTexCoord2f #define pglTexCoord2fv glTexCoord2fv #define pglVertexPointer glVertexPointer @@ -237,6 +240,10 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...) #define pglEnableClientState glEnableClientState #define pglDisableClientState glDisableClientState #define pglClientActiveTexture glClientActiveTexture +#define pglGenBuffers glGenBuffers +#define pglBindBuffer glBindBuffer +#define pglBufferData glBufferData +#define pglDeleteBuffers glDeleteBuffers /* Lighting */ #define pglShadeModel glShadeModel @@ -346,6 +353,10 @@ typedef void (APIENTRY * PFNglColor4f) (GLfloat red, GLfloat green, GLfloat blue static PFNglColor4f pglColor4f; typedef void (APIENTRY * PFNglColor4fv) (const GLfloat *v); static PFNglColor4fv pglColor4fv; +typedef void (APIENTRY * PFNglColor4ub) (GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); +static PFNglColor4ub pglColor4ub; +typedef void (APIENTRY * PFNglColor4ubv) (const GLubyte *v); +static PFNglColor4ubv pglColor4ubv; typedef void (APIENTRY * PFNglTexCoord2f) (GLfloat s, GLfloat t); static PFNglTexCoord2f pglTexCoord2f; typedef void (APIENTRY * PFNglTexCoord2fv) (const GLfloat *v); @@ -364,6 +375,15 @@ typedef void (APIENTRY * PFNglEnableClientState) (GLenum cap); static PFNglEnableClientState pglEnableClientState; typedef void (APIENTRY * PFNglDisableClientState) (GLenum cap); static PFNglDisableClientState pglDisableClientState; +typedef void (APIENTRY * PFNglGenBuffers) (GLsizei n, GLuint *buffers); +static PFNglGenBuffers pglGenBuffers; +typedef void (APIENTRY * PFNglBindBuffer) (GLenum target, GLuint buffer); +static PFNglBindBuffer pglBindBuffer; +typedef void (APIENTRY * PFNglBufferData) (GLenum target, GLsizei size, const GLvoid *data, GLenum usage); +static PFNglBufferData pglBufferData; +typedef void (APIENTRY * PFNglDeleteBuffers) (GLsizei n, const GLuint *buffers); +static PFNglDeleteBuffers pglDeleteBuffers; + /* Lighting */ typedef void (APIENTRY * PFNglShadeModel) (GLenum mode); @@ -492,6 +512,8 @@ boolean SetupGLfunc(void) GETOPENGLFUNC(pglNormal3bv, glNormal3bv) GETOPENGLFUNC(pglColor4f , glColor4f) GETOPENGLFUNC(pglColor4fv , glColor4fv) + GETOPENGLFUNC(pglColor4ub, glColor4ub) + GETOPENGLFUNC(pglColor4ubv, glColor4ubv) GETOPENGLFUNC(pglTexCoord2f , glTexCoord2f) GETOPENGLFUNC(pglTexCoord2fv, glTexCoord2fv) GETOPENGLFUNC(pglVertexPointer, glVertexPointer) @@ -501,9 +523,6 @@ boolean SetupGLfunc(void) GETOPENGLFUNC(pglDrawElements, glDrawElements) GETOPENGLFUNC(pglEnableClientState, glEnableClientState) GETOPENGLFUNC(pglDisableClientState, glDisableClientState) - GETOPENGLFUNC(pglClientActiveTexture, glClientActiveTexture) - if (!pglClientActiveTexture) - GETOPENGLFUNC(pglClientActiveTexture, glClientActiveTextureARB) GETOPENGLFUNC(pglShadeModel , glShadeModel) GETOPENGLFUNC(pglLightfv, glLightfv) @@ -542,6 +561,10 @@ boolean SetupGLFunc13(void) pglMultiTexCoord2f = GetGLFunc("glMultiTexCoord2f"); pglClientActiveTexture = GetGLFunc("glClientActiveTexture"); pglMultiTexCoord2fv = GetGLFunc("glMultiTexCoord2fv"); + pglGenBuffers = GetGLFunc("glGenBuffers"); + pglBindBuffer = GetGLFunc("glBindBuffer"); + pglBufferData = GetGLFunc("glBufferData"); + pglDeleteBuffers = GetGLFunc("glDeleteBuffers"); return true; } @@ -950,8 +973,6 @@ EXPORT void HWRAPI(Draw2DLine) (F2DCoord * v1, F2DCoord * v2, RGBA_t Color) { - GLRGBAFloat c; - // DBG_Printf ("DrawLine() (%f %f %f) %d\n", v1->x, -v1->y, -v1->z, v1->argb); GLfloat p[12]; GLfloat dx, dy; @@ -962,11 +983,6 @@ EXPORT void HWRAPI(Draw2DLine) (F2DCoord * v1, pglDisable(GL_TEXTURE_2D); - c.red = byte2float[Color.s.red]; - c.green = byte2float[Color.s.green]; - c.blue = byte2float[Color.s.blue]; - c.alpha = byte2float[Color.s.alpha]; - // This is the preferred, 'modern' way of rendering lines -- creating a polygon. if (fabsf(v2->x - v1->x) > FLT_EPSILON) angle = (float)atan((v2->y-v1->y)/(v2->x-v1->x)); @@ -981,7 +997,7 @@ EXPORT void HWRAPI(Draw2DLine) (F2DCoord * v1, p[9] = v1->x + dx; p[10] = -(v1->y - dy); p[11] = 1; pglDisableClientState(GL_TEXTURE_COORD_ARRAY); - pglColor4fv(&c.red); // is in RGBA float format + pglColor4ubv((GLbyte*)&Color); pglVertexPointer(3, GL_FLOAT, 0, p); pglDrawArrays(GL_TRIANGLE_FAN, 0, 4); @@ -1098,7 +1114,7 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags) if (oglflags & GLF_NOTEXENV) { if (!(PolyFlags & PF_Modulated)) - pglColor4fv(white); + pglColor4ubv(white); } else #endif @@ -1379,7 +1395,6 @@ EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, { FUINT i; FUINT j; - GLRGBAFloat c = {0,0,0,0}; if ((PolyFlags & PF_Corona) && (oglflags & GLF_NOZBUFREAD)) PolyFlags &= ~(PF_NoDepthTest|PF_Corona); @@ -1388,24 +1403,7 @@ EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, // If Modulated, mix the surface colour to the texture if ((CurrentPolyFlags & PF_Modulated) && pSurf) - { - if (pal_col) - { // hack for non-palettized mode - c.red = (const_pal_col.red +byte2float[pSurf->FlatColor.s.red]) /2.0f; - c.green = (const_pal_col.green+byte2float[pSurf->FlatColor.s.green])/2.0f; - c.blue = (const_pal_col.blue +byte2float[pSurf->FlatColor.s.blue]) /2.0f; - c.alpha = byte2float[pSurf->FlatColor.s.alpha]; - } - else - { - c.red = byte2float[pSurf->FlatColor.s.red]; - c.green = byte2float[pSurf->FlatColor.s.green]; - c.blue = byte2float[pSurf->FlatColor.s.blue]; - c.alpha = byte2float[pSurf->FlatColor.s.alpha]; - } - - pglColor4fv(&c.red); // is in RGBA float format - } + pglColor4ubv(&pSurf->FlatColor.s); // this test is added for new coronas' code (without depth buffer) // I think I should do a separate function for drawing coronas, so it will be a little faster @@ -1452,8 +1450,15 @@ EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, if (scalef < 0.05f) return; - c.alpha *= scalef; // change the alpha value (it seems better than changing the size of the corona) - pglColor4fv(&c.red); + GLubyte c[4]; + c[0] = pSurf->FlatColor.s.red; + c[1] = pSurf->FlatColor.s.green; + c[2] = pSurf->FlatColor.s.blue; + + float alpha = byte2float[pSurf->FlatColor.s.alpha]; + alpha *= scalef; // change the alpha value (it seems better than changing the size of the corona) + c[3] = (unsigned char)(alpha * 255); + pglColor4ubv(c); } pglVertexPointer(3, GL_FLOAT, sizeof(FOutVector), &pOutVerts[0].x); @@ -1489,15 +1494,6 @@ EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value) } #endif - case HWD_SET_PALETTECOLOR: - { - pal_col = Value; - const_pal_col.blue = byte2float[((Value>>16)&0xff)]; - const_pal_col.green = byte2float[((Value>>8)&0xff)]; - const_pal_col.red = byte2float[((Value)&0xff)]; - break; - } - case HWD_SET_FOG_COLOR: { GLfloat fogcolor[4]; @@ -1539,13 +1535,6 @@ EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value) pglDisable(GL_FOG); break; - case HWD_SET_POLYGON_SMOOTH: - if (Value) - pglEnable(GL_POLYGON_SMOOTH); - else - pglDisable(GL_POLYGON_SMOOTH); - break; - case HWD_SET_TEXTUREFILTERMODE: switch (Value) { @@ -1643,6 +1632,155 @@ static void AllocLerpTinyBuffer(size_t size) normTinyBuffer = malloc(lerpTinyBufferSize / 2); } +#ifndef GL_STATIC_DRAW +#define GL_STATIC_DRAW 0x88E4 +#endif + +#ifndef GL_ARRAY_BUFFER +#define GL_ARRAY_BUFFER 0x8892 +#endif + +static void CreateModelVBO(mesh_t *mesh, mdlframe_t *frame) +{ + int bufferSize = sizeof(vbo64_t)*mesh->numTriangles * 3; + vbo64_t *buffer = (vbo64_t*)malloc(bufferSize); + vbo64_t *bufPtr = buffer; + + float *vertPtr = frame->vertices; + float *normPtr = frame->normals; + float *tanPtr = frame->tangents; + float *uvPtr = mesh->uvs; + float *lightPtr = mesh->lightuvs; + char *colorPtr = frame->colors; + + int i; + for (i = 0; i < mesh->numTriangles * 3; i++) + { + bufPtr->x = *vertPtr++; + bufPtr->y = *vertPtr++; + bufPtr->z = *vertPtr++; + + bufPtr->nx = *normPtr++; + bufPtr->ny = *normPtr++; + bufPtr->nz = *normPtr++; + + bufPtr->s0 = *uvPtr++; + bufPtr->t0 = *uvPtr++; + + if (tanPtr != NULL) + { + bufPtr->tan0 = *tanPtr++; + bufPtr->tan1 = *tanPtr++; + bufPtr->tan2 = *tanPtr++; + } + + if (lightPtr != NULL) + { + bufPtr->s1 = *lightPtr++; + bufPtr->t1 = *lightPtr++; + } + + if (colorPtr) + { + bufPtr->r = *colorPtr++; + bufPtr->g = *colorPtr++; + bufPtr->b = *colorPtr++; + bufPtr->a = *colorPtr++; + } + else + { + bufPtr->r = 255; + bufPtr->g = 255; + bufPtr->b = 255; + bufPtr->a = 255; + } + + bufPtr++; + } + + pglGenBuffers(1, &frame->vboID); + pglBindBuffer(GL_ARRAY_BUFFER, frame->vboID); + pglBufferData(GL_ARRAY_BUFFER, bufferSize, buffer, GL_STATIC_DRAW); + free(buffer); +} + +static void CreateModelVBOTiny(mesh_t *mesh, tinyframe_t *frame) +{ + int bufferSize = sizeof(vbotiny_t)*mesh->numTriangles * 3; + vbotiny_t *buffer = (vbotiny_t*)malloc(bufferSize); + vbotiny_t *bufPtr = buffer; + + short *vertPtr = frame->vertices; + char *normPtr = frame->normals; + float *uvPtr = mesh->uvs; + char *tanPtr = frame->tangents; + + int i; + for (i = 0; i < mesh->numVertices; i++) + { + bufPtr->x = *vertPtr++; + bufPtr->y = *vertPtr++; + bufPtr->z = *vertPtr++; + + bufPtr->nx = *normPtr++; + bufPtr->ny = *normPtr++; + bufPtr->nz = *normPtr++; + + bufPtr->s0 = *uvPtr++; + bufPtr->t0 = *uvPtr++; + + if (tanPtr) + { + bufPtr->tanx = *tanPtr++; + bufPtr->tany = *tanPtr++; + bufPtr->tanz = *tanPtr++; + } + + bufPtr++; + } + + pglGenBuffers(1, &frame->vboID); + pglBindBuffer(GL_ARRAY_BUFFER, frame->vboID); + pglBufferData(GL_ARRAY_BUFFER, bufferSize, buffer, GL_STATIC_DRAW); + free(buffer); +} + +EXPORT void HWRAPI(CreateModelVBOs) (model_t *model) +{ + int i; + for (i = 0; i < model->numMeshes; i++) + { + mesh_t *mesh = &model->meshes[i]; + + if (mesh->frames) + { + int j; + for (j = 0; j < model->meshes[i].numFrames; j++) + { + mdlframe_t *frame = &mesh->frames[j]; + if (frame->vboID) + pglDeleteBuffers(1, &frame->vboID); + frame->vboID = 0; + CreateModelVBO(mesh, frame); + } + } + else if (mesh->tinyframes) + { + int j; + for (j = 0; j < model->meshes[i].numFrames; j++) + { + tinyframe_t *frame = &mesh->tinyframes[j]; + if (frame->vboID) + pglDeleteBuffers(1, &frame->vboID); + frame->vboID = 0; + CreateModelVBOTiny(mesh, frame); + } + } + } +} + +#define BUFFER_OFFSET(i) ((char*)NULL + (i)) + static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 *color) { GLfloat ambient[4]; @@ -1773,10 +1911,13 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 if (!nextframe || fpclassify(pol) == FP_ZERO) { - pglVertexPointer(3, GL_SHORT, 0, frame->vertices); - pglNormalPointer(GL_BYTE, 0, frame->normals); - pglTexCoordPointer(2, GL_FLOAT, 0, mesh->uvs); + pglBindBuffer(GL_ARRAY_BUFFER, frame->vboID); + pglVertexPointer(3, GL_SHORT, sizeof(vbotiny_t), BUFFER_OFFSET(0)); + pglNormalPointer(GL_BYTE, sizeof(vbotiny_t), BUFFER_OFFSET(sizeof(short)*3)); + pglTexCoordPointer(2, GL_FLOAT, sizeof(vbotiny_t), BUFFER_OFFSET(sizeof(short) * 3 + sizeof(byte) * 6)); + pglDrawElements(GL_TRIANGLES, mesh->numTriangles * 3, GL_UNSIGNED_SHORT, mesh->indices); + pglBindBuffer(GL_ARRAY_BUFFER, 0); } else { @@ -1814,10 +1955,18 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 if (!nextframe || fpclassify(pol) == FP_ZERO) { // Zoom! Take advantage of just shoving the entire arrays to the GPU. - pglVertexPointer(3, GL_FLOAT, 0, frame->vertices); +/* pglVertexPointer(3, GL_FLOAT, 0, frame->vertices); pglNormalPointer(GL_FLOAT, 0, frame->normals); pglTexCoordPointer(2, GL_FLOAT, 0, mesh->uvs); - pglDrawArrays(GL_TRIANGLES, 0, mesh->numTriangles * 3); + pglDrawArrays(GL_TRIANGLES, 0, mesh->numTriangles * 3);*/ + + pglBindBuffer(GL_ARRAY_BUFFER, frame->vboID); + pglVertexPointer(3, GL_FLOAT, sizeof(vbo64_t), BUFFER_OFFSET(0)); + pglNormalPointer(GL_FLOAT, sizeof(vbo64_t), BUFFER_OFFSET(sizeof(float) * 3)); + pglTexCoordPointer(2, GL_FLOAT, sizeof(vbo64_t), BUFFER_OFFSET(sizeof(float) * 6)); + + pglDrawElements(GL_TRIANGLES, mesh->numTriangles * 3, GL_UNSIGNED_SHORT, mesh->indices); + pglBindBuffer(GL_ARRAY_BUFFER, 0); } else { @@ -1971,7 +2120,7 @@ EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]) // Draw a black square behind the screen texture, // so nothing shows through the edges - pglColor4fv(white); + pglColor4ubv(white); pglVertexPointer(3, GL_FLOAT, 0, blackBack); pglDrawArrays(GL_TRIANGLE_FAN, 0, 4); @@ -2143,7 +2292,7 @@ EXPORT void HWRAPI(DrawIntermissionBG)(void) pglClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); pglBindTexture(GL_TEXTURE_2D, screentexture); - pglColor4fv(white); + pglColor4ubv(white); pglTexCoordPointer(2, GL_FLOAT, 0, fix); pglVertexPointer(3, GL_FLOAT, 0, screenVerts); @@ -2208,7 +2357,7 @@ EXPORT void HWRAPI(DoScreenWipe)(float alpha) // Draw the original screen pglBindTexture(GL_TEXTURE_2D, startScreenWipe); - pglColor4fv(white); + pglColor4ubv(white); pglTexCoordPointer(2, GL_FLOAT, 0, fix); pglVertexPointer(3, GL_FLOAT, 0, screenVerts); pglDrawArrays(GL_TRIANGLE_FAN, 0, 4); @@ -2366,7 +2515,7 @@ EXPORT void HWRAPI(DrawScreenFinalTexture)(int width, int height) ClearBuffer(true, false, &clearColour); pglBindTexture(GL_TEXTURE_2D, finalScreenTexture); - pglColor4fv(white); + pglColor4ubv(white); pglTexCoordPointer(2, GL_FLOAT, 0, fix); pglVertexPointer(3, GL_FLOAT, 0, off); diff --git a/src/hardware/r_opengl/r_vbo.h b/src/hardware/r_opengl/r_vbo.h new file mode 100644 index 000000000..ca1a974da --- /dev/null +++ b/src/hardware/r_opengl/r_vbo.h @@ -0,0 +1,52 @@ +/* + From the 'Wizard2' engine by Spaddlewit Inc. ( http://www.spaddlewit.com ) + An experimental work-in-progress. + + Donated to Sonic Team Junior and adapted to work with + Sonic Robo Blast 2. The license of this code matches whatever + the licensing is for Sonic Robo Blast 2. +*/ +#ifndef _R_VBO_H_ +#define _R_VBO_H_ + +typedef struct +{ + float x, y, z; // Vertex + float nx, ny, nz; // Normal + float s0, t0; // Texcoord0 +} vbo32_t; + +typedef struct +{ + float x, y, z; // Vertex + float s0, t0; // Texcoord0 + unsigned char r, g, b, a; // Color + float pad[2]; // Pad +} vbo2d32_t; + +typedef struct +{ + float x, y; // Vertex + float s0, t0; // Texcoord0 +} vbofont_t; + +typedef struct +{ + short x, y, z; // Vertex + char nx, ny, nz; // Normal + char tanx, tany, tanz; // Tangent + float s0, t0; // Texcoord0 +} vbotiny_t; + +typedef struct +{ + float x, y, z; // Vertex + float nx, ny, nz; // Normal + float s0, t0; // Texcoord0 + float s1, t1; // Texcoord1 + float s2, t2; // Texcoord2 + float tan0, tan1, tan2; // Tangent + unsigned char r, g, b, a; // Color +} vbo64_t; + +#endif diff --git a/src/r_main.c b/src/r_main.c index 94945af5b..e543145bb 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1397,7 +1397,6 @@ void R_RegisterEngineStuff(void) CV_RegisterVar(&cv_grgammared); CV_RegisterVar(&cv_grfovchange); CV_RegisterVar(&cv_grfog); - CV_RegisterVar(&cv_voodoocompatibility); CV_RegisterVar(&cv_grfogcolor); CV_RegisterVar(&cv_grsoftwarefog); #ifdef ALAM_LIGHTING diff --git a/src/sdl/hwsym_sdl.c b/src/sdl/hwsym_sdl.c index 9f844c623..4e083b4c2 100644 --- a/src/sdl/hwsym_sdl.c +++ b/src/sdl/hwsym_sdl.c @@ -88,6 +88,7 @@ void *hwSym(const char *funcName,void *handle) GETFUNC(SetSpecialState); GETFUNC(GetTextureUsed); GETFUNC(DrawModel); + GETFUNC(CreateModelVBOs); GETFUNC(SetTransform); GETFUNC(GetRenderVersion); GETFUNC(PostImgRedraw); diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 23795913c..7d08845e8 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1489,6 +1489,7 @@ void I_StartupGraphics(void) HWD.pfnSetPalette = hwSym("SetPalette",NULL); HWD.pfnGetTextureUsed = hwSym("GetTextureUsed",NULL); HWD.pfnDrawModel = hwSym("DrawModel",NULL); + HWD.pfnCreateModelVBOs = hwSym("CreateModelVBOs",NULL); HWD.pfnSetTransform = hwSym("SetTransform",NULL); HWD.pfnGetRenderVersion = hwSym("GetRenderVersion",NULL); HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL); diff --git a/src/v_video.c b/src/v_video.c index cfe7d0360..03ac7a1d2 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -60,7 +60,6 @@ static void CV_Gammaxxx_ONChange(void); static CV_PossibleValue_t grgamma_cons_t[] = {{1, "MIN"}, {255, "MAX"}, {0, NULL}}; static CV_PossibleValue_t grsoftwarefog_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "LightPlanes"}, {0, NULL}}; -consvar_t cv_voodoocompatibility = {"gr_voodoocompatibility", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grfovchange = {"gr_fovchange", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grfog = {"gr_fog", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grfogcolor = {"gr_fogcolor", "AAAAAA", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; diff --git a/src/w_wad.c b/src/w_wad.c index 88e89974a..fdab8962b 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -1572,12 +1572,12 @@ void W_VerifyFileMD5(UINT16 wadfilenum, const char *matchmd5) { char actualmd5text[2*MD5_LEN+1]; PrintMD5String(wadfiles[wadfilenum]->md5sum, actualmd5text); -#ifdef _DEBUG +/*#ifdef _DEBUG CONS_Printf #else I_Error #endif - (M_GetText("File is corrupt or has been modified: %s (found md5: %s, wanted: %s)\n"), wadfiles[wadfilenum]->filename, actualmd5text, matchmd5); + (M_GetText("File is corrupt or has been modified: %s (found md5: %s, wanted: %s)\n"), wadfiles[wadfilenum]->filename, actualmd5text, matchmd5);*/ } #endif } From f6e8b26af1648e99e6924c3f20409ca88bf4d275 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Thu, 27 Dec 2018 00:47:43 -0500 Subject: [PATCH 29/74] Compile fixes -- specify GLubyte for pglColor4ubv --- src/hardware/r_opengl/r_opengl.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index d4d00741b..fd4cfe958 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -67,8 +67,10 @@ static float NEAR_CLIPPING_PLANE = NZCLIP_PLANE; static GLuint NextTexAvail = FIRST_TEX_AVAIL; static GLuint tex_downloaded = 0; static GLfloat fov = 90.0f; +#if 0 static GLuint pal_col = 0; static FRGBAFloat const_pal_col; +#endif static FBITFIELD CurrentPolyFlags; static FTextureInfo* gr_cachetail = NULL; @@ -997,7 +999,7 @@ EXPORT void HWRAPI(Draw2DLine) (F2DCoord * v1, p[9] = v1->x + dx; p[10] = -(v1->y - dy); p[11] = 1; pglDisableClientState(GL_TEXTURE_COORD_ARRAY); - pglColor4ubv((GLbyte*)&Color); + pglColor4ubv((GLubyte*)&Color); pglVertexPointer(3, GL_FLOAT, 0, p); pglDrawArrays(GL_TRIANGLE_FAN, 0, 4); @@ -1403,7 +1405,7 @@ EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, // If Modulated, mix the surface colour to the texture if ((CurrentPolyFlags & PF_Modulated) && pSurf) - pglColor4ubv(&pSurf->FlatColor.s); + pglColor4ubv((GLubyte*)&pSurf->FlatColor.s); // this test is added for new coronas' code (without depth buffer) // I think I should do a separate function for drawing coronas, so it will be a little faster From f7a01c60a4d633c8c6f5326d28c26d2d99f6f959 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Thu, 27 Dec 2018 00:54:27 -0500 Subject: [PATCH 30/74] Buildbot fixes --- src/hardware/r_opengl/r_opengl.c | 10 +++++++--- src/hardware/r_opengl/r_opengl.h | 4 +++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index fd4cfe958..9b92cac6c 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1417,6 +1417,10 @@ EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, GLdouble px = 0.0f, py = 0.0f, pz = -1.0f; GLfloat scalef = 0.0f; + GLubyte c[4]; + + float alpha; + cx = (pOutVerts[0].x + pOutVerts[2].x) / 2.0f; // we should change the coronas' ... cy = (pOutVerts[0].y + pOutVerts[2].y) / 2.0f; // ... code so its only done once. cz = pOutVerts[0].z; @@ -1452,12 +1456,12 @@ EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, if (scalef < 0.05f) return; - GLubyte c[4]; + // GLubyte c[4]; c[0] = pSurf->FlatColor.s.red; c[1] = pSurf->FlatColor.s.green; c[2] = pSurf->FlatColor.s.blue; - float alpha = byte2float[pSurf->FlatColor.s.alpha]; + alpha = byte2float[pSurf->FlatColor.s.alpha]; alpha *= scalef; // change the alpha value (it seems better than changing the size of the corona) c[3] = (unsigned char)(alpha * 255); pglColor4ubv(c); @@ -1916,7 +1920,7 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 pglBindBuffer(GL_ARRAY_BUFFER, frame->vboID); pglVertexPointer(3, GL_SHORT, sizeof(vbotiny_t), BUFFER_OFFSET(0)); pglNormalPointer(GL_BYTE, sizeof(vbotiny_t), BUFFER_OFFSET(sizeof(short)*3)); - pglTexCoordPointer(2, GL_FLOAT, sizeof(vbotiny_t), BUFFER_OFFSET(sizeof(short) * 3 + sizeof(byte) * 6)); + pglTexCoordPointer(2, GL_FLOAT, sizeof(vbotiny_t), BUFFER_OFFSET(sizeof(short) * 3 + sizeof(char) * 6)); pglDrawElements(GL_TRIANGLES, mesh->numTriangles * 3, GL_UNSIGNED_SHORT, mesh->indices); pglBindBuffer(GL_ARRAY_BUFFER, 0); diff --git a/src/hardware/r_opengl/r_opengl.h b/src/hardware/r_opengl/r_opengl.h index b543749fc..b5187a587 100644 --- a/src/hardware/r_opengl/r_opengl.h +++ b/src/hardware/r_opengl/r_opengl.h @@ -118,9 +118,11 @@ typedef void (APIENTRY * PFNglGetIntegerv) (GLenum pname, GLint *params); extern PFNglGetIntegerv pglGetIntegerv; typedef const GLubyte* (APIENTRY * PFNglGetString) (GLenum name); extern PFNglGetString pglGetString; -typedef void (APIENTRY * PFNglEnableClientState) (GLenum cap); +#if 0 +typedef void (APIENTRY * PFNglEnableClientState) (GLenum cap); // redefined in r_opengl.c static PFNglEnableClientState pglEnableClientState; #endif +#endif // ========================================================================== // GLOBAL From b83790260f48b7e41fc41a376d9c0c0486c4ef50 Mon Sep 17 00:00:00 2001 From: Arthur Date: Thu, 27 Dec 2018 14:58:07 -0500 Subject: [PATCH 31/74] Fix screen transitions --- src/hardware/r_opengl/r_opengl.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 9b92cac6c..68c1c326a 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -999,7 +999,7 @@ EXPORT void HWRAPI(Draw2DLine) (F2DCoord * v1, p[9] = v1->x + dx; p[10] = -(v1->y - dy); p[11] = 1; pglDisableClientState(GL_TEXTURE_COORD_ARRAY); - pglColor4ubv((GLubyte*)&Color); + pglColor4ubv((GLubyte*)&Color.s); pglVertexPointer(3, GL_FLOAT, 0, p); pglDrawArrays(GL_TRIANGLE_FAN, 0, 4); @@ -2372,27 +2372,31 @@ EXPORT void HWRAPI(DoScreenWipe)(float alpha) // Draw the end screen that fades in pglActiveTexture(GL_TEXTURE0); + pglEnable(GL_TEXTURE_2D); pglBindTexture(GL_TEXTURE_2D, endScreenWipe); pglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); pglActiveTexture(GL_TEXTURE1); + pglEnable(GL_TEXTURE_2D); pglBindTexture(GL_TEXTURE_2D, fademaskdownloaded); pglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); // const float defaultST[8] - pglVertexPointer(3, GL_FLOAT, 0, screenVerts); pglClientActiveTexture(GL_TEXTURE0); pglTexCoordPointer(2, GL_FLOAT, 0, fix); + pglVertexPointer(3, GL_FLOAT, 0, screenVerts); pglClientActiveTexture(GL_TEXTURE1); + pglEnableClientState(GL_TEXTURE_COORD_ARRAY); pglTexCoordPointer(2, GL_FLOAT, 0, defaultST); pglDrawArrays(GL_TRIANGLE_FAN, 0, 4); - pglClientActiveTexture(GL_TEXTURE0); - pglDisable(GL_TEXTURE_2D); // disable the texture in the 2nd texture unit + pglDisableClientState(GL_TEXTURE_COORD_ARRAY); + pglActiveTexture(GL_TEXTURE0); + pglClientActiveTexture(GL_TEXTURE0); tex_downloaded = endScreenWipe; } From 4f1f3155630b37598d0b82691de586d4d5099fc7 Mon Sep 17 00:00:00 2001 From: Arthur Date: Thu, 27 Dec 2018 15:23:33 -0500 Subject: [PATCH 32/74] Eliminate some old GL functions so we don't slide back into bad habits! --- src/hardware/hw_clip.c | 8 +- src/hardware/hw_drv.h | 2 +- src/hardware/hw_main.c | 2 +- src/hardware/r_opengl/ogl_win.c | 22 +---- src/hardware/r_opengl/r_opengl.c | 158 ++++++++----------------------- src/hardware/r_opengl/r_opengl.h | 5 - 6 files changed, 49 insertions(+), 148 deletions(-) diff --git a/src/hardware/hw_clip.c b/src/hardware/hw_clip.c index 6d120efe7..4bdc753ec 100644 --- a/src/hardware/hw_clip.c +++ b/src/hardware/hw_clip.c @@ -77,8 +77,8 @@ #include "r_opengl/r_opengl.h" #ifdef HAVE_SPHEREFRUSTRUM -static GLdouble viewMatrix[16]; -static GLdouble projMatrix[16]; +static GLfloat viewMatrix[16]; +static GLfloat projMatrix[16]; float frustum[6][4]; #endif @@ -380,8 +380,8 @@ void gld_FrustrumSetup(void) float t; float clip[16]; - pglGetDoublev(GL_PROJECTION_MATRIX, projMatrix); - pglGetDoublev(GL_MODELVIEW_MATRIX, viewMatrix); + pglGeFloatv(GL_PROJECTION_MATRIX, projMatrix); + pglGetFloatv(GL_MODELVIEW_MATRIX, viewMatrix); clip[0] = CALCMATRIX(0, 0, 1, 4, 2, 8, 3, 12); clip[1] = CALCMATRIX(0, 1, 1, 5, 2, 9, 3, 13); diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index e1d050cf8..54bd9e786 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -69,7 +69,7 @@ EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]); EXPORT void HWRAPI(FlushScreenTextures) (void); EXPORT void HWRAPI(StartScreenWipe) (void); EXPORT void HWRAPI(EndScreenWipe) (void); -EXPORT void HWRAPI(DoScreenWipe) (float alpha); +EXPORT void HWRAPI(DoScreenWipe) (void); EXPORT void HWRAPI(DrawIntermissionBG) (void); EXPORT void HWRAPI(MakeScreenTexture) (void); EXPORT void HWRAPI(MakeScreenFinalTexture) (void); diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 617bc1cf3..98c495236 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -6740,7 +6740,7 @@ void HWR_DoWipe(UINT8 wipenum, UINT8 scrnnum) HWR_GetFadeMask(lumpnum); - HWD.pfnDoScreenWipe(HWRWipeCounter); // Still send in wipecounter since old stuff might not support multitexturing + HWD.pfnDoScreenWipe(); HWRWipeCounter += 0.05f; // increase opacity of end screen diff --git a/src/hardware/r_opengl/ogl_win.c b/src/hardware/r_opengl/ogl_win.c index eb9a31a7d..562afe998 100644 --- a/src/hardware/r_opengl/ogl_win.c +++ b/src/hardware/r_opengl/ogl_win.c @@ -347,13 +347,6 @@ static INT32 WINAPI SetRes(viddef_t *lvid, vmode_t *pcurrentmode) if (strstr(renderer, "810")) oglflags |= GLF_NOZBUFREAD; DBG_Printf("oglflags : 0x%X\n", oglflags); -#ifdef USE_PALETTED_TEXTURE - if (isExtAvailable("GL_EXT_paletted_texture",gl_extensions)) - glColorTableEXT = GetGLFunc("glColorTableEXT"); - else - glColorTableEXT = NULL; -#endif - #ifdef USE_WGL_SWAP if (isExtAvailable("WGL_EXT_swap_control",gl_extensions)) wglSwapIntervalEXT = GetGLFunc("wglSwapIntervalEXT"); @@ -582,19 +575,8 @@ EXPORT void HWRAPI(SetPalette) (RGBA_t *pal, RGBA_t *gamma) myPaletteData[i].s.blue = (UINT8)MIN((pal[i].s.blue*gamma->s.blue)/127, 255); myPaletteData[i].s.alpha = pal[i].s.alpha; } -#ifdef USE_PALETTED_TEXTURE - if (glColorTableEXT) - { - for (i = 0; i < 256; i++) - { - palette_tex[3*i+0] = pal[i].s.red; - palette_tex[3*i+1] = pal[i].s.green; - palette_tex[3*i+2] = pal[i].s.blue; - } - glColorTableEXT(GL_TEXTURE_2D, GL_RGB8, 256, GL_RGB, GL_UNSIGNED_BYTE, palette_tex); - } -#endif - // on a chang� de palette, il faut recharger toutes les textures + + // on a palette change, you have to reload all of the textures Flush(); } diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 68c1c326a..5d252a698 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -33,7 +33,6 @@ #include "r_vbo.h" #if defined (HWRENDER) && !defined (NOROPENGL) -// for KOS: GL_TEXTURE_ENV, glAlphaFunc, glColorMask, glPolygonOffset, glReadPixels, GL_ALPHA_TEST, GL_POLYGON_OFFSET_FILL struct GLRGBAFloat { @@ -91,16 +90,10 @@ static FTransform md2_transform; const GLubyte *gl_extensions = NULL; //Hurdler: 04/10/2000: added for the kick ass coronas as Boris wanted;-) -static GLdouble modelMatrix[16]; -static GLdouble projMatrix[16]; +static GLfloat modelMatrix[16]; +static GLfloat projMatrix[16]; static GLint viewport[4]; - -#ifdef USE_PALETTED_TEXTURE - PFNGLCOLORTABLEEXTPROC glColorTableEXT = NULL; - GLubyte palette_tex[256*3]; -#endif - // Yay for arbitrary numbers! NextTexAvail is buggy for some reason. // Sryder: NextTexAvail is broken for these because palette changes or changes to the texture filter or antialiasing // flush all of the stored textures, leaving them unavailable at times such as between levels @@ -192,12 +185,11 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...) #define pglAlphaFunc glAlphaFunc #define pglBlendFunc glBlendFunc #define pglCullFace glCullFace -#define pglPolygonMode glPolygonMode #define pglPolygonOffset glPolygonOffset #define pglScissor glScissor #define pglEnable glEnable #define pglDisable glDisable -#define pglGetDoublev glGetDoublev +#define pglGetFloatv glGetFloatv //glGetIntegerv //glGetString #define pglHint glHint @@ -215,25 +207,12 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...) #define pglPopMatrix glPopMatrix #define pglLoadIdentity glLoadIdentity #define pglMultMatrixf glMultMatrixf -#define pglMultMatrixd glMultMatrixd #define pglRotatef glRotatef #define pglScalef glScalef #define pglTranslatef glTranslatef /* Drawing Functions */ -#define pglBegin glBegin -#define pglEnd glEnd -#define pglVertex3f glVertex3f -#define pglVertex3fv glVertex3fv -#define pglVertex3sv glVertex3sv -#define pglNormal3f glNormal3f -#define pglNormal3bv glNormal3bv -#define pglColor4f glColor4f -#define pglColor4fv glColor4fv -#define pglColor4ub glColor4ub #define pglColor4ubv glColor4ubv -#define pglTexCoord2f glTexCoord2f -#define pglTexCoord2fv glTexCoord2fv #define pglVertexPointer glVertexPointer #define pglNormalPointer glNormalPointer #define pglTexCoordPointer glTexCoordPointer @@ -289,8 +268,6 @@ typedef void (APIENTRY * PFNglBlendFunc) (GLenum sfactor, GLenum dfactor); static PFNglBlendFunc pglBlendFunc; typedef void (APIENTRY * PFNglCullFace) (GLenum mode); static PFNglCullFace pglCullFace; -typedef void (APIENTRY * PFNglPolygonMode) (GLenum face, GLenum mode); -static PFNglPolygonMode pglPolygonMode; typedef void (APIENTRY * PFNglPolygonOffset) (GLfloat factor, GLfloat units); static PFNglPolygonOffset pglPolygonOffset; typedef void (APIENTRY * PFNglScissor) (GLint x, GLint y, GLsizei width, GLsizei height); @@ -299,8 +276,8 @@ typedef void (APIENTRY * PFNglEnable) (GLenum cap); static PFNglEnable pglEnable; typedef void (APIENTRY * PFNglDisable) (GLenum cap); static PFNglDisable pglDisable; -typedef void (APIENTRY * PFNglGetDoublev) (GLenum pname, GLdouble *params); -static PFNglGetDoublev pglGetDoublev; +typedef void (APIENTRY * PFNglGetFloatv) (GLenum pname, GLfloat *params); +static PFNglGetFloatv pglGetFloatv; //glGetIntegerv //glGetString @@ -327,8 +304,6 @@ typedef void (APIENTRY * PFNglLoadIdentity) (void); static PFNglLoadIdentity pglLoadIdentity; typedef void (APIENTRY * PFNglMultMatrixf) (const GLfloat *m); static PFNglMultMatrixf pglMultMatrixf; -typedef void (APIENTRY * PFNglMultMatrixd) (const GLdouble *m); -static PFNglMultMatrixd pglMultMatrixd; typedef void (APIENTRY * PFNglRotatef) (GLfloat angle, GLfloat x, GLfloat y, GLfloat z); static PFNglRotatef pglRotatef; typedef void (APIENTRY * PFNglScalef) (GLfloat x, GLfloat y, GLfloat z); @@ -337,32 +312,8 @@ typedef void (APIENTRY * PFNglTranslatef) (GLfloat x, GLfloat y, GLfloat z); static PFNglTranslatef pglTranslatef; /* Drawing Functions */ -typedef void (APIENTRY * PFNglBegin) (GLenum mode); -static PFNglBegin pglBegin; -typedef void (APIENTRY * PFNglEnd) (void); -static PFNglEnd pglEnd; -typedef void (APIENTRY * PFNglVertex3f) (GLfloat x, GLfloat y, GLfloat z); -static PFNglVertex3f pglVertex3f; -typedef void (APIENTRY * PFNglVertex3fv)(const GLfloat *v); -static PFNglVertex3fv pglVertex3fv; -typedef void (APIENTRY * PFNglVertex3sv) (const GLshort *v); -static PFNglVertex3sv pglVertex3sv; -typedef void (APIENTRY * PFNglNormal3f) (GLfloat x, GLfloat y, GLfloat z); -static PFNglNormal3f pglNormal3f; -typedef void (APIENTRY * PFNglNormal3bv)(const GLbyte *v); -static PFNglNormal3bv pglNormal3bv; -typedef void (APIENTRY * PFNglColor4f) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); -static PFNglColor4f pglColor4f; -typedef void (APIENTRY * PFNglColor4fv) (const GLfloat *v); -static PFNglColor4fv pglColor4fv; -typedef void (APIENTRY * PFNglColor4ub) (GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); -static PFNglColor4ub pglColor4ub; typedef void (APIENTRY * PFNglColor4ubv) (const GLubyte *v); static PFNglColor4ubv pglColor4ubv; -typedef void (APIENTRY * PFNglTexCoord2f) (GLfloat s, GLfloat t); -static PFNglTexCoord2f pglTexCoord2f; -typedef void (APIENTRY * PFNglTexCoord2fv) (const GLfloat *v); -static PFNglTexCoord2fv pglTexCoord2fv; typedef void (APIENTRY * PFNglVertexPointer) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); static PFNglVertexPointer pglVertexPointer; typedef void (APIENTRY * PFNglNormalPointer) (GLenum type, GLsizei stride, const GLvoid *pointer); @@ -475,19 +426,18 @@ boolean SetupGLfunc(void) GETOPENGLFUNC(pglClearColor, glClearColor) - GETOPENGLFUNC(pglClear , glClear) - GETOPENGLFUNC(pglColorMask , glColorMask) - GETOPENGLFUNC(pglAlphaFunc , glAlphaFunc) - GETOPENGLFUNC(pglBlendFunc , glBlendFunc) - GETOPENGLFUNC(pglCullFace , glCullFace) - GETOPENGLFUNC(pglPolygonMode , glPolygonMode) - GETOPENGLFUNC(pglPolygonOffset , glPolygonOffset) - GETOPENGLFUNC(pglScissor , glScissor) - GETOPENGLFUNC(pglEnable , glEnable) - GETOPENGLFUNC(pglDisable , glDisable) - GETOPENGLFUNC(pglGetDoublev , glGetDoublev) - GETOPENGLFUNC(pglGetIntegerv , glGetIntegerv) - GETOPENGLFUNC(pglGetString , glGetString) + GETOPENGLFUNC(pglClear, glClear) + GETOPENGLFUNC(pglColorMask, glColorMask) + GETOPENGLFUNC(pglAlphaFunc, glAlphaFunc) + GETOPENGLFUNC(pglBlendFunc, glBlendFunc) + GETOPENGLFUNC(pglCullFace, glCullFace) + GETOPENGLFUNC(pglPolygonOffset, glPolygonOffset) + GETOPENGLFUNC(pglScissor, glScissor) + GETOPENGLFUNC(pglEnable, glEnable) + GETOPENGLFUNC(pglDisable, glDisable) + GETOPENGLFUNC(pglGetFloatv, glGetFloatv) + GETOPENGLFUNC(pglGetIntegerv, glGetIntegerv) + GETOPENGLFUNC(pglGetString, glGetString) GETOPENGLFUNC(pglClearDepth , glClearDepth) GETOPENGLFUNC(pglDepthFunc , glDepthFunc) @@ -500,24 +450,11 @@ boolean SetupGLfunc(void) GETOPENGLFUNC(pglPopMatrix , glPopMatrix) GETOPENGLFUNC(pglLoadIdentity , glLoadIdentity) GETOPENGLFUNC(pglMultMatrixf , glMultMatrixf) - GETOPENGLFUNC(pglMultMatrixd , glMultMatrixd) GETOPENGLFUNC(pglRotatef , glRotatef) GETOPENGLFUNC(pglScalef , glScalef) GETOPENGLFUNC(pglTranslatef , glTranslatef) - GETOPENGLFUNC(pglBegin , glBegin) - GETOPENGLFUNC(pglEnd , glEnd) - GETOPENGLFUNC(pglVertex3f , glVertex3f) - GETOPENGLFUNC(pglVertex3fv, glVertex3fv) - GETOPENGLFUNC(pglVertex3sv, glVertex3sv) - GETOPENGLFUNC(pglNormal3f , glNormal3f) - GETOPENGLFUNC(pglNormal3bv, glNormal3bv) - GETOPENGLFUNC(pglColor4f , glColor4f) - GETOPENGLFUNC(pglColor4fv , glColor4fv) - GETOPENGLFUNC(pglColor4ub, glColor4ub) GETOPENGLFUNC(pglColor4ubv, glColor4ubv) - GETOPENGLFUNC(pglTexCoord2f , glTexCoord2f) - GETOPENGLFUNC(pglTexCoord2fv, glTexCoord2fv) GETOPENGLFUNC(pglVertexPointer, glVertexPointer) GETOPENGLFUNC(pglNormalPointer, glNormalPointer) GETOPENGLFUNC(pglTexCoordPointer, glTexCoordPointer) @@ -584,40 +521,40 @@ static void SetNoTexture(void) } } -static void GLPerspective(GLdouble fovy, GLdouble aspect) +static void GLPerspective(GLfloat fovy, GLfloat aspect) { - GLdouble m[4][4] = + GLfloat m[4][4] = { { 1.0f, 0.0f, 0.0f, 0.0f}, { 0.0f, 1.0f, 0.0f, 0.0f}, { 0.0f, 0.0f, 1.0f,-1.0f}, { 0.0f, 0.0f, 0.0f, 0.0f}, }; - const GLdouble zNear = NEAR_CLIPPING_PLANE; - const GLdouble zFar = FAR_CLIPPING_PLANE; - const GLdouble radians = (GLdouble)(fovy / 2.0f * M_PIl / 180.0f); - const GLdouble sine = sin(radians); - const GLdouble deltaZ = zFar - zNear; - GLdouble cotangent; + const GLfloat zNear = NEAR_CLIPPING_PLANE; + const GLfloat zFar = FAR_CLIPPING_PLANE; + const GLfloat radians = (GLfloat)(fovy / 2.0f * M_PIl / 180.0f); + const GLfloat sine = sinf(radians); + const GLfloat deltaZ = zFar - zNear; + GLfloat cotangent; if ((fabsf((float)deltaZ) < 1.0E-36f) || fpclassify(sine) == FP_ZERO || fpclassify(aspect) == FP_ZERO) { return; } - cotangent = cos(radians) / sine; + cotangent = cosf(radians) / sine; m[0][0] = cotangent / aspect; m[1][1] = cotangent; m[2][2] = -(zFar + zNear) / deltaZ; m[3][2] = -2.0f * zNear * zFar / deltaZ; - pglMultMatrixd(&m[0][0]); + pglMultMatrixf(&m[0][0]); } -static void GLProject(GLdouble objX, GLdouble objY, GLdouble objZ, - GLdouble* winX, GLdouble* winY, GLdouble* winZ) +static void GLProject(GLfloat objX, GLfloat objY, GLfloat objZ, + GLfloat* winX, GLfloat* winY, GLfloat* winZ) { - GLdouble in[4], out[4]; + GLfloat in[4], out[4]; int i; for (i=0; i<4; i++) @@ -684,7 +621,7 @@ void SetModelView(GLint w, GLint h) // added for new coronas' code (without depth buffer) pglGetIntegerv(GL_VIEWPORT, viewport); - pglGetDoublev(GL_PROJECTION_MATRIX, projMatrix); + pglGetFloatv(GL_PROJECTION_MATRIX, projMatrix); } @@ -746,8 +683,6 @@ void SetStates(void) //pglEnable(GL_CULL_FACE); //pglCullFace(GL_FRONT); - //pglPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - //pglPolygonMode(GL_FRONT, GL_LINE); //glFogi(GL_FOG_MODE, GL_EXP); //pglHint(GL_FOG_HINT, GL_FASTEST); @@ -763,7 +698,7 @@ void SetStates(void) // bp : when no t&l :) pglLoadIdentity(); pglScalef(1.0f, 1.0f, -1.0f); - pglGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix); // added for new coronas' code (without depth buffer) + pglGetFloatv(GL_MODELVIEW_MATRIX, modelMatrix); // added for new coronas' code (without depth buffer) } @@ -929,7 +864,7 @@ EXPORT void HWRAPI(GClipRect) (INT32 minx, INT32 miny, INT32 maxx, INT32 maxy, f // added for new coronas' code (without depth buffer) pglGetIntegerv(GL_VIEWPORT, viewport); - pglGetDoublev(GL_PROJECTION_MATRIX, projMatrix); + pglGetFloatv(GL_PROJECTION_MATRIX, projMatrix); } @@ -1191,17 +1126,6 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo) w = pTexInfo->width; h = pTexInfo->height; -#ifdef USE_PALETTED_TEXTURE - if (glColorTableEXT && - (pTexInfo->grInfo.format == GR_TEXFMT_P_8) && - !(pTexInfo->flags & TF_CHROMAKEYED)) - { - // do nothing here. - // Not a problem with MiniGL since we don't use paletted texture - } - else -#endif - if ((pTexInfo->grInfo.format == GR_TEXFMT_P_8) || (pTexInfo->grInfo.format == GR_TEXFMT_AP_88)) { @@ -1413,8 +1337,8 @@ EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, { //rem: all 8 (or 8.0f) values are hard coded: it can be changed to a higher value GLfloat buf[8][8]; - GLdouble cx, cy, cz; - GLdouble px = 0.0f, py = 0.0f, pz = -1.0f; + GLfloat cx, cy, cz; + GLfloat px = 0.0f, py = 0.0f, pz = -1.0f; GLfloat scalef = 0.0f; GLubyte c[4]; @@ -2052,10 +1976,10 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform) fovx90 = stransform->fovxangle > 0.0f && fabsf(stransform->fovxangle - 90.0f) < 0.5f; special_splitscreen = (stransform->splitscreen && fovx90); if (special_splitscreen) - GLPerspective(53.13l, 2*ASPECT_RATIO); // 53.13 = 2*atan(0.5) + GLPerspective(53.13f, 2*ASPECT_RATIO); // 53.13 = 2*atan(0.5) else GLPerspective(stransform->fovxangle, ASPECT_RATIO); - pglGetDoublev(GL_PROJECTION_MATRIX, projMatrix); // added for new coronas' code (without depth buffer) + pglGetFloatv(GL_PROJECTION_MATRIX, projMatrix); // added for new coronas' code (without depth buffer) pglMatrixMode(GL_MODELVIEW); } else @@ -2065,15 +1989,15 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform) pglMatrixMode(GL_PROJECTION); pglLoadIdentity(); if (special_splitscreen) - GLPerspective(53.13l, 2*ASPECT_RATIO); // 53.13 = 2*atan(0.5) + GLPerspective(53.13f, 2*ASPECT_RATIO); // 53.13 = 2*atan(0.5) else //Hurdler: is "fov" correct? GLPerspective(fov, ASPECT_RATIO); - pglGetDoublev(GL_PROJECTION_MATRIX, projMatrix); // added for new coronas' code (without depth buffer) + pglGetFloatv(GL_PROJECTION_MATRIX, projMatrix); // added for new coronas' code (without depth buffer) pglMatrixMode(GL_MODELVIEW); } - pglGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix); // added for new coronas' code (without depth buffer) + pglGetFloatv(GL_MODELVIEW_MATRIX, modelMatrix); // added for new coronas' code (without depth buffer) } EXPORT INT32 HWRAPI(GetTextureUsed) (void) @@ -2308,7 +2232,7 @@ EXPORT void HWRAPI(DrawIntermissionBG)(void) } // Do screen fades! -EXPORT void HWRAPI(DoScreenWipe)(float alpha) +EXPORT void HWRAPI(DoScreenWipe)() { INT32 texsize = 2048; float xfix, yfix; diff --git a/src/hardware/r_opengl/r_opengl.h b/src/hardware/r_opengl/r_opengl.h index b5187a587..1bb97c37c 100644 --- a/src/hardware/r_opengl/r_opengl.h +++ b/src/hardware/r_opengl/r_opengl.h @@ -71,7 +71,6 @@ extern FILE *gllogstream; #endif #ifndef DRIVER_STRING -// #define USE_PALETTED_TEXTURE #define DRIVER_STRING "HWRAPI Init(): SRB2 OpenGL renderer" // Tails #endif @@ -89,10 +88,6 @@ int SetupPixelFormat(INT32 WantColorBits, INT32 WantStencilBits, INT32 WantDepth void SetModelView(GLint w, GLint h); void SetStates(void); FUNCMATH float byteasfloat(UINT8 fbyte); -#ifdef USE_PALETTED_TEXTURE -extern PFNGLCOLORTABLEEXTPROC glColorTableEXT; -extern GLubyte palette_tex[256*3]; -#endif #ifndef GL_EXT_texture_filter_anisotropic #define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE From 34915f05082008e32dce3157ee7b9da7d392676d Mon Sep 17 00:00:00 2001 From: mazmazz Date: Thu, 27 Dec 2018 22:25:13 -0500 Subject: [PATCH 33/74] Compile fix -- remove (void)alpha from DoScreenWipe --- src/hardware/r_opengl/r_opengl.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 5d252a698..ce4465644 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -2232,7 +2232,7 @@ EXPORT void HWRAPI(DrawIntermissionBG)(void) } // Do screen fades! -EXPORT void HWRAPI(DoScreenWipe)() +EXPORT void HWRAPI(DoScreenWipe)(void) { INT32 texsize = 2048; float xfix, yfix; @@ -2257,8 +2257,6 @@ EXPORT void HWRAPI(DoScreenWipe)() 1.0f, 1.0f }; - (void)alpha; - // Use a power of two texture, dammit if(screen_width <= 1024) texsize = 1024; From 1d9b8d357b00fbd6633a232b566f3ac439d211b5 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Thu, 27 Dec 2018 23:05:06 -0500 Subject: [PATCH 34/74] Add framecount increment to HWR_RenderPlayerView Analogue to R_RenderPlayerView; used for timedemo FPS reading --- src/hardware/hw_main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index efecac524..9bfe7afb4 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -6032,6 +6032,7 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) // note: sets viewangle, viewx, viewy, viewz R_SetupFrame(player, false); // This can stay false because it is only used to set viewsky in r_main.c, which isn't used here + framecount++; // timedemo // copy view cam position for local use dup_viewx = viewx; From 89c12a4ee838742b8cd27a28fc2f73a61238a4a0 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Thu, 27 Dec 2018 23:23:09 -0500 Subject: [PATCH 35/74] Reset timedemo counters after wipe --- src/d_main.c | 7 +++++++ src/g_game.c | 2 +- src/g_game.h | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/d_main.c b/src/d_main.c index dd2cfe0e5..481818754 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -483,6 +483,13 @@ static void D_Display(void) F_WipeEndScreen(); F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK); } + + // reset counters so timedemo doesn't count the wipe duration + if (timingdemo) + { + framecount = 0; + demostarttime = I_GetTime(); + } } NetUpdate(); // send out any new accumulation diff --git a/src/g_game.c b/src/g_game.c index 213c3b83e..273b582a4 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -97,7 +97,7 @@ UINT32 demoIdleTime = 3*TICRATE; boolean timingdemo; // if true, exit with report on completion boolean nodrawers; // for comparative timing purposes boolean noblit; // for comparative timing purposes -static tic_t demostarttime; // for comparative timing purposes +tic_t demostarttime; // for comparative timing purposes boolean netgame; // only true if packets are broadcast boolean multiplayer; diff --git a/src/g_game.h b/src/g_game.h index 5259eacbb..7260d3384 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -37,6 +37,7 @@ extern boolean playeringame[MAXPLAYERS]; // demoplaying back and demo recording extern boolean demoplayback, titledemo, demorecording, timingdemo; +extern tic_t demostarttime; // Quit after playing a demo from cmdline. extern boolean singledemo; From 56892c13ab47c6f681dc9df33e4d57795ed3fe0d Mon Sep 17 00:00:00 2001 From: mazmazz Date: Fri, 28 Dec 2018 22:59:54 -0500 Subject: [PATCH 36/74] Add framecount to timedemo message --- src/g_game.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index 273b582a4..800492d47 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -5660,7 +5660,7 @@ boolean G_CheckDemoStatus(void) timingdemo = false; f1 = (double)demotime; f2 = (double)framecount*TICRATE; - CONS_Printf(M_GetText("timed %u gametics in %d realtics\n%f seconds, %f avg fps\n"), leveltime,demotime,f1/TICRATE,f2/f1); + CONS_Printf(M_GetText("timed %u gametics in %d realtics - %u frames\n%f seconds, %f avg fps\n"), leveltime,demotime,(UINT32)framecount,f1/TICRATE,f2/f1); if (restorecv_vidwait != cv_vidwait.value) CV_SetValue(&cv_vidwait, restorecv_vidwait); D_AdvanceDemo(); From b3908755afc96e14e96d637402d586fc7cf6a600 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 29 Dec 2018 04:51:00 -0500 Subject: [PATCH 37/74] Add CSV functionality to timedemo * Append timedemo trials to timedemo.csv * Specify -csv to toggle CSV behavior * Specify -quit to immediately quit after timedemo * Add ticrate, rendermode, video mode, demo name, bits to CSV timedemo row --- src/d_clisrv.c | 7 ++++++- src/d_netcmd.c | 28 ++++++++++++++++++++++------ src/d_netcmd.h | 5 +++++ src/g_game.c | 41 ++++++++++++++++++++++++++++++++++++++++- 4 files changed, 73 insertions(+), 8 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 2529b05d0..0fb903ff9 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -4596,7 +4596,12 @@ void TryRunTics(tic_t realtics) if (neededtic > gametic) { if (advancedemo) - D_StartTitle(); + { + if (timedemo_quit) + COM_ImmedExecute("quit"); + else + D_StartTitle(); + } else // run the count * tics while (neededtic > gametic) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 11b9413a8..d1101a69d 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -364,6 +364,11 @@ consvar_t cv_mute = {"mute", "Off", CV_NETVAR|CV_CALL, CV_OnOff, Mute_OnChange, consvar_t cv_sleep = {"cpusleep", "-1", CV_SAVE, sleeping_cons_t, NULL, -1, NULL, NULL, 0, 0, NULL}; +char timedemo_name[256]; +boolean timedemo_csv; +char timedemo_csv_id[256]; +boolean timedemo_quit; + INT16 gametype = GT_COOP; boolean splitscreen = false; boolean circuitmap = false; @@ -1479,11 +1484,11 @@ static void Command_Playdemo_f(void) static void Command_Timedemo_f(void) { - char name[256]; + size_t i = 0; - if (COM_Argc() != 2) + if (COM_Argc() < 2) { - CONS_Printf(M_GetText("timedemo : time a demo\n")); + CONS_Printf(M_GetText("timedemo [-csv []] [-quit]: time a demo\n")); return; } @@ -1500,12 +1505,23 @@ static void Command_Timedemo_f(void) G_StopMetalDemo(); // open the demo file - strcpy (name, COM_Argv(1)); + strcpy (timedemo_name, COM_Argv(1)); // dont add .lmp so internal game demos can be played - CONS_Printf(M_GetText("Timing demo '%s'.\n"), name); + // print timedemo results as CSV? + i = COM_CheckParm("-csv"); + timedemo_csv = (i > 0); + if (COM_CheckParm("-quit") != i + 1) + strcpy(timedemo_csv_id, COM_Argv(i + 1)); // user-defined string to identify row + else + timedemo_csv_id[0] = 0; - G_TimeDemo(name); + // exit after the timedemo? + timedemo_quit = (COM_CheckParm("-quit") > 0); + + CONS_Printf(M_GetText("Timing demo '%s'.\n"), timedemo_name); + + G_TimeDemo(timedemo_name); } // stop current demo diff --git a/src/d_netcmd.h b/src/d_netcmd.h index b82065c82..505434541 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -111,6 +111,11 @@ extern consvar_t cv_skipmapcheck; extern consvar_t cv_sleep; +extern char timedemo_name[256]; +extern boolean timedemo_csv; +extern char timedemo_csv_id[256]; +extern boolean timedemo_quit; + typedef enum { XD_NAMEANDCOLOR = 1, diff --git a/src/g_game.c b/src/g_game.c index 800492d47..93342c1f3 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -5660,7 +5660,46 @@ boolean G_CheckDemoStatus(void) timingdemo = false; f1 = (double)demotime; f2 = (double)framecount*TICRATE; - CONS_Printf(M_GetText("timed %u gametics in %d realtics - %u frames\n%f seconds, %f avg fps\n"), leveltime,demotime,(UINT32)framecount,f1/TICRATE,f2/f1); + + CONS_Printf(M_GetText("timed %u gametics in %d realtics - %u frames\n%f seconds, %f avg fps\n"), + leveltime,demotime,(UINT32)framecount,f1/TICRATE,f2/f1); + + // CSV-readable timedemo results, for external parsing + if (timedemo_csv) + { + FILE *f; + const char *csvpath = va("%s"PATHSEP"%s", srb2home, "timedemo.csv"); + const char *header = "id,demoname,seconds,avgfps,leveltime,demotime,framecount,ticrate,rendermode,vidmode,vidwidth,vidheight,procbits\n"; + const char *rowformat = "\"%s\",\"%s\",%f,%f,%u,%d,%u,%u,%u,%u,%u,%u,%u\n"; + boolean headerrow = !FIL_FileExists(csvpath); + UINT8 procbits = 0; + + // Bitness + if (sizeof(void*) == 4) + procbits = 32; + else if (sizeof(void*) == 8) + procbits = 64; + + f = fopen(csvpath, "a+"); + + if (f) + { + if (headerrow) + fputs(header, f); + fprintf(f, rowformat, + timedemo_csv_id,timedemo_name,f1/TICRATE,f2/f1,leveltime,demotime,(UINT32)framecount,TICRATE,rendermode,vid.modenum,vid.width,vid.height,procbits); + fclose(f); + CONS_Printf("Timedemo results saved to '%s'\n", csvpath); + } + else + { + // Just print the CSV output to console + CON_LogMessage(header); + CONS_Printf(rowformat, + timedemo_csv_id,timedemo_name,f1/TICRATE,f2/f1,leveltime,demotime,(UINT32)framecount,TICRATE,rendermode,vid.modenum,vid.width,vid.height,procbits); + } + } + if (restorecv_vidwait != cv_vidwait.value) CV_SetValue(&cv_vidwait, restorecv_vidwait); D_AdvanceDemo(); From 908a6d321de246724675624a1e58c4a40a361120 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Wed, 2 Jan 2019 23:31:29 -0500 Subject: [PATCH 38/74] Un-dummy md5 checks --- src/w_wad.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/w_wad.c b/src/w_wad.c index fdab8962b..88e89974a 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -1572,12 +1572,12 @@ void W_VerifyFileMD5(UINT16 wadfilenum, const char *matchmd5) { char actualmd5text[2*MD5_LEN+1]; PrintMD5String(wadfiles[wadfilenum]->md5sum, actualmd5text); -/*#ifdef _DEBUG +#ifdef _DEBUG CONS_Printf #else I_Error #endif - (M_GetText("File is corrupt or has been modified: %s (found md5: %s, wanted: %s)\n"), wadfiles[wadfilenum]->filename, actualmd5text, matchmd5);*/ + (M_GetText("File is corrupt or has been modified: %s (found md5: %s, wanted: %s)\n"), wadfiles[wadfilenum]->filename, actualmd5text, matchmd5); } #endif } From bbcc82e9b4fef423a8fad0112337d20c167c15c4 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Thu, 3 Jan 2019 00:57:14 -0500 Subject: [PATCH 39/74] Fix blinking MD2 models MD2 models are forced to load float frames, so mesh->indices is never loaded, so glDrawElements can't be used. Use glDrawArrays instead. --- src/hardware/r_opengl/r_opengl.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index ce4465644..2dba9980a 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1895,7 +1895,9 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 pglNormalPointer(GL_FLOAT, sizeof(vbo64_t), BUFFER_OFFSET(sizeof(float) * 3)); pglTexCoordPointer(2, GL_FLOAT, sizeof(vbo64_t), BUFFER_OFFSET(sizeof(float) * 6)); - pglDrawElements(GL_TRIANGLES, mesh->numTriangles * 3, GL_UNSIGNED_SHORT, mesh->indices); + pglDrawArrays(GL_TRIANGLES, 0, mesh->numTriangles * 3); + // No tinyframes, no mesh indices + //pglDrawElements(GL_TRIANGLES, mesh->numTriangles * 3, GL_UNSIGNED_SHORT, mesh->indices); pglBindBuffer(GL_ARRAY_BUFFER, 0); } else From a3fd5e7247599bbf12479f425ec399ef020ba0ea Mon Sep 17 00:00:00 2001 From: mazmazz Date: Fri, 4 Jan 2019 11:31:20 -0500 Subject: [PATCH 40/74] Revert "Un-dummy md5 checks" This reverts commit 908a6d321de246724675624a1e58c4a40a361120. --- src/w_wad.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/w_wad.c b/src/w_wad.c index 88e89974a..fdab8962b 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -1572,12 +1572,12 @@ void W_VerifyFileMD5(UINT16 wadfilenum, const char *matchmd5) { char actualmd5text[2*MD5_LEN+1]; PrintMD5String(wadfiles[wadfilenum]->md5sum, actualmd5text); -#ifdef _DEBUG +/*#ifdef _DEBUG CONS_Printf #else I_Error #endif - (M_GetText("File is corrupt or has been modified: %s (found md5: %s, wanted: %s)\n"), wadfiles[wadfilenum]->filename, actualmd5text, matchmd5); + (M_GetText("File is corrupt or has been modified: %s (found md5: %s, wanted: %s)\n"), wadfiles[wadfilenum]->filename, actualmd5text, matchmd5);*/ } #endif } From d05caf59632e039c64f1421a514026d5825cc242 Mon Sep 17 00:00:00 2001 From: Digiku Date: Tue, 8 Jan 2019 11:26:39 -0500 Subject: [PATCH 41/74] Update hw_md2.c -- add comment about anglef player->frameangle from Kart --- src/hardware/hw_md2.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 0cd4e97e2..8bc33ea0f 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1075,7 +1075,14 @@ void HWR_DrawMD2(gr_vissprite_t *spr) if (sprframe->rotate) { - const fixed_t anglef = AngleFixed(spr->mobj->angle); + fixed_t anglef = AngleFixed(spr->mobj->angle); + // \todo adapt for 2.2 directionchar? The below code is from Kart +#if 0 + if (spr->mobj->player) + anglef = AngleFixed(spr->mobj->player->frameangle); + else + anglef = AngleFixed(spr->mobj->angle); +#endif p.angley = FIXED_TO_FLOAT(anglef); } else From 79fed1e954ce77fabb2f09573e2fcd00d6326cef Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 2 May 2019 17:49:10 -0400 Subject: [PATCH 42/74] Unbind VBO from model during mid-frame --- src/hardware/r_opengl/r_opengl.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 2dba9980a..5caa31e29 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1632,6 +1632,10 @@ static void CreateModelVBO(mesh_t *mesh, mdlframe_t *frame) pglBindBuffer(GL_ARRAY_BUFFER, frame->vboID); pglBufferData(GL_ARRAY_BUFFER, bufferSize, buffer, GL_STATIC_DRAW); free(buffer); + + // Don't leave the array buffer bound to the model, + // since this is called mid-frame + pglBindBuffer(GL_ARRAY_BUFFER, 0); } static void CreateModelVBOTiny(mesh_t *mesh, tinyframe_t *frame) @@ -1673,6 +1677,11 @@ static void CreateModelVBOTiny(mesh_t *mesh, tinyframe_t *frame) pglBindBuffer(GL_ARRAY_BUFFER, frame->vboID); pglBufferData(GL_ARRAY_BUFFER, bufferSize, buffer, GL_STATIC_DRAW); free(buffer); + + // Don't leave the array buffer bound to the model, + // since this is called mid-frame + pglBindBuffer(GL_ARRAY_BUFFER, 0); +} } EXPORT void HWRAPI(CreateModelVBOs) (model_t *model) From 39c422506e11b594240cfbed0779d44a9ebe66f5 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 2 May 2019 17:55:43 -0400 Subject: [PATCH 43/74] Unbind VBO from model during mid-frame https://git.magicalgirl.moe/STJr/SRB2/merge_requests/397?commit_id=79fed1e954ce77fabb2f09573e2fcd00d6326cef#note_11536 --- src/hardware/r_opengl/r_opengl.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 2dba9980a..816c4758c 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1632,6 +1632,10 @@ static void CreateModelVBO(mesh_t *mesh, mdlframe_t *frame) pglBindBuffer(GL_ARRAY_BUFFER, frame->vboID); pglBufferData(GL_ARRAY_BUFFER, bufferSize, buffer, GL_STATIC_DRAW); free(buffer); + + // Don't leave the array buffer bound to the model, + // since this is called mid-frame + pglBindBuffer(GL_ARRAY_BUFFER, 0); } static void CreateModelVBOTiny(mesh_t *mesh, tinyframe_t *frame) @@ -1673,6 +1677,10 @@ static void CreateModelVBOTiny(mesh_t *mesh, tinyframe_t *frame) pglBindBuffer(GL_ARRAY_BUFFER, frame->vboID); pglBufferData(GL_ARRAY_BUFFER, bufferSize, buffer, GL_STATIC_DRAW); free(buffer); + + // Don't leave the array buffer bound to the model, + // since this is called mid-frame + pglBindBuffer(GL_ARRAY_BUFFER, 0); } EXPORT void HWRAPI(CreateModelVBOs) (model_t *model) From 6aac014608fb33d5b5549601b77a96854b3b8ec6 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Thu, 2 May 2019 22:55:45 -0400 Subject: [PATCH 44/74] Generic model terminology --- src/hardware/hw_main.c | 6 +++--- src/hardware/hw_main.h | 2 +- src/hardware/hw_md2.c | 36 ++++++++++++++++++------------------ src/r_main.c | 2 +- src/v_video.c | 2 +- 5 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 77eb16ce1..9938ea0a9 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5246,14 +5246,14 @@ static void HWR_DrawSprites(void) #endif if (spr->mobj && spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) { - if (!cv_grmd2.value || md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound || md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale < 0.0f) + if (!cv_grmdls.value || md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound || md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale < 0.0f) HWR_DrawSprite(spr); else HWR_DrawMD2(spr); } else { - if (!cv_grmd2.value || md2_models[spr->mobj->sprite].notfound || md2_models[spr->mobj->sprite].scale < 0.0f) + if (!cv_grmdls.value || md2_models[spr->mobj->sprite].notfound || md2_models[spr->mobj->sprite].scale < 0.0f) HWR_DrawSprite(spr); else HWR_DrawMD2(spr); @@ -5377,7 +5377,7 @@ static void HWR_ProjectSprite(mobj_t *thing) tz = (tr_x * gr_viewcos) + (tr_y * gr_viewsin); // thing is behind view plane? - if (tz < ZCLIP_PLANE && (!cv_grmd2.value || md2_models[thing->sprite].notfound == true)) //Yellow: Only MD2's dont disappear + if (tz < ZCLIP_PLANE && (!cv_grmdls.value || md2_models[thing->sprite].notfound == true)) //Yellow: Only MD2's dont disappear return; // The above can stay as it works for cutting sprites that are too close diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index 4fee9dee9..4589e4fb0 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -80,7 +80,7 @@ extern consvar_t cv_grcoronas; extern consvar_t cv_grcoronasize; #endif extern consvar_t cv_grfov; -extern consvar_t cv_grmd2; +extern consvar_t cv_grmdls; extern consvar_t cv_grfog; extern consvar_t cv_grfogcolor; extern consvar_t cv_grfogdensity; diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 8bc33ea0f..4bb86cdf1 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -159,7 +159,7 @@ static GrTextureFormat_t PNG_Load(const char *filename, int *w, int *h, GLPatch_ #endif png_FILE_p png_FILE; //Filename checking fixed ~Monster Iestyn and Golden - char *pngfilename = va("%s"PATHSEP"md2"PATHSEP"%s", srb2home, filename); + char *pngfilename = va("%s"PATHSEP"mdls"PATHSEP"%s", srb2home, filename); FIL_ForceExtension(pngfilename, ".png"); png_FILE = fopen(pngfilename, "rb"); @@ -288,7 +288,7 @@ static GrTextureFormat_t PCX_Load(const char *filename, int *w, int *h, INT32 ch, rep; FILE *file; //Filename checking fixed ~Monster Iestyn and Golden - char *pcxfilename = va("%s"PATHSEP"md2"PATHSEP"%s", srb2home, filename); + char *pcxfilename = va("%s"PATHSEP"mdls"PATHSEP"%s", srb2home, filename); FIL_ForceExtension(pcxfilename, ".pcx"); file = fopen(pcxfilename, "rb"); @@ -477,13 +477,13 @@ void HWR_InitMD2(void) md2_models[i].error = false; } - // read the md2.dat file + // read the mdls.dat file //Filename checking fixed ~Monster Iestyn and Golden - f = fopen(va("%s"PATHSEP"%s", srb2home, "md2.dat"), "rt"); + f = fopen(va("%s"PATHSEP"%s", srb2home, "mdls.dat"), "rt"); if (!f) { - CONS_Printf("%s %s\n", M_GetText("Error while loading md2.dat:"), strerror(errno)); + CONS_Printf("%s %s\n", M_GetText("Error while loading mdls.dat:"), strerror(errno)); nomd2s = true; return; } @@ -491,7 +491,7 @@ void HWR_InitMD2(void) { if (stricmp(name, "PLAY") == 0) { - CONS_Printf("MD2 for sprite PLAY detected in md2.dat, use a player skin instead!\n"); + CONS_Printf("MD2 for sprite PLAY detected in mdls.dat, use a player skin instead!\n"); continue; } @@ -525,7 +525,7 @@ void HWR_InitMD2(void) } } // no sprite/player skin name found?!? - CONS_Printf("Unknown sprite/player skin %s detected in md2.dat\n", name); + CONS_Printf("Unknown sprite/player skin %s detected in mdls.dat\n", name); md2found: // move on to next line... continue; @@ -544,13 +544,13 @@ void HWR_AddPlayerMD2(int skin) // For MD2's that were added after startup CONS_Printf("AddPlayerMD2()...\n"); - // read the md2.dat file + // read the mdls.dat file //Filename checking fixed ~Monster Iestyn and Golden - f = fopen(va("%s"PATHSEP"%s", srb2home, "md2.dat"), "rt"); + f = fopen(va("%s"PATHSEP"%s", srb2home, "mdls.dat"), "rt"); if (!f) { - CONS_Printf("Error while loading md2.dat\n"); + CONS_Printf("Error while loading mdls.dat\n"); nomd2s = true; return; } @@ -579,7 +579,7 @@ playermd2found: void HWR_AddSpriteMD2(size_t spritenum) // For MD2s that were added after startup { FILE *f; - // name[18] is used to check for names in the md2.dat file that match with sprites or player skins + // name[18] is used to check for names in the mdls.dat file that match with sprites or player skins // sprite names are always 4 characters long, and names is for player skins can be up to 19 characters long char name[18], filename[32]; float scale, offset; @@ -590,13 +590,13 @@ void HWR_AddSpriteMD2(size_t spritenum) // For MD2s that were added after startu if (spritenum == SPR_PLAY) // Handled already NEWMD2: Per sprite, per-skin check return; - // Read the md2.dat file + // Read the mdls.dat file //Filename checking fixed ~Monster Iestyn and Golden - f = fopen(va("%s"PATHSEP"%s", srb2home, "md2.dat"), "rt"); + f = fopen(va("%s"PATHSEP"%s", srb2home, "mdls.dat"), "rt"); if (!f) { - CONS_Printf("Error while loading md2.dat\n"); + CONS_Printf("Error while loading mdls.dat\n"); nomd2s = true; return; } @@ -895,7 +895,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) md2_t *md2; UINT8 color[4]; - if (!cv_grmd2.value) + if (!cv_grmdls.value) return; if (spr->precip) @@ -974,8 +974,8 @@ void HWR_DrawMD2(gr_vissprite_t *spr) return; // we already failed loading this before :( if (!md2->model) { - //CONS_Debug(DBG_RENDER, "Loading MD2... (%s)", sprnames[spr->mobj->sprite]); - sprintf(filename, "md2/%s", md2->filename); + //CONS_Debug(DBG_RENDER, "Loading model... (%s)", sprnames[spr->mobj->sprite]); + sprintf(filename, "mdls/%s", md2->filename); md2->model = md2_readModel(filename); if (md2->model) @@ -1034,7 +1034,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) frame = (spr->mobj->frame & FF_FRAMEMASK) % md2->model->meshes[0].numFrames; #ifdef USE_MODEL_NEXTFRAME - if (cv_grmd2.value == 1 && tics <= durs) + if (cv_grmdls.value == 1 && tics <= durs) { // frames are handled differently for states with FF_ANIMATE, so get the next frame differently for the interpolation if (spr->mobj->frame & FF_ANIMATE) diff --git a/src/r_main.c b/src/r_main.c index e543145bb..194fbd5b7 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1405,7 +1405,7 @@ void R_RegisterEngineStuff(void) CV_RegisterVar(&cv_grcoronas); CV_RegisterVar(&cv_grcoronasize); #endif - CV_RegisterVar(&cv_grmd2); + CV_RegisterVar(&cv_grmdls); #endif #ifdef HWRENDER diff --git a/src/v_video.c b/src/v_video.c index 03ac7a1d2..c06402eb6 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -79,7 +79,7 @@ consvar_t cv_grcoronasize = {"gr_coronasize", "1", CV_SAVE| CV_FLOAT, 0, NULL, 0 static CV_PossibleValue_t CV_MD2[] = {{0, "Off"}, {1, "On"}, {2, "Old"}, {0, NULL}}; // console variables in development -consvar_t cv_grmd2 = {"gr_md2", "Off", CV_SAVE, CV_MD2, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_grmdls = {"gr_mdls", "Off", CV_SAVE, CV_MD2, NULL, 0, NULL, NULL, 0, 0, NULL}; #endif const UINT8 gammatable[5][256] = From b1f402538f6df1139d4b7e19b83805ad47eb33ee Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sun, 4 Aug 2019 21:32:41 -0400 Subject: [PATCH 45/74] Post-merge fixes (todo: spr2) --- src/hardware/hw_md2.c | 69 +++++++++++++++---------------------------- 1 file changed, 24 insertions(+), 45 deletions(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index f0783bfe4..0f1c89b99 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -860,13 +860,8 @@ void HWR_DrawMD2(gr_vissprite_t *spr) GLPatch_t *gpatch; INT32 durs = spr->mobj->state->tics; INT32 tics = spr->mobj->tics; -<<<<<<< HEAD //mdlframe_t *next = NULL; const UINT8 flip = (UINT8)((spr->mobj->eflags & MFE_VERTICALFLIP) == MFE_VERTICALFLIP); -======= - md2_frame_t *curr, *next = NULL; - const UINT8 flip = (UINT8)(!(spr->mobj->eflags & MFE_VERTICALFLIP) != !(spr->mobj->frame & FF_VERTICALFLIP)); ->>>>>>> origin/master spritedef_t *sprdef; spriteframe_t *sprframe; float finalscale; @@ -955,17 +950,10 @@ void HWR_DrawMD2(gr_vissprite_t *spr) tics = spr->mobj->anim_duration; } -<<<<<<< HEAD - //FIXME: this is not yet correct - frame = (spr->mobj->frame & FF_FRAMEMASK) % md2->model->meshes[0].numFrames; - -#ifdef USE_MODEL_NEXTFRAME - if (cv_grmdls.value == 1 && tics <= durs) -======= #define INTERPOLERATION_LIMIT TICRATE/4 +#if 0 if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY && md2->model->spr2frames) ->>>>>>> origin/master { UINT8 spr2 = P_GetModelSprite2(md2, spr->mobj->skin, spr->mobj->sprite2, spr->mobj->player); UINT8 mod = md2->model->spr2frames[spr2*2 + 1] ? md2->model->spr2frames[spr2*2 + 1] : md2->model->header.numFrames; @@ -979,13 +967,6 @@ void HWR_DrawMD2(gr_vissprite_t *spr) curr = &md2->model->frames[md2->model->spr2frames[spr2*2] + frame]; if (cv_grmd2.value == 1 && tics <= durs && tics <= INTERPOLERATION_LIMIT) { -<<<<<<< HEAD - nextFrame = (spr->mobj->frame & FF_FRAMEMASK) + 1; - if (nextFrame >= spr->mobj->state->var1) - nextFrame = (spr->mobj->state->frame & FF_FRAMEMASK); - nextFrame %= md2->model->meshes[0].numFrames; - //next = &md2->model->meshes[0].frames[nextFrame]; -======= if (durs > INTERPOLERATION_LIMIT) durs = INTERPOLERATION_LIMIT; @@ -999,46 +980,38 @@ void HWR_DrawMD2(gr_vissprite_t *spr) if (frame || !(spr->mobj->state->frame & FF_SPR2ENDSTATE)) next = &md2->model->frames[md2->model->spr2frames[spr2*2] + frame]; } ->>>>>>> origin/master } } else +#endif { //FIXME: this is not yet correct - frame = (spr->mobj->frame & FF_FRAMEMASK) % md2->model->header.numFrames; - buff = md2->model->glCommandBuffer; - curr = &md2->model->frames[frame]; - if (cv_grmd2.value == 1 && tics <= durs && tics <= INTERPOLERATION_LIMIT) - { - if (durs > INTERPOLERATION_LIMIT) - durs = INTERPOLERATION_LIMIT; + frame = (spr->mobj->frame & FF_FRAMEMASK) % md2->model->meshes[0].numFrames; +#ifdef USE_MODEL_NEXTFRAME + if (cv_grmdls.value == 1 && tics <= durs) + { // frames are handled differently for states with FF_ANIMATE, so get the next frame differently for the interpolation if (spr->mobj->frame & FF_ANIMATE) { -<<<<<<< HEAD - nextFrame = (states[spr->mobj->state->nextstate].frame & FF_FRAMEMASK) % md2->model->meshes[0].numFrames; + nextFrame = (spr->mobj->frame & FF_FRAMEMASK) + 1; + if (nextFrame >= spr->mobj->state->var1) + nextFrame = (spr->mobj->state->frame & FF_FRAMEMASK); + nextFrame %= md2->model->meshes[0].numFrames; //next = &md2->model->meshes[0].frames[nextFrame]; -======= - UINT32 nextframe = (spr->mobj->frame & FF_FRAMEMASK) + 1; - if (nextframe >= (UINT32)spr->mobj->state->var1) - nextframe = (spr->mobj->state->frame & FF_FRAMEMASK); - nextframe %= md2->model->header.numFrames; - next = &md2->model->frames[nextframe]; ->>>>>>> origin/master } else { - if (spr->mobj->state->nextstate != S_NULL - && states[spr->mobj->state->nextstate].sprite == spr->mobj->sprite) + if (spr->mobj->state->nextstate != S_NULL && states[spr->mobj->state->nextstate].sprite != SPR_NULL + && !(spr->mobj->player && (spr->mobj->state->nextstate == S_PLAY_TAP1 || spr->mobj->state->nextstate == S_PLAY_TAP2) && spr->mobj->state == &states[S_PLAY_STND])) { - const UINT32 nextframe = (states[spr->mobj->state->nextstate].frame & FF_FRAMEMASK) % md2->model->header.numFrames; - next = &md2->model->frames[nextframe]; + nextFrame = (states[spr->mobj->state->nextstate].frame & FF_FRAMEMASK) % md2->model->meshes[0].numFrames; + //next = &md2->model->meshes[0].frames[nextFrame]; } } } - } #endif + } #undef INTERPOLERATION_LIMIT @@ -1046,13 +1019,13 @@ void HWR_DrawMD2(gr_vissprite_t *spr) p.x = FIXED_TO_FLOAT(spr->mobj->x); p.y = FIXED_TO_FLOAT(spr->mobj->y)+md2->offset; - if (flip) + if (spr->mobj->eflags & MFE_VERTICALFLIP) p.z = FIXED_TO_FLOAT(spr->mobj->z + spr->mobj->height); else p.z = FIXED_TO_FLOAT(spr->mobj->z); if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) - sprdef = &((skin_t *)spr->mobj->skin)->sprites[spr->mobj->sprite2]; + sprdef = &((skin_t *)spr->mobj->skin)->spritedef; else sprdef = &sprites[spr->mobj->sprite]; @@ -1060,7 +1033,13 @@ void HWR_DrawMD2(gr_vissprite_t *spr) if (sprframe->rotate) { - const fixed_t anglef = AngleFixed((spr->mobj->player ? spr->mobj->player->drawangle : spr->mobj->angle)); + fixed_t anglef = AngleFixed(spr->mobj->angle); + + if (spr->mobj->player) + anglef = AngleFixed(spr->mobj->player->frameangle); + else + anglef = AngleFixed(spr->mobj->angle); + p.angley = FIXED_TO_FLOAT(anglef); } else From e1e2572357a370384698bfbd049caa4b4aee39ee Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sun, 4 Aug 2019 21:49:31 -0400 Subject: [PATCH 46/74] More post-merge fixes --- src/hardware/hw_md2.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index f76730baa..27976ecdc 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -34,6 +34,7 @@ #include "hw_drv.h" #include "hw_light.h" #include "hw_md2.h" +#include "../d_main.h" #include "../r_bsp.h" #include "../r_main.h" #include "../m_misc.h" @@ -831,6 +832,7 @@ static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT run? */ +#if 0 static UINT8 P_GetModelSprite2(md2_t *md2, skin_t *skin, UINT8 spr2, player_t *player) { UINT8 super = 0, i = 0; @@ -881,6 +883,7 @@ static UINT8 P_GetModelSprite2(md2_t *md2, skin_t *skin, UINT8 spr2, player_t *p return spr2; } +#endif #define NORMALFOG 0x00000000 #define FADEFOG 0x19000000 @@ -1106,7 +1109,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) else { if (spr->mobj->state->nextstate != S_NULL && states[spr->mobj->state->nextstate].sprite != SPR_NULL - && !(spr->mobj->player && (spr->mobj->state->nextstate == S_PLAY_TAP1 || spr->mobj->state->nextstate == S_PLAY_TAP2) && spr->mobj->state == &states[S_PLAY_STND])) + && !(spr->mobj->player && (spr->mobj->state->nextstate == S_PLAY_WAIT) && spr->mobj->state == &states[S_PLAY_STND])) { nextFrame = (states[spr->mobj->state->nextstate].frame & FF_FRAMEMASK) % md2->model->meshes[0].numFrames; //next = &md2->model->meshes[0].frames[nextFrame]; @@ -1128,7 +1131,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) p.z = FIXED_TO_FLOAT(spr->mobj->z); if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) - sprdef = &((skin_t *)spr->mobj->skin)->spritedef; + sprdef = &((skin_t *)spr->mobj->skin)->sprites[spr->mobj->sprite2]; else sprdef = &sprites[spr->mobj->sprite]; @@ -1139,7 +1142,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) fixed_t anglef = AngleFixed(spr->mobj->angle); if (spr->mobj->player) - anglef = AngleFixed(spr->mobj->player->frameangle); + anglef = AngleFixed(spr->mobj->player->drawangle); else anglef = AngleFixed(spr->mobj->angle); From c21d83e8af4e3d6f8e0f47d61d14472a235b8d42 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 2 Sep 2019 23:29:16 -0300 Subject: [PATCH 47/74] Sprite2 support! --- src/hardware/hw_main.c | 6 +- src/hardware/hw_main.h | 2 +- src/hardware/hw_md2.c | 157 ++++++++++++++--------------------------- src/r_main.c | 2 +- src/v_video.c | 2 +- 5 files changed, 58 insertions(+), 111 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 8c45fc57f..52da7433f 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5362,14 +5362,14 @@ static void HWR_DrawSprites(void) #endif if (spr->mobj && spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) { - if (!cv_grmdls.value || md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound || md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale < 0.0f) + if (!cv_grmodels.value || md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound || md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale < 0.0f) HWR_DrawSprite(spr); else HWR_DrawMD2(spr); } else { - if (!cv_grmdls.value || md2_models[spr->mobj->sprite].notfound || md2_models[spr->mobj->sprite].scale < 0.0f) + if (!cv_grmodels.value || md2_models[spr->mobj->sprite].notfound || md2_models[spr->mobj->sprite].scale < 0.0f) HWR_DrawSprite(spr); else HWR_DrawMD2(spr); @@ -5490,7 +5490,7 @@ static void HWR_ProjectSprite(mobj_t *thing) tz = (tr_x * gr_viewcos) + (tr_y * gr_viewsin); // thing is behind view plane? - if (tz < ZCLIP_PLANE && !papersprite && (!cv_grmdls.value || md2_models[thing->sprite].notfound == true)) //Yellow: Only MD2's dont disappear + if (tz < ZCLIP_PLANE && !papersprite && (!cv_grmodels.value || md2_models[thing->sprite].notfound == true)) //Yellow: Only MD2's dont disappear return; // The above can stay as it works for cutting sprites that are too close diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index efed16cf5..67d022ec6 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -82,7 +82,7 @@ extern consvar_t cv_grcoronas; extern consvar_t cv_grcoronasize; #endif extern consvar_t cv_grfov; -extern consvar_t cv_grmdls; +extern consvar_t cv_grmodels; extern consvar_t cv_grfog; extern consvar_t cv_grfogcolor; extern consvar_t cv_grfogdensity; diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 3db7f1f86..3888dad85 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -160,7 +160,7 @@ static GrTextureFormat_t PNG_Load(const char *filename, int *w, int *h, GLPatch_ #endif png_FILE_p png_FILE; //Filename checking fixed ~Monster Iestyn and Golden - char *pngfilename = va("%s"PATHSEP"mdls"PATHSEP"%s", srb2home, filename); + char *pngfilename = va("%s"PATHSEP"models"PATHSEP"%s", srb2home, filename); FIL_ForceExtension(pngfilename, ".png"); png_FILE = fopen(pngfilename, "rb"); @@ -289,7 +289,7 @@ static GrTextureFormat_t PCX_Load(const char *filename, int *w, int *h, INT32 ch, rep; FILE *file; //Filename checking fixed ~Monster Iestyn and Golden - char *pcxfilename = va("%s"PATHSEP"mdls"PATHSEP"%s", srb2home, filename); + char *pcxfilename = va("%s"PATHSEP"models"PATHSEP"%s", srb2home, filename); FIL_ForceExtension(pcxfilename, ".pcx"); file = fopen(pcxfilename, "rb"); @@ -478,13 +478,13 @@ void HWR_InitMD2(void) md2_models[i].error = false; } - // read the mdls.dat file + // read the models.dat file //Filename checking fixed ~Monster Iestyn and Golden - f = fopen(va("%s"PATHSEP"%s", srb2home, "mdls.dat"), "rt"); + f = fopen(va("%s"PATHSEP"%s", srb2home, "models.dat"), "rt"); if (!f) { - CONS_Printf("%s %s\n", M_GetText("Error while loading mdls.dat:"), strerror(errno)); + CONS_Printf("%s %s\n", M_GetText("Error while loading models.dat:"), strerror(errno)); nomd2s = true; return; } @@ -492,7 +492,7 @@ void HWR_InitMD2(void) { if (stricmp(name, "PLAY") == 0) { - CONS_Printf("MD2 for sprite PLAY detected in mdls.dat, use a player skin instead!\n"); + CONS_Printf("MD2 for sprite PLAY detected in models.dat, use a player skin instead!\n"); continue; } @@ -526,7 +526,7 @@ void HWR_InitMD2(void) } } // no sprite/player skin name found?!? - CONS_Printf("Unknown sprite/player skin %s detected in mdls.dat\n", name); + CONS_Printf("Unknown sprite/player skin %s detected in models.dat\n", name); md2found: // move on to next line... continue; @@ -545,13 +545,13 @@ void HWR_AddPlayerMD2(int skin) // For MD2's that were added after startup CONS_Printf("AddPlayerMD2()...\n"); - // read the mdls.dat file + // read the models.dat file //Filename checking fixed ~Monster Iestyn and Golden - f = fopen(va("%s"PATHSEP"%s", srb2home, "mdls.dat"), "rt"); + f = fopen(va("%s"PATHSEP"%s", srb2home, "models.dat"), "rt"); if (!f) { - CONS_Printf("Error while loading mdls.dat\n"); + CONS_Printf("Error while loading models.dat\n"); nomd2s = true; return; } @@ -580,7 +580,7 @@ playermd2found: void HWR_AddSpriteMD2(size_t spritenum) // For MD2s that were added after startup { FILE *f; - // name[18] is used to check for names in the mdls.dat file that match with sprites or player skins + // name[18] is used to check for names in the models.dat file that match with sprites or player skins // sprite names are always 4 characters long, and names is for player skins can be up to 19 characters long char name[18], filename[32]; float scale, offset; @@ -591,13 +591,13 @@ void HWR_AddSpriteMD2(size_t spritenum) // For MD2s that were added after startu if (spritenum == SPR_PLAY) // Handled already NEWMD2: Per sprite, per-skin check return; - // Read the mdls.dat file + // Read the models.dat file //Filename checking fixed ~Monster Iestyn and Golden - f = fopen(va("%s"PATHSEP"%s", srb2home, "mdls.dat"), "rt"); + f = fopen(va("%s"PATHSEP"%s", srb2home, "models.dat"), "rt"); if (!f) { - CONS_Printf("Error while loading mdls.dat\n"); + CONS_Printf("Error while loading models.dat\n"); nomd2s = true; return; } @@ -832,58 +832,25 @@ static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT run? */ -#if 0 -static UINT8 P_GetModelSprite2(md2_t *md2, skin_t *skin, UINT8 spr2, player_t *player) +static UINT32 HWR_GetModelSprite2(mobj_t *mobj) { - UINT8 super = 0, i = 0; - - if (!md2 || !skin) - return 0; - - if ((unsigned)(spr2 & ~FF_SPR2SUPER) >= free_spr2) - return 0; - - while (!(md2->model->spr2frames[spr2*2 + 1]) - && spr2 != SPR2_STND - && ++i != 32) // recursion limiter + UINT8 spr2 = 0; + UINT32 frame = 0; + spritedef_t *sprdef; + while (spr2 != mobj->sprite2) { - if (spr2 & FF_SPR2SUPER) - { - super = FF_SPR2SUPER; - spr2 &= ~FF_SPR2SUPER; - continue; - } - - switch(spr2) - { - // Normal special cases. - case SPR2_JUMP: - spr2 = ((player - ? player->charflags - : skin->flags) - & SF_NOJUMPSPIN) ? SPR2_SPNG : SPR2_ROLL; - break; - case SPR2_TIRE: - spr2 = ((player - ? player->charability - : skin->ability) - == CA_SWIM) ? SPR2_SWIM : SPR2_FLY; - break; - // Use the handy list, that's what it's there for! - default: - spr2 = spr2defaults[spr2]; - break; - } - - spr2 |= super; + sprdef = &((skin_t *)mobj->skin)->sprites[spr2]; + frame += sprdef->numframes; + spr2++; } - - if (i >= 32) // probably an infinite loop... - return 0; - - return spr2; + return frame; +} + +static boolean HWR_CanInterpolateModel(mobj_t *mobj) +{ + return (!(mobj->state->nextstate == S_PLAY_WAIT && mobj->state == &states[S_PLAY_STND])) + && (mobj->state != &states[S_PLAY_ROLL]); } -#endif #define NORMALFOG 0x00000000 #define FADEFOG 0x19000000 @@ -898,7 +865,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) md2_t *md2; UINT8 color[4]; - if (!cv_grmdls.value) + if (!cv_grmodels.value) return; if (spr->precip) @@ -978,7 +945,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) if (!md2->model) { //CONS_Debug(DBG_RENDER, "Loading model... (%s)", sprnames[spr->mobj->sprite]); - sprintf(filename, "mdls/%s", md2->filename); + sprintf(filename, "models/%s", md2->filename); md2->model = md2_readModel(filename); if (md2->model) @@ -1056,46 +1023,28 @@ void HWR_DrawMD2(gr_vissprite_t *spr) tics = spr->mobj->anim_duration; } -#define INTERPOLERATION_LIMIT TICRATE/4 - -#if 0 - if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY && md2->model->spr2frames) - { - UINT8 spr2 = P_GetModelSprite2(md2, spr->mobj->skin, spr->mobj->sprite2, spr->mobj->player); - UINT8 mod = md2->model->spr2frames[spr2*2 + 1] ? md2->model->spr2frames[spr2*2 + 1] : md2->model->header.numFrames; - if (mod > ((skin_t *)spr->mobj->skin)->sprites[spr2].numframes) - mod = ((skin_t *)spr->mobj->skin)->sprites[spr2].numframes; - //FIXME: this is not yet correct - frame = (spr->mobj->frame & FF_FRAMEMASK); - if (frame >= mod) - frame = 0; - buff = md2->model->glCommandBuffer; - curr = &md2->model->frames[md2->model->spr2frames[spr2*2] + frame]; - if (cv_grmd2.value == 1 && tics <= durs && tics <= INTERPOLERATION_LIMIT) - { - if (durs > INTERPOLERATION_LIMIT) - durs = INTERPOLERATION_LIMIT; - - if (spr->mobj->frame & FF_ANIMATE - || (spr->mobj->state->nextstate != S_NULL - && states[spr->mobj->state->nextstate].sprite == spr->mobj->sprite - && (states[spr->mobj->state->nextstate].frame & FF_FRAMEMASK) == spr->mobj->sprite2)) - { - if (++frame >= mod) - frame = 0; - if (frame || !(spr->mobj->state->frame & FF_SPR2ENDSTATE)) - next = &md2->model->frames[md2->model->spr2frames[spr2*2] + frame]; - } - } - } - else -#endif - { - //FIXME: this is not yet correct - frame = (spr->mobj->frame & FF_FRAMEMASK) % md2->model->meshes[0].numFrames; + //FIXME: this is not yet correct + frame = (spr->mobj->frame & FF_FRAMEMASK); + if (spr->mobj->sprite2) + frame = HWR_GetModelSprite2(spr->mobj) + frame; + frame %= md2->model->meshes[0].numFrames; #ifdef USE_MODEL_NEXTFRAME - if (cv_grmdls.value == 1 && tics <= durs) + if (cv_grmodels.value == 1 && tics <= durs) + { + if (spr->mobj->sprite2) + { + if (HWR_CanInterpolateModel(spr->mobj)) + { + UINT32 framecount = (&((skin_t *)spr->mobj->skin)->sprites[spr->mobj->sprite2])->numframes; + nextFrame = (spr->mobj->frame & FF_FRAMEMASK) + 1; + if (nextFrame >= framecount) + nextFrame = 0; + nextFrame = HWR_GetModelSprite2(spr->mobj) + nextFrame; + nextFrame %= md2->model->meshes[0].numFrames; + } + } + else { // frames are handled differently for states with FF_ANIMATE, so get the next frame differently for the interpolation if (spr->mobj->frame & FF_ANIMATE) @@ -1116,10 +1065,8 @@ void HWR_DrawMD2(gr_vissprite_t *spr) } } } -#endif } - -#undef INTERPOLERATION_LIMIT +#endif //Hurdler: it seems there is still a small problem with mobj angle p.x = FIXED_TO_FLOAT(spr->mobj->x); diff --git a/src/r_main.c b/src/r_main.c index 703993fc9..8032e2d78 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1212,7 +1212,7 @@ void R_RegisterEngineStuff(void) CV_RegisterVar(&cv_grcoronas); CV_RegisterVar(&cv_grcoronasize); #endif - CV_RegisterVar(&cv_grmdls); + CV_RegisterVar(&cv_grmodels); CV_RegisterVar(&cv_grspritebillboarding); #endif diff --git a/src/v_video.c b/src/v_video.c index 81f501a7a..ca95cfc62 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -109,7 +109,7 @@ consvar_t cv_grcoronasize = {"gr_coronasize", "1", CV_SAVE| CV_FLOAT, 0, NULL, 0 static CV_PossibleValue_t CV_MD2[] = {{0, "Off"}, {1, "On"}, {2, "Old"}, {0, NULL}}; // console variables in development -consvar_t cv_grmdls = {"gr_mdls", "Off", CV_SAVE, CV_MD2, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_grmodels = {"gr_models", "Off", CV_SAVE, CV_MD2, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grspritebillboarding = {"gr_spritebillboarding", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; #endif From 1dca3338fde59b907afa792a768e1f3ba35bb1a2 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 3 Sep 2019 18:27:22 -0300 Subject: [PATCH 48/74] Sprite2 support but I'm not a dumbass --- src/hardware/hw_md2.c | 44 +++++++++----------- src/hardware/hw_md2load.c | 10 +++++ src/hardware/hw_md3load.c | 12 ++++++ src/hardware/hw_model.c | 84 ++++++++++++++++++++++++++++++++++++++- src/hardware/hw_model.h | 12 ++++++ src/p_setup.c | 5 +++ 6 files changed, 141 insertions(+), 26 deletions(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 3888dad85..07b06b967 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -810,7 +810,8 @@ static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT Z_ChangeTag(newmip->grInfo.data, PU_HWRCACHE_UNLOCKED); } - +#define NORMALFOG 0x00000000 +#define FADEFOG 0x19000000 // -----------------+ // HWR_DrawMD2 : Draw MD2 @@ -832,28 +833,12 @@ static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT run? */ -static UINT32 HWR_GetModelSprite2(mobj_t *mobj) -{ - UINT8 spr2 = 0; - UINT32 frame = 0; - spritedef_t *sprdef; - while (spr2 != mobj->sprite2) - { - sprdef = &((skin_t *)mobj->skin)->sprites[spr2]; - frame += sprdef->numframes; - spr2++; - } - return frame; -} - static boolean HWR_CanInterpolateModel(mobj_t *mobj) { - return (!(mobj->state->nextstate == S_PLAY_WAIT && mobj->state == &states[S_PLAY_STND])) + return (!(mobj->state->nextstate == S_PLAY_WAIT && mobj->state == &states[S_PLAY_STND] && !(mobj->sprite2 & FF_SPR2SUPER))) && (mobj->state != &states[S_PLAY_ROLL]); } -#define NORMALFOG 0x00000000 -#define FADEFOG 0x19000000 void HWR_DrawMD2(gr_vissprite_t *spr) { FSurfaceInfo Surf; @@ -861,6 +846,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) char filename[64]; INT32 frame = 0; INT32 nextFrame = -1; + UINT8 spr2 = 0; FTransform p; md2_t *md2; UINT8 color[4]; @@ -1024,10 +1010,17 @@ void HWR_DrawMD2(gr_vissprite_t *spr) } //FIXME: this is not yet correct - frame = (spr->mobj->frame & FF_FRAMEMASK); if (spr->mobj->sprite2) - frame = HWR_GetModelSprite2(spr->mobj) + frame; - frame %= md2->model->meshes[0].numFrames; + { + spr2 = (spr->mobj->sprite2 & ~FF_SPR2SUPER); + frame = (spr->mobj->frame & FF_FRAMEMASK); + if (spr->mobj->sprite2 & FF_SPR2SUPER) + frame = md2->model->spr2frames[spr2].superframes[frame]; + else + frame = md2->model->spr2frames[spr2].frames[frame]; + } + else + frame = (spr->mobj->frame & FF_FRAMEMASK); #ifdef USE_MODEL_NEXTFRAME if (cv_grmodels.value == 1 && tics <= durs) @@ -1040,8 +1033,10 @@ void HWR_DrawMD2(gr_vissprite_t *spr) nextFrame = (spr->mobj->frame & FF_FRAMEMASK) + 1; if (nextFrame >= framecount) nextFrame = 0; - nextFrame = HWR_GetModelSprite2(spr->mobj) + nextFrame; - nextFrame %= md2->model->meshes[0].numFrames; + if (spr->mobj->sprite2 & FF_SPR2SUPER) + nextFrame = md2->model->spr2frames[spr2].superframes[nextFrame]; + else + nextFrame = md2->model->spr2frames[spr2].frames[nextFrame]; } } else @@ -1052,7 +1047,6 @@ void HWR_DrawMD2(gr_vissprite_t *spr) nextFrame = (spr->mobj->frame & FF_FRAMEMASK) + 1; if (nextFrame >= spr->mobj->state->var1) nextFrame = (spr->mobj->state->frame & FF_FRAMEMASK); - nextFrame %= md2->model->meshes[0].numFrames; //next = &md2->model->meshes[0].frames[nextFrame]; } else @@ -1060,7 +1054,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) if (spr->mobj->state->nextstate != S_NULL && states[spr->mobj->state->nextstate].sprite != SPR_NULL && !(spr->mobj->player && (spr->mobj->state->nextstate == S_PLAY_WAIT) && spr->mobj->state == &states[S_PLAY_STND])) { - nextFrame = (states[spr->mobj->state->nextstate].frame & FF_FRAMEMASK) % md2->model->meshes[0].numFrames; + nextFrame = (states[spr->mobj->state->nextstate].frame & FF_FRAMEMASK); //next = &md2->model->meshes[0].frames[nextFrame]; } } diff --git a/src/hardware/hw_md2load.c b/src/hardware/hw_md2load.c index 3805deffb..803573ade 100644 --- a/src/hardware/hw_md2load.c +++ b/src/hardware/hw_md2load.c @@ -252,6 +252,7 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) md2triangle_t *tris; md2texcoord_t *texcoords; md2frame_t *frames; + char *fname = NULL; int t; @@ -326,6 +327,15 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) texcoords = (md2texcoord_t*)&buffer[header->offsetST]; frames = (md2frame_t*)&buffer[header->offsetFrames]; + retModel->framenames = (char*)Z_Calloc(header->numFrames*16, ztag, 0); + fname = retModel->framenames; + for (i = 0; i < header->numFrames; i++) + { + memcpy(fname, frames->name, 16); + fname += 16; + frames++; + } + // Read in textures retModel->numMaterials = header->numSkins; diff --git a/src/hardware/hw_md3load.c b/src/hardware/hw_md3load.c index 53f6034c0..87931d27b 100644 --- a/src/hardware/hw_md3load.c +++ b/src/hardware/hw_md3load.c @@ -148,6 +148,8 @@ model_t *MD3_LoadModel(const char *fileName, int ztag, boolean useFloat) { const float WUNITS = 1.0f; model_t *retModel = NULL; + md3Frame *frames = NULL; + char *fname = NULL; md3modelHeader *mdh; long fileLen; long fileReadLen; @@ -227,6 +229,16 @@ model_t *MD3_LoadModel(const char *fileName, int ztag, boolean useFloat) retModel->meshes = (mesh_t*)Z_Calloc(sizeof(mesh_t)*retModel->numMeshes, ztag, 0); + frames = (md3Frame*)&buffer[mdh->offsetFrames]; + retModel->framenames = (char*)Z_Calloc(mdh->numFrames*16, ztag, 0); + fname = retModel->framenames; + for (i = 0; i < mdh->numFrames; i++) + { + memcpy(fname, frames->name, 16); + fname += 16; + frames++; + } + matCount = 0; for (i = 0, surfEnd = 0; i < mdh->numSurfaces; i++) { diff --git a/src/hardware/hw_model.c b/src/hardware/hw_model.c index 2c36f9744..dfbc4d54c 100644 --- a/src/hardware/hw_model.c +++ b/src/hardware/hw_model.c @@ -7,11 +7,14 @@ the licensing is for Sonic Robo Blast 2. */ -#include "../z_zone.h" #include "../doomdef.h" +#include "../doomtype.h" +#include "../info.h" +#include "../z_zone.h" #include "hw_model.h" #include "hw_md2load.h" #include "hw_md3load.h" +#include "hw_md2.h" #include "u_list.h" #include @@ -195,6 +198,7 @@ model_t *LoadModel(const char *filename, int ztag) Optimize(model); GeneratePolygonNormals(model, ztag); + LoadModelSprite2(model); // Default material properties for (i = 0 ; i < model->numMaterials; i++) @@ -218,6 +222,84 @@ model_t *LoadModel(const char *filename, int ztag) return model; } +void HWR_ReloadModels(void) +{ + size_t i; + INT32 s; + + for (s = 0; s < MAXSKINS; s++) + { + if (md2_playermodels[s].model) + LoadModelSprite2(md2_playermodels[s].model); + } + + for (i = 0; i < NUMSPRITES; i++) + { + if (md2_models[i].model) + LoadModelSprite2(md2_models[i].model); + } +} + +void LoadModelSprite2(model_t *model) +{ + INT32 i; + modelspr2frames_t *spr2frames = NULL; + INT32 numframes = model->meshes[0].numFrames; + char *framename = model->framenames; + + if (!framename) + return; + + for (i = 0; i < numframes; i++) + { + char prefix[6]; + char name[5]; + char framechar[3]; + UINT8 frame = 0; + UINT8 spr2idx; + + memset(&prefix, 0x00, 6); + memset(&name, 0x00, 5); + memset(&framechar, 0x00, 3); + + if (strlen(framename) >= 8) + { + char *modelframename = framename; + memcpy(&prefix, modelframename, 5); + modelframename += 5; + memcpy(&name, modelframename, 4); + modelframename += 4; + memcpy(&framechar, modelframename, 2); + frame = atoi(framechar); + + if ((!memcmp(prefix, "SPR2_", 5)) || (!memcmp(prefix, "SUPER", 5))) + { + spr2idx = 0; + while (spr2idx < NUMPLAYERSPRITES) + { + if (!memcmp(spr2names[spr2idx], name, 4)) + { + if (!spr2frames) + spr2frames = (modelspr2frames_t*)Z_Calloc(sizeof(modelspr2frames_t)*NUMPLAYERSPRITES, PU_STATIC, NULL); + if (!memcmp(prefix, "SUPER", 5)) + spr2frames[spr2idx].superframes[frame] = i; + else + spr2frames[spr2idx].frames[frame] = i; + break; + } + spr2idx++; + } + } + } + + framename += 16; + } + + if (model->spr2frames) + Z_Free(model->spr2frames); + model->spr2frames = spr2frames; +} + // // GenerateVertexNormals // diff --git a/src/hardware/hw_model.h b/src/hardware/hw_model.h index 1803f4c5c..af9020ef9 100644 --- a/src/hardware/hw_model.h +++ b/src/hardware/hw_model.h @@ -73,6 +73,12 @@ typedef struct tag_s // matrix_t transform; } tag_t; +typedef struct +{ + INT32 frames[256]; + INT32 superframes[256]; +} modelspr2frames_t; + typedef struct model_s { int maxNumFrames; @@ -86,15 +92,21 @@ typedef struct model_s char *mdlFilename; boolean unloaded; + + modelspr2frames_t *spr2frames; + char *framenames; } model_t; extern int numModels; extern model_t *modelHead; +void HWR_ReloadModels(void); + tag_t *GetTagByName(model_t *model, char *name, int frame); model_t *LoadModel(const char *filename, int ztag); void UnloadModel(model_t *model); void Optimize(model_t *model); +void LoadModelSprite2(model_t *model); void GenerateVertexNormals(model_t *model); void GeneratePolygonNormals(model_t *model, int ztag); void CreateVBOTiny(mesh_t *mesh, tinyframe_t *frame); diff --git a/src/p_setup.c b/src/p_setup.c index d0cd14b22..cb8f25457 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -75,6 +75,7 @@ #ifdef HWRENDER #include "hardware/hw_main.h" #include "hardware/hw_light.h" +#include "hardware/hw_model.h" #endif #ifdef ESLOPE @@ -3479,6 +3480,10 @@ boolean P_AddWadFile(const char *wadfilename) if (!mapsadded) CONS_Printf(M_GetText("No maps added\n")); +#ifdef HWRENDER + HWR_ReloadModels(); +#endif // HWRENDER + // reload status bar (warning should have valid player!) if (gamestate == GS_LEVEL) ST_Start(); From 916bdeb88057ce6f447093d1acc83d5f4d4770b0 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 3 Sep 2019 18:31:59 -0300 Subject: [PATCH 49/74] 3 digits frame number --- src/hardware/hw_model.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hardware/hw_model.c b/src/hardware/hw_model.c index dfbc4d54c..d4130df34 100644 --- a/src/hardware/hw_model.c +++ b/src/hardware/hw_model.c @@ -254,22 +254,22 @@ void LoadModelSprite2(model_t *model) { char prefix[6]; char name[5]; - char framechar[3]; + char framechar[4]; UINT8 frame = 0; UINT8 spr2idx; memset(&prefix, 0x00, 6); memset(&name, 0x00, 5); - memset(&framechar, 0x00, 3); + memset(&framechar, 0x00, 4); - if (strlen(framename) >= 8) + if (strlen(framename) >= 9) { char *modelframename = framename; memcpy(&prefix, modelframename, 5); modelframename += 5; memcpy(&name, modelframename, 4); modelframename += 4; - memcpy(&framechar, modelframename, 2); + memcpy(&framechar, modelframename, 3); frame = atoi(framechar); if ((!memcmp(prefix, "SPR2_", 5)) || (!memcmp(prefix, "SUPER", 5))) From 4760ff0963bc198b886282fffdb265da530daad5 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 3 Sep 2019 21:31:32 -0300 Subject: [PATCH 50/74] Crash prevention --- src/hardware/hw_md2.c | 4 ++-- src/hardware/hw_model.c | 8 -------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 07b06b967..158c07803 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1010,7 +1010,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) } //FIXME: this is not yet correct - if (spr->mobj->sprite2) + if (spr->mobj->sprite2 && md2->model->spr2frames) { spr2 = (spr->mobj->sprite2 & ~FF_SPR2SUPER); frame = (spr->mobj->frame & FF_FRAMEMASK); @@ -1025,7 +1025,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) #ifdef USE_MODEL_NEXTFRAME if (cv_grmodels.value == 1 && tics <= durs) { - if (spr->mobj->sprite2) + if (spr->mobj->sprite2 && md2->model->spr2frames) { if (HWR_CanInterpolateModel(spr->mobj)) { diff --git a/src/hardware/hw_model.c b/src/hardware/hw_model.c index d4130df34..63c8b8f34 100644 --- a/src/hardware/hw_model.c +++ b/src/hardware/hw_model.c @@ -224,20 +224,12 @@ model_t *LoadModel(const char *filename, int ztag) void HWR_ReloadModels(void) { - size_t i; INT32 s; - for (s = 0; s < MAXSKINS; s++) { if (md2_playermodels[s].model) LoadModelSprite2(md2_playermodels[s].model); } - - for (i = 0; i < NUMSPRITES; i++) - { - if (md2_models[i].model) - LoadModelSprite2(md2_models[i].model); - } } void LoadModelSprite2(model_t *model) From 53ddf19f94fcf2630d1ee489fe13e3ffbf896e8f Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 3 Sep 2019 22:57:54 -0300 Subject: [PATCH 51/74] Interpolation flag support --- src/hardware/hw_md2.c | 14 ++++++---- src/hardware/hw_model.c | 60 +++++++++++++++++++++++++++++++++++++++++ src/hardware/hw_model.h | 7 ++++- 3 files changed, 75 insertions(+), 6 deletions(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 158c07803..89a3c6c98 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -833,10 +833,14 @@ static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT run? */ -static boolean HWR_CanInterpolateModel(mobj_t *mobj) +static boolean HWR_CanInterpolateModel(mobj_t *mobj, model_t *model) { - return (!(mobj->state->nextstate == S_PLAY_WAIT && mobj->state == &states[S_PLAY_STND] && !(mobj->sprite2 & FF_SPR2SUPER))) - && (mobj->state != &states[S_PLAY_ROLL]); + return model->interpolate[(mobj->frame & FF_FRAMEMASK)]; +} + +static boolean HWR_CanInterpolateSprite2(modelspr2frames_t *spr2frame) +{ + return spr2frame->interpolate; } void HWR_DrawMD2(gr_vissprite_t *spr) @@ -1027,7 +1031,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) { if (spr->mobj->sprite2 && md2->model->spr2frames) { - if (HWR_CanInterpolateModel(spr->mobj)) + if (HWR_CanInterpolateSprite2(&md2->model->spr2frames[spr2])) { UINT32 framecount = (&((skin_t *)spr->mobj->skin)->sprites[spr->mobj->sprite2])->numframes; nextFrame = (spr->mobj->frame & FF_FRAMEMASK) + 1; @@ -1039,7 +1043,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) nextFrame = md2->model->spr2frames[spr2].frames[nextFrame]; } } - else + else if (HWR_CanInterpolateModel(spr->mobj, md2->model)) { // frames are handled differently for states with FF_ANIMATE, so get the next frame differently for the interpolation if (spr->mobj->frame & FF_ANIMATE) diff --git a/src/hardware/hw_model.c b/src/hardware/hw_model.c index 63c8b8f34..7e9c6cd57 100644 --- a/src/hardware/hw_model.c +++ b/src/hardware/hw_model.c @@ -199,6 +199,8 @@ model_t *LoadModel(const char *filename, int ztag) Optimize(model); GeneratePolygonNormals(model, ztag); LoadModelSprite2(model); + if (!model->spr2frames) + LoadModelInterpolationSettings(model); // Default material properties for (i = 0 ; i < model->numMaterials; i++) @@ -224,12 +226,59 @@ model_t *LoadModel(const char *filename, int ztag) void HWR_ReloadModels(void) { + size_t i; INT32 s; + for (s = 0; s < MAXSKINS; s++) { if (md2_playermodels[s].model) LoadModelSprite2(md2_playermodels[s].model); } + + for (i = 0; i < NUMSPRITES; i++) + { + if (md2_models[i].model) + LoadModelInterpolationSettings(md2_models[i].model); + } +} + +void LoadModelInterpolationSettings(model_t *model) +{ + INT32 i; + INT32 numframes = model->meshes[0].numFrames; + char *framename = model->framenames; + + if (!framename) + return; + + #define GET_OFFSET \ + memcpy(&interpolation_flag, framename + offset, 2); \ + model->interpolate[i] = (!memcmp(interpolation_flag, MODEL_INTERPOLATION_FLAG, 2)); + + for (i = 0; i < numframes; i++) + { + int offset = (strlen(framename) - 4); + char interpolation_flag[3]; + memset(&interpolation_flag, 0x00, 3); + + // find the +i on the frame name + // ANIM+i00 + // so the offset is (frame name length - 4) + GET_OFFSET; + + // maybe the frame had three digits? + // ANIM+i000 + // so the offset is (frame name length - 5) + if (!model->interpolate[i]) + { + offset--; + GET_OFFSET; + } + + framename += 16; + } + + #undef GET_OFFSET } void LoadModelSprite2(model_t *model) @@ -246,12 +295,15 @@ void LoadModelSprite2(model_t *model) { char prefix[6]; char name[5]; + char interpolation_flag[3]; char framechar[4]; UINT8 frame = 0; UINT8 spr2idx; + boolean interpolate = false; memset(&prefix, 0x00, 6); memset(&name, 0x00, 5); + memset(&interpolation_flag, 0x00, 3); memset(&framechar, 0x00, 4); if (strlen(framename) >= 9) @@ -261,6 +313,13 @@ void LoadModelSprite2(model_t *model) modelframename += 5; memcpy(&name, modelframename, 4); modelframename += 4; + // Oh look + memcpy(&interpolation_flag, modelframename, 2); + if (!memcmp(interpolation_flag, MODEL_INTERPOLATION_FLAG, 2)) + { + interpolate = true; + modelframename += 2; + } memcpy(&framechar, modelframename, 3); frame = atoi(framechar); @@ -277,6 +336,7 @@ void LoadModelSprite2(model_t *model) spr2frames[spr2idx].superframes[frame] = i; else spr2frames[spr2idx].frames[frame] = i; + spr2frames[spr2idx].interpolate = interpolate; break; } spr2idx++; diff --git a/src/hardware/hw_model.h b/src/hardware/hw_model.h index af9020ef9..75495c930 100644 --- a/src/hardware/hw_model.h +++ b/src/hardware/hw_model.h @@ -73,10 +73,13 @@ typedef struct tag_s // matrix_t transform; } tag_t; +#define MODEL_INTERPOLATION_FLAG "+i" + typedef struct { INT32 frames[256]; INT32 superframes[256]; + boolean interpolate; } modelspr2frames_t; typedef struct model_s @@ -93,8 +96,9 @@ typedef struct model_s char *mdlFilename; boolean unloaded; - modelspr2frames_t *spr2frames; char *framenames; + boolean interpolate[256]; + modelspr2frames_t *spr2frames; } model_t; extern int numModels; @@ -106,6 +110,7 @@ tag_t *GetTagByName(model_t *model, char *name, int frame); model_t *LoadModel(const char *filename, int ztag); void UnloadModel(model_t *model); void Optimize(model_t *model); +void LoadModelInterpolationSettings(model_t *model); void LoadModelSprite2(model_t *model); void GenerateVertexNormals(model_t *model); void GeneratePolygonNormals(model_t *model, int ztag); From a86e2332da7de4459bcf11d8991d142abb3a82fe Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 15 Sep 2019 16:24:17 -0300 Subject: [PATCH 52/74] Fix MD2 loading --- src/hardware/hw_md2load.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/hardware/hw_md2load.c b/src/hardware/hw_md2load.c index 803573ade..fed81e411 100644 --- a/src/hardware/hw_md2load.c +++ b/src/hardware/hw_md2load.c @@ -253,6 +253,7 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) md2texcoord_t *texcoords; md2frame_t *frames; char *fname = NULL; + int foffset = 0; int t; @@ -331,9 +332,10 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat) fname = retModel->framenames; for (i = 0; i < header->numFrames; i++) { - memcpy(fname, frames->name, 16); + md2frame_t *fr = (md2frame_t*)&buffer[header->offsetFrames + foffset]; + memcpy(fname, fr->name, 16); + foffset += sizeof(md2frame_t) + (sizeof(md2vertex_t) * header->numXYZ); fname += 16; - frames++; } // Read in textures From 91eb3804128df59fd47f25e6d77ec71cd42ef329 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 26 Oct 2019 15:02:45 -0400 Subject: [PATCH 53/74] Fix some jingle resuming behavior with boss music switching --- src/p_enemy.c | 14 +++++++++----- src/s_sound.c | 33 +++++++++++++++++++++++++++------ src/s_sound.h | 1 + 3 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index cc2d64e8b..12a34ebf5 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3930,11 +3930,15 @@ void A_BossDeath(mobj_t *mo) { // Touching the egg trap button calls P_DoPlayerExit, which calls P_RestoreMusic. // So just park ourselves in the mapmus variables. - boolean changed = strnicmp(mapheaderinfo[gamemap-1]->musname, mapmusname, 7); - strncpy(mapmusname, mapheaderinfo[gamemap-1]->muspostbossname, 7); - mapmusname[6] = 0; - mapmusflags = (mapheaderinfo[gamemap-1]->muspostbosstrack & MUSIC_TRACKMASK) | MUSIC_RELOADRESET; - mapmusposition = mapheaderinfo[gamemap-1]->muspostbosspos; + // But don't change the mapmus variables if they were modified from their level header values (e.g., TUNES). + boolean changed = strnicmp(mapheaderinfo[gamemap-1]->musname, S_MusicName(), 7); + if (!strnicmp(mapheaderinfo[gamemap-1]->musname, mapmusname, 7)) + { + strncpy(mapmusname, mapheaderinfo[gamemap-1]->muspostbossname, 7); + mapmusname[6] = 0; + mapmusflags = (mapheaderinfo[gamemap-1]->muspostbosstrack & MUSIC_TRACKMASK) | MUSIC_RELOADRESET; + mapmusposition = mapheaderinfo[gamemap-1]->muspostbosspos; + } // don't change if we're in another tune // but in case we're in jingle, use our parked mapmus variables so the correct track restores diff --git a/src/s_sound.c b/src/s_sound.c index 22bc848fe..aa088754b 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -64,6 +64,8 @@ static void ModFilter_OnChange(void); static lumpnum_t S_GetMusicLumpNum(const char *mname); +static boolean S_CheckQueue(void); + // commands for music and sound servers #ifdef MUSSERV consvar_t musserver_cmd = {"musserver_cmd", "musserver", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -1613,13 +1615,14 @@ static void S_AddMusicStackEntry(const char *mname, UINT16 mflags, boolean loopi if (!music_stacks) { music_stacks = Z_Calloc(sizeof (*mst), PU_MUSIC, NULL); - strncpy(music_stacks->musname, (status == JT_MASTER ? mname : mapmusname), 7); - music_stacks->musflags = (status == JT_MASTER ? mflags : mapmusflags); - music_stacks->looping = (status == JT_MASTER ? looping : true); - music_stacks->position = (status == JT_MASTER ? position : S_GetMusicPosition()); + strncpy(music_stacks->musname, (status == JT_MASTER ? mname : (S_CheckQueue() ? queue_name : mapmusname)), 7); + music_stacks->musflags = (status == JT_MASTER ? mflags : (S_CheckQueue() ? queue_flags : mapmusflags)); + music_stacks->looping = (status == JT_MASTER ? looping : (S_CheckQueue() ? queue_looping : true)); + music_stacks->position = (status == JT_MASTER ? position : (S_CheckQueue() ? queue_position : S_GetMusicPosition())); music_stacks->tic = gametic; music_stacks->status = JT_MASTER; music_stacks->mlumpnum = S_GetMusicLumpNum(music_stacks->musname); + music_stacks->noposition = S_CheckQueue(); if (status == JT_MASTER) return; // we just added the user's entry here @@ -1638,6 +1641,7 @@ static void S_AddMusicStackEntry(const char *mname, UINT16 mflags, boolean loopi new_mst->tic = gametic; new_mst->status = status; new_mst->mlumpnum = S_GetMusicLumpNum(new_mst->musname); + new_mst->noposition = false; mst->next = new_mst; new_mst->prev = mst; @@ -1745,11 +1749,23 @@ boolean S_RecallMusic(UINT16 status, boolean fromfirst) entry->tic = gametic; entry->status = JT_MASTER; entry->mlumpnum = S_GetMusicLumpNum(entry->musname); + entry->noposition = false; // don't set this until we do the mapmuschanged check, below. Else, this breaks some resumes. } if (entry->status == JT_MASTER) { mapmuschanged = strnicmp(entry->musname, mapmusname, 7); + if (mapmuschanged) + { + strncpy(entry->musname, mapmusname, 7); + entry->musflags = mapmusflags; + entry->looping = true; + entry->position = mapmusposition; + entry->tic = gametic; + entry->status = JT_MASTER; + entry->mlumpnum = S_GetMusicLumpNum(entry->musname); + entry->noposition = true; + } S_ResetMusicStack(); } else if (!entry->status) @@ -1758,7 +1774,7 @@ boolean S_RecallMusic(UINT16 status, boolean fromfirst) return false; } - if (!mapmuschanged && strncmp(entry->musname, S_MusicName(), 7)) // don't restart music if we're already playing it + if (strncmp(entry->musname, S_MusicName(), 7)) // don't restart music if we're already playing it { if (music_stack_fadeout) S_ChangeMusicEx(entry->musname, entry->musflags, entry->looping, 0, music_stack_fadeout, 0); @@ -1766,7 +1782,7 @@ boolean S_RecallMusic(UINT16 status, boolean fromfirst) { S_ChangeMusicEx(entry->musname, entry->musflags, entry->looping, 0, 0, music_stack_fadein); - if (!music_stack_noposition) // HACK: Global boolean to toggle position resuming, e.g., de-superize + if (!entry->noposition && !music_stack_noposition) // HACK: Global boolean to toggle position resuming, e.g., de-superize { UINT32 poslapse = 0; @@ -1908,6 +1924,11 @@ static void S_QueueMusic(const char *mmusic, UINT16 mflags, boolean looping, UIN queue_fadeinms = fadeinms; } +static boolean S_CheckQueue(void) +{ + return queue_name[0]; +} + static void S_ClearQueue(void) { queue_name[0] = queue_flags = queue_looping = queue_position = queue_fadeinms = 0; diff --git a/src/s_sound.h b/src/s_sound.h index 20b2489a5..c46c9fa08 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -220,6 +220,7 @@ typedef struct musicstack_s tic_t tic; UINT16 status; lumpnum_t mlumpnum; + boolean noposition; // force music stack resuming from zero (like music_stack_noposition) struct musicstack_s *prev; struct musicstack_s *next; From b6e145f0c5ce990e54f4dd99a7f78d0df39303e0 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 26 Oct 2019 12:50:49 -0700 Subject: [PATCH 54/74] Render title map on connecting to server screen too --- src/d_main.c | 117 ++++++++++++++++++++++++------------------------- src/d_main.h | 3 ++ src/f_finale.c | 12 ++--- 3 files changed, 67 insertions(+), 65 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index e71b1cdb3..c1b7741f2 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -284,11 +284,8 @@ static void D_Display(void) switch (gamestate) { case GS_TITLESCREEN: - if (!titlemapinaction || !curbghide) { - F_TitleScreenDrawer(); - break; - } - /* FALLTHRU */ + F_TitleScreenDrawer(); + break; case GS_LEVEL: if (!gametic) break; @@ -359,56 +356,11 @@ static void D_Display(void) // clean up border stuff // see if the border needs to be initially drawn - if (gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction && curbghide && (!hidetitlemap))) + if (gamestate == GS_LEVEL) { // draw the view directly - if (!automapactive && !dedicated && cv_renderview.value) - { - if (players[displayplayer].mo || players[displayplayer].playerstate == PST_DEAD) - { - topleft = screens[0] + viewwindowy*vid.width + viewwindowx; - objectsdrawn = 0; - #ifdef HWRENDER - if (rendermode != render_soft) - HWR_RenderPlayerView(0, &players[displayplayer]); - else - #endif - if (rendermode != render_none) - R_RenderPlayerView(&players[displayplayer]); - } - - // render the second screen - if (splitscreen && players[secondarydisplayplayer].mo) - { - #ifdef HWRENDER - if (rendermode != render_soft) - HWR_RenderPlayerView(1, &players[secondarydisplayplayer]); - else - #endif - if (rendermode != render_none) - { - viewwindowy = vid.height / 2; - M_Memcpy(ylookup, ylookup2, viewheight*sizeof (ylookup[0])); - - topleft = screens[0] + viewwindowy*vid.width + viewwindowx; - - R_RenderPlayerView(&players[secondarydisplayplayer]); - - viewwindowy = 0; - M_Memcpy(ylookup, ylookup1, viewheight*sizeof (ylookup[0])); - } - } - - // Image postprocessing effect - if (rendermode == render_soft) - { - if (postimgtype) - V_DoPostProcessor(0, postimgtype, postimgparam); - if (postimgtype2) - V_DoPostProcessor(1, postimgtype2, postimgparam2); - } - } + D_Render(); if (lastdraw) { @@ -420,14 +372,9 @@ static void D_Display(void) lastdraw = false; } - if (gamestate == GS_LEVEL) - { - ST_Drawer(); - F_TextPromptDrawer(); - HU_Drawer(); - } - else - F_TitleScreenDrawer(); + ST_Drawer(); + F_TextPromptDrawer(); + HU_Drawer(); } } @@ -523,6 +470,56 @@ static void D_Display(void) } } +void D_Render(void) +{ + if (!automapactive && !dedicated && cv_renderview.value) + { + if (players[displayplayer].mo || players[displayplayer].playerstate == PST_DEAD) + { + topleft = screens[0] + viewwindowy*vid.width + viewwindowx; + objectsdrawn = 0; +#ifdef HWRENDER + if (rendermode != render_soft) + HWR_RenderPlayerView(0, &players[displayplayer]); + else +#endif + if (rendermode != render_none) + R_RenderPlayerView(&players[displayplayer]); + } + + // render the second screen + if (splitscreen && players[secondarydisplayplayer].mo) + { +#ifdef HWRENDER + if (rendermode != render_soft) + HWR_RenderPlayerView(1, &players[secondarydisplayplayer]); + else +#endif + if (rendermode != render_none) + { + viewwindowy = vid.height / 2; + M_Memcpy(ylookup, ylookup2, viewheight*sizeof (ylookup[0])); + + topleft = screens[0] + viewwindowy*vid.width + viewwindowx; + + R_RenderPlayerView(&players[secondarydisplayplayer]); + + viewwindowy = 0; + M_Memcpy(ylookup, ylookup1, viewheight*sizeof (ylookup[0])); + } + } + + // Image postprocessing effect + if (rendermode == render_soft) + { + if (postimgtype) + V_DoPostProcessor(0, postimgtype, postimgparam); + if (postimgtype2) + V_DoPostProcessor(1, postimgtype2, postimgparam2); + } + } +} + // ========================================================================= // D_SRB2Loop // ========================================================================= diff --git a/src/d_main.h b/src/d_main.h index d67a5bb49..65c51802a 100644 --- a/src/d_main.h +++ b/src/d_main.h @@ -54,4 +54,7 @@ const char *D_Home(void); void D_AdvanceDemo(void); void D_StartTitle(void); +/* Here for title maps */ +void D_Render(void); + #endif //__D_MAIN__ diff --git a/src/f_finale.c b/src/f_finale.c index eb1415042..416f6f38f 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -2285,7 +2285,9 @@ void F_TitleScreenDrawer(void) // Draw that sky! if (curbgcolor >= 0) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, curbgcolor); - else if (!curbghide || !titlemapinaction || gamestate == GS_WAITINGPLAYERS) + else if (titlemapinaction && curbghide && ! hidetitlemap) + D_Render(); + else F_SkyScroll(curbgxspeed, curbgyspeed, curbgname); // Don't draw outside of the title screen, or if the patch isn't there. @@ -2358,10 +2360,6 @@ void F_TitleScreenTicker(boolean run) if (run) finalecount++; - // don't trigger if doing anything besides idling on title - if (gameaction != ga_nothing || gamestate != GS_TITLESCREEN) - return; - // Execute the titlemap camera settings if (titlemapinaction) { @@ -2408,6 +2406,10 @@ void F_TitleScreenTicker(boolean run) } } + // don't trigger if doing anything besides idling on title + if (gameaction != ga_nothing || gamestate != GS_TITLESCREEN) + return; + // no demos to play? or, are they disabled? if (!cv_rollingdemos.value || !numDemos) return; From 0c52de7a292718b6d7f96ee9f655f43b7ed2cbe0 Mon Sep 17 00:00:00 2001 From: toaster Date: Sun, 27 Oct 2019 12:20:17 +0000 Subject: [PATCH 55/74] Fix bot showing up in NiGHTS stages with a two-pronged approach. * Sometimes, D_MapChange is passed a mapnum of -1, to complete an existing mapchange. Don't handle botingame checks when that happens. * Disable charsel on secret level platter when selected map is a NiGHTS stage, since gameplay will be identical across characters (consistent with NiGHTS Attack). Also: * Replace IT_DYBIGSPACE hack in M_SetupChoosePlayer, and replace with a more direct workaround system for not being able to select characters before warping. --- src/d_netcmd.c | 47 ++++++++-------- src/m_menu.c | 145 +++++++++++++++++++++++++------------------------ 2 files changed, 98 insertions(+), 94 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index b14f92b33..0929577b4 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1646,7 +1646,31 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pultmode, boolean rese // The supplied data are assumed to be good. I_Assert(delay >= 0 && delay <= 2); if (mapnum != -1) + { CV_SetValue(&cv_nextmap, mapnum); + // Kick bot from special stages + if (botskin) + { + if (G_IsSpecialStage(mapnum) || (mapheaderinfo[mapnum-1] && (mapheaderinfo[mapnum-1]->typeoflevel & TOL_NIGHTS))) + { + if (botingame) + { + //CL_RemoveSplitscreenPlayer(); + botingame = false; + playeringame[1] = false; + } + } + else if (!botingame) + { + //CL_AddSplitscreenPlayer(); + botingame = true; + secondarydisplayplayer = 1; + playeringame[1] = true; + players[1].bot = 1; + SendNameAndColor2(); + } + } + } CONS_Debug(DBG_GAMELOGIC, "Map change: mapnum=%d gametype=%d ultmode=%d resetplayers=%d delay=%d skipprecutscene=%d\n", mapnum, newgametype, pultmode, resetplayers, delay, skipprecutscene); if ((netgame || multiplayer) && !((gametype == newgametype) && (newgametype == GT_COOP))) @@ -1689,29 +1713,6 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pultmode, boolean rese return; } - // Kick bot from special stages - if (botskin) - { - if (G_IsSpecialStage(mapnum) || (mapheaderinfo[mapnum-1] && (mapheaderinfo[mapnum-1]->typeoflevel & TOL_NIGHTS))) - { - if (botingame) - { - //CL_RemoveSplitscreenPlayer(); - botingame = false; - playeringame[1] = false; - } - } - else if (!botingame) - { - //CL_AddSplitscreenPlayer(); - botingame = true; - secondarydisplayplayer = 1; - playeringame[1] = true; - players[1].bot = 1; - SendNameAndColor2(); - } - } - chmappending++; if (netgame) WRITEUINT32(buf_p, M_RandomizedSeed()); // random seed diff --git a/src/m_menu.c b/src/m_menu.c index 54c0b6c87..b510bd972 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6511,7 +6511,7 @@ static void M_LevelSelectWarp(INT32 choice) if (W_CheckNumForName(G_BuildMapName(cv_nextmap.value)) == LUMPERROR) { -// CONS_Alert(CONS_WARNING, "Internal game map '%s' not found\n", G_BuildMapName(cv_nextmap.value)); + CONS_Alert(CONS_WARNING, "Internal game map '%s' not found\n", G_BuildMapName(cv_nextmap.value)); return; } @@ -7928,81 +7928,80 @@ static void M_SetupChoosePlayer(INT32 choice) char *and; (void)choice; - SP_PlayerMenu[0].status &= ~IT_DYBIGSPACE; // Correcting a hack that may be made below. - - for (i = 0; i < 32; i++) // Handle charsels, availability, and unlocks. + if (!(mapheaderinfo[startmap-1] + && (mapheaderinfo[startmap-1]->forcecharacter[0] != '\0' + || (mapheaderinfo[startmap-1]->typeoflevel & TOL_NIGHTS)) // remove this later when everyone gets their own nights sprites, maybe + )) { - if (description[i].used) // If the character's disabled through SOC, there's nothing we can do for it. + for (i = 0; i < 32; i++) // Handle charsels, availability, and unlocks. { - and = strchr(description[i].skinname, '&'); - if (and) + if (description[i].used) // If the character's disabled through SOC, there's nothing we can do for it. { - char firstskin[SKINNAMESIZE+1]; - strncpy(firstskin, description[i].skinname, (and - description[i].skinname)); - firstskin[(and - description[i].skinname)] = '\0'; - description[i].skinnum[0] = R_SkinAvailable(firstskin); - description[i].skinnum[1] = R_SkinAvailable(and+1); - } - else - { - description[i].skinnum[0] = R_SkinAvailable(description[i].skinname); - description[i].skinnum[1] = -1; - } - skinnum = description[i].skinnum[0]; - if ((skinnum != -1) && (R_SkinUsable(-1, skinnum))) - { - // Handling order. - if (firstvalid == 255) - firstvalid = i; + and = strchr(description[i].skinname, '&'); + if (and) + { + char firstskin[SKINNAMESIZE+1]; + strncpy(firstskin, description[i].skinname, (and - description[i].skinname)); + firstskin[(and - description[i].skinname)] = '\0'; + description[i].skinnum[0] = R_SkinAvailable(firstskin); + description[i].skinnum[1] = R_SkinAvailable(and+1); + } else { - description[i].prev = lastvalid; - description[lastvalid].next = i; + description[i].skinnum[0] = R_SkinAvailable(description[i].skinname); + description[i].skinnum[1] = -1; } - lastvalid = i; - - if (i == char_on) - allowed = true; - - if (!(description[i].picname[0])) + skinnum = description[i].skinnum[0]; + if ((skinnum != -1) && (R_SkinUsable(-1, skinnum))) { - if (skins[skinnum].sprites[SPR2_XTRA].numframes >= XTRA_CHARSEL+1) + // Handling order. + if (firstvalid == 255) + firstvalid = i; + else { - spritedef_t *sprdef = &skins[skinnum].sprites[SPR2_XTRA]; - spriteframe_t *sprframe = &sprdef->spriteframes[XTRA_CHARSEL]; - description[i].charpic = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); + description[i].prev = lastvalid; + description[lastvalid].next = i; + } + lastvalid = i; + + if (i == char_on) + allowed = true; + + if (!(description[i].picname[0])) + { + if (skins[skinnum].sprites[SPR2_XTRA].numframes >= XTRA_CHARSEL+1) + { + spritedef_t *sprdef = &skins[skinnum].sprites[SPR2_XTRA]; + spriteframe_t *sprframe = &sprdef->spriteframes[XTRA_CHARSEL]; + description[i].charpic = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); + } + else + description[i].charpic = W_CachePatchName("MISSING", PU_CACHE); } else - description[i].charpic = W_CachePatchName("MISSING", PU_CACHE); - } - else - description[i].charpic = W_CachePatchName(description[i].picname, PU_CACHE); + description[i].charpic = W_CachePatchName(description[i].picname, PU_CACHE); - if (description[i].nametag[0]) - { - const char *nametag = description[i].nametag; - description[i].namepic = NULL; - if (W_LumpExists(nametag)) - description[i].namepic = W_CachePatchName(nametag, PU_CACHE); + if (description[i].nametag[0]) + { + const char *nametag = description[i].nametag; + description[i].namepic = NULL; + if (W_LumpExists(nametag)) + description[i].namepic = W_CachePatchName(nametag, PU_CACHE); + } } + // else -- Technically, character select icons without corresponding skins get bundled away behind this too. Sucks to be them. } - // else -- Technically, character select icons without corresponding skins get bundled away behind this too. Sucks to be them. } } - if ((firstvalid != 255) - && !(mapheaderinfo[startmap-1] - && (mapheaderinfo[startmap-1]->forcecharacter[0] != '\0') - ) - ) + if (firstvalid != 255) { // One last bit of order we can't do in the iteration above. description[firstvalid].prev = lastvalid; description[lastvalid].next = firstvalid; } - else // We're being forced into a specific character, so might as well. + else // We're being forced into a specific character, so might as well just skip it. { - SP_PlayerMenu[0].status |= IT_DYBIGSPACE; // This is a dummy flag hack to make a non-IT_CALL character in slot 0 not softlock the game. - M_ChoosePlayer(0); + M_ChoosePlayer(-1); return; } @@ -8329,38 +8328,42 @@ static void M_DrawSetupChoosePlayerMenu(void) static void M_ChoosePlayer(INT32 choice) { boolean ultmode = (ultimate_selectable && SP_PlayerDef.prevMenu == &SP_LoadDef && saveSlotSelected == NOSAVESLOT); + UINT8 skinnum; // skip this if forcecharacter or no characters available - if (!(SP_PlayerMenu[0].status & IT_DYBIGSPACE)) + if (choice == -1) + { + skinnum = botskin = 0; + botingame = false; + } + // M_SetupChoosePlayer didn't call us directly, that means we've been properly set up. + else { - // M_SetupChoosePlayer didn't call us directly, that means we've been properly set up. char_scroll = 0; // finish scrolling the menu M_DrawSetupChoosePlayerMenu(); // draw the finally selected character one last time for the fadeout // Is this a hack? charseltimer = 0; - } - M_ClearMenus(true); - if (description[choice].skinnum[1] != -1) { - // this character has a second skin - botingame = true; - botskin = (UINT8)(description[choice].skinnum[1]+1); - botcolor = skins[description[choice].skinnum[1]].prefcolor; - } - else - { - botingame = false; - botskin = 0; - botcolor = 0; + skinnum = description[choice].skinnum[0]; + + if ((botingame = (description[choice].skinnum[1] != -1))) { + // this character has a second skin + botskin = (UINT8)(description[choice].skinnum[1]+1); + botcolor = skins[description[choice].skinnum[1]].prefcolor; + } + else + botskin = botcolor = 0; } + M_ClearMenus(true); + if (startmap != spstage_start) cursaveslot = 0; //lastmapsaved = 0; gamecomplete = false; - G_DeferedInitNew(ultmode, G_BuildMapName(startmap), (UINT8)description[choice].skinnum[0], false, fromlevelselect); + G_DeferedInitNew(ultmode, G_BuildMapName(startmap), skinnum, false, fromlevelselect); COM_BufAddText("dummyconsvar 1\n"); // G_DeferedInitNew doesn't do this if (levelselect.rows) From fa187a66e2344fe2b086d08880c86906574f0355 Mon Sep 17 00:00:00 2001 From: toaster Date: Sun, 27 Oct 2019 12:47:58 +0000 Subject: [PATCH 56/74] * Disable dashmode if pw_carry is set or the player is exiting, in addition to getting the flag. * Add a dashmode downpower sound. --- src/p_user.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index dde1dc1dc..834fc293c 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -11811,8 +11811,8 @@ void P_PlayerThink(player_t *player) player->pflags &= ~PF_SLIDING; #define dashmode player->dashmode - // Dash mode - thanks be to Iceman404 - if ((player->charflags & SF_DASHMODE) && !(player->gotflag) && !(maptol & TOL_NIGHTS)) // woo, dashmode! no nights tho. + // Dash mode - thanks be to VelocitOni + if ((player->charflags & SF_DASHMODE) && !player->gotflag && !player->powers[pw_carry] && !player->exiting && !(maptol & TOL_NIGHTS)) // woo, dashmode! no nights tho. { boolean totallyradical = player->speed >= FixedMul(player->runspeed, player->mo->scale); boolean floating = (player->secondjump == 1); @@ -11827,7 +11827,11 @@ void P_PlayerThink(player_t *player) else if ((!totallyradical || !floating) && !(player->pflags & PF_SPINNING)) { if (dashmode > 3) + { dashmode -= 3; // Rather than lose it all, it gently counts back down! + if ((dashmode+3) >= DASHMODE_THRESHOLD && dashmode < DASHMODE_THRESHOLD) + S_StartSound(player->mo, sfx_s3k72); + } else dashmode = 0; } @@ -11858,6 +11862,7 @@ void P_PlayerThink(player_t *player) { player->normalspeed = skins[player->skin].normalspeed; player->jumpfactor = skins[player->skin].jumpfactor; + S_StartSound(player->mo, sfx_s3k72); } dashmode = 0; } From 9e8733be4210de3e3ccb2048bb712295a2a27d0f Mon Sep 17 00:00:00 2001 From: toaster Date: Sun, 27 Oct 2019 13:07:06 +0000 Subject: [PATCH 57/74] Make player flash colorized when dashmode if not SF_MACHINE, per Sonic Advance 2. --- src/r_things.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 00eaae1c2..0102489eb 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -755,10 +755,13 @@ static void R_DrawVisSprite(vissprite_t *vis) dc_translation = R_GetTranslationColormap(TC_RAINBOW, vis->mobj->color, GTC_CACHE); else if (!(vis->cut & SC_PRECIP) && vis->mobj->player && vis->mobj->player->dashmode >= DASHMODE_THRESHOLD - && (vis->mobj->player->charflags & (SF_DASHMODE|SF_MACHINE)) == (SF_DASHMODE|SF_MACHINE) + && (vis->mobj->player->charflags & SF_DASHMODE) && ((leveltime/2) & 1)) { - dc_translation = R_GetTranslationColormap(TC_DASHMODE, 0, GTC_CACHE); + if (vis->mobj->player->charflags & SF_MACHINE) + dc_translation = R_GetTranslationColormap(TC_DASHMODE, 0, GTC_CACHE); + else + dc_translation = R_GetTranslationColormap(TC_RAINBOW, vis->mobj->color, GTC_CACHE); } else if (!(vis->cut & SC_PRECIP) && vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // MT_GHOST LOOKS LIKE A PLAYER SO USE THE PLAYER TRANSLATION TABLES. >_> { From 1306b2bbc516237c9fa860afd15f2eb698c426eb Mon Sep 17 00:00:00 2001 From: lachwright Date: Mon, 28 Oct 2019 21:30:36 +0800 Subject: [PATCH 58/74] Slow glide down underwater --- src/p_user.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index dde1dc1dc..9538c5faa 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -5303,14 +5303,23 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) // Now Knuckles-type abilities are checked. if (!(player->pflags & PF_THOKKED) || player->charflags & SF_MULTIABILITY) { - INT32 glidespeed = player->actionspd; + fixed_t glidespeed = FixedMul(player->actionspd, player->mo->scale); + fixed_t playerspeed = player->speed; + + if (player->mo->eflags & MFE_UNDERWATER) + { + glidespeed >>= 1; + playerspeed >>= 1; + player->mo->momx = ((player->mo->momx - player->cmomx) >> 1) + player->cmomx; + player->mo->momy = ((player->mo->momy - player->cmomy) >> 1) + player->cmomy; + } player->pflags |= PF_GLIDING|PF_THOKKED; player->glidetime = 0; P_SetPlayerMobjState(player->mo, S_PLAY_GLIDE); - if (player->speed < glidespeed) - P_Thrust(player->mo, player->mo->angle, glidespeed - player->speed); + if (playerspeed < glidespeed) + P_Thrust(player->mo, player->mo->angle, glidespeed - playerspeed); player->pflags &= ~(PF_SPINNING|PF_STARTDASH); } break; From b93c2467e7c8f228946a101169a7ec7ff3add0a2 Mon Sep 17 00:00:00 2001 From: lachwright Date: Mon, 28 Oct 2019 22:13:34 +0800 Subject: [PATCH 59/74] Don't let Knuckles play the landing animation unless in fall state --- 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 9538c5faa..a3af3cb78 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2263,7 +2263,7 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) else if (!player->skidtime) player->pflags &= ~PF_GLIDING; } - else if (player->charability == CA_GLIDEANDCLIMB && player->pflags & PF_THOKKED && (~player->pflags) & PF_SHIELDABILITY) + else if (player->charability == CA_GLIDEANDCLIMB && player->pflags & PF_THOKKED && !(player->pflags & PF_SHIELDABILITY) && player->mo->state-states == S_PLAY_FALL) { if (player->mo->state-states != S_PLAY_GLIDE_LANDING) { From 9a160823aa934aee7575e63da09f05004e1b5ff8 Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 28 Oct 2019 14:19:07 +0000 Subject: [PATCH 60/74] Replace the s3k sound used when starting dashmode with the Sonic CD equivalent, which among other things is more appropriate AND isn't used for anything unrelated so can have a more appropriate caption --- 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 834fc293c..6169c3b1f 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -11822,7 +11822,7 @@ void P_PlayerThink(player_t *player) if (dashmode < DASHMODE_MAX) dashmode++; // Counter. Adds 1 to dash mode per tic in top speed. if (dashmode == DASHMODE_THRESHOLD) // This isn't in the ">=" equation because it'd cause the sound to play infinitely. - S_StartSound(player->mo, sfx_s3ka2); // If the player enters dashmode, play this sound on the the tic it starts. + S_StartSound(player->mo, sfx_cdfm62); // If the player enters dashmode, play this sound on the the tic it starts. } else if ((!totallyradical || !floating) && !(player->pflags & PF_SPINNING)) { From 46ba9885416a046e636ee1c40904c10ad6a46a6c Mon Sep 17 00:00:00 2001 From: lachwright Date: Mon, 28 Oct 2019 22:21:20 +0800 Subject: [PATCH 61/74] Slow climbing down underwater --- src/p_user.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index a3af3cb78..a637ff4b2 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -5979,7 +5979,12 @@ static void P_3dMovement(player_t *player) if (player->climbing) { if (cmd->forwardmove) - P_SetObjectMomZ(player->mo, FixedDiv(cmd->forwardmove*FRACUNIT, 15*FRACUNIT>>1), false); + { + if (player->mo->eflags & MFE_UNDERWATER) + P_SetObjectMomZ(player->mo, FixedDiv(cmd->forwardmove*FRACUNIT, 10*FRACUNIT), false); + else + P_SetObjectMomZ(player->mo, FixedDiv(cmd->forwardmove*FRACUNIT, 15*FRACUNIT>>1), false); + } } else if (!analogmove && cmd->forwardmove != 0 && !(player->pflags & PF_GLIDING || player->exiting @@ -6013,7 +6018,12 @@ static void P_3dMovement(player_t *player) } // Sideways movement if (player->climbing) - P_InstaThrust(player->mo, player->mo->angle-ANGLE_90, FixedDiv(cmd->sidemove*player->mo->scale, 15*FRACUNIT>>1)); + { + if (player->mo->eflags & MFE_UNDERWATER) + P_InstaThrust(player->mo, player->mo->angle-ANGLE_90, FixedDiv(cmd->sidemove*player->mo->scale, 10*FRACUNIT)); + else + P_InstaThrust(player->mo, player->mo->angle-ANGLE_90, FixedDiv(cmd->sidemove*player->mo->scale, 15*FRACUNIT>>1)); + } // Analog movement control else if (analogmove) { From 67a99f6334494fea4713d79d59bdf33cf91deed1 Mon Sep 17 00:00:00 2001 From: toaster Date: Wed, 30 Oct 2019 17:16:44 +0000 Subject: [PATCH 62/74] ACTUALLY applied colorized flashing for dashmode to non-SF_MACHINE players, which wasn't happening for non-transparent players because :VVV --- src/r_things.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 0102489eb..1b44a22b8 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -786,10 +786,13 @@ static void R_DrawVisSprite(vissprite_t *vis) dc_translation = R_GetTranslationColormap(TC_RAINBOW, vis->mobj->color, GTC_CACHE); else if (!(vis->cut & SC_PRECIP) && vis->mobj->player && vis->mobj->player->dashmode >= DASHMODE_THRESHOLD - && (vis->mobj->player->charflags & (SF_DASHMODE|SF_MACHINE)) == (SF_DASHMODE|SF_MACHINE) + && (vis->mobj->player->charflags & SF_DASHMODE) && ((leveltime/2) & 1)) { - dc_translation = R_GetTranslationColormap(TC_DASHMODE, 0, GTC_CACHE); + if (vis->mobj->player->charflags & SF_MACHINE) + dc_translation = R_GetTranslationColormap(TC_DASHMODE, 0, GTC_CACHE); + else + dc_translation = R_GetTranslationColormap(TC_RAINBOW, vis->mobj->color, GTC_CACHE); } else if (!(vis->cut & SC_PRECIP) && vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // This thing is a player! { From 126fc44d6e36ecead0cd7c9007ab64ce6a1264f3 Mon Sep 17 00:00:00 2001 From: toaster Date: Wed, 30 Oct 2019 17:37:42 +0000 Subject: [PATCH 63/74] Change sounds, after discussing with Lach. --- src/p_user.c | 6 +++--- src/sounds.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index d49a63bf7..8604b9751 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -11822,7 +11822,7 @@ void P_PlayerThink(player_t *player) if (dashmode < DASHMODE_MAX) dashmode++; // Counter. Adds 1 to dash mode per tic in top speed. if (dashmode == DASHMODE_THRESHOLD) // This isn't in the ">=" equation because it'd cause the sound to play infinitely. - S_StartSound(player->mo, sfx_cdfm62); // If the player enters dashmode, play this sound on the the tic it starts. + S_StartSound(player->mo, (player->charflags & SF_MACHINE) ? sfx_kc4d : sfx_cdfm40); // If the player enters dashmode, play this sound on the the tic it starts. } else if ((!totallyradical || !floating) && !(player->pflags & PF_SPINNING)) { @@ -11830,7 +11830,7 @@ void P_PlayerThink(player_t *player) { dashmode -= 3; // Rather than lose it all, it gently counts back down! if ((dashmode+3) >= DASHMODE_THRESHOLD && dashmode < DASHMODE_THRESHOLD) - S_StartSound(player->mo, sfx_s3k72); + S_StartSound(player->mo, sfx_kc65); } else dashmode = 0; @@ -11862,7 +11862,7 @@ void P_PlayerThink(player_t *player) { player->normalspeed = skins[player->skin].normalspeed; player->jumpfactor = skins[player->skin].jumpfactor; - S_StartSound(player->mo, sfx_s3k72); + S_StartSound(player->mo, sfx_kc65); } dashmode = 0; } diff --git a/src/sounds.c b/src/sounds.c index 8dc97b1e6..791a7571e 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -693,7 +693,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"cdfm37", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"cdfm38", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Drowning"}, {"cdfm39", false, 128, 8, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"cdfm40", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"cdfm40", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Power up"}, {"cdfm41", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"cdfm42", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"cdfm43", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, @@ -780,7 +780,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"kc4a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"kc4b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"kc4c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"kc4d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"kc4d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Power up"}, {"kc4e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"kc4f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"kc50", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, @@ -804,7 +804,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"kc62", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"kc63", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"kc64", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Terrifying rumble"}, - {"kc65", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"kc65", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Power down"}, {"kc66", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"kc67", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"kc68", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, From 417f17ebdd09367fcbbfeaa710b7cd8e1375e8a9 Mon Sep 17 00:00:00 2001 From: toaster Date: Sat, 2 Nov 2019 17:52:54 +0000 Subject: [PATCH 64/74] Do a bunch of stuff to the MD2/3 sprite2 support to get it back to feature parity with before, without going back to being hacky as fuck. * Store the number of frames per sprite2 run in the spr2frames struct. * Reintroduce P_GetModelSprite2, to allow for the sprite2 defaulting system to be used to full advantage even in GL. * Instead of splitting the SUPER and normal SPR2 stuff within the same cell of the struct, have them exist in different cells just like in the "normal" sprite2 structs. * Allow for just providing spr2 frames in order without specifying which "normal" sprite2 frame it's supposed to replace. Also: * Fix FF_VERTICALFLIP-ignoring regression. * Fix whitespace adjustment in win_dll.c * Remove bracket in P_GetSkinSprite2 because I realised it was extraneous while making sure P_GetModelSprite2 worked with it. --- src/hardware/hw_md2.c | 112 +++++++++++++++++++++++++++++++++------- src/hardware/hw_model.c | 30 +++++++---- src/hardware/hw_model.h | 2 +- src/r_things.c | 2 +- src/win32/win_dll.c | 2 +- 5 files changed, 116 insertions(+), 32 deletions(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 2690f014f..9b2607fea 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -848,6 +848,63 @@ static boolean HWR_CanInterpolateSprite2(modelspr2frames_t *spr2frame) return spr2frame->interpolate; } +// +// P_GetModelSprite2 (see P_GetSkinSprite2) +// For non-super players, tries each sprite2's immediate predecessor until it finds one with a number of frames or ends up at standing. +// For super players, does the same as above - but tries the super equivalent for each sprite2 before the non-super version. +// + +static UINT8 P_GetModelSprite2(md2_t *md2, skin_t *skin, UINT8 spr2, player_t *player) +{ + UINT8 super = 0, i = 0; + + if (!md2 || !md2->model || !md2->model->spr2frames || !skin) + return 0; + + if ((playersprite_t)(spr2 & ~FF_SPR2SUPER) >= free_spr2) + return 0; + + while (!md2->model->spr2frames[spr2].numframes + && spr2 != SPR2_STND + && ++i != 32) // recursion limiter + { + if (spr2 & FF_SPR2SUPER) + { + super = FF_SPR2SUPER; + spr2 &= ~FF_SPR2SUPER; + continue; + } + + switch(spr2) + { + // Normal special cases. + case SPR2_JUMP: + spr2 = ((player + ? player->charflags + : skin->flags) + & SF_NOJUMPSPIN) ? SPR2_SPNG : SPR2_ROLL; + break; + case SPR2_TIRE: + spr2 = ((player + ? player->charability + : skin->ability) + == CA_SWIM) ? SPR2_SWIM : SPR2_FLY; + break; + // Use the handy list, that's what it's there for! + default: + spr2 = spr2defaults[spr2]; + break; + } + + spr2 |= super; + } + + if (i >= 32) // probably an infinite loop... + return 0; + + return spr2; +} + void HWR_DrawMD2(gr_vissprite_t *spr) { FSurfaceInfo Surf; @@ -906,9 +963,10 @@ void HWR_DrawMD2(gr_vissprite_t *spr) INT32 durs = spr->mobj->state->tics; INT32 tics = spr->mobj->tics; //mdlframe_t *next = NULL; - const UINT8 flip = (UINT8)((spr->mobj->eflags & MFE_VERTICALFLIP) == MFE_VERTICALFLIP); + const UINT8 flip = (UINT8)(!(spr->mobj->eflags & MFE_VERTICALFLIP) != !(spr->mobj->frame & FF_VERTICALFLIP)); spritedef_t *sprdef; spriteframe_t *sprframe; + INT32 mod; float finalscale; // Apparently people don't like jump frames like that, so back it goes @@ -1018,34 +1076,49 @@ void HWR_DrawMD2(gr_vissprite_t *spr) tics = spr->mobj->anim_duration; } - //FIXME: this is not yet correct - if (spr->mobj->sprite2 && md2->model->spr2frames) + frame = (spr->mobj->frame & FF_FRAMEMASK); + if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY && md2->model->spr2frames) { - spr2 = (spr->mobj->sprite2 & ~FF_SPR2SUPER); - frame = (spr->mobj->frame & FF_FRAMEMASK); - if (spr->mobj->sprite2 & FF_SPR2SUPER) - frame = md2->model->spr2frames[spr2].superframes[frame]; + spr2 = P_GetModelSprite2(md2, spr->mobj->skin, spr->mobj->sprite2, spr->mobj->player); + mod = md2->model->spr2frames[spr2].numframes; +#ifndef DONTHIDEDIFFANIMLENGTH // by default, different anim length is masked by the mod + if (mod > (INT32)((skin_t *)spr->mobj->skin)->sprites[spr2].numframes) + mod = ((skin_t *)spr->mobj->skin)->sprites[spr2].numframes; +#endif + if (mod) + frame = md2->model->spr2frames[spr2].frames[frame%mod]; else - frame = md2->model->spr2frames[spr2].frames[frame]; + frame = 0; } else - frame = (spr->mobj->frame & FF_FRAMEMASK); + { + mod = md2->model->meshes[0].numFrames; + if (mod) + frame %= mod; + } #ifdef USE_MODEL_NEXTFRAME - if (cv_grmodels.value == 1 && tics <= durs) +#define INTERPOLERATION_LIMIT TICRATE/4 + if (cv_grmodels.value == 1 && tics <= durs && tics <= INTERPOLERATION_LIMIT) { - if (spr->mobj->sprite2 && md2->model->spr2frames) + if (durs > INTERPOLERATION_LIMIT) + durs = INTERPOLERATION_LIMIT; + + if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY && md2->model->spr2frames) { - if (HWR_CanInterpolateSprite2(&md2->model->spr2frames[spr2])) + if (mod && HWR_CanInterpolateSprite2(&md2->model->spr2frames[spr2]) + && (spr->mobj->frame & FF_ANIMATE + || (spr->mobj->state->nextstate != S_NULL + && states[spr->mobj->state->nextstate].sprite == SPR_PLAY + && ((P_GetSkinSprite2(spr->mobj->skin, (((spr->mobj->player && spr->mobj->player->powers[pw_super]) ? FF_SPR2SUPER : 0)|states[spr->mobj->state->nextstate].frame) & FF_FRAMEMASK, spr->mobj->player) == spr->mobj->sprite2))))) { - UINT32 framecount = (&((skin_t *)spr->mobj->skin)->sprites[spr->mobj->sprite2])->numframes; nextFrame = (spr->mobj->frame & FF_FRAMEMASK) + 1; - if (nextFrame >= framecount) + if (nextFrame >= mod) nextFrame = 0; - if (spr->mobj->sprite2 & FF_SPR2SUPER) - nextFrame = md2->model->spr2frames[spr2].superframes[nextFrame]; - else + if (frame || !(spr->mobj->state->frame & FF_SPR2ENDSTATE)) nextFrame = md2->model->spr2frames[spr2].frames[nextFrame]; + else + nextFrame = -1; } } else if (HWR_CanInterpolateModel(spr->mobj, md2->model)) @@ -1054,7 +1127,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) if (spr->mobj->frame & FF_ANIMATE) { nextFrame = (spr->mobj->frame & FF_FRAMEMASK) + 1; - if (nextFrame >= spr->mobj->state->var1) + if (nextFrame >= (INT32)(spr->mobj->state->var1 + (spr->mobj->state->frame & FF_FRAMEMASK))) nextFrame = (spr->mobj->state->frame & FF_FRAMEMASK); //next = &md2->model->meshes[0].frames[nextFrame]; } @@ -1069,13 +1142,14 @@ void HWR_DrawMD2(gr_vissprite_t *spr) } } } +#undef INTERPOLERATION_LIMIT #endif //Hurdler: it seems there is still a small problem with mobj angle p.x = FIXED_TO_FLOAT(spr->mobj->x); p.y = FIXED_TO_FLOAT(spr->mobj->y)+md2->offset; - if (spr->mobj->eflags & MFE_VERTICALFLIP) + if (flip) p.z = FIXED_TO_FLOAT(spr->mobj->z + spr->mobj->height); else p.z = FIXED_TO_FLOAT(spr->mobj->z); diff --git a/src/hardware/hw_model.c b/src/hardware/hw_model.c index 7e9c6cd57..ac73f8aca 100644 --- a/src/hardware/hw_model.c +++ b/src/hardware/hw_model.c @@ -296,7 +296,7 @@ void LoadModelSprite2(model_t *model) char prefix[6]; char name[5]; char interpolation_flag[3]; - char framechar[4]; + char framechars[4]; UINT8 frame = 0; UINT8 spr2idx; boolean interpolate = false; @@ -304,10 +304,11 @@ void LoadModelSprite2(model_t *model) memset(&prefix, 0x00, 6); memset(&name, 0x00, 5); memset(&interpolation_flag, 0x00, 3); - memset(&framechar, 0x00, 4); + memset(&framechars, 0x00, 4); if (strlen(framename) >= 9) { + boolean super; char *modelframename = framename; memcpy(&prefix, modelframename, 5); modelframename += 5; @@ -320,22 +321,31 @@ void LoadModelSprite2(model_t *model) interpolate = true; modelframename += 2; } - memcpy(&framechar, modelframename, 3); - frame = atoi(framechar); + memcpy(&framechars, modelframename, 3); - if ((!memcmp(prefix, "SPR2_", 5)) || (!memcmp(prefix, "SUPER", 5))) + if ((super = (!memcmp(prefix, "SUPER", 5))) || (!memcmp(prefix, "SPR2_", 5))) { spr2idx = 0; - while (spr2idx < NUMPLAYERSPRITES) + while (spr2idx < free_spr2) { if (!memcmp(spr2names[spr2idx], name, 4)) { if (!spr2frames) - spr2frames = (modelspr2frames_t*)Z_Calloc(sizeof(modelspr2frames_t)*NUMPLAYERSPRITES, PU_STATIC, NULL); - if (!memcmp(prefix, "SUPER", 5)) - spr2frames[spr2idx].superframes[frame] = i; + spr2frames = (modelspr2frames_t*)Z_Calloc(sizeof(modelspr2frames_t)*NUMPLAYERSPRITES*2, PU_STATIC, NULL); + if (super) + spr2idx |= FF_SPR2SUPER; + if (framechars[0]) + { + frame = atoi(framechars); + if (spr2frames[spr2idx].numframes < frame+1) + spr2frames[spr2idx].numframes = frame+1; + } else - spr2frames[spr2idx].frames[frame] = i; + { + frame = spr2frames[spr2idx].numframes; + spr2frames[spr2idx].numframes++; + } + spr2frames[spr2idx].frames[frame] = i; spr2frames[spr2idx].interpolate = interpolate; break; } diff --git a/src/hardware/hw_model.h b/src/hardware/hw_model.h index 75495c930..2a5240bde 100644 --- a/src/hardware/hw_model.h +++ b/src/hardware/hw_model.h @@ -78,7 +78,7 @@ typedef struct tag_s typedef struct { INT32 frames[256]; - INT32 superframes[256]; + UINT8 numframes; boolean interpolate; } modelspr2frames_t; diff --git a/src/r_things.c b/src/r_things.c index 43e006a30..238a0a247 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2527,7 +2527,7 @@ UINT8 P_GetSkinSprite2(skin_t *skin, UINT8 spr2, player_t *player) if ((playersprite_t)(spr2 & ~FF_SPR2SUPER) >= free_spr2) return 0; - while (!(skin->sprites[spr2].numframes) + while (!skin->sprites[spr2].numframes && spr2 != SPR2_STND && ++i < 32) // recursion limiter { diff --git a/src/win32/win_dll.c b/src/win32/win_dll.c index bc67f04a5..f86981015 100644 --- a/src/win32/win_dll.c +++ b/src/win32/win_dll.c @@ -139,7 +139,7 @@ static loadfunc_t hwdFuncTable[] = { {"GClipRect", &hwdriver.pfnGClipRect}, {"ClearMipMapCache", &hwdriver.pfnClearMipMapCache}, {"SetSpecialState", &hwdriver.pfnSetSpecialState}, - {"DrawModel", &hwdriver.pfnDrawModel}, + {"DrawModel", &hwdriver.pfnDrawModel}, {"SetTransform", &hwdriver.pfnSetTransform}, {"GetTextureUsed", &hwdriver.pfnGetTextureUsed}, {"GetRenderVersion", &hwdriver.pfnGetRenderVersion}, From 8909598bafb54ee7a8a1d12c72b16fbf9beeda3d Mon Sep 17 00:00:00 2001 From: toaster Date: Sat, 2 Nov 2019 18:12:12 +0000 Subject: [PATCH 65/74] Instead of checking for mod being nonzero, pretend it's 1 - after all, there's no good behaviour in that circumstance otherwise. --- src/hardware/hw_md2.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 9b2607fea..675f84e4a 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1085,16 +1085,15 @@ void HWR_DrawMD2(gr_vissprite_t *spr) if (mod > (INT32)((skin_t *)spr->mobj->skin)->sprites[spr2].numframes) mod = ((skin_t *)spr->mobj->skin)->sprites[spr2].numframes; #endif - if (mod) - frame = md2->model->spr2frames[spr2].frames[frame%mod]; - else - frame = 0; + if (!mod) + mod = 1; + frame = md2->model->spr2frames[spr2].frames[frame%mod]; } else { mod = md2->model->meshes[0].numFrames; - if (mod) - frame %= mod; + if (!mod) + mod = 1; } #ifdef USE_MODEL_NEXTFRAME @@ -1106,7 +1105,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY && md2->model->spr2frames) { - if (mod && HWR_CanInterpolateSprite2(&md2->model->spr2frames[spr2]) + if (HWR_CanInterpolateSprite2(&md2->model->spr2frames[spr2]) && (spr->mobj->frame & FF_ANIMATE || (spr->mobj->state->nextstate != S_NULL && states[spr->mobj->state->nextstate].sprite == SPR_PLAY @@ -1128,17 +1127,13 @@ void HWR_DrawMD2(gr_vissprite_t *spr) { nextFrame = (spr->mobj->frame & FF_FRAMEMASK) + 1; if (nextFrame >= (INT32)(spr->mobj->state->var1 + (spr->mobj->state->frame & FF_FRAMEMASK))) - nextFrame = (spr->mobj->state->frame & FF_FRAMEMASK); - //next = &md2->model->meshes[0].frames[nextFrame]; + nextFrame = (spr->mobj->state->frame & FF_FRAMEMASK) % mod; } else { if (spr->mobj->state->nextstate != S_NULL && states[spr->mobj->state->nextstate].sprite != SPR_NULL - && !(spr->mobj->player && (spr->mobj->state->nextstate == S_PLAY_WAIT) && spr->mobj->state == &states[S_PLAY_STND])) - { - nextFrame = (states[spr->mobj->state->nextstate].frame & FF_FRAMEMASK); - //next = &md2->model->meshes[0].frames[nextFrame]; - } + && !(spr->mobj->player && (spr->mobj->state->nextstate == S_PLAY_WAIT) && spr->mobj->state == &states[S_PLAY_STND])) + nextFrame = (states[spr->mobj->state->nextstate].frame & FF_FRAMEMASK) % mod; } } } From 751d398321fef2dec398beef80db502c373637a0 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 2 Nov 2019 17:33:36 -0300 Subject: [PATCH 66/74] Fix sky dome --- src/hardware/r_opengl/r_opengl.c | 64 +++++++++++++++++++++++--------- 1 file changed, 46 insertions(+), 18 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index d4c9ed5d8..7bd2b6f9e 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -216,6 +216,7 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...) #define pglVertexPointer glVertexPointer #define pglNormalPointer glNormalPointer #define pglTexCoordPointer glTexCoordPointer +#define pglColorPointer glColorPointer #define pglDrawArrays glDrawArrays #define pglDrawElements glDrawElements #define pglEnableClientState glEnableClientState @@ -320,6 +321,8 @@ typedef void (APIENTRY * PFNglNormalPointer) (GLenum type, GLsizei stride, const static PFNglNormalPointer pglNormalPointer; typedef void (APIENTRY * PFNglTexCoordPointer) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); static PFNglTexCoordPointer pglTexCoordPointer; +typedef void (APIENTRY * PFNglColorPointer) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +static PFNglColorPointer pglColorPointer; typedef void (APIENTRY * PFNglDrawArrays) (GLenum mode, GLint first, GLsizei count); static PFNglDrawArrays pglDrawArrays; typedef void (APIENTRY * PFNglDrawElements) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices); @@ -458,6 +461,7 @@ boolean SetupGLfunc(void) GETOPENGLFUNC(pglVertexPointer, glVertexPointer) GETOPENGLFUNC(pglNormalPointer, glNormalPointer) GETOPENGLFUNC(pglTexCoordPointer, glTexCoordPointer) + GETOPENGLFUNC(pglColorPointer, glColorPointer) GETOPENGLFUNC(pglDrawArrays, glDrawArrays) GETOPENGLFUNC(pglDrawElements, glDrawElements) GETOPENGLFUNC(pglEnableClientState, glEnableClientState) @@ -1407,13 +1411,17 @@ typedef struct typedef struct { - int id; + unsigned int id; int rows, columns; int loopcount; GLSkyLoopDef *loops; vbo_vertex_t *data; } GLSkyVBO; +#define sky_vbo_x (&vbo->data[0].x) +#define sky_vbo_u (&vbo->data[0].u) +#define sky_vbo_r (&vbo->data[0].r) + // The texture offset to be applied to the texture coordinates in SkyVertex(). static int rows, columns; static boolean yflip; @@ -1423,6 +1431,7 @@ static float delta = 0.0f; static int gl_sky_detail = 16; +static boolean vbo_init = false; static INT32 lasttex = -1; #define MAP_COEFF 128.0f @@ -1550,20 +1559,45 @@ static void gld_BuildSky(int row_count, int col_count) static void RenderDome(INT32 skytexture) { int i, j; + int vbosize; GLSkyVBO *vbo = &sky_vbo; - pglRotatef(270.0f, 0.0f, 1.0f, 0.0f); - rows = 4; columns = 4 * gl_sky_detail; + vbosize = 2 * rows * (columns * 2 + 2) + columns * 2; + // generate a new VBO and get the associated ID + if (!vbo_init) + { + pglGenBuffers(1, &vbo->id); + vbo_init = true; + } + + // Build the sky dome! Yes! if (lasttex != skytexture) { lasttex = skytexture; gld_BuildSky(rows, columns); + + // bind VBO in order to use + pglBindBuffer(GL_ARRAY_BUFFER, vbo->id); + + // upload data to VBO + pglBufferData(GL_ARRAY_BUFFER, vbosize * sizeof(vbo->data[0]), vbo->data, GL_STATIC_DRAW); } + // activate and specify pointers to arrays + pglBindBuffer(GL_ARRAY_BUFFER, vbo->id); + pglVertexPointer(3, GL_FLOAT, sizeof(vbo->data[0]), sky_vbo_x); + pglTexCoordPointer(2, GL_FLOAT, sizeof(vbo->data[0]), sky_vbo_u); + pglColorPointer(4, GL_UNSIGNED_BYTE, sizeof(vbo->data[0]), sky_vbo_r); + + // activate color arrays + pglEnableClientState(GL_COLOR_ARRAY); + + // set transforms pglScalef(1.0f, (float)texh / 230.0f, 1.0f); + pglRotatef(270.0f, 0.0f, 1.0f, 0.0f); for (j = 0; j < 2; j++) { @@ -1573,25 +1607,19 @@ static void RenderDome(INT32 skytexture) if (j == 0 ? loop->use_texture : !loop->use_texture) continue; - else - { - int k; - pglBegin(loop->mode); - for (k = loop->vertexindex; k < (loop->vertexindex + loop->vertexcount); k++) - { - vbo_vertex_t *v = &vbo->data[k]; - if (loop->use_texture) - pglTexCoord2f(v->u, v->v); - pglColor4f(v->r, v->g, v->b, v->a); - pglVertex3f(v->x, v->y, v->z); - } - pglEnd(); - } + + pglDrawArrays(loop->mode, loop->vertexindex, loop->vertexcount); } } pglScalef(1.0f, 1.0f, 1.0f); - pglColor4f(1.0f, 1.0f, 1.0f, 1.0f); + pglColor4ubv(white); + + // bind with 0, so, switch back to normal pointer operation + pglBindBuffer(GL_ARRAY_BUFFER, 0); + + // deactivate color array + pglDisableClientState(GL_COLOR_ARRAY); } EXPORT void HWRAPI(RenderSkyDome) (INT32 tex, INT32 texture_width, INT32 texture_height, FTransform transform) From e7e3c6ccbb83916d5d61a3b3df40d176d9e2aa95 Mon Sep 17 00:00:00 2001 From: toaster Date: Sun, 3 Nov 2019 10:23:21 +0000 Subject: [PATCH 67/74] Slightly unrelated to the express purpose of the branch, but since I was here, and I noticed it was a problem when ~~playing~~ testing with md3s in ACZ: Don't draw the midtextures for horizon lines. --- src/hardware/hw_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 7e400b7dd..41256d853 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1972,7 +1972,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) { // Single sided line... Deal only with the middletexture (if one exists) gr_midtexture = R_GetTextureNum(gr_sidedef->midtexture); - if (gr_midtexture) + if (gr_midtexture && gr_linedef->special != 41) // Ignore horizon line for OGL { { fixed_t texturevpeg; From ef886e4b80c6d91950e74fc4eb8cfccfc6ac2272 Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 4 Nov 2019 13:11:04 +0000 Subject: [PATCH 68/74] Fix TC_DASHMODE and associated not being applied in GL. (Won't conflict with md3 branch because these lines weren't modified there!) --- src/hardware/hw_main.c | 9 +++++++++ src/hardware/hw_md2.c | 19 ++++++++++++------- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index f2658707d..4b4011eea 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5755,6 +5755,15 @@ static void HWR_ProjectSprite(mobj_t *thing) // New colormap stuff for skins Tails 06-07-2002 if (thing->colorized) vis->colormap = R_GetTranslationColormap(TC_RAINBOW, thing->color, GTC_CACHE); + else if (thing->player && thing->player->dashmode >= DASHMODE_THRESHOLD + && (thing->player->charflags & SF_DASHMODE) + && ((leveltime/2) & 1)) + { + if (thing->player->charflags & SF_MACHINE) + vis->colormap = R_GetTranslationColormap(TC_DASHMODE, 0, GTC_CACHE); + else + vis->colormap = R_GetTranslationColormap(TC_RAINBOW, thing->color, GTC_CACHE); + } else if (thing->skin && thing->sprite == SPR_PLAY) // This thing is a player! { size_t skinnum = (skin_t*)thing->skin-skins; diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index b847fdbc3..490ed318a 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1397,16 +1397,21 @@ void HWR_DrawMD2(gr_vissprite_t *spr) } else if (spr->mobj->color) { - if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) + if (spr->mobj->colorized) + skinnum = TC_RAINBOW; + else if (spr->mobj->player && spr->mobj->player->dashmode >= DASHMODE_THRESHOLD + && (spr->mobj->player->charflags & SF_DASHMODE) + && ((leveltime/2) & 1)) { - if (spr->mobj->colorized) - skinnum = TC_RAINBOW; + if (spr->mobj->player->charflags & SF_MACHINE) + skinnum = TC_DASHMODE; else - { - skinnum = (INT32)((skin_t*)spr->mobj->skin-skins); - } + skinnum = TC_RAINBOW; } - else skinnum = TC_DEFAULT; + else if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) + skinnum = (INT32)((skin_t*)spr->mobj->skin-skins); + else + skinnum = TC_DEFAULT; } HWR_GetBlendedTexture(gpatch, (GLPatch_t *)md2->blendgrpatch, skinnum, spr->colormap, (skincolors_t)spr->mobj->color); } From 8ac49d8855a07ce1855ba626454eb7db86c01a26 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 4 Nov 2019 12:21:53 -0300 Subject: [PATCH 69/74] add gr_modelinterpolation --- src/hardware/hw_main.h | 1 + src/hardware/hw_md2.c | 6 +++++- src/r_main.c | 1 + src/v_video.c | 7 ++++--- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index 5abf10f42..3a0a58427 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -83,6 +83,7 @@ extern consvar_t cv_grcoronasize; #endif extern consvar_t cv_grfov; extern consvar_t cv_grmodels; +extern consvar_t cv_grmodelinterpolation; extern consvar_t cv_grfog; extern consvar_t cv_grfogcolor; extern consvar_t cv_grfogdensity; diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 94abef06d..5fbc1ad53 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -840,11 +840,15 @@ static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT static boolean HWR_CanInterpolateModel(mobj_t *mobj, model_t *model) { + if (cv_grmodelinterpolation.value == 2) // Always + return true; return model->interpolate[(mobj->frame & FF_FRAMEMASK)]; } static boolean HWR_CanInterpolateSprite2(modelspr2frames_t *spr2frame) { + if (cv_grmodelinterpolation.value == 2) // Always + return true; return spr2frame->interpolate; } @@ -1101,7 +1105,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) #ifdef USE_MODEL_NEXTFRAME #define INTERPOLERATION_LIMIT TICRATE/4 - if (cv_grmodels.value == 1 && tics <= durs && tics <= INTERPOLERATION_LIMIT) + if (cv_grmodelinterpolation.value && tics <= durs && tics <= INTERPOLERATION_LIMIT) { if (durs > INTERPOLERATION_LIMIT) durs = INTERPOLERATION_LIMIT; diff --git a/src/r_main.c b/src/r_main.c index 1a5e402b5..3ed509af5 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1216,6 +1216,7 @@ void R_RegisterEngineStuff(void) CV_RegisterVar(&cv_grcoronas); CV_RegisterVar(&cv_grcoronasize); #endif + CV_RegisterVar(&cv_grmodelinterpolation); CV_RegisterVar(&cv_grmodels); CV_RegisterVar(&cv_grspritebillboarding); CV_RegisterVar(&cv_grskydome); diff --git a/src/v_video.c b/src/v_video.c index 8e977f25d..7f99cfd32 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -89,6 +89,7 @@ static void CV_Gammaxxx_ONChange(void); // but they won't do anything. static CV_PossibleValue_t grgamma_cons_t[] = {{1, "MIN"}, {255, "MAX"}, {0, NULL}}; static CV_PossibleValue_t grsoftwarefog_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "LightPlanes"}, {0, NULL}}; +static CV_PossibleValue_t grmodelinterpolation_cons_t[] = {{0, "Off"}, {1, "Sometimes"}, {2, "Always"}, {0, NULL}}; consvar_t cv_grfovchange = {"gr_fovchange", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grfog = {"gr_fog", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -107,9 +108,9 @@ consvar_t cv_grcoronas = {"gr_coronas", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, consvar_t cv_grcoronasize = {"gr_coronasize", "1", CV_SAVE| CV_FLOAT, 0, NULL, 0, NULL, NULL, 0, 0, NULL}; #endif -static CV_PossibleValue_t CV_MD2[] = {{0, "Off"}, {1, "On"}, {2, "Old"}, {0, NULL}}; -// console variables in development -consvar_t cv_grmodels = {"gr_models", "Off", CV_SAVE, CV_MD2, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_grmodels = {"gr_models", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_grmodelinterpolation = {"gr_modelinterpolation", "Sometimes", CV_SAVE, grmodelinterpolation_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; + consvar_t cv_grspritebillboarding = {"gr_spritebillboarding", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grskydome = {"gr_skydome", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; #endif From d45ed97e504ec6fdff6eaaad5dae17f61821efea Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 4 Nov 2019 12:30:28 -0300 Subject: [PATCH 70/74] Update m_menu.c --- src/m_menu.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 8fe782cac..5f7f8c83c 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1295,18 +1295,21 @@ static menuitem_t OP_ColorOptionsMenu[] = #ifdef HWRENDER static menuitem_t OP_OpenGLOptionsMenu[] = { - {IT_STRING|IT_CVAR, NULL, "Field of view", &cv_grfov, 10}, - {IT_STRING|IT_CVAR, NULL, "Quality", &cv_scr_depth, 20}, - {IT_STRING|IT_CVAR, NULL, "Texture Filter", &cv_grfiltermode, 30}, - {IT_STRING|IT_CVAR, NULL, "Anisotropic", &cv_granisotropicmode,40}, + {IT_STRING|IT_CVAR, NULL, "Models", &cv_grmodels, 10}, + {IT_STRING|IT_CVAR, NULL, "Model interpolation", &cv_grmodelinterpolation, 20}, + + {IT_STRING|IT_CVAR, NULL, "Field of view", &cv_grfov, 40}, + {IT_STRING|IT_CVAR, NULL, "Quality", &cv_scr_depth, 50}, + {IT_STRING|IT_CVAR, NULL, "Texture Filter", &cv_grfiltermode, 60}, + {IT_STRING|IT_CVAR, NULL, "Anisotropic", &cv_granisotropicmode,70}, #if defined (_WINDOWS) && (!((defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL))) - {IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 50}, + {IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 80}, #endif #ifdef ALAM_LIGHTING - {IT_SUBMENU|IT_STRING, NULL, "Lighting...", &OP_OpenGLLightingDef, 70}, + {IT_SUBMENU|IT_STRING, NULL, "Lighting...", &OP_OpenGLLightingDef, 100}, #endif - {IT_SUBMENU|IT_STRING, NULL, "Fog...", &OP_OpenGLFogDef, 80}, - {IT_SUBMENU|IT_STRING, NULL, "Gamma...", &OP_OpenGLColorDef, 90}, + {IT_SUBMENU|IT_STRING, NULL, "Fog...", &OP_OpenGLFogDef, 110}, + {IT_SUBMENU|IT_STRING, NULL, "Gamma...", &OP_OpenGLColorDef, 120}, }; #ifdef ALAM_LIGHTING From 55c6c4f5fe6c2949884288280add57b4e136a090 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 4 Nov 2019 14:36:12 -0300 Subject: [PATCH 71/74] Attempt to fix sky dome --- src/hardware/r_opengl/r_opengl.c | 47 ++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 7bd2b6f9e..1a50854c7 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1418,9 +1418,12 @@ typedef struct vbo_vertex_t *data; } GLSkyVBO; -#define sky_vbo_x (&vbo->data[0].x) -#define sky_vbo_u (&vbo->data[0].u) -#define sky_vbo_r (&vbo->data[0].r) +static const boolean gl_ext_arb_vertex_buffer_object = true; + +#define NULL_VBO_VERTEX ((vbo_vertex_t*)NULL) +#define sky_vbo_x (gl_ext_arb_vertex_buffer_object ? &NULL_VBO_VERTEX->x : &vbo->data[0].x) +#define sky_vbo_u (gl_ext_arb_vertex_buffer_object ? &NULL_VBO_VERTEX->u : &vbo->data[0].u) +#define sky_vbo_r (gl_ext_arb_vertex_buffer_object ? &NULL_VBO_VERTEX->r : &vbo->data[0].r) // The texture offset to be applied to the texture coordinates in SkyVertex(). static int rows, columns; @@ -1431,7 +1434,6 @@ static float delta = 0.0f; static int gl_sky_detail = 16; -static boolean vbo_init = false; static INT32 lasttex = -1; #define MAP_COEFF 128.0f @@ -1564,30 +1566,40 @@ static void RenderDome(INT32 skytexture) rows = 4; columns = 4 * gl_sky_detail; - vbosize = 2 * rows * (columns * 2 + 2) + columns * 2; - // generate a new VBO and get the associated ID - if (!vbo_init) - { - pglGenBuffers(1, &vbo->id); - vbo_init = true; - } + vbosize = 2 * rows * (columns * 2 + 2) + columns * 2; // Build the sky dome! Yes! if (lasttex != skytexture) { + // delete VBO when already exists + if (gl_ext_arb_vertex_buffer_object) + { + if (vbo->id) + pglDeleteBuffers(1, &vbo->id); + } + lasttex = skytexture; gld_BuildSky(rows, columns); - // bind VBO in order to use - pglBindBuffer(GL_ARRAY_BUFFER, vbo->id); + if (gl_ext_arb_vertex_buffer_object) + { + // generate a new VBO and get the associated ID + pglGenBuffers(1, &vbo->id); - // upload data to VBO - pglBufferData(GL_ARRAY_BUFFER, vbosize * sizeof(vbo->data[0]), vbo->data, GL_STATIC_DRAW); + // bind VBO in order to use + pglBindBuffer(GL_ARRAY_BUFFER, vbo->id); + + // upload data to VBO + pglBufferData(GL_ARRAY_BUFFER, vbosize * sizeof(vbo->data[0]), vbo->data, GL_STATIC_DRAW); + } } + // bind VBO in order to use + if (gl_ext_arb_vertex_buffer_object) + pglBindBuffer(GL_ARRAY_BUFFER, vbo->id); + // activate and specify pointers to arrays - pglBindBuffer(GL_ARRAY_BUFFER, vbo->id); pglVertexPointer(3, GL_FLOAT, sizeof(vbo->data[0]), sky_vbo_x); pglTexCoordPointer(2, GL_FLOAT, sizeof(vbo->data[0]), sky_vbo_u); pglColorPointer(4, GL_UNSIGNED_BYTE, sizeof(vbo->data[0]), sky_vbo_r); @@ -1616,7 +1628,8 @@ static void RenderDome(INT32 skytexture) pglColor4ubv(white); // bind with 0, so, switch back to normal pointer operation - pglBindBuffer(GL_ARRAY_BUFFER, 0); + if (gl_ext_arb_vertex_buffer_object) + pglBindBuffer(GL_ARRAY_BUFFER, 0); // deactivate color array pglDisableClientState(GL_COLOR_ARRAY); From 4ff769704ada561ccfc5b083e21ad4bec73d3286 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 5 Nov 2019 10:28:19 -0300 Subject: [PATCH 72/74] function renaming --- src/hardware/hw_main.c | 8 +++--- src/hardware/hw_md2.c | 58 +++++++++++++++--------------------------- src/hardware/hw_md2.h | 8 +++--- src/r_things.c | 4 +-- 4 files changed, 30 insertions(+), 48 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 41256d853..a1e8e5949 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5429,14 +5429,14 @@ static void HWR_DrawSprites(void) if (!cv_grmodels.value || md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound || md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale < 0.0f) HWR_DrawSprite(spr); else - HWR_DrawMD2(spr); + HWR_DrawModel(spr); } else { if (!cv_grmodels.value || md2_models[spr->mobj->sprite].notfound || md2_models[spr->mobj->sprite].scale < 0.0f) HWR_DrawSprite(spr); else - HWR_DrawMD2(spr); + HWR_DrawModel(spr); } } } @@ -6604,13 +6604,13 @@ void HWR_Startup(void) // do this once if (!startupdone) { - CONS_Printf("HWR_Startup()\n"); + CONS_Printf("HWR_Startup()...\n"); HWR_InitPolyPool(); // add console cmds & vars HWR_AddEngineCommands(); HWR_InitTextureCache(); - HWR_InitMD2(); + HWR_InitModels(); #ifdef ALAM_LIGHTING HWR_InitLight(); diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 5fbc1ad53..64468d77f 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -351,7 +351,7 @@ static GrTextureFormat_t PCX_Load(const char *filename, int *w, int *h, } // -----------------+ -// md2_loadTexture : Download a pcx or png texture for MD2 models +// md2_loadTexture : Download a pcx or png texture for models // -----------------+ static void md2_loadTexture(md2_t *model) { @@ -455,7 +455,7 @@ static void md2_loadBlendTexture(md2_t *model) // Don't spam the console, or the OS with fopen requests! static boolean nomd2s = false; -void HWR_InitMD2(void) +void HWR_InitModels(void) { size_t i; INT32 s; @@ -463,7 +463,7 @@ void HWR_InitMD2(void) char name[18], filename[32]; float scale, offset; - CONS_Printf("InitMD2()...\n"); + CONS_Printf("HWR_InitModels()...\n"); for (s = 0; s < MAXSKINS; s++) { md2_playermodels[s].scale = -1.0f; @@ -497,7 +497,7 @@ void HWR_InitMD2(void) { if (stricmp(name, "PLAY") == 0) { - CONS_Printf("MD2 for sprite PLAY detected in models.dat, use a player skin instead!\n"); + CONS_Printf("Model for sprite PLAY detected in models.dat, use a player skin instead!\n"); continue; } @@ -531,7 +531,7 @@ void HWR_InitMD2(void) } } // no sprite/player skin name found?!? - CONS_Printf("Unknown sprite/player skin %s detected in models.dat\n", name); + //CONS_Printf("Unknown sprite/player skin %s detected in models.dat\n", name); md2found: // move on to next line... continue; @@ -539,7 +539,7 @@ md2found: fclose(f); } -void HWR_AddPlayerMD2(int skin) // For MD2's that were added after startup +void HWR_AddPlayerModel(int skin) // For skins that were added after startup { FILE *f; char name[18], filename[32]; @@ -548,7 +548,7 @@ void HWR_AddPlayerMD2(int skin) // For MD2's that were added after startup if (nomd2s) return; - CONS_Printf("AddPlayerMD2()...\n"); + //CONS_Printf("HWR_AddPlayerModel()...\n"); // read the models.dat file //Filename checking fixed ~Monster Iestyn and Golden @@ -561,7 +561,7 @@ void HWR_AddPlayerMD2(int skin) // For MD2's that were added after startup return; } - // Check for any MD2s that match the names of player skins! + // Check for any model that match the names of player skins! while (fscanf(f, "%19s %31s %f %f", name, filename, &scale, &offset) == 4) { if (stricmp(name, skins[skin].name) == 0) @@ -575,14 +575,13 @@ void HWR_AddPlayerMD2(int skin) // For MD2's that were added after startup } } - //CONS_Printf("MD2 for player skin %s not found\n", skins[skin].name); + //CONS_Printf("Model for player skin %s not found\n", skins[skin].name); md2_playermodels[skin].notfound = true; playermd2found: fclose(f); } - -void HWR_AddSpriteMD2(size_t spritenum) // For MD2s that were added after startup +void HWR_AddSpriteModel(size_t spritenum) // For sprites that were added after startup { FILE *f; // name[18] is used to check for names in the models.dat file that match with sprites or player skins @@ -631,7 +630,6 @@ spritemd2found: // 0.2126 to red // 0.7152 to green // 0.0722 to blue -// (See this same define in k_kart.c!) #define SETBRIGHTNESS(brightness,r,g,b) \ brightness = (UINT8)(((1063*((UINT16)r)/5000) + (3576*((UINT16)g)/5000) + (361*((UINT16)b)/5000)) / 3) @@ -818,47 +816,27 @@ static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT #define NORMALFOG 0x00000000 #define FADEFOG 0x19000000 -// -----------------+ -// HWR_DrawMD2 : Draw MD2 -// : (monsters, bonuses, weapons, lights, ...) -// Returns : -// -----------------+ - /* - wait/stand - death - pain - walk - shoot/fire - - die? - atka? - atkb? - attacka/b/c/d? - res? - run? - */ - static boolean HWR_CanInterpolateModel(mobj_t *mobj, model_t *model) { - if (cv_grmodelinterpolation.value == 2) // Always + if (cv_grmodelinterpolation.value == 2) // Always interpolate return true; return model->interpolate[(mobj->frame & FF_FRAMEMASK)]; } static boolean HWR_CanInterpolateSprite2(modelspr2frames_t *spr2frame) { - if (cv_grmodelinterpolation.value == 2) // Always + if (cv_grmodelinterpolation.value == 2) // Always interpolate return true; return spr2frame->interpolate; } // -// P_GetModelSprite2 (see P_GetSkinSprite2) +// HWR_GetModelSprite2 (see P_GetSkinSprite2) // For non-super players, tries each sprite2's immediate predecessor until it finds one with a number of frames or ends up at standing. // For super players, does the same as above - but tries the super equivalent for each sprite2 before the non-super version. // -static UINT8 P_GetModelSprite2(md2_t *md2, skin_t *skin, UINT8 spr2, player_t *player) +static UINT8 HWR_GetModelSprite2(md2_t *md2, skin_t *skin, UINT8 spr2, player_t *player) { UINT8 super = 0, i = 0; @@ -909,7 +887,11 @@ static UINT8 P_GetModelSprite2(md2_t *md2, skin_t *skin, UINT8 spr2, player_t *p return spr2; } -void HWR_DrawMD2(gr_vissprite_t *spr) +// +// HWR_DrawModel +// + +void HWR_DrawModel(gr_vissprite_t *spr) { FSurfaceInfo Surf; @@ -1086,7 +1068,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) frame = (spr->mobj->frame & FF_FRAMEMASK); if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY && md2->model->spr2frames) { - spr2 = P_GetModelSprite2(md2, spr->mobj->skin, spr->mobj->sprite2, spr->mobj->player); + spr2 = HWR_GetModelSprite2(md2, spr->mobj->skin, spr->mobj->sprite2, spr->mobj->player); mod = md2->model->spr2frames[spr2].numframes; #ifndef DONTHIDEDIFFANIMLENGTH // by default, different anim length is masked by the mod if (mod > (INT32)((skin_t *)spr->mobj->skin)->sprites[spr2].numframes) diff --git a/src/hardware/hw_md2.h b/src/hardware/hw_md2.h index 57d8026b9..a5f5fc117 100644 --- a/src/hardware/hw_md2.h +++ b/src/hardware/hw_md2.h @@ -44,9 +44,9 @@ typedef struct extern md2_t md2_models[NUMSPRITES]; extern md2_t md2_playermodels[MAXSKINS]; -void HWR_InitMD2(void); -void HWR_DrawMD2(gr_vissprite_t *spr); -void HWR_AddPlayerMD2(INT32 skin); -void HWR_AddSpriteMD2(size_t spritenum); +void HWR_InitModels(void); +void HWR_DrawModel(gr_vissprite_t *spr); +void HWR_AddPlayerModel(INT32 skin); +void HWR_AddSpriteModel(size_t spritenum); #endif // _HW_MD2_H_ diff --git a/src/r_things.c b/src/r_things.c index 1c98ee347..c468e222f 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -441,7 +441,7 @@ void R_AddSpriteDefs(UINT16 wadnum) { #ifdef HWRENDER if (rendermode == render_opengl) - HWR_AddSpriteMD2(i); + HWR_AddSpriteModel(i); #endif // if a new sprite was added (not just replaced) addsprites++; @@ -3180,7 +3180,7 @@ next_token: #ifdef HWRENDER if (rendermode == render_opengl) - HWR_AddPlayerMD2(numskins); + HWR_AddPlayerModel(numskins); #endif numskins++; From ed94549a370d26631244022ea3516726ba9ee348 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 7 Nov 2019 14:15:57 -0800 Subject: [PATCH 73/74] Whitespace --- 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 37debee94..da6152929 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -5305,7 +5305,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) { fixed_t glidespeed = FixedMul(player->actionspd, player->mo->scale); fixed_t playerspeed = player->speed; - + if (player->mo->eflags & MFE_UNDERWATER) { glidespeed >>= 1; From 773f2efdd92f5cf80bf673d26593a1f855ec7464 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 9 Nov 2019 01:45:00 -0300 Subject: [PATCH 74/74] minor fixes --- src/p_spec.c | 2 +- src/r_data.c | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index 7fcdfd1e3..9ab50d947 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -464,7 +464,7 @@ static inline void P_FindAnimatedFlat(INT32 animnum) for (i = 0; i < numlevelflats; i++, foundflats++) { // is that levelflat from the flat anim sequence ? - if ((anims[animnum].istexture) && (foundflats->u.texture.num != 0 && foundflats->u.texture.num != -1) + if ((anims[animnum].istexture) && (foundflats->type == LEVELFLAT_TEXTURE) && ((UINT16)foundflats->u.texture.num >= startflatnum && (UINT16)foundflats->u.texture.num <= endflatnum)) { foundflats->u.texture.basenum = startflatnum; diff --git a/src/r_data.c b/src/r_data.c index fa5e5c43b..5c1d53bd9 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -456,6 +456,7 @@ static UINT8 *R_GenerateTexture(size_t texnum) texture_t *texture; texpatch_t *patch; patch_t *realpatch; + boolean dealloc = false; int x, x1, x2, i, width, height; size_t blocksize; column_t *patchcol; @@ -487,10 +488,7 @@ static UINT8 *R_GenerateTexture(size_t texnum) #ifndef NO_PNG_LUMPS if (R_IsLumpPNG((UINT8 *)realpatch, lumplength)) - { - realpatch = R_PNGToPatch((UINT8 *)realpatch, lumplength, NULL, false); goto multipatch; - } #endif // Check the patch for holes. @@ -579,9 +577,14 @@ static UINT8 *R_GenerateTexture(size_t texnum) lumpnum = patch->lump; lumplength = W_LumpLengthPwad(wadnum, lumpnum); realpatch = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE); + dealloc = false; + #ifndef NO_PNG_LUMPS if (R_IsLumpPNG((UINT8 *)realpatch, lumplength)) + { realpatch = R_PNGToPatch((UINT8 *)realpatch, lumplength, NULL, false); + dealloc = true; + } #endif x1 = patch->originx; @@ -619,6 +622,9 @@ static UINT8 *R_GenerateTexture(size_t texnum) colofs[x] = LONG((x * texture->height) + (texture->width*4)); ColumnDrawerPointer(patchcol, block + LONG(colofs[x]), patch, texture->height, height); } + + if (dealloc) + Z_Free(realpatch); } done: