2013-06-27 23:05:11 +00:00
|
|
|
#ifdef USE_OPENGL
|
|
|
|
|
2014-02-10 10:56:14 +00:00
|
|
|
#include "baselayer.h"
|
2013-05-15 02:17:17 +00:00
|
|
|
#include "build.h"
|
2014-02-10 10:55:49 +00:00
|
|
|
#include "lz4.h"
|
2013-05-15 02:17:17 +00:00
|
|
|
#include "hightile.h"
|
|
|
|
#include "polymost.h"
|
|
|
|
#include "texcache.h"
|
|
|
|
#include "scriptfile.h"
|
2014-03-22 09:26:39 +00:00
|
|
|
#include "xxhash.h"
|
2014-09-30 04:18:43 +00:00
|
|
|
#include "kplib.h"
|
2013-05-15 02:17:17 +00:00
|
|
|
|
2019-03-01 08:51:50 +00:00
|
|
|
#include "vfs.h"
|
|
|
|
|
|
|
|
|
2018-02-16 06:38:21 +00:00
|
|
|
#define CLEAR_GL_ERRORS() while(glGetError() != GL_NO_ERROR) { }
|
2013-05-15 02:17:17 +00:00
|
|
|
#define TEXCACHE_FREEBUFS() { Bfree(pic), Bfree(packbuf), Bfree(midbuf); }
|
|
|
|
|
2013-05-17 03:42:37 +00:00
|
|
|
globaltexcache texcache;
|
2013-05-15 02:17:17 +00:00
|
|
|
|
2018-03-23 04:02:35 +00:00
|
|
|
static pthtyp *texcache_tryart(int32_t const dapicnum, int32_t const dapalnum, int32_t const dashade, int32_t dameth)
|
2014-09-30 04:06:05 +00:00
|
|
|
{
|
|
|
|
const int32_t j = dapicnum&(GLTEXCACHEADSIZ-1);
|
2014-10-25 03:30:38 +00:00
|
|
|
pthtyp *pth;
|
2015-04-14 08:07:41 +00:00
|
|
|
int32_t tintpalnum = -1;
|
|
|
|
int32_t searchpalnum = dapalnum;
|
2017-06-21 13:46:50 +00:00
|
|
|
polytintflags_t const tintflags = hictinting[dapalnum].f;
|
2014-09-30 04:06:05 +00:00
|
|
|
|
2017-06-21 13:46:59 +00:00
|
|
|
if (tintflags & (HICTINT_USEONART|HICTINT_ALWAYSUSEART))
|
2015-04-14 08:07:41 +00:00
|
|
|
{
|
|
|
|
tintpalnum = dapalnum;
|
2018-03-23 04:02:35 +00:00
|
|
|
dameth &= ~PTH_INDEXED;
|
2017-06-21 13:46:50 +00:00
|
|
|
if (!(tintflags & HICTINT_APPLYOVERPALSWAP))
|
2015-04-14 08:07:41 +00:00
|
|
|
searchpalnum = 0;
|
|
|
|
}
|
2015-03-09 20:32:11 +00:00
|
|
|
|
2014-09-30 04:06:05 +00:00
|
|
|
// load from art
|
|
|
|
for (pth=texcache.list[j]; pth; pth=pth->next)
|
2018-03-21 20:41:26 +00:00
|
|
|
if (pth->picnum == dapicnum &&
|
|
|
|
(dameth & PTH_INDEXED ? (pth->flags & PTH_INDEXED) &&
|
|
|
|
(pth->flags & PTH_CLAMPED) == TO_PTH_CLAMPED(dameth) :
|
|
|
|
(pth->palnum == dapalnum && pth->shade == dashade &&
|
|
|
|
!(pth->flags & PTH_INDEXED) &&
|
|
|
|
(pth->flags & (PTH_CLAMPED | PTH_HIGHTILE | PTH_NOTRANSFIX)) ==
|
|
|
|
(TO_PTH_CLAMPED(dameth) | TO_PTH_NOTRANSFIX(dameth)) &&
|
|
|
|
polymost_want_npotytex(dameth, tilesiz[dapicnum].y) == !!(pth->flags&PTH_NPOTWALL))))
|
2014-09-30 04:06:05 +00:00
|
|
|
{
|
|
|
|
if (pth->flags & PTH_INVALIDATED)
|
|
|
|
{
|
|
|
|
pth->flags &= ~PTH_INVALIDATED;
|
2015-04-14 08:07:41 +00:00
|
|
|
gloadtile_art(dapicnum, searchpalnum, tintpalnum, dashade, dameth, pth, 0);
|
|
|
|
pth->palnum = dapalnum;
|
2014-09-30 04:06:05 +00:00
|
|
|
}
|
|
|
|
|
2016-06-21 00:34:41 +00:00
|
|
|
return pth;
|
2014-09-30 04:06:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pth = (pthtyp *)Xcalloc(1,sizeof(pthtyp));
|
|
|
|
|
2019-09-13 19:43:05 +00:00
|
|
|
#ifdef TIMING
|
|
|
|
cycle_t clock;
|
|
|
|
clock.Reset();
|
|
|
|
clock.Clock();
|
|
|
|
#endif
|
|
|
|
gloadtile_art(dapicnum, searchpalnum, tintpalnum, dashade, dameth, pth, 1);
|
|
|
|
//thl.AddToCache(dapicnum, dapalnum, dameth);
|
|
|
|
#ifdef TIMING
|
|
|
|
clock.Unclock();
|
|
|
|
OSD_Printf("Loaded texture %d, palnum %d, meth %d -> %2.3f\n", dapicnum, dapalnum, dameth, clock.TimeMS());
|
|
|
|
#endif
|
2014-09-30 04:06:05 +00:00
|
|
|
|
2015-04-14 08:07:41 +00:00
|
|
|
pth->palnum = dapalnum;
|
2014-09-30 04:06:05 +00:00
|
|
|
pth->next = texcache.list[j];
|
|
|
|
texcache.list[j] = pth;
|
|
|
|
|
2016-06-21 00:34:41 +00:00
|
|
|
return pth;
|
2014-09-30 04:06:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pthtyp *texcache_fetchmulti(pthtyp *pth, hicreplctyp *si, int32_t dapicnum, int32_t dameth)
|
|
|
|
{
|
|
|
|
const int32_t j = dapicnum&(GLTEXCACHEADSIZ-1);
|
2014-10-25 03:30:38 +00:00
|
|
|
int32_t i;
|
2014-09-30 04:06:05 +00:00
|
|
|
|
2014-10-25 03:30:38 +00:00
|
|
|
for (i = 0; i <= (GLTEXCACHEADSIZ - 1); i++)
|
2014-09-30 04:06:05 +00:00
|
|
|
{
|
|
|
|
const pthtyp *pth2;
|
|
|
|
|
|
|
|
for (pth2=texcache.list[i]; pth2; pth2=pth2->next)
|
|
|
|
{
|
2017-06-22 01:32:05 +00:00
|
|
|
if (pth2->hicr && pth2->hicr->filename && si->filename && filnamcmp(pth2->hicr->filename, si->filename) == 0)
|
2014-09-30 04:06:05 +00:00
|
|
|
{
|
|
|
|
Bmemcpy(pth, pth2, sizeof(pthtyp));
|
|
|
|
pth->picnum = dapicnum;
|
2015-12-04 11:52:58 +00:00
|
|
|
pth->flags = TO_PTH_CLAMPED(dameth) | TO_PTH_NOTRANSFIX(dameth) |
|
|
|
|
PTH_HIGHTILE | (drawingskybox>0)*PTH_SKYBOX;
|
2014-09-30 04:06:05 +00:00
|
|
|
if (pth2->flags & PTH_HASALPHA)
|
|
|
|
pth->flags |= PTH_HASALPHA;
|
|
|
|
pth->hicr = si;
|
|
|
|
|
|
|
|
pth->next = texcache.list[j];
|
|
|
|
texcache.list[j] = pth;
|
|
|
|
|
|
|
|
return pth;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2014-03-30 13:53:08 +00:00
|
|
|
// <dashade>: ignored if not in Polymost+r_usetileshades
|
2013-05-15 02:18:27 +00:00
|
|
|
pthtyp *texcache_fetch(int32_t dapicnum, int32_t dapalnum, int32_t dashade, int32_t dameth)
|
2013-05-15 02:17:17 +00:00
|
|
|
{
|
2014-11-22 12:34:29 +00:00
|
|
|
const int32_t j = dapicnum & (GLTEXCACHEADSIZ - 1);
|
2017-06-21 13:46:59 +00:00
|
|
|
hicreplctyp *si = usehightile ? hicfindsubst(dapicnum, dapalnum, hictinting[dapalnum].f & HICTINT_ALWAYSUSEART) : NULL;
|
2014-09-30 04:06:05 +00:00
|
|
|
|
|
|
|
if (drawingskybox && usehightile)
|
|
|
|
if ((si = hicfindskybox(dapicnum, dapalnum)) == NULL)
|
|
|
|
return NULL;
|
2013-05-15 02:17:17 +00:00
|
|
|
|
2018-04-12 21:03:12 +00:00
|
|
|
if (!r_usetileshades || (globalflags & GLOBAL_NO_GL_TILESHADES) || videoGetRenderMode() != REND_POLYMOST)
|
2014-03-30 13:53:08 +00:00
|
|
|
dashade = 0;
|
2013-05-15 02:17:17 +00:00
|
|
|
|
|
|
|
if (!si)
|
|
|
|
{
|
2014-11-22 12:34:29 +00:00
|
|
|
return (dapalnum >= (MAXPALOOKUPS - RESERVEDPALS) || hicprecaching) ?
|
|
|
|
NULL : texcache_tryart(dapicnum, dapalnum, dashade, dameth);
|
2013-05-15 02:17:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* if palette > 0 && replacement found
|
|
|
|
* no effects are applied to the texture
|
|
|
|
* else if palette > 0 && no replacement found
|
|
|
|
* effects are applied to the palette 0 texture if it exists
|
|
|
|
*/
|
|
|
|
|
2017-06-21 13:46:50 +00:00
|
|
|
polytintflags_t const tintflags = hictinting[dapalnum].f;
|
|
|
|
|
|
|
|
const int32_t checktintpal = (tintflags & HICTINT_APPLYOVERALTPAL) ? 0 : si->palnum;
|
2018-10-07 05:20:19 +00:00
|
|
|
const int32_t checkcachepal = ((tintflags & HICTINT_IN_MEMORY) || ((tintflags & HICTINT_APPLYOVERALTPAL) && si->palnum > 0)) ? dapalnum : si->palnum;
|
2015-04-14 08:07:23 +00:00
|
|
|
|
2013-05-15 02:17:17 +00:00
|
|
|
// load a replacement
|
2015-03-24 00:40:33 +00:00
|
|
|
for (pthtyp *pth = texcache.list[j]; pth; pth = pth->next)
|
2013-05-15 02:17:17 +00:00
|
|
|
{
|
2017-06-27 02:24:34 +00:00
|
|
|
if (pth->picnum == dapicnum && pth->palnum == checkcachepal && (checktintpal > 0 ? 1 : (pth->effects == tintflags))
|
|
|
|
&& (pth->flags & (PTH_CLAMPED | PTH_HIGHTILE | PTH_SKYBOX | PTH_NOTRANSFIX))
|
|
|
|
== (TO_PTH_CLAMPED(dameth) | TO_PTH_NOTRANSFIX(dameth) | PTH_HIGHTILE | (drawingskybox > 0) * PTH_SKYBOX)
|
|
|
|
&& (drawingskybox > 0 ? (pth->skyface == drawingskybox) : 1))
|
2013-05-15 02:17:17 +00:00
|
|
|
{
|
2014-05-28 22:40:16 +00:00
|
|
|
if (pth->flags & PTH_INVALIDATED)
|
2013-05-15 02:17:17 +00:00
|
|
|
{
|
2014-05-28 22:40:16 +00:00
|
|
|
pth->flags &= ~PTH_INVALIDATED;
|
|
|
|
|
2019-09-18 18:44:21 +00:00
|
|
|
int32_t tilestat = gloadtile_hi(dapicnum, dapalnum, drawingskybox, si, dameth, pth, 0,
|
2017-06-21 13:46:50 +00:00
|
|
|
(checktintpal > 0) ? 0 : tintflags); // reload tile
|
2014-09-30 04:06:05 +00:00
|
|
|
|
2014-11-22 12:34:29 +00:00
|
|
|
if (!tilestat)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (tilestat == -2) // bad filename
|
|
|
|
hicclearsubst(dapicnum, dapalnum);
|
2017-06-27 02:24:34 +00:00
|
|
|
|
2014-11-22 12:34:29 +00:00
|
|
|
return (drawingskybox || hicprecaching) ? NULL : texcache_tryart(dapicnum, dapalnum, dashade, dameth);
|
2013-05-15 02:17:17 +00:00
|
|
|
}
|
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
return pth;
|
2013-05-15 02:17:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
pthtyp *pth = (pthtyp *)Xcalloc(1, sizeof(pthtyp));
|
2013-05-15 02:17:17 +00:00
|
|
|
|
|
|
|
// possibly fetch an already loaded multitexture :_)
|
2017-06-27 11:01:12 +00:00
|
|
|
if (dapalnum == DETAILPAL && texcache_fetchmulti(pth, si, dapicnum, dameth))
|
2014-09-30 04:06:05 +00:00
|
|
|
return pth;
|
2014-05-30 00:02:14 +00:00
|
|
|
|
2019-09-13 19:43:05 +00:00
|
|
|
#ifdef TIMING
|
|
|
|
cycle_t clock;
|
|
|
|
clock.Reset();
|
|
|
|
clock.Clock();
|
|
|
|
#endif
|
|
|
|
int32_t tilestat = gloadtile_hi(dapicnum, dapalnum, drawingskybox, si, dameth, pth, 1, (checktintpal > 0) ? 0 : tintflags);
|
|
|
|
#ifdef TIMING
|
|
|
|
clock.Unclock();
|
|
|
|
OSD_Printf("Loaded texture %d, palnum %d, meth %d -> %2.3f\n", dapicnum, dapalnum, dameth, clock.TimeMS());
|
|
|
|
#endif
|
2014-11-22 12:34:29 +00:00
|
|
|
if (!tilestat)
|
2013-05-15 02:17:17 +00:00
|
|
|
{
|
2014-11-22 12:34:29 +00:00
|
|
|
pth->next = texcache.list[j];
|
2015-04-14 21:17:36 +00:00
|
|
|
pth->palnum = checkcachepal;
|
2014-11-22 12:34:29 +00:00
|
|
|
texcache.list[j] = pth;
|
|
|
|
return pth;
|
2013-05-15 02:17:17 +00:00
|
|
|
}
|
|
|
|
|
2014-11-22 12:34:29 +00:00
|
|
|
if (tilestat == -2) // bad filename
|
|
|
|
hicclearsubst(dapicnum, dapalnum);
|
2013-05-15 02:17:17 +00:00
|
|
|
|
2014-11-22 12:34:29 +00:00
|
|
|
Bfree(pth);
|
|
|
|
|
|
|
|
return (drawingskybox || hicprecaching) ? NULL : texcache_tryart(dapicnum, dapalnum, dashade, dameth);
|
2013-05-15 02:17:17 +00:00
|
|
|
}
|
|
|
|
|
2017-06-27 02:24:34 +00:00
|
|
|
|
|
|
|
|
2013-05-15 02:18:27 +00:00
|
|
|
|
2013-06-27 23:05:11 +00:00
|
|
|
#endif
|