# Added support for automatically loading 3d models in the COLLADA format.

* CMeshManager: Changed to check for .pmd and .dae files and convert
and cache as appropriate.
 * CModelDef: Fixed misinterpreted doc comments in.
 * lib:
   * Fixed init/shutdown sequences to support multiple VFS-using tests
correctly.
   * Fixed most reported memory leaks from the new leak-reporting test
system.
   * Fixed error when trying to dump debug data about fonts after
unloading them.
 * Added sphere dae/pmd data for tests.
 * Added output buffering to DAE->PMD converter.
 * Added precompiled COLLADA converter DLLs.
 * Removed old redundant conversion script.

This was SVN commit r4709.
This commit is contained in:
Ykkrosh
2006-12-20 03:22:24 +00:00
parent ab12d7303f
commit f6de818ea8
25 changed files with 733 additions and 282 deletions
Binary file not shown.
Binary file not shown.
-43
View File
@@ -1,43 +0,0 @@
from ctypes import *
import sys
import os
if len(sys.argv) != 3:
print "Incorrect command-line syntax. Use"
print " " + sys.argv[0] + " input.dae output.pmd"
sys.exit(-1)
input_filename, output_filename = sys.argv[1:]
if not os.path.exists(input_filename):
print "Cannot find input file '%s'" % input_filename
sys.exit(-1)
dll_filename = {
'posix': './libCollada_dbg.so',
'nt': 'Collada.dll',
}[os.name]
library = cdll.LoadLibrary(dll_filename)
def log(severity, message):
print '[%s] %s' % (('INFO', 'WARNING', 'ERROR')[severity], message)
clog = CFUNCTYPE(None, c_int, c_char_p)(log)
# (the CFUNCTYPE must not be GC'd, so try to keep a reference)
library.set_logger(clog)
def convert_dae_to_pmd(filename):
output = []
def cb(str, len):
output.append(string_at(str, len))
cbtype = CFUNCTYPE(None, POINTER(c_char), c_uint)
status = library.convert_dae_to_pmd(filename, cbtype(cb))
assert(status == 0)
return ''.join(output)
input = open(input_filename).read()
output = convert_dae_to_pmd(input)
open(output_filename, 'wb').write(output)
+5 -4
View File
@@ -38,7 +38,7 @@ void require_(int line, const FUStatus& status)
}
/** Outputs a structure, using sizeof to get the size. */
template<typename T> void write(OutputFn output, const T& data)
template<typename T> void write(OutputCB& output, const T& data)
{
output((char*)&data, sizeof(T));
}
@@ -83,7 +83,7 @@ public:
* @param xmlErrors output - errors reported by the XML parser
* @throws ColladaException on failure
*/
static void ColladaToPMD(const char* input, OutputFn output, std::string& xmlErrors)
static void ColladaToPMD(const char* input, OutputCB& output, std::string& xmlErrors)
{
FUStatus ret;
@@ -239,7 +239,8 @@ public:
/**
* Writes the model data in the PMD format.
*/
static void WritePMD(OutputFn output, size_t vertexCount, size_t boneCount,
static void WritePMD(OutputCB& output,
size_t vertexCount, size_t boneCount,
float* position, float* normal, float* texcoord,
VertexBlend* boneWeights, BoneTransform* boneTransforms)
{
@@ -565,7 +566,7 @@ public:
// with forward declarations of functions - but provide the plain function
// interface here:
void ColladaToPMD(const char* input, OutputFn output, std::string& xmlErrors)
void ColladaToPMD(const char* input, OutputCB& output, std::string& xmlErrors)
{
Converter::ColladaToPMD(input, output, xmlErrors);
}
+6 -1
View File
@@ -24,6 +24,11 @@ private:
std::string msg;
};
void ColladaToPMD(const char* input, OutputFn output, std::string& xmlErrors);
struct OutputCB
{
virtual void operator() (const char* data, unsigned int length)=0;
};
void ColladaToPMD(const char* input, OutputCB& output, std::string& xmlErrors);
#endif // CONVERTER_H__
+52 -3
View File
@@ -3,6 +3,7 @@
#include "Converter.h"
#include <cstdarg>
#include <cassert>
void default_logger(int severity, const char* message)
{
@@ -13,7 +14,10 @@ static LogFn g_Logger = &default_logger;
void set_logger(LogFn logger)
{
g_Logger = logger;
if (logger)
g_Logger = logger;
else
g_Logger = &default_logger;
}
void Log(int severity, const char* msg, ...)
@@ -28,14 +32,59 @@ void Log(int severity, const char* msg, ...)
g_Logger(severity, buffer);
}
int convert_dae_to_pmd(const char* dae, OutputFn pmd_writer)
struct BufferedOutputCallback : public OutputCB
{
static const int bufferSize = 4096;
char buffer[bufferSize];
int bufferUsed;
OutputFn fn;
void* cb_data;
BufferedOutputCallback(OutputFn fn, void* cb_data)
: fn(fn), cb_data(cb_data), bufferUsed(0)
{
}
~BufferedOutputCallback()
{
// flush the buffer if it's not empty
if (bufferUsed > 0)
fn(cb_data, buffer, bufferUsed);
}
virtual void operator() (const char* data, unsigned int length)
{
if (bufferUsed+length > bufferSize)
{
// will overflow buffer, so flush the buffer first
fn(cb_data, buffer, bufferUsed);
bufferUsed = 0;
if (length > bufferSize)
{
// new data won't fit in buffer, so send it out unbuffered
fn(cb_data, data, length);
return;
}
}
// append onto buffer
memcpy(buffer+bufferUsed, data, length);
bufferUsed += length;
assert(bufferUsed <= bufferSize);
}
};
int convert_dae_to_pmd(const char* dae, OutputFn pmd_writer, void* cb_data)
{
Log(LOG_INFO, "Starting conversion");
std::string xmlErrors;
BufferedOutputCallback cb(pmd_writer, cb_data);
try
{
ColladaToPMD(dae, pmd_writer, xmlErrors);
ColladaToPMD(dae, cb, xmlErrors);
}
catch (ColladaException e)
{
+4 -2
View File
@@ -21,10 +21,12 @@ extern "C"
#define LOG_ERROR 2
typedef void (*LogFn) (int severity, const char* text);
typedef void (*OutputFn) (const char* data, unsigned int length);
typedef void (*OutputFn) (void* cb_data, const char* data, unsigned int length);
#define COLLADA_CONVERTER_VERSION 1
EXPORT void set_logger(LogFn logger);
EXPORT int convert_dae_to_pmd(const char* dae, OutputFn pmd_writer);
EXPORT int convert_dae_to_pmd(const char* dae, OutputFn pmd_writer, void* cb_data);
#ifdef __cplusplus
};
+5 -5
View File
@@ -21,11 +21,11 @@ library.set_logger(clog)
def convert_dae_to_pmd(filename):
output = []
def cb(str, len):
def cb(cbdata, str, len):
output.append(string_at(str, len))
cbtype = CFUNCTYPE(None, POINTER(c_char), c_uint)
status = library.convert_dae_to_pmd(filename, cbtype(cb))
cbtype = CFUNCTYPE(None, POINTER(None), POINTER(c_char), c_uint)
status = library.convert_dae_to_pmd(filename, cbtype(cb), None)
assert(status == 0)
return ''.join(output)
@@ -64,8 +64,8 @@ test_mod = binaries + '/data/mods/_test.collada'
clean_dir(test_mod + '/art/meshes')
clean_dir(test_mod + '/art/actors')
for test_file in ['cube', 'jav2', 'teapot_basic', 'teapot_skin', 'plane_skin', 'dude_skin']:
#for test_file in ['dude_skin']:
#for test_file in ['cube', 'jav2', 'teapot_basic', 'teapot_skin', 'plane_skin', 'dude_skin']:
for test_file in ['sphere']:
input_filename = '%s/%s.dae' % (test_data, test_file)
output_filename = '%s/art/meshes/%s.pmd' % (test_mod, test_file)
+218 -18
View File
@@ -1,41 +1,241 @@
#include "precompiled.h"
#include "graphics/MeshManager.h"
#include "MeshManager.h"
#include "graphics/ModelDef.h"
#include "ps/CLogger.h"
#include "ps/FileUnpacker.h" // to get access to its CError
#include "ModelDef.h"
#include "ps/CVFSFile.h"
#include "ps/DllLoader.h"
#include "lib/res/file/vfs.h"
namespace Collada
{
#include "collada/DLL.h"
}
#include <boost/weak_ptr.hpp>
#define LOG_CATEGORY "mesh"
void ColladaLog(int severity, const char* text)
{
LOG(severity==LOG_INFO ? NORMAL : severity==LOG_WARNING ? WARNING : ERROR,
"collada", "%s", text);
}
struct VFSOutputCB
{
VFSOutputCB(Handle hf) : hf(hf) {}
void operator() (const char* data, unsigned int length)
{
FileIOBuf buf = (FileIOBuf)data;
const ssize_t ret = vfs_io(hf, length, &buf);
// TODO: handle errors sensibly
}
Handle hf;
};
void ColladaOutput(void* cb_data, const char* data, unsigned int length)
{
VFSOutputCB* cb = static_cast<VFSOutputCB*>(cb_data);
(*cb)(data, length);
}
typedef STL_HASH_MAP<CStr, boost::weak_ptr<CModelDef>, CStr_hash_compare> mesh_map;
class CMeshManagerImpl
{
DllLoader dll;
void (*set_logger)(Collada::LogFn logger);
int (*convert_dae_to_pmd)(const char* dae, Collada::OutputFn pmd_writer, void* cb_data);
public:
mesh_map MeshMap;
CMeshManagerImpl()
: dll("Collada")
{
}
~CMeshManagerImpl()
{
if (dll.IsLoaded())
set_logger(NULL); // unregister the log handler
}
CModelDefPtr Convert(const CStr& daeFilename, const CStr& pmdFilename, const CStr& name)
{
// To avoid always loading the DLL when it's usually not going to be
// used (and to do the same on Linux where delay-loading won't help),
// and to avoid compile-time dependencies (because it's a minor pain
// to get all the right libraries to build the COLLADA DLL), we load
// it dynamically when it is required, instead of using the exported
// functions and binding at link-time.
if (! dll.IsLoaded())
{
if (! dll.LoadDLL())
{
LOG_ONCE(ERROR, LOG_CATEGORY, "Failed to load COLLADA conversion DLL");
return CModelDefPtr();
}
try
{
dll.LoadSymbol("set_logger", set_logger);
dll.LoadSymbol("convert_dae_to_pmd", convert_dae_to_pmd);
}
catch (PSERROR_DllLoader&)
{
LOG(ERROR, LOG_CATEGORY, "Failed to load symbols from COLLADA conversion DLL");
return CModelDefPtr();
}
set_logger(ColladaLog);
}
// We need to null-terminate the buffer, so do it (possibly inefficiently)
// by converting to a CStr
CStr daeData;
{
CVFSFile daeFile;
if (daeFile.Load(daeFilename) != PSRETURN_OK)
return CModelDefPtr();
daeData = daeFile.GetAsString();
// scope closes daeFile - necessary if we don't use FILE_LONG_LIVED
}
// Prepare the output file
Handle hf = vfs_open(pmdFilename, FILE_WRITE|FILE_NO_AIO);
if (hf < 0)
return CModelDefPtr();
// Do the conversion
VFSOutputCB cb (hf);
convert_dae_to_pmd(daeData.c_str(), ColladaOutput, static_cast<void*>(&cb));
vfs_close(hf);
// Now load the PMD that was just created
CModelDefPtr model (CModelDef::Load(pmdFilename, name));
MeshMap[name] = model;
return model;
}
};
CMeshManager::CMeshManager()
: m(new CMeshManagerImpl())
{
}
CMeshManager::~CMeshManager()
{
delete m;
}
CModelDefPtr CMeshManager::GetMesh(const char *filename)
CModelDefPtr CMeshManager::GetMesh(const CStr& filename)
{
CStr fn(filename);
mesh_map::iterator iter = m_MeshMap.find(fn);
if (iter != m_MeshMap.end() && !iter->second.expired())
{
CModelDefPtr model (iter->second);
//LOG(MESSAGE, "mesh", "Loading mesh '%s%' (cached)...", filename);
return model;
}
// Strip a three-letter file extension (if there is one) from the filename
CStr name;
if (filename.Length() > 4 && filename[filename.Length()-4] == '.')
name = filename.GetSubstring(0, filename.Length()-4);
else
name = filename;
// Find the mesh if it's already been loaded and cached
mesh_map::iterator iter = m->MeshMap.find(name);
if (iter != m->MeshMap.end() && !iter->second.expired())
return CModelDefPtr(iter->second);
/*
If there is a .dae file:
* Calculate a hash to identify it.
* Look for a cached .pmd file matching that hash.
* If it exists, load it. Else, convert the .dae into .pmd and load it.
Otherwise, if there is a (non-cache) .pmd file:
* Load it.
Else, fail.
The hash calculation ought to be fast, since normally (during development)
the .dae file will exist but won't have changed recently and so the cache
would be used. Hence, just hash the file's size, mtime, and the converter
version number (so updates will cause regeneration of .pmds) instead of
its contents.
TODO (maybe): The .dae -> .pmd conversion may fail (e.g. if the .dae is
invalid or unsupported), but it may take a long time to start the conversion
then realise it's not going to work. That will delay the loading of the game
every time, which is annoying, so maybe it should cache the error messge
until the .dae is updated and fixed. (Alternatively, avoid having many
broken .daes in the game's data files.)
*/
try
{
CModelDefPtr model (CModelDef::Load(filename));
if (!model)
return CModelDefPtr();
CStr dae = name+".dae";
if (! vfs_exists(dae))
{
// No .dae - got to use the .pmd, assuming there is one
CModelDefPtr model (CModelDef::Load(name+".pmd", name));
m->MeshMap[name] = model;
return model;
}
//LOG(MESSAGE, "mesh", "Loading mesh '%s'...", filename);
m_MeshMap[fn] = model;
return model;
// There is a .dae - see if there's an up-to-date cached copy
struct stat fileStat;
if (vfs_stat(dae, &fileStat) < 0)
{
// This shouldn't occur for any sensible reasons
LOG(ERROR, LOG_CATEGORY, "Failed to stat DAE file '%s'", filename.c_str());
return CModelDefPtr();
}
// Build a struct of all the data we want to hash.
// (Use ints and not time_t/off_t because we don't care about overflow
// but do care about the fields not being 64-bit aligned)
struct { int version; int mtime; int size; } hashSource
= { COLLADA_CONVERTER_VERSION, fileStat.st_mtime & ~1, fileStat.st_size };
cassert(sizeof(hashSource) == sizeof(int) * 3); // no padding, because that would be bad
// Calculate the hash, convert to hex
u32 hash = fnv_hash(static_cast<void*>(&hashSource), sizeof(hashSource));
char hashString[9];
sprintf(hashString, "%08x", hash);
char realDaePath[PATH_MAX];
vfs_realpath(dae, realDaePath);
// realDaePath is "mods/whatever/art/meshes/whatever.dae"
CStr cachedPmdVfsPath = "cache/";
cachedPmdVfsPath += realDaePath;
// Remove the .dae extension (which will certainly be there)
cachedPmdVfsPath = cachedPmdVfsPath.GetSubstring(0, cachedPmdVfsPath.Length()-4);
// Add a _hash.pmd extension
cachedPmdVfsPath += "_";
cachedPmdVfsPath += hashString;
cachedPmdVfsPath += ".pmd";
// If it's cached, load and return that copy
if (vfs_exists(cachedPmdVfsPath))
{
CModelDefPtr model (CModelDef::Load(cachedPmdVfsPath, name));
m->MeshMap[name] = model;
return model;
}
// Not in the cache, so create it
return m->Convert(dae, cachedPmdVfsPath, name);
}
catch (PSERROR_File&)
{
LOG(ERROR, "mesh", "Could not load mesh '%s'!", filename);
LOG(ERROR, LOG_CATEGORY, "Could not load mesh '%s'", filename.c_str());
return CModelDefPtr();
}
}
+11 -9
View File
@@ -2,26 +2,28 @@
#define __H_MESHMANAGER_H__
#include "ps/Singleton.h"
#include "ps/CStr.h"
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#define g_MeshManager CMeshManager::GetSingleton()
class CModelDef;
typedef boost::shared_ptr<CModelDef> CModelDefPtr;
typedef STL_HASH_MAP<CStr, boost::weak_ptr<CModelDef>, CStr_hash_compare> mesh_map;
class CStr8;
#define g_MeshManager CMeshManager::GetSingleton()
class CMeshManagerImpl;
class CMeshManager : public Singleton<CMeshManager>
{
public:
CMeshManager();
~CMeshManager();
CMeshManager();
~CMeshManager();
CModelDefPtr GetMesh(const CStr8& filename);
CModelDefPtr GetMesh(const char *filename);
private:
mesh_map m_MeshMap;
CMeshManagerImpl* m;
};
#endif
+3 -10
View File
@@ -77,7 +77,6 @@ CVector3D CModelDef::SkinNormal(const SModelVertex& vtx,
return result;
}
///////////////////////////////////////////////////////////////////////////////
// CModelDef Constructor
CModelDef::CModelDef()
: m_NumVertices(0), m_pVertices(0), m_NumFaces(0), m_pFaces(0), m_NumBones(0), m_Bones(0),
@@ -85,7 +84,6 @@ CModelDef::CModelDef()
{
}
///////////////////////////////////////////////////////////////////////////////
// CModelDef Destructor
CModelDef::~CModelDef()
{
@@ -97,7 +95,6 @@ CModelDef::~CModelDef()
delete[] m_PropPoints;
}
///////////////////////////////////////////////////////////////////////////////
// FindPropPoint: find and return pointer to prop point matching given name;
// return null if no match (case insensitive search)
SPropPoint* CModelDef::FindPropPoint(const char* name) const
@@ -109,9 +106,8 @@ SPropPoint* CModelDef::FindPropPoint(const char* name) const
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// Load: read and return a new CModelDef initialised with data from given file
CModelDef* CModelDef::Load(const char* filename)
CModelDef* CModelDef::Load(const char* filename, const char* name)
{
CFileUnpacker unpacker;
@@ -123,8 +119,8 @@ CModelDef* CModelDef::Load(const char* filename)
throw PSERROR_File_InvalidVersion();
}
std::auto_ptr<CModelDef> mdef (new CModelDef);
mdef->m_Name = filename;
std::auto_ptr<CModelDef> mdef (new CModelDef());
mdef->m_Name = name;
// now unpack everything
unpacker.UnpackRaw(&mdef->m_NumVertices,sizeof(mdef->m_NumVertices));
@@ -195,7 +191,6 @@ CModelDef* CModelDef::Load(const char* filename)
return mdef.release();
}
///////////////////////////////////////////////////////////////////////////////
// Save: write the given CModelDef to the given file
void CModelDef::Save(const char* filename,const CModelDef* mdef)
{
@@ -227,7 +222,6 @@ void CModelDef::Save(const char* filename,const CModelDef* mdef)
packer.Write(filename);
}
///////////////////////////////////////////////////////////////////////////////
// SetRenderData: Set the render data object for the given key,
void CModelDef::SetRenderData(const void* key, CModelDefRPrivate* data)
{
@@ -235,7 +229,6 @@ void CModelDef::SetRenderData(const void* key, CModelDefRPrivate* data)
m_RenderData[key] = data;
}
///////////////////////////////////////////////////////////////////////////////
// GetRenderData: Get the render data object for the given key,
// or 0 if no such object exists.
// Reference count of the render data object is automatically increased.
+12 -10
View File
@@ -14,8 +14,6 @@
#include "maths/Quaternion.h"
#include <map>
class CMeshManager;
class CModelDef;
class CBoneState;
///////////////////////////////////////////////////////////////////////////////
@@ -85,7 +83,6 @@ public:
// information of a model
class CModelDef
{
friend class CMeshManager;
public:
// current file version given to saved animations
enum { FILE_VERSION = 3 };
@@ -94,13 +91,21 @@ public:
public:
// constructor
CModelDef();
// destructor
virtual ~CModelDef();
~CModelDef();
// model I/O functions
static void Save(const char* filename,const CModelDef* mdef);
static void Save(const char* filename,const CModelDef* mdef);
/**
* Loads a PMD file.
* @param filename VFS path of .pmd file to load
* @param name arbitrary name to give the model for debugging purposes
* @return the model - always non-NULL
* @throw PSERROR_File if it can't load the model
*/
static CModelDef* Load(const char* filename, const char* name);
public:
// accessor: get vertex data
@@ -183,9 +188,6 @@ private:
// by render path
typedef std::map<const void*, CModelDefRPrivate*> RenderDataMap;
RenderDataMap m_RenderData;
protected:
static CModelDef* Load(const char* filename);
};
#endif
+5 -7
View File
@@ -68,13 +68,11 @@ bool CObjectEntry::BuildVariation(const std::vector<std::set<CStr8> >& selection
// remember the old model so we can replace any models using it later on
CModelDefPtr oldmodeldef = m_Model ? m_Model->GetModelDef() : CModelDefPtr();
const char* modelfilename = m_ModelName;
// try and create a model
CModelDefPtr modeldef (g_MeshManager.GetMesh(modelfilename));
CModelDefPtr modeldef (g_MeshManager.GetMesh(m_ModelName));
if (!modeldef)
{
LOG(ERROR, LOG_CATEGORY, "CObjectEntry::BuildModel(): Model %s failed to load", modelfilename);
LOG(ERROR, LOG_CATEGORY, "CObjectEntry::BuildModel(): Model %s failed to load", m_ModelName.c_str());
return false;
}
@@ -126,7 +124,7 @@ bool CObjectEntry::BuildVariation(const std::vector<std::set<CStr8> >& selection
{
// start up idling
if (! m_Model->SetAnimation(GetRandomAnimation("idle")))
LOG(ERROR, LOG_CATEGORY, "Failed to set idle animation in model \"%s\"", modelfilename);
LOG(ERROR, LOG_CATEGORY, "Failed to set idle animation in model \"%s\"", m_ModelName.c_str());
}
// build props - TODO, RC - need to fix up bounds here
@@ -154,7 +152,7 @@ bool CObjectEntry::BuildVariation(const std::vector<std::set<CStr8> >& selection
m_AmmunitionModel = oe->m_Model;
m_AmmunitionPoint = modeldef->FindPropPoint((const char*)ppn );
if( !m_AmmunitionPoint )
LOG(ERROR, LOG_CATEGORY, "Failed to find matching prop point called \"%s\" in model \"%s\" on actor \"%s\"", (const char*)ppn, modelfilename, (const char*)prop.m_ModelName);
LOG(ERROR, LOG_CATEGORY, "Failed to find matching prop point called \"%s\" in model \"%s\" on actor \"%s\"", (const char*)ppn, (const char*)m_ModelName, (const char*)prop.m_ModelName);
}
else
{
@@ -166,7 +164,7 @@ bool CObjectEntry::BuildVariation(const std::vector<std::set<CStr8> >& selection
propmodel->SetAnimation(oe->GetRandomAnimation("idle"));
}
else
LOG(ERROR, LOG_CATEGORY, "Failed to find matching prop point called \"%s\" in model \"%s\" on actor \"%s\"", (const char*)prop.m_PropPointName, modelfilename, (const char*)prop.m_ModelName);
LOG(ERROR, LOG_CATEGORY, "Failed to find matching prop point called \"%s\" in model \"%s\" on actor \"%s\"", (const char*)prop.m_PropPointName, (const char*)m_ModelName, (const char*)prop.m_ModelName);
}
}
+177
View File
@@ -0,0 +1,177 @@
#include "lib/self_test.h"
#include "lib/res/file/vfs.h"
#include "lib/res/file/vfs_optimizer.h"
#include "lib/res/file/path.h"
#include "lib/res/file/trace.h"
#include "lib/res/h_mgr.h"
#include "graphics/MeshManager.h"
#include "graphics/ModelDef.h"
#define MOD_PATH "mods/_test.mesh"
#define CACHE_PATH "_testcache"
const char* srcDAE = "tests/collada/sphere.dae";
const char* srcPMD = "tests/collada/sphere.pmd";
const char* testDAE = "art/meshes/skeletal/test.dae";
const char* testPMD = "art/meshes/skeletal/test.pmd";
const char* testBase = "art/meshes/skeletal/test";
class TestMeshManager : public CxxTest::TestSuite
{
void initVfs()
{
// Initialise VFS:
TS_ASSERT_OK(file_init());
TS_ASSERT_OK(file_set_root_dir(0, "../data"));
// Set up a mod directory to work in:
// Make sure the required directories doesn't exist when we start,
// in case the previous test aborted and left them full of junk
if (file_exists(MOD_PATH))
TS_ASSERT_OK(dir_delete(MOD_PATH));
if (file_exists(CACHE_PATH))
TS_ASSERT_OK(dir_delete(CACHE_PATH));
TS_ASSERT_OK(dir_create(MOD_PATH, S_IRWXU|S_IRWXG|S_IRWXO));
TS_ASSERT_OK(dir_create(CACHE_PATH, S_IRWXU|S_IRWXG|S_IRWXO));
vfs_init();
// Mount the mod on /
TS_ASSERT_OK(vfs_mount("", MOD_PATH, VFS_MOUNT_RECURSIVE|VFS_MOUNT_ARCHIVES|VFS_MOUNT_ARCHIVABLE));
// Mount _testcache onto virtual /cache - don't use the normal cache
// directory because that's full of loads of cached files from the
// proper game and takes a long time to load.
TS_ASSERT_OK(vfs_mount("cache/", CACHE_PATH, VFS_MOUNT_RECURSIVE|VFS_MOUNT_ARCHIVES|VFS_MOUNT_ARCHIVABLE));
TS_ASSERT_OK(vfs_set_write_target(MOD_PATH));
}
void deinitVfs()
{
// (TODO: It'd be nice if this kind of code didn't have to be
// duplicated in each test suite that's using VFS things)
vfs_shutdown();
h_mgr_shutdown();
TS_ASSERT_OK(file_shutdown());
TS_ASSERT_OK(dir_delete(MOD_PATH));
if (file_exists(CACHE_PATH))
TS_ASSERT_OK(dir_delete(CACHE_PATH));
path_reset_root_dir();
}
void copyFile(const char* src, const char* dst)
{
// Copy a file into the mod directory, so we can work on it:
File f;
TS_ASSERT_OK(file_open(src, 0, &f));
FileIOBuf buf = FILE_BUF_ALLOC;
ssize_t read = file_io(&f, 0, f.size, &buf);
TS_ASSERT_EQUALS(read, f.size);
vfs_store(dst, buf, read, FILE_NO_AIO);
file_buf_free(buf);
file_close(&f);
}
void buildArchive()
{
// Create a junk trace file first, because vfs_opt_auto_build requires one
std::string trace = "000.000000: L \"-\" 0 0000\n";
vfs_store("trace.txt", trace.c_str(), trace.size(), FILE_NO_AIO);
// then make the archive
TS_ASSERT_OK(vfs_opt_rebuild_main_archive(MOD_PATH"/trace.txt", MOD_PATH"/test%02d.zip"));
}
CMeshManager* meshManager;
public:
void setUp()
{
initVfs();
meshManager = new CMeshManager();
}
void tearDown()
{
delete meshManager;
deinitVfs();
}
void IRRELEVANT_test_archived()
{
copyFile(srcDAE, testDAE);
buildArchive();
// Have to specify FILE_WRITE_TO_TARGET in order to overwrite existent
// files when they might have been archived
vfs_store(testDAE, "Test", 4, FILE_NO_AIO | FILE_WRITE_TO_TARGET);
// We can't overwrite cache files because FILE_WRITE_TO_TARGET won't
// write into cache/ - it might be nice to fix that. For now we just
// use unique filenames.
}
void test_load_pmd_with_extension()
{
copyFile(srcPMD, testPMD);
CModelDefPtr modeldef = meshManager->GetMesh(testPMD);
TS_ASSERT(modeldef);
if (modeldef) TS_ASSERT_STR_EQUALS(modeldef->GetName(), testBase);
}
void test_load_pmd_without_extension()
{
copyFile(srcPMD, testPMD);
CModelDefPtr modeldef = meshManager->GetMesh(testBase);
TS_ASSERT(modeldef);
if (modeldef) TS_ASSERT_STR_EQUALS(modeldef->GetName(), testBase);
}
void test_caching()
{
copyFile(srcPMD, testPMD);
CModelDefPtr modeldef1 = meshManager->GetMesh(testPMD);
CModelDefPtr modeldef2 = meshManager->GetMesh(testPMD);
TS_ASSERT(modeldef1 && modeldef2);
TS_ASSERT_EQUALS(modeldef1.get(), modeldef2.get());
}
void test_load_dae()
{
copyFile(srcDAE, testDAE);
CModelDefPtr modeldef = meshManager->GetMesh(testDAE);
TS_ASSERT(modeldef);
if (modeldef) TS_ASSERT_STR_EQUALS(modeldef->GetName(), testBase);
}
void test_load_nonexistent_pmd()
{
CModelDefPtr modeldef = meshManager->GetMesh(testPMD);
TS_ASSERT(! modeldef);
}
void test_load_nonexistent_dae()
{
CModelDefPtr modeldef = meshManager->GetMesh(testDAE);
TS_ASSERT(! modeldef);
}
};
+7 -9
View File
@@ -117,27 +117,25 @@ public:
DynHashTbl()
{
tbl = 0;
num_entries = 0;
max_entries = tr.initial_entries/2; // will be doubled in expand_tbl
debug_assert(is_pow2(max_entries));
expand_tbl();
clear();
}
~DynHashTbl()
{
clear();
free(tbl);
}
void clear()
{
// note: users might call clear() right before the dtor runs,
// so safely handling calling this twice.
// must remain usable after calling clear, so shrink the table to
// its initial size but don't deallocate it completely
SAFE_FREE(tbl);
num_entries = 0;
// rationale: must not set to 0 because expand_tbl only doubles the size.
// don't keep the previous size because it may have become huge and
// there is no provision for shrinking.
// don't keep the previous size when clearing because it may have become
// huge and there is no provision for shrinking.
max_entries = tr.initial_entries/2; // will be doubled in expand_tbl
expand_tbl();
}
void insert(const Key key, const T t)
+14 -3
View File
@@ -222,6 +222,9 @@ void path_reset_root_dir()
// arena, which is also more memory-efficient than the heap (no headers).
static Pool atom_pool;
typedef DynHashTbl<const char*, const char*> AtomMap;
static AtomMap atom_map;
bool path_is_atom_fn(const char* fn)
{
return pool_contains(&atom_pool, (void*)fn);
@@ -247,8 +250,6 @@ const char* file_make_unique_fn_copy(const char* P_fn)
// rationale: the entire storage could be done via container,
// rather than simply using it as a lookup mapping.
// however, DynHashTbl together with Pool (see above) is more efficient.
typedef DynHashTbl<const char*, const char*> AtomMap;
static AtomMap atom_map;
unique_fn = atom_map.find(P_fn);
if(unique_fn)
return unique_fn;
@@ -269,15 +270,25 @@ const char* file_make_unique_fn_copy(const char* P_fn)
}
static ModuleInitState init_state;
void path_init()
{
ONCE_NOT(return;);
moduleInit_assertCanInit(init_state);
pool_create(&atom_pool, 8*MiB, POOL_VARIABLE_ALLOCS);
moduleInit_markInitialized(&init_state);
}
void path_shutdown()
{
moduleInit_assertCanShutdown(init_state);
atom_map.clear();
(void)pool_destroy(&atom_pool);
moduleInit_markShutdown(&init_state);
}
@@ -6,6 +6,8 @@
#include "lib/res/file/vfs.h"
#include "lib/res/file/archive.h"
#include "lib/res/file/archive_builder.h"
#include "lib/res/h_mgr.h"
#include "lib/res/mem.h"
class TestArchiveBuilder : public CxxTest::TestSuite
{
@@ -85,7 +87,6 @@ public:
void setUp()
{
(void)file_init();
path_init(); // required for file_make_unique_fn_copy
(void)file_set_root_dir(0, ".");
vfs_init();
}
@@ -93,12 +94,16 @@ public:
void tearDown()
{
vfs_shutdown();
file_shutdown();
h_mgr_shutdown();
path_reset_root_dir();
}
void test_create_archive_with_random_files()
{
TS_ASSERT_OK(dir_create("archivetest", S_IRWXU|S_IRWXG|S_IRWXO));
if(!file_exists("archivetest")) // don't get stuck if this test fails and never deletes the directory it created
TS_ASSERT_OK(dir_create("archivetest", S_IRWXU|S_IRWXG|S_IRWXO));
TS_ASSERT_OK(vfs_mount("", "archivetest"));
generate_random_files();
@@ -122,6 +127,7 @@ public:
TS_ASSERT_SAME_DATA(buf, files[i].data, files[i].size);
TS_ASSERT_OK(file_buf_free(buf));
TS_ASSERT_OK(afile_close(&f));
SAFE_ARRAY_DELETE(files[i].data);
}
TS_ASSERT_OK(archive_close(ha));
@@ -44,6 +44,9 @@ public:
TS_ASSERT_EQUALS(ucsize_final, data_size); // correct amount of output
}
comp_free(c);
comp_free(d);
// verify data survived intact
TS_ASSERT_SAME_DATA(data, ucdata, data_size);
}
+2
View File
@@ -63,5 +63,7 @@ public:
break;
}
TS_ASSERT(tries_left != 0);
path_shutdown();
}
};
+1 -1
View File
@@ -46,7 +46,7 @@ static inline void trace_init()
void trace_shutdown()
{
if(CAS(&trace_initialized, 1, 2))
if(CAS(&trace_initialized, 1, 0))
(void)pool_destroy(&trace_pool);
}
+3
View File
@@ -302,7 +302,10 @@ RealDir rd; // HACK; removeme
{
TNode* node = *it;
if(node->type == NT_DIR)
{
((TDir*)node)->clearR();
((TDir*)node)->~TDir();
}
}
// wipe out this directory
+6 -3
View File
@@ -67,8 +67,8 @@ static LibError UniFont_reload(UniFont* f, const char* fn, Handle UNUSED(h))
if(f->ht > 0)
return INFO::OK;
f->glyphs_id = new glyphmap_id;
f->glyphs_size = new glyphmap_size;
f->glyphs_id = new glyphmap_id();
f->glyphs_size = new glyphmap_size();
// fn is the base filename, e.g. "console"
// The font definition file is "fonts/"+fn+".fnt" and the texture is "fonts/"+fn+".tga"
@@ -186,7 +186,10 @@ static LibError UniFont_validate(const UniFont* f)
static LibError UniFont_to_string(const UniFont* f, char* buf)
{
snprintf(buf, H_STRING_LEN, "Font %s", h_filename(f->ht));
if (f->ht) // not true if this is called after dtor (which it is)
snprintf(buf, H_STRING_LEN, "Font %s", h_filename(f->ht));
else
snprintf(buf, H_STRING_LEN, "Font");
return INFO::OK;
}
+17 -2
View File
@@ -414,15 +414,22 @@ static Pool fn_pool;
// choose this to balance internal fragmentation and accessing the heap.
static const size_t FN_POOL_EL_SIZE = 64;
static ModuleInitState init_state;
static void fn_init()
{
moduleInit_assertCanInit(init_state);
// (if this fails, so will subsequent fn_stores - no need to complain here)
(void)pool_create(&fn_pool, MAX_EXTANT_HANDLES*FN_POOL_EL_SIZE, FN_POOL_EL_SIZE);
moduleInit_markInitialized(&init_state);
}
static void fn_store(HDATA* hd, const char* fn)
{
ONCE(fn_init());
if (init_state != MODULE_INITIALIZED)
fn_init();
const size_t size = strlen(fn)+1;
@@ -468,7 +475,15 @@ static void fn_free(HDATA* hd)
static void fn_shutdown()
{
pool_destroy(&fn_pool);
// this can be validly called even if not initialized yet,
// since fn_store may have never been called
if (init_state == MODULE_INITIALIZED)
{
pool_destroy(&fn_pool);
}
moduleInit_markShutdown(&init_state);
}
+167 -150
View File
@@ -5,6 +5,7 @@
#include "Errors.h"
class PSERROR_CVFSFile : public PSERROR {};
class PSERROR_DllLoader : public PSERROR {};
class PSERROR_Error : public PSERROR {};
class PSERROR_File : public PSERROR {};
class PSERROR_GUI : public PSERROR {};
@@ -23,6 +24,8 @@ class PSERROR_Scripting_LoadFile : public PSERROR_Scripting {};
class PSERROR_CVFSFile_AlreadyLoaded : public PSERROR_CVFSFile { public: PSRETURN getCode() const; };
class PSERROR_CVFSFile_InvalidBufferAccess : public PSERROR_CVFSFile { public: PSRETURN getCode() const; };
class PSERROR_CVFSFile_LoadFailed : public PSERROR_CVFSFile { public: PSRETURN getCode() const; };
class PSERROR_DllLoader_DllNotLoaded : public PSERROR_DllLoader { public: PSRETURN getCode() const; };
class PSERROR_DllLoader_SymbolNotFound : public PSERROR_DllLoader { public: PSRETURN getCode() const; };
class PSERROR_Error_InvalidError : public PSERROR_Error { public: PSRETURN getCode() const; };
class PSERROR_File_InvalidType : public PSERROR_File { public: PSRETURN getCode() const; };
class PSERROR_File_InvalidVersion : public PSERROR_File { public: PSRETURN getCode() const; };
@@ -54,62 +57,66 @@ class PSERROR_Xeromyces_XMLParseError : public PSERROR_Xeromyces { public: PSRET
extern const PSRETURN PSRETURN_CVFSFile_AlreadyLoaded = 0x01000001;
extern const PSRETURN PSRETURN_CVFSFile_InvalidBufferAccess = 0x01000002;
extern const PSRETURN PSRETURN_CVFSFile_LoadFailed = 0x01000003;
extern const PSRETURN PSRETURN_Error_InvalidError = 0x02000001;
extern const PSRETURN PSRETURN_File_InvalidType = 0x03000001;
extern const PSRETURN PSRETURN_File_InvalidVersion = 0x03000002;
extern const PSRETURN PSRETURN_File_OpenFailed = 0x03000003;
extern const PSRETURN PSRETURN_File_ReadFailed = 0x03000004;
extern const PSRETURN PSRETURN_File_UnexpectedEOF = 0x03000005;
extern const PSRETURN PSRETURN_File_WriteFailed = 0x03000006;
extern const PSRETURN PSRETURN_GUI_JSOpenFailed = 0x04000001;
extern const PSRETURN PSRETURN_Game_World_MapLoadFailed = 0x05040001;
extern const PSRETURN PSRETURN_I18n_Script_SetupFailed = 0x06030001;
extern const PSRETURN PSRETURN_Renderer_VBOFailed = 0x07000001;
extern const PSRETURN PSRETURN_Scripting_DefineType_AlreadyExists = 0x08010001;
extern const PSRETURN PSRETURN_Scripting_DefineType_CreationFailed = 0x08010002;
extern const PSRETURN PSRETURN_Scripting_LoadFile_EvalErrors = 0x08020001;
extern const PSRETURN PSRETURN_Scripting_LoadFile_OpenFailed = 0x08020002;
extern const PSRETURN PSRETURN_Scripting_CallFunctionFailed = 0x08000001;
extern const PSRETURN PSRETURN_Scripting_ConversionFailed = 0x08000002;
extern const PSRETURN PSRETURN_Scripting_CreateObjectFailed = 0x08000003;
extern const PSRETURN PSRETURN_Scripting_DefineConstantFailed = 0x08000004;
extern const PSRETURN PSRETURN_Scripting_RegisterFunctionFailed = 0x08000005;
extern const PSRETURN PSRETURN_Scripting_SetupFailed = 0x08000006;
extern const PSRETURN PSRETURN_Scripting_TypeDoesNotExist = 0x08000007;
extern const PSRETURN PSRETURN_System_RequiredExtensionsMissing = 0x09000001;
extern const PSRETURN PSRETURN_System_SDLInitFailed = 0x09000002;
extern const PSRETURN PSRETURN_System_VmodeFailed = 0x09000003;
extern const PSRETURN PSRETURN_Xeromyces_XMLOpenFailed = 0x0a000001;
extern const PSRETURN PSRETURN_Xeromyces_XMLParseError = 0x0a000002;
extern const PSRETURN PSRETURN_DllLoader_DllNotLoaded = 0x02000001;
extern const PSRETURN PSRETURN_DllLoader_SymbolNotFound = 0x02000002;
extern const PSRETURN PSRETURN_Error_InvalidError = 0x03000001;
extern const PSRETURN PSRETURN_File_InvalidType = 0x04000001;
extern const PSRETURN PSRETURN_File_InvalidVersion = 0x04000002;
extern const PSRETURN PSRETURN_File_OpenFailed = 0x04000003;
extern const PSRETURN PSRETURN_File_ReadFailed = 0x04000004;
extern const PSRETURN PSRETURN_File_UnexpectedEOF = 0x04000005;
extern const PSRETURN PSRETURN_File_WriteFailed = 0x04000006;
extern const PSRETURN PSRETURN_GUI_JSOpenFailed = 0x05000001;
extern const PSRETURN PSRETURN_Game_World_MapLoadFailed = 0x06040001;
extern const PSRETURN PSRETURN_I18n_Script_SetupFailed = 0x07030001;
extern const PSRETURN PSRETURN_Renderer_VBOFailed = 0x08000001;
extern const PSRETURN PSRETURN_Scripting_DefineType_AlreadyExists = 0x09010001;
extern const PSRETURN PSRETURN_Scripting_DefineType_CreationFailed = 0x09010002;
extern const PSRETURN PSRETURN_Scripting_LoadFile_EvalErrors = 0x09020001;
extern const PSRETURN PSRETURN_Scripting_LoadFile_OpenFailed = 0x09020002;
extern const PSRETURN PSRETURN_Scripting_CallFunctionFailed = 0x09000001;
extern const PSRETURN PSRETURN_Scripting_ConversionFailed = 0x09000002;
extern const PSRETURN PSRETURN_Scripting_CreateObjectFailed = 0x09000003;
extern const PSRETURN PSRETURN_Scripting_DefineConstantFailed = 0x09000004;
extern const PSRETURN PSRETURN_Scripting_RegisterFunctionFailed = 0x09000005;
extern const PSRETURN PSRETURN_Scripting_SetupFailed = 0x09000006;
extern const PSRETURN PSRETURN_Scripting_TypeDoesNotExist = 0x09000007;
extern const PSRETURN PSRETURN_System_RequiredExtensionsMissing = 0x0a000001;
extern const PSRETURN PSRETURN_System_SDLInitFailed = 0x0a000002;
extern const PSRETURN PSRETURN_System_VmodeFailed = 0x0a000003;
extern const PSRETURN PSRETURN_Xeromyces_XMLOpenFailed = 0x0b000001;
extern const PSRETURN PSRETURN_Xeromyces_XMLParseError = 0x0b000002;
extern const PSRETURN MASK__PSRETURN_CVFSFile = 0xff000000;
extern const PSRETURN CODE__PSRETURN_CVFSFile = 0x01000000;
extern const PSRETURN MASK__PSRETURN_DllLoader = 0xff000000;
extern const PSRETURN CODE__PSRETURN_DllLoader = 0x02000000;
extern const PSRETURN MASK__PSRETURN_Error = 0xff000000;
extern const PSRETURN CODE__PSRETURN_Error = 0x02000000;
extern const PSRETURN CODE__PSRETURN_Error = 0x03000000;
extern const PSRETURN MASK__PSRETURN_File = 0xff000000;
extern const PSRETURN CODE__PSRETURN_File = 0x03000000;
extern const PSRETURN CODE__PSRETURN_File = 0x04000000;
extern const PSRETURN MASK__PSRETURN_GUI = 0xff000000;
extern const PSRETURN CODE__PSRETURN_GUI = 0x04000000;
extern const PSRETURN CODE__PSRETURN_GUI = 0x05000000;
extern const PSRETURN MASK__PSRETURN_Game = 0xff000000;
extern const PSRETURN CODE__PSRETURN_Game = 0x05000000;
extern const PSRETURN CODE__PSRETURN_Game = 0x06000000;
extern const PSRETURN MASK__PSRETURN_I18n = 0xff000000;
extern const PSRETURN CODE__PSRETURN_I18n = 0x06000000;
extern const PSRETURN CODE__PSRETURN_I18n = 0x07000000;
extern const PSRETURN MASK__PSRETURN_Renderer = 0xff000000;
extern const PSRETURN CODE__PSRETURN_Renderer = 0x07000000;
extern const PSRETURN CODE__PSRETURN_Renderer = 0x08000000;
extern const PSRETURN MASK__PSRETURN_Scripting = 0xff000000;
extern const PSRETURN CODE__PSRETURN_Scripting = 0x08000000;
extern const PSRETURN MASK__PSRETURN_System = 0xff000000;
extern const PSRETURN CODE__PSRETURN_System = 0x09000000;
extern const PSRETURN MASK__PSRETURN_Xeromyces = 0x0a000000;
extern const PSRETURN CODE__PSRETURN_Xeromyces = 0x0a000000;
extern const PSRETURN CODE__PSRETURN_Scripting = 0x09000000;
extern const PSRETURN MASK__PSRETURN_System = 0x0a000000;
extern const PSRETURN CODE__PSRETURN_System = 0x0a000000;
extern const PSRETURN MASK__PSRETURN_Xeromyces = 0x0b000000;
extern const PSRETURN CODE__PSRETURN_Xeromyces = 0x0b000000;
extern const PSRETURN MASK__PSRETURN_Game_World = 0xffff0000;
extern const PSRETURN CODE__PSRETURN_Game_World = 0x05040000;
extern const PSRETURN CODE__PSRETURN_Game_World = 0x06040000;
extern const PSRETURN MASK__PSRETURN_I18n_Script = 0xffff0000;
extern const PSRETURN CODE__PSRETURN_I18n_Script = 0x06030000;
extern const PSRETURN CODE__PSRETURN_I18n_Script = 0x07030000;
extern const PSRETURN MASK__PSRETURN_Scripting_DefineType = 0xffff0000;
extern const PSRETURN CODE__PSRETURN_Scripting_DefineType = 0x08010000;
extern const PSRETURN CODE__PSRETURN_Scripting_DefineType = 0x09010000;
extern const PSRETURN MASK__PSRETURN_Scripting_LoadFile = 0xffff0000;
extern const PSRETURN CODE__PSRETURN_Scripting_LoadFile = 0x08020000;
extern const PSRETURN CODE__PSRETURN_Scripting_LoadFile = 0x09020000;
extern const PSRETURN MASK__PSRETURN_CVFSFile_AlreadyLoaded = 0xffffffff;
extern const PSRETURN CODE__PSRETURN_CVFSFile_AlreadyLoaded = 0x01000001;
@@ -117,91 +124,97 @@ extern const PSRETURN MASK__PSRETURN_CVFSFile_InvalidBufferAccess = 0xffffffff;
extern const PSRETURN CODE__PSRETURN_CVFSFile_InvalidBufferAccess = 0x01000002;
extern const PSRETURN MASK__PSRETURN_CVFSFile_LoadFailed = 0xffffffff;
extern const PSRETURN CODE__PSRETURN_CVFSFile_LoadFailed = 0x01000003;
extern const PSRETURN MASK__PSRETURN_DllLoader_DllNotLoaded = 0xffffffff;
extern const PSRETURN CODE__PSRETURN_DllLoader_DllNotLoaded = 0x02000001;
extern const PSRETURN MASK__PSRETURN_DllLoader_SymbolNotFound = 0xffffffff;
extern const PSRETURN CODE__PSRETURN_DllLoader_SymbolNotFound = 0x02000002;
extern const PSRETURN MASK__PSRETURN_Error_InvalidError = 0xffffffff;
extern const PSRETURN CODE__PSRETURN_Error_InvalidError = 0x02000001;
extern const PSRETURN CODE__PSRETURN_Error_InvalidError = 0x03000001;
extern const PSRETURN MASK__PSRETURN_File_InvalidType = 0xffffffff;
extern const PSRETURN CODE__PSRETURN_File_InvalidType = 0x03000001;
extern const PSRETURN CODE__PSRETURN_File_InvalidType = 0x04000001;
extern const PSRETURN MASK__PSRETURN_File_InvalidVersion = 0xffffffff;
extern const PSRETURN CODE__PSRETURN_File_InvalidVersion = 0x03000002;
extern const PSRETURN CODE__PSRETURN_File_InvalidVersion = 0x04000002;
extern const PSRETURN MASK__PSRETURN_File_OpenFailed = 0xffffffff;
extern const PSRETURN CODE__PSRETURN_File_OpenFailed = 0x03000003;
extern const PSRETURN CODE__PSRETURN_File_OpenFailed = 0x04000003;
extern const PSRETURN MASK__PSRETURN_File_ReadFailed = 0xffffffff;
extern const PSRETURN CODE__PSRETURN_File_ReadFailed = 0x03000004;
extern const PSRETURN CODE__PSRETURN_File_ReadFailed = 0x04000004;
extern const PSRETURN MASK__PSRETURN_File_UnexpectedEOF = 0xffffffff;
extern const PSRETURN CODE__PSRETURN_File_UnexpectedEOF = 0x03000005;
extern const PSRETURN CODE__PSRETURN_File_UnexpectedEOF = 0x04000005;
extern const PSRETURN MASK__PSRETURN_File_WriteFailed = 0xffffffff;
extern const PSRETURN CODE__PSRETURN_File_WriteFailed = 0x03000006;
extern const PSRETURN CODE__PSRETURN_File_WriteFailed = 0x04000006;
extern const PSRETURN MASK__PSRETURN_GUI_JSOpenFailed = 0xffffffff;
extern const PSRETURN CODE__PSRETURN_GUI_JSOpenFailed = 0x04000001;
extern const PSRETURN CODE__PSRETURN_GUI_JSOpenFailed = 0x05000001;
extern const PSRETURN MASK__PSRETURN_Game_World_MapLoadFailed = 0xffffffff;
extern const PSRETURN CODE__PSRETURN_Game_World_MapLoadFailed = 0x05040001;
extern const PSRETURN CODE__PSRETURN_Game_World_MapLoadFailed = 0x06040001;
extern const PSRETURN MASK__PSRETURN_I18n_Script_SetupFailed = 0xffffffff;
extern const PSRETURN CODE__PSRETURN_I18n_Script_SetupFailed = 0x06030001;
extern const PSRETURN CODE__PSRETURN_I18n_Script_SetupFailed = 0x07030001;
extern const PSRETURN MASK__PSRETURN_Renderer_VBOFailed = 0xffffffff;
extern const PSRETURN CODE__PSRETURN_Renderer_VBOFailed = 0x07000001;
extern const PSRETURN CODE__PSRETURN_Renderer_VBOFailed = 0x08000001;
extern const PSRETURN MASK__PSRETURN_Scripting_DefineType_AlreadyExists = 0xffffffff;
extern const PSRETURN CODE__PSRETURN_Scripting_DefineType_AlreadyExists = 0x08010001;
extern const PSRETURN CODE__PSRETURN_Scripting_DefineType_AlreadyExists = 0x09010001;
extern const PSRETURN MASK__PSRETURN_Scripting_DefineType_CreationFailed = 0xffffffff;
extern const PSRETURN CODE__PSRETURN_Scripting_DefineType_CreationFailed = 0x08010002;
extern const PSRETURN CODE__PSRETURN_Scripting_DefineType_CreationFailed = 0x09010002;
extern const PSRETURN MASK__PSRETURN_Scripting_LoadFile_EvalErrors = 0xffffffff;
extern const PSRETURN CODE__PSRETURN_Scripting_LoadFile_EvalErrors = 0x08020001;
extern const PSRETURN CODE__PSRETURN_Scripting_LoadFile_EvalErrors = 0x09020001;
extern const PSRETURN MASK__PSRETURN_Scripting_LoadFile_OpenFailed = 0xffffffff;
extern const PSRETURN CODE__PSRETURN_Scripting_LoadFile_OpenFailed = 0x08020002;
extern const PSRETURN CODE__PSRETURN_Scripting_LoadFile_OpenFailed = 0x09020002;
extern const PSRETURN MASK__PSRETURN_Scripting_CallFunctionFailed = 0xffffffff;
extern const PSRETURN CODE__PSRETURN_Scripting_CallFunctionFailed = 0x08000001;
extern const PSRETURN CODE__PSRETURN_Scripting_CallFunctionFailed = 0x09000001;
extern const PSRETURN MASK__PSRETURN_Scripting_ConversionFailed = 0xffffffff;
extern const PSRETURN CODE__PSRETURN_Scripting_ConversionFailed = 0x08000002;
extern const PSRETURN CODE__PSRETURN_Scripting_ConversionFailed = 0x09000002;
extern const PSRETURN MASK__PSRETURN_Scripting_CreateObjectFailed = 0xffffffff;
extern const PSRETURN CODE__PSRETURN_Scripting_CreateObjectFailed = 0x08000003;
extern const PSRETURN CODE__PSRETURN_Scripting_CreateObjectFailed = 0x09000003;
extern const PSRETURN MASK__PSRETURN_Scripting_DefineConstantFailed = 0xffffffff;
extern const PSRETURN CODE__PSRETURN_Scripting_DefineConstantFailed = 0x08000004;
extern const PSRETURN CODE__PSRETURN_Scripting_DefineConstantFailed = 0x09000004;
extern const PSRETURN MASK__PSRETURN_Scripting_RegisterFunctionFailed = 0xffffffff;
extern const PSRETURN CODE__PSRETURN_Scripting_RegisterFunctionFailed = 0x08000005;
extern const PSRETURN CODE__PSRETURN_Scripting_RegisterFunctionFailed = 0x09000005;
extern const PSRETURN MASK__PSRETURN_Scripting_SetupFailed = 0xffffffff;
extern const PSRETURN CODE__PSRETURN_Scripting_SetupFailed = 0x08000006;
extern const PSRETURN CODE__PSRETURN_Scripting_SetupFailed = 0x09000006;
extern const PSRETURN MASK__PSRETURN_Scripting_TypeDoesNotExist = 0xffffffff;
extern const PSRETURN CODE__PSRETURN_Scripting_TypeDoesNotExist = 0x08000007;
extern const PSRETURN CODE__PSRETURN_Scripting_TypeDoesNotExist = 0x09000007;
extern const PSRETURN MASK__PSRETURN_System_RequiredExtensionsMissing = 0xffffffff;
extern const PSRETURN CODE__PSRETURN_System_RequiredExtensionsMissing = 0x09000001;
extern const PSRETURN CODE__PSRETURN_System_RequiredExtensionsMissing = 0x0a000001;
extern const PSRETURN MASK__PSRETURN_System_SDLInitFailed = 0xffffffff;
extern const PSRETURN CODE__PSRETURN_System_SDLInitFailed = 0x09000002;
extern const PSRETURN CODE__PSRETURN_System_SDLInitFailed = 0x0a000002;
extern const PSRETURN MASK__PSRETURN_System_VmodeFailed = 0xffffffff;
extern const PSRETURN CODE__PSRETURN_System_VmodeFailed = 0x09000003;
extern const PSRETURN CODE__PSRETURN_System_VmodeFailed = 0x0a000003;
extern const PSRETURN MASK__PSRETURN_Xeromyces_XMLOpenFailed = 0xffffffff;
extern const PSRETURN CODE__PSRETURN_Xeromyces_XMLOpenFailed = 0x0a000001;
extern const PSRETURN CODE__PSRETURN_Xeromyces_XMLOpenFailed = 0x0b000001;
extern const PSRETURN MASK__PSRETURN_Xeromyces_XMLParseError = 0xffffffff;
extern const PSRETURN CODE__PSRETURN_Xeromyces_XMLParseError = 0x0a000002;
extern const PSRETURN CODE__PSRETURN_Xeromyces_XMLParseError = 0x0b000002;
PSRETURN PSERROR_CVFSFile_AlreadyLoaded::getCode() const { return 0x01000001; }
PSRETURN PSERROR_CVFSFile_InvalidBufferAccess::getCode() const { return 0x01000002; }
PSRETURN PSERROR_CVFSFile_LoadFailed::getCode() const { return 0x01000003; }
PSRETURN PSERROR_Error_InvalidError::getCode() const { return 0x02000001; }
PSRETURN PSERROR_File_InvalidType::getCode() const { return 0x03000001; }
PSRETURN PSERROR_File_InvalidVersion::getCode() const { return 0x03000002; }
PSRETURN PSERROR_File_OpenFailed::getCode() const { return 0x03000003; }
PSRETURN PSERROR_File_ReadFailed::getCode() const { return 0x03000004; }
PSRETURN PSERROR_File_UnexpectedEOF::getCode() const { return 0x03000005; }
PSRETURN PSERROR_File_WriteFailed::getCode() const { return 0x03000006; }
PSRETURN PSERROR_GUI_JSOpenFailed::getCode() const { return 0x04000001; }
PSRETURN PSERROR_Game_World_MapLoadFailed::getCode() const { return 0x05040001; }
PSRETURN PSERROR_I18n_Script_SetupFailed::getCode() const { return 0x06030001; }
PSRETURN PSERROR_Renderer_VBOFailed::getCode() const { return 0x07000001; }
PSRETURN PSERROR_Scripting_DefineType_AlreadyExists::getCode() const { return 0x08010001; }
PSRETURN PSERROR_Scripting_DefineType_CreationFailed::getCode() const { return 0x08010002; }
PSRETURN PSERROR_Scripting_LoadFile_EvalErrors::getCode() const { return 0x08020001; }
PSRETURN PSERROR_Scripting_LoadFile_OpenFailed::getCode() const { return 0x08020002; }
PSRETURN PSERROR_Scripting_CallFunctionFailed::getCode() const { return 0x08000001; }
PSRETURN PSERROR_Scripting_ConversionFailed::getCode() const { return 0x08000002; }
PSRETURN PSERROR_Scripting_CreateObjectFailed::getCode() const { return 0x08000003; }
PSRETURN PSERROR_Scripting_DefineConstantFailed::getCode() const { return 0x08000004; }
PSRETURN PSERROR_Scripting_RegisterFunctionFailed::getCode() const { return 0x08000005; }
PSRETURN PSERROR_Scripting_SetupFailed::getCode() const { return 0x08000006; }
PSRETURN PSERROR_Scripting_TypeDoesNotExist::getCode() const { return 0x08000007; }
PSRETURN PSERROR_System_RequiredExtensionsMissing::getCode() const { return 0x09000001; }
PSRETURN PSERROR_System_SDLInitFailed::getCode() const { return 0x09000002; }
PSRETURN PSERROR_System_VmodeFailed::getCode() const { return 0x09000003; }
PSRETURN PSERROR_Xeromyces_XMLOpenFailed::getCode() const { return 0x0a000001; }
PSRETURN PSERROR_Xeromyces_XMLParseError::getCode() const { return 0x0a000002; }
PSRETURN PSERROR_DllLoader_DllNotLoaded::getCode() const { return 0x02000001; }
PSRETURN PSERROR_DllLoader_SymbolNotFound::getCode() const { return 0x02000002; }
PSRETURN PSERROR_Error_InvalidError::getCode() const { return 0x03000001; }
PSRETURN PSERROR_File_InvalidType::getCode() const { return 0x04000001; }
PSRETURN PSERROR_File_InvalidVersion::getCode() const { return 0x04000002; }
PSRETURN PSERROR_File_OpenFailed::getCode() const { return 0x04000003; }
PSRETURN PSERROR_File_ReadFailed::getCode() const { return 0x04000004; }
PSRETURN PSERROR_File_UnexpectedEOF::getCode() const { return 0x04000005; }
PSRETURN PSERROR_File_WriteFailed::getCode() const { return 0x04000006; }
PSRETURN PSERROR_GUI_JSOpenFailed::getCode() const { return 0x05000001; }
PSRETURN PSERROR_Game_World_MapLoadFailed::getCode() const { return 0x06040001; }
PSRETURN PSERROR_I18n_Script_SetupFailed::getCode() const { return 0x07030001; }
PSRETURN PSERROR_Renderer_VBOFailed::getCode() const { return 0x08000001; }
PSRETURN PSERROR_Scripting_DefineType_AlreadyExists::getCode() const { return 0x09010001; }
PSRETURN PSERROR_Scripting_DefineType_CreationFailed::getCode() const { return 0x09010002; }
PSRETURN PSERROR_Scripting_LoadFile_EvalErrors::getCode() const { return 0x09020001; }
PSRETURN PSERROR_Scripting_LoadFile_OpenFailed::getCode() const { return 0x09020002; }
PSRETURN PSERROR_Scripting_CallFunctionFailed::getCode() const { return 0x09000001; }
PSRETURN PSERROR_Scripting_ConversionFailed::getCode() const { return 0x09000002; }
PSRETURN PSERROR_Scripting_CreateObjectFailed::getCode() const { return 0x09000003; }
PSRETURN PSERROR_Scripting_DefineConstantFailed::getCode() const { return 0x09000004; }
PSRETURN PSERROR_Scripting_RegisterFunctionFailed::getCode() const { return 0x09000005; }
PSRETURN PSERROR_Scripting_SetupFailed::getCode() const { return 0x09000006; }
PSRETURN PSERROR_Scripting_TypeDoesNotExist::getCode() const { return 0x09000007; }
PSRETURN PSERROR_System_RequiredExtensionsMissing::getCode() const { return 0x0a000001; }
PSRETURN PSERROR_System_SDLInitFailed::getCode() const { return 0x0a000002; }
PSRETURN PSERROR_System_VmodeFailed::getCode() const { return 0x0a000003; }
PSRETURN PSERROR_Xeromyces_XMLOpenFailed::getCode() const { return 0x0b000001; }
PSRETURN PSERROR_Xeromyces_XMLParseError::getCode() const { return 0x0b000002; }
const char* PSERROR::what() const throw ()
{
@@ -220,33 +233,35 @@ const char* GetErrorString(PSRETURN code)
case 0x01000001: return "CVFSFile_AlreadyLoaded";
case 0x01000002: return "CVFSFile_InvalidBufferAccess";
case 0x01000003: return "CVFSFile_LoadFailed";
case 0x02000001: return "Error_InvalidError";
case 0x03000001: return "File_InvalidType";
case 0x03000002: return "File_InvalidVersion";
case 0x03000003: return "File_OpenFailed";
case 0x03000004: return "File_ReadFailed";
case 0x03000005: return "File_UnexpectedEOF";
case 0x03000006: return "File_WriteFailed";
case 0x04000001: return "GUI_JSOpenFailed";
case 0x05040001: return "Game_World_MapLoadFailed";
case 0x06030001: return "I18n_Script_SetupFailed";
case 0x07000001: return "Renderer_VBOFailed";
case 0x08010001: return "Scripting_DefineType_AlreadyExists";
case 0x08010002: return "Scripting_DefineType_CreationFailed";
case 0x08020001: return "Scripting_LoadFile_EvalErrors";
case 0x08020002: return "Scripting_LoadFile_OpenFailed";
case 0x08000001: return "Scripting_CallFunctionFailed";
case 0x08000002: return "Scripting_ConversionFailed";
case 0x08000003: return "Scripting_CreateObjectFailed";
case 0x08000004: return "Scripting_DefineConstantFailed";
case 0x08000005: return "Scripting_RegisterFunctionFailed";
case 0x08000006: return "Scripting_SetupFailed";
case 0x08000007: return "Scripting_TypeDoesNotExist";
case 0x09000001: return "System_RequiredExtensionsMissing";
case 0x09000002: return "System_SDLInitFailed";
case 0x09000003: return "System_VmodeFailed";
case 0x0a000001: return "Xeromyces_XMLOpenFailed";
case 0x0a000002: return "Xeromyces_XMLParseError";
case 0x02000001: return "DllLoader_DllNotLoaded";
case 0x02000002: return "DllLoader_SymbolNotFound";
case 0x03000001: return "Error_InvalidError";
case 0x04000001: return "File_InvalidType";
case 0x04000002: return "File_InvalidVersion";
case 0x04000003: return "File_OpenFailed";
case 0x04000004: return "File_ReadFailed";
case 0x04000005: return "File_UnexpectedEOF";
case 0x04000006: return "File_WriteFailed";
case 0x05000001: return "GUI_JSOpenFailed";
case 0x06040001: return "Game_World_MapLoadFailed";
case 0x07030001: return "I18n_Script_SetupFailed";
case 0x08000001: return "Renderer_VBOFailed";
case 0x09010001: return "Scripting_DefineType_AlreadyExists";
case 0x09010002: return "Scripting_DefineType_CreationFailed";
case 0x09020001: return "Scripting_LoadFile_EvalErrors";
case 0x09020002: return "Scripting_LoadFile_OpenFailed";
case 0x09000001: return "Scripting_CallFunctionFailed";
case 0x09000002: return "Scripting_ConversionFailed";
case 0x09000003: return "Scripting_CreateObjectFailed";
case 0x09000004: return "Scripting_DefineConstantFailed";
case 0x09000005: return "Scripting_RegisterFunctionFailed";
case 0x09000006: return "Scripting_SetupFailed";
case 0x09000007: return "Scripting_TypeDoesNotExist";
case 0x0a000001: return "System_RequiredExtensionsMissing";
case 0x0a000002: return "System_SDLInitFailed";
case 0x0a000003: return "System_VmodeFailed";
case 0x0b000001: return "Xeromyces_XMLOpenFailed";
case 0x0b000002: return "Xeromyces_XMLParseError";
default: return "Unrecognised error";
}
@@ -259,33 +274,35 @@ void ThrowError(PSRETURN code)
case 0x01000001: throw PSERROR_CVFSFile_AlreadyLoaded(); break;
case 0x01000002: throw PSERROR_CVFSFile_InvalidBufferAccess(); break;
case 0x01000003: throw PSERROR_CVFSFile_LoadFailed(); break;
case 0x02000001: throw PSERROR_Error_InvalidError(); break;
case 0x03000001: throw PSERROR_File_InvalidType(); break;
case 0x03000002: throw PSERROR_File_InvalidVersion(); break;
case 0x03000003: throw PSERROR_File_OpenFailed(); break;
case 0x03000004: throw PSERROR_File_ReadFailed(); break;
case 0x03000005: throw PSERROR_File_UnexpectedEOF(); break;
case 0x03000006: throw PSERROR_File_WriteFailed(); break;
case 0x04000001: throw PSERROR_GUI_JSOpenFailed(); break;
case 0x05040001: throw PSERROR_Game_World_MapLoadFailed(); break;
case 0x06030001: throw PSERROR_I18n_Script_SetupFailed(); break;
case 0x07000001: throw PSERROR_Renderer_VBOFailed(); break;
case 0x08010001: throw PSERROR_Scripting_DefineType_AlreadyExists(); break;
case 0x08010002: throw PSERROR_Scripting_DefineType_CreationFailed(); break;
case 0x08020001: throw PSERROR_Scripting_LoadFile_EvalErrors(); break;
case 0x08020002: throw PSERROR_Scripting_LoadFile_OpenFailed(); break;
case 0x08000001: throw PSERROR_Scripting_CallFunctionFailed(); break;
case 0x08000002: throw PSERROR_Scripting_ConversionFailed(); break;
case 0x08000003: throw PSERROR_Scripting_CreateObjectFailed(); break;
case 0x08000004: throw PSERROR_Scripting_DefineConstantFailed(); break;
case 0x08000005: throw PSERROR_Scripting_RegisterFunctionFailed(); break;
case 0x08000006: throw PSERROR_Scripting_SetupFailed(); break;
case 0x08000007: throw PSERROR_Scripting_TypeDoesNotExist(); break;
case 0x09000001: throw PSERROR_System_RequiredExtensionsMissing(); break;
case 0x09000002: throw PSERROR_System_SDLInitFailed(); break;
case 0x09000003: throw PSERROR_System_VmodeFailed(); break;
case 0x0a000001: throw PSERROR_Xeromyces_XMLOpenFailed(); break;
case 0x0a000002: throw PSERROR_Xeromyces_XMLParseError(); break;
case 0x02000001: throw PSERROR_DllLoader_DllNotLoaded(); break;
case 0x02000002: throw PSERROR_DllLoader_SymbolNotFound(); break;
case 0x03000001: throw PSERROR_Error_InvalidError(); break;
case 0x04000001: throw PSERROR_File_InvalidType(); break;
case 0x04000002: throw PSERROR_File_InvalidVersion(); break;
case 0x04000003: throw PSERROR_File_OpenFailed(); break;
case 0x04000004: throw PSERROR_File_ReadFailed(); break;
case 0x04000005: throw PSERROR_File_UnexpectedEOF(); break;
case 0x04000006: throw PSERROR_File_WriteFailed(); break;
case 0x05000001: throw PSERROR_GUI_JSOpenFailed(); break;
case 0x06040001: throw PSERROR_Game_World_MapLoadFailed(); break;
case 0x07030001: throw PSERROR_I18n_Script_SetupFailed(); break;
case 0x08000001: throw PSERROR_Renderer_VBOFailed(); break;
case 0x09010001: throw PSERROR_Scripting_DefineType_AlreadyExists(); break;
case 0x09010002: throw PSERROR_Scripting_DefineType_CreationFailed(); break;
case 0x09020001: throw PSERROR_Scripting_LoadFile_EvalErrors(); break;
case 0x09020002: throw PSERROR_Scripting_LoadFile_OpenFailed(); break;
case 0x09000001: throw PSERROR_Scripting_CallFunctionFailed(); break;
case 0x09000002: throw PSERROR_Scripting_ConversionFailed(); break;
case 0x09000003: throw PSERROR_Scripting_CreateObjectFailed(); break;
case 0x09000004: throw PSERROR_Scripting_DefineConstantFailed(); break;
case 0x09000005: throw PSERROR_Scripting_RegisterFunctionFailed(); break;
case 0x09000006: throw PSERROR_Scripting_SetupFailed(); break;
case 0x09000007: throw PSERROR_Scripting_TypeDoesNotExist(); break;
case 0x0a000001: throw PSERROR_System_RequiredExtensionsMissing(); break;
case 0x0a000002: throw PSERROR_System_SDLInitFailed(); break;
case 0x0a000003: throw PSERROR_System_VmodeFailed(); break;
case 0x0b000001: throw PSERROR_Xeromyces_XMLOpenFailed(); break;
case 0x0b000002: throw PSERROR_Xeromyces_XMLParseError(); break;
default: throw PSERROR_Error_InvalidError(); // Hmm...
}
+1
View File
@@ -27,6 +27,7 @@
#include "renderer/Renderer.h"
#include "renderer/RenderModifiers.h"
#include <boost/weak_ptr.hpp>
#define LOG_CATEGORY "graphics"