Files
2022-03-30 13:05:56 +00:00

146 lines
4.7 KiB
C++

#include "SurfaceCache.h"
namespace LogicalBodyTypes {
SurfaceCache::SurfaceCache(UINT32 size) {
loadedElementsMax = size;
loadedElements = 0;
oldest = newest = NULL;
};
SurfaceCache::~SurfaceCache() {
for (UINT32 i = 0; i < surfaceVector.size(); i++) {
delete surfaceVector[i];
}
}
AnimationSurfaceType* SurfaceCache::GetLoadedSurface(UINT32 idx) {
if (idx >= surfaceVector.size()) {
// TODO more sensible handling of errors
SET_ERROR("Error: surface index out of range!");
return NULL;
}
CacheEntry* node = surfaceVector[idx];
if (node == newest) {
return node->surface; // nothing to be done here...
}
if (loadedElements < loadedElementsMax) {
if (!oldest) oldest = node;
if (!node->loaded) {
node->loaded = LoadSurface(node->surface, node->structFile);
// TODO more sensible handling of errors
if (!node->loaded) {
SET_ERROR("Error: a surface could not be loaded! Surface file: %s", node->surface->Filename);
return NULL;
}
loadedElements++;
} else {
if (node->next) node->next->prev = node->prev;
if (node->prev) node->prev->next = node->next;
}
if (newest) {
newest->next = node;
node->prev = newest;
}
newest = node;
} else {
if (node->loaded) {
if (node == oldest) {
oldest = oldest->next;
}
if (node->next) node->next->prev = node->prev;
if (node->prev) node->prev->next = node->next;
} else {
CacheEntry* oldNext = oldest->next;
while (node == oldNext) {
oldNext = oldNext->next;
}
oldest->prev = NULL;
oldest->next = NULL;
oldest->loaded = !UnloadSurface(oldest->surface);
oldest = oldNext;
node->loaded = LoadSurface(node->surface, node->structFile);
// TODO more sensible handling of errors
if (!node->loaded) {
SET_ERROR("Error: a surface could not be loaded!");
return NULL;
}
}
newest->next = node;
node->prev = newest;
newest = node;
}
return node->surface;
}
UINT32 SurfaceCache::AddSurface(AnimationSurfaceType* surface, STRUCTURE_FILE_REF* pStructFile) {
surface->hVideoObject = NULL;
CacheEntry* node = new CacheEntry(surface, pStructFile);
surfaceVector.push_back(node);
return surfaceVector.size() - 1;
}
bool SurfaceCache::UnloadSurface(AnimationSurfaceType* animSurfaceType) {
if (animSurfaceType->hVideoObject != NULL) {
DeleteVideoObject(animSurfaceType->hVideoObject);
animSurfaceType->hVideoObject = NULL;
}
return true;
}
bool SurfaceCache::LoadSurface(AnimationSurfaceType* animSurfaceType, STRUCTURE_FILE_REF* pStructureFileRef) {
AuxObjectData *pAuxData;
VOBJECT_DESC VObjectDesc;
HVOBJECT hVObject;
HIMAGE hImage;
CHAR8 sFilename[48];
// Create video object
FilenameForBPP(animSurfaceType->Filename, sFilename);
AnimDebugMsg(String("SurfaceCache::LoadSurface, %s", sFilename));
hImage = CreateImage(sFilename, IMAGE_ALLDATA);
if (hImage == NULL) return TRUE == SET_ERROR("Error: Could not load animation file %s", sFilename);
VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMHIMAGE;
VObjectDesc.hImage = hImage;
hVObject = CreateVideoObject( &VObjectDesc );
if ( hVObject == NULL ) {
SET_ERROR("Error: Could not load animation file: %s", sFilename);
// Video Object will set error conition.
DestroyImage( hImage );
return false;
}
// Get aux data
if (hImage->uiAppDataSize == hVObject->usNumberOfObjects * sizeof(AuxObjectData)) {
// Valid auxiliary data, so get # od frames from data
pAuxData = (AuxObjectData*) hImage->pAppData;
animSurfaceType->uiNumFramesPerDir = pAuxData->ubNumberOfFrames;
}
else {
SET_ERROR("Invalid # of animations given");
DestroyImage(hImage);
return false;
}
if (pStructureFileRef != NULL) {
INT16 sStartFrame = 0;
// removed exception coding. Do we even need the next block without that? See original global function
if (AddZStripInfoToVObject(hVObject, pStructureFileRef, TRUE, sStartFrame) == FALSE) {
DestroyImage(hImage);
DeleteVideoObject(hVObject);
AnimDebugMsg(String("Animation structure ZStrip creation error: %s", sFilename));
SET_ERROR(String("Animation structure ZStrip creation error: %s", sFilename));
return false;
}
}
// the hImage is no longer needed
DestroyImage(hImage);
// Set video object index
animSurfaceType->hVideoObject = hVObject;
// Determine if we have a problem with #frames + directions ( ie mismatch )
if ((animSurfaceType->uiNumDirections * animSurfaceType->uiNumFramesPerDir ) != animSurfaceType->hVideoObject->usNumberOfObjects) {
AnimDebugMsg(String("Surface Database: WARNING!!! Surface %d has #frames mismatch. Filename %s", animSurfaceType->ubName, animSurfaceType->Filename));
}
return true;
}
}