2019-01-18 15:55:06 +01:00
|
|
|
#include "cachedtexture.hpp"
|
2019-01-18 21:26:42 +01:00
|
|
|
|
|
|
|
|
#include <stdutil.hpp>
|
|
|
|
|
#include <gxcanvas.hpp>
|
|
|
|
|
#include <gxgraphics.hpp>
|
2014-01-31 08:23:00 +13:00
|
|
|
|
|
|
|
|
int active_texs;
|
|
|
|
|
|
2019-01-18 17:04:17 +01:00
|
|
|
extern gxRuntime* gx_runtime;
|
|
|
|
|
extern gxGraphics* gx_graphics;
|
2014-01-31 08:23:00 +13:00
|
|
|
|
2019-01-18 21:26:42 +01:00
|
|
|
std::set<CachedTexture::CTInstance*> CachedTexture::rep_set;
|
2014-01-31 08:23:00 +13:00
|
|
|
|
2019-01-18 21:26:42 +01:00
|
|
|
static std::string path;
|
2014-01-31 08:23:00 +13:00
|
|
|
|
2019-01-18 21:26:42 +01:00
|
|
|
struct CachedTexture::CTInstance {
|
2019-01-18 17:04:17 +01:00
|
|
|
int ref_cnt;
|
2019-01-18 21:26:42 +01:00
|
|
|
std::string file;
|
2019-01-18 17:04:17 +01:00
|
|
|
int flags, w, h, first;
|
2019-01-18 21:26:42 +01:00
|
|
|
std::vector<gxCanvas*> frames;
|
2014-01-31 08:23:00 +13:00
|
|
|
|
2019-01-18 21:26:42 +01:00
|
|
|
CTInstance(int w, int h, int flags, int cnt) : ref_cnt(1), flags(flags), w(w), h(h), first(0)
|
2019-01-18 17:04:17 +01:00
|
|
|
{
|
2014-01-31 08:23:00 +13:00
|
|
|
++active_texs;
|
2019-01-18 17:04:17 +01:00
|
|
|
while (cnt-- > 0) {
|
|
|
|
|
if (gxCanvas* t = gx_graphics->createCanvas(w, h, flags)) {
|
|
|
|
|
frames.push_back(t);
|
|
|
|
|
} else
|
|
|
|
|
break;
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-18 21:26:42 +01:00
|
|
|
CTInstance(const std::string& f, int flags, int w, int h, int first, int cnt)
|
2019-01-18 17:04:17 +01:00
|
|
|
: ref_cnt(1), file(f), flags(flags), w(w), h(h), first(first)
|
|
|
|
|
{
|
2014-01-31 08:23:00 +13:00
|
|
|
++active_texs;
|
2019-01-18 17:04:17 +01:00
|
|
|
if (!(flags & gxCanvas::CANVAS_TEX_CUBE)) {
|
|
|
|
|
if (w <= 0 || h <= 0 || first < 0 || cnt <= 0) {
|
|
|
|
|
w = h = first = 0;
|
|
|
|
|
if (gxCanvas* t = gx_graphics->loadCanvas(f, flags)) {
|
|
|
|
|
frames.push_back(t);
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-18 17:04:17 +01:00
|
|
|
int t_flags = flags
|
|
|
|
|
& (gxCanvas::CANVAS_TEX_RGB | gxCanvas::CANVAS_TEX_ALPHA | gxCanvas::CANVAS_TEX_MASK
|
|
|
|
|
| gxCanvas::CANVAS_TEX_HICOLOR)
|
|
|
|
|
| gxCanvas::CANVAS_NONDISPLAY;
|
2014-01-31 08:23:00 +13:00
|
|
|
|
2019-01-18 17:04:17 +01:00
|
|
|
gxCanvas* t = gx_graphics->loadCanvas(f, t_flags);
|
|
|
|
|
if (!t)
|
|
|
|
|
return;
|
|
|
|
|
if (!t->getDepth()) {
|
|
|
|
|
gx_graphics->freeCanvas(t);
|
2014-01-31 08:23:00 +13:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-18 17:04:17 +01:00
|
|
|
if (flags & gxCanvas::CANVAS_TEX_CUBE) {
|
|
|
|
|
int w = t->getWidth() / 6;
|
|
|
|
|
if (w * 6 != t->getWidth())
|
|
|
|
|
return;
|
|
|
|
|
int h = t->getHeight();
|
2014-01-31 08:23:00 +13:00
|
|
|
|
2019-01-18 17:04:17 +01:00
|
|
|
gxCanvas* tex = gx_graphics->createCanvas(w, h, flags);
|
|
|
|
|
if (tex) {
|
|
|
|
|
frames.push_back(tex);
|
2014-01-31 08:23:00 +13:00
|
|
|
|
2019-01-18 17:04:17 +01:00
|
|
|
for (int face = 0; face < 6; ++face) {
|
2014-01-31 08:23:00 +13:00
|
|
|
tex->setCubeFace(face);
|
2019-01-18 17:04:17 +01:00
|
|
|
gx_graphics->copy(tex, 0, 0, tex->getWidth(), tex->getHeight(), t, face * w, 0, w, h);
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
|
|
|
|
tex->setCubeFace(1);
|
|
|
|
|
}
|
2019-01-18 17:04:17 +01:00
|
|
|
} else {
|
|
|
|
|
int x_tiles = t->getWidth() / w;
|
|
|
|
|
int y_tiles = t->getHeight() / h;
|
|
|
|
|
if (first + cnt > x_tiles * y_tiles) {
|
|
|
|
|
gx_graphics->freeCanvas(t);
|
2014-01-31 08:23:00 +13:00
|
|
|
return;
|
|
|
|
|
}
|
2019-01-18 17:04:17 +01:00
|
|
|
int x = (first % x_tiles) * w;
|
|
|
|
|
int y = (first / x_tiles) * h;
|
|
|
|
|
while (cnt--) {
|
|
|
|
|
gxCanvas* p = gx_graphics->createCanvas(w, h, flags);
|
|
|
|
|
gx_graphics->copy(p, 0, 0, p->getWidth(), p->getHeight(), t, x, y, w, h);
|
2014-01-31 08:23:00 +13:00
|
|
|
frames.push_back(p);
|
2019-01-18 17:04:17 +01:00
|
|
|
x = x + w;
|
|
|
|
|
if (x + w > t->getWidth()) {
|
|
|
|
|
x = 0;
|
|
|
|
|
y = y + h;
|
|
|
|
|
}
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
|
|
|
|
}
|
2019-01-18 17:04:17 +01:00
|
|
|
gx_graphics->freeCanvas(t);
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
|
|
|
|
|
2019-01-18 21:26:42 +01:00
|
|
|
~CTInstance()
|
2019-01-18 17:04:17 +01:00
|
|
|
{
|
2014-01-31 08:23:00 +13:00
|
|
|
--active_texs;
|
2019-01-18 17:04:17 +01:00
|
|
|
for (int k = 0; k < frames.size(); ++k)
|
|
|
|
|
gx_graphics->freeCanvas(frames[k]);
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2019-01-18 21:26:42 +01:00
|
|
|
CachedTexture::CTInstance* CachedTexture::findRep(const std::string& f, int flags, int w, int h, int first, int cnt)
|
2019-01-18 17:04:17 +01:00
|
|
|
{
|
2019-01-18 21:26:42 +01:00
|
|
|
std::set<CTInstance*>::const_iterator it;
|
2019-01-18 17:04:17 +01:00
|
|
|
for (it = rep_set.begin(); it != rep_set.end(); ++it) {
|
2019-01-18 21:26:42 +01:00
|
|
|
CTInstance* rep = *it;
|
2019-01-18 17:04:17 +01:00
|
|
|
if (rep->file == f && rep->flags == flags && rep->w == w && rep->h == h && rep->first == first
|
|
|
|
|
&& rep->frames.size() == cnt) {
|
|
|
|
|
++rep->ref_cnt;
|
|
|
|
|
return rep;
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-18 21:26:42 +01:00
|
|
|
CachedTexture::CachedTexture(int w, int h, int flags, int cnt) : rep(new CTInstance(w, h, flags, cnt)) {}
|
2019-01-18 17:04:17 +01:00
|
|
|
|
2019-01-18 21:26:42 +01:00
|
|
|
CachedTexture::CachedTexture(const std::string& f_, int flags, int w, int h, int first, int cnt)
|
2019-01-18 17:04:17 +01:00
|
|
|
{
|
2019-01-18 21:26:42 +01:00
|
|
|
std::string f = f_;
|
2019-01-18 17:04:17 +01:00
|
|
|
if (f.substr(0, 2) == ".\\")
|
|
|
|
|
f = f.substr(2);
|
|
|
|
|
if (path.size()) {
|
2019-01-18 21:26:42 +01:00
|
|
|
std::string t = path + tolower(filenamefile(f));
|
2019-01-18 17:04:17 +01:00
|
|
|
if (rep = findRep(t, flags, w, h, first, cnt))
|
|
|
|
|
return;
|
2019-01-18 21:26:42 +01:00
|
|
|
rep = new CTInstance(t, flags, w, h, first, cnt);
|
2019-01-18 17:04:17 +01:00
|
|
|
if (rep->frames.size()) {
|
|
|
|
|
rep_set.insert(rep);
|
2014-01-31 08:23:00 +13:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
delete rep;
|
|
|
|
|
}
|
2019-01-18 21:26:42 +01:00
|
|
|
std::string t = tolower(fullfilename(f));
|
2019-01-18 17:04:17 +01:00
|
|
|
if (rep = findRep(t, flags, w, h, first, cnt))
|
|
|
|
|
return;
|
2019-01-18 21:26:42 +01:00
|
|
|
rep = new CTInstance(t, flags, w, h, first, cnt);
|
2019-01-18 17:04:17 +01:00
|
|
|
rep_set.insert(rep);
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
|
|
|
|
|
2019-01-18 21:26:42 +01:00
|
|
|
CachedTexture::CachedTexture(const CachedTexture& t) : rep(t.rep)
|
2019-01-18 17:04:17 +01:00
|
|
|
{
|
2014-01-31 08:23:00 +13:00
|
|
|
++rep->ref_cnt;
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-18 21:26:42 +01:00
|
|
|
CachedTexture::~CachedTexture()
|
2019-01-18 17:04:17 +01:00
|
|
|
{
|
|
|
|
|
if (!--rep->ref_cnt) {
|
|
|
|
|
rep_set.erase(rep);
|
2014-01-31 08:23:00 +13:00
|
|
|
delete rep;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-18 21:26:42 +01:00
|
|
|
CachedTexture& CachedTexture::operator=(const CachedTexture& t)
|
2019-01-18 17:04:17 +01:00
|
|
|
{
|
2014-01-31 08:23:00 +13:00
|
|
|
++t.rep->ref_cnt;
|
2019-01-18 17:04:17 +01:00
|
|
|
if (!--rep->ref_cnt) {
|
|
|
|
|
rep_set.erase(rep);
|
2014-01-31 08:23:00 +13:00
|
|
|
delete rep;
|
|
|
|
|
}
|
2019-01-18 17:04:17 +01:00
|
|
|
rep = t.rep;
|
2014-01-31 08:23:00 +13:00
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-18 21:26:42 +01:00
|
|
|
std::string CachedTexture::getName() const
|
2019-01-18 17:04:17 +01:00
|
|
|
{
|
2014-01-31 08:23:00 +13:00
|
|
|
return rep->file;
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-18 21:26:42 +01:00
|
|
|
const std::vector<gxCanvas*>& CachedTexture::getFrames() const
|
2019-01-18 17:04:17 +01:00
|
|
|
{
|
2014-01-31 08:23:00 +13:00
|
|
|
return rep->frames;
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-18 21:26:42 +01:00
|
|
|
void CachedTexture::setPath(const std::string& t)
|
2019-01-18 17:04:17 +01:00
|
|
|
{
|
|
|
|
|
path = tolower(t);
|
|
|
|
|
if (int sz = path.size()) {
|
|
|
|
|
if (path[sz - 1] != '/' && path[sz - 1] != '\\')
|
|
|
|
|
path += '\\';
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
|
|
|
|
}
|