373 lines
8.6 KiB
C++
373 lines
8.6 KiB
C++
#include "PrecompiledHeader.h"
|
|
|
|
#include "utils.h"
|
|
#include <JFileSystem.h>
|
|
#include "WResourceManager.h"
|
|
#include "WCachedResource.h"
|
|
#include <hge/hgeparticle.h>
|
|
|
|
#ifdef WITH_FMOD
|
|
#endif
|
|
|
|
const std::string kPlaceholderID("placeholder");
|
|
|
|
//WResource
|
|
WResource::~WResource()
|
|
{
|
|
}
|
|
|
|
WResource::WResource()
|
|
{
|
|
locks = WRES_UNLOCKED;
|
|
lastTime = WResourceManager::Instance()->nowTime();
|
|
loadedMode = 0;
|
|
}
|
|
|
|
bool WResource::isLocked()
|
|
{
|
|
return (locks != WRES_UNLOCKED);
|
|
}
|
|
|
|
bool WResource::isPermanent()
|
|
{
|
|
return (locks == WRES_PERMANENT);
|
|
}
|
|
|
|
void WResource::deadbolt()
|
|
{
|
|
if (locks <= WRES_MAX_LOCK) locks = WRES_PERMANENT;
|
|
}
|
|
|
|
void WResource::lock()
|
|
{
|
|
if (locks < WRES_MAX_LOCK) locks++;
|
|
// watch out for this - if the lock count increases beyond a reasonable threshold,
|
|
// someone is probably not releasing the texture correctly
|
|
assert(locks < 50);
|
|
}
|
|
|
|
void WResource::unlock(bool force)
|
|
{
|
|
if (force)
|
|
locks = 0;
|
|
else if (locks > WRES_UNLOCKED)
|
|
{
|
|
if (locks <= WRES_MAX_LOCK) locks--;
|
|
}
|
|
else
|
|
#ifdef DEBUG_CACHE
|
|
locks = WRES_UNDERLOCKED;
|
|
#else
|
|
locks = 0;
|
|
#endif
|
|
|
|
}
|
|
|
|
void WResource::hit()
|
|
{
|
|
lastTime = WResourceManager::Instance()->nowTime();
|
|
}
|
|
|
|
WCachedResource::~WCachedResource()
|
|
{
|
|
DebugTrace("Destroying WCachedResource: " << mFilename);
|
|
}
|
|
|
|
//WCachedTexture
|
|
WCachedTexture::WCachedTexture()
|
|
{
|
|
texture = NULL;
|
|
}
|
|
|
|
WCachedTexture::~WCachedTexture()
|
|
{
|
|
if (texture)
|
|
SAFE_DELETE(texture);
|
|
}
|
|
|
|
JTexture * WCachedTexture::Actual()
|
|
{
|
|
return texture;
|
|
}
|
|
|
|
bool WCachedTexture::isLocked()
|
|
{
|
|
return (locks != WRES_UNLOCKED);
|
|
}
|
|
|
|
JQuadPtr WCachedTexture::GetQuad(float offX, float offY, float width, float height, const string& resname)
|
|
{
|
|
if (!texture) return JQuadPtr();
|
|
|
|
if (width == 0.0f || width > static_cast<float> (texture->mWidth)) width = static_cast<float> (texture->mWidth);
|
|
if (height == 0.0f || height > static_cast<float> (texture->mHeight)) height = static_cast<float> (texture->mHeight);
|
|
|
|
// If we're fetching a card resource, but it's not available yet, we'll be attempting to get the Quad from the temporary back image.
|
|
// If that's the case, don't stash a separate tracked quad entry for each card name in the the Back/BackThumbnail's resource
|
|
string resource(resname);
|
|
if (mFilename == kGenericCard || mFilename == kGenericThumbCard)
|
|
{
|
|
// if we're the back or thumb_back file, but we've been asked for a card ID, then assign it
|
|
// a placeholder ID. Reason being, hotspots on quads are different (ie centered) for card images, so we'll store a separate quad for cards
|
|
if (resname != kGenericCardID && resname != kGenericCardThumbnailID)
|
|
resource = kPlaceholderID;
|
|
}
|
|
|
|
std::map<string, JQuadPtr>::iterator iter = mTrackedQuads.find(resource);
|
|
if (iter != mTrackedQuads.end())
|
|
return iter->second;
|
|
|
|
JQuadPtr quad(NEW JQuad(texture, offX, offY, width, height));
|
|
|
|
//Update JQ's values to what we called this with.
|
|
quad->SetTextureRect(offX, offY, width, height);
|
|
mTrackedQuads.insert(std::pair<string, JQuadPtr>(resource, quad));
|
|
return quad;
|
|
|
|
}
|
|
|
|
JQuadPtr WCachedTexture::GetQuad(const string& resname)
|
|
{
|
|
JQuadPtr result;
|
|
std::map<string, JQuadPtr>::iterator iter = mTrackedQuads.find(resname);
|
|
if (iter != mTrackedQuads.end())
|
|
result = iter->second;
|
|
|
|
return result;
|
|
}
|
|
|
|
JQuadPtr WCachedTexture::GetCard(float offX, float offY, float width, float height, const string& resname)
|
|
{
|
|
JQuadPtr jq = GetQuad(offX, offY, width, height, resname);
|
|
if (jq.get())
|
|
jq->SetHotSpot(static_cast<float> (jq->mTex->mWidth / 2), static_cast<float> (jq->mTex->mHeight / 2));
|
|
|
|
return jq;
|
|
}
|
|
|
|
unsigned long WCachedTexture::size()
|
|
{
|
|
if (!texture) return 0;
|
|
|
|
unsigned int pixel_size = 4;
|
|
#if defined(PSP)
|
|
pixel_size = JRenderer::GetInstance()->PixelSize(texture->mTextureFormat);
|
|
#endif
|
|
return texture->mTexHeight * texture->mTexWidth * pixel_size;
|
|
}
|
|
|
|
bool WCachedTexture::isGood()
|
|
{
|
|
return (texture != NULL);
|
|
}
|
|
|
|
void WCachedTexture::Refresh()
|
|
{
|
|
int error = 0;
|
|
JTexture* old = texture;
|
|
texture = NULL;
|
|
|
|
if (!Attempt(mFilename, loadedMode, error))
|
|
SAFE_DELETE(texture);
|
|
|
|
if (!texture)
|
|
texture = old;
|
|
else
|
|
SAFE_DELETE(old);
|
|
|
|
JRenderer::GetInstance()->TransferTextureToGLContext(*texture);
|
|
|
|
for (map<string, JQuadPtr>::iterator it = mTrackedQuads.begin(); it != mTrackedQuads.end(); ++it)
|
|
{
|
|
if (it->second.get())
|
|
it->second->mTex = texture;
|
|
}
|
|
}
|
|
|
|
bool WCachedTexture::Attempt(const string& filename, int submode, int & error)
|
|
{
|
|
mFilename = filename;
|
|
int format = TEXTURE_FORMAT;
|
|
loadedMode = submode;
|
|
string realname = filename;
|
|
|
|
//Form correct filename.
|
|
if (submode & TEXTURE_SUB_CARD)
|
|
{
|
|
if (submode & TEXTURE_SUB_THUMB)
|
|
{
|
|
for (string::size_type i = 0; i < realname.size(); i++)
|
|
{
|
|
if (realname[i] == '\\' || realname[i] == '/')
|
|
{
|
|
realname.insert(i + 1, "thumbnails/");
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
realname = WResourceManager::Instance()->cardFile(realname);
|
|
}
|
|
else
|
|
{
|
|
if (submode & TEXTURE_SUB_THUMB) realname.insert(0, "thumbnails/");
|
|
|
|
if (submode & TEXTURE_SUB_AVATAR)
|
|
realname = WResourceManager::Instance()->avatarFile(realname);
|
|
else
|
|
realname = WResourceManager::Instance()->graphicsFile(realname);
|
|
}
|
|
|
|
//Apply pixel mode
|
|
if (submode & TEXTURE_SUB_5551) format = GU_PSM_5551;
|
|
|
|
if (!realname.size())
|
|
{
|
|
error = CACHE_ERROR_404;
|
|
return false;
|
|
}
|
|
|
|
texture = JRenderer::GetInstance()->LoadTexture(realname.c_str(), TEX_TYPE_USE_VRAM, format);
|
|
|
|
//Failure.
|
|
if (!texture)
|
|
{
|
|
error = CACHE_ERROR_BAD;
|
|
if (!fileExists(realname.c_str())) error = CACHE_ERROR_404;
|
|
return false;
|
|
}
|
|
|
|
error = CACHE_ERROR_NONE;
|
|
return true;
|
|
}
|
|
|
|
//WCachedSample
|
|
WCachedSample::WCachedSample()
|
|
{
|
|
sample = NULL;
|
|
}
|
|
|
|
WCachedSample::~WCachedSample()
|
|
{
|
|
SAFE_DELETE(sample);
|
|
}
|
|
|
|
JSample * WCachedSample::Actual()
|
|
{
|
|
return sample;
|
|
}
|
|
|
|
unsigned long WCachedSample::size()
|
|
{
|
|
if (!sample || !sample->mSample) return 0;
|
|
return sample->fileSize();
|
|
}
|
|
|
|
bool WCachedSample::isGood()
|
|
{
|
|
if (!sample || !sample->mSample) return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
void WCachedSample::Refresh()
|
|
{
|
|
return;
|
|
}
|
|
|
|
bool WCachedSample::Attempt(const string& filename, int submode, int & error)
|
|
{
|
|
loadedMode = submode;
|
|
string sfxFile = WResourceManager::Instance()->sfxFile(filename);
|
|
sample = JSoundSystem::GetInstance()->LoadSample(sfxFile.c_str());
|
|
|
|
if (!isGood())
|
|
{
|
|
SAFE_DELETE(sample);
|
|
if (!fileExists(filename.c_str()))
|
|
error = CACHE_ERROR_404;
|
|
else
|
|
error = CACHE_ERROR_BAD;
|
|
return false;
|
|
}
|
|
|
|
error = CACHE_ERROR_NONE;
|
|
return true;
|
|
}
|
|
|
|
//WCachedParticles
|
|
|
|
bool WCachedParticles::isGood()
|
|
{
|
|
if (!particles) return false;
|
|
return true;
|
|
}
|
|
|
|
unsigned long WCachedParticles::size()
|
|
{
|
|
if (!particles) return 0; //Sizeof(pointer)
|
|
|
|
return sizeof(hgeParticleSystemInfo);
|
|
}
|
|
|
|
//Only effects future particle systems, of course.
|
|
void WCachedParticles::Refresh()
|
|
{
|
|
hgeParticleSystemInfo * old = particles;
|
|
|
|
int error = 0;
|
|
Attempt(mFilename, loadedMode, error);
|
|
|
|
if (isGood())
|
|
SAFE_DELETE(old);
|
|
else
|
|
{
|
|
SAFE_DELETE(particles);
|
|
particles = old;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
bool WCachedParticles::Attempt(const string& filename, int, int & error)
|
|
{
|
|
|
|
JFileSystem* fileSys = JFileSystem::GetInstance();
|
|
|
|
if (!fileSys->OpenFile(WResourceManager::Instance()->graphicsFile(filename)))
|
|
{
|
|
error = CACHE_ERROR_404;
|
|
return false;
|
|
}
|
|
|
|
SAFE_DELETE(particles);
|
|
|
|
particles = NEW hgeParticleSystemInfo;
|
|
// We Skip reading the pointer as it may be larger than 4 bytes in the structure
|
|
void *dummyPointer;
|
|
fileSys->ReadFile(&dummyPointer, 4);
|
|
// we're actually trying to read more than the file size now, but it's no problem.
|
|
// Note that this fix is only to avoid the largest problems, filling a structure
|
|
// by directly reading a file, is really a bad idea ...
|
|
fileSys->ReadFile(&(particles->nEmission), sizeof(hgeParticleSystemInfo) - sizeof(void*));
|
|
fileSys->CloseFile();
|
|
|
|
particles->sprite = NULL;
|
|
error = CACHE_ERROR_NONE;
|
|
return true;
|
|
}
|
|
|
|
hgeParticleSystemInfo * WCachedParticles::Actual()
|
|
{
|
|
return particles;
|
|
}
|
|
|
|
WCachedParticles::WCachedParticles()
|
|
{
|
|
particles = NULL;
|
|
}
|
|
WCachedParticles::~WCachedParticles()
|
|
{
|
|
SAFE_DELETE(particles);
|
|
}
|