From 97a0cb2a1060559a614fa5baa2ab3a77871c243c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 4 Apr 2021 10:33:29 +0200 Subject: [PATCH] - handle voxel rotation in the backend to enable it for all games. This was previously only present in the Blood module and missed in Exhumed from upstream so the entire option was rather pointless. Fixes #290 --- source/build/include/buildtypes.h | 7 ++++++- source/build/include/mdsprite.h | 2 +- source/build/include/polymost.h | 1 + source/build/src/mdsprite.cpp | 2 +- source/build/src/polymost.cpp | 7 +++++-- source/build/src/voxmodel.cpp | 11 +++++++++-- source/core/gamecontrol.h | 1 + source/games/blood/src/animatesprite.cpp | 6 +++--- source/games/blood/src/view.cpp | 1 + source/games/duke/src/render.cpp | 1 + source/games/exhumed/src/view.cpp | 1 + source/games/sw/src/draw.cpp | 1 + 12 files changed, 31 insertions(+), 10 deletions(-) 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) {