From ee70dad305a94709c877e776d723aee64d023cb5 Mon Sep 17 00:00:00 2001 From: Franklin Wei Date: Fri, 9 Aug 2019 20:08:10 -0400 Subject: quake: merge some fixed-point optimizations from PocketQuake The PocketQuake project, available below, has some nice fixed-point code: https://web.archive.org/web/20150412233306/http://quake.pocketmatrix.com/PocketQuake0062_src.zip I'd like to see most of them merged into our Quake port. This commit gives +0.9FPS on ipod6g. (A big change given that it was running at only 9.7FPS to begin with!) Change-Id: I91931bdd5c22f14fb28616de938a03b4e7d7b076 --- apps/plugins/sdl/progs/quake/FixedPointMath.h | 246 ++++++++++++++++++++ apps/plugins/sdl/progs/quake/d_polyse.c | 99 +++++++- apps/plugins/sdl/progs/quake/mathlib.h | 13 ++ apps/plugins/sdl/progs/quake/model.h | 14 ++ apps/plugins/sdl/progs/quake/quakedef.h | 12 + apps/plugins/sdl/progs/quake/r_bsp.c | 109 ++++++++- apps/plugins/sdl/progs/quake/r_draw.c | 313 ++++++++++++++++++++++++++ apps/plugins/sdl/progs/quake/r_local.h | 9 + apps/plugins/sdl/progs/quake/r_main.c | 50 ++++ apps/plugins/sdl/progs/quake/render.h | 9 + 10 files changed, 867 insertions(+), 7 deletions(-) create mode 100644 apps/plugins/sdl/progs/quake/FixedPointMath.h (limited to 'apps/plugins/sdl/progs') diff --git a/apps/plugins/sdl/progs/quake/FixedPointMath.h b/apps/plugins/sdl/progs/quake/FixedPointMath.h new file mode 100644 index 0000000000..112b1a103b --- /dev/null +++ b/apps/plugins/sdl/progs/quake/FixedPointMath.h @@ -0,0 +1,246 @@ +#ifndef _FIXEDPOINTMATH_H +#define _FIXEDPOINTMATH_H +//Fixed point math routines (16.16) +//Dan East +//01-24-2001 + +#define FPM_PI 205887L +#define FPM_2PI 411775L +#define FPM_E 178144L +#define FPM_ROOT2 74804L +#define FPM_ROOT3 113512L +#define FPM_GOLDEN 106039L +#define FPM_MAX 0x7fff0000 + + +typedef long fixedpoint_t; +typedef long fixedpoint8_24_t; + + +fixedpoint_t fpm_FromFloat(double f); +float fpm_ToFloat(fixedpoint_t fxp); + +fixedpoint_t fpm_FromLong(long l); +long fpm_ToLong(fixedpoint_t fxp); + +fixedpoint_t fpm_Add(fixedpoint_t fxp1, fixedpoint_t fxp2); +fixedpoint_t fpm_Add3(fixedpoint_t fxp1, fixedpoint_t fxp2, fixedpoint_t fxp3); + +fixedpoint_t fpm_Sub(fixedpoint_t fxp1, fixedpoint_t fxp2); + +fixedpoint_t fpm_Mul(fixedpoint_t fxp1, fixedpoint_t fxp2); + +fixedpoint_t fpm_Div(fixedpoint_t fxp1, fixedpoint_t fxp2); +fixedpoint_t fpm_DivInt(fixedpoint_t fxp1, long l); +fixedpoint_t fpm_Abs(fixedpoint_t fxp); + +fixedpoint_t fpm_Ceil(fixedpoint_t fxp); +fixedpoint_t fpm_Floor(fixedpoint_t fxp); + +fixedpoint_t fpm_Sqrt(fixedpoint_t fxp); +fixedpoint_t fpm_Sqr(fixedpoint_t fxp); + +fixedpoint_t fpm_Inv(fixedpoint_t fxp); + +fixedpoint_t fpm_Sin(fixedpoint_t fxp); +fixedpoint_t fpm_Cos(fixedpoint_t fxp); +fixedpoint_t fpm_Tan(fixedpoint_t fxp); +fixedpoint_t fpm_ATan(fixedpoint_t fxp); +//These take degrees +fixedpoint_t fpm_SinDeg(fixedpoint_t fxp); +fixedpoint_t fpm_CosDeg(fixedpoint_t fxp); +fixedpoint_t fpm_TanDeg(fixedpoint_t fxp); +fixedpoint_t fpm_ATanDeg(fixedpoint_t fxp); + + +#define FPM_FROMFLOAT(f) fpm_FromFloat(f) +#define FPM_FROMFLOATC(f) ((long)((f) * 65536.0 )) //Constant version +#define FPM_TOFLOAT(fxp) fpm_ToFloat(fxp) + +#define FPM_FROMLONG(l) fpm_FromLong(l) +#define FPM_FROMLONGC(l) ((l)<<16) //Constant version +#define FPM_TOLONG(l) fpm_ToLong(l) + +#define FPM_ADD(f1, f2) fpm_Add(f1, f2) +#define FPM_ADD3(f1, f2, f3) fpm_Add3(f1, f2, f3) +#define FPM_INC(f1) ((f1)=FPM_ADD(f1, FPM_FROMLONG(1))) + +#define FPM_SUB(f1, f2) fpm_Sub(f1, f2) +#define FPM_DEC(f1) ((f1)=FPM_SUB(f1, FPM_FROMLONG(1))) + +#define FPM_MUL(f1, f2) fpm_Mul(f1, f2) + +#define FPM_DIV(n, d) fpm_Div(n, d) +#define FPM_DIVINT(n, d) fpm_DivInt(n, d) + +#define FPM_ABS(fxp) fpm_Abs(fxp) + +#define FPM_CEIL(fxp) fpm_Ceil(fxp) +#define FPM_FLOOR(fxp) fpm_Floor(fxp) + +#define FPM_SQRT(fxp) fpm_Sqrt(fxp) +#define FPM_SQR(fxp) fpm_Sqr(fxp) + +#define FPM_INV(fxp) fpm_Inv(fxp) + +//These take radians +#define FPM_SIN(r) fpm_Sin(r) +#define FPM_COS(r) fpm_Cos(r) +#define FPM_TAN(r) fpm_Tan(r) +#define FPM_ATAN(r) fpm_ATan(r) + +//These take degrees +#define FPM_SIN_DEG(d) fpm_SinDeg(d) +#define FPM_COS_DEG(d) fpm_CosDeg(d) +#define FPM_TAN_DEG(d) fpm_TanDeg(d) +#define FPM_ATAN_DEG(d) fpm_ATanDeg(d) + +fixedpoint8_24_t fpm_FromFloat(double f); +float fpm_ToFloat8_24(fixedpoint8_24_t fxp); + +fixedpoint8_24_t fpm_FromLong8_24(long l); +long fpm_ToLong8_24(fixedpoint8_24_t fxp); + +fixedpoint8_24_t fpm_FromFixedPoint(fixedpoint_t fxp); +fixedpoint_t fpm_ToFixedPoint(fixedpoint8_24_t fxp); + +fixedpoint8_24_t fpm_Add8_24(fixedpoint8_24_t fxp1, fixedpoint8_24_t fxp2); +fixedpoint8_24_t fpm_Add38_24(fixedpoint8_24_t fxp1, fixedpoint8_24_t fxp2, fixedpoint8_24_t fxp3); + +fixedpoint8_24_t fpm_Sub8_24(fixedpoint8_24_t fxp1, fixedpoint8_24_t fxp2); + +fixedpoint8_24_t fpm_Mul8_24(fixedpoint8_24_t fxp1, fixedpoint8_24_t fxp2); +fixedpoint_t fpm_MulMixed8_24(fixedpoint8_24_t fxp1, fixedpoint_t fxp2); + +fixedpoint8_24_t fpm_Div8_24(fixedpoint8_24_t fxp1, fixedpoint8_24_t fxp2); +fixedpoint8_24_t fpm_DivInt8_24(fixedpoint8_24_t fxp1, long l); +fixedpoint8_24_t fpm_DivInt64_8_24(fixedpoint8_24_t fxp1, long long l); + +fixedpoint8_24_t fpm_Abs8_24(fixedpoint8_24_t fxp); + +fixedpoint8_24_t fpm_Ceil8_24(fixedpoint8_24_t fxp); +fixedpoint8_24_t fpm_Floor8_24(fixedpoint8_24_t fxp); + +fixedpoint8_24_t fpm_Sqrt8_24(fixedpoint8_24_t fxp); +fixedpoint8_24_t fpm_Sqr8_24(fixedpoint8_24_t fxp); + +fixedpoint8_24_t fpm_Inv8_24(fixedpoint8_24_t fxp); + + +#define FPM_FROMFLOAT8_24(f) fpm_FromFloat8_24(f) +#define FPM_FROMFLOATC8_24(f) ((long)((f) * 16777216.0 )) //Constant version +#define FPM_TOFLOAT8_24(fxp) fpm_ToFloat8_24(fxp) + +#define FPM_FROMLONG8_24(l) fpm_FromLong8_24(l) +#define FPM_FROMLONGC8_24(l) ((l)<<24) //Constant version +#define FPM_TOLONG8_24(l) fpm_ToLong8_24(l) + + +/* +extern __int64 FPM_TMPVAR_INT64; + + #define FPM_FROMFLOAT(f) ((long)((f) * 65536.0 )) //+0.5 +#define FPM_TOFLOAT(fxp) (((float)(fxp)) / 65536.0) + +#define FPM_FROMLONG(l) ((l)<<16) +#define FPM_TOLONG(l) ((l)<0?(-(long)((l)^0xffffffff)>>16):(((l)>>16)&0x0000ffff)) + +#define FPM_ADD(f1, f2) ((f1)+(f2)) +#define FPM_ADD3(f1, f2, f3) ((f1)+(f2)+(f3)) +#define FPM_INC(f1) ((f1)=FPM_ADD(f1, FPM_FROMLONG(1))) + +#define FPM_SUB(f1, f2) ((f1)-(f2)) +#define FPM_DEC(f1) ((f1)=FPM_SUB(f1, FPM_FROMLONG(1))) + +#define FPM_MUL(f1, f2) (((f1)>>8)*((f2)>>8)) +//#define FPM_MUL(f1, f2) ((fixedpoint_t)((FPM_TMPVAR_INT64=(f1))*(f2))>>16) +//#define FPM_MUL(f1, f2) (((f1)*(f2))>>16) +//TODO: This needs to be done without copying to another var +#define FPM_DIV(n, d) ((fixedpoint_t)(((FPM_TMPVAR_INT64=(n))<<16)/d)) +#define FPM_DIVINT(n, d) ((fixedpoint_t)((n)/(d))) +//#define FPM_DIV(n, d) ((long)(((__int64)n)<<16)/(d)) + +#define FPM_ABS(fxp) (abs(fxp)) + +//TODO: could be more effecient +#define FPM_CEIL(fxp) ((fxp)&0x0000ffff?((fxp)<=0?((fxp)&0xffff0000):(((fxp)&0xffff0000)+FPM_FROMLONG(1))):(fxp)) +#define FPM_FLOOR(fxp) ((fxp)&0x0000ffff?((fxp)<0?(((fxp)&0xffff0000)-FPM_FROMLONG(1)):((fxp)&0xffff0000)):(fxp)) + +//TODO: Implement sqrt mathematically instead of converting to float and back +#define FPM_SQRT(fxp) (FPM_FROMFLOAT(sqrt(FPM_TOFLOAT(fxp)))) +#define FPM_SQR(fxp) (FPM_MUL(fxp,fxp)>>16) + +#define FPM_INV(fxp) (FPM_DIV(0x10000, fxp)) +//TODO: Calc trig functions (or lookup) instead of converting to float and back +//These take radians +#define FPM_SIN(r) (FPM_FROMFLOAT(sin(FPM_TOFLOAT(r)))) +#define FPM_COS(r) (FPM_FROMFLOAT(cos(FPM_TOFLOAT(r)))) +#define FPM_TAN(r) (FPM_FROMFLOAT(tan(FPM_TOFLOAT(r)))) +#define FPM_ATAN(r) (FPM_FROMFLOAT(atan(FPM_TOFLOAT(r)))) + +//These take degrees +#define FPM_SIN_DEG(d) (FPM_SIN(FPM_DIV(FPM_MUL(d,FPM_PI),0xB40000))) //0xB40000 = 180.0 +#define FPM_COS_DEG(d) (FPM_COS(FPM_DIV(FPM_MUL(d,FPM_PI),0xB40000))) +#define FPM_TAN_DEG(d) (FPM_TAN(FPM_DIV(FPM_MUL(d,FPM_PI),0xB40000))) +#define FPM_ATAN_DEG(d) (FPM_ATAN(FPM_DIV(FPM_MUL(d,FPM_PI),0xB40000))) + +*/ +/* +#define FPM_PI 3.14 +#define FPM_2PI (3.14*2) +#define FPM_E 178144L +#define FPM_ROOT2 74804L +#define FPM_ROOT3 113512L +#define FPM_GOLDEN 106039L + + +typedef float fixedpoint_t; +//This variable must be declared in one of the implementation files. +extern __int64 FPM_TMPVAR_INT64; + +#define FPM_FROMFLOAT(f) (f) +#define FPM_TOFLOAT(fxp) (fxp) + +#define FPM_FROMLONG(l) ((float)l) +#define FPM_TOLONG(fxp) ((long)fxp) + +#define FPM_ADD(f1, f2) ((f1)+(f2)) +#define FPM_ADD3(f1, f2, f3) ((f1)+(f2)+(f3)) +#define FPM_INC(f1) ((f1)++) + +#define FPM_SUB(f1, f2) ((f1)-(f2)) +#define FPM_DEC(f1) ((f1)--) + +#define FPM_MUL(f1, f2) ((f1)*(f2)) +//#define FPM_MUL(f1, f2) ((fixedpoint_t)((FPM_TMPVAR_INT64=(f1))*(f2))>>16) +//#define FPM_MUL(f1, f2) (((f1)*(f2))>>16) +//TODO: This needs to be done without copying to another var +#define FPM_DIV(n, d) ((n)/(d)) +//#define FPM_DIV(n, d) ((long)(((__int64)n)<<16)/(d)) + +#define FPM_ABS(fxp) (abs(fxp)) + +//TODO: Implement ceil mathematically instead of converting to float and back +#define FPM_CEIL(fxp) (ceil(fxp)) +#define FPM_FLOOR(fxp) (floor(fxp)) + +//TODO: Implement sqrt mathematically instead of converting to float and back +#define FPM_SQRT(fxp) (sqrt(fxp)) +#define FPM_SQR(fxp) ((fxp)*(fxp)) + +#define FPM_INV(fxp) (1/(fxp)) +//TODO: Calc trig functions (or lookup) instead of converting to float and back +//These take radians +#define FPM_SIN(r) (sin(r)) +#define FPM_COS(r) (cos(r)) +#define FPM_TAN(r) (tan(r)) +#define FPM_ATAN(r) (atan(r)) + +//These take degrees +#define FPM_SIN_DEG(d) FPM_SIN(((d)*FPM_PI)/180.0) //0xB40000 = 180.0 +#define FPM_COS_DEG(d) FPM_COS(((d)*FPM_PI)/180.0) +#define FPM_TAN_DEG(d) FPM_TAN(((d)*FPM_PI)/180.0) +#define FPM_ATAN_DEG(d) FPM_ATAN(((d)*FPM_PI)/180.0) +*/ + +#endif //_FIXEDPOINTMATH_H diff --git a/apps/plugins/sdl/progs/quake/d_polyse.c b/apps/plugins/sdl/progs/quake/d_polyse.c index 9acd34b102..f02f9a016e 100644 --- a/apps/plugins/sdl/progs/quake/d_polyse.c +++ b/apps/plugins/sdl/progs/quake/d_polyse.c @@ -122,6 +122,7 @@ void D_PolysetScanLeftEdge (int height); D_PolysetDraw ================ */ +#ifndef USE_PQ_OPT void D_PolysetDraw (void) { spanpackage_t spans[DPS_MAXSPANS + 1 + @@ -140,7 +141,21 @@ void D_PolysetDraw (void) D_DrawNonSubdiv (); } } +#else +//JB: Optimization +//Dan East: May result in image quality loss. Actual performance gain not verified. +void D_PolysetDraw (void) +{ + spanpackage_t spans[DPS_MAXSPANS + 1 + + ((CACHE_SIZE - 1) / sizeof(spanpackage_t)) + 1]; + // one extra because of cache line pretouching + a_spans = (spanpackage_t *) + (((long)&spans[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1)); + + D_DrawNonSubdiv (); +} +#endif /* ================ @@ -528,6 +543,7 @@ void D_PolysetSetUpForLineScan(fixed8_t startvertu, fixed8_t startvertv, D_PolysetCalcGradients ================ */ +#ifndef USE_PQ_OPT4 void D_PolysetCalcGradients (int skinwidth) { float xstepdenominv, ystepdenominv, t0, t1; @@ -583,7 +599,88 @@ void D_PolysetCalcGradients (int skinwidth) a_ststepxwhole = skinwidth * (r_tstepx >> 16) + (r_sstepx >> 16); } - +#else +void D_PolysetCalcGradients (int skinwidth) +{ + //Dan East: Fixed point conversion + int p01_minus_p21, p11_minus_p21, p00_minus_p20, p10_minus_p20, t0, t1; + int tmp, ydenom; + + //float xstepdenominv = (float)(1.0 / (float)d_xdenom); + //float ystepdenominv = -xstepdenominv; + //int checkx, checky; + + p00_minus_p20 = (r_p0[0] - r_p2[0]); + p01_minus_p21 = (r_p0[1] - r_p2[1]); + p10_minus_p20 = (r_p1[0] - r_p2[0]); + p11_minus_p21 = (r_p1[1] - r_p2[1]); + + //xstepdenominv = d_xdenom; + ydenom=-d_xdenom; + //ystepdenominv = -xstepdenominv; + + t0 = (r_p0[4] - r_p2[4]); + t1 = (r_p1[4] - r_p2[4]); + //TODO: Ceil has been removed + tmp=t1 * p01_minus_p21 - t0 * p11_minus_p21; + r_lstepx = tmp / d_xdenom; + if (tmp%d_xdenom) r_lstepx++; + + tmp=t1 * p00_minus_p20 - t0 * p10_minus_p20; + r_lstepy = tmp / ydenom; + if (tmp%ydenom) r_lstepy++; + /* + checkx = (int)ceil((t1 * p01_minus_p21 - t0 * p11_minus_p21) * xstepdenominv); + checky = (int)ceil((t1 * p00_minus_p20 - t0 * p10_minus_p20) * ystepdenominv); + if (checkx-r_lstepx>1||checkx-r_lstepx<-1) + r_lstepx=r_lstepx; + if (checky-r_lstepy>1||checky-r_lstepy<-1) + r_lstepy=r_lstepy; + */ + t0 = (r_p0[2] - r_p2[2]); + t1 = (r_p1[2] - r_p2[2]); + r_sstepx = (t1 * p01_minus_p21 - t0 * p11_minus_p21) / d_xdenom; + r_sstepy = (t1 * p00_minus_p20 - t0* p10_minus_p20) / ydenom; + /* + checkx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) * xstepdenominv); + checky = (int)((t1 * p00_minus_p20 - t0* p10_minus_p20) * ystepdenominv); + if (checkx-r_sstepx>1||checkx-r_sstepx<-1) + r_lstepx=r_lstepx; + if (checky-r_sstepy>1||checky-r_sstepy<-1) + r_lstepy=r_lstepy; + */ + + t0 = (r_p0[3] - r_p2[3]); + t1 = (r_p1[3] - r_p2[3]); + r_tstepx = (t1 * p01_minus_p21 - t0 * p11_minus_p21) / d_xdenom; + r_tstepy = (t1 * p00_minus_p20 - t0 * p10_minus_p20) / ydenom; + /* + checkx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) * xstepdenominv); + checky = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) * ystepdenominv); + if (checkx-r_tstepx>1||checkx-r_tstepx<-1) + r_lstepx=r_lstepx; + if (checky-r_tstepy>1||checky-r_tstepy<-1) + r_lstepy=r_lstepy; + */ + + t0 = (r_p0[5] - r_p2[5]); + t1 = (r_p1[5] - r_p2[5]); + r_zistepx = (t1 * p01_minus_p21 - t0 * p11_minus_p21) / d_xdenom; + r_zistepy = (t1 * p00_minus_p20 - t0 * p10_minus_p20) / ydenom; + /* + checkx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) * xstepdenominv); + checky = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) * ystepdenominv); + if (checkx-r_zistepx>1||checkx-r_zistepx<-1) + r_lstepx=checkx; + if (checky-r_zistepy>1||checky-r_zistepy<-1) + r_lstepy=checky; + */ + + a_sstepxfrac = r_sstepx & 0xFFFF; + a_tstepxfrac = r_tstepx & 0xFFFF; + a_ststepxwhole = skinwidth * (r_tstepx >> 16) + (r_sstepx >> 16); +} +#endif #endif // !id386 diff --git a/apps/plugins/sdl/progs/quake/mathlib.h b/apps/plugins/sdl/progs/quake/mathlib.h index b754966802..5f7ae430f1 100644 --- a/apps/plugins/sdl/progs/quake/mathlib.h +++ b/apps/plugins/sdl/progs/quake/mathlib.h @@ -19,6 +19,19 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // mathlib.h +//Dan East: +#include "FixedPointMath.h" + +#ifdef USE_PQ_OPT +typedef int fpvec3[3]; +#endif + +typedef fixedpoint_t vec3_FPM_t[3]; +typedef fixedpoint8_24_t vec3_8_24FPM_t[3]; +typedef fixedpoint_t vec5_FPM_t[5]; + +//End Dan + typedef float vec_t; typedef vec_t vec3_t[3]; typedef vec_t vec5_t[5]; diff --git a/apps/plugins/sdl/progs/quake/model.h b/apps/plugins/sdl/progs/quake/model.h index 899010f0fb..aa034f958c 100644 --- a/apps/plugins/sdl/progs/quake/model.h +++ b/apps/plugins/sdl/progs/quake/model.h @@ -49,6 +49,16 @@ typedef struct vec3_t position; } mvertex_t; +typedef struct +{ + int position[3]; +} mvertex_fxp_t; + +typedef struct +{ + vec3_FPM_t position; +} mvertex_FPM_t; + #define SIDE_FRONT 0 #define SIDE_BACK 1 #define SIDE_ON 2 @@ -331,6 +341,10 @@ typedef struct model_s int numvertexes; mvertex_t *vertexes; + +#ifdef USE_PQ_OPT2 + mvertex_fxp_t *vertexes_fxp; +#endif int numedges; medge_t *edges; diff --git a/apps/plugins/sdl/progs/quake/quakedef.h b/apps/plugins/sdl/progs/quake/quakedef.h index b16d9b72f3..8328154c0b 100644 --- a/apps/plugins/sdl/progs/quake/quakedef.h +++ b/apps/plugins/sdl/progs/quake/quakedef.h @@ -25,6 +25,18 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #include +#define FIXEDPOINT_OPT // FW: enable fixed-point optimizations + +/* Fixed-point optimizations, thanks to Pocket Quake and Dan East. */ +#ifdef FIXEDPOINT_OPT +#define USE_PQ_OPT +#define USE_PQ_OPT1 +//#define USE_PQ_OPT2 +//#define USE_PQ_OPT3 // don't use +#define USE_PQ_OPT4 +//#define USE_PQ_OPT5 +#endif + #define QUAKE_GAME // as opposed to utilities #undef VERSION diff --git a/apps/plugins/sdl/progs/quake/r_bsp.c b/apps/plugins/sdl/progs/quake/r_bsp.c index f8c38cf601..2940b1a509 100644 --- a/apps/plugins/sdl/progs/quake/r_bsp.c +++ b/apps/plugins/sdl/progs/quake/r_bsp.c @@ -27,6 +27,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // qboolean insubmodel; entity_t *currententity; + +#ifdef USE_PQ_OPT1 +int modelorg_fxp[3]; +#endif + vec3_t modelorg, base_modelorg; // modelorg is the viewpoint reletive to // the currently rendering entity @@ -440,6 +445,10 @@ void R_DrawSubmodelPolygons (model_t *pmodel, int clipflags) } } +#ifdef USE_PQ_OPT1 +int clipplanes_fxp[4][3]; +int clipdist_fxp[4]; +#endif /* ================ @@ -449,11 +458,16 @@ R_RecursiveWorldNode void R_RecursiveWorldNode (mnode_t *node, int clipflags) { int i, c, side, *pindex; - vec3_t acceptpt, rejectpt; mplane_t *plane; msurface_t *surf, **mark; mleaf_t *pleaf; - double d, dot; + double dot; +#ifdef USE_PQ_OPT1 + int d_fxp; +#else + double d; + vec3_t acceptpt, rejectpt; +#endif if (node->contents == CONTENTS_SOLID) return; // solid @@ -477,16 +491,29 @@ void R_RecursiveWorldNode (mnode_t *node, int clipflags) pindex = pfrustum_indexes[i]; +#ifdef USE_PQ_OPT1 + d_fxp=node->minmaxs[pindex[0]]*clipplanes_fxp[i][0]+node->minmaxs[pindex[1]]*clipplanes_fxp[i][1]+node->minmaxs[pindex[2]]*clipplanes_fxp[i][2]; + d_fxp-=clipdist_fxp[i]; + + if (d_fxp <= 0) + return; + + d_fxp=node->minmaxs[pindex[3]]*clipplanes_fxp[i][0]+node->minmaxs[pindex[4]]*clipplanes_fxp[i][1]+node->minmaxs[pindex[5]]*clipplanes_fxp[i][2]; + d_fxp-=clipdist_fxp[i]; + + if (d_fxp >= 0) + clipflags &= ~(1<minmaxs[pindex[0]]; rejectpt[1] = (float)node->minmaxs[pindex[1]]; rejectpt[2] = (float)node->minmaxs[pindex[2]]; - + d = DotProduct (rejectpt, view_clipplanes[i].normal); d -= view_clipplanes[i].dist; - if (d <= 0) + if (d <= 0) return; - + acceptpt[0] = (float)node->minmaxs[pindex[3+0]]; acceptpt[1] = (float)node->minmaxs[pindex[3+1]]; acceptpt[2] = (float)node->minmaxs[pindex[3+2]]; @@ -496,6 +523,7 @@ void R_RecursiveWorldNode (mnode_t *node, int clipflags) if (d >= 0) clipflags &= ~(1<model; r_pcurrentvertbase = clmodel->vertexes; - R_RecursiveWorldNode (clmodel->nodes, 15); +#ifdef USE_PQ_OPT2 + r_pcurrentvertbase_fxp = clmodel->vertexes_fxp; +#endif +#ifdef USE_PQ_OPT1 + //Dan Fixed point conversion stuff + for (i=0; i<4; i++) { + clipplanes_fxp[i][0]=(int)(view_clipplanes[i].normal[0]*65536.0); + clipplanes_fxp[i][1]=(int)(view_clipplanes[i].normal[1]*65536.0); + clipplanes_fxp[i][2]=(int)(view_clipplanes[i].normal[2]*65536.0); + clipdist_fxp[i] =(int)(view_clipplanes[i].dist*65536.0); +#ifdef USE_PQ_OPT2 + view_clipplanes_fxp[i].leftedge=view_clipplanes[i].leftedge; + view_clipplanes_fxp[i].rightedge=view_clipplanes[i].rightedge; + if (!view_clipplanes[i].normal[0]) view_clipplanes_fxp[i].normal[0]=2<<29; + else view_clipplanes_fxp[i].normal[0]=(int)(4096.0f/view_clipplanes[i].normal[0]); + if (!view_clipplanes[i].normal[0]) view_clipplanes_fxp[i].normal[0]=2<<29; + + if (!view_clipplanes[i].normal[1]) view_clipplanes_fxp[i].normal[1]=2<<29; + else view_clipplanes_fxp[i].normal[1]=(int)(4096.0f/view_clipplanes[i].normal[1]); + if (!view_clipplanes[i].normal[1]) view_clipplanes_fxp[i].normal[1]=2<<29; + + if (!view_clipplanes[i].normal[2]) view_clipplanes_fxp[i].normal[2]=2<<29; + else view_clipplanes_fxp[i].normal[2]=(int)(4096.0f/view_clipplanes[i].normal[2]); + if (!view_clipplanes[i].normal[2]) view_clipplanes_fxp[i].normal[2]=2<<29; + + view_clipplanes_fxp[i].dist=(int)(view_clipplanes[i].dist*128.0f); +#endif +#if defined(_X86_)&&defined(DEBUG) + LogFloat(view_clipplanes[i].normal[0], "view_clipplanes[i].normal[0]", i, -1); + LogFloat(view_clipplanes[i].normal[1], "view_clipplanes[i].normal[1]", i, -1); + LogFloat(view_clipplanes[i].normal[2], "view_clipplanes[i].normal[2]", i, -1); +#endif + } +#endif + + R_RecursiveWorldNode (clmodel->nodes, 15); // if the driver wants the polygons back to front, play the visible ones back // in that order diff --git a/apps/plugins/sdl/progs/quake/r_draw.c b/apps/plugins/sdl/progs/quake/r_draw.c index 8789cc015a..c4bf95f112 100644 --- a/apps/plugins/sdl/progs/quake/r_draw.c +++ b/apps/plugins/sdl/progs/quake/r_draw.c @@ -44,6 +44,10 @@ clipplane_t *entity_clipplanes; clipplane_t view_clipplanes[4]; clipplane_t world_clipplanes[16]; +#ifdef USE_PQ_OPT2 +clipplane_fxp_t view_clipplanes_fxp[4]; +#endif + medge_t *r_pedge; qboolean r_leftclipped, r_rightclipped; @@ -67,6 +71,11 @@ float r_nearzi; float r_u1, r_v1, r_lzi1; int r_ceilv1; +#ifdef USE_PQ_OPT1 +int r_u1_fxp, r_v1_fxp, r_lzi1_fxp; +extern int modelorg_fxp[3]; +#endif + qboolean r_lastvertvalid; @@ -250,6 +259,306 @@ void R_EmitEdge (mvertex_t *pv0, mvertex_t *pv1) removeedges[v2] = edge; } +#ifdef USE_PQ_OPT1 +void R_EmitEdge_fxp (mvertex_t *pv0, mvertex_t *pv1) +{ + edge_t *edge, *pcheck; + int u_check; + //float u, u_step; + int u_fxp, u_step_fxp; + //vec3_t local, transformed; + int local_fxp[3], transformed_fxp[3]; + float *world; + int v, v2, ceilv0; + //float scale, lzi0, u0, v0; + int scale_fxp, scale2_fxp, lzi0_fxp, u0_fxp, v0_fxp; + int side; + + if (r_lastvertvalid) + { + u0_fxp = r_u1_fxp; + v0_fxp = r_v1_fxp; + lzi0_fxp = r_lzi1_fxp; + //lzi0 = r_lzi1; + ceilv0 = r_ceilv1; + } + else + { + //world_fxp=(int)(pv0->position[0]*(float)(2^16)); + world = &pv0->position[0]; + + // transform and project + //VectorSubtract (world, modelorg, local); + //Vector Subtract (and convert) + local_fxp[0]=((int)(world[0]*(524288.0)))-modelorg_fxp[0]; + local_fxp[1]=((int)(world[1]*(524288.0)))-modelorg_fxp[1]; + local_fxp[2]=((int)(world[2]*(524288.0)))-modelorg_fxp[2]; + + //TransformVector (local, transformed); + //transformed_fxp[0] = (int)(local_fxp[0]*vright[0])+(int)(local_fxp[1]*vright[1])+(int)(local_fxp[2]*vright[2]); + //transformed_fxp[1] = (int)(local_fxp[0]*vup[0])+(int)(local_fxp[1]*vup[1])+(int)(local_fxp[2]*vup[2]); + //transformed_fxp[2] = (int)(local_fxp[0]*vpn[0])+(int)(local_fxp[1]*vpn[1])+(int)(local_fxp[2]*vpn[2]); + + transformed_fxp[0] = local_fxp[0]/vright_fxp[0]+local_fxp[1]/vright_fxp[1]+local_fxp[2]/vright_fxp[2]; + //transformed_fxp[0]*=256; + transformed_fxp[1] = local_fxp[0]/vup_fxp[0]+local_fxp[1]/vup_fxp[1]+local_fxp[2]/vup_fxp[2]; + //transformed_fxp[1]*=256; + transformed_fxp[2] = local_fxp[0]/vpn_fxp[0]+local_fxp[1]/vpn_fxp[1]+local_fxp[2]/vpn_fxp[2]; + transformed_fxp[2]*=256; + + if (transformed_fxp[2] < (int)(NEAR_CLIP*1048576.0)) + transformed_fxp[2] = (int)(NEAR_CLIP*1048576.0); + + transformed_fxp[0]/=16; + transformed_fxp[1]/=16; + transformed_fxp[2]/=2048; + + lzi0_fxp=transformed_fxp[2]; + //lzi0 = (float)(1.0 / transformed[2]); + + // FIXME: build x/yscale into transform? + //scale = xscale * lzi0; + //u0 = (xcenter + scale*transformed[0]); + + scale_fxp=xscale_fxp/transformed_fxp[2]; //9.23 / 24.8 = 17.15 + scale2_fxp=transformed_fxp[0]*(scale_fxp); // 25.7 * 17.15 = 10.22 + + if (transformed_fxp[0]<0) { + if (scale2_fxp>0) scale2_fxp=-511*4194304; + } else { + if (scale2_fxp<0) scale2_fxp=511*4194304; + } + + u0_fxp=scale2_fxp+xcenter_fxp; + + if (u0_fxp < r_refdef_fvrectx_adj_fxp) + u0_fxp = r_refdef_fvrectx_adj_fxp; + if (u0_fxp > r_refdef_fvrectright_adj_fxp) + u0_fxp = r_refdef_fvrectright_adj_fxp; + + //scale = yscale * lzi0; + //v0 = (ycenter - scale*transformed[1]); + scale_fxp=yscale_fxp/transformed_fxp[2]; //9.23 / 24.8 = 17.15 + scale2_fxp=transformed_fxp[1]*(scale_fxp); // 25.7 * 17.15 = 10.22 + + if (transformed_fxp[1]<0) { + if (scale2_fxp>0) scale2_fxp=-511*4194304; + } else { + if (scale2_fxp<0) scale2_fxp=511*4194304; //255*8388608; + } + + v0_fxp = ycenter_fxp-scale2_fxp; + + if (v0_fxp < r_refdef_fvrecty_adj_fxp) + v0_fxp = r_refdef_fvrecty_adj_fxp; + if (v0_fxp > r_refdef_fvrectbottom_adj_fxp) + v0_fxp = r_refdef_fvrectbottom_adj_fxp; + + ceilv0 = v0_fxp/4194304; + if (v0_fxp&0x3FFFFF) ceilv0++; + } + + //world(pv1->position[0]*(float)(2^16)); + world = &pv1->position[0]; + +// transform and project + //VectorSubtract (world, modelorg, local); + //Vector Subtract (and convert) + local_fxp[0]=((int)(world[0]*(524288.0)))-modelorg_fxp[0]; + local_fxp[1]=((int)(world[1]*(524288.0)))-modelorg_fxp[1]; + local_fxp[2]=((int)(world[2]*(524288.0)))-modelorg_fxp[2]; + + //TransformVector (local, transformed); + //transformed_fxp[0] = ((int)(local_fxp[0]*vright[0]))+((int)(local_fxp[1]*vright[1]))+((int)(local_fxp[2]*vright[2])); + //transformed_fxp[1] = ((int)(local_fxp[0]*vup[0]))+((int)(local_fxp[1]*vup[1]))+((int)(local_fxp[2]*vup[2])); + //transformed_fxp[2] = ((int)(local_fxp[0]*vpn[0]))+((int)(local_fxp[1]*vpn[1]))+((int)(local_fxp[2]*vpn[2])); + + transformed_fxp[0] = local_fxp[0]/vright_fxp[0]+local_fxp[1]/vright_fxp[1]+local_fxp[2]/vright_fxp[2]; + //transformed_fxp[0]*=256; + transformed_fxp[1] = local_fxp[0]/vup_fxp[0]+local_fxp[1]/vup_fxp[1]+local_fxp[2]/vup_fxp[2]; + //transformed_fxp[1]*=256; + transformed_fxp[2] = local_fxp[0]/vpn_fxp[0]+local_fxp[1]/vpn_fxp[1]+local_fxp[2]/vpn_fxp[2]; + transformed_fxp[2]*=256; + + //transformed_fxp[2]=-transformed_fxp[2]; + //if (transformed[2] < NEAR_CLIP) + // transformed[2] = (float)NEAR_CLIP; + if (transformed_fxp[2] < (int)(NEAR_CLIP*524288.0)) + transformed_fxp[2] = (int)(NEAR_CLIP*524288.0); + + transformed_fxp[0]/=16; + transformed_fxp[1]/=16; + transformed_fxp[2]/=2048; + + r_lzi1_fxp=transformed_fxp[2]; + //r_lzi1 = (float)(1.0 / transformed[2]); + //scale = xscale * r_lzi1; + + scale_fxp=xscale_fxp/transformed_fxp[2]; //9.23 / 24.8 = 17.15 + scale2_fxp=transformed_fxp[0]*(scale_fxp); // 24.8 * 17.15 = 9.23 //21.11 + + if (transformed_fxp[0]<0) { + if (scale2_fxp>0) scale2_fxp=-511*4194304; + } else { + if (scale2_fxp<0) scale2_fxp=511*4194304; + } + + //r_u1 = (xcenter + scale*transformed[0]); + r_u1_fxp = xcenter_fxp + scale2_fxp; + if (r_u1_fxp < r_refdef_fvrectx_adj_fxp) + r_u1_fxp = r_refdef_fvrectx_adj_fxp; + if (r_u1_fxp > r_refdef_fvrectright_adj_fxp) + r_u1_fxp = r_refdef_fvrectright_adj_fxp; + + //scale = yscale * r_lzi1; + //r_v1 = (ycenter - scale*transformed[1]); + + scale_fxp=yscale_fxp/transformed_fxp[2]; //9.23 / 24.8 = 17.15 + scale2_fxp=transformed_fxp[1]*(scale_fxp); // 23.9 * 17.15 = 9.23 //21.11 + + if (transformed_fxp[1]<0) { + if (scale2_fxp>0) scale2_fxp=-511*4194304; + } else { + if (scale2_fxp<0) scale2_fxp=511*4194304; + } + + r_v1_fxp = ycenter_fxp - scale2_fxp; + if (r_v1_fxp < r_refdef_fvrecty_adj_fxp) + r_v1_fxp = r_refdef_fvrecty_adj_fxp; + if (r_v1_fxp > r_refdef_fvrectbottom_adj_fxp) + r_v1_fxp = r_refdef_fvrectbottom_adj_fxp; + + //if (r_lzi1 > lzi0) + // lzi0 = r_lzi1; + if (r_lzi1_fxp < lzi0_fxp) + lzi0_fxp = r_lzi1_fxp; + + //if (lzi0 > r_nearzi) // for mipmap finding + // r_nearzi = lzi0; + if (128.0/lzi0_fxp > r_nearzi) { // for mipmap finding + //if (!lzi0_fxp) r_nearzi=0; + //else + r_nearzi = (float)(128.0/lzi0_fxp); + } + +// for right edges, all we want is the effect on 1/z + if (r_nearzionly) + return; + + r_emitted = 1; + + //r_ceilv1 = (int) ceil(r_v1); + r_ceilv1 = r_v1_fxp/4194304; + if (r_v1_fxp&0x3FFFFF) r_ceilv1++; + + +// create the edge + if (ceilv0 == r_ceilv1) + { + // we cache unclipped horizontal edges as fully clipped + if (cacheoffset != 0x7FFFFFFF) + { + cacheoffset = FULLY_CLIPPED_CACHED | + (r_framecount & FRAMECOUNT_MASK); + } + + return; // horizontal edge + } + + side = ceilv0 > r_ceilv1; + + edge = edge_p++; + + edge->owner = NULL; + + edge->owner = r_pedge; + + edge->nearzi = (float)(128.0/lzi0_fxp); + + { + //float tmp; + if (side == 0) + { + //int tmp; + // trailing edge (go from p1 to p2) + v = ceilv0; + v2 = r_ceilv1 - 1; + + edge->surfs[0] = surface_p - surfaces; + edge->surfs[1] = 0; + + //u_step = ((r_u1 - u0) / (r_v1 - v0)); + //u = u0 + ((float)v - v0) * u_step; + + u_step_fxp=(r_u1_fxp - u0_fxp) / ((r_v1_fxp - v0_fxp)>>10); //10.22 / 15.12 = 22.10 + u_fxp = u0_fxp + ((v*4194304 - v0_fxp)>>12 * u_step_fxp>>12); + + //tmp=(((r_u1_fxp - u0_fxp)/8388608.0) / ((r_v1_fxp - v0_fxp)/8388608.0)); + //u_step_fxp=(int)(tmp*8388608.0); + //u_fxp = u0_fxp + (((float)v - v0_fxp/8388608.0) * tmp)*8388608.0; + } + else + { + //int tmp; + // leading edge (go from p2 to p1) + v2 = ceilv0 - 1; + v = r_ceilv1; + + edge->surfs[0] = 0; + edge->surfs[1] = surface_p - surfaces; + + //u_step = ((u0 - r_u1) / (v0 - r_v1)); + //u = r_u1 + ((float)v - r_v1) * u_step; + + u_step_fxp = (u0_fxp - r_u1_fxp) / ((v0_fxp - r_v1_fxp)>>10); + u_fxp = r_u1_fxp + ((v*4194304 - r_v1_fxp)>>12 * u_step_fxp>>12); + + //tmp=(((u0_fxp - r_u1_fxp)/8388608.0) / ((v0_fxp - r_v1_fxp)/8388608.0)); + //u_step_fxp = (int)(tmp*8388608.0); + //u_fxp = r_u1_fxp + (((float)v - r_v1_fxp/8388608.0) * tmp)*8388608.0; + } + //edge->u_step = tmp*0x100000; + //edge->u = (int)(/*(u_fxp/65536)*0x100000*/u_fxp/4 + 0xFFFFF); + + edge->u_step = u_step_fxp*1024;///16; //tmp*0x100000; + edge->u = (int)(/*(u_fxp/65536)*0x100000*/u_fxp/4 + 0xFFFFF); +} + +// we need to do this to avoid stepping off the edges if a very nearly +// horizontal edge is less than epsilon above a scan, and numeric error causes +// it to incorrectly extend to the scan, and the extension of the line goes off +// the edge of the screen +// FIXME: is this actually needed? + if (edge->u < r_refdef.vrect_x_adj_shift20) + edge->u = r_refdef.vrect_x_adj_shift20; + if (edge->u > r_refdef.vrectright_adj_shift20) + edge->u = r_refdef.vrectright_adj_shift20; + +// +// sort the edge in normally +// + u_check = edge->u; + if (edge->surfs[0]) + u_check++; // sort trailers after leaders + + if (!newedges[v] || newedges[v]->u >= u_check) + { + edge->next = newedges[v]; + newedges[v] = edge; + } + else + { + pcheck = newedges[v]; + while (pcheck->next && pcheck->next->u < u_check) + pcheck = pcheck->next; + edge->next = pcheck->next; + pcheck->next = edge; + } + + edge->nextremove = removeedges[v2]; + removeedges[v2] = edge; +} +#endif /* ================ @@ -349,7 +658,11 @@ static inline void R_ClipEdge (mvertex_t *pv0, mvertex_t *pv1, clipplane_t *clip } // add the edge +#ifndef USE_PQ_OPT1 R_EmitEdge (pv0, pv1); +#else + R_EmitEdge_fxp (pv0, pv1); +#endif } #endif // !id386 diff --git a/apps/plugins/sdl/progs/quake/r_local.h b/apps/plugins/sdl/progs/quake/r_local.h index 910bdbffc9..ae3416ba2f 100644 --- a/apps/plugins/sdl/progs/quake/r_local.h +++ b/apps/plugins/sdl/progs/quake/r_local.h @@ -96,6 +96,11 @@ typedef struct clipplane_s extern clipplane_t view_clipplanes[4]; +#ifdef USE_PQ_OPT2 +extern clipplane_fxp_t view_clipplanes_fxp[4]; +#endif + + //============================================================================= void R_RenderWorld (void); @@ -277,6 +282,10 @@ extern int r_outofsurfaces; extern int r_outofedges; extern mvertex_t *r_pcurrentvertbase; +extern mvertex_FPM_t *r_pcurrentvertbaseFPM; +#ifdef USE_PQ_OPT2 +extern mvertex_fxp_t *r_pcurrentvertbase_fxp; +#endif extern int r_maxvalidedgeoffset; void R_AliasClipTriangle (mtriangle_t *ptri); diff --git a/apps/plugins/sdl/progs/quake/r_main.c b/apps/plugins/sdl/progs/quake/r_main.c index dc785a850d..7776b46bde 100644 --- a/apps/plugins/sdl/progs/quake/r_main.c +++ b/apps/plugins/sdl/progs/quake/r_main.c @@ -62,6 +62,18 @@ vec3_t vup, base_vup; vec3_t vpn, base_vpn; vec3_t vright, base_vright; vec3_t r_origin; +#ifdef USE_PQ_OPT1 +int vup_fxp[3]; +int vpn_fxp[3]; +int vright_fxp[3]; +int xscale_fxp, yscale_fxp; +int xcenter_fxp, ycenter_fxp; +int r_refdef_fvrectx_adj_fxp; +int r_refdef_fvrectright_adj_fxp; +int r_refdef_fvrecty_adj_fxp; +int r_refdef_fvrectbottom_adj_fxp; +extern int modelorg_fxp[3]; +#endif // // screen size info @@ -421,6 +433,17 @@ void R_ViewChanged (vrect_t *pvrect, int lineadj, float aspect) yscaleinv = 1.0 / yscale; xscaleshrink = (r_refdef.vrect.width-6)/r_refdef.horizontalFieldOfView; yscaleshrink = xscaleshrink*pixelAspect; + +#ifdef USE_PQ_OPT1 + xscale_fxp=(int)(xscale*8388608.0); //9.23 + yscale_fxp=(int)(yscale*8388608.0); //9.23 + xcenter_fxp=(int)(xcenter*4194304.0); //10.22 + ycenter_fxp=(int)(ycenter*4194304.0); //10.22 + r_refdef_fvrectx_adj_fxp=(int)(r_refdef.fvrectx_adj*4194304.0); + r_refdef_fvrectright_adj_fxp=(int)(r_refdef.fvrectright_adj*4194304.0); + r_refdef_fvrecty_adj_fxp=(int)(r_refdef.fvrecty_adj*4194304.0); + r_refdef_fvrectbottom_adj_fxp=(int)(r_refdef.fvrectbottom_adj*4194304.0); +#endif // left side clip screenedge[0].normal[0] = -1.0 / (xOrigin*r_refdef.horizontalFieldOfView); @@ -789,6 +812,33 @@ void R_DrawBEntitiesOnList (void) // FIXME: stop transforming twice R_RotateBmodel (); +#ifdef USE_PQ_OPT1 + modelorg_fxp[0]=(int)(modelorg[0]*524288.0); + modelorg_fxp[1]=(int)(modelorg[1]*524288.0); + modelorg_fxp[2]=(int)(modelorg[2]*524288.0); + + vright_fxp[0]=(int)(256.0/vright[0]); + if (!vright_fxp[0]) vright_fxp[0]=0x7fffffff; + vright_fxp[1]=(int)(256.0/vright[1]); + if (!vright_fxp[1]) vright_fxp[1]=0x7fffffff; + vright_fxp[2]=(int)(256.0/vright[2]); + if (!vright_fxp[2]) vright_fxp[2]=0x7fffffff; + + vpn_fxp[0]=(int)(256.0/vpn[0]); + if (!vpn_fxp[0]) vpn_fxp[0]=0x7fffffff; + vpn_fxp[1]=(int)(256.0/vpn[1]); + if (!vpn_fxp[1]) vpn_fxp[1]=0x7fffffff; + vpn_fxp[2]=(int)(256.0/vpn[2]); + if (!vpn_fxp[2]) vpn_fxp[2]=0x7fffffff; + + vup_fxp[0]=(int)(256.0/vup[0]); + if (!vup_fxp[0]) vup_fxp[0]=0x7fffffff; + vup_fxp[1]=(int)(256.0/vup[1]); + if (!vup_fxp[1]) vup_fxp[1]=0x7fffffff; + vup_fxp[2]=(int)(256.0/vup[2]); + if (!vup_fxp[2]) vup_fxp[2]=0x7fffffff; +#endif + // calculate dynamic lighting for bmodel if it's not an // instanced model if (clmodel->firstmodelsurface != 0) diff --git a/apps/plugins/sdl/progs/quake/render.h b/apps/plugins/sdl/progs/quake/render.h index b5f8382c31..46cd4e326f 100644 --- a/apps/plugins/sdl/progs/quake/render.h +++ b/apps/plugins/sdl/progs/quake/render.h @@ -110,6 +110,15 @@ extern int reinit_surfcache; extern refdef_t r_refdef; extern vec3_t r_origin, vpn, vright, vup; +#ifdef USE_PQ_OPT1 +extern int vpn_fxp[3], vright_fxp[3], vup_fxp[3]; +extern int xscale_fxp, yscale_fxp, xcenter_fxp, ycenter_fxp; +extern int r_refdef_fvrectx_adj_fxp; +extern int r_refdef_fvrectright_adj_fxp; +extern int r_refdef_fvrecty_adj_fxp; +extern int r_refdef_fvrectbottom_adj_fxp; +#endif + extern struct texture_s *r_notexture_mip; -- cgit