mirror of
https://github.com/ZDoom/raze-gles.git
synced 2025-01-12 11:10:39 +00:00
Classic-noasm: fix drawing of walls and maskwalls with non-pow2 y size tiles.
Related to that, it looks like out-of-bounds accesses when drawing such walls/ maskwalls or *sprites* are fixed, too. Sprites still show a stray lines on some occasions, but Valgrind doesn't complain then. git-svn-id: https://svn.eduke32.com/eduke32@2805 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
51331e11a0
commit
5a96b4e572
2 changed files with 114 additions and 26 deletions
|
@ -88,6 +88,22 @@ void slopevlin(intptr_t p, int32_t i, intptr_t slopaloffs, int32_t cnt, int32_t
|
||||||
|
|
||||||
///// Wall,face sprite/wall sprite vertical line functions /////
|
///// Wall,face sprite/wall sprite vertical line functions /////
|
||||||
|
|
||||||
|
|
||||||
|
extern int32_t globaltilesizy;
|
||||||
|
|
||||||
|
static inline uint32_t ourmulscale32(uint32_t a, uint32_t b)
|
||||||
|
{
|
||||||
|
return ((uint64_t)a*b)>>32;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int32_t getpix(int32_t logy, const char *buf, uint32_t vplc)
|
||||||
|
{
|
||||||
|
if (logy != 0)
|
||||||
|
return buf[vplc>>logy];
|
||||||
|
else
|
||||||
|
return buf[ourmulscale32(vplc,globaltilesizy)];
|
||||||
|
}
|
||||||
|
|
||||||
void setupvlineasm(int32_t neglogy) { glogy = neglogy; }
|
void setupvlineasm(int32_t neglogy) { glogy = neglogy; }
|
||||||
// cnt+1 loop iterations!
|
// cnt+1 loop iterations!
|
||||||
int32_t vlineasm1(int32_t vinc, intptr_t paloffs, int32_t cnt, uint32_t vplc, intptr_t bufplc, intptr_t p)
|
int32_t vlineasm1(int32_t vinc, intptr_t paloffs, int32_t cnt, uint32_t vplc, intptr_t bufplc, intptr_t p)
|
||||||
|
@ -101,7 +117,11 @@ int32_t vlineasm1(int32_t vinc, intptr_t paloffs, int32_t cnt, uint32_t vplc, in
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
if (logy != 0)
|
||||||
*pp = pal[buf[vplc>>logy]];
|
*pp = pal[buf[vplc>>logy]];
|
||||||
|
else
|
||||||
|
*pp = pal[buf[ourmulscale32(vplc,globaltilesizy)]];
|
||||||
|
|
||||||
pp += ourbpl;
|
pp += ourbpl;
|
||||||
vplc += vinc;
|
vplc += vinc;
|
||||||
}
|
}
|
||||||
|
@ -145,7 +165,8 @@ void vlineasm4(int32_t cnt, char *p)
|
||||||
{
|
{
|
||||||
for (i=0; i<4; i++)
|
for (i=0; i<4; i++)
|
||||||
{
|
{
|
||||||
ch = buf[i][vplc[i]>>logy]; p[i] = pal[i][ch];
|
ch = getpix(logy, buf[i], vplc[i]);
|
||||||
|
p[i] = pal[i][ch];
|
||||||
vplc[i] += vinc[i];
|
vplc[i] += vinc[i];
|
||||||
}
|
}
|
||||||
p += ourbpl;
|
p += ourbpl;
|
||||||
|
@ -170,7 +191,8 @@ int32_t mvlineasm1(int32_t vinc, intptr_t paloffs, int32_t cnt, uint32_t vplc, i
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
ch = buf[vplc>>logy]; if (ch != 255) *pp = pal[ch];
|
ch = getpix(logy, buf, vplc);
|
||||||
|
if (ch != 255) *pp = pal[ch];
|
||||||
pp += ourbpl;
|
pp += ourbpl;
|
||||||
vplc += vinc;
|
vplc += vinc;
|
||||||
}
|
}
|
||||||
|
@ -196,7 +218,8 @@ void mvlineasm4(int32_t cnt, char *p)
|
||||||
{
|
{
|
||||||
for (i=0; i<4; i++)
|
for (i=0; i<4; i++)
|
||||||
{
|
{
|
||||||
ch = buf[i][vplc[i]>>logy]; if (ch != 255) p[i] = pal[i][ch];
|
ch = getpix(logy, buf[i], vplc[i]);
|
||||||
|
if (ch != 255) p[i] = pal[i][ch];
|
||||||
vplc[i] += vinc[i];
|
vplc[i] += vinc[i];
|
||||||
}
|
}
|
||||||
p += ourbpl;
|
p += ourbpl;
|
||||||
|
@ -225,7 +248,7 @@ int32_t tvlineasm1(int32_t vinc, intptr_t paloffs, int32_t cnt, uint32_t vplc, i
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
ch = buf[vplc>>logy];
|
ch = getpix(logy, buf, vplc);
|
||||||
if (ch != 255) *pp = trans[(*pp)|(pal[ch]<<8)];
|
if (ch != 255) *pp = trans[(*pp)|(pal[ch]<<8)];
|
||||||
pp += ourbpl;
|
pp += ourbpl;
|
||||||
vplc += vinc;
|
vplc += vinc;
|
||||||
|
@ -236,7 +259,7 @@ int32_t tvlineasm1(int32_t vinc, intptr_t paloffs, int32_t cnt, uint32_t vplc, i
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
ch = buf[vplc>>logy];
|
ch = getpix(logy, buf, vplc);
|
||||||
if (ch != 255) *pp = trans[((*pp)<<8)|pal[ch]];
|
if (ch != 255) *pp = trans[((*pp)<<8)|pal[ch]];
|
||||||
pp += ourbpl;
|
pp += ourbpl;
|
||||||
vplc += vinc;
|
vplc += vinc;
|
||||||
|
@ -274,11 +297,11 @@ void tvlineasm2(uint32_t vplc2, int32_t vinc1, intptr_t bufplc1, intptr_t bufplc
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
ch = buf1[vplc1>>logy];
|
ch = getpix(logy, buf1, vplc1);
|
||||||
if (ch != 255) pp[0] = gtrans[pp[0]|(gpal[ch]<<8)];
|
if (ch != 255) pp[0] = gtrans[pp[0]|(gpal[ch]<<8)];
|
||||||
vplc1 += vinc1;
|
vplc1 += vinc1;
|
||||||
|
|
||||||
ch = buf2[vplc2>>logy];
|
ch = getpix(logy, buf2, vplc2);
|
||||||
if (ch != 255) pp[1] = gtrans[pp[1]|(gpal2[ch]<<8)];
|
if (ch != 255) pp[1] = gtrans[pp[1]|(gpal2[ch]<<8)];
|
||||||
vplc2 += vinc2;
|
vplc2 += vinc2;
|
||||||
|
|
||||||
|
@ -290,11 +313,11 @@ void tvlineasm2(uint32_t vplc2, int32_t vinc1, intptr_t bufplc1, intptr_t bufplc
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
ch = buf1[vplc1>>logy];
|
ch = getpix(logy, buf1, vplc1);
|
||||||
if (ch != 255) pp[0] = gtrans[(pp[0]<<8)|gpal[ch]];
|
if (ch != 255) pp[0] = gtrans[(pp[0]<<8)|gpal[ch]];
|
||||||
vplc1 += vinc1;
|
vplc1 += vinc1;
|
||||||
|
|
||||||
ch = buf2[vplc2>>logy];
|
ch = getpix(logy, buf2, vplc2);
|
||||||
if (ch != 255) pp[1] = gtrans[(pp[1]<<8)|gpal2[ch]];
|
if (ch != 255) pp[1] = gtrans[(pp[1]<<8)|gpal2[ch]];
|
||||||
vplc2 += vinc2;
|
vplc2 += vinc2;
|
||||||
|
|
||||||
|
|
|
@ -2250,6 +2250,8 @@ static int32_t globalzd, globalyscale;
|
||||||
static int32_t globalxspan, globalyspan, globalispow2=1; // true if texture has power-of-two x and y size
|
static int32_t globalxspan, globalyspan, globalispow2=1; // true if texture has power-of-two x and y size
|
||||||
static intptr_t globalbufplc;
|
static intptr_t globalbufplc;
|
||||||
|
|
||||||
|
int32_t globaltilesizy;
|
||||||
|
|
||||||
int32_t globalx1, globaly2, globalx3, globaly3;
|
int32_t globalx1, globaly2, globalx3, globaly3;
|
||||||
static int32_t globaly1, globalx2, globalzx;
|
static int32_t globaly1, globalx2, globalzx;
|
||||||
static int32_t globalx, globaly, globalz;
|
static int32_t globalx, globaly, globalz;
|
||||||
|
@ -4501,15 +4503,42 @@ static void setup_globals_wall1(const walltype *wal, int32_t dapicnum)
|
||||||
|
|
||||||
static void setup_globals_wall2(const walltype *wal, uint8_t secvisibility, int32_t topzref, int32_t botzref)
|
static void setup_globals_wall2(const walltype *wal, uint8_t secvisibility, int32_t topzref, int32_t botzref)
|
||||||
{
|
{
|
||||||
|
const int32_t logtilesizy = (picsiz[globalpicnum]>>4);
|
||||||
|
const int32_t tsizy = tilesizy[globalpicnum];
|
||||||
|
|
||||||
|
if (tsizy==0)
|
||||||
|
{
|
||||||
|
globalshiftval = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
globvis = globalvisibility;
|
globvis = globalvisibility;
|
||||||
if (secvisibility != 0)
|
if (secvisibility != 0)
|
||||||
globvis = mulscale4(globvis, (int32_t)((uint8_t)(secvisibility+16)));
|
globvis = mulscale4(globvis, (int32_t)((uint8_t)(secvisibility+16)));
|
||||||
|
|
||||||
globalshiftval = (picsiz[globalpicnum]>>4);
|
globalshiftval = logtilesizy;
|
||||||
if (pow2long[globalshiftval] != tilesizy[globalpicnum]) globalshiftval++;
|
#if !defined ENGINE_USING_A_C
|
||||||
globalshiftval = 32-globalshiftval;
|
// before proper non-power-of-two tilesizy drawing
|
||||||
|
if (pow2long[logtilesizy] != tilesizy[globalpicnum])
|
||||||
|
globalshiftval++;
|
||||||
|
|
||||||
globalyscale = (wal->yrepeat<<(globalshiftval-19));
|
if (1)
|
||||||
|
#else
|
||||||
|
// non power-of-two y size textures!
|
||||||
|
if (pow2long[logtilesizy] == tsizy)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
// globalshiftval==13 --> globalshiftval==19
|
||||||
|
// ==> upper texture y size limit *here* = 8192
|
||||||
|
globalshiftval = 32-globalshiftval;
|
||||||
|
globalyscale = wal->yrepeat<<(globalshiftval-19);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
globaltilesizy = tsizy;
|
||||||
|
globalyscale = divscale13(wal->yrepeat, tsizy);
|
||||||
|
globalshiftval = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if ((globalorientation&4) == 0)
|
if ((globalorientation&4) == 0)
|
||||||
globalzd = (((int64_t)(globalposz-topzref)*globalyscale)<<8);
|
globalzd = (((int64_t)(globalposz-topzref)*globalyscale)<<8);
|
||||||
|
@ -4789,8 +4818,11 @@ static void drawalls(int32_t bunch)
|
||||||
setup_globals_wall1(wal, wal->picnum);
|
setup_globals_wall1(wal, wal->picnum);
|
||||||
setup_globals_wall2(wal, sec->visibility, nextsec->ceilingz, sec->ceilingz);
|
setup_globals_wall2(wal, sec->visibility, nextsec->ceilingz, sec->ceilingz);
|
||||||
|
|
||||||
|
if (globalshiftval >= 0)
|
||||||
|
{
|
||||||
if (gotswall == 0) { gotswall = 1; prepwall(z,wal); }
|
if (gotswall == 0) { gotswall = 1; prepwall(z,wal); }
|
||||||
wallscan(x1,x2,uplc,dwall,swall,lwall);
|
wallscan(x1,x2,uplc,dwall,swall,lwall);
|
||||||
|
}
|
||||||
|
|
||||||
if ((cz[2] >= cz[0]) && (cz[3] >= cz[1]))
|
if ((cz[2] >= cz[0]) && (cz[3] >= cz[1]))
|
||||||
{
|
{
|
||||||
|
@ -4878,8 +4910,11 @@ static void drawalls(int32_t bunch)
|
||||||
|
|
||||||
setup_globals_wall2(wal, sec->visibility, nextsec->floorz, sec->ceilingz);
|
setup_globals_wall2(wal, sec->visibility, nextsec->floorz, sec->ceilingz);
|
||||||
|
|
||||||
|
if (globalshiftval >= 0)
|
||||||
|
{
|
||||||
if (gotswall == 0) { gotswall = 1; prepwall(z,wal); }
|
if (gotswall == 0) { gotswall = 1; prepwall(z,wal); }
|
||||||
wallscan(x1,x2,uwall,dplc,swall,lwall);
|
wallscan(x1,x2,uwall,dplc,swall,lwall);
|
||||||
|
}
|
||||||
|
|
||||||
if ((fz[2] <= fz[0]) && (fz[3] <= fz[1]))
|
if ((fz[2] <= fz[0]) && (fz[3] <= fz[1]))
|
||||||
{
|
{
|
||||||
|
@ -4959,8 +4994,11 @@ static void drawalls(int32_t bunch)
|
||||||
(nextsectnum >= 0) ? nextsec->ceilingz : sec->ceilingz,
|
(nextsectnum >= 0) ? nextsec->ceilingz : sec->ceilingz,
|
||||||
(nextsectnum >= 0) ? sec->ceilingz : sec->floorz);
|
(nextsectnum >= 0) ? sec->ceilingz : sec->floorz);
|
||||||
|
|
||||||
|
if (globalshiftval >= 0)
|
||||||
|
{
|
||||||
if (gotswall == 0) { gotswall = 1; prepwall(z,wal); }
|
if (gotswall == 0) { gotswall = 1; prepwall(z,wal); }
|
||||||
wallscan(x1,x2,uplc,dplc,swall,lwall);
|
wallscan(x1,x2,uplc,dplc,swall,lwall);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef YAX_ENABLE
|
#ifdef YAX_ENABLE
|
||||||
// TODO: slopes?
|
// TODO: slopes?
|
||||||
|
@ -5315,10 +5353,12 @@ static void drawvox(int32_t dasprx, int32_t daspry, int32_t dasprz, int32_t dasp
|
||||||
enddrawing(); //}}}
|
enddrawing(); //}}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void setup_globals_sprite1(const spritetype *tspr, const sectortype *sec,
|
static void setup_globals_sprite1(const spritetype *tspr, const sectortype *sec,
|
||||||
int32_t yspan, int32_t yoff, int32_t tilenum,
|
int32_t yspan, int32_t yoff, int32_t tilenum,
|
||||||
int32_t cstat, int32_t *z1ptr, int32_t *z2ptr)
|
int32_t cstat, int32_t *z1ptr, int32_t *z2ptr)
|
||||||
{
|
{
|
||||||
|
int32_t logtilesizy, tsizy;
|
||||||
int32_t z1, z2 = tspr->z - ((yoff*tspr->yrepeat)<<2);
|
int32_t z1, z2 = tspr->z - ((yoff*tspr->yrepeat)<<2);
|
||||||
|
|
||||||
if (cstat&128)
|
if (cstat&128)
|
||||||
|
@ -5337,11 +5377,31 @@ static void setup_globals_sprite1(const spritetype *tspr, const sectortype *sec,
|
||||||
globvis = globalvisibility;
|
globvis = globalvisibility;
|
||||||
if (sec->visibility != 0) globvis = mulscale4(globvis,(int32_t)((uint8_t)(sec->visibility+16)));
|
if (sec->visibility != 0) globvis = mulscale4(globvis,(int32_t)((uint8_t)(sec->visibility+16)));
|
||||||
|
|
||||||
globalshiftval = (picsiz[globalpicnum]>>4);
|
logtilesizy = (picsiz[globalpicnum]>>4);
|
||||||
if (pow2long[globalshiftval] != tilesizy[globalpicnum]) globalshiftval++;
|
tsizy = tilesizy[globalpicnum];
|
||||||
globalshiftval = 32-globalshiftval;
|
|
||||||
|
|
||||||
|
globalshiftval = logtilesizy;
|
||||||
|
#if !defined ENGINE_USING_A_C
|
||||||
|
// before proper non-power-of-two tilesizy drawing
|
||||||
|
if (pow2long[logtilesizy] != tilesizy[globalpicnum])
|
||||||
|
globalshiftval++;
|
||||||
|
|
||||||
|
if (1)
|
||||||
|
#else
|
||||||
|
// non power-of-two y size textures!
|
||||||
|
if (pow2long[logtilesizy] == tsizy)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
globalshiftval = 32-globalshiftval;
|
||||||
globalyscale = divscale(512,tspr->yrepeat,globalshiftval-19);
|
globalyscale = divscale(512,tspr->yrepeat,globalshiftval-19);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
globaltilesizy = tsizy;
|
||||||
|
globalyscale = (1<<22)/(tsizy*tspr->yrepeat);
|
||||||
|
globalshiftval = 0;
|
||||||
|
}
|
||||||
|
|
||||||
globalzd = ((int64_t)(globalposz-z1)*globalyscale)<<8;
|
globalzd = ((int64_t)(globalposz-z1)*globalyscale)<<8;
|
||||||
if ((cstat&8) > 0)
|
if ((cstat&8) > 0)
|
||||||
{
|
{
|
||||||
|
@ -6373,13 +6433,18 @@ static void drawmaskwall(int16_t damaskwallcnt)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((globalorientation&128) == 0)
|
if ((globalorientation&128) == 0)
|
||||||
|
{
|
||||||
|
if (globalshiftval >= 0)
|
||||||
maskwallscan(xb1[z],xb2[z],uwall,dwall,swall,lwall);
|
maskwallscan(xb1[z],xb2[z],uwall,dwall,swall,lwall);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (globalorientation&128)
|
if (globalorientation&128)
|
||||||
{
|
{
|
||||||
if (globalorientation&512) settransreverse(); else settransnormal();
|
if (globalorientation&512) settransreverse(); else settransnormal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (globalshiftval >= 0)
|
||||||
transmaskwallscan(xb1[z],xb2[z]);
|
transmaskwallscan(xb1[z],xb2[z]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue