diff --git a/polymer/build/include/build.h b/polymer/build/include/build.h index b5c760713..6a6e9c10c 100644 --- a/polymer/build/include/build.h +++ b/polymer/build/include/build.h @@ -153,6 +153,8 @@ typedef struct BPACK typedef struct BPACK { unsigned long mdanimtims; short mdanimcur; + short mdcurframe, mdoldframe; + short mdsmooth; short angoff; short pitch, roll; long xoff, yoff, zoff; @@ -277,13 +279,13 @@ SPRITE VARIABLES: EXTERN short nextspritesect[MAXSPRITES], nextspritestat[MAXSPRITES]; Example: if the linked lists look like the following: - �������������������������������Ŀ + ???????????????????????????????? Sector lists: Status lists: - �������������������������������Ĵ + ???????????????????????????????J Sector0: 4, 5, 8 Status0: 2, 0, 8 Sector1: 16, 2, 0, 7 Status1: 4, 5, 16, 7, 3, 9 Sector2: 3, 9 - �������������������������������� + ???????????????????????????????? Notice that each number listed above is shown exactly once on both the left and right side. This is because any sprite that exists must be in some sector, and must have some kind of status that you define. @@ -501,6 +503,7 @@ extern long r_glowmapping; extern long r_vertexarrays; extern long r_vbos; extern long r_vbocount; +extern long r_animsmoothing; #endif void hicinit(void); diff --git a/polymer/build/include/glbuild.h b/polymer/build/include/glbuild.h index 269bf6033..51b2e255e 100644 --- a/polymer/build/include/glbuild.h +++ b/polymer/build/include/glbuild.h @@ -55,6 +55,7 @@ extern void (APIENTRY * bglPolygonOffset)( GLfloat factor, GLfloat units ); extern void (APIENTRY * bglPolygonMode)( GLenum face, GLenum mode ); extern void (APIENTRY * bglEnable)( GLenum cap ); extern void (APIENTRY * bglDisable)( GLenum cap ); +extern void (APIENTRY * bglGetDoublev)( GLenum pname, GLdouble *params ); extern void (APIENTRY * bglGetFloatv)( GLenum pname, GLfloat *params ); extern void (APIENTRY * bglGetIntegerv)( GLenum pname, GLint *params ); extern void (APIENTRY * bglPushAttrib)( GLbitfield mask ); @@ -79,7 +80,9 @@ extern void (APIENTRY * bglPushMatrix)( void ); extern void (APIENTRY * bglPopMatrix)( void ); extern void (APIENTRY * bglLoadIdentity)( void ); extern void (APIENTRY * bglLoadMatrixf)( const GLfloat *m ); +extern void (APIENTRY * bglLoadMatrixd)( const GLdouble *m ); extern void (APIENTRY * bglMultMatrixf)( const GLfloat *m ); +extern void (APIENTRY * bglMultMatrixd)( const GLdouble *m ); extern void (APIENTRY * bglRotatef)(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); extern void (APIENTRY * bglScalef)(GLfloat x, GLfloat y, GLfloat z); extern void (APIENTRY * bglTranslatef)(GLfloat x, GLfloat y, GLfloat z); @@ -172,17 +175,19 @@ extern void* (APIENTRY * bglMapBufferARB)(GLenum target, GLenum access); extern GLboolean (APIENTRY * bglUnmapBufferARB)(GLenum target); // GLU -extern void (APIENTRY * bgluTessBeginContour) (GLUtesselator* tess); -extern void (APIENTRY * bgluTessBeginPolygon) (GLUtesselator* tess, GLvoid* data); -extern void (APIENTRY * bgluTessCallback) (GLUtesselator* tess, GLenum which, void (PR_CALLBACK CallBackFunc)()); -extern void (APIENTRY * bgluTessEndContour) (GLUtesselator* tess); -extern void (APIENTRY * bgluTessEndPolygon) (GLUtesselator* tess); -extern void (APIENTRY * bgluTessNormal) (GLUtesselator* tess, GLdouble valueX, GLdouble valueY, GLdouble valueZ); -extern void (APIENTRY * bgluTessProperty) (GLUtesselator* tess, GLenum which, GLdouble data); -extern void (APIENTRY * bgluTessVertex) (GLUtesselator* tess, GLdouble *location, GLvoid* data); -extern GLUtesselator* (APIENTRY * bgluNewTess) (void); -extern void (APIENTRY * bgluPerspective) (GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar); -extern const GLubyte * (APIENTRY * bgluErrorString) (GLenum error); +extern void (APIENTRY * bgluTessBeginContour) (GLUtesselator* tess); +extern void (APIENTRY * bgluTessBeginPolygon) (GLUtesselator* tess, GLvoid* data); +extern void (APIENTRY * bgluTessCallback) (GLUtesselator* tess, GLenum which, void (PR_CALLBACK CallBackFunc)()); +extern void (APIENTRY * bgluTessEndContour) (GLUtesselator* tess); +extern void (APIENTRY * bgluTessEndPolygon) (GLUtesselator* tess); +extern void (APIENTRY * bgluTessNormal) (GLUtesselator* tess, GLdouble valueX, GLdouble valueY, GLdouble valueZ); +extern void (APIENTRY * bgluTessProperty) (GLUtesselator* tess, GLenum which, GLdouble data); +extern void (APIENTRY * bgluTessVertex) (GLUtesselator* tess, GLdouble *location, GLvoid* data); +extern GLUtesselator* (APIENTRY * bgluNewTess) (void); + +extern void (APIENTRY * bgluPerspective) (GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar); + +extern const GLubyte * (APIENTRY * bgluErrorString) (GLenum error); #ifdef RENDERTYPEWIN // Windows diff --git a/polymer/build/include/polymer.h b/polymer/build/include/polymer.h index aaddbba85..233d50738 100644 --- a/polymer/build/include/polymer.h +++ b/polymer/build/include/polymer.h @@ -84,6 +84,7 @@ extern int updatesectors; int polymer_init(void); void polymer_glinit(void); void polymer_loadboard(void); +void polymer_drawroom(short sectnum); void polymer_drawrooms(long daposx, long daposy, long daposz, short daang, long dahoriz, short dacursectnum, int root); void polymer_rotatesprite(long sx, long sy, long z, short a, short picnum, signed char dashade, char dapalnum, char dastat, long cx1, long cy1, long cx2, long cy2); void polymer_drawmaskwall(long damaskwallcnt); @@ -102,7 +103,7 @@ int polymer_initwall(short wallnum); void polymer_updatewall(short wallnum); void polymer_drawwall(short wallnum); // HSR -void polymer_extractfrustum(void); +void polymer_extractfrustum(GLdouble* modelview, GLdouble* projection); int polymer_portalinfrustum(short wallnum); void polymer_addcliplane(_equation clip, _equation left, _equation right, float refx, float refy); int polymer_wallincliplanes(short wallnum); diff --git a/polymer/build/src/glbuild.c b/polymer/build/src/glbuild.c index a6acae4cc..0b9004331 100644 --- a/polymer/build/src/glbuild.c +++ b/polymer/build/src/glbuild.c @@ -26,6 +26,7 @@ void (APIENTRY * bglPolygonOffset)( GLfloat factor, GLfloat units ); void (APIENTRY * bglPolygonMode)( GLenum face, GLenum mode ); void (APIENTRY * bglEnable)( GLenum cap ); void (APIENTRY * bglDisable)( GLenum cap ); +void (APIENTRY * bglGetDoublev)( GLenum pname, GLdouble *params ); void (APIENTRY * bglGetFloatv)( GLenum pname, GLfloat *params ); void (APIENTRY * bglGetIntegerv)( GLenum pname, GLint *params ); void (APIENTRY * bglPushAttrib)( GLbitfield mask ); @@ -50,7 +51,9 @@ void (APIENTRY * bglPushMatrix)( void ); void (APIENTRY * bglPopMatrix)( void ); void (APIENTRY * bglLoadIdentity)( void ); void (APIENTRY * bglLoadMatrixf)( const GLfloat *m ); +void (APIENTRY * bglLoadMatrixd)( const GLdouble *m ); void (APIENTRY * bglMultMatrixf)( const GLfloat *m ); +void (APIENTRY * bglMultMatrixd)( const GLdouble *m ); void (APIENTRY * bglRotatef)(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); void (APIENTRY * bglScalef)(GLfloat x, GLfloat y, GLfloat z); void (APIENTRY * bglTranslatef)(GLfloat x, GLfloat y, GLfloat z); @@ -252,6 +255,7 @@ int loadgldriver(const char *driver) bglPolygonMode = GETPROC("glPolygonMode"); bglEnable = GETPROC("glEnable"); bglDisable = GETPROC("glDisable"); + bglGetDoublev = GETPROC("glGetDoublev"); bglGetFloatv = GETPROC("glGetFloatv"); bglGetIntegerv = GETPROC("glGetIntegerv"); bglPushAttrib = GETPROC("glPushAttrib"); @@ -276,7 +280,9 @@ int loadgldriver(const char *driver) bglPopMatrix = GETPROC("glPopMatrix"); bglLoadIdentity = GETPROC("glLoadIdentity"); bglLoadMatrixf = GETPROC("glLoadMatrixf"); + bglLoadMatrixd = GETPROC("glLoadMatrixd"); bglMultMatrixf = GETPROC("glMultMatrixf"); + bglMultMatrixd = GETPROC("glMultMatrixd"); bglRotatef = GETPROC("glRotatef"); bglScalef = GETPROC("glScalef"); bglTranslatef = GETPROC("glTranslatef"); @@ -413,6 +419,7 @@ int unloadgldriver(void) bglPolygonMode = NULL; bglEnable = NULL; bglDisable = NULL; + bglGetDoublev = NULL; bglGetFloatv = NULL; bglGetIntegerv = NULL; bglPushAttrib = NULL; @@ -437,7 +444,9 @@ int unloadgldriver(void) bglPopMatrix = NULL; bglLoadIdentity = NULL; bglLoadMatrixf = NULL; + bglLoadMatrixd = NULL; bglMultMatrixf = NULL; + bglMultMatrixd = NULL; bglRotatef = NULL; bglScalef = NULL; bglTranslatef = NULL; diff --git a/polymer/build/src/mdsprite.c b/polymer/build/src/mdsprite.c index 03e7f7196..9a6cf1099 100644 --- a/polymer/build/src/mdsprite.c +++ b/polymer/build/src/mdsprite.c @@ -859,6 +859,7 @@ static void updateanimation (md2model *m, spritetype *tspr) { mdanim_t *anim; long i, j; + int fps; if (mdpause) { @@ -880,25 +881,49 @@ if (!anim) { m->interpol = 0; return; } { spriteext[tspr->owner].mdanimcur = (short)anim->startframe; spriteext[tspr->owner].mdanimtims = mdtims; - m->cframe = m->nframe = anim->startframe; m->interpol = 0; - return; + if (!r_animsmoothing) + { + m->cframe = m->nframe = anim->startframe; + return; + } + spriteext[tspr->owner].mdsmooth = 1; } - i = (mdtims-spriteext[tspr->owner].mdanimtims)*((anim->fpssc*timerticspersec)/120); + if (spriteext[tspr->owner].mdsmooth) + fps = anim->fpssc / r_animsmoothing; + else + fps = anim->fpssc; + + i = (mdtims-spriteext[tspr->owner].mdanimtims)*((fps*timerticspersec)/120); j = ((anim->endframe+1-anim->startframe)<<16); //Just in case you play the game for a VERY long time... if (i < 0) { i = 0; spriteext[tspr->owner].mdanimtims = mdtims; } //compare with j*2 instead of j to ensure i stays > j-65536 for MDANIM_ONESHOT - if ((i >= j+j) && (anim->fpssc)) //Keep mdanimtims close to mdtims to avoid the use of MOD - spriteext[tspr->owner].mdanimtims += j/((anim->fpssc*timerticspersec)/120); + if ((i >= j+j) && (fps)) //Keep mdanimtims close to mdtims to avoid the use of MOD + spriteext[tspr->owner].mdanimtims += j/((fps*timerticspersec)/120); if (anim->flags&MDANIM_ONESHOT) { if (i > j-65536) i = j-65536; } else { if (i >= j) { i -= j; if (i >= j) i %= j; } } - m->cframe = (i>>16)+anim->startframe; - m->nframe = m->cframe+1; if (m->nframe > anim->endframe) m->nframe = anim->startframe; + if (r_animsmoothing) + { + m->nframe = (i>>16)+anim->startframe; + if (m->nframe != spriteext[tspr->owner].mdcurframe) + { + spriteext[tspr->owner].mdoldframe = spriteext[tspr->owner].mdcurframe; + spriteext[tspr->owner].mdcurframe = m->nframe; + } + m->cframe = spriteext[tspr->owner].mdoldframe; + if (m->nframe > anim->startframe) + spriteext[tspr->owner].mdsmooth = 0; + } + else + { + m->cframe = (i>>16)+anim->startframe; + m->nframe = m->cframe+1; if (m->nframe > anim->endframe) m->nframe = anim->startframe; + } m->interpol = ((float)(i&65535))/65536.f; } diff --git a/polymer/build/src/polymer.c b/polymer/build/src/polymer.c index 259ca5553..45d500bab 100644 --- a/polymer/build/src/polymer.c +++ b/polymer/build/src/polymer.c @@ -20,6 +20,11 @@ short cursky; // CONTROL float frustum[16]; // left right top bottom +GLdouble modelviewmatrix[16]; +GLdouble projectionmatrix[16]; +GLint viewport[4]; +GLint portal[4]; + _cliplane *cliplanes; int cliplanecount, maxcliplanecount; @@ -77,6 +82,8 @@ void polymer_glinit(void) bglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); bglViewport(0, 0, xdim, ydim); + bglGetIntegerv(GL_VIEWPORT, viewport); + // texturing bglEnable(GL_TEXTURE_2D); bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); @@ -94,6 +101,9 @@ void polymer_glinit(void) bglLoadIdentity(); bgluPerspective((float)(pr_fov) / (2048.0f / 360.0f), (float)xdim / (float)ydim, 0.001f, 1000000.0f); + // get the new projection matrix + bglGetDoublev(GL_PROJECTION_MATRIX, projectionmatrix); + bglMatrixMode(GL_MODELVIEW); bglLoadIdentity(); @@ -175,11 +185,18 @@ void polymer_drawrooms(long daposx, long daposy, long daposz, sho bglScalef(1.0f / 1000.0f, 1.0f / 16000.0f, 1.0f / 1000.0f); bglTranslatef(pos[0], pos[1], pos[2]); + // get the new modelview + bglGetDoublev(GL_MODELVIEW_MATRIX, modelviewmatrix); + if (pr_frustumculling) - polymer_extractfrustum(); + polymer_extractfrustum(modelviewmatrix, projectionmatrix); + + // initialize the portal to the whole viewport + memcpy(portal, viewport, sizeof(GLint) * 4); cliplanecount = 0; + // game tic if (updatesectors || 1) { i = 0; @@ -198,6 +215,7 @@ void polymer_drawrooms(long daposx, long daposy, long daposz, sho updatesectors = 0; } + // external view (editor) if (dacursectnum == -1) { i = 0; @@ -216,6 +234,7 @@ void polymer_drawrooms(long daposx, long daposy, long daposz, sho return; } + // unflag all sectors i = 0; while (i < numsectors) { @@ -223,7 +242,9 @@ void polymer_drawrooms(long daposx, long daposy, long daposz, sho i++; } - prsectors[dacursectnum]->drawingstate = 2; // SEED OF LIFE + polymer_drawroom(dacursectnum); + + /*prsectors[dacursectnum]->drawingstate = 2; // SEED OF LIFE drawnsectors = 1; while (drawnsectors > 0) @@ -243,20 +264,11 @@ void polymer_drawrooms(long daposx, long daposy, long daposz, sho j = 0; while (j < sec->wallnum) { - if (((pr_frustumculling == 0) || polymer_portalinfrustum(sec->wallptr + j)) && - ((pr_cliplanes == 0) || polymer_wallincliplanes(sec->wallptr + j))) + if ((pr_frustumculling == 0) || polymer_portalinfrustum(sec->wallptr + j)) { polymer_drawwall(sec->wallptr + j); if ((wal->nextsector != -1) && (prsectors[wal->nextsector]) && (prsectors[wal->nextsector]->drawingstate == 0)) prsectors[wal->nextsector]->drawingstate = 1; - if (wal->nextsector == -1 && pr_cliplanes) - { // add a 2D cliplane for map limits - polymer_addcliplane(equation(wal->x, wal->y, wall[wal->point2].x, wall[wal->point2].y), - equation(daposx, daposy, wal->x, wal->y), - equation(daposx, daposy, wall[wal->point2].x, wall[wal->point2].y), - (float)(daposx + wal->x + wall[wal->point2].x) / 3.0f, - (float)(daposy + wal->y + wall[wal->point2].y) / 3.0f); - } } j++; @@ -276,11 +288,50 @@ void polymer_drawrooms(long daposx, long daposy, long daposz, sho prsectors[i]->drawingstate = 2; i++; } - } + }*/ if (pr_verbosity >= 3) OSD_Printf("PR : Rooms drawn.\n"); } +void polymer_drawroom(short sectnum) +{ + int i, j; + sectortype *sec; + walltype *wal; + GLint curportal[4]; + + sec = §or[i]; + wal = &wall[sec->wallptr]; + + memcpy(curportal, portal, sizeof(GLint) * 4); + + // first draw the sector + polymer_drawsector(sectnum); + prsectors[sectnum]->drawingstate = 1; + + i = 0; + while (i < sec->wallnum) + { + if (polymer_checkportal(sec->wallptr + i)) + { + polymer_drawwall(sec->wallptr + i); + if ((wal->nextsector != -1) && (prsectors[wal->nextsector]->drawingstate == 0)) + polymer_drawroom(wal->nextsector); + memcpy(portal, curportal, sizeof(GLint) * 4); + } + i++; + wal = &wall[sec->wallptr + i]; + } + + +} + +int polymer_checkportal(short wallnum) +{ // Returns 1 if the wall is in the current portal and sets the current portal to the wall, returns 0 otherwise + +} + + void polymer_rotatesprite(long sx, long sy, long z, short a, short picnum, signed char dashade, char dapalnum, char dastat, long cx1, long cy1, long cx2, long cy2) { } @@ -977,17 +1028,15 @@ void polymer_drawwall(short wallnum) } // HSR -void polymer_extractfrustum(void) +void polymer_extractfrustum(GLdouble* modelview, GLdouble* projection) { - GLfloat matrix[16]; + GLdouble matrix[16]; int i; bglMatrixMode(GL_TEXTURE); - bglGetFloatv(GL_PROJECTION_MATRIX, matrix); - bglLoadMatrixf(matrix); - bglGetFloatv(GL_MODELVIEW_MATRIX, matrix); - bglMultMatrixf(matrix); - bglGetFloatv(GL_TEXTURE_MATRIX, matrix); + bglLoadMatrixd(projection); + bglMultMatrixd(modelview); + bglGetDoublev(GL_TEXTURE_MATRIX, matrix); bglLoadIdentity(); i = 0; diff --git a/polymer/build/src/polymost.c b/polymer/build/src/polymost.c index dc6ff6e64..d19acc1cc 100644 --- a/polymer/build/src/polymost.c +++ b/polymer/build/src/polymost.c @@ -162,6 +162,8 @@ long r_vertexarrays = 1; long r_vbos = 0; long r_vbocount = 64; +// model animation smoothing cvar +long r_animsmoothing = 0; static float fogresult, ofogresult, fogcol[4]; @@ -5375,6 +5377,12 @@ static int osdcmd_polymostvars(const osdfuncparm_t *parm) else r_vbocount = val; return OSDCMD_OK; } + else if (!Bstrcasecmp(parm->name, "r_animsmoothing")) { + if (showval) { OSD_Printf("r_animsmoothing is %d\n", r_animsmoothing); } + else if (val < 1) { OSD_Printf("Value out of range.\n"); } + else r_animsmoothing = val; + return OSDCMD_OK; + } else if (!Bstrcasecmp(parm->name, "glpolygonmode")) { if (showval) { OSD_Printf("glpolygonmode is %d\n", glpolygonmode); } else glpolygonmode = val; @@ -5464,6 +5472,7 @@ void polymost_initosdfuncs(void) OSD_RegisterFunction("r_vertexarrays","r_vertexarrays: enable/disable using vertex arrays when drawing models",osdcmd_polymostvars); OSD_RegisterFunction("r_vbos","r_vbos: enable/disable using Vertex Buffer Objects when drawing models",osdcmd_polymostvars); OSD_RegisterFunction("r_vbocount","r_vbocount: sets the number of Vertex Buffer Objects to use when drawing models",osdcmd_polymostvars); + OSD_RegisterFunction("r_animsmoothing","r_animsmoothing: enable/disable model animation smoothing",osdcmd_polymostvars); #endif OSD_RegisterFunction("usemodels","usemodels: enable/disable model rendering in >8-bit mode",osdcmd_polymostvars); OSD_RegisterFunction("usehightile","usehightile: enable/disable hightile texture rendering in >8-bit mode",osdcmd_polymostvars); diff --git a/polymer/eduke32/source/config.c b/polymer/eduke32/source/config.c index 10ff989d4..4e87f6530 100644 --- a/polymer/eduke32/source/config.c +++ b/polymer/eduke32/source/config.c @@ -291,6 +291,7 @@ void CONFIG_SetDefaults(void) ud.viewbob = 1; ud.weaponsway = 1; ud.weaponswitch = 3; // new+empty + ud.angleinterpolation = 50; UseJoystick = 0; UseMouse = 1; VoiceToggle = 2; @@ -685,6 +686,8 @@ int32 CONFIG_ReadSetup(void) SCRIPT_GetNumber(scripthandle, "Screen Setup", "GLVBOs", &r_vbos); SCRIPT_GetNumber(scripthandle, "Screen Setup", "GLVBOCount", &r_vbocount); + SCRIPT_GetNumber(scripthandle, "Screen Setup", "GLAnimationSmoothing", &r_animsmoothing); + dummy = usemodels; SCRIPT_GetNumber(scripthandle, "Screen Setup", "UseModels",&dummy); usemodels = dummy != 0; @@ -722,6 +725,8 @@ int32 CONFIG_ReadSetup(void) SCRIPT_GetNumber(scripthandle, "Misc", "UsePrecache",&dummy); useprecache = dummy != 0; + SCRIPT_GetNumber(scripthandle, "Misc","AngleInterpolation",&ud.angleinterpolation); + // weapon choices are defaulted in checkcommandline, which may override them if (!CommandWeaponChoice) for (i=0;i<10;i++) @@ -825,6 +830,7 @@ void CONFIG_WriteSetup(void) SCRIPT_PutNumber(scripthandle, "Misc", "UsePrecache",useprecache,false,false); SCRIPT_PutNumber(scripthandle, "Misc", "ViewBobbing",ud.viewbob,false,false); SCRIPT_PutNumber(scripthandle, "Misc", "WeaponSway",ud.weaponsway,false,false); + SCRIPT_PutNumber(scripthandle, "Misc", "AngleInterpolation",ud.angleinterpolation,false,false); SCRIPT_PutNumber(scripthandle, "Screen Setup", "Detail",ud.detail,false,false); #if defined(POLYMOST) && defined(USE_OPENGL) @@ -844,6 +850,8 @@ void CONFIG_WriteSetup(void) SCRIPT_PutNumber(scripthandle, "Screen Setup", "GLVertexArrays", r_vertexarrays,false,false); SCRIPT_PutNumber(scripthandle, "Screen Setup", "GLVBOs", r_vbos,false,false); SCRIPT_PutNumber(scripthandle, "Screen Setup", "GLVBOCount", r_vbocount,false,false); + + SCRIPT_PutNumber(scripthandle, "Screen Setup", "GLAnimationSmoothing",r_animsmoothing,false,false); #endif #ifdef RENDERTYPEWIN SCRIPT_PutNumber(scripthandle, "Screen Setup", "MaxRefreshFreq",maxrefreshfreq,false,false); diff --git a/polymer/eduke32/source/duke3d.h b/polymer/eduke32/source/duke3d.h index b9730663c..d31dade0e 100644 --- a/polymer/eduke32/source/duke3d.h +++ b/polymer/eduke32/source/duke3d.h @@ -366,7 +366,7 @@ struct user_defs { int32 entered_name,screen_tilting,shadows,fta_on,executions,auto_run; int32 coords,tickrate,levelstats,m_coop,coop,screen_size,lockout,crosshair; - int32 wchoice[MAXPLAYERS][MAX_WEAPONS],playerai; + int32 wchoice[MAXPLAYERS][MAX_WEAPONS],playerai,angleinterpolation; int32 respawn_monsters,respawn_items,respawn_inventory,recstat,monsters_off,brightness; int32 m_respawn_items,m_respawn_monsters,m_respawn_inventory,m_recstat,m_monsters_off,detail; @@ -502,7 +502,7 @@ struct spriteinterpolate { long x; long y; long z; - int ang; + short ang, oldang, angdir, angdif; }; extern struct spriteinterpolate sprpos[MAXSPRITES]; diff --git a/polymer/eduke32/source/game.c b/polymer/eduke32/source/game.c index 114bbc0bb..c113d4825 100644 --- a/polymer/eduke32/source/game.c +++ b/polymer/eduke32/source/game.c @@ -4250,7 +4250,7 @@ int EGS(int whatsect,long s_x,long s_y,long s_z,int s_pn,int s_s,int s_xr,int s_ sprpos[i].x = sprite[i].x; sprpos[i].y = sprite[i].y; sprpos[i].z = sprite[i].z; - sprpos[i].ang = sprite[i].ang; + sprpos[i].ang = sprpos[i].oldang = sprite[i].ang; if (actorscrptr[s_pn]) { @@ -4385,7 +4385,7 @@ int spawn(int j, int pn) sprpos[i].x = sprite[i].x; sprpos[i].y = sprite[i].y; sprpos[i].z = sprite[i].z; - sprpos[i].ang = sprite[i].ang; + sprpos[i].ang = sprpos[i].oldang = sprite[i].ang; if (PN != SPEAKER && PN != LETTER && PN != DUCK && PN != TARGET && PN != TRIPBOMB && PN != VIEWSCREEN && PN != VIEWSCREEN2 && (CS&48)) if (!(PN >= CRACK1 && PN <= CRACK4)) @@ -6772,6 +6772,14 @@ PALONLY: t->z = sprpos[i].z+mulscale16((long)(s->z-sprpos[i].z),smoothratio); t->ang = sprpos[i].ang+mulscale16((long)(s->ang-sprpos[i].ang),smoothratio); #endif + if (ud.angleinterpolation) + { + if (sprpos[i].ang != sprpos[i].oldang) + t->ang = (sprpos[i].oldang + (mulscale16((long)(sprpos[i].angdif),smoothratio) * sprpos[i].angdir)) & 2047; + else + t->ang = sprpos[i].ang; + } + if (t4) { l = *(long *)(t4+8); diff --git a/polymer/eduke32/source/gameexec.c b/polymer/eduke32/source/gameexec.c index c8e1c5502..43f2f81e3 100644 --- a/polymer/eduke32/source/gameexec.c +++ b/polymer/eduke32/source/gameexec.c @@ -6385,6 +6385,8 @@ void LoadActor(long iActor) void execute(int iActor,int iPlayer,long lDist) { + short temp, temp2; + g_i = iActor; // Sprite ID g_p = iPlayer; // Player ID g_x = lDist; // ?? @@ -6440,6 +6442,21 @@ void execute(int iActor,int iPlayer,long lDist) sprpos[g_i].ang = g_sp->ang; #endif + if (ud.angleinterpolation) + { + temp = (g_sp->ang & 2047) - sprpos[g_i].ang; + sprpos[g_i].oldang = sprpos[g_i].ang; + if (temp) + { + temp2 = temp/klabs(temp); + if (klabs(temp) > 1024) temp2 = -(temp2); + sprpos[g_i].angdir = temp2; + sprpos[g_i].angdif = min(ud.angleinterpolation,klabs(temp)); + sprpos[g_i].ang += sprpos[g_i].angdif * sprpos[g_i].angdir; + sprpos[g_i].ang &= 2047; + } + } + if (g_sp->statnum == 1) { if (badguy(g_sp)) diff --git a/polymer/eduke32/source/osdcmds.c b/polymer/eduke32/source/osdcmds.c index b77ce9036..3865546fa 100644 --- a/polymer/eduke32/source/osdcmds.c +++ b/polymer/eduke32/source/osdcmds.c @@ -643,6 +643,7 @@ cvar[] = { "cl_weaponsway", "cl_weaponsway: enable/disable player weapon swaying\n", (void*)&ud.weaponsway, CVAR_BOOL, 0, 0, 1 }, { "cl_weaponswitch", "cl_weaponswitch: enable/disable auto weapon switching", (void*)&ud.weaponswitch, CVAR_INT|256, 0, 0, 3 }, + { "cl_angleinterpolation", "cl_angleinterpolation: enable/disable angle interpolation", (void*)&ud.angleinterpolation, CVAR_INT, 0, 0, 256 }, #if defined(POLYMOST) && defined(USE_OPENGL) { "r_anamorphic", "r_anamorphic: enable/disable widescreen mode", (void*)&glwidescreen, CVAR_BOOL, 0, 0, 1 }, { "r_projectionhack", "r_projectionhack: enable/disable projection hack", (void*)&glprojectionhacks, CVAR_BOOL, 0, 0, 1 },