diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 7c093126c..edf8a21b9 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -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 diff --git a/source/blood/src/credits.cpp b/source/blood/src/credits.cpp index ece342d3f..b7b735f2f 100644 --- a/source/blood/src/credits.cpp +++ b/source/blood/src/credits.cpp @@ -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_); } diff --git a/source/blood/src/mirrors.cpp b/source/blood/src/mirrors.cpp index 1699e306d..ef5ad55bc 100644 --- a/source/blood/src/mirrors.cpp +++ b/source/blood/src/mirrors.cpp @@ -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; diff --git a/source/blood/src/tile.cpp b/source/blood/src/tile.cpp index e02917fd4..f54162fab 100644 --- a/source/blood/src/tile.cpp +++ b/source/blood/src/tile.cpp @@ -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; diff --git a/source/blood/src/tile.h b/source/blood/src/tile.h index 438953068..452b79480 100644 --- a/source/blood/src/tile.h +++ b/source/blood/src/tile.h @@ -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); diff --git a/source/build/include/build.h b/source/build/include/build.h index 2eb75c812..0df7b558f 100644 --- a/source/build/include/build.h +++ b/source/build/include/build.h @@ -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); diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index edb3504f1..aae06bd95 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -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; diff --git a/source/build/src/engine_priv.h b/source/build/src/engine_priv.h index 86eea23e9..4db7c1e2d 100644 --- a/source/build/src/engine_priv.h +++ b/source/build/src/engine_priv.h @@ -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; diff --git a/source/build/src/polymost.cpp b/source/build/src/polymost.cpp index 019949464..ec5f072aa 100644 --- a/source/build/src/polymost.cpp +++ b/source/build/src/polymost.cpp @@ -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))<>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); } diff --git a/source/build/src/tiles.cpp b/source/build/src/tiles.cpp index b821c76d0..369187646 100644 --- a/source/build/src/tiles.cpp +++ b/source/build/src/tiles.cpp @@ -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 // diff --git a/source/common/textures/formats/buildtexture.cpp b/source/common/textures/formats/buildtexture.cpp deleted file mode 100644 index 495ecfd97..000000000 --- a/source/common/textures/formats/buildtexture.cpp +++ /dev/null @@ -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 -#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 FBuildTexture::CreatePalettedPixels(int conversion) -{ - TArray 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 &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 \ No newline at end of file diff --git a/source/common/textures/texture.cpp b/source/common/textures/texture.cpp index 95759a959..806b9f3a9 100644 --- a/source/common/textures/texture.cpp +++ b/source/common/textures/texture.cpp @@ -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; +} \ No newline at end of file diff --git a/source/common/textures/textures.h b/source/common/textures/textures.h index 71ea3646a..fdf033c67 100644 --- a/source/common/textures/textures.h +++ b/source/common/textures/textures.h @@ -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; } diff --git a/source/duke3d/src/game.cpp b/source/duke3d/src/game.cpp index 77ed26744..f06c6102c 100644 --- a/source/duke3d/src/game.cpp +++ b/source/duke3d/src/game.cpp @@ -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) { diff --git a/source/duke3d/src/savegame.cpp b/source/duke3d/src/savegame.cpp index 3c14294bf..740061aef 100644 --- a/source/duke3d/src/savegame.cpp +++ b/source/duke3d/src/savegame.cpp @@ -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) diff --git a/source/rr/src/anim.cpp b/source/rr/src/anim.cpp index 6b6441c73..03507ec4d 100644 --- a/source/rr/src/anim.cpp +++ b/source/rr/src/anim.cpp @@ -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); diff --git a/source/rr/src/game.cpp b/source/rr/src/game.cpp index b9c964d1d..fc4700159 100644 --- a/source/rr/src/game.cpp +++ b/source/rr/src/game.cpp @@ -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) { diff --git a/source/rr/src/premap.cpp b/source/rr/src/premap.cpp index c60061ead..683233191 100644 --- a/source/rr/src/premap.cpp +++ b/source/rr/src/premap.cpp @@ -1892,8 +1892,7 @@ static void prelevel(char g) } if (RR) { - tilesiz[0].x = 0; - tilesiz[0].y = 0; + tileDelete(0); } G_SetupGlobalPsky(); diff --git a/source/rr/src/savegame.cpp b/source/rr/src/savegame.cpp index 78fecb140..4e4643ce2 100644 --- a/source/rr/src/savegame.cpp +++ b/source/rr/src/savegame.cpp @@ -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) diff --git a/source/sw/src/anim.cpp b/source/sw/src/anim.cpp index 352769831..dd98b6946 100644 --- a/source/sw/src/anim.cpp +++ b/source/sw/src/anim.cpp @@ -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(); diff --git a/source/sw/src/draw.cpp b/source/sw/src/draw.cpp index 94c2bdb76..c360c9124 100644 --- a/source/sw/src/draw.cpp +++ b/source/sw/src/draw.cpp @@ -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; } diff --git a/source/sw/src/jsector.cpp b/source/sw/src/jsector.cpp index 108288c4c..a1d004849 100644 --- a/source/sw/src/jsector.cpp +++ b/source/sw/src/jsector.cpp @@ -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