mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-13 16:07:55 +00:00
Merge branch 'master' of https://github.com/rheit/zdoom
This commit is contained in:
commit
b709db3fd3
21 changed files with 638 additions and 1140 deletions
|
@ -197,7 +197,6 @@ else()
|
||||||
else()
|
else()
|
||||||
option( NO_GTK "Disable GTK+ dialogs (Not applicable to Windows)" )
|
option( NO_GTK "Disable GTK+ dialogs (Not applicable to Windows)" )
|
||||||
option( DYN_GTK "Load GTK+ at runtime instead of compile time" ON )
|
option( DYN_GTK "Load GTK+ at runtime instead of compile time" ON )
|
||||||
option( VALGRIND "Add special Valgrind sequences to self-modifying code" )
|
|
||||||
|
|
||||||
set( FMOD_SEARCH_PATHS
|
set( FMOD_SEARCH_PATHS
|
||||||
/usr/local/include
|
/usr/local/include
|
||||||
|
@ -816,6 +815,7 @@ set( FASTMATH_PCH_SOURCES
|
||||||
r_segs.cpp
|
r_segs.cpp
|
||||||
r_sky.cpp
|
r_sky.cpp
|
||||||
r_things.cpp
|
r_things.cpp
|
||||||
|
r_walldraw.cpp
|
||||||
s_advsound.cpp
|
s_advsound.cpp
|
||||||
s_environment.cpp
|
s_environment.cpp
|
||||||
s_playlist.cpp
|
s_playlist.cpp
|
||||||
|
|
|
@ -20,11 +20,6 @@ static __forceinline SDWORD Scale (SDWORD a, SDWORD b, SDWORD c)
|
||||||
return (SDWORD)(((SQWORD)a*b)/c);
|
return (SDWORD)(((SQWORD)a*b)/c);
|
||||||
}
|
}
|
||||||
|
|
||||||
static __forceinline SDWORD MulScale (SDWORD a, SDWORD b, SDWORD c)
|
|
||||||
{
|
|
||||||
return (SDWORD)(((SQWORD)a*b)>>c);
|
|
||||||
}
|
|
||||||
|
|
||||||
static __forceinline SDWORD MulScale1 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 1); }
|
static __forceinline SDWORD MulScale1 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 1); }
|
||||||
static __forceinline SDWORD MulScale2 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 2); }
|
static __forceinline SDWORD MulScale2 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 2); }
|
||||||
static __forceinline SDWORD MulScale3 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 3); }
|
static __forceinline SDWORD MulScale3 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 3); }
|
||||||
|
@ -60,11 +55,6 @@ static __forceinline SDWORD MulScale32 (SDWORD a, SDWORD b) { return (SDWORD)(((
|
||||||
|
|
||||||
static __forceinline DWORD UMulScale16 (DWORD a, DWORD b) { return (DWORD)(((QWORD)a * b) >> 16); }
|
static __forceinline DWORD UMulScale16 (DWORD a, DWORD b) { return (DWORD)(((QWORD)a * b) >> 16); }
|
||||||
|
|
||||||
static __forceinline SDWORD DMulScale (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD s)
|
|
||||||
{
|
|
||||||
return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> s);
|
|
||||||
}
|
|
||||||
|
|
||||||
static __forceinline SDWORD DMulScale1 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 1); }
|
static __forceinline SDWORD DMulScale1 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 1); }
|
||||||
static __forceinline SDWORD DMulScale2 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 2); }
|
static __forceinline SDWORD DMulScale2 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 2); }
|
||||||
static __forceinline SDWORD DMulScale3 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 3); }
|
static __forceinline SDWORD DMulScale3 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 3); }
|
||||||
|
@ -98,53 +88,6 @@ static __forceinline SDWORD DMulScale30 (SDWORD a, SDWORD b, SDWORD c, SDWORD d)
|
||||||
static __forceinline SDWORD DMulScale31 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 31); }
|
static __forceinline SDWORD DMulScale31 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 31); }
|
||||||
static __forceinline SDWORD DMulScale32 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 32); }
|
static __forceinline SDWORD DMulScale32 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 32); }
|
||||||
|
|
||||||
static __forceinline SDWORD TMulScale1 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 1); }
|
|
||||||
static __forceinline SDWORD TMulScale2 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 2); }
|
|
||||||
static __forceinline SDWORD TMulScale3 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 3); }
|
|
||||||
static __forceinline SDWORD TMulScale4 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 4); }
|
|
||||||
static __forceinline SDWORD TMulScale5 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 5); }
|
|
||||||
static __forceinline SDWORD TMulScale6 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 6); }
|
|
||||||
static __forceinline SDWORD TMulScale7 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 7); }
|
|
||||||
static __forceinline SDWORD TMulScale8 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 8); }
|
|
||||||
static __forceinline SDWORD TMulScale9 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 9); }
|
|
||||||
static __forceinline SDWORD TMulScale10 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 10); }
|
|
||||||
static __forceinline SDWORD TMulScale11 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 11); }
|
|
||||||
static __forceinline SDWORD TMulScale12 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 12); }
|
|
||||||
static __forceinline SDWORD TMulScale13 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 13); }
|
|
||||||
static __forceinline SDWORD TMulScale14 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 14); }
|
|
||||||
static __forceinline SDWORD TMulScale15 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 15); }
|
|
||||||
static __forceinline SDWORD TMulScale16 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 16); }
|
|
||||||
static __forceinline SDWORD TMulScale17 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 17); }
|
|
||||||
static __forceinline SDWORD TMulScale18 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 18); }
|
|
||||||
static __forceinline SDWORD TMulScale19 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 19); }
|
|
||||||
static __forceinline SDWORD TMulScale20 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 20); }
|
|
||||||
static __forceinline SDWORD TMulScale21 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 21); }
|
|
||||||
static __forceinline SDWORD TMulScale22 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 22); }
|
|
||||||
static __forceinline SDWORD TMulScale23 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 23); }
|
|
||||||
static __forceinline SDWORD TMulScale24 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 24); }
|
|
||||||
static __forceinline SDWORD TMulScale25 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 25); }
|
|
||||||
static __forceinline SDWORD TMulScale26 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 26); }
|
|
||||||
static __forceinline SDWORD TMulScale27 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 27); }
|
|
||||||
static __forceinline SDWORD TMulScale28 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 28); }
|
|
||||||
static __forceinline SDWORD TMulScale29 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 29); }
|
|
||||||
static __forceinline SDWORD TMulScale30 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 30); }
|
|
||||||
static __forceinline SDWORD TMulScale31 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 31); }
|
|
||||||
static __forceinline SDWORD TMulScale32 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 32); }
|
|
||||||
|
|
||||||
static __forceinline SDWORD BoundMulScale (SDWORD a, SDWORD b, SDWORD c)
|
|
||||||
{
|
|
||||||
SQWORD x = ((SQWORD)a * b) >> c;
|
|
||||||
return x > 0x7FFFFFFFll ? 0x7FFFFFFF :
|
|
||||||
x < -0x80000000ll ? 0x80000000 :
|
|
||||||
(SDWORD)x;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline SDWORD DivScale (SDWORD a, SDWORD b, SDWORD c)
|
|
||||||
{
|
|
||||||
return (SDWORD)(((SQWORD)a << c) / b);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline SDWORD DivScale1 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 1) / b); }
|
|
||||||
static inline SDWORD DivScale2 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 2) / b); }
|
static inline SDWORD DivScale2 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 2) / b); }
|
||||||
static inline SDWORD DivScale3 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 3) / b); }
|
static inline SDWORD DivScale3 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 3) / b); }
|
||||||
static inline SDWORD DivScale4 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 4) / b); }
|
static inline SDWORD DivScale4 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 4) / b); }
|
||||||
|
@ -175,29 +118,4 @@ static inline SDWORD DivScale28 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)
|
||||||
static inline SDWORD DivScale29 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 29) / b); }
|
static inline SDWORD DivScale29 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 29) / b); }
|
||||||
static inline SDWORD DivScale30 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 30) / b); }
|
static inline SDWORD DivScale30 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 30) / b); }
|
||||||
static inline SDWORD DivScale31 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 31) / b); }
|
static inline SDWORD DivScale31 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 31) / b); }
|
||||||
static inline SDWORD DivScale32 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 32) / b); }
|
|
||||||
|
|
||||||
static __forceinline void clearbuf (void *buff, unsigned int count, SDWORD clear)
|
|
||||||
{
|
|
||||||
SDWORD *b2 = (SDWORD *)buff;
|
|
||||||
for (unsigned int i = 0; i != count; ++i)
|
|
||||||
{
|
|
||||||
b2[i] = clear;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static __forceinline void clearbufshort (void *buff, unsigned int count, WORD clear)
|
|
||||||
{
|
|
||||||
SWORD *b2 = (SWORD *)buff;
|
|
||||||
for (unsigned int i = 0; i != count; ++i)
|
|
||||||
{
|
|
||||||
b2[i] = clear;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static __forceinline SDWORD ksgn (SDWORD a)
|
|
||||||
{
|
|
||||||
if (a < 0) return -1;
|
|
||||||
else if (a > 0) return 1;
|
|
||||||
else return 0;
|
|
||||||
}
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ DLightningThinker::DLightningThinker ()
|
||||||
NextLightningFlash = ((pr_lightning()&15)+5)*35; // don't flash at level start
|
NextLightningFlash = ((pr_lightning()&15)+5)*35; // don't flash at level start
|
||||||
|
|
||||||
LightningLightLevels.Resize(numsectors);
|
LightningLightLevels.Resize(numsectors);
|
||||||
clearbufshort(&LightningLightLevels[0], numsectors, SHRT_MAX);
|
fillshort(&LightningLightLevels[0], numsectors, SHRT_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
DLightningThinker::~DLightningThinker ()
|
DLightningThinker::~DLightningThinker ()
|
||||||
|
@ -87,7 +87,7 @@ void DLightningThinker::LightningFlash ()
|
||||||
tempSec->SetLightLevel(LightningLightLevels[j]);
|
tempSec->SetLightLevel(LightningLightLevels[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
clearbufshort(&LightningLightLevels[0], numsectors, SHRT_MAX);
|
fillshort(&LightningLightLevels[0], numsectors, SHRT_MAX);
|
||||||
level.flags &= ~LEVEL_SWAPSKIES;
|
level.flags &= ~LEVEL_SWAPSKIES;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -174,14 +174,10 @@ void FHealthBar::MakeTexture ()
|
||||||
|
|
||||||
void FHealthBar::FillBar (int min, int max, BYTE light, BYTE dark)
|
void FHealthBar::FillBar (int min, int max, BYTE light, BYTE dark)
|
||||||
{
|
{
|
||||||
#ifdef __BIG_ENDIAN__
|
for (int i = min*2; i < max*2; i++)
|
||||||
SDWORD fill = (light << 24) | (dark << 16) | (light << 8) | dark;
|
|
||||||
#else
|
|
||||||
SDWORD fill = light | (dark << 8) | (light << 16) | (dark << 24);
|
|
||||||
#endif
|
|
||||||
if (max > min)
|
|
||||||
{
|
{
|
||||||
clearbuf (&Pixels[min*4], max - min, fill);
|
Pixels[i * 2] = light;
|
||||||
|
Pixels[i * 2 + 1] = dark;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
156
src/gccinlines.h
156
src/gccinlines.h
|
@ -47,23 +47,6 @@ static inline SDWORD Scale (SDWORD a, SDWORD b, SDWORD c)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline SDWORD MulScale (SDWORD a, SDWORD b, SDWORD c)
|
|
||||||
{
|
|
||||||
SDWORD result, dummy;
|
|
||||||
|
|
||||||
asm volatile
|
|
||||||
("imull %3\n\t"
|
|
||||||
"shrdl %b4,%1,%0"
|
|
||||||
: "=a,a,a,a" (result),
|
|
||||||
"=d,d,d,d" (dummy)
|
|
||||||
: "a,a,a,a" (a),
|
|
||||||
"m,r,m,r" (b),
|
|
||||||
"c,c,I,I" (c)
|
|
||||||
: "cc"
|
|
||||||
);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define MAKECONSTMulScale(s) \
|
#define MAKECONSTMulScale(s) \
|
||||||
static inline SDWORD MulScale##s (SDWORD a, SDWORD b) { return ((SQWORD)a * b) >> s; }
|
static inline SDWORD MulScale##s (SDWORD a, SDWORD b) { return ((SQWORD)a * b) >> s; }
|
||||||
|
|
||||||
|
@ -143,92 +126,6 @@ MAKECONSTDMulScale(31)
|
||||||
MAKECONSTDMulScale(32)
|
MAKECONSTDMulScale(32)
|
||||||
#undef MAKECONSTDMulScale
|
#undef MAKECONSTDMulScale
|
||||||
|
|
||||||
#define MAKECONSTTMulScale(s) \
|
|
||||||
static inline SDWORD TMulScale##s (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD ee) \
|
|
||||||
{ \
|
|
||||||
return (((SQWORD)a * b) + ((SQWORD)c * d) + ((SQWORD)e * ee)) >> s; \
|
|
||||||
}
|
|
||||||
|
|
||||||
MAKECONSTTMulScale(1)
|
|
||||||
MAKECONSTTMulScale(2)
|
|
||||||
MAKECONSTTMulScale(3)
|
|
||||||
MAKECONSTTMulScale(4)
|
|
||||||
MAKECONSTTMulScale(5)
|
|
||||||
MAKECONSTTMulScale(6)
|
|
||||||
MAKECONSTTMulScale(7)
|
|
||||||
MAKECONSTTMulScale(8)
|
|
||||||
MAKECONSTTMulScale(9)
|
|
||||||
MAKECONSTTMulScale(10)
|
|
||||||
MAKECONSTTMulScale(11)
|
|
||||||
MAKECONSTTMulScale(12)
|
|
||||||
MAKECONSTTMulScale(13)
|
|
||||||
MAKECONSTTMulScale(14)
|
|
||||||
MAKECONSTTMulScale(15)
|
|
||||||
MAKECONSTTMulScale(16)
|
|
||||||
MAKECONSTTMulScale(17)
|
|
||||||
MAKECONSTTMulScale(18)
|
|
||||||
MAKECONSTTMulScale(19)
|
|
||||||
MAKECONSTTMulScale(20)
|
|
||||||
MAKECONSTTMulScale(21)
|
|
||||||
MAKECONSTTMulScale(22)
|
|
||||||
MAKECONSTTMulScale(23)
|
|
||||||
MAKECONSTTMulScale(24)
|
|
||||||
MAKECONSTTMulScale(25)
|
|
||||||
MAKECONSTTMulScale(26)
|
|
||||||
MAKECONSTTMulScale(27)
|
|
||||||
MAKECONSTTMulScale(28)
|
|
||||||
MAKECONSTTMulScale(29)
|
|
||||||
MAKECONSTTMulScale(30)
|
|
||||||
MAKECONSTTMulScale(31)
|
|
||||||
MAKECONSTTMulScale(32)
|
|
||||||
#undef MAKECONSTTMulScale
|
|
||||||
|
|
||||||
static inline SDWORD BoundMulScale (SDWORD a, SDWORD b, SDWORD c)
|
|
||||||
{
|
|
||||||
union {
|
|
||||||
long long big;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
int l, h;
|
|
||||||
};
|
|
||||||
} u;
|
|
||||||
u.big = ((long long)a * b) >> c;
|
|
||||||
if ((u.h ^ u.l) < 0 || (unsigned int)(u.h+1) > 1) return (u.h >> 31) ^ 0x7fffffff;
|
|
||||||
return u.l;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline SDWORD DivScale (SDWORD a, SDWORD b, SDWORD c)
|
|
||||||
{
|
|
||||||
SDWORD result, dummy;
|
|
||||||
SDWORD lo = a << c;
|
|
||||||
SDWORD hi = a >> (-c);
|
|
||||||
|
|
||||||
asm volatile
|
|
||||||
("idivl %4"
|
|
||||||
:"=a" (result),
|
|
||||||
"=d" (dummy)
|
|
||||||
: "a" (lo),
|
|
||||||
"d" (hi),
|
|
||||||
"r" (b)
|
|
||||||
: "cc");
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline SDWORD DivScale1 (SDWORD a, SDWORD b)
|
|
||||||
{
|
|
||||||
SDWORD result, dummy;
|
|
||||||
|
|
||||||
asm volatile
|
|
||||||
("addl %%eax,%%eax\n\t"
|
|
||||||
"sbbl %%edx,%%edx\n\t"
|
|
||||||
"idivl %3"
|
|
||||||
:"=a,a" (result),
|
|
||||||
"=&d,d" (dummy)
|
|
||||||
: "a,a" (a),
|
|
||||||
"r,m" (b)
|
|
||||||
: "cc");
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define MAKECONSTDivScale(s) \
|
#define MAKECONSTDivScale(s) \
|
||||||
static inline SDWORD DivScale##s (SDWORD a, SDWORD b) \
|
static inline SDWORD DivScale##s (SDWORD a, SDWORD b) \
|
||||||
|
@ -277,56 +174,3 @@ MAKECONSTDivScale(30)
|
||||||
MAKECONSTDivScale(31)
|
MAKECONSTDivScale(31)
|
||||||
#undef MAKECONSTDivScale
|
#undef MAKECONSTDivScale
|
||||||
|
|
||||||
static inline SDWORD DivScale32 (SDWORD a, SDWORD b)
|
|
||||||
{
|
|
||||||
SDWORD result = 0, dummy;
|
|
||||||
|
|
||||||
asm volatile
|
|
||||||
("idivl %3"
|
|
||||||
:"+a,a" (result),
|
|
||||||
"=d,d" (dummy)
|
|
||||||
: "d,d" (a),
|
|
||||||
"r,m" (b)
|
|
||||||
: "cc");
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void clearbuf (void *buff, int count, SDWORD clear)
|
|
||||||
{
|
|
||||||
int dummy1, dummy2;
|
|
||||||
asm volatile
|
|
||||||
("rep stosl"
|
|
||||||
:"=D" (dummy1),
|
|
||||||
"=c" (dummy2)
|
|
||||||
: "D" (buff),
|
|
||||||
"c" (count),
|
|
||||||
"a" (clear)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void clearbufshort (void *buff, unsigned int count, WORD clear)
|
|
||||||
{
|
|
||||||
asm volatile
|
|
||||||
("shr $1,%%ecx\n\t"
|
|
||||||
"rep stosl\n\t"
|
|
||||||
"adc %%ecx,%%ecx\n\t"
|
|
||||||
"rep stosw"
|
|
||||||
:"=D" (buff), "=c" (count)
|
|
||||||
:"D" (buff), "c" (count), "a" (clear|(clear<<16))
|
|
||||||
:"cc");
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline SDWORD ksgn (SDWORD a)
|
|
||||||
{
|
|
||||||
SDWORD result, dummy;
|
|
||||||
|
|
||||||
asm volatile
|
|
||||||
("add %0,%0\n\t"
|
|
||||||
"sbb %1,%1\n\t"
|
|
||||||
"cmp %0,%1\n\t"
|
|
||||||
"adc $0,%1"
|
|
||||||
:"=r" (dummy), "=r" (result)
|
|
||||||
:"0" (a)
|
|
||||||
:"cc");
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
126
src/m_fixed.h
126
src/m_fixed.h
|
@ -1,11 +1,3 @@
|
||||||
// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman
|
|
||||||
// Ken Silverman's official web site: "http://www.advsys.net/ken"
|
|
||||||
// See the included license file "BUILDLIC.TXT" for license info.
|
|
||||||
//
|
|
||||||
// This file is based on pragmas.h from Ken Silverman's original Build
|
|
||||||
// source code release and contains routines that were originally
|
|
||||||
// inline assembly but are not now.
|
|
||||||
|
|
||||||
#ifndef __M_FIXED__
|
#ifndef __M_FIXED__
|
||||||
#define __M_FIXED__
|
#define __M_FIXED__
|
||||||
|
|
||||||
|
@ -20,121 +12,25 @@
|
||||||
#include "basicinlines.h"
|
#include "basicinlines.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "xs_Float.h"
|
__forceinline void fillshort(void *buff, unsigned int count, WORD clear)
|
||||||
|
|
||||||
#define MAKESAFEDIVSCALE(x) \
|
|
||||||
inline SDWORD SafeDivScale##x (SDWORD a, SDWORD b) \
|
|
||||||
{ \
|
|
||||||
if ((DWORD)abs(a) >> (31-x) >= (DWORD)abs (b)) \
|
|
||||||
return (a^b)<0 ? FIXED_MIN : FIXED_MAX; \
|
|
||||||
return DivScale##x (a, b); \
|
|
||||||
}
|
|
||||||
|
|
||||||
MAKESAFEDIVSCALE(1)
|
|
||||||
MAKESAFEDIVSCALE(2)
|
|
||||||
MAKESAFEDIVSCALE(3)
|
|
||||||
MAKESAFEDIVSCALE(4)
|
|
||||||
MAKESAFEDIVSCALE(5)
|
|
||||||
MAKESAFEDIVSCALE(6)
|
|
||||||
MAKESAFEDIVSCALE(7)
|
|
||||||
MAKESAFEDIVSCALE(8)
|
|
||||||
MAKESAFEDIVSCALE(9)
|
|
||||||
MAKESAFEDIVSCALE(10)
|
|
||||||
MAKESAFEDIVSCALE(11)
|
|
||||||
MAKESAFEDIVSCALE(12)
|
|
||||||
MAKESAFEDIVSCALE(13)
|
|
||||||
MAKESAFEDIVSCALE(14)
|
|
||||||
MAKESAFEDIVSCALE(15)
|
|
||||||
MAKESAFEDIVSCALE(16)
|
|
||||||
MAKESAFEDIVSCALE(17)
|
|
||||||
MAKESAFEDIVSCALE(18)
|
|
||||||
MAKESAFEDIVSCALE(19)
|
|
||||||
MAKESAFEDIVSCALE(20)
|
|
||||||
MAKESAFEDIVSCALE(21)
|
|
||||||
MAKESAFEDIVSCALE(22)
|
|
||||||
MAKESAFEDIVSCALE(23)
|
|
||||||
MAKESAFEDIVSCALE(24)
|
|
||||||
MAKESAFEDIVSCALE(25)
|
|
||||||
MAKESAFEDIVSCALE(26)
|
|
||||||
MAKESAFEDIVSCALE(27)
|
|
||||||
MAKESAFEDIVSCALE(28)
|
|
||||||
MAKESAFEDIVSCALE(29)
|
|
||||||
MAKESAFEDIVSCALE(30)
|
|
||||||
#undef MAKESAFEDIVSCALE
|
|
||||||
|
|
||||||
inline SDWORD SafeDivScale31 (SDWORD a, SDWORD b)
|
|
||||||
{
|
{
|
||||||
if ((DWORD)abs(a) >= (DWORD)abs (b))
|
SWORD *b2 = (SWORD *)buff;
|
||||||
return (a^b)<0 ? FIXED_MIN : FIXED_MAX;
|
for (unsigned int i = 0; i != count; ++i)
|
||||||
return DivScale31 (a, b);
|
{
|
||||||
|
b2[i] = clear;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline SDWORD SafeDivScale32 (SDWORD a, SDWORD b)
|
#include "xs_Float.h"
|
||||||
|
|
||||||
|
inline SDWORD FixedDiv (SDWORD a, SDWORD b)
|
||||||
{
|
{
|
||||||
if ((DWORD)abs(a) >= (DWORD)abs (b) >> 1)
|
if ((DWORD)abs(a) >> (31-16) >= (DWORD)abs (b))
|
||||||
return (a^b)<0 ? FIXED_MIN : FIXED_MAX;
|
return (a^b)<0 ? FIXED_MIN : FIXED_MAX;
|
||||||
return DivScale32 (a, b);
|
return DivScale16 (a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FixedMul MulScale16
|
#define FixedMul MulScale16
|
||||||
#define FixedDiv SafeDivScale16
|
|
||||||
|
|
||||||
inline void qinterpolatedown16 (SDWORD *out, DWORD count, SDWORD val, SDWORD delta)
|
|
||||||
{
|
|
||||||
if (count & 1)
|
|
||||||
{
|
|
||||||
out[0] = val >> 16;
|
|
||||||
val += delta;
|
|
||||||
}
|
|
||||||
count >>= 1;
|
|
||||||
while (count-- != 0)
|
|
||||||
{
|
|
||||||
int temp = val + delta;
|
|
||||||
out[0] = val >> 16;
|
|
||||||
val = temp + delta;
|
|
||||||
out[1] = temp >> 16;
|
|
||||||
out += 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void qinterpolatedown16short (short *out, DWORD count, SDWORD val, SDWORD delta)
|
|
||||||
{
|
|
||||||
if (count)
|
|
||||||
{
|
|
||||||
if ((size_t)out & 2)
|
|
||||||
{ // align to dword boundary
|
|
||||||
*out++ = (short)(val >> 16);
|
|
||||||
count--;
|
|
||||||
val += delta;
|
|
||||||
}
|
|
||||||
DWORD *o2 = (DWORD *)out;
|
|
||||||
DWORD c2 = count>>1;
|
|
||||||
while (c2-- != 0)
|
|
||||||
{
|
|
||||||
SDWORD temp = val + delta;
|
|
||||||
*o2++ = (temp & 0xffff0000) | ((DWORD)val >> 16);
|
|
||||||
val = temp + delta;
|
|
||||||
}
|
|
||||||
if (count & 1)
|
|
||||||
{
|
|
||||||
*(short *)o2 = (short)(val >> 16);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//returns num/den, dmval = num%den
|
|
||||||
inline SDWORD DivMod (SDWORD num, SDWORD den, SDWORD *dmval)
|
|
||||||
{
|
|
||||||
*dmval = num % den;
|
|
||||||
return num / den;
|
|
||||||
}
|
|
||||||
|
|
||||||
//returns num%den, dmval = num/den
|
|
||||||
inline SDWORD ModDiv (SDWORD num, SDWORD den, SDWORD *dmval)
|
|
||||||
{
|
|
||||||
*dmval = num / den;
|
|
||||||
return num % den;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fixed_t FloatToFixed(double f)
|
inline fixed_t FloatToFixed(double f)
|
||||||
{
|
{
|
||||||
|
|
165
src/mscinlines.h
165
src/mscinlines.h
|
@ -27,14 +27,6 @@ __forceinline SDWORD Scale (SDWORD a, SDWORD b, SDWORD c)
|
||||||
__asm idiv c
|
__asm idiv c
|
||||||
}
|
}
|
||||||
|
|
||||||
__forceinline SDWORD MulScale (SDWORD a, SDWORD b, SDWORD c)
|
|
||||||
{
|
|
||||||
__asm mov eax,a
|
|
||||||
__asm mov ecx,c
|
|
||||||
__asm imul b
|
|
||||||
__asm shrd eax,edx,cl
|
|
||||||
}
|
|
||||||
|
|
||||||
#define MAKECONSTMulScale(s) \
|
#define MAKECONSTMulScale(s) \
|
||||||
__forceinline SDWORD MulScale##s (SDWORD a, SDWORD b) \
|
__forceinline SDWORD MulScale##s (SDWORD a, SDWORD b) \
|
||||||
{ \
|
{ \
|
||||||
|
@ -89,20 +81,6 @@ __forceinline DWORD UMulScale16(DWORD a, DWORD b)
|
||||||
__asm shrd eax,edx,16
|
__asm shrd eax,edx,16
|
||||||
}
|
}
|
||||||
|
|
||||||
__forceinline SDWORD DMulScale (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD s)
|
|
||||||
{
|
|
||||||
__asm mov eax,a
|
|
||||||
__asm imul b
|
|
||||||
__asm mov ebx,eax
|
|
||||||
__asm mov eax,c
|
|
||||||
__asm mov esi,edx
|
|
||||||
__asm mov ecx,s
|
|
||||||
__asm imul d
|
|
||||||
__asm add eax,ebx
|
|
||||||
__asm adc edx,esi
|
|
||||||
__asm shrd eax,edx,cl
|
|
||||||
}
|
|
||||||
|
|
||||||
#define MAKECONSTDMulScale(s) \
|
#define MAKECONSTDMulScale(s) \
|
||||||
__forceinline SDWORD DMulScale##s (SDWORD a, SDWORD b, SDWORD c, SDWORD d) \
|
__forceinline SDWORD DMulScale##s (SDWORD a, SDWORD b, SDWORD c, SDWORD d) \
|
||||||
{ \
|
{ \
|
||||||
|
@ -163,115 +141,6 @@ __forceinline SDWORD DMulScale32 (SDWORD a, SDWORD b, SDWORD c, SDWORD d)
|
||||||
__asm mov eax,edx
|
__asm mov eax,edx
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAKECONSTTMulScale(s) \
|
|
||||||
__forceinline SDWORD TMulScale##s (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) \
|
|
||||||
{ \
|
|
||||||
__asm mov eax,a \
|
|
||||||
__asm imul b \
|
|
||||||
__asm mov ebx,eax \
|
|
||||||
__asm mov eax,d \
|
|
||||||
__asm mov ecx,edx \
|
|
||||||
__asm imul c \
|
|
||||||
__asm add ebx,eax \
|
|
||||||
__asm mov eax,e \
|
|
||||||
__asm adc ecx,edx \
|
|
||||||
__asm imul f \
|
|
||||||
__asm add eax,ebx \
|
|
||||||
__asm adc edx,ecx \
|
|
||||||
__asm shrd eax,edx,s \
|
|
||||||
}
|
|
||||||
|
|
||||||
MAKECONSTTMulScale(1)
|
|
||||||
MAKECONSTTMulScale(2)
|
|
||||||
MAKECONSTTMulScale(3)
|
|
||||||
MAKECONSTTMulScale(4)
|
|
||||||
MAKECONSTTMulScale(5)
|
|
||||||
MAKECONSTTMulScale(6)
|
|
||||||
MAKECONSTTMulScale(7)
|
|
||||||
MAKECONSTTMulScale(8)
|
|
||||||
MAKECONSTTMulScale(9)
|
|
||||||
MAKECONSTTMulScale(10)
|
|
||||||
MAKECONSTTMulScale(11)
|
|
||||||
MAKECONSTTMulScale(12)
|
|
||||||
MAKECONSTTMulScale(13)
|
|
||||||
MAKECONSTTMulScale(14)
|
|
||||||
MAKECONSTTMulScale(15)
|
|
||||||
MAKECONSTTMulScale(16)
|
|
||||||
MAKECONSTTMulScale(17)
|
|
||||||
MAKECONSTTMulScale(18)
|
|
||||||
MAKECONSTTMulScale(19)
|
|
||||||
MAKECONSTTMulScale(20)
|
|
||||||
MAKECONSTTMulScale(21)
|
|
||||||
MAKECONSTTMulScale(22)
|
|
||||||
MAKECONSTTMulScale(23)
|
|
||||||
MAKECONSTTMulScale(24)
|
|
||||||
MAKECONSTTMulScale(25)
|
|
||||||
MAKECONSTTMulScale(26)
|
|
||||||
MAKECONSTTMulScale(27)
|
|
||||||
MAKECONSTTMulScale(28)
|
|
||||||
MAKECONSTTMulScale(29)
|
|
||||||
MAKECONSTTMulScale(30)
|
|
||||||
MAKECONSTTMulScale(31)
|
|
||||||
#undef MAKECONSTTMulScale
|
|
||||||
|
|
||||||
__forceinline SDWORD TMulScale32 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f)
|
|
||||||
{
|
|
||||||
__asm mov eax,a
|
|
||||||
__asm imul b
|
|
||||||
__asm mov ebx,eax
|
|
||||||
__asm mov eax,c
|
|
||||||
__asm mov ecx,edx
|
|
||||||
__asm imul d
|
|
||||||
__asm add ebx,eax
|
|
||||||
__asm mov eax,e
|
|
||||||
__asm adc ecx,edx
|
|
||||||
__asm imul f
|
|
||||||
__asm add eax,ebx
|
|
||||||
__asm adc edx,ecx
|
|
||||||
__asm mov eax,edx
|
|
||||||
}
|
|
||||||
|
|
||||||
__forceinline SDWORD BoundMulScale (SDWORD a, SDWORD b, SDWORD c)
|
|
||||||
{
|
|
||||||
__asm mov eax,a
|
|
||||||
__asm imul b
|
|
||||||
__asm mov ebx,edx
|
|
||||||
__asm mov ecx,c
|
|
||||||
__asm shrd eax,edx,cl
|
|
||||||
__asm sar edx,cl
|
|
||||||
__asm xor edx,eax
|
|
||||||
__asm js checkit
|
|
||||||
__asm xor edx,eax
|
|
||||||
__asm jz skipboundit
|
|
||||||
__asm cmp edx,0xffffffff
|
|
||||||
__asm je skipboundit
|
|
||||||
checkit:
|
|
||||||
__asm mov eax,ebx
|
|
||||||
__asm sar eax,31
|
|
||||||
__asm xor eax,0x7fffffff
|
|
||||||
skipboundit:
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
__forceinline SDWORD DivScale (SDWORD a, SDWORD b, SDWORD c)
|
|
||||||
{
|
|
||||||
__asm mov eax,a
|
|
||||||
__asm mov ecx,c
|
|
||||||
__asm shl eax,cl
|
|
||||||
__asm mov edx,a
|
|
||||||
__asm neg cl
|
|
||||||
__asm sar edx,cl
|
|
||||||
__asm idiv b
|
|
||||||
}
|
|
||||||
|
|
||||||
__forceinline SDWORD DivScale1 (SDWORD a, SDWORD b)
|
|
||||||
{
|
|
||||||
__asm mov eax,a
|
|
||||||
__asm add eax,eax
|
|
||||||
__asm sbb edx,edx
|
|
||||||
__asm idiv b
|
|
||||||
}
|
|
||||||
|
|
||||||
#define MAKECONSTDivScale(s) \
|
#define MAKECONSTDivScale(s) \
|
||||||
__forceinline SDWORD DivScale##s (SDWORD a, SDWORD b) \
|
__forceinline SDWORD DivScale##s (SDWORD a, SDWORD b) \
|
||||||
{ \
|
{ \
|
||||||
|
@ -314,38 +183,4 @@ MAKECONSTDivScale(30)
|
||||||
MAKECONSTDivScale(31)
|
MAKECONSTDivScale(31)
|
||||||
#undef MAKECONSTDivScale
|
#undef MAKECONSTDivScale
|
||||||
|
|
||||||
__forceinline SDWORD DivScale32 (SDWORD a, SDWORD b)
|
|
||||||
{
|
|
||||||
__asm mov edx,a
|
|
||||||
__asm xor eax,eax
|
|
||||||
__asm idiv b
|
|
||||||
}
|
|
||||||
|
|
||||||
__forceinline void clearbuf (void *buff, unsigned int count, SDWORD clear)
|
|
||||||
{
|
|
||||||
SDWORD *b2 = (SDWORD *)buff;
|
|
||||||
for (unsigned int i = 0; i != count; ++i)
|
|
||||||
{
|
|
||||||
b2[i] = clear;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
__forceinline void clearbufshort (void *buff, unsigned int count, WORD clear)
|
|
||||||
{
|
|
||||||
SWORD *b2 = (SWORD *)buff;
|
|
||||||
for (unsigned int i = 0; i != count; ++i)
|
|
||||||
{
|
|
||||||
b2[i] = clear;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
__forceinline SDWORD ksgn (SDWORD a)
|
|
||||||
{
|
|
||||||
__asm mov edx,a
|
|
||||||
__asm add edx,edx
|
|
||||||
__asm sbb eax,eax
|
|
||||||
__asm cmp eax,edx
|
|
||||||
__asm adc eax,0
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma warning (default: 4035)
|
#pragma warning (default: 4035)
|
||||||
|
|
|
@ -198,7 +198,7 @@ void P_FindParticleSubsectors ()
|
||||||
ParticlesInSubsec.Reserve (numsubsectors - ParticlesInSubsec.Size());
|
ParticlesInSubsec.Reserve (numsubsectors - ParticlesInSubsec.Size());
|
||||||
}
|
}
|
||||||
|
|
||||||
clearbufshort (&ParticlesInSubsec[0], numsubsectors, NO_PARTICLE);
|
fillshort (&ParticlesInSubsec[0], numsubsectors, NO_PARTICLE);
|
||||||
|
|
||||||
if (!r_particles)
|
if (!r_particles)
|
||||||
{
|
{
|
||||||
|
|
|
@ -925,7 +925,7 @@ void FBlockThingsIterator::init(const FBoundingBox &box)
|
||||||
|
|
||||||
void FBlockThingsIterator::ClearHash()
|
void FBlockThingsIterator::ClearHash()
|
||||||
{
|
{
|
||||||
clearbuf(Buckets, countof(Buckets), -1);
|
memset(Buckets, -1, sizeof(Buckets));
|
||||||
NumFixedHash = 0;
|
NumFixedHash = 0;
|
||||||
DynHash.Clear();
|
DynHash.Clear();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2609,11 +2609,7 @@ void P_PlayerThink (player_t *player)
|
||||||
else if (cmd->ucmd.upmove != 0)
|
else if (cmd->ucmd.upmove != 0)
|
||||||
{
|
{
|
||||||
// Clamp the speed to some reasonable maximum.
|
// Clamp the speed to some reasonable maximum.
|
||||||
int magnitude = abs (cmd->ucmd.upmove);
|
cmd->ucmd.upmove = clamp<short>(cmd->ucmd.upmove, -0x300, 0x300);
|
||||||
if (magnitude > 0x300)
|
|
||||||
{
|
|
||||||
cmd->ucmd.upmove = ksgn (cmd->ucmd.upmove) * 0x300;
|
|
||||||
}
|
|
||||||
if (player->mo->waterlevel >= 2 || (player->mo->flags2 & MF2_FLY) || (player->cheats & CF_NOCLIP2))
|
if (player->mo->waterlevel >= 2 || (player->mo->flags2 & MF2_FLY) || (player->cheats & CF_NOCLIP2))
|
||||||
{
|
{
|
||||||
player->mo->Vel.Z = player->mo->Speed * cmd->ucmd.upmove / 128.;
|
player->mo->Vel.Z = player->mo->Speed * cmd->ucmd.upmove / 128.;
|
||||||
|
|
|
@ -17,12 +17,6 @@
|
||||||
// DESCRIPTION:
|
// DESCRIPTION:
|
||||||
// BSP traversal, handling of LineSegs for rendering.
|
// BSP traversal, handling of LineSegs for rendering.
|
||||||
//
|
//
|
||||||
// This file contains some code from the Build Engine.
|
|
||||||
//
|
|
||||||
// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman
|
|
||||||
// Ken Silverman's official web site: "http://www.advsys.net/ken"
|
|
||||||
// See the included license file "BUILDLIC.TXT" for license info.
|
|
||||||
//
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
@ -746,8 +740,8 @@ void R_AddLine (seg_t *line)
|
||||||
if (line->linedef->special == Line_Horizon)
|
if (line->linedef->special == Line_Horizon)
|
||||||
{
|
{
|
||||||
// Be aware: Line_Horizon does not work properly with sloped planes
|
// Be aware: Line_Horizon does not work properly with sloped planes
|
||||||
clearbufshort (walltop+WallC.sx1, WallC.sx2 - WallC.sx1, centery);
|
fillshort (walltop+WallC.sx1, WallC.sx2 - WallC.sx1, centery);
|
||||||
clearbufshort (wallbottom+WallC.sx1, WallC.sx2 - WallC.sx1, centery);
|
fillshort (wallbottom+WallC.sx1, WallC.sx2 - WallC.sx1, centery);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -270,7 +270,7 @@ void R_InitSpriteDefs ()
|
||||||
// Create a hash table to speed up the process
|
// Create a hash table to speed up the process
|
||||||
smax = TexMan.NumTextures();
|
smax = TexMan.NumTextures();
|
||||||
hashes = new Hasher[smax];
|
hashes = new Hasher[smax];
|
||||||
clearbuf(hashes, sizeof(Hasher)*smax/4, -1);
|
memset(hashes, -1, sizeof(Hasher)*smax);
|
||||||
for (i = 0; i < smax; ++i)
|
for (i = 0; i < smax; ++i)
|
||||||
{
|
{
|
||||||
FTexture *tex = TexMan.ByIndex(i);
|
FTexture *tex = TexMan.ByIndex(i);
|
||||||
|
@ -285,7 +285,7 @@ void R_InitSpriteDefs ()
|
||||||
// Repeat, for voxels
|
// Repeat, for voxels
|
||||||
vmax = Wads.GetNumLumps();
|
vmax = Wads.GetNumLumps();
|
||||||
vhashes = new VHasher[vmax];
|
vhashes = new VHasher[vmax];
|
||||||
clearbuf(vhashes, sizeof(VHasher)*vmax/4, -1);
|
memset(vhashes, -1, sizeof(VHasher)*vmax);
|
||||||
for (i = 0; i < vmax; ++i)
|
for (i = 0; i < vmax; ++i)
|
||||||
{
|
{
|
||||||
if (Wads.GetLumpNamespace(i) == ns_voxels)
|
if (Wads.GetLumpNamespace(i) == ns_voxels)
|
||||||
|
|
|
@ -1274,7 +1274,7 @@ namespace swrenderer
|
||||||
|
|
||||||
if (b2 > t2)
|
if (b2 > t2)
|
||||||
{
|
{
|
||||||
clearbufshort(spanend + t2, b2 - t2, x);
|
fillshort(spanend + t2, b2 - t2, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
R_SetColorMapLight(basecolormap->Maps, (float)light, wallshade);
|
R_SetColorMapLight(basecolormap->Maps, (float)light, wallshade);
|
||||||
|
@ -1301,7 +1301,7 @@ namespace swrenderer
|
||||||
if (b1 > b2) b2 = b1;
|
if (b1 > b2) b2 = b1;
|
||||||
if (t2 < b2)
|
if (t2 < b2)
|
||||||
{
|
{
|
||||||
clearbufshort(spanend + t2, b2 - t2, x);
|
fillshort(spanend + t2, b2 - t2, x);
|
||||||
}
|
}
|
||||||
rcolormap = lcolormap;
|
rcolormap = lcolormap;
|
||||||
R_SetColorMapLight(basecolormap->Maps, (float)light, wallshade);
|
R_SetColorMapLight(basecolormap->Maps, (float)light, wallshade);
|
||||||
|
|
|
@ -104,8 +104,6 @@ namespace swrenderer
|
||||||
|
|
||||||
const uint8_t *R_GetColumn(FTexture *tex, int col);
|
const uint8_t *R_GetColumn(FTexture *tex, int col);
|
||||||
void wallscan(int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, const uint8_t *(*getcol)(FTexture *tex, int col) = R_GetColumn);
|
void wallscan(int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, const uint8_t *(*getcol)(FTexture *tex, int col) = R_GetColumn);
|
||||||
void maskwallscan(int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, const uint8_t *(*getcol)(FTexture *tex, int col) = R_GetColumn);
|
|
||||||
void transmaskwallscan(int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, const uint8_t *(*getcol)(FTexture *tex, int col) = R_GetColumn);
|
|
||||||
|
|
||||||
void rt_initcols(uint8_t *buffer = nullptr);
|
void rt_initcols(uint8_t *buffer = nullptr);
|
||||||
void rt_span_coverage(int x, int start, int stop);
|
void rt_span_coverage(int x, int start, int stop);
|
||||||
|
|
|
@ -374,7 +374,7 @@ void R_SWRSetWindow(int windowSize, int fullWidth, int fullHeight, int stHeight,
|
||||||
pspritexiscale = 1 / pspritexscale;
|
pspritexiscale = 1 / pspritexscale;
|
||||||
|
|
||||||
// thing clipping
|
// thing clipping
|
||||||
clearbufshort (screenheightarray, viewwidth, (short)viewheight);
|
fillshort (screenheightarray, viewwidth, (short)viewheight);
|
||||||
|
|
||||||
R_InitTextureMapping ();
|
R_InitTextureMapping ();
|
||||||
|
|
||||||
|
@ -397,7 +397,7 @@ void R_InitRenderer()
|
||||||
{
|
{
|
||||||
atterm(R_ShutdownRenderer);
|
atterm(R_ShutdownRenderer);
|
||||||
// viewwidth / viewheight are set by the defaults
|
// viewwidth / viewheight are set by the defaults
|
||||||
clearbufshort (zeroarray, MAXWIDTH, 0);
|
fillshort (zeroarray, MAXWIDTH, 0);
|
||||||
|
|
||||||
R_InitPlanes ();
|
R_InitPlanes ();
|
||||||
R_InitShadeMaps();
|
R_InitShadeMaps();
|
||||||
|
|
|
@ -317,9 +317,9 @@ void R_ClearPlanes (bool fullclear)
|
||||||
}
|
}
|
||||||
|
|
||||||
// opening / clipping determination
|
// opening / clipping determination
|
||||||
clearbufshort (floorclip, viewwidth, viewheight);
|
fillshort (floorclip, viewwidth, viewheight);
|
||||||
// [RH] clip ceiling to console bottom
|
// [RH] clip ceiling to console bottom
|
||||||
clearbufshort (ceilingclip, viewwidth,
|
fillshort (ceilingclip, viewwidth,
|
||||||
!screen->Accel2D && ConBottom > viewwindowy && !bRenderingToCanvas
|
!screen->Accel2D && ConBottom > viewwindowy && !bRenderingToCanvas
|
||||||
? (ConBottom - viewwindowy) : 0);
|
? (ConBottom - viewwindowy) : 0);
|
||||||
|
|
||||||
|
@ -492,7 +492,7 @@ visplane_t *R_FindPlane (const secplane_t &height, FTextureID picnum, int lightl
|
||||||
check->MirrorFlags = MirrorFlags;
|
check->MirrorFlags = MirrorFlags;
|
||||||
check->CurrentSkybox = CurrentSkybox;
|
check->CurrentSkybox = CurrentSkybox;
|
||||||
|
|
||||||
clearbufshort (check->top, viewwidth, 0x7fff);
|
fillshort (check->top, viewwidth, 0x7fff);
|
||||||
|
|
||||||
return check;
|
return check;
|
||||||
}
|
}
|
||||||
|
@ -577,7 +577,7 @@ visplane_t *R_CheckPlane (visplane_t *pl, int start, int stop)
|
||||||
pl = new_pl;
|
pl = new_pl;
|
||||||
pl->left = start;
|
pl->left = start;
|
||||||
pl->right = stop;
|
pl->right = stop;
|
||||||
clearbufshort (pl->top, viewwidth, 0x7fff);
|
fillshort (pl->top, viewwidth, 0x7fff);
|
||||||
}
|
}
|
||||||
return pl;
|
return pl;
|
||||||
}
|
}
|
||||||
|
@ -1681,7 +1681,7 @@ void R_MapVisPlane (visplane_t *pl, void (*mapfunc)(int y, int x1))
|
||||||
|
|
||||||
if (b2 > t2)
|
if (b2 > t2)
|
||||||
{
|
{
|
||||||
clearbufshort (spanend+t2, b2-t2, x);
|
fillshort (spanend+t2, b2-t2, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (--x; x >= pl->left; --x)
|
for (--x; x >= pl->left; --x)
|
||||||
|
|
556
src/r_segs.cpp
556
src/r_segs.cpp
|
@ -56,7 +56,6 @@
|
||||||
#define WALLYREPEAT 8
|
#define WALLYREPEAT 8
|
||||||
|
|
||||||
|
|
||||||
CVAR(Bool, r_np2, true, 0)
|
|
||||||
CVAR(Bool, r_fogboundary, true, 0)
|
CVAR(Bool, r_fogboundary, true, 0)
|
||||||
CVAR(Bool, r_drawmirrors, true, 0)
|
CVAR(Bool, r_drawmirrors, true, 0)
|
||||||
EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor);
|
EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor);
|
||||||
|
@ -65,6 +64,10 @@ namespace swrenderer
|
||||||
{
|
{
|
||||||
using namespace drawerargs;
|
using namespace drawerargs;
|
||||||
|
|
||||||
|
void call_wallscan(int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, bool mask);
|
||||||
|
void wallscan_np2(int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, double top, double bot, bool mask);
|
||||||
|
void wallscan_np2_ds(drawseg_t *ds, int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat);
|
||||||
|
|
||||||
#define HEIGHTBITS 12
|
#define HEIGHTBITS 12
|
||||||
#define HEIGHTSHIFT (FRACBITS-HEIGHTBITS)
|
#define HEIGHTSHIFT (FRACBITS-HEIGHTBITS)
|
||||||
|
|
||||||
|
@ -140,9 +143,6 @@ static fixed_t *maskedtexturecol;
|
||||||
|
|
||||||
static void R_RenderDecal (side_t *wall, DBaseDecal *first, drawseg_t *clipper, int pass);
|
static void R_RenderDecal (side_t *wall, DBaseDecal *first, drawseg_t *clipper, int pass);
|
||||||
static void WallSpriteColumn (void (*drawfunc)(const BYTE *column, const FTexture::Span *spans));
|
static void WallSpriteColumn (void (*drawfunc)(const BYTE *column, const FTexture::Span *spans));
|
||||||
void wallscan_np2(int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, double top, double bot, bool mask);
|
|
||||||
static void wallscan_np2_ds(drawseg_t *ds, int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat);
|
|
||||||
static void call_wallscan(int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, bool mask);
|
|
||||||
|
|
||||||
inline bool IsFogBoundary (sector_t *front, sector_t *back)
|
inline bool IsFogBoundary (sector_t *front, sector_t *back)
|
||||||
{
|
{
|
||||||
|
@ -538,7 +538,7 @@ clearfog:
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
clearbufshort(openings + ds->sprtopclip - ds->x1 + x1, x2 - x1, viewheight);
|
fillshort(openings + ds->sprtopclip - ds->x1 + x1, x2 - x1, viewheight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -1051,542 +1051,6 @@ void R_RenderFakeWallRange (drawseg_t *ds, int x1, int x2)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WallscanSampler
|
|
||||||
{
|
|
||||||
WallscanSampler() { }
|
|
||||||
WallscanSampler(int y1, float swal, double yrepeat, fixed_t xoffset, FTexture *texture, const BYTE*(*getcol)(FTexture *texture, int x));
|
|
||||||
|
|
||||||
uint32_t uv_pos;
|
|
||||||
uint32_t uv_step;
|
|
||||||
uint32_t uv_max;
|
|
||||||
|
|
||||||
const BYTE *source;
|
|
||||||
uint32_t height;
|
|
||||||
};
|
|
||||||
|
|
||||||
WallscanSampler::WallscanSampler(int y1, float swal, double yrepeat, fixed_t xoffset, FTexture *texture, const BYTE*(*getcol)(FTexture *texture, int x))
|
|
||||||
{
|
|
||||||
height = texture->GetHeight();
|
|
||||||
|
|
||||||
int uv_fracbits = 32 - texture->HeightBits;
|
|
||||||
if (uv_fracbits != 32)
|
|
||||||
{
|
|
||||||
uv_max = height << uv_fracbits;
|
|
||||||
|
|
||||||
// Find start uv in [0-base_height[ range.
|
|
||||||
// Not using xs_ToFixed because it rounds the result and we need something that always rounds down to stay within the range.
|
|
||||||
double uv_stepd = swal * yrepeat;
|
|
||||||
double v = (dc_texturemid + uv_stepd * (y1 - CenterY + 0.5)) / height;
|
|
||||||
v = v - floor(v);
|
|
||||||
v *= height;
|
|
||||||
v *= (1 << uv_fracbits);
|
|
||||||
|
|
||||||
uv_pos = (uint32_t)v;
|
|
||||||
uv_step = xs_ToFixed(uv_fracbits, uv_stepd);
|
|
||||||
if (uv_step == 0) // To prevent divide by zero elsewhere
|
|
||||||
uv_step = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // Hack for one pixel tall textures
|
|
||||||
uv_pos = 0;
|
|
||||||
uv_step = 0;
|
|
||||||
uv_max = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
source = getcol(texture, xoffset >> FRACBITS);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw a column with support for non-power-of-two ranges
|
|
||||||
void wallscan_drawcol1(int x, int y1, int y2, WallscanSampler &sampler, DWORD(*draw1column)())
|
|
||||||
{
|
|
||||||
if (sampler.uv_max == 0 || sampler.uv_step == 0) // power of two
|
|
||||||
{
|
|
||||||
int count = y2 - y1;
|
|
||||||
|
|
||||||
dc_source = sampler.source;
|
|
||||||
dc_dest = (ylookup[y1] + x) + dc_destorg;
|
|
||||||
dc_count = count;
|
|
||||||
dc_iscale = sampler.uv_step;
|
|
||||||
dc_texturefrac = sampler.uv_pos;
|
|
||||||
draw1column();
|
|
||||||
|
|
||||||
uint64_t step64 = sampler.uv_step;
|
|
||||||
uint64_t pos64 = sampler.uv_pos;
|
|
||||||
sampler.uv_pos = (uint32_t)(pos64 + step64 * count);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
uint32_t uv_pos = sampler.uv_pos;
|
|
||||||
|
|
||||||
uint32_t left = y2 - y1;
|
|
||||||
while (left > 0)
|
|
||||||
{
|
|
||||||
uint32_t available = sampler.uv_max - uv_pos;
|
|
||||||
uint32_t next_uv_wrap = available / sampler.uv_step;
|
|
||||||
if (available % sampler.uv_step != 0)
|
|
||||||
next_uv_wrap++;
|
|
||||||
uint32_t count = MIN(left, next_uv_wrap);
|
|
||||||
|
|
||||||
dc_source = sampler.source;
|
|
||||||
dc_dest = (ylookup[y1] + x) + dc_destorg;
|
|
||||||
dc_count = count;
|
|
||||||
dc_iscale = sampler.uv_step;
|
|
||||||
dc_texturefrac = uv_pos;
|
|
||||||
draw1column();
|
|
||||||
|
|
||||||
left -= count;
|
|
||||||
uv_pos += sampler.uv_step * count;
|
|
||||||
if (uv_pos >= sampler.uv_max)
|
|
||||||
uv_pos -= sampler.uv_max;
|
|
||||||
}
|
|
||||||
|
|
||||||
sampler.uv_pos = uv_pos;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw four columns with support for non-power-of-two ranges
|
|
||||||
void wallscan_drawcol4(int x, int y1, int y2, WallscanSampler *sampler, void(*draw4columns)())
|
|
||||||
{
|
|
||||||
if (sampler[0].uv_max == 0 || sampler[0].uv_step == 0) // power of two, no wrap handling needed
|
|
||||||
{
|
|
||||||
int count = y2 - y1;
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
bufplce[i] = sampler[i].source;
|
|
||||||
vplce[i] = sampler[i].uv_pos;
|
|
||||||
vince[i] = sampler[i].uv_step;
|
|
||||||
|
|
||||||
uint64_t step64 = sampler[i].uv_step;
|
|
||||||
uint64_t pos64 = sampler[i].uv_pos;
|
|
||||||
sampler[i].uv_pos = (uint32_t)(pos64 + step64 * count);
|
|
||||||
}
|
|
||||||
dc_dest = (ylookup[y1] + x) + dc_destorg;
|
|
||||||
dc_count = count;
|
|
||||||
draw4columns();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dc_dest = (ylookup[y1] + x) + dc_destorg;
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
bufplce[i] = sampler[i].source;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t left = y2 - y1;
|
|
||||||
while (left > 0)
|
|
||||||
{
|
|
||||||
// Find which column wraps first
|
|
||||||
uint32_t count = left;
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
uint32_t available = sampler[i].uv_max - sampler[i].uv_pos;
|
|
||||||
uint32_t next_uv_wrap = available / sampler[i].uv_step;
|
|
||||||
if (available % sampler[i].uv_step != 0)
|
|
||||||
next_uv_wrap++;
|
|
||||||
count = MIN(next_uv_wrap, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw until that column wraps
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
vplce[i] = sampler[i].uv_pos;
|
|
||||||
vince[i] = sampler[i].uv_step;
|
|
||||||
}
|
|
||||||
dc_count = count;
|
|
||||||
draw4columns();
|
|
||||||
|
|
||||||
// Wrap the uv position
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
sampler[i].uv_pos += sampler[i].uv_step * count;
|
|
||||||
if (sampler[i].uv_pos >= sampler[i].uv_max)
|
|
||||||
sampler[i].uv_pos -= sampler[i].uv_max;
|
|
||||||
}
|
|
||||||
|
|
||||||
left -= count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef DWORD(*Draw1ColumnFuncPtr)();
|
|
||||||
typedef void(*Draw4ColumnsFuncPtr)();
|
|
||||||
|
|
||||||
void wallscan_any(
|
|
||||||
int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat,
|
|
||||||
const BYTE *(*getcol)(FTexture *tex, int x),
|
|
||||||
void(setupwallscan(int bits, Draw1ColumnFuncPtr &draw1, Draw4ColumnsFuncPtr &draw2)))
|
|
||||||
{
|
|
||||||
if (rw_pic->UseType == FTexture::TEX_Null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
fixed_t xoffset = rw_offset;
|
|
||||||
|
|
||||||
rw_pic->GetHeight(); // To ensure that rw_pic->HeightBits has been set
|
|
||||||
int fracbits = 32 - rw_pic->HeightBits;
|
|
||||||
if (fracbits == 32)
|
|
||||||
{ // Hack for one pixel tall textures
|
|
||||||
fracbits = 0;
|
|
||||||
yrepeat = 0;
|
|
||||||
dc_texturemid = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD(*draw1column)();
|
|
||||||
void(*draw4columns)();
|
|
||||||
setupwallscan(fracbits, draw1column, draw4columns);
|
|
||||||
|
|
||||||
bool fixed = (fixedcolormap != NULL || fixedlightlev >= 0);
|
|
||||||
if (fixed)
|
|
||||||
{
|
|
||||||
palookupoffse[0] = dc_colormap;
|
|
||||||
palookupoffse[1] = dc_colormap;
|
|
||||||
palookupoffse[2] = dc_colormap;
|
|
||||||
palookupoffse[3] = dc_colormap;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fixedcolormap)
|
|
||||||
dc_colormap = fixedcolormap;
|
|
||||||
else
|
|
||||||
dc_colormap = basecolormap->Maps;
|
|
||||||
|
|
||||||
float light = rw_light;
|
|
||||||
|
|
||||||
// Calculate where 4 column alignment begins and ends:
|
|
||||||
int aligned_x1 = clamp((x1 + 3) / 4 * 4, x1, x2);
|
|
||||||
int aligned_x2 = clamp(x2 / 4 * 4, x1, x2);
|
|
||||||
|
|
||||||
// First unaligned columns:
|
|
||||||
for (int x = x1; x < aligned_x1; x++, light += rw_lightstep)
|
|
||||||
{
|
|
||||||
int y1 = uwal[x];
|
|
||||||
int y2 = dwal[x];
|
|
||||||
if (y2 <= y1)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!fixed)
|
|
||||||
dc_colormap = basecolormap->Maps + (GETPALOOKUP(light, wallshade) << COLORMAPSHIFT);
|
|
||||||
|
|
||||||
WallscanSampler sampler(y1, swal[x], yrepeat, lwal[x] + xoffset, rw_pic, getcol);
|
|
||||||
wallscan_drawcol1(x, y1, y2, sampler, draw1column);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The aligned columns
|
|
||||||
for (int x = aligned_x1; x < aligned_x2; x += 4)
|
|
||||||
{
|
|
||||||
// Find y1, y2, light and uv values for four columns:
|
|
||||||
int y1[4] = { uwal[x], uwal[x + 1], uwal[x + 2], uwal[x + 3] };
|
|
||||||
int y2[4] = { dwal[x], dwal[x + 1], dwal[x + 2], dwal[x + 3] };
|
|
||||||
|
|
||||||
float lights[4];
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
lights[i] = light;
|
|
||||||
light += rw_lightstep;
|
|
||||||
}
|
|
||||||
|
|
||||||
WallscanSampler sampler[4];
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
sampler[i] = WallscanSampler(y1[i], swal[x + i], yrepeat, lwal[x + i] + xoffset, rw_pic, getcol);
|
|
||||||
|
|
||||||
// Figure out where we vertically can start and stop drawing 4 columns in one go
|
|
||||||
int middle_y1 = y1[0];
|
|
||||||
int middle_y2 = y2[0];
|
|
||||||
for (int i = 1; i < 4; i++)
|
|
||||||
{
|
|
||||||
middle_y1 = MAX(y1[i], middle_y1);
|
|
||||||
middle_y2 = MIN(y2[i], middle_y2);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we got an empty column in our set we cannot draw 4 columns in one go:
|
|
||||||
bool empty_column_in_set = false;
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
if (y2[i] <= y1[i])
|
|
||||||
empty_column_in_set = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (empty_column_in_set || middle_y2 <= middle_y1)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
if (y2[i] <= y1[i])
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!fixed)
|
|
||||||
dc_colormap = basecolormap->Maps + (GETPALOOKUP(lights[i], wallshade) << COLORMAPSHIFT);
|
|
||||||
wallscan_drawcol1(x + i, y1[i], y2[i], sampler[i], draw1column);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw the first rows where not all 4 columns are active
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
if (!fixed)
|
|
||||||
dc_colormap = basecolormap->Maps + (GETPALOOKUP(lights[i], wallshade) << COLORMAPSHIFT);
|
|
||||||
|
|
||||||
if (y1[i] < middle_y1)
|
|
||||||
wallscan_drawcol1(x + i, y1[i], middle_y1, sampler[i], draw1column);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw the area where all 4 columns are active
|
|
||||||
if (!fixed)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
palookupoffse[i] = basecolormap->Maps + (GETPALOOKUP(lights[i], wallshade) << COLORMAPSHIFT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
wallscan_drawcol4(x, middle_y1, middle_y2, sampler, draw4columns);
|
|
||||||
|
|
||||||
// Draw the last rows where not all 4 columns are active
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
if (!fixed)
|
|
||||||
dc_colormap = basecolormap->Maps + (GETPALOOKUP(lights[i], wallshade) << COLORMAPSHIFT);
|
|
||||||
|
|
||||||
if (middle_y2 < y2[i])
|
|
||||||
wallscan_drawcol1(x + i, middle_y2, y2[i], sampler[i], draw1column);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The last unaligned columns:
|
|
||||||
for (int x = aligned_x2; x < x2; x++, light += rw_lightstep)
|
|
||||||
{
|
|
||||||
int y1 = uwal[x];
|
|
||||||
int y2 = dwal[x];
|
|
||||||
if (y2 <= y1)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!fixed)
|
|
||||||
dc_colormap = basecolormap->Maps + (GETPALOOKUP(light, wallshade) << COLORMAPSHIFT);
|
|
||||||
|
|
||||||
WallscanSampler sampler(y1, swal[x], yrepeat, lwal[x] + xoffset, rw_pic, getcol);
|
|
||||||
wallscan_drawcol1(x, y1, y2, sampler, draw1column);
|
|
||||||
}
|
|
||||||
|
|
||||||
NetUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
void wallscan(int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, const BYTE *(*getcol)(FTexture *tex, int x))
|
|
||||||
{
|
|
||||||
wallscan_any(x1, x2, uwal, dwal, swal, lwal, yrepeat, getcol, [](int bits, Draw1ColumnFuncPtr &line1, Draw4ColumnsFuncPtr &line4)
|
|
||||||
{
|
|
||||||
setupvline(bits);
|
|
||||||
line1 = dovline1;
|
|
||||||
line4 = dovline4;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void maskwallscan(int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, const BYTE *(*getcol)(FTexture *tex, int x))
|
|
||||||
{
|
|
||||||
if (!rw_pic->bMasked) // Textures that aren't masked can use the faster wallscan.
|
|
||||||
{
|
|
||||||
wallscan(x1, x2, uwal, dwal, swal, lwal, yrepeat, getcol);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
wallscan_any(x1, x2, uwal, dwal, swal, lwal, yrepeat, getcol, [](int bits, Draw1ColumnFuncPtr &line1, Draw4ColumnsFuncPtr &line4)
|
|
||||||
{
|
|
||||||
setupmvline(bits);
|
|
||||||
line1 = domvline1;
|
|
||||||
line4 = domvline4;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void transmaskwallscan(int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, const BYTE *(*getcol)(FTexture *tex, int x))
|
|
||||||
{
|
|
||||||
static fixed_t(*tmvline1)();
|
|
||||||
static void(*tmvline4)();
|
|
||||||
if (!R_GetTransMaskDrawers(&tmvline1, &tmvline4))
|
|
||||||
{
|
|
||||||
// The current translucency is unsupported, so draw with regular maskwallscan instead.
|
|
||||||
maskwallscan(x1, x2, uwal, dwal, swal, lwal, yrepeat, getcol);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
wallscan_any(x1, x2, uwal, dwal, swal, lwal, yrepeat, getcol, [](int bits, Draw1ColumnFuncPtr &line1, Draw4ColumnsFuncPtr &line4)
|
|
||||||
{
|
|
||||||
setuptmvline(bits);
|
|
||||||
line1 = reinterpret_cast<DWORD(*)()>(tmvline1);
|
|
||||||
line4 = tmvline4;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void wallscan_striped (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat)
|
|
||||||
{
|
|
||||||
FDynamicColormap *startcolormap = basecolormap;
|
|
||||||
int startshade = wallshade;
|
|
||||||
bool fogginess = foggy;
|
|
||||||
|
|
||||||
short most1[MAXWIDTH], most2[MAXWIDTH], most3[MAXWIDTH];
|
|
||||||
short *up, *down;
|
|
||||||
|
|
||||||
up = uwal;
|
|
||||||
down = most1;
|
|
||||||
|
|
||||||
assert(WallC.sx1 <= x1);
|
|
||||||
assert(WallC.sx2 >= x2);
|
|
||||||
|
|
||||||
// kg3D - fake floors instead of zdoom light list
|
|
||||||
for (unsigned int i = 0; i < frontsector->e->XFloor.lightlist.Size(); i++)
|
|
||||||
{
|
|
||||||
int j = WallMost (most3, frontsector->e->XFloor.lightlist[i].plane, &WallC);
|
|
||||||
if (j != 3)
|
|
||||||
{
|
|
||||||
for (int j = x1; j < x2; ++j)
|
|
||||||
{
|
|
||||||
down[j] = clamp (most3[j], up[j], dwal[j]);
|
|
||||||
}
|
|
||||||
wallscan (x1, x2, up, down, swal, lwal, yrepeat);
|
|
||||||
up = down;
|
|
||||||
down = (down == most1) ? most2 : most1;
|
|
||||||
}
|
|
||||||
|
|
||||||
lightlist_t *lit = &frontsector->e->XFloor.lightlist[i];
|
|
||||||
basecolormap = lit->extra_colormap;
|
|
||||||
wallshade = LIGHT2SHADE(curline->sidedef->GetLightLevel(fogginess,
|
|
||||||
*lit->p_lightlevel, lit->lightsource != NULL) + r_actualextralight);
|
|
||||||
}
|
|
||||||
|
|
||||||
wallscan (x1, x2, up, dwal, swal, lwal, yrepeat);
|
|
||||||
basecolormap = startcolormap;
|
|
||||||
wallshade = startshade;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void call_wallscan(int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, bool mask)
|
|
||||||
{
|
|
||||||
if (mask)
|
|
||||||
{
|
|
||||||
if (colfunc == basecolfunc)
|
|
||||||
{
|
|
||||||
maskwallscan(x1, x2, uwal, dwal, swal, lwal, yrepeat);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
transmaskwallscan(x1, x2, uwal, dwal, swal, lwal, yrepeat);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (fixedcolormap != NULL || fixedlightlev >= 0 || !(frontsector->e && frontsector->e->XFloor.lightlist.Size()))
|
|
||||||
{
|
|
||||||
wallscan(x1, x2, uwal, dwal, swal, lwal, yrepeat);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
wallscan_striped(x1, x2, uwal, dwal, swal, lwal, yrepeat);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//=============================================================================
|
|
||||||
//
|
|
||||||
// wallscan_np2
|
|
||||||
//
|
|
||||||
// This is a wrapper around wallscan that helps it tile textures whose heights
|
|
||||||
// are not powers of 2. It divides the wall into texture-sized strips and calls
|
|
||||||
// wallscan for each of those. Since only one repetition of the texture fits
|
|
||||||
// in each strip, wallscan will not tile.
|
|
||||||
//
|
|
||||||
//=============================================================================
|
|
||||||
|
|
||||||
void wallscan_np2(int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, double top, double bot, bool mask)
|
|
||||||
{
|
|
||||||
if (!r_np2)
|
|
||||||
{
|
|
||||||
call_wallscan(x1, x2, uwal, dwal, swal, lwal, yrepeat, mask);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
short most1[MAXWIDTH], most2[MAXWIDTH], most3[MAXWIDTH];
|
|
||||||
short *up, *down;
|
|
||||||
double texheight = rw_pic->GetHeight();
|
|
||||||
double partition;
|
|
||||||
double scaledtexheight = texheight / yrepeat;
|
|
||||||
|
|
||||||
if (yrepeat >= 0)
|
|
||||||
{ // normal orientation: draw strips from top to bottom
|
|
||||||
partition = top - fmod(top - dc_texturemid / yrepeat - ViewPos.Z, scaledtexheight);
|
|
||||||
if (partition == top)
|
|
||||||
{
|
|
||||||
partition -= scaledtexheight;
|
|
||||||
}
|
|
||||||
up = uwal;
|
|
||||||
down = most1;
|
|
||||||
dc_texturemid = (partition - ViewPos.Z) * yrepeat + texheight;
|
|
||||||
while (partition > bot)
|
|
||||||
{
|
|
||||||
int j = OWallMost(most3, partition - ViewPos.Z, &WallC);
|
|
||||||
if (j != 3)
|
|
||||||
{
|
|
||||||
for (int j = x1; j < x2; ++j)
|
|
||||||
{
|
|
||||||
down[j] = clamp(most3[j], up[j], dwal[j]);
|
|
||||||
}
|
|
||||||
call_wallscan(x1, x2, up, down, swal, lwal, yrepeat, mask);
|
|
||||||
up = down;
|
|
||||||
down = (down == most1) ? most2 : most1;
|
|
||||||
}
|
|
||||||
partition -= scaledtexheight;
|
|
||||||
dc_texturemid -= texheight;
|
|
||||||
}
|
|
||||||
call_wallscan(x1, x2, up, dwal, swal, lwal, yrepeat, mask);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // upside down: draw strips from bottom to top
|
|
||||||
partition = bot - fmod(bot - dc_texturemid / yrepeat - ViewPos.Z, scaledtexheight);
|
|
||||||
up = most1;
|
|
||||||
down = dwal;
|
|
||||||
dc_texturemid = (partition - ViewPos.Z) * yrepeat + texheight;
|
|
||||||
while (partition < top)
|
|
||||||
{
|
|
||||||
int j = OWallMost(most3, partition - ViewPos.Z, &WallC);
|
|
||||||
if (j != 12)
|
|
||||||
{
|
|
||||||
for (int j = x1; j < x2; ++j)
|
|
||||||
{
|
|
||||||
up[j] = clamp(most3[j], uwal[j], down[j]);
|
|
||||||
}
|
|
||||||
call_wallscan(x1, x2, up, down, swal, lwal, yrepeat, mask);
|
|
||||||
down = up;
|
|
||||||
up = (up == most1) ? most2 : most1;
|
|
||||||
}
|
|
||||||
partition -= scaledtexheight;
|
|
||||||
dc_texturemid -= texheight;
|
|
||||||
}
|
|
||||||
call_wallscan(x1, x2, uwal, down, swal, lwal, yrepeat, mask);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void wallscan_np2_ds(drawseg_t *ds, int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat)
|
|
||||||
{
|
|
||||||
if (rw_pic->GetHeight() != 1 << rw_pic->HeightBits)
|
|
||||||
{
|
|
||||||
double frontcz1 = ds->curline->frontsector->ceilingplane.ZatPoint(ds->curline->v1);
|
|
||||||
double frontfz1 = ds->curline->frontsector->floorplane.ZatPoint(ds->curline->v1);
|
|
||||||
double frontcz2 = ds->curline->frontsector->ceilingplane.ZatPoint(ds->curline->v2);
|
|
||||||
double frontfz2 = ds->curline->frontsector->floorplane.ZatPoint(ds->curline->v2);
|
|
||||||
double top = MAX(frontcz1, frontcz2);
|
|
||||||
double bot = MIN(frontfz1, frontfz2);
|
|
||||||
if (fake3D & FAKE3D_CLIPTOP)
|
|
||||||
{
|
|
||||||
top = MIN(top, sclipTop);
|
|
||||||
}
|
|
||||||
if (fake3D & FAKE3D_CLIPBOTTOM)
|
|
||||||
{
|
|
||||||
bot = MAX(bot, sclipBottom);
|
|
||||||
}
|
|
||||||
wallscan_np2(x1, x2, uwal, dwal, swal, lwal, yrepeat, top, bot, true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
call_wallscan(x1, x2, uwal, dwal, swal, lwal, yrepeat, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// R_RenderSegLoop
|
// R_RenderSegLoop
|
||||||
// Draws zero, one, or two textures for walls.
|
// Draws zero, one, or two textures for walls.
|
||||||
|
@ -1720,8 +1184,8 @@ void R_RenderSegLoop ()
|
||||||
call_wallscan(x1, x2, walltop, wallbottom, swall, lwall, yscale, false);
|
call_wallscan(x1, x2, walltop, wallbottom, swall, lwall, yscale, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
clearbufshort (ceilingclip+x1, x2-x1, viewheight);
|
fillshort (ceilingclip+x1, x2-x1, viewheight);
|
||||||
clearbufshort (floorclip+x1, x2-x1, 0xffff);
|
fillshort (floorclip+x1, x2-x1, 0xffff);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ // two sided line
|
{ // two sided line
|
||||||
|
@ -2244,7 +1708,7 @@ void R_StoreWallRange (int start, int stop)
|
||||||
{
|
{
|
||||||
ds_p->sprtopclip = R_NewOpening (stop - start);
|
ds_p->sprtopclip = R_NewOpening (stop - start);
|
||||||
ds_p->sprbottomclip = R_NewOpening (stop - start);
|
ds_p->sprbottomclip = R_NewOpening (stop - start);
|
||||||
clearbufshort (openings + ds_p->sprtopclip, stop-start, viewheight);
|
fillshort (openings + ds_p->sprtopclip, stop-start, viewheight);
|
||||||
memset (openings + ds_p->sprbottomclip, -1, (stop-start)*sizeof(short));
|
memset (openings + ds_p->sprbottomclip, -1, (stop-start)*sizeof(short));
|
||||||
ds_p->silhouette = SIL_BOTH;
|
ds_p->silhouette = SIL_BOTH;
|
||||||
}
|
}
|
||||||
|
@ -2284,7 +1748,7 @@ void R_StoreWallRange (int start, int stop)
|
||||||
if (doorclosed || (rw_backfz1 >= rw_frontcz1 && rw_backfz2 >= rw_frontcz2))
|
if (doorclosed || (rw_backfz1 >= rw_frontcz1 && rw_backfz2 >= rw_frontcz2))
|
||||||
{ // killough 1/17/98, 2/8/98
|
{ // killough 1/17/98, 2/8/98
|
||||||
ds_p->sprtopclip = R_NewOpening (stop - start);
|
ds_p->sprtopclip = R_NewOpening (stop - start);
|
||||||
clearbufshort (openings + ds_p->sprtopclip, stop - start, viewheight);
|
fillshort (openings + ds_p->sprtopclip, stop - start, viewheight);
|
||||||
ds_p->silhouette |= SIL_TOP;
|
ds_p->silhouette |= SIL_TOP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2505,7 +1969,7 @@ int WallMostAny(short *mostbuf, double z1, double z2, const FWallCoords *wallc)
|
||||||
}
|
}
|
||||||
else if (y1 > viewheight && y2 > viewheight) // entire line is below screen
|
else if (y1 > viewheight && y2 > viewheight) // entire line is below screen
|
||||||
{
|
{
|
||||||
clearbufshort(&mostbuf[wallc->sx1], wallc->sx2 - wallc->sx1, viewheight);
|
fillshort(&mostbuf[wallc->sx1], wallc->sx2 - wallc->sx1, viewheight);
|
||||||
return 12;
|
return 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2331,11 +2331,11 @@ void R_DrawSprite (vissprite_t *spr)
|
||||||
// for R_DrawVisVoxel().
|
// for R_DrawVisVoxel().
|
||||||
if (x1 > 0)
|
if (x1 > 0)
|
||||||
{
|
{
|
||||||
clearbufshort(cliptop, x1, viewheight);
|
fillshort(cliptop, x1, viewheight);
|
||||||
}
|
}
|
||||||
if (x2 < viewwidth - 1)
|
if (x2 < viewwidth - 1)
|
||||||
{
|
{
|
||||||
clearbufshort(cliptop + x2, viewwidth - x2, viewheight);
|
fillshort(cliptop + x2, viewwidth - x2, viewheight);
|
||||||
}
|
}
|
||||||
int minvoxely = spr->gzt <= hzt ? 0 : xs_RoundToInt((spr->gzt - hzt) / spr->yscale);
|
int minvoxely = spr->gzt <= hzt ? 0 : xs_RoundToInt((spr->gzt - hzt) / spr->yscale);
|
||||||
int maxvoxely = spr->gzb > hzb ? INT_MAX : xs_RoundToInt((spr->gzt - hzb) / spr->yscale);
|
int maxvoxely = spr->gzb > hzb ? INT_MAX : xs_RoundToInt((spr->gzt - hzb) / spr->yscale);
|
||||||
|
@ -2701,6 +2701,11 @@ void R_DrawParticle_C (vissprite_t *vis)
|
||||||
|
|
||||||
extern double BaseYaspectMul;;
|
extern double BaseYaspectMul;;
|
||||||
|
|
||||||
|
inline int sgn(int v)
|
||||||
|
{
|
||||||
|
return v < 0 ? -1 : v > 0 ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
void R_DrawVoxel(const FVector3 &globalpos, FAngle viewangle,
|
void R_DrawVoxel(const FVector3 &globalpos, FAngle viewangle,
|
||||||
const FVector3 &dasprpos, DAngle dasprang,
|
const FVector3 &dasprpos, DAngle dasprang,
|
||||||
fixed_t daxscale, fixed_t dayscale, FVoxel *voxobj,
|
fixed_t daxscale, fixed_t dayscale, FVoxel *voxobj,
|
||||||
|
@ -2840,7 +2845,7 @@ void R_DrawVoxel(const FVector3 &globalpos, FAngle viewangle,
|
||||||
xe += xi; ye += yi;
|
xe += xi; ye += yi;
|
||||||
}
|
}
|
||||||
|
|
||||||
i = ksgn(ys-backy)+ksgn(xs-backx)*3+4;
|
i = sgn(ys - backy) + sgn(xs - backx) * 3 + 4;
|
||||||
switch(i)
|
switch(i)
|
||||||
{
|
{
|
||||||
case 6: case 7: x1 = 0; y1 = 0; break;
|
case 6: case 7: x1 = 0; y1 = 0; break;
|
||||||
|
|
583
src/r_walldraw.cpp
Normal file
583
src/r_walldraw.cpp
Normal file
|
@ -0,0 +1,583 @@
|
||||||
|
/*
|
||||||
|
** Wall drawing stuff free of Build pollution
|
||||||
|
** Copyright (c) 2016 Magnus Norddahl
|
||||||
|
**
|
||||||
|
** This software is provided 'as-is', without any express or implied
|
||||||
|
** warranty. In no event will the authors be held liable for any damages
|
||||||
|
** arising from the use of this software.
|
||||||
|
**
|
||||||
|
** Permission is granted to anyone to use this software for any purpose,
|
||||||
|
** including commercial applications, and to alter it and redistribute it
|
||||||
|
** freely, subject to the following restrictions:
|
||||||
|
**
|
||||||
|
** 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
** claim that you wrote the original software. If you use this software
|
||||||
|
** in a product, an acknowledgment in the product documentation would be
|
||||||
|
** appreciated but is not required.
|
||||||
|
** 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
** misrepresented as being the original software.
|
||||||
|
** 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include "doomdef.h"
|
||||||
|
#include "doomstat.h"
|
||||||
|
#include "doomdata.h"
|
||||||
|
|
||||||
|
#include "r_local.h"
|
||||||
|
#include "r_sky.h"
|
||||||
|
#include "v_video.h"
|
||||||
|
|
||||||
|
#include "m_swap.h"
|
||||||
|
#include "a_sharedglobal.h"
|
||||||
|
#include "d_net.h"
|
||||||
|
#include "g_level.h"
|
||||||
|
#include "r_draw.h"
|
||||||
|
#include "r_bsp.h"
|
||||||
|
#include "r_plane.h"
|
||||||
|
#include "r_segs.h"
|
||||||
|
#include "r_3dfloors.h"
|
||||||
|
#include "v_palette.h"
|
||||||
|
#include "r_data/colormaps.h"
|
||||||
|
|
||||||
|
namespace swrenderer
|
||||||
|
{
|
||||||
|
using namespace drawerargs;
|
||||||
|
|
||||||
|
extern FTexture *rw_pic;
|
||||||
|
extern int wallshade;
|
||||||
|
|
||||||
|
struct WallscanSampler
|
||||||
|
{
|
||||||
|
WallscanSampler() { }
|
||||||
|
WallscanSampler(int y1, float swal, double yrepeat, fixed_t xoffset, FTexture *texture, const BYTE*(*getcol)(FTexture *texture, int x));
|
||||||
|
|
||||||
|
uint32_t uv_pos;
|
||||||
|
uint32_t uv_step;
|
||||||
|
uint32_t uv_max;
|
||||||
|
|
||||||
|
const BYTE *source;
|
||||||
|
uint32_t height;
|
||||||
|
};
|
||||||
|
|
||||||
|
WallscanSampler::WallscanSampler(int y1, float swal, double yrepeat, fixed_t xoffset, FTexture *texture, const BYTE*(*getcol)(FTexture *texture, int x))
|
||||||
|
{
|
||||||
|
height = texture->GetHeight();
|
||||||
|
|
||||||
|
int uv_fracbits = 32 - texture->HeightBits;
|
||||||
|
if (uv_fracbits != 32)
|
||||||
|
{
|
||||||
|
uv_max = height << uv_fracbits;
|
||||||
|
|
||||||
|
// Find start uv in [0-base_height[ range.
|
||||||
|
// Not using xs_ToFixed because it rounds the result and we need something that always rounds down to stay within the range.
|
||||||
|
double uv_stepd = swal * yrepeat;
|
||||||
|
double v = (dc_texturemid + uv_stepd * (y1 - CenterY + 0.5)) / height;
|
||||||
|
v = v - floor(v);
|
||||||
|
v *= height;
|
||||||
|
v *= (1 << uv_fracbits);
|
||||||
|
|
||||||
|
uv_pos = (uint32_t)v;
|
||||||
|
uv_step = xs_ToFixed(uv_fracbits, uv_stepd);
|
||||||
|
if (uv_step == 0) // To prevent divide by zero elsewhere
|
||||||
|
uv_step = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // Hack for one pixel tall textures
|
||||||
|
uv_pos = 0;
|
||||||
|
uv_step = 0;
|
||||||
|
uv_max = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
source = getcol(texture, xoffset >> FRACBITS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw a column with support for non-power-of-two ranges
|
||||||
|
void wallscan_drawcol1(int x, int y1, int y2, WallscanSampler &sampler, DWORD(*draw1column)())
|
||||||
|
{
|
||||||
|
if (sampler.uv_max == 0 || sampler.uv_step == 0) // power of two
|
||||||
|
{
|
||||||
|
int count = y2 - y1;
|
||||||
|
|
||||||
|
dc_source = sampler.source;
|
||||||
|
dc_dest = (ylookup[y1] + x) + dc_destorg;
|
||||||
|
dc_count = count;
|
||||||
|
dc_iscale = sampler.uv_step;
|
||||||
|
dc_texturefrac = sampler.uv_pos;
|
||||||
|
draw1column();
|
||||||
|
|
||||||
|
uint64_t step64 = sampler.uv_step;
|
||||||
|
uint64_t pos64 = sampler.uv_pos;
|
||||||
|
sampler.uv_pos = (uint32_t)(pos64 + step64 * count);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint32_t uv_pos = sampler.uv_pos;
|
||||||
|
|
||||||
|
uint32_t left = y2 - y1;
|
||||||
|
while (left > 0)
|
||||||
|
{
|
||||||
|
uint32_t available = sampler.uv_max - uv_pos;
|
||||||
|
uint32_t next_uv_wrap = available / sampler.uv_step;
|
||||||
|
if (available % sampler.uv_step != 0)
|
||||||
|
next_uv_wrap++;
|
||||||
|
uint32_t count = MIN(left, next_uv_wrap);
|
||||||
|
|
||||||
|
dc_source = sampler.source;
|
||||||
|
dc_dest = (ylookup[y1] + x) + dc_destorg;
|
||||||
|
dc_count = count;
|
||||||
|
dc_iscale = sampler.uv_step;
|
||||||
|
dc_texturefrac = uv_pos;
|
||||||
|
draw1column();
|
||||||
|
|
||||||
|
left -= count;
|
||||||
|
uv_pos += sampler.uv_step * count;
|
||||||
|
if (uv_pos >= sampler.uv_max)
|
||||||
|
uv_pos -= sampler.uv_max;
|
||||||
|
}
|
||||||
|
|
||||||
|
sampler.uv_pos = uv_pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw four columns with support for non-power-of-two ranges
|
||||||
|
void wallscan_drawcol4(int x, int y1, int y2, WallscanSampler *sampler, void(*draw4columns)())
|
||||||
|
{
|
||||||
|
if (sampler[0].uv_max == 0 || sampler[0].uv_step == 0) // power of two, no wrap handling needed
|
||||||
|
{
|
||||||
|
int count = y2 - y1;
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
bufplce[i] = sampler[i].source;
|
||||||
|
vplce[i] = sampler[i].uv_pos;
|
||||||
|
vince[i] = sampler[i].uv_step;
|
||||||
|
|
||||||
|
uint64_t step64 = sampler[i].uv_step;
|
||||||
|
uint64_t pos64 = sampler[i].uv_pos;
|
||||||
|
sampler[i].uv_pos = (uint32_t)(pos64 + step64 * count);
|
||||||
|
}
|
||||||
|
dc_dest = (ylookup[y1] + x) + dc_destorg;
|
||||||
|
dc_count = count;
|
||||||
|
draw4columns();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dc_dest = (ylookup[y1] + x) + dc_destorg;
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
bufplce[i] = sampler[i].source;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t left = y2 - y1;
|
||||||
|
while (left > 0)
|
||||||
|
{
|
||||||
|
// Find which column wraps first
|
||||||
|
uint32_t count = left;
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
uint32_t available = sampler[i].uv_max - sampler[i].uv_pos;
|
||||||
|
uint32_t next_uv_wrap = available / sampler[i].uv_step;
|
||||||
|
if (available % sampler[i].uv_step != 0)
|
||||||
|
next_uv_wrap++;
|
||||||
|
count = MIN(next_uv_wrap, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw until that column wraps
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
vplce[i] = sampler[i].uv_pos;
|
||||||
|
vince[i] = sampler[i].uv_step;
|
||||||
|
}
|
||||||
|
dc_count = count;
|
||||||
|
draw4columns();
|
||||||
|
|
||||||
|
// Wrap the uv position
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
sampler[i].uv_pos += sampler[i].uv_step * count;
|
||||||
|
if (sampler[i].uv_pos >= sampler[i].uv_max)
|
||||||
|
sampler[i].uv_pos -= sampler[i].uv_max;
|
||||||
|
}
|
||||||
|
|
||||||
|
left -= count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef DWORD(*Draw1ColumnFuncPtr)();
|
||||||
|
typedef void(*Draw4ColumnsFuncPtr)();
|
||||||
|
|
||||||
|
void wallscan_any(
|
||||||
|
int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat,
|
||||||
|
const BYTE *(*getcol)(FTexture *tex, int x),
|
||||||
|
void(setupwallscan(int bits, Draw1ColumnFuncPtr &draw1, Draw4ColumnsFuncPtr &draw2)))
|
||||||
|
{
|
||||||
|
if (rw_pic->UseType == FTexture::TEX_Null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fixed_t xoffset = rw_offset;
|
||||||
|
|
||||||
|
rw_pic->GetHeight(); // To ensure that rw_pic->HeightBits has been set
|
||||||
|
int fracbits = 32 - rw_pic->HeightBits;
|
||||||
|
if (fracbits == 32)
|
||||||
|
{ // Hack for one pixel tall textures
|
||||||
|
fracbits = 0;
|
||||||
|
yrepeat = 0;
|
||||||
|
dc_texturemid = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD(*draw1column)();
|
||||||
|
void(*draw4columns)();
|
||||||
|
setupwallscan(fracbits, draw1column, draw4columns);
|
||||||
|
|
||||||
|
bool fixed = (fixedcolormap != NULL || fixedlightlev >= 0);
|
||||||
|
if (fixed)
|
||||||
|
{
|
||||||
|
palookupoffse[0] = dc_colormap;
|
||||||
|
palookupoffse[1] = dc_colormap;
|
||||||
|
palookupoffse[2] = dc_colormap;
|
||||||
|
palookupoffse[3] = dc_colormap;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fixedcolormap)
|
||||||
|
dc_colormap = fixedcolormap;
|
||||||
|
else
|
||||||
|
dc_colormap = basecolormap->Maps;
|
||||||
|
|
||||||
|
float light = rw_light;
|
||||||
|
|
||||||
|
// Calculate where 4 column alignment begins and ends:
|
||||||
|
int aligned_x1 = clamp((x1 + 3) / 4 * 4, x1, x2);
|
||||||
|
int aligned_x2 = clamp(x2 / 4 * 4, x1, x2);
|
||||||
|
|
||||||
|
// First unaligned columns:
|
||||||
|
for (int x = x1; x < aligned_x1; x++, light += rw_lightstep)
|
||||||
|
{
|
||||||
|
int y1 = uwal[x];
|
||||||
|
int y2 = dwal[x];
|
||||||
|
if (y2 <= y1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!fixed)
|
||||||
|
dc_colormap = basecolormap->Maps + (GETPALOOKUP(light, wallshade) << COLORMAPSHIFT);
|
||||||
|
|
||||||
|
WallscanSampler sampler(y1, swal[x], yrepeat, lwal[x] + xoffset, rw_pic, getcol);
|
||||||
|
wallscan_drawcol1(x, y1, y2, sampler, draw1column);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The aligned columns
|
||||||
|
for (int x = aligned_x1; x < aligned_x2; x += 4)
|
||||||
|
{
|
||||||
|
// Find y1, y2, light and uv values for four columns:
|
||||||
|
int y1[4] = { uwal[x], uwal[x + 1], uwal[x + 2], uwal[x + 3] };
|
||||||
|
int y2[4] = { dwal[x], dwal[x + 1], dwal[x + 2], dwal[x + 3] };
|
||||||
|
|
||||||
|
float lights[4];
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
lights[i] = light;
|
||||||
|
light += rw_lightstep;
|
||||||
|
}
|
||||||
|
|
||||||
|
WallscanSampler sampler[4];
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
sampler[i] = WallscanSampler(y1[i], swal[x + i], yrepeat, lwal[x + i] + xoffset, rw_pic, getcol);
|
||||||
|
|
||||||
|
// Figure out where we vertically can start and stop drawing 4 columns in one go
|
||||||
|
int middle_y1 = y1[0];
|
||||||
|
int middle_y2 = y2[0];
|
||||||
|
for (int i = 1; i < 4; i++)
|
||||||
|
{
|
||||||
|
middle_y1 = MAX(y1[i], middle_y1);
|
||||||
|
middle_y2 = MIN(y2[i], middle_y2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we got an empty column in our set we cannot draw 4 columns in one go:
|
||||||
|
bool empty_column_in_set = false;
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
if (y2[i] <= y1[i])
|
||||||
|
empty_column_in_set = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty_column_in_set || middle_y2 <= middle_y1)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
if (y2[i] <= y1[i])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!fixed)
|
||||||
|
dc_colormap = basecolormap->Maps + (GETPALOOKUP(lights[i], wallshade) << COLORMAPSHIFT);
|
||||||
|
wallscan_drawcol1(x + i, y1[i], y2[i], sampler[i], draw1column);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw the first rows where not all 4 columns are active
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
if (!fixed)
|
||||||
|
dc_colormap = basecolormap->Maps + (GETPALOOKUP(lights[i], wallshade) << COLORMAPSHIFT);
|
||||||
|
|
||||||
|
if (y1[i] < middle_y1)
|
||||||
|
wallscan_drawcol1(x + i, y1[i], middle_y1, sampler[i], draw1column);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw the area where all 4 columns are active
|
||||||
|
if (!fixed)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
palookupoffse[i] = basecolormap->Maps + (GETPALOOKUP(lights[i], wallshade) << COLORMAPSHIFT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wallscan_drawcol4(x, middle_y1, middle_y2, sampler, draw4columns);
|
||||||
|
|
||||||
|
// Draw the last rows where not all 4 columns are active
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
if (!fixed)
|
||||||
|
dc_colormap = basecolormap->Maps + (GETPALOOKUP(lights[i], wallshade) << COLORMAPSHIFT);
|
||||||
|
|
||||||
|
if (middle_y2 < y2[i])
|
||||||
|
wallscan_drawcol1(x + i, middle_y2, y2[i], sampler[i], draw1column);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The last unaligned columns:
|
||||||
|
for (int x = aligned_x2; x < x2; x++, light += rw_lightstep)
|
||||||
|
{
|
||||||
|
int y1 = uwal[x];
|
||||||
|
int y2 = dwal[x];
|
||||||
|
if (y2 <= y1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!fixed)
|
||||||
|
dc_colormap = basecolormap->Maps + (GETPALOOKUP(light, wallshade) << COLORMAPSHIFT);
|
||||||
|
|
||||||
|
WallscanSampler sampler(y1, swal[x], yrepeat, lwal[x] + xoffset, rw_pic, getcol);
|
||||||
|
wallscan_drawcol1(x, y1, y2, sampler, draw1column);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void wallscan(int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, const BYTE *(*getcol)(FTexture *tex, int x))
|
||||||
|
{
|
||||||
|
wallscan_any(x1, x2, uwal, dwal, swal, lwal, yrepeat, getcol, [](int bits, Draw1ColumnFuncPtr &line1, Draw4ColumnsFuncPtr &line4)
|
||||||
|
{
|
||||||
|
setupvline(bits);
|
||||||
|
line1 = dovline1;
|
||||||
|
line4 = dovline4;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void maskwallscan(int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, const BYTE *(*getcol)(FTexture *tex, int x) = R_GetColumn)
|
||||||
|
{
|
||||||
|
if (!rw_pic->bMasked) // Textures that aren't masked can use the faster wallscan.
|
||||||
|
{
|
||||||
|
wallscan(x1, x2, uwal, dwal, swal, lwal, yrepeat, getcol);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wallscan_any(x1, x2, uwal, dwal, swal, lwal, yrepeat, getcol, [](int bits, Draw1ColumnFuncPtr &line1, Draw4ColumnsFuncPtr &line4)
|
||||||
|
{
|
||||||
|
setupmvline(bits);
|
||||||
|
line1 = domvline1;
|
||||||
|
line4 = domvline4;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void transmaskwallscan(int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, const BYTE *(*getcol)(FTexture *tex, int x) = R_GetColumn)
|
||||||
|
{
|
||||||
|
static fixed_t(*tmvline1)();
|
||||||
|
static void(*tmvline4)();
|
||||||
|
if (!R_GetTransMaskDrawers(&tmvline1, &tmvline4))
|
||||||
|
{
|
||||||
|
// The current translucency is unsupported, so draw with regular maskwallscan instead.
|
||||||
|
maskwallscan(x1, x2, uwal, dwal, swal, lwal, yrepeat, getcol);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wallscan_any(x1, x2, uwal, dwal, swal, lwal, yrepeat, getcol, [](int bits, Draw1ColumnFuncPtr &line1, Draw4ColumnsFuncPtr &line4)
|
||||||
|
{
|
||||||
|
setuptmvline(bits);
|
||||||
|
line1 = reinterpret_cast<DWORD(*)()>(tmvline1);
|
||||||
|
line4 = tmvline4;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void wallscan_striped (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat)
|
||||||
|
{
|
||||||
|
FDynamicColormap *startcolormap = basecolormap;
|
||||||
|
int startshade = wallshade;
|
||||||
|
bool fogginess = foggy;
|
||||||
|
|
||||||
|
short most1[MAXWIDTH], most2[MAXWIDTH], most3[MAXWIDTH];
|
||||||
|
short *up, *down;
|
||||||
|
|
||||||
|
up = uwal;
|
||||||
|
down = most1;
|
||||||
|
|
||||||
|
assert(WallC.sx1 <= x1);
|
||||||
|
assert(WallC.sx2 >= x2);
|
||||||
|
|
||||||
|
// kg3D - fake floors instead of zdoom light list
|
||||||
|
for (unsigned int i = 0; i < frontsector->e->XFloor.lightlist.Size(); i++)
|
||||||
|
{
|
||||||
|
int j = WallMost (most3, frontsector->e->XFloor.lightlist[i].plane, &WallC);
|
||||||
|
if (j != 3)
|
||||||
|
{
|
||||||
|
for (int j = x1; j < x2; ++j)
|
||||||
|
{
|
||||||
|
down[j] = clamp (most3[j], up[j], dwal[j]);
|
||||||
|
}
|
||||||
|
wallscan (x1, x2, up, down, swal, lwal, yrepeat);
|
||||||
|
up = down;
|
||||||
|
down = (down == most1) ? most2 : most1;
|
||||||
|
}
|
||||||
|
|
||||||
|
lightlist_t *lit = &frontsector->e->XFloor.lightlist[i];
|
||||||
|
basecolormap = lit->extra_colormap;
|
||||||
|
wallshade = LIGHT2SHADE(curline->sidedef->GetLightLevel(fogginess,
|
||||||
|
*lit->p_lightlevel, lit->lightsource != NULL) + r_actualextralight);
|
||||||
|
}
|
||||||
|
|
||||||
|
wallscan (x1, x2, up, dwal, swal, lwal, yrepeat);
|
||||||
|
basecolormap = startcolormap;
|
||||||
|
wallshade = startshade;
|
||||||
|
}
|
||||||
|
|
||||||
|
void call_wallscan(int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, bool mask)
|
||||||
|
{
|
||||||
|
if (mask)
|
||||||
|
{
|
||||||
|
if (colfunc == basecolfunc)
|
||||||
|
{
|
||||||
|
maskwallscan(x1, x2, uwal, dwal, swal, lwal, yrepeat);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
transmaskwallscan(x1, x2, uwal, dwal, swal, lwal, yrepeat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (fixedcolormap != NULL || fixedlightlev >= 0 || !(frontsector->e && frontsector->e->XFloor.lightlist.Size()))
|
||||||
|
{
|
||||||
|
wallscan(x1, x2, uwal, dwal, swal, lwal, yrepeat);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wallscan_striped(x1, x2, uwal, dwal, swal, lwal, yrepeat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
//
|
||||||
|
// wallscan_np2
|
||||||
|
//
|
||||||
|
// This is a wrapper around wallscan that helps it tile textures whose heights
|
||||||
|
// are not powers of 2. It divides the wall into texture-sized strips and calls
|
||||||
|
// wallscan for each of those. Since only one repetition of the texture fits
|
||||||
|
// in each strip, wallscan will not tile.
|
||||||
|
//
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
|
void wallscan_np2(int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, double top, double bot, bool mask)
|
||||||
|
{
|
||||||
|
short most1[MAXWIDTH], most2[MAXWIDTH], most3[MAXWIDTH];
|
||||||
|
short *up, *down;
|
||||||
|
double texheight = rw_pic->GetHeight();
|
||||||
|
double partition;
|
||||||
|
double scaledtexheight = texheight / yrepeat;
|
||||||
|
|
||||||
|
if (yrepeat >= 0)
|
||||||
|
{ // normal orientation: draw strips from top to bottom
|
||||||
|
partition = top - fmod(top - dc_texturemid / yrepeat - ViewPos.Z, scaledtexheight);
|
||||||
|
if (partition == top)
|
||||||
|
{
|
||||||
|
partition -= scaledtexheight;
|
||||||
|
}
|
||||||
|
up = uwal;
|
||||||
|
down = most1;
|
||||||
|
dc_texturemid = (partition - ViewPos.Z) * yrepeat + texheight;
|
||||||
|
while (partition > bot)
|
||||||
|
{
|
||||||
|
int j = OWallMost(most3, partition - ViewPos.Z, &WallC);
|
||||||
|
if (j != 3)
|
||||||
|
{
|
||||||
|
for (int j = x1; j < x2; ++j)
|
||||||
|
{
|
||||||
|
down[j] = clamp(most3[j], up[j], dwal[j]);
|
||||||
|
}
|
||||||
|
call_wallscan(x1, x2, up, down, swal, lwal, yrepeat, mask);
|
||||||
|
up = down;
|
||||||
|
down = (down == most1) ? most2 : most1;
|
||||||
|
}
|
||||||
|
partition -= scaledtexheight;
|
||||||
|
dc_texturemid -= texheight;
|
||||||
|
}
|
||||||
|
call_wallscan(x1, x2, up, dwal, swal, lwal, yrepeat, mask);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // upside down: draw strips from bottom to top
|
||||||
|
partition = bot - fmod(bot - dc_texturemid / yrepeat - ViewPos.Z, scaledtexheight);
|
||||||
|
up = most1;
|
||||||
|
down = dwal;
|
||||||
|
dc_texturemid = (partition - ViewPos.Z) * yrepeat + texheight;
|
||||||
|
while (partition < top)
|
||||||
|
{
|
||||||
|
int j = OWallMost(most3, partition - ViewPos.Z, &WallC);
|
||||||
|
if (j != 12)
|
||||||
|
{
|
||||||
|
for (int j = x1; j < x2; ++j)
|
||||||
|
{
|
||||||
|
up[j] = clamp(most3[j], uwal[j], down[j]);
|
||||||
|
}
|
||||||
|
call_wallscan(x1, x2, up, down, swal, lwal, yrepeat, mask);
|
||||||
|
down = up;
|
||||||
|
up = (up == most1) ? most2 : most1;
|
||||||
|
}
|
||||||
|
partition -= scaledtexheight;
|
||||||
|
dc_texturemid -= texheight;
|
||||||
|
}
|
||||||
|
call_wallscan(x1, x2, uwal, down, swal, lwal, yrepeat, mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void wallscan_np2_ds(drawseg_t *ds, int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat)
|
||||||
|
{
|
||||||
|
if (rw_pic->GetHeight() != 1 << rw_pic->HeightBits)
|
||||||
|
{
|
||||||
|
double frontcz1 = ds->curline->frontsector->ceilingplane.ZatPoint(ds->curline->v1);
|
||||||
|
double frontfz1 = ds->curline->frontsector->floorplane.ZatPoint(ds->curline->v1);
|
||||||
|
double frontcz2 = ds->curline->frontsector->ceilingplane.ZatPoint(ds->curline->v2);
|
||||||
|
double frontfz2 = ds->curline->frontsector->floorplane.ZatPoint(ds->curline->v2);
|
||||||
|
double top = MAX(frontcz1, frontcz2);
|
||||||
|
double bot = MIN(frontfz1, frontfz2);
|
||||||
|
if (fake3D & FAKE3D_CLIPTOP)
|
||||||
|
{
|
||||||
|
top = MIN(top, sclipTop);
|
||||||
|
}
|
||||||
|
if (fake3D & FAKE3D_CLIPBOTTOM)
|
||||||
|
{
|
||||||
|
bot = MAX(bot, sclipBottom);
|
||||||
|
}
|
||||||
|
wallscan_np2(x1, x2, uwal, dwal, swal, lwal, yrepeat, top, bot, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
call_wallscan(x1, x2, uwal, dwal, swal, lwal, yrepeat, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -235,13 +235,13 @@ void DCanvas::DrawTextureParms(FTexture *img, DrawParms &parms)
|
||||||
|
|
||||||
if (bottomclipper[0] != parms.dclip)
|
if (bottomclipper[0] != parms.dclip)
|
||||||
{
|
{
|
||||||
clearbufshort(bottomclipper, screen->GetWidth(), (short)parms.dclip);
|
fillshort(bottomclipper, screen->GetWidth(), (short)parms.dclip);
|
||||||
}
|
}
|
||||||
if (parms.uclip != 0)
|
if (parms.uclip != 0)
|
||||||
{
|
{
|
||||||
if (topclipper[0] != parms.uclip)
|
if (topclipper[0] != parms.uclip)
|
||||||
{
|
{
|
||||||
clearbufshort(topclipper, screen->GetWidth(), (short)parms.uclip);
|
fillshort(topclipper, screen->GetWidth(), (short)parms.uclip);
|
||||||
}
|
}
|
||||||
mceilingclip = topclipper;
|
mceilingclip = topclipper;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
%ifdef VALGRIND_AWARE
|
|
||||||
|
|
||||||
%define VG_USERREQ__DISCARD_TRANSLATIONS 0x1002
|
|
||||||
|
|
||||||
%macro selfmod 2
|
|
||||||
pusha
|
|
||||||
sub esp,6*4
|
|
||||||
mov dword [esp], VG_USERREQ__DISCARD_TRANSLATIONS
|
|
||||||
mov dword [esp+4], %1
|
|
||||||
mov dword [esp+8], %2 - %1
|
|
||||||
mov dword [esp+12], 0
|
|
||||||
mov dword [esp+16], 0
|
|
||||||
mov dword [esp+20], 0
|
|
||||||
mov eax, esp
|
|
||||||
; special instruction preamble
|
|
||||||
rol edi, 3
|
|
||||||
rol edi, 13
|
|
||||||
rol edi, 29
|
|
||||||
rol edi, 19
|
|
||||||
xchg ebx, ebx
|
|
||||||
; restore state
|
|
||||||
add esp,6*4
|
|
||||||
popa
|
|
||||||
%endmacro
|
|
||||||
|
|
||||||
%else
|
|
||||||
|
|
||||||
%macro selfmod 2
|
|
||||||
%endmacro
|
|
||||||
|
|
||||||
%endif
|
|
Loading…
Reference in a new issue