diff --git a/source/build/include/buildtypes.h b/source/build/include/buildtypes.h index 1ac86d561..d526315a0 100644 --- a/source/build/include/buildtypes.h +++ b/source/build/include/buildtypes.h @@ -149,6 +149,10 @@ enum CSTAT_SPRITE_RESERVED5 = 1u<<14u, // used by Duke 3D (Polymer), Shadow Warrior, Blood CSTAT_SPRITE_INVISIBLE = 1u<<15u, + + // Raze extensions, using the higher bits to avoid conflitcs with the reserved and undocumented bits above. + CSTAT_SPRITE_MDLROTATE = 1u<<16u, // Only for tsprites: rotate if this is a model or voxel. + }; enum { @@ -180,6 +184,7 @@ enum CSTAT_WALL_RESERVED1 = 1u<<13u, CSTAT_WALL_RESERVED2 = 1u<<14u, // used by Shadow Warrior, Blood CSTAT_WALL_RESERVED3 = 1u<<15u, // used by Shadow Warrior, Blood + }; #endif @@ -202,7 +207,7 @@ struct spritetype }; vec3_t opos; }; - uint16_t cstat; + uint32_t cstat; int16_t picnum; int8_t shade; uint8_t pal, clipdist, blend; diff --git a/source/build/include/mdsprite.h b/source/build/include/mdsprite.h index 1c4882ab3..05cf0b10e 100644 --- a/source/build/include/mdsprite.h +++ b/source/build/include/mdsprite.h @@ -210,7 +210,7 @@ EXTERN voxmodel_t *voxmodels[MAXVOXELS]; void voxfree(voxmodel_t *m); voxmodel_t *voxload(int lumpnum); -int32_t polymost_voxdraw(voxmodel_t *m, tspriteptr_t const tspr); +int32_t polymost_voxdraw(voxmodel_t *m, tspriteptr_t const tspr, bool rotate); int md3postload_polymer(md3model_t* m); //int32_t md_thinoutmodel(int32_t modelid, uint8_t *usedframebitmap); diff --git a/source/build/include/polymost.h b/source/build/include/polymost.h index 41bbc7fbf..ee9a14849 100644 --- a/source/build/include/polymost.h +++ b/source/build/include/polymost.h @@ -11,6 +11,7 @@ extern float gtang; extern double gxyaspect; extern float grhalfxdown10x; extern float gcosang, gsinang, gcosang2, gsinang2; +extern int pm_smoothratio; extern void Polymost_prepare_loadboard(void); diff --git a/source/build/src/mdsprite.cpp b/source/build/src/mdsprite.cpp index 1ce3b78f2..dcd16b5c6 100644 --- a/source/build/src/mdsprite.cpp +++ b/source/build/src/mdsprite.cpp @@ -1648,7 +1648,7 @@ int32_t polymost_mddraw(tspriteptr_t tspr) mdmodel_t *const vm = models[tile2model[Ptile2tile(tspr->picnum, (tspr->owner >= MAXSPRITES) ? tspr->pal : sprite[tspr->owner].pal)].modelid]; if (vm->mdnum == 1) - return polymost_voxdraw((voxmodel_t *)vm,tspr); + return polymost_voxdraw((voxmodel_t *)vm,tspr, false); // can't access rotating info anymore else if (vm->mdnum == 3) return polymost_md3draw((md3model_t *)vm,tspr); return 0; diff --git a/source/build/src/polymost.cpp b/source/build/src/polymost.cpp index c21e2417e..496edb870 100644 --- a/source/build/src/polymost.cpp +++ b/source/build/src/polymost.cpp @@ -36,6 +36,7 @@ CUSTOM_CVARD(Bool, hw_useindexedcolortextures, false, CVAR_ARCHIVE | CVAR_GLOBAL { if (screen) screen->SetTextureFilterMode(); } +int pm_smoothratio; //{ "r_yshearing", "enable/disable y-shearing", (void*)&r_yshearing, CVAR_BOOL, 0, 1 }, disabled because not fully functional @@ -3034,13 +3035,15 @@ void polymost_drawsprite(int32_t snum) { if ((tspr->cstat & 48) != 48 && tiletovox[tspr->picnum] >= 0 && voxmodels[tiletovox[tspr->picnum]]) { - if (polymost_voxdraw(voxmodels[tiletovox[tspr->picnum]], tspr)) return; + int num = tiletovox[tspr->picnum]; + if (polymost_voxdraw(voxmodels[num], tspr, voxrotate[num>>3] & (1<<(num&7)))) return; break; // else, render as flat sprite } if ((tspr->cstat & 48) == 48 && tspr->picnum < MAXVOXELS && voxmodels[tspr->picnum]) { - polymost_voxdraw(voxmodels[tspr->picnum], tspr); + int num = tspr->picnum; + polymost_voxdraw(voxmodels[tspr->picnum], tspr, voxrotate[num >> 3] & (1 << (num & 7))); return; } } diff --git a/source/build/src/voxmodel.cpp b/source/build/src/voxmodel.cpp index 79db18c36..2e3b37e60 100644 --- a/source/build/src/voxmodel.cpp +++ b/source/build/src/voxmodel.cpp @@ -12,6 +12,7 @@ #include "hw_renderstate.h" #include "texturemanager.h" #include "voxels.h" +#include "gamecontrol.h" #include "glbackend/gl_models.h" #include "palette.h" @@ -50,8 +51,7 @@ voxmodel_t *voxload(int lumpnum) } //Draw voxel model as perfect cubes -// Note: This is a hopeless mess that totally forfeits any chance of using a vertex buffer with its messy coordinate adjustments. :( -int32_t polymost_voxdraw(voxmodel_t* m, tspriteptr_t const tspr) +int32_t polymost_voxdraw(voxmodel_t* m, tspriteptr_t const tspr, bool rotate) { float f, g, k0, zoff; @@ -65,6 +65,13 @@ int32_t polymost_voxdraw(voxmodel_t* m, tspriteptr_t const tspr) //updateanimation((md2model *)m,tspr); + if ((tspr->cstat & CSTAT_SPRITE_MDLROTATE) || rotate) + { + int myclock = (PlayClock << 3) + MulScale(4 << 3, pm_smoothratio, 16); + tspr->ang = (tspr->ang + myclock) & 2047; // will be applied in md3_vox_calcmat_common. + } + + vec3f_t m0 = { m->scale, m->scale, m->scale }; vec3f_t a0 = { 0, 0, m->zadd*m->scale }; diff --git a/source/core/gamecontrol.h b/source/core/gamecontrol.h index 66ae96da2..85242b2f7 100644 --- a/source/core/gamecontrol.h +++ b/source/core/gamecontrol.h @@ -14,6 +14,7 @@ extern FString currentGame; extern FString LumpFilter; +extern int PlayClock; class FArgs; extern bool GUICapture; extern bool AppActive; diff --git a/source/games/blood/src/animatesprite.cpp b/source/games/blood/src/animatesprite.cpp index dfe6f84f3..fb9e477a9 100644 --- a/source/games/blood/src/animatesprite.cpp +++ b/source/games/blood/src/animatesprite.cpp @@ -574,8 +574,8 @@ void viewProcessSprites(int32_t cX, int32_t cY, int32_t cZ, int32_t cA, int32_t int const nVoxel = tiletovox[pTSprite->picnum]; - if (nVoxel != -1 && ((voxrotate[nVoxel>>3]&pow2char[nVoxel&7]) != 0 || (picanm[nRootTile].extra&7) == 7)) - pTSprite->ang = (pTSprite->ang+myclock)&2047; + if (nVoxel != -1 && (picanm[nRootTile].extra & 7) == 7) + pTSprite->cstat |= CSTAT_SPRITE_MDLROTATE; // per-sprite rotation setting. } if ((pTSprite->cstat&48) != 48 && hw_models && !(spriteext[nSprite].flags&SPREXT_NOTMD)) @@ -590,7 +590,7 @@ void viewProcessSprites(int32_t cX, int32_t cY, int32_t cZ, int32_t cA, int32_t pTSprite->xoffset += tileLeftOffset(nAnimTile); if ((picanm[nRootTile].extra&7) == 7) - pTSprite->ang = (pTSprite->ang+myclock)&2047; + pTSprite->cstat |= CSTAT_SPRITE_MDLROTATE; // per-sprite rotation setting. } } diff --git a/source/games/blood/src/view.cpp b/source/games/blood/src/view.cpp index 6575d1298..938156aa7 100644 --- a/source/games/blood/src/view.cpp +++ b/source/games/blood/src/view.cpp @@ -467,6 +467,7 @@ void viewDrawScreen(bool sceneonly) gInterpolate = I_GetTimeFrac() * MaxSmoothRatio; } else gInterpolate = MaxSmoothRatio; + pm_smoothratio = (int)gInterpolate; if (cl_interpolate) { diff --git a/source/games/duke/src/render.cpp b/source/games/duke/src/render.cpp index 321e2bc31..42bcc0c07 100644 --- a/source/games/duke/src/render.cpp +++ b/source/games/duke/src/render.cpp @@ -474,6 +474,7 @@ void displayrooms(int snum, double smoothratio) int tiltcs = 0; // JBF 20030807 p = &ps[snum]; + pm_smoothratio = (int)smoothratio; if (automapMode == am_full || p->cursectnum == -1) return; diff --git a/source/games/exhumed/src/view.cpp b/source/games/exhumed/src/view.cpp index bd17491b4..8d3e7cf20 100644 --- a/source/games/exhumed/src/view.cpp +++ b/source/games/exhumed/src/view.cpp @@ -207,6 +207,7 @@ void DrawView(double smoothRatio, bool sceneonly) zbob = bsin(2 * bobangle, -3); DoInterpolations(smoothRatio / 65536.); + pm_smoothratio = (int)smoothRatio; int nPlayerSprite = PlayerList[nLocalPlayer].nSprite; int nPlayerOldCstat = sprite[nPlayerSprite].cstat; diff --git a/source/games/sw/src/draw.cpp b/source/games/sw/src/draw.cpp index 6763fd752..915788055 100644 --- a/source/games/sw/src/draw.cpp +++ b/source/games/sw/src/draw.cpp @@ -1492,6 +1492,7 @@ drawscreen(PLAYERp pp, double smoothratio) PreDraw(); PreUpdatePanel(smoothratio); + pm_smoothratio = (int)smoothratio; if (!ScreenSavePic) {