- rerouted all write accesses to tilesiz and picsiz through a function interface.

These will have to do some texture management bookkeeping so directly changing the values is problematic.
This required changing the parameter interface in polymost.cpp because a few places hacked around with the global state to pass parameters to subfunctions.
This commit is contained in:
Christoph Oelckers 2019-10-11 21:04:31 +02:00
parent fdbb27a796
commit 3621aae3f0
22 changed files with 151 additions and 379 deletions

View file

@ -1056,7 +1056,6 @@ set (PCH_SOURCES
common/textures/image.cpp
common/textures/imagetexture.cpp
common/textures/imagehelpers.cpp
common/textures/formats/buildtexture.cpp
common/textures/formats/ddstexture.cpp
common/textures/formats/jpegtexture.cpp
common/textures/formats/pcxtexture.cpp

View file

@ -215,10 +215,9 @@ void credPlaySmk(const char *_pzSMK, const char *_pzWAV, int nWav)
uint32_t nWidth, nHeight;
Smacker_GetFrameSize(hSMK, nWidth, nHeight);
uint8_t palette[768];
uint8_t *pFrame = (uint8_t*)Xmalloc(nWidth*nHeight);
waloff[kSMKTile] = (intptr_t)pFrame;
tilesiz[kSMKTile].y = nWidth;
tilesiz[kSMKTile].x = nHeight;
tileDelete(kSMKTile);
tileCreate(kSMKTile, nWidth, nHeight);
auto pFrame = (uint8_t*)waloff[kSMKTile];
if (!pFrame)
{
Smacker_Close(hSMK);
@ -288,7 +287,7 @@ void credPlaySmk(const char *_pzSMK, const char *_pzWAV, int nWav)
ctrlClearAllInput();
FX_StopAllSounds();
videoSetPalette(gBrightness >> 2, 0, 8+2);
Bfree(pFrame);
tileDelete(kSMKTile);
Bfree(pzSMK_);
Bfree(pzWAV_);
}

View file

@ -87,12 +87,12 @@ void InitMirrors(void)
#endif
mirrorcnt = 0;
tilesiz[504].x = 0;
tilesiz[504].y = 0;
tileDelete(504);
for(int i = 0; i < 16; i++)
tilesiz[4080+i].x = 0, tilesiz[4080+i].y = 0;
for (int i = 0; i < 16; i++)
{
tileDelete(4080 + i);
}
for (int i = numwalls - 1; i >= 0; i--)
{
if (mirrorcnt == 16)
@ -504,11 +504,12 @@ void MirrorLoadSave::Load(void)
Read(&mirrorsector,sizeof(mirrorsector));
Read(mirror, sizeof(mirror));
Read(mirrorwall, sizeof(mirrorwall));
tilesiz[504].x = 0;
tilesiz[504].y = 0;
tileDelete(504);
for (int i = 0; i < 16; i++)
tilesiz[4080 + i].x = 0, tilesiz[4080 + i].y = 0;
for (int i = 0; i < 16; i++)
{
tileDelete(4080 + i);
}
for (int i = 0; i < 4; i++)
{
wall[mirrorwall[i]].picnum = 504;

View file

@ -61,16 +61,6 @@ void qloadvoxel(int32_t nVoxel)
}
}
void CalcPicsiz(int a1, int a2, int a3)
{
int nP = 0;
for (int i = 2; i <= a2; i<<= 1)
nP++;
for (int i = 2; i <= a3; i<<= 1)
nP+=1<<4;
picsiz[a1] = nP;
}
CACHENODE tileNode[kMaxTiles];
bool artLoaded = false;

View file

@ -56,7 +56,6 @@ extern char precachehightile[2][(MAXTILES+7)>>3];
extern int32_t MAXCACHE1DSIZE;
void qloadvoxel(int32_t nVoxel);
void CalcPicsiz(int a1, int a2, int a3);
int tileInit(char a1, const char *a2);
#ifdef USE_OPENGL
void tileProcessGLVoxels(void);

View file

@ -797,9 +797,8 @@ EXTERN int16_t headspritesect[MAXSECTORS+1], headspritestat[MAXSTATUS+1];
EXTERN int16_t prevspritesect[MAXSPRITES], prevspritestat[MAXSPRITES];
EXTERN int16_t nextspritesect[MAXSPRITES], nextspritestat[MAXSPRITES];
EXTERN vec2_16_t tilesiz[MAXTILES];
EXTERN uint8_t picsiz[MAXTILES];
extern const vec2_16_t * const tilesiz;
extern const uint8_t * const picsiz;
EXTERN uint8_t walock[MAXTILES];
extern const char pow2char_[];
@ -1095,6 +1094,7 @@ void tileUpdatePicSiz(int32_t picnum);
int32_t qloadkvx(int32_t voxindex, const char *filename);
void vox_undefine(int32_t const);
intptr_t tileCreate(int16_t tilenume, int32_t xsiz, int32_t ysiz);
intptr_t tileSetExternal(int16_t tilenume, int32_t xsiz, int32_t ysiz, const uint8_t* data);
void tileCopySection(int32_t tilenume1, int32_t sx1, int32_t sy1, int32_t xsiz, int32_t ysiz, int32_t tilenume2, int32_t sx2, int32_t sy2);
void squarerotatetile(int16_t tilenume);

View file

@ -12128,7 +12128,8 @@ void renderSetTarget(int16_t tilenume, int32_t xsiz, int32_t ysiz)
return;
//DRAWROOMS TO TILE BACKUP&SET CODE
tilesiz[tilenume].x = xsiz; tilesiz[tilenume].y = ysiz;
tileDelete(tilenume);
tileCreate(tilenume, xsiz, ysiz);
bakxsiz[setviewcnt] = xdim; bakysiz[setviewcnt] = ydim;
bakframeplace[setviewcnt] = frameplace; frameplace = waloff[tilenume];
bakwindowxy1[setviewcnt] = windowxy1;

View file

@ -122,7 +122,7 @@ extern int16_t searchbottomwall, searchisbottom;
extern char inpreparemirror;
extern uint8_t picsiz[MAXTILES];
extern const uint8_t * const picsiz;
extern int16_t sectorborder[256];
extern int32_t qsetmode;
extern int32_t hitallsprites;

View file

@ -604,9 +604,9 @@ static void polymost_identityrotmat(void)
}
}
static void polymost_flatskyrender(vec2f_t const* const dpxy, int32_t const n, int32_t method);
static void polymost_flatskyrender(vec2f_t const* const dpxy, int32_t const n, int32_t method, const vec2_16_t& tilesiz);
static void polymost_drawpoly(vec2f_t const * const dpxy, int32_t const n, int32_t method)
static void polymost_drawpoly(vec2f_t const * const dpxy, int32_t const n, int32_t method, const vec2_16_t &tilesize)
{
if (method == DAMETH_BACKFACECULL ||
#ifdef YAX_ENABLE
@ -635,7 +635,7 @@ static void polymost_drawpoly(vec2f_t const * const dpxy, int32_t const n, int32
static int32_t skyzbufferhack_pass = 0;
if (flatskyrender && skyzbufferhack_pass == 0)
{
polymost_flatskyrender(dpxy, n, method);
polymost_flatskyrender(dpxy, n, method, tilesize);
return;
}
@ -644,8 +644,7 @@ static void polymost_drawpoly(vec2f_t const * const dpxy, int32_t const n, int32
//Load texture (globalpicnum)
setgotpic(globalpicnum);
vec2_16_t const & tsizart = tilesiz[globalpicnum];
vec2_t tsiz = { tsizart.x, tsizart.y };
vec2_t tsiz = { tilesize.x, tilesize.y };
if (!waloff[globalpicnum])
{
@ -796,14 +795,14 @@ static void polymost_drawpoly(vec2f_t const * const dpxy, int32_t const n, int32
if ((method & DAMETH_WALL) != 0)
{
int32_t size = tilesiz[globalpicnum].y;
int32_t size = tilesize.y;
int32_t size2;
for (size2 = 1; size2 < size; size2 += size2) {}
if (size == size2)
GLInterface.SetNpotEmulation(false, 1.f, 0.f);
else
{
float xOffset = 1.f / tilesiz[globalpicnum].x;
float xOffset = 1.f / tilesize.x;
GLInterface.SetNpotEmulation(true, (1.f*size2) / size, xOffset);
}
}
@ -915,7 +914,7 @@ static void polymost_drawpoly(vec2f_t const * const dpxy, int32_t const n, int32
xtex = xtex2, ytex = ytex2, otex = otex2;
skyzbufferhack_pass++;
GLInterface.SetColorMask(false);
polymost_drawpoly(dpxy, n, DAMETH_MASK);
polymost_drawpoly(dpxy, n, DAMETH_MASK, tilesize);
GLInterface.SetColorMask(true);
xtex = bxtex, ytex = bytex, otex = botex;
skyzbufferhack_pass--;
@ -1318,7 +1317,7 @@ skip: ;
}
else
#endif
polymost_drawpoly(dpxy, n, domostpolymethod);
polymost_drawpoly(dpxy, n, domostpolymethod, tilesiz[globalpicnum]);
vsp[i].cy[0] = n0.y;
vsp[i].cy[1] = n1.y;
@ -1340,7 +1339,7 @@ skip: ;
}
else
#endif
polymost_drawpoly(dpxy, n, domostpolymethod);
polymost_drawpoly(dpxy, n, domostpolymethod, tilesiz[globalpicnum]);
vsp[i].cy[0] = n0.y;
vsp[i].ctag = gtag;
@ -1361,7 +1360,7 @@ skip: ;
}
else
#endif
polymost_drawpoly(dpxy, n, domostpolymethod);
polymost_drawpoly(dpxy, n, domostpolymethod, tilesiz[globalpicnum]);
vsp[i].cy[1] = n1.y;
vsp[i].ctag = gtag;
@ -1383,7 +1382,7 @@ skip: ;
}
else
#endif
polymost_drawpoly(dpxy, n, domostpolymethod);
polymost_drawpoly(dpxy, n, domostpolymethod, tilesiz[globalpicnum]);
vsp[i].ctag = vsp[i].ftag = -1;
}
@ -1412,7 +1411,7 @@ skip: ;
}
else
#endif
polymost_drawpoly(dpxy, n, domostpolymethod);
polymost_drawpoly(dpxy, n, domostpolymethod, tilesiz[globalpicnum]);
vsp[i].fy[0] = n0.y;
vsp[i].fy[1] = n1.y;
@ -1434,7 +1433,7 @@ skip: ;
}
else
#endif
polymost_drawpoly(dpxy, n, domostpolymethod);
polymost_drawpoly(dpxy, n, domostpolymethod, tilesiz[globalpicnum]);
vsp[i].fy[0] = n0.y;
vsp[i].ftag = gtag;
@ -1455,7 +1454,7 @@ skip: ;
}
else
#endif
polymost_drawpoly(dpxy, n, domostpolymethod);
polymost_drawpoly(dpxy, n, domostpolymethod, tilesiz[globalpicnum]);
vsp[i].fy[1] = n1.y;
vsp[i].ftag = gtag;
@ -1475,7 +1474,7 @@ skip: ;
}
else
#endif
polymost_drawpoly(dpxy, n, domostpolymethod);
polymost_drawpoly(dpxy, n, domostpolymethod, tilesiz[globalpicnum]);
vsp[i].ctag = vsp[i].ftag = -1;
}
@ -2120,13 +2119,13 @@ static void polymost_internal_nonparallaxed(vec2f_t n0, vec2f_t n1, float ryp0,
static void calc_ypanning(int32_t refposz, float ryp0, float ryp1,
float x0, float x1, uint8_t ypan, uint8_t yrepeat,
int32_t dopancor)
int32_t dopancor, const vec2_16_t &tilesize)
{
float const t0 = ((float)(refposz-globalposz))*ryp0 + ghoriz;
float const t1 = ((float)(refposz-globalposz))*ryp1 + ghoriz;
float t = (float(xtex.d*x0 + otex.d) * (float)yrepeat) / ((x1-x0) * ryp0 * 2048.f);
int i = (1<<(picsiz[globalpicnum]>>4));
if (i < tilesiz[globalpicnum].y) i <<= 1;
if (i < tilesize.y) i <<= 1;
float const fy = (float)(ypan * i) * (1.f / 256.f);
@ -2229,7 +2228,7 @@ void fgetzsofslope(usectorptr_t sec, float dax, float day, float* ceilz, float *
*florz += (sec->floorheinum*j)/i;
}
static void polymost_flatskyrender(vec2f_t const* const dpxy, int32_t const n, int32_t method)
static void polymost_flatskyrender(vec2f_t const* const dpxy, int32_t const n, int32_t method, const vec2_16_t &tilesiz)
{
flatskyrender = 0;
vec2f_t xys[8];
@ -2256,8 +2255,8 @@ static void polymost_flatskyrender(vec2f_t const* const dpxy, int32_t const n, i
float vv[2];
float t = (float)((1<<(picsiz[globalpicnum]&15))<<dapskybits);
vv[1] = dd*((float)xdimscale*fviewingrange) * (1.f/(daptileyscale*65536.f));
vv[0] = dd*((float)((tilesiz[globalpicnum].y>>1)+dapyoffs)) - vv[1]*ghoriz;
int ti = (1<<(picsiz[globalpicnum]>>4)); if (ti != tilesiz[globalpicnum].y) ti += ti;
vv[0] = dd*((float)((tilesiz.y>>1)+dapyoffs)) - vv[1]*ghoriz;
int ti = (1<<(picsiz[globalpicnum]>>4)); if (ti != tilesiz.y) ti += ti;
vec3f_t o;
skyclamphack = 0;
@ -2278,7 +2277,7 @@ static void polymost_flatskyrender(vec2f_t const* const dpxy, int32_t const n, i
if (xys[i].x > x1) x1 = xys[i].x;
}
int const npot = (1<<(picsiz[globalpicnum]&15)) != tilesiz[globalpicnum].x;
int const npot = (1<<(picsiz[globalpicnum]&15)) != tilesiz.x;
int const xpanning = (r_parallaxskypanning?global_cf_xpanning:0);
GLInterface.SetClamp((npot || xpanning != 0) ? 0 : 2);
@ -2408,7 +2407,7 @@ static void polymost_flatskyrender(vec2f_t const* const dpxy, int32_t const n, i
cxy[i].y = v.y * r + ghalfy;
}
polymost_drawpoly(cxy, n3, method|DAMETH_WALL);
polymost_drawpoly(cxy, n3, method|DAMETH_WALL, tilesiz);
otex = otexbak, xtex = xtexbak, ytex = ytexbak;
}
@ -3123,7 +3122,7 @@ static void polymost_drawalls(int32_t const bunch)
int i = (!(wal->cstat&4)) ? sector[nextsectnum].ceilingz : sec->ceilingz;
// over
calc_ypanning(i, ryp0, ryp1, x0, x1, wal->ypanning, wal->yrepeat, wal->cstat&4);
calc_ypanning(i, ryp0, ryp1, x0, x1, wal->ypanning, wal->yrepeat, wal->cstat&4, tilesiz[globalpicnum]);
if (wal->cstat&8) //xflip
{
@ -3168,7 +3167,7 @@ static void polymost_drawalls(int32_t const bunch)
int i = (!(nwal->cstat&4)) ? sector[nextsectnum].floorz : sec->ceilingz;
// under
calc_ypanning(i, ryp0, ryp1, x0, x1, nwal->ypanning, wal->yrepeat, !(nwal->cstat&4));
calc_ypanning(i, ryp0, ryp1, x0, x1, nwal->ypanning, wal->yrepeat, !(nwal->cstat&4), tilesiz[globalpicnum]);
if (wal->cstat&8) //xflip
{
@ -3225,7 +3224,7 @@ static void polymost_drawalls(int32_t const bunch)
else { i = nwcs4 ? sec->ceilingz : sec->floorz; }
// white / 1-way
calc_ypanning(i, ryp0, ryp1, x0, x1, wal->ypanning, wal->yrepeat, nwcs4 && !maskingOneWay);
calc_ypanning(i, ryp0, ryp1, x0, x1, wal->ypanning, wal->yrepeat, nwcs4 && !maskingOneWay, tilesiz[globalpicnum]);
if (wal->cstat&8) //xflip
{
@ -3890,7 +3889,7 @@ static void polymost_drawmaskwallinternal(int32_t wallIndex)
// mask
calc_ypanning((!(wal->cstat & 4)) ? max(nsec->ceilingz, sec->ceilingz) : min(nsec->floorz, sec->floorz), ryp0, ryp1,
x0, x1, wal->ypanning, wal->yrepeat, 0);
x0, x1, wal->ypanning, wal->yrepeat, 0, tilesiz[globalpicnum]);
if (wal->cstat&8) //xflip
{
@ -4004,7 +4003,7 @@ static void polymost_drawmaskwallinternal(int32_t wallIndex)
skyclamphack = 0;
polymost_updaterotmat();
polymost_drawpoly(dpxy, n, method);
polymost_drawpoly(dpxy, n, method, tilesiz[globalpicnum]);
polymost_identityrotmat();
}
@ -4395,9 +4394,9 @@ void polymost_drawsprite(int32_t snum)
pxy[2].y = pxy[3].y = s0.y;
}
tilesiz[globalpicnum] = { (int16_t)tsiz.x, (int16_t)tsiz.y };
vec2_16_t tempsiz = { (int16_t)tsiz.x, (int16_t)tsiz.y };
pow2xsplit = 0;
polymost_drawpoly(pxy, 4, method);
polymost_drawpoly(pxy, 4, method, tempsiz);
drawpoly_srepeat = 0;
drawpoly_trepeat = 0;
@ -4605,9 +4604,9 @@ void polymost_drawsprite(int32_t snum)
vec2f_t const pxy[4] = { { sx0, sc0 }, { sx1, sc1 }, { sx1, sf1 }, { sx0, sf0 } };
tilesiz[globalpicnum] = { (int16_t)tsiz.x, (int16_t)tsiz.y };
pow2xsplit = 0;
polymost_drawpoly(pxy, 4, method);
vec2_16_t tempsiz = { (int16_t)tsiz.x, (int16_t)tsiz.y };
pow2xsplit = 0;
polymost_drawpoly(pxy, 4, method, tempsiz);
drawpoly_srepeat = 0;
drawpoly_trepeat = 0;
@ -4780,10 +4779,10 @@ void polymost_drawsprite(int32_t snum)
drawpoly_trepeat = 1;
}
tilesiz[globalpicnum] = { (int16_t)tsiz.x, (int16_t)tsiz.y };
pow2xsplit = 0;
vec2_16_t tempsiz = { (int16_t)tsiz.x, (int16_t)tsiz.y };
pow2xsplit = 0;
polymost_drawpoly(pxy, npoints, method);
polymost_drawpoly(pxy, npoints, method, tempsiz);
drawpoly_srepeat = 0;
drawpoly_trepeat = 0;
@ -4800,7 +4799,6 @@ void polymost_drawsprite(int32_t snum)
_drawsprite_return:
polymost_identityrotmat();
tilesiz[globalpicnum] = oldsiz;
}
EDUKE32_STATIC_ASSERT((int)RS_YFLIP == (int)HUDFLAG_FLIPPED);
@ -5215,7 +5213,7 @@ void polymost_dorotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16
ytex.v = yv*(1.0/65536.0);
GLInterface.SetFogEnabled(false);
pow2xsplit = 0; polymost_drawpoly(fpxy,n,method);
pow2xsplit = 0; polymost_drawpoly(fpxy,n,method, tilesiz[globalpicnum]);
if (!nofog) GLInterface.SetFogEnabled(true);
}

View file

@ -26,6 +26,12 @@ EDUKE32_STATIC_ASSERT(MAXARTFILES_TOTAL <= 256);
static int32_t tilefileoffs[MAXTILES];
static vec2_16_t tilesizearray[MAXTILES];
static uint8_t picsizearray[MAXTILES];
// These may only be manipulated through a function interface so that the backing texture objects can be adjusted or replaced.
const vec2_16_t* const tilesiz = tilesizearray;
const uint8_t* const picsiz = picsizearray;
// Backup tilefilenum[] and tilefileoffs[]. These get allocated only when
// necessary (have per-map ART files).
@ -112,8 +118,8 @@ void artClearMapArt(void)
// Restore original per-tile arrays
RESTORE_MAPART_ARRAY(tilefilenum, g_bakTileFileNum);
RESTORE_MAPART_ARRAY(tilefileoffs, g_bakTileFileOffs);
RESTORE_MAPART_ARRAY(tilesiz, g_bakTileSiz);
RESTORE_MAPART_ARRAY(picsiz, g_bakPicSiz);
RESTORE_MAPART_ARRAY(tilesizearray, g_bakTileSiz);
RESTORE_MAPART_ARRAY(picsizearray, g_bakPicSiz);
RESTORE_MAPART_ARRAY(walock, g_bakWalock);
RESTORE_MAPART_ARRAY(waloff, g_bakWaloff);
RESTORE_MAPART_ARRAY(picanm, g_bakPicAnm);
@ -161,8 +167,8 @@ void artSetupMapArt(const char *filename)
// Allocate backup arrays.
ALLOC_MAPART_ARRAY(tilefilenum, g_bakTileFileNum);
ALLOC_MAPART_ARRAY(tilefileoffs, g_bakTileFileOffs);
ALLOC_MAPART_ARRAY(tilesiz, g_bakTileSiz);
ALLOC_MAPART_ARRAY(picsiz, g_bakPicSiz);
ALLOC_MAPART_ARRAY(tilesizearray, g_bakTileSiz);
ALLOC_MAPART_ARRAY(picsizearray, g_bakPicSiz);
ALLOC_MAPART_ARRAY(walock, g_bakWalock);
ALLOC_MAPART_ARRAY(waloff, g_bakWaloff);
ALLOC_MAPART_ARRAY(picanm, g_bakPicAnm);
@ -243,9 +249,9 @@ void tileSetData(int32_t const tile, int32_t tsiz, char const * const buffer)
static void tileSoftDelete(int32_t const tile)
{
tilesiz[tile].x = 0;
tilesiz[tile].y = 0;
picsiz[tile] = 0;
tilesizearray[tile].x = 0;
tilesizearray[tile].y = 0;
picsizearray[tile] = 0;
// CACHE1D_FREE
walock[tile] = 1;
@ -277,18 +283,18 @@ void tileUpdatePicSiz(int32_t picnum)
while ((j > 1) && (pow2long[j] > tilesiz[picnum].x))
j--;
picsiz[picnum] = j;
picsizearray[picnum] = j;
j = 15;
while ((j > 1) && (pow2long[j] > tilesiz[picnum].y))
j--;
picsiz[picnum] |= j<<4;
picsizearray[picnum] |= j<<4;
}
void tileSetSize(int32_t picnum, int16_t dasizx, int16_t dasizy)
{
tilesiz[picnum].x = dasizx;
tilesiz[picnum].y = dasizy;
tilesizearray[picnum].x = dasizx;
tilesizearray[picnum].y = dasizy;
tileUpdatePicSiz(picnum);
}
@ -411,8 +417,8 @@ void artReadManifest(int32_t const fil, artheader_t const* const local)
{
int32_t picanmdisk;
tilesiz[i].x = B_LITTLE16(tilesizx[i - local->tilestart]);
tilesiz[i].y = B_LITTLE16(tilesizy[i - local->tilestart]);
tilesizearray[i].x = B_LITTLE16(tilesizx[i - local->tilestart]);
tilesizearray[i].y = B_LITTLE16(tilesizy[i - local->tilestart]);
kread(fil, &picanmdisk, sizeof(int32_t));
picanmdisk = B_LITTLE32(picanmdisk);
@ -574,7 +580,7 @@ int32_t artLoadFiles(const char *filename, int32_t askedsize)
{
Bstrncpyz(artfilenameformat, filename, sizeof(artfilenameformat));
Bmemset(&tilesiz[0], 0, sizeof(vec2_16_t) * MAXTILES);
Bmemset(&tilesizearray[0], 0, sizeof(vec2_16_t) * MAXTILES);
Bmemset(picanm, 0, sizeof(picanm));
for (auto &rot : rottile)
@ -748,6 +754,22 @@ intptr_t tileCreate(int16_t tilenume, int32_t xsiz, int32_t ysiz)
return waloff[tilenume];
}
intptr_t tileSetExternal(int16_t tilenume, int32_t xsiz, int32_t ysiz, const uint8_t *data)
{
if (xsiz <= 0 || ysiz <= 0 || (unsigned)tilenume >= MAXTILES)
return 0;
int const dasiz = xsiz * ysiz;
walock[tilenume] = 255;
waloff[tilenume] = (intptr_t)data;
tileSetSize(tilenume, xsiz, ysiz);
picanm[tilenume] = {};
return waloff[tilenume];
}
//
// copytilepiece
//

View file

@ -1,250 +0,0 @@
/*
** buildtexture.cpp
** Handling Build textures (now as a usable editing feature!)
**
**---------------------------------------------------------------------------
** Copyright 2004-2006 Randy Heit
** Copyright 2018 Christoph Oelckers
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**---------------------------------------------------------------------------
**
**
*/
#include <stdint.h>
#include "zstring.h"
#include "files.h"
#include "templates.h"
#include "bitmap.h"
#include "textures/textures.h"
#include "image.h"
//==========================================================================
//
// A texture defined in a Build TILESxxx.ART file
//
//==========================================================================
class FBuildTexture : public FImageSource
{
public:
FBuildTexture (const FString &pathprefix, int tilenum, const uint8_t *pixels, int width, int height, int left, int top);
//void CreatePalettedPixels(uint8_t *destbuffer) override;
protected:
const uint8_t *RawPixels;
};
//==========================================================================
//
//
//
//==========================================================================
FBuildTexture::FBuildTexture(const FString &pathprefix, int tilenum, const uint8_t *pixels, int width, int height, int left, int top)
: RawPixels (pixels)
{
Width = width;
Height = height;
LeftOffset = left;
TopOffset = top;
}
#if 0
TArray<uint8_t> FBuildTexture::CreatePalettedPixels(int conversion)
{
TArray<uint8_t> Pixels(Width * Height, true);
memcpy(Pixels.Data(), RawPixels, Width * Height);
return Pixels;
}
#endif
#if 0
//===========================================================================
//
// AddTiles
//
// Adds all the tiles in an artfile to the texture manager.
//
//===========================================================================
void FTextureManager::AddTiles (const FString &pathprefix, const void *tiles)
{
// int numtiles = LittleLong(((uint32_t *)tiles)[1]); // This value is not reliable
int tilestart = LittleLong(((uint32_t *)tiles)[2]);
int tileend = LittleLong(((uint32_t *)tiles)[3]);
const uint16_t *tilesizx = &((const uint16_t *)tiles)[8];
const uint16_t *tilesizy = &tilesizx[tileend - tilestart + 1];
const uint32_t *picanm = (const uint32_t *)&tilesizy[tileend - tilestart + 1];
const uint8_t *tiledata = (const uint8_t *)&picanm[tileend - tilestart + 1];
for (int i = tilestart; i <= tileend; ++i)
{
int pic = i - tilestart;
int width = LittleShort(tilesizx[pic]);
int height = LittleShort(tilesizy[pic]);
uint32_t anm = LittleLong(picanm[pic]);
int xoffs = (int8_t)((anm >> 8) & 255) + width/2;
int yoffs = (int8_t)((anm >> 16) & 255) + height/2;
int size = width*height;
//FTextureID texnum;
FTexture *tex;
if (width <= 0 || height <= 0) continue;
tex = new FImageTexture(new FBuildTexture (pathprefix, i, tiledata, width, height, xoffs, yoffs));
//texnum = AddTexture (tex);
tiledata += size;
tex->Name.Format("%sTILE%04d", pathprefix.GetChars(), i);
// I have no idea if this makes sense or if we better leave animation control to the game code.
// To be decided later.
#if 0
if ((picanm[pic] & 63) && (picanm[pic] & 192))
{
int type, speed;
switch (picanm[pic] & 192)
{
case 64: type = 2; break;
case 128: type = 0; break;
case 192: type = 1; break;
default: type = 0; break; // Won't happen, but GCC bugs me if I don't put this here.
}
speed = (anm >> 24) & 15;
speed = MAX (1, (1 << speed) * 1000 / 120); // Convert from 120 Hz to 1000 Hz.
AddSimpleAnim (texnum, picanm[pic] & 63, type, speed);
}
#endif
// Blood's rotation types:
// 0 - Single
// 1 - 5 Full
// 2 - 8 Full
// 3 - Bounce (looks no different from Single; seems to signal bouncy sprites)
// 4 - 5 Half (not used in game)
// 5 - 3 Flat (not used in game)
// 6 - Voxel
// 7 - Spin Voxel
#if 0
int rotType = (anm >> 28) & 7;
if (rotType == 1)
{
spriteframe_t rot;
rot.Texture[0] =
rot.Texture[1] = texnum;
for (int j = 1; j < 4; ++j)
{
rot.Texture[j*2] =
rot.Texture[j*2+1] =
rot.Texture[16-j*2] =
rot.Texture[17-j*2] = texnum.GetIndex() + j;
}
rot.Texture[8] =
rot.Texture[9] = texnum.GetIndex() + 4;
rot.Flip = 0x00FC;
rot.Voxel = NULL;
tex->Rotations = SpriteFrames.Push (rot);
}
else if (rotType == 2)
{
spriteframe_t rot;
rot.Texture[0] =
rot.Texture[1] = texnum;
for (int j = 1; j < 8; ++j)
{
rot.Texture[16-j*2] =
rot.Texture[17-j*2] = texnum.GetIndex() + j;
}
rot.Flip = 0;
rot.Voxel = NULL;
tex->Rotations = SpriteFrames.Push (rot);
}
#endif
}
}
//===========================================================================
//
// CountTiles
//
// Returns the number of tiles provided by an artfile
//
//===========================================================================
static int CountTiles (const void *tiles)
{
int version = LittleLong(*(uint32_t *)tiles);
if (version != 1)
{
return 0;
}
int tilestart = LittleLong(((uint32_t *)tiles)[2]);
int tileend = LittleLong(((uint32_t *)tiles)[3]);
return tileend >= tilestart ? tileend - tilestart + 1 : 0;
}
//===========================================================================
//
// R_CountBuildTiles
//
// Returns the number of tiles found. Also loads all the data for
// R_InitBuildTiles() to process later.
//
//===========================================================================
void FTextureManager::InitBuildTiles(TArray<FString> &tileFiles)
{
int numtiles;
int totaltiles = 0;
for (auto &artpath : tileFiles)
{
int lumpnum = fileSystem.FindFile(artpath);
if (lumpnum >= 0)
{
BuildTileData.Reserve(1);
auto &artdata = BuildTileData.Last();
artdata = fileSystem.GetFileData(lumpnum);
if ((numtiles = CountTiles(artdata.Data())) > 0)
{
AddTiles("", &artdata[0]);
totaltiles += numtiles;
}
}
}
}
#endif

View file

@ -431,3 +431,38 @@ FTexture *FTexture::GetTexture(const char *path)
if (tex) textures.Insert(path, tex);
return tex;
}
//==========================================================================
//
// A minimalistic wrapper around a Build ART file.
// The data in here is already the format we need.
//
//==========================================================================
class FBuildTexture : public FImageSource
{
const uint8_t* RawPixels;
public:
FBuildTexture(const uint8_t* raw, int width, int height, int left, int top)
: RawPixels(raw)
{
Width = width;
Height = height;
LeftOffset = left;
TopOffset = top;
}
const uint8_t* GetPalettedPixels() override
{
return RawPixels;
}
};
FTexture* FTexture::GetTileTexture(const char* name, const uint8_t* data, int width, int height, int xofs, int yofs)
{
auto res = textures.CheckKey(name);
if (res) return *res;
auto tex = new FImageTexture(new FBuildTexture(data, width, height, xofs, yofs), name);
if (tex) textures.Insert(name, tex);
return tex;
}

View file

@ -147,6 +147,7 @@ class FTexture
public:
static FTexture *CreateTexture(const char *name);
static FTexture* GetTexture(const char* path);
static FTexture* GetTileTexture(const char* name, const uint8_t* data, int width, int height, int xofs, int yofs);
virtual ~FTexture ();
virtual FImageSource *GetImage() const { return nullptr; }

View file

@ -500,7 +500,7 @@ static void G_SE40(int32_t smoothratio)
renderz = sprite[sprite2].z - (sprite[sprite2].yrepeat * tilesiz[sprite[sprite2].picnum].y<<1);
picnum = sector[sprite[sprite2].sectnum].ceilingpicnum;
sector[sprite[sprite2].sectnum].ceilingpicnum = 562;
tilesiz[562].x = tilesiz[562].y = 0;
tileDelete(562);
pix_diff = klabs(z) >> 8;
newz = - ((pix_diff / 128) + 1) * (128<<8);
@ -522,7 +522,7 @@ static void G_SE40(int32_t smoothratio)
renderz = sprite[sprite2].z;
picnum = sector[sprite[sprite2].sectnum].floorpicnum;
sector[sprite[sprite2].sectnum].floorpicnum = 562;
tilesiz[562].x = tilesiz[562].y = 0;
tileDelete(562);
pix_diff = klabs(z) >> 8;
newz = ((pix_diff / 128) + 1) * (128<<8);
@ -714,14 +714,13 @@ static void G_ReadGLFrame(void)
{
// Save OpenGL screenshot with Duke3D palette
palette_t *const frame = (palette_t *)Xcalloc(xdim * ydim, sizeof(palette_t));
char *const pic = (char *) waloff[TILE_SAVESHOT];
int32_t x, y;
const int32_t xf = divscale16(ydim*4/3, 320);
const int32_t yf = divscale16(ydim, 200); // (ydim<<16)/200
tilesiz[TILE_SAVESHOT].x = 200;
tilesiz[TILE_SAVESHOT].y = 320;
tileCreate(TILE_SAVESHOT, 200, 320);
char* const pic = (char*)waloff[TILE_SAVESHOT];
if (!frame)
{

View file

@ -314,11 +314,7 @@ int32_t G_LoadSaveHeaderNew(char const *fn, savehead_t *saveh)
if (kread(fil, &screenshotofs, 4) != 4)
goto corrupt;
walock[TILE_LOADSHOT] = 255;
if (waloff[TILE_LOADSHOT] == 0)
cacheAllocateBlock(&waloff[TILE_LOADSHOT], 320*200, &walock[TILE_LOADSHOT]);
tilesiz[TILE_LOADSHOT].x = 200;
tilesiz[TILE_LOADSHOT].y = 320;
tileCreate(TILE_LOADSHOT, 200, 320);
if (screenshotofs)
{
if (kdfread_LZ4((char *)waloff[TILE_LOADSHOT], 320, 200, fil) != 200)

View file

@ -467,14 +467,12 @@ int32_t Anim_Play(const char *fn)
goto end_anim;
}
walock[TILE_ANIM] = 219;
anim->animlock = 1;
if (!anim->animbuf)
cacheAllocateBlock((intptr_t *)&anim->animbuf, length + 1, &anim->animlock);
tilesiz[TILE_ANIM].x = 200;
tilesiz[TILE_ANIM].y = 320;
tileCreate(TILE_ANIM, 200, 320);
kread(handle, anim->animbuf, length);
kclose(handle);

View file

@ -523,8 +523,6 @@ static void G_SE150_Draw(int32_t spnum, int32_t x, int32_t y, int32_t z, int32_t
if (sprite[spnum].ang != 512) return;
tilesiz[13].x = 0;
tilesiz[13].y = 0;
tileDelete(13);
if (!(gotpic[i >> 3] & (1 << (i & 7)))) return;
gotpic[i >> 3] &= ~(1 << (i & 7));
@ -738,7 +736,7 @@ static void G_SE40(int32_t smoothratio)
renderz = sprite[sprite2].z - (sprite[sprite2].yrepeat * tilesiz[sprite[sprite2].picnum].y<<1);
picnum = sector[sprite[sprite2].sectnum].ceilingpicnum;
sector[sprite[sprite2].sectnum].ceilingpicnum = 562;
tilesiz[562].x = tilesiz[562].y = 0;
tileDelete(562);
pix_diff = klabs(z) >> 8;
newz = - ((pix_diff / 128) + 1) * (128<<8);
@ -760,7 +758,7 @@ static void G_SE40(int32_t smoothratio)
renderz = sprite[sprite2].z;
picnum = sector[sprite[sprite2].sectnum].floorpicnum;
sector[sprite[sprite2].sectnum].floorpicnum = 562;
tilesiz[562].x = tilesiz[562].y = 0;
tileDelete(562);
pix_diff = klabs(z) >> 8;
newz = ((pix_diff / 128) + 1) * (128<<8);
@ -916,14 +914,13 @@ static void G_ReadGLFrame(void)
{
// Save OpenGL screenshot with Duke3D palette
palette_t *const frame = (palette_t *)Xcalloc(xdim * ydim, sizeof(palette_t));
char *const pic = (char *) waloff[TILE_SAVESHOT];
int32_t x, y;
const int32_t xf = divscale16(ydim*4/3, 320);
const int32_t yf = divscale16(ydim, 200); // (ydim<<16)/200
tilesiz[TILE_SAVESHOT].x = 200;
tilesiz[TILE_SAVESHOT].y = 320;
tileCreate(TILE_SAVESHOT, 200, 320);
char* const pic = (char*)waloff[TILE_SAVESHOT];
if (!frame)
{

View file

@ -1892,8 +1892,7 @@ static void prelevel(char g)
}
if (RR)
{
tilesiz[0].x = 0;
tilesiz[0].y = 0;
tileDelete(0);
}
G_SetupGlobalPsky();

View file

@ -294,11 +294,7 @@ int32_t G_LoadSaveHeaderNew(char const *fn, savehead_t *saveh)
if (kread(fil, &screenshotofs, 4) != 4)
goto corrupt;
walock[TILE_LOADSHOT] = 255;
if (waloff[TILE_LOADSHOT] == 0)
cacheAllocateBlock(&waloff[TILE_LOADSHOT], 320*200, &walock[TILE_LOADSHOT]);
tilesiz[TILE_LOADSHOT].x = 200;
tilesiz[TILE_LOADSHOT].y = 320;
tileCreate(TILE_LOADSHOT, 200, 320);
if (screenshotofs)
{
if (kdfread_LZ4((char *)waloff[TILE_LOADSHOT], 320, 200, fil) != 200)

View file

@ -306,8 +306,6 @@ playanm(short anim_num)
palptr = ANIM_GetPalette();
tilesiz[ANIM_TILE(ANIMnum)].x = 200;
tilesiz[ANIM_TILE(ANIMnum)].y = 320;
videoClearViewableArea(0L);
@ -316,7 +314,7 @@ playanm(short anim_num)
if (ANIMnum == 1)
{
// draw the first frame
waloff[ANIM_TILE(ANIMnum)] = (intptr_t)ANIM_DrawFrame(1);
tileSetExternal(ANIM_TILE(ANIMnum), 200, 320, ANIM_DrawFrame(1));
tileInvalidate(ANIM_TILE(ANIMnum), 0, 1<<4);
rotatesprite(0 << 16, 0 << 16, 65536L, 512, ANIM_TILE(ANIMnum), 0, 0, 2 + 4 + 8 + 16 + 64, 0, 0, xdim - 1, ydim - 1);
}
@ -363,8 +361,8 @@ playanm(short anim_num)
break;
}
waloff[ANIM_TILE(ANIMnum)] = (intptr_t)ANIM_DrawFrame(i);
tileInvalidate(ANIM_TILE(ANIMnum), 0, 1<<4);
tileSetExternal(ANIM_TILE(ANIMnum), 200, 320, ANIM_DrawFrame(1));
tileInvalidate(ANIM_TILE(ANIMnum), 0, 1<<4);
rotatesprite(0 << 16, 0 << 16, 65536L, 512, ANIM_TILE(ANIMnum), 0, 0, 2 + 4 + 8 + 16 + 64, 0, 0, xdim - 1, ydim - 1);
videoNextPage();

View file

@ -2693,12 +2693,8 @@ ScreenLoadSaveSetup(PLAYERp pp)
ScreenTileLock();
if (!waloff[SAVE_SCREEN_TILE])
cacheAllocateBlock((intptr_t*)&waloff[SAVE_SCREEN_TILE], SAVE_SCREEN_XSIZE * SAVE_SCREEN_YSIZE, &walock[SAVE_SCREEN_TILE]);
tilesiz[SAVE_SCREEN_TILE].x = SAVE_SCREEN_XSIZE;
tilesiz[SAVE_SCREEN_TILE].x = SAVE_SCREEN_YSIZE;
tileDelete(SAVE_SCREEN_TILE);
tileCreate(SAVE_SCREEN_TILE, SAVE_SCREEN_XSIZE, SAVE_SCREEN_YSIZE);
return SAVE_SCREEN_TILE;
}

View file

@ -334,13 +334,11 @@ JS_InitMirrors(void)
// Scan wall tags for mirrors
mirrorcnt = 0;
tilesiz[MIRROR].x = 0;
tilesiz[MIRROR].y = 0;
tileDelete(MIRROR);
for (i = 0; i < MAXMIRRORS; i++)
{
tilesiz[i + MIRRORLABEL].x = 0;
tilesiz[i + MIRRORLABEL].y = 0;
tileDelete(i + MIRRORLABEL);
mirror[i].campic = -1;
mirror[i].camsprite = -1;
mirror[i].camera = -1;
@ -422,7 +420,7 @@ JS_InitMirrors(void)
mirror[mirrorcnt].camsprite = SpriteNum;
// JBF: commenting out this line results in the screen in $BULLET being visible
tilesiz[mirror[mirrorcnt].campic].x = tilesiz[mirror[mirrorcnt].campic].y = 0;
tileDelete(mirror[mirrorcnt].campic);
Found_Cam = TRUE;
}
@ -785,12 +783,12 @@ JS_DrawMirrors(PLAYERp pp, int tx, int ty, int tz, short tpang, int tphoriz)
// you are outside of it!
if (mirror[cnt].mstate != m_viewon)
{
tilesiz[MIRROR].x = tilesiz[MIRROR].y = 0;
tileDelete(MIRROR);
// Set TV camera sprite size to 0 to show mirror
// behind in this case!
if (mirror[cnt].campic != -1)
tilesiz[mirror[cnt].campic].x = tilesiz[mirror[cnt].campic].y = 0;
tileDelete(mirror[cnt].campic);
drawrooms(dx, dy, dz, tpang, tphoriz, sp->sectnum + MAXSECTORS);
analyzesprites(dx, dy, dz, FALSE);
renderDrawMasks();
@ -862,7 +860,7 @@ JS_DrawMirrors(PLAYERp pp, int tx, int ty, int tz, short tpang, int tphoriz)
// Set up the tile for drawing
tilesiz[mirror[cnt].campic].x = tilesiz[mirror[cnt].campic].y = 128;
tileCreate(mirror[cnt].campic, 128, 128);
if (MirrorMoveSkip16 == 0 || (DoCam && (MoveSkip4 == 0)))
{
@ -910,7 +908,7 @@ JS_DrawMirrors(PLAYERp pp, int tx, int ty, int tz, short tpang, int tphoriz)
// drawrooms(tx, ty, tz, tpang, tphoriz, pp->cursectnum);
// Clean up anything that the camera view might have done
SetFragBar(pp);
tilesiz[MIRROR].x = tilesiz[MIRROR].y = 0;
tileDelete(MIRROR);
wall[mirror[cnt].mirrorwall].overpicnum = MIRRORLABEL + cnt;
}
else