2016-06-21 00:33:30 +00:00
|
|
|
#pragma once
|
|
|
|
|
2008-12-02 10:44:39 +00:00
|
|
|
#ifndef ENGINE_PRIV_H
|
|
|
|
#define ENGINE_PRIV_H
|
|
|
|
|
|
|
|
#define MAXPERMS 512
|
2014-01-12 14:54:36 +00:00
|
|
|
#define MAXARTFILES_BASE 200
|
|
|
|
#define MAXARTFILES_TOTAL 220
|
2008-12-02 10:44:39 +00:00
|
|
|
#define MAXCLIPDIST 1024
|
|
|
|
|
2013-05-04 16:36:12 +00:00
|
|
|
// Uncomment to clear the screen before each top-level draw (classic only).
|
|
|
|
// FIXME: doesn't work with mirrors.
|
2011-05-17 21:48:13 +00:00
|
|
|
//#define ENGINE_CLEAR_SCREEN
|
2011-05-12 23:31:13 +00:00
|
|
|
|
2011-05-07 18:23:34 +00:00
|
|
|
#ifdef YAX_ENABLE
|
2011-05-12 23:31:13 +00:00
|
|
|
# define YAX_MAXDRAWS 8
|
2011-05-07 18:23:34 +00:00
|
|
|
#endif
|
|
|
|
|
2014-02-11 06:14:03 +00:00
|
|
|
#if !defined(NOASM) && defined __cplusplus
|
2012-11-15 14:28:11 +00:00
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
extern intptr_t asm1, asm2, asm3, asm4;
|
|
|
|
extern int32_t globalx1, globaly2;
|
2014-02-11 06:14:03 +00:00
|
|
|
#if !defined(NOASM) && defined __cplusplus
|
2014-11-26 04:39:23 +00:00
|
|
|
}
|
2012-11-15 14:28:11 +00:00
|
|
|
#endif
|
|
|
|
|
2014-11-28 08:14:00 +00:00
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
2016-06-21 00:33:30 +00:00
|
|
|
extern uint16_t ATTRIBUTE((used)) sqrtable[4096], ATTRIBUTE((used)) shlookup[4096+256];
|
|
|
|
|
|
|
|
#if defined(_MSC_VER) && !defined(NOASM)
|
|
|
|
|
|
|
|
//
|
|
|
|
// Microsoft C Inline Assembly Routines
|
|
|
|
//
|
|
|
|
|
|
|
|
static inline int32_t nsqrtasm(int32_t a)
|
|
|
|
{
|
|
|
|
_asm
|
|
|
|
{
|
|
|
|
push ebx
|
|
|
|
mov eax, a
|
|
|
|
test eax, 0xff000000
|
|
|
|
mov ebx, eax
|
|
|
|
jnz short over24
|
|
|
|
shr ebx, 12
|
|
|
|
mov cx, word ptr shlookup[ebx*2]
|
|
|
|
jmp short under24
|
|
|
|
over24 :
|
|
|
|
shr ebx, 24
|
|
|
|
mov cx, word ptr shlookup[ebx*2+8192]
|
|
|
|
under24 :
|
|
|
|
shr eax, cl
|
|
|
|
mov cl, ch
|
|
|
|
mov ax, word ptr sqrtable[eax*2]
|
|
|
|
shr eax, cl
|
|
|
|
pop ebx
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int32_t msqrtasm(int32_t c)
|
|
|
|
{
|
|
|
|
_asm
|
|
|
|
{
|
|
|
|
push ebx
|
|
|
|
mov ecx, c
|
|
|
|
mov eax, 0x40000000
|
|
|
|
mov ebx, 0x20000000
|
|
|
|
begit:
|
|
|
|
cmp ecx, eax
|
|
|
|
jl skip
|
|
|
|
sub ecx, eax
|
|
|
|
lea eax, [eax+ebx*4]
|
|
|
|
skip :
|
|
|
|
sub eax, ebx
|
|
|
|
shr eax, 1
|
|
|
|
shr ebx, 2
|
|
|
|
jnz begit
|
|
|
|
cmp ecx, eax
|
|
|
|
sbb eax, -1
|
|
|
|
shr eax, 1
|
|
|
|
pop ebx
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int32_t getclipmask(int32_t a, int32_t b, int32_t c, int32_t d)
|
|
|
|
{
|
|
|
|
_asm
|
|
|
|
{
|
|
|
|
push ebx
|
|
|
|
mov eax, a
|
|
|
|
mov ebx, b
|
|
|
|
mov ecx, c
|
|
|
|
mov edx, d
|
|
|
|
sar eax, 31
|
|
|
|
add ebx, ebx
|
|
|
|
adc eax, eax
|
|
|
|
add ecx, ecx
|
|
|
|
adc eax, eax
|
|
|
|
add edx, edx
|
|
|
|
adc eax, eax
|
|
|
|
mov ebx, eax
|
|
|
|
shl ebx, 4
|
|
|
|
or al, 0xf0
|
|
|
|
xor eax, ebx
|
|
|
|
pop ebx
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int32_t getkensmessagecrc(void *b)
|
|
|
|
{
|
|
|
|
_asm
|
|
|
|
{
|
|
|
|
push ebx
|
|
|
|
mov ebx, b
|
|
|
|
xor eax, eax
|
|
|
|
mov ecx, 32
|
|
|
|
beg:
|
|
|
|
mov edx, dword ptr[ebx+ecx*4-4]
|
|
|
|
ror edx, cl
|
|
|
|
adc eax, edx
|
|
|
|
bswap eax
|
|
|
|
loop short beg
|
|
|
|
pop ebx
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#elif defined(__GNUC__) && defined(__i386__) && !defined(NOASM) // _MSC_VER
|
|
|
|
|
|
|
|
//
|
|
|
|
// GCC "Inline" Assembly Routines
|
|
|
|
//
|
|
|
|
|
|
|
|
#define nsqrtasm(a) \
|
|
|
|
({ int32_t __r, __a=(a); \
|
|
|
|
__asm__ __volatile__ ( \
|
|
|
|
"testl $0xff000000, %%eax\n\t" \
|
|
|
|
"movl %%eax, %%ebx\n\t" \
|
|
|
|
"jnz 0f\n\t" \
|
|
|
|
"shrl $12, %%ebx\n\t" \
|
|
|
|
"movw " ASMSYM("shlookup") "(,%%ebx,2), %%cx\n\t" \
|
|
|
|
"jmp 1f\n\t" \
|
|
|
|
"0:\n\t" \
|
|
|
|
"shrl $24, %%ebx\n\t" \
|
|
|
|
"movw (" ASMSYM("shlookup") "+8192)(,%%ebx,2), %%cx\n\t" \
|
|
|
|
"1:\n\t" \
|
|
|
|
"shrl %%cl, %%eax\n\t" \
|
|
|
|
"movb %%ch, %%cl\n\t" \
|
|
|
|
"movw " ASMSYM("sqrtable") "(,%%eax,2), %%ax\n\t" \
|
|
|
|
"shrl %%cl, %%eax" \
|
|
|
|
: "=a" (__r) : "a" (__a) : "ebx", "ecx", "cc"); \
|
|
|
|
__r; })
|
|
|
|
|
|
|
|
// edx is blown by this code somehow?!
|
|
|
|
#define msqrtasm(c) \
|
|
|
|
({ int32_t __r, __c=(c); \
|
|
|
|
__asm__ __volatile__ ( \
|
|
|
|
"movl $0x40000000, %%eax\n\t" \
|
|
|
|
"movl $0x20000000, %%ebx\n\t" \
|
|
|
|
"0:\n\t" \
|
|
|
|
"cmpl %%eax, %%ecx\n\t" \
|
|
|
|
"jl 1f\n\t" \
|
|
|
|
"subl %%eax, %%ecx\n\t" \
|
|
|
|
"leal (%%eax,%%ebx,4), %%eax\n\t" \
|
|
|
|
"1:\n\t" \
|
|
|
|
"subl %%ebx, %%eax\n\t" \
|
|
|
|
"shrl $1, %%eax\n\t" \
|
|
|
|
"shrl $2, %%ebx\n\t" \
|
|
|
|
"jnz 0b\n\t" \
|
|
|
|
"cmpl %%eax, %%ecx\n\t" \
|
|
|
|
"sbbl $-1, %%eax\n\t" \
|
|
|
|
"shrl $1, %%eax" \
|
|
|
|
: "=a" (__r) : "c" (__c) : "edx","ebx", "cc"); \
|
|
|
|
__r; })
|
|
|
|
|
|
|
|
#define getclipmask(a,b,c,d) \
|
|
|
|
({ int32_t __a=(a), __b=(b), __c=(c), __d=(d); \
|
|
|
|
__asm__ __volatile__ ("sarl $31, %%eax; addl %%ebx, %%ebx; adcl %%eax, %%eax; " \
|
|
|
|
"addl %%ecx, %%ecx; adcl %%eax, %%eax; addl %%edx, %%edx; " \
|
|
|
|
"adcl %%eax, %%eax; movl %%eax, %%ebx; shl $4, %%ebx; " \
|
|
|
|
"orb $0xf0, %%al; xorl %%ebx, %%eax" \
|
|
|
|
: "=a" (__a), "=b" (__b), "=c" (__c), "=d" (__d) \
|
|
|
|
: "a" (__a), "b" (__b), "c" (__c), "d" (__d) : "cc"); \
|
|
|
|
__a; })
|
|
|
|
|
|
|
|
|
|
|
|
#define getkensmessagecrc(b) \
|
|
|
|
({ int32_t __a, __b=(b); \
|
|
|
|
__asm__ __volatile__ ( \
|
|
|
|
"xorl %%eax, %%eax\n\t" \
|
|
|
|
"movl $32, %%ecx\n\t" \
|
|
|
|
"0:\n\t" \
|
|
|
|
"movl -4(%%ebx,%%ecx,4), %%edx\n\t" \
|
|
|
|
"rorl %%cl, %%edx\n\t" \
|
|
|
|
"adcl %%edx, %%eax\n\t" \
|
|
|
|
"bswapl %%eax\n\t" \
|
|
|
|
"loop 0b" \
|
|
|
|
: "=a" (__a) : "b" (__b) : "ecx", "edx" \
|
|
|
|
__a; })
|
|
|
|
|
|
|
|
#else // __GNUC__ && __i386__
|
|
|
|
|
|
|
|
static inline int32_t nsqrtasm(uint32_t a)
|
|
|
|
{
|
|
|
|
// JBF 20030901: This was a damn lot simpler to reverse engineer than
|
|
|
|
// msqrtasm was. Really, it was just like simplifying an algebra equation.
|
|
|
|
uint16_t c;
|
|
|
|
|
|
|
|
if (a & 0xff000000) // test eax, 0xff000000 / jnz short over24
|
|
|
|
{
|
|
|
|
c = shlookup[(a >> 24) + 4096]; // mov ebx, eax
|
|
|
|
// over24: shr ebx, 24
|
|
|
|
// mov cx, word ptr shlookup[ebx*2+8192]
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
c = shlookup[a >> 12]; // mov ebx, eax
|
|
|
|
// shr ebx, 12
|
|
|
|
// mov cx, word ptr shlookup[ebx*2]
|
|
|
|
// jmp short under24
|
|
|
|
}
|
|
|
|
a >>= c&0xff; // under24: shr eax, cl
|
|
|
|
a = (a&0xffff0000)|(sqrtable[a]); // mov ax, word ptr sqrtable[eax*2]
|
|
|
|
a >>= ((c&0xff00) >> 8); // mov cl, ch
|
|
|
|
// shr eax, cl
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int32_t msqrtasm(uint32_t c)
|
|
|
|
{
|
|
|
|
uint32_t a, b;
|
|
|
|
|
|
|
|
a = 0x40000000l; // mov eax, 0x40000000
|
|
|
|
b = 0x20000000l; // mov ebx, 0x20000000
|
|
|
|
do // begit:
|
|
|
|
{
|
|
|
|
if (c >= a) // cmp ecx, eax / jl skip
|
|
|
|
{
|
|
|
|
c -= a; // sub ecx, eax
|
|
|
|
a += b*4; // lea eax, [eax+ebx*4]
|
|
|
|
} // skip:
|
|
|
|
a -= b; // sub eax, ebx
|
|
|
|
a >>= 1; // shr eax, 1
|
|
|
|
b >>= 2; // shr ebx, 2
|
|
|
|
} while (b); // jnz begit
|
|
|
|
if (c >= a) // cmp ecx, eax
|
|
|
|
a++; // sbb eax, -1
|
|
|
|
a >>= 1; // shr eax, 1
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int32_t getclipmask(int32_t a, int32_t b, int32_t c, int32_t d)
|
|
|
|
{
|
|
|
|
// Ken did this
|
|
|
|
d = ((a<0)<<3) + ((b<0)<<2) + ((c<0)<<1) + (d<0);
|
2016-06-21 00:34:41 +00:00
|
|
|
return (((d<<4)^0xf0)|d);
|
2016-06-21 00:33:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
inline int32_t getkensmessagecrc(int32_t b)
|
|
|
|
{
|
|
|
|
UNREFERENCED_PARAMETER(b);
|
|
|
|
return 0x56c764d4l;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2009-01-10 07:38:50 +00:00
|
|
|
extern int16_t thesector[MAXWALLSB], thewall[MAXWALLSB];
|
|
|
|
extern int16_t bunchfirst[MAXWALLSB], bunchlast[MAXWALLSB];
|
|
|
|
extern int16_t maskwall[MAXWALLSB], maskwallcnt;
|
2016-06-21 00:33:58 +00:00
|
|
|
extern uspritetype *tspriteptr[MAXSPRITESONSCREEN + 1];
|
2009-01-10 07:38:50 +00:00
|
|
|
extern int32_t xdimen, xdimenrecip, halfxdimen, xdimenscale, xdimscale, ydimen;
|
2014-11-28 08:14:00 +00:00
|
|
|
extern float fxdimen;
|
2008-12-03 11:07:01 +00:00
|
|
|
extern intptr_t frameoffset;
|
2009-01-10 07:38:50 +00:00
|
|
|
extern int32_t globalposx, globalposy, globalposz, globalhoriz;
|
2014-10-25 03:32:26 +00:00
|
|
|
extern float fglobalposx, fglobalposy, fglobalposz;
|
2009-01-10 07:38:50 +00:00
|
|
|
extern int16_t globalang, globalcursectnum;
|
|
|
|
extern int32_t globalpal, cosglobalang, singlobalang;
|
|
|
|
extern int32_t cosviewingrangeglobalang, sinviewingrangeglobalang;
|
2013-05-15 02:19:14 +00:00
|
|
|
extern int32_t globalhisibility, globalpisibility, globalcisibility;
|
|
|
|
extern int32_t globvis, globalvisibility;
|
2009-01-10 07:38:50 +00:00
|
|
|
extern int32_t xyaspect;
|
|
|
|
extern int32_t globalshade;
|
|
|
|
extern int16_t globalpicnum;
|
2012-11-15 14:28:11 +00:00
|
|
|
|
2009-01-10 07:38:50 +00:00
|
|
|
extern int32_t globalorientation;
|
2008-12-02 10:44:39 +00:00
|
|
|
|
2011-10-02 22:38:09 +00:00
|
|
|
extern int16_t editstatus;
|
|
|
|
|
2009-01-10 07:38:50 +00:00
|
|
|
extern int16_t searchit;
|
|
|
|
extern int32_t searchx, searchy;
|
|
|
|
extern int16_t searchsector, searchwall, searchstat;
|
2011-03-17 23:37:38 +00:00
|
|
|
extern int16_t searchbottomwall, searchisbottom;
|
2008-12-02 10:44:39 +00:00
|
|
|
|
|
|
|
extern char inpreparemirror;
|
|
|
|
|
|
|
|
extern char picsiz[MAXTILES];
|
2014-04-21 17:00:54 +00:00
|
|
|
extern int16_t sectorborder[256];
|
2009-01-10 07:38:50 +00:00
|
|
|
extern int32_t qsetmode;
|
|
|
|
extern int32_t hitallsprites;
|
2008-12-02 10:44:39 +00:00
|
|
|
|
2009-01-10 07:38:50 +00:00
|
|
|
extern int32_t xb1[MAXWALLSB];
|
|
|
|
extern int32_t rx1[MAXWALLSB], ry1[MAXWALLSB];
|
2014-09-30 04:14:21 +00:00
|
|
|
extern int16_t bunchp2[MAXWALLSB];
|
2012-01-26 21:58:08 +00:00
|
|
|
extern int16_t numscans, numbunches;
|
2016-06-21 00:33:30 +00:00
|
|
|
extern int32_t rxi[8], ryi[8];
|
2008-12-02 10:44:39 +00:00
|
|
|
|
|
|
|
#ifdef USE_OPENGL
|
2012-12-16 19:18:18 +00:00
|
|
|
|
|
|
|
// For GL_EXP2 fog:
|
2014-09-30 04:06:32 +00:00
|
|
|
#define FOGSCALE 0.0000768f
|
2012-12-16 19:18:18 +00:00
|
|
|
|
2013-05-15 02:19:14 +00:00
|
|
|
void calc_and_apply_fog(int32_t tile, int32_t shade, int32_t vis, int32_t pal);
|
|
|
|
void calc_and_apply_fog_factor(int32_t tile, int32_t shade, int32_t vis, int32_t pal, float factor);
|
2008-12-02 10:44:39 +00:00
|
|
|
#endif
|
|
|
|
|
2016-06-21 00:34:18 +00:00
|
|
|
extern void get_wallspr_points(uspritetype const * const spr, int32_t *x1, int32_t *x2,
|
2016-06-21 00:33:30 +00:00
|
|
|
int32_t *y1, int32_t *y2);
|
2016-06-21 00:34:18 +00:00
|
|
|
extern void get_floorspr_points(uspritetype const * const spr, int32_t px, int32_t py,
|
2016-06-21 00:33:30 +00:00
|
|
|
int32_t *x1, int32_t *x2, int32_t *x3, int32_t *x4,
|
|
|
|
int32_t *y1, int32_t *y2, int32_t *y3, int32_t *y4);
|
|
|
|
|
|
|
|
|
2010-06-07 09:03:16 +00:00
|
|
|
// int32_t wallmost(int16_t *mostbuf, int32_t w, int32_t sectnum, char dastat);
|
2009-01-10 07:38:50 +00:00
|
|
|
int32_t wallfront(int32_t l1, int32_t l2);
|
2013-02-10 16:24:11 +00:00
|
|
|
|
|
|
|
void set_globalang(int16_t ang);
|
2008-12-02 10:44:39 +00:00
|
|
|
|
2015-01-11 04:55:07 +00:00
|
|
|
#ifdef DEBUGGINGAIDS
|
|
|
|
int32_t animateoffs(int const tilenum, int fakevar);
|
2012-11-17 19:46:28 +00:00
|
|
|
#define DO_TILE_ANIM(Picnum, Fakevar) do { \
|
|
|
|
if (picanm[Picnum].sf&PICANM_ANIMTYPE_MASK) Picnum += animateoffs(Picnum, Fakevar); \
|
2012-11-15 21:09:53 +00:00
|
|
|
} while (0)
|
2015-01-11 04:55:07 +00:00
|
|
|
#else
|
|
|
|
int32_t animateoffs(int const tilenum);
|
|
|
|
#define DO_TILE_ANIM(Picnum, Fakevar) do { \
|
|
|
|
if (picanm[Picnum].sf&PICANM_ANIMTYPE_MASK) Picnum += animateoffs(Picnum); \
|
|
|
|
} while (0)
|
|
|
|
#endif
|
2012-11-15 21:09:53 +00:00
|
|
|
|
2016-06-21 00:33:58 +00:00
|
|
|
FORCE_INLINE int32_t bad_tspr(const uspritetype *tspr)
|
2013-04-29 19:24:19 +00:00
|
|
|
{
|
2013-05-01 17:42:07 +00:00
|
|
|
// NOTE: tspr->owner >= MAXSPRITES (could be model) has to be handled by
|
|
|
|
// caller.
|
|
|
|
return (tspr->owner < 0 || (unsigned)tspr->picnum >= MAXTILES);
|
2013-04-29 19:24:19 +00:00
|
|
|
}
|
|
|
|
|
2013-05-15 02:19:14 +00:00
|
|
|
//
|
|
|
|
// getpalookup (internal)
|
|
|
|
//
|
2015-01-11 04:55:07 +00:00
|
|
|
FORCE_INLINE int32_t getpalookup(int32_t davis, int32_t dashade)
|
2013-05-15 02:19:14 +00:00
|
|
|
{
|
2016-06-21 00:34:41 +00:00
|
|
|
return min(max(dashade + (davis >> 8), 0), numshades - 1);
|
2013-05-15 02:19:14 +00:00
|
|
|
}
|
|
|
|
|
2015-01-11 04:55:07 +00:00
|
|
|
FORCE_INLINE int32_t getpalookupsh(int32_t davis) { return getpalookup(davis, globalshade) << 8; }
|
2013-05-15 02:19:14 +00:00
|
|
|
|
2012-08-19 12:51:04 +00:00
|
|
|
void dorotspr_handle_bit2(int32_t *sx, int32_t *sy, int32_t *z, int32_t dastat,
|
|
|
|
int32_t cx1_plus_cx2, int32_t cy1_plus_cy2,
|
|
|
|
int32_t *ret_ouryxaspect, int32_t *ret_ourxyaspect);
|
2012-08-16 21:48:50 +00:00
|
|
|
|
2011-05-22 21:52:22 +00:00
|
|
|
////// yax'y stuff //////
|
|
|
|
#ifdef USE_OPENGL
|
|
|
|
extern void polymost_scansector(int32_t sectnum);
|
|
|
|
#endif
|
|
|
|
int32_t engine_addtsprite(int16_t z, int16_t sectnum);
|
2011-09-04 19:44:07 +00:00
|
|
|
#ifdef YAX_ENABLE
|
2011-09-15 17:02:12 +00:00
|
|
|
extern int32_t g_nodraw, scansector_retfast;
|
|
|
|
extern int32_t yax_globallev, yax_globalbunch;
|
Support for drawing 'island sectors' for TROR/classic (and with limited
functionality, Polymost).
The new feature can be enabled/disabled with the 'r_tror_nomaskpass' cvar.
The basic idea is that when drawing lower or upper levels, a first pass
is performed that ignores all red walls for which the TROR nextwall link
'towards' the viewer arrives at a red wall. Thus, in the worst case, there
can be up to twice as many rendering passes now (when it is discovered that
the no-mask-pass isn't different that what would be drawn with the ordinary
one, the latter is skipped, since we've already drawn all needed geometry).
Hovever, this kind of multi-pass splitting is only suitable for simple scenes,
like the upper subway in the TROR test map. In particular, multiple islands
shouldn't 'see' each other.
Two issues are worth mentioning: first, care needs to be taken for translucent
ceilings or floors, since drawing them twice isn't the same as drawing them
once. This is done for classic, but not for Polymost. Second, sprites (which
are always drawn _after_ the geometry for a given pass) are still clipped to
the geometry of the ordinary pass, resulting in their disappearance from
certain angles.
--
Additionaly, a change made it into this commit that fixes redundant collection
of sprites in TROR:classic/Polymost.
git-svn-id: https://svn.eduke32.com/eduke32@2024 1a8010ca-5511-0410-912e-c29ae57300e0
2011-09-15 17:04:14 +00:00
|
|
|
extern int32_t yax_globalcf, yax_nomaskpass, yax_nomaskdidit;
|
2011-09-04 19:44:07 +00:00
|
|
|
extern uint8_t haveymost[YAX_MAXBUNCHES>>3];
|
Support for drawing 'island sectors' for TROR/classic (and with limited
functionality, Polymost).
The new feature can be enabled/disabled with the 'r_tror_nomaskpass' cvar.
The basic idea is that when drawing lower or upper levels, a first pass
is performed that ignores all red walls for which the TROR nextwall link
'towards' the viewer arrives at a red wall. Thus, in the worst case, there
can be up to twice as many rendering passes now (when it is discovered that
the no-mask-pass isn't different that what would be drawn with the ordinary
one, the latter is skipped, since we've already drawn all needed geometry).
Hovever, this kind of multi-pass splitting is only suitable for simple scenes,
like the upper subway in the TROR test map. In particular, multiple islands
shouldn't 'see' each other.
Two issues are worth mentioning: first, care needs to be taken for translucent
ceilings or floors, since drawing them twice isn't the same as drawing them
once. This is done for classic, but not for Polymost. Second, sprites (which
are always drawn _after_ the geometry for a given pass) are still clipped to
the geometry of the ordinary pass, resulting in their disappearance from
certain angles.
--
Additionaly, a change made it into this commit that fixes redundant collection
of sprites in TROR:classic/Polymost.
git-svn-id: https://svn.eduke32.com/eduke32@2024 1a8010ca-5511-0410-912e-c29ae57300e0
2011-09-15 17:04:14 +00:00
|
|
|
extern uint8_t yax_gotsector[MAXSECTORS>>3];
|
|
|
|
|
2015-01-11 04:55:07 +00:00
|
|
|
FORCE_INLINE int32_t yax_isislandwall(int32_t line, int32_t cf) { return (yax_vnextsec(line, cf) >= 0); }
|
2011-09-04 19:44:07 +00:00
|
|
|
#endif
|
2011-05-22 21:52:22 +00:00
|
|
|
|
|
|
|
#ifdef YAX_DEBUG
|
|
|
|
extern char m32_debugstr[64][128];
|
|
|
|
extern int32_t m32_numdebuglines;
|
|
|
|
# define yaxdebug(fmt, ...) do { if (m32_numdebuglines<64) Bsnprintf(m32_debugstr[m32_numdebuglines++], 128, fmt, ##__VA_ARGS__); } while (0)
|
|
|
|
# define yaxprintf(fmt, ...) do { initprintf(fmt, ##__VA_ARGS__); } while (0)
|
|
|
|
#else
|
|
|
|
# define yaxdebug(fmt, ...)
|
|
|
|
# define yaxprintf(fmt, ...)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2008-12-02 10:44:39 +00:00
|
|
|
|
2009-07-09 02:29:48 +00:00
|
|
|
#if defined(_MSC_VER) && !defined(NOASM)
|
2008-12-02 10:44:39 +00:00
|
|
|
|
2009-01-10 07:38:50 +00:00
|
|
|
static inline void setgotpic(int32_t a)
|
2008-12-02 10:44:39 +00:00
|
|
|
{
|
|
|
|
_asm {
|
|
|
|
push ebx
|
|
|
|
mov eax, a
|
|
|
|
mov ebx, eax
|
|
|
|
cmp byte ptr walock[eax], 200
|
|
|
|
jae skipit
|
|
|
|
mov byte ptr walock[eax], 199
|
|
|
|
skipit:
|
|
|
|
shr eax, 3
|
|
|
|
and ebx, 7
|
|
|
|
mov dl, byte ptr gotpic[eax]
|
|
|
|
mov bl, byte ptr pow2char[ebx]
|
|
|
|
or dl, bl
|
|
|
|
mov byte ptr gotpic[eax], dl
|
|
|
|
pop ebx
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#elif defined(__GNUC__) && defined(__i386__) && !defined(NOASM) // _MSC_VER
|
|
|
|
|
|
|
|
#define setgotpic(a) \
|
2009-01-10 07:38:50 +00:00
|
|
|
({ int32_t __a=(a); \
|
2008-12-02 10:44:39 +00:00
|
|
|
__asm__ __volatile__ ( \
|
|
|
|
"movl %%eax, %%ebx\n\t" \
|
2014-02-10 11:00:07 +00:00
|
|
|
"cmpb $200, " ASMSYM("walock") "(%%eax)\n\t" \
|
2008-12-02 10:44:39 +00:00
|
|
|
"jae 0f\n\t" \
|
2014-02-10 11:00:07 +00:00
|
|
|
"movb $199, " ASMSYM("walock") "(%%eax)\n\t" \
|
2008-12-02 10:44:39 +00:00
|
|
|
"0:\n\t" \
|
|
|
|
"shrl $3, %%eax\n\t" \
|
|
|
|
"andl $7, %%ebx\n\t" \
|
2014-02-10 11:00:07 +00:00
|
|
|
"movb " ASMSYM("gotpic") "(%%eax), %%dl\n\t" \
|
|
|
|
"movb " ASMSYM("pow2char") "(%%ebx), %%bl\n\t" \
|
2008-12-02 10:44:39 +00:00
|
|
|
"orb %%bl, %%dl\n\t" \
|
2014-02-10 11:00:07 +00:00
|
|
|
"movb %%dl, " ASMSYM("gotpic") "(%%eax)" \
|
2008-12-02 10:44:39 +00:00
|
|
|
: "=a" (__a) : "a" (__a) \
|
|
|
|
: "ebx", "edx", "memory", "cc"); \
|
|
|
|
__a; })
|
|
|
|
|
|
|
|
#else // __GNUC__ && __i386__
|
|
|
|
|
2015-01-11 04:55:07 +00:00
|
|
|
FORCE_INLINE void setgotpic(int32_t tilenume)
|
2008-12-02 10:44:39 +00:00
|
|
|
{
|
|
|
|
if (walock[tilenume] < 200) walock[tilenume] = 199;
|
|
|
|
gotpic[tilenume>>3] |= pow2char[tilenume&7];
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2013-08-04 20:37:45 +00:00
|
|
|
// Get properties of parallaxed sky to draw.
|
2016-10-14 07:40:50 +00:00
|
|
|
// Returns: pointer to tile offset array. Sets-by-pointer the other three.
|
|
|
|
FORCE_INLINE const int8_t *getpsky(int32_t picnum, int32_t *dapyscale, int32_t *dapskybits, int32_t *dapyoffs)
|
2013-08-04 20:37:45 +00:00
|
|
|
{
|
2015-05-27 08:47:34 +00:00
|
|
|
psky_t const * const psky = &multipsky[getpskyidx(picnum)];
|
2013-08-04 20:37:45 +00:00
|
|
|
|
2013-08-04 20:37:49 +00:00
|
|
|
if (dapskybits)
|
2015-05-27 08:47:34 +00:00
|
|
|
*dapskybits = (pskybits_override == -1 ? psky->lognumtiles : pskybits_override);
|
2013-08-04 20:37:45 +00:00
|
|
|
if (dapyscale)
|
2015-05-27 08:47:34 +00:00
|
|
|
*dapyscale = (parallaxyscale_override == 0 ? psky->horizfrac : parallaxyscale_override);
|
2016-10-14 07:40:50 +00:00
|
|
|
if (dapyoffs)
|
|
|
|
*dapyoffs = psky->yoffs + parallaxyoffs_override;
|
Clean up parallaxed sky functionality, part 2.
- Rename sky_t members: yscale -> horizfrac, bits -> lognumtiles.
- Add default sky (8 tiles, horizfrac=32768 (i.e. 1/2 the scene horiz), offsets
all zero) and CLOUDYOCEAN sky (8 tiles, horizfrac=65536, offsets all zero)
to multipsky[].
- Get rid of "psky_t g_psky", merely maintaining a g_pskyidx instead. Set it up
at map load time so as to keep the behavior of the legacy per-map psky:
the last sector index with a matching psky ceiling wins.
- In mapstate_t, save g_pskyidx too, not (former) pskybits and pskyoffs[].
- Make on-map-load global psky setup consistent for the game and editor by
factoring it out into common.c: G_SetupGlobalPsky().
- Remove a couple of useless initializations, add some static assertions.
This commit is more likely to introduce subtle differences in behavior.
Specifically, getpsky() now always returns the default sky properties instead of
the global sky ones (but with all-zero offsets) when no match for a suiting
multi-psky is found. This is only likely to affect the yscale/horizfrac of
non-multi-pskies when a global non-default multi-psky has been set up.
Bump BYTEVERSION again.
git-svn-id: https://svn.eduke32.com/eduke32@3976 1a8010ca-5511-0410-912e-c29ae57300e0
2013-08-04 20:37:48 +00:00
|
|
|
|
2015-05-27 08:47:34 +00:00
|
|
|
return psky->tileofs;
|
2013-08-04 20:37:45 +00:00
|
|
|
}
|
2014-10-25 03:32:26 +00:00
|
|
|
|
2015-01-11 04:55:07 +00:00
|
|
|
FORCE_INLINE void set_globalpos(int32_t const x, int32_t const y, int32_t const z)
|
2014-10-25 03:32:26 +00:00
|
|
|
{
|
|
|
|
globalposx = x, fglobalposx = (float)x;
|
|
|
|
globalposy = y, fglobalposy = (float)y;
|
|
|
|
globalposz = z, fglobalposz = (float)z;
|
|
|
|
}
|
|
|
|
|
2014-11-28 08:14:00 +00:00
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2008-12-02 10:44:39 +00:00
|
|
|
#endif /* ENGINE_PRIV_H */
|