improved update frequency and accuracy of progress bar (by splitting up more init functions).
also add thunk mechanism to ease binding to member functions; finally, added instrumentation to measure how long functions really take This was SVN commit r2038.
This commit is contained in:
parent
9feaba2f36
commit
f19d8dafee
@ -17,6 +17,7 @@
|
||||
#include "Hotkey.h"
|
||||
#include "ConfigDB.h"
|
||||
#include "Loader.h"
|
||||
#include "LoaderThunks.h"
|
||||
|
||||
#include "Quaternion.h"
|
||||
#include "Unit.h"
|
||||
@ -94,33 +95,24 @@ void CGameView::Initialize(CGameAttributes *pAttribs)
|
||||
if( ( m_ViewSnapSmoothness < 0.0f ) || ( m_ViewSnapSmoothness > 1.0f ) ) m_ViewSnapSmoothness = 0.02f;
|
||||
|
||||
#undef getViewParameter
|
||||
|
||||
InitResources();
|
||||
}
|
||||
|
||||
struct ThunkParams
|
||||
{
|
||||
CGameView* const this_;
|
||||
CGameAttributes* const pAttribs;
|
||||
ThunkParams(CGameView* this__, CGameAttributes* pAttribs_)
|
||||
: this_(this__), pAttribs(pAttribs_) {}
|
||||
};
|
||||
|
||||
static int LoadThunk(void* param, double time_left)
|
||||
{
|
||||
const ThunkParams* p = (const ThunkParams*)param;
|
||||
CGameView* const this_ = p->this_;
|
||||
CGameAttributes* const pAttribs = p->pAttribs;
|
||||
|
||||
this_->Initialize(pAttribs);
|
||||
delete p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void CGameView::RegisterInit(CGameAttributes *pAttribs)
|
||||
{
|
||||
void* param = new ThunkParams(this, pAttribs);
|
||||
THROW_ERR(LDR_Register(LoadThunk, param, L"CGameView", 1000));
|
||||
// CGameView init
|
||||
RegMemFun1(this, &CGameView::Initialize, pAttribs, L"CGameView init", 1);
|
||||
|
||||
// previously done by CGameView::InitResources
|
||||
RegMemFun(g_TexMan.GetSingletonPtr(), &CTextureManager::LoadTerrainTextures, L"LoadTerrainTextures", 17);
|
||||
RegMemFun(g_ObjMan.GetSingletonPtr(), &CObjectManager::LoadObjects, L"LoadObjects", 1063);
|
||||
RegMemFun(g_Renderer.GetSingletonPtr(), &CRenderer::LoadAlphaMaps, L"LoadAlphaMaps", 36);
|
||||
}
|
||||
|
||||
|
||||
@ -192,15 +184,6 @@ void CGameView::RenderNoCull()
|
||||
}
|
||||
}
|
||||
|
||||
void CGameView::InitResources()
|
||||
{
|
||||
TIMER(CGameView__InitResources);
|
||||
|
||||
g_TexMan.LoadTerrainTextures();
|
||||
g_ObjMan.LoadObjects();
|
||||
|
||||
g_Renderer.LoadAlphaMaps();
|
||||
}
|
||||
|
||||
void CGameView::UnloadResources()
|
||||
{
|
||||
|
@ -15,22 +15,25 @@
|
||||
#include "TextureManager.h"
|
||||
|
||||
#include "timer.h"
|
||||
#include "Loader.h"
|
||||
#include "LoaderThunks.h"
|
||||
|
||||
// CMapReader constructor: nothing to do at the minute
|
||||
CMapReader::CMapReader()
|
||||
{
|
||||
}
|
||||
|
||||
// LoadMap: try to load the map from given file; reinitialise the scene to new data if successful
|
||||
void CMapReader::LoadMap(const char* filename, CTerrain *pTerrain, CUnitManager *pUnitMan, CLightEnv *pLightEnv)
|
||||
{
|
||||
TIMER(__CMapReader__LoadMap);
|
||||
|
||||
CFileUnpacker unpacker;
|
||||
{
|
||||
TIMER(____CMapReader__LoadMap__read);
|
||||
unpacker.Read(filename,"PSMP");
|
||||
}
|
||||
// LoadMap: try to load the map from given file; reinitialise the scene to new data if successful
|
||||
void CMapReader::LoadMap(const char* filename, CTerrain *pTerrain_, CUnitManager *pUnitMan_, CLightEnv *pLightEnv_)
|
||||
{
|
||||
// latch parameters (held until DelayedLoadFinished)
|
||||
pTerrain = pTerrain_;
|
||||
pUnitMan = pUnitMan_;
|
||||
pLightEnv = pLightEnv_;
|
||||
|
||||
// [25ms]
|
||||
unpacker.Read(filename,"PSMP");
|
||||
|
||||
// check version
|
||||
if (unpacker.GetVersion()<FILE_READ_VERSION) {
|
||||
@ -38,34 +41,34 @@ void CMapReader::LoadMap(const char* filename, CTerrain *pTerrain, CUnitManager
|
||||
}
|
||||
|
||||
// unpack the data
|
||||
UnpackMap(unpacker);
|
||||
RegMemFun(this, &CMapReader::UnpackMap, L"CMapReader::UnpackMap", 691);
|
||||
|
||||
// apply data to the world
|
||||
ApplyData(unpacker, pTerrain, pUnitMan, pLightEnv);
|
||||
RegMemFun(this, &CMapReader::ApplyData, L"CMapReader::ApplyData", 415);
|
||||
|
||||
if (unpacker.GetVersion()>=3) {
|
||||
// read the corresponding XML file
|
||||
CStr filename_xml (filename);
|
||||
filename_xml = filename;
|
||||
filename_xml = filename_xml.Left(filename_xml.Length()-4) + ".xml";
|
||||
ReadXML(filename_xml);
|
||||
RegMemFun(this, &CMapReader::ReadXML, L"CMapReader::ReadXML", 1320);
|
||||
}
|
||||
|
||||
RegMemFun(this, &CMapReader::DelayLoadFinished, L"CMapReader::DelayLoadFinished", 3);
|
||||
}
|
||||
|
||||
// UnpackMap: unpack the given data from the raw data stream into local variables
|
||||
void CMapReader::UnpackMap(CFileUnpacker& unpacker)
|
||||
void CMapReader::UnpackMap()
|
||||
{
|
||||
TIMER(____CMapReader__UnpackMap);
|
||||
|
||||
// now unpack everything into local data
|
||||
UnpackTerrain(unpacker);
|
||||
UnpackObjects(unpacker);
|
||||
UnpackTerrain();
|
||||
UnpackObjects();
|
||||
if (unpacker.GetVersion()>=2) {
|
||||
UnpackLightEnv(unpacker);
|
||||
UnpackLightEnv();
|
||||
}
|
||||
}
|
||||
|
||||
// UnpackLightEnv: unpack lighting parameters from input stream
|
||||
void CMapReader::UnpackLightEnv(CFileUnpacker& unpacker)
|
||||
void CMapReader::UnpackLightEnv()
|
||||
{
|
||||
unpacker.UnpackRaw(&m_LightEnv.m_SunColor,sizeof(m_LightEnv.m_SunColor));
|
||||
unpacker.UnpackRaw(&m_LightEnv.m_Elevation,sizeof(m_LightEnv.m_Elevation));
|
||||
@ -76,7 +79,7 @@ void CMapReader::UnpackLightEnv(CFileUnpacker& unpacker)
|
||||
}
|
||||
|
||||
// UnpackObjects: unpack world objects from input stream
|
||||
void CMapReader::UnpackObjects(CFileUnpacker& unpacker)
|
||||
void CMapReader::UnpackObjects()
|
||||
{
|
||||
// unpack object types
|
||||
u32 numObjTypes;
|
||||
@ -95,7 +98,7 @@ void CMapReader::UnpackObjects(CFileUnpacker& unpacker)
|
||||
|
||||
// UnpackTerrain: unpack the terrain from the end of the input data stream
|
||||
// - data: map size, heightmap, list of textures used by map, texture tile assignments
|
||||
void CMapReader::UnpackTerrain(CFileUnpacker& unpacker)
|
||||
void CMapReader::UnpackTerrain()
|
||||
{
|
||||
// unpack map size
|
||||
unpacker.UnpackRaw(&m_MapSize,sizeof(m_MapSize));
|
||||
@ -132,10 +135,8 @@ void CMapReader::UnpackTerrain(CFileUnpacker& unpacker)
|
||||
}
|
||||
|
||||
// ApplyData: take all the input data, and rebuild the scene from it
|
||||
void CMapReader::ApplyData(CFileUnpacker& unpacker, CTerrain *pTerrain, CUnitManager *pUnitMan, CLightEnv *pLightEnv)
|
||||
void CMapReader::ApplyData()
|
||||
{
|
||||
TIMER(____CMapReader__ApplyData);
|
||||
|
||||
// initialise the terrain
|
||||
pTerrain->Initialize(m_MapSize,&m_Heightmap[0]);
|
||||
|
||||
@ -200,21 +201,19 @@ TIMER(____CMapReader__ApplyData);
|
||||
}
|
||||
|
||||
|
||||
void CMapReader::ReadXML(const char* filename)
|
||||
void CMapReader::ReadXML()
|
||||
{
|
||||
TIMER(____CMapReader__ReadXML);
|
||||
|
||||
#ifdef SCED
|
||||
// HACK: ScEd uses absolute filenames, not VFS paths. I can't be bothered
|
||||
// to make Xeromyces work with non-VFS, so just cheat:
|
||||
CStr filename_vfs (filename);
|
||||
CStr filename_vfs (filename_xml);
|
||||
filename_vfs = filename_vfs.substr(filename_vfs.ReverseFind("\\mods\\official\\") + 15);
|
||||
filename_vfs.Replace("\\", "/");
|
||||
filename = filename_vfs;
|
||||
filename_xml = filename_vfs;
|
||||
#endif
|
||||
|
||||
CXeromyces XeroFile;
|
||||
if (XeroFile.Load(filename) != PSRETURN_OK)
|
||||
if (XeroFile.Load(filename_xml) != PSRETURN_OK)
|
||||
throw CFileUnpacker::CFileReadError();
|
||||
|
||||
// Define all the elements and attributes used in the XML file
|
||||
@ -307,3 +306,10 @@ void CMapReader::ReadXML(const char* filename)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CMapReader::DelayLoadFinished()
|
||||
{
|
||||
// we were dynamically allocated by CWorld::Initialize
|
||||
delete this;
|
||||
}
|
@ -22,19 +22,22 @@ public:
|
||||
|
||||
private:
|
||||
// UnpackMap: unpack the given data from the raw data stream into local variables
|
||||
void UnpackMap(CFileUnpacker& unpacker);
|
||||
void UnpackMap();
|
||||
// UnpackTerrain: unpack the terrain from the input stream
|
||||
void UnpackTerrain(CFileUnpacker& unpacker);
|
||||
void UnpackTerrain();
|
||||
// UnpackObjects: unpack world objects from the input stream
|
||||
void UnpackObjects(CFileUnpacker& unpacker);
|
||||
void UnpackObjects();
|
||||
// UnpackObjects: unpack lighting parameters from the input stream
|
||||
void UnpackLightEnv(CFileUnpacker& unpacker);
|
||||
void UnpackLightEnv();
|
||||
|
||||
// ApplyData: take all the input data, and rebuild the scene from it
|
||||
void ApplyData(CFileUnpacker& unpacker, CTerrain *pTerrain, CUnitManager *pUnitMan, CLightEnv *pLightEnv);
|
||||
void ApplyData();
|
||||
|
||||
// ReadXML: read some other data (entities, etc) in XML format
|
||||
void ReadXML(const char* filename);
|
||||
void ReadXML();
|
||||
|
||||
// clean up everything used during delayed load
|
||||
void DelayLoadFinished();
|
||||
|
||||
// size of map
|
||||
u32 m_MapSize;
|
||||
@ -50,6 +53,13 @@ private:
|
||||
std::vector<SObjectDesc> m_Objects;
|
||||
// lightenv stored in file
|
||||
CLightEnv m_LightEnv;
|
||||
|
||||
// state latched by LoadMap and held until DelayedLoadFinished
|
||||
CFileUnpacker unpacker;
|
||||
CTerrain *pTerrain;
|
||||
CUnitManager *pUnitMan;
|
||||
CLightEnv *pLightEnv;
|
||||
CStr filename_xml;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -170,8 +170,6 @@ void CObjectManager::DeleteObjectBase(CObjectBase* base)
|
||||
|
||||
void CObjectManager::LoadObjects()
|
||||
{
|
||||
TIMER(__CObjectManager__LoadObjects);
|
||||
|
||||
AddObjectType("");
|
||||
|
||||
CStr root ("art/actors");
|
||||
|
@ -137,8 +137,6 @@ void CTextureManager::BuildTerrainTypes()
|
||||
|
||||
void CTextureManager::LoadTerrainTextures()
|
||||
{
|
||||
TIMER(__CTextureManager__LoadTerrainTextures);
|
||||
|
||||
// find all the terrain types by directory name
|
||||
BuildTerrainTypes();
|
||||
|
||||
|
@ -955,7 +955,8 @@ static int ProgressiveLoad()
|
||||
// no load active => no-op (skip code below)
|
||||
case 1:
|
||||
return 1;
|
||||
// current task isn't complete (we don't care about this distinction)
|
||||
// current task didn't complete. we only care about this insofar as the
|
||||
// load process is therefore not yet finished.
|
||||
case ERR_TIMED_OUT:
|
||||
break;
|
||||
// just finished loading
|
||||
@ -1161,15 +1162,6 @@ sle(11340106);
|
||||
if(oglHaveExtension("WGL_EXT_swap_control"))
|
||||
wglSwapIntervalEXT(g_VSync? 1 : 0);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
u64 CURTSC=rdtsc();
|
||||
debug_out(
|
||||
"----------------------------------------\n"\
|
||||
"low-level ready (elapsed = %f ms)\n"\
|
||||
"----------------------------------------\n", (CURTSC-PREVTSC)/2e9*1e3);
|
||||
PREVTSC=CURTSC;
|
||||
#endif
|
||||
|
||||
MICROLOG(L"init ps");
|
||||
InitPs();
|
||||
|
||||
@ -1256,16 +1248,11 @@ TIMER(init_after_InitRenderer);
|
||||
|
||||
g_Console->RegisterFunc(Testing, L"Testing");
|
||||
|
||||
#ifdef _MSC_VER
|
||||
{
|
||||
u64 CURTSC=rdtsc();
|
||||
debug_out(
|
||||
"----------------------------------------\n"\
|
||||
"READY (elapsed = %f ms)\n"\
|
||||
"----------------------------------------\n", (CURTSC-PREVTSC)/2e9*1e3);
|
||||
PREVTSC=CURTSC;
|
||||
}
|
||||
#endif
|
||||
"----------------------------------------\n"
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
@ -22,13 +22,19 @@ static int progress_percent = 0;
|
||||
// set by LDR_EndRegistering; used for progress % calculation. may be 0.
|
||||
static double total_estimated_duration;
|
||||
|
||||
// used by LDR_ProgressiveLoad to add up the duration of requests that
|
||||
// time out by themselves (and therefore may be split across multiple calls)
|
||||
static double request_duration;
|
||||
|
||||
// main purpose is to indicate whether a load is in progress, so that
|
||||
// LDR_ProgressiveLoad can return 0 iff loading just completed.
|
||||
// the REGISTERING state allows us to detect 2 simultaneous loads (bogus).
|
||||
// the REGISTERING state allows us to detect 2 simultaneous loads (bogus);
|
||||
// FIRST_LOAD is used to skip the first timeslice (see LDR_ProgressiveLoad).
|
||||
static enum
|
||||
{
|
||||
IDLE,
|
||||
REGISTERING,
|
||||
FIRST_LOAD,
|
||||
LOADING,
|
||||
}
|
||||
state = IDLE;
|
||||
@ -122,9 +128,10 @@ int LDR_EndRegistering()
|
||||
if(load_requests.empty())
|
||||
debug_warn("LDR_EndRegistering: no LoadRequests queued");
|
||||
|
||||
state = LOADING;
|
||||
state = FIRST_LOAD;
|
||||
progress_percent = 0;
|
||||
total_estimated_duration = std::accumulate(load_requests.begin(), load_requests.end(), 0.0, DurationAdder());
|
||||
request_duration = 0.0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -191,21 +198,36 @@ static bool HaveTimeForNextTask(double time_left, double time_budget, int estima
|
||||
int LDR_ProgressiveLoad(double time_budget, wchar_t* description_,
|
||||
size_t max_chars, int* progress_percent_)
|
||||
{
|
||||
int ret; // single exit; this is returned
|
||||
double time_left = time_budget;
|
||||
|
||||
// don't do any work the first call so that a graphics update
|
||||
// happens before the first (probably lengthy) timeslice.
|
||||
if(state == FIRST_LOAD)
|
||||
{
|
||||
state = LOADING;
|
||||
ret = ERR_TIMED_OUT; // make caller think we did something
|
||||
goto done;
|
||||
}
|
||||
|
||||
// we're called unconditionally from the main loop, so this isn't
|
||||
// an error; there is just nothing to do.
|
||||
if(state != LOADING)
|
||||
return 1;
|
||||
|
||||
const double end_time = get_time() + time_budget;
|
||||
int ret; // single exit; this is returned
|
||||
|
||||
while(!load_requests.empty())
|
||||
{
|
||||
double time_left = end_time - get_time();
|
||||
|
||||
// do actual work of loading
|
||||
const LoadRequest& lr = load_requests.front();
|
||||
const double t0 = get_time();
|
||||
ret = lr.func(lr.param, time_left);
|
||||
const double elapsed_time = get_time() - t0;
|
||||
|
||||
// time accounting
|
||||
time_left -= elapsed_time;
|
||||
request_duration += elapsed_time;
|
||||
wcscpy_s(description_, max_chars, lr.description); // HACK, used below
|
||||
|
||||
// .. either finished entirely, or failed => remove from queue
|
||||
if(ret != ERR_TIMED_OUT)
|
||||
load_requests.pop_front();
|
||||
@ -224,12 +246,13 @@ int LDR_ProgressiveLoad(double time_budget, wchar_t* description_,
|
||||
progress_percent += (int)(fraction * 100.0);
|
||||
assert(0 <= progress_percent && progress_percent <= 100);
|
||||
}
|
||||
debug_out("LOADER: completed %ls in %f ms\n", description_, elapsed_time*1e3);
|
||||
request_duration = 0.0;
|
||||
|
||||
// check if we're out of time; take into account next task length.
|
||||
// note: do this at the end of the loop to make sure there's
|
||||
// progress even if the timer is low-resolution (=> time_left = 0).
|
||||
time_left = end_time - get_time();
|
||||
if(!HaveTimeForNextTask(time_left, time_budget, lr.estimated_duration_ms))
|
||||
// if(!HaveTimeForNextTask(time_left, time_budget, lr.estimated_duration_ms))
|
||||
{
|
||||
ret = ERR_TIMED_OUT;
|
||||
goto done;
|
||||
@ -240,6 +263,7 @@ int LDR_ProgressiveLoad(double time_budget, wchar_t* description_,
|
||||
state = IDLE;
|
||||
ret = 0;
|
||||
|
||||
|
||||
// set output params (there are several return points above)
|
||||
done:
|
||||
*progress_percent_ = progress_percent;
|
||||
|
51
source/ps/LoaderThunks.h
Normal file
51
source/ps/LoaderThunks.h
Normal file
@ -0,0 +1,51 @@
|
||||
|
||||
template<class T> struct MemFun_t
|
||||
{
|
||||
T* const this_;
|
||||
void(T::*func)(void);
|
||||
MemFun_t(T* this__, void(T::*func_)(void))
|
||||
: this_(this__), func(func_) {}
|
||||
};
|
||||
|
||||
template<class T> static int MemFunThunk(void* param, double time_left)
|
||||
{
|
||||
MemFun_t<T>* const mf = (MemFun_t<T>*)param;
|
||||
(mf->this_->*mf->func)();
|
||||
delete mf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<class T> void RegMemFun(T* this_, void(T::*func)(void),
|
||||
const wchar_t* description, int estimated_duration_ms)
|
||||
{
|
||||
void* param = new MemFun_t<T>(this_, func);
|
||||
THROW_ERR(LDR_Register(MemFunThunk<T>, param, description, estimated_duration_ms));
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
template<class T, class Arg> struct MemFun1_t
|
||||
{
|
||||
T* const this_;
|
||||
Arg arg;
|
||||
void(T::*func)(Arg);
|
||||
MemFun1_t(T* this__, void(T::*func_)(Arg), Arg arg_)
|
||||
: this_(this__), func(func_), arg(arg_) {}
|
||||
};
|
||||
|
||||
template<class T, class Arg> static int MemFun1Thunk(void* param, double time_left)
|
||||
{
|
||||
MemFun1_t<T, Arg>* const mf = (MemFun1_t<T, Arg>*)param;
|
||||
(mf->this_->*mf->func)(mf->arg);
|
||||
delete mf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<class T, class Arg> void RegMemFun1(T* this_, void(T::*func)(Arg), Arg arg,
|
||||
const wchar_t* description, int estimated_duration_ms)
|
||||
{
|
||||
void* param = new MemFun1_t<T, Arg>(this_, func, arg);
|
||||
THROW_ERR(LDR_Register(MemFun1Thunk<T, Arg>, param, description, estimated_duration_ms));
|
||||
}
|
@ -13,6 +13,7 @@
|
||||
#include "EntityManager.h"
|
||||
#include "timer.h"
|
||||
#include "Loader.h"
|
||||
#include "LoaderThunks.h"
|
||||
|
||||
#define LOG_CATEGORY "world"
|
||||
|
||||
@ -20,10 +21,8 @@ CLightEnv g_LightEnv;
|
||||
|
||||
void CWorld::Initialize(CGameAttributes *pAttribs)
|
||||
{
|
||||
TIMER(CWorld__Initialize);
|
||||
|
||||
// TODO: Find a better way of handling these global things
|
||||
ONCE(g_EntityTemplateCollection.loadTemplates());
|
||||
ONCE(RegMemFun(CBaseEntityCollection::GetSingletonPtr(), &CBaseEntityCollection::loadTemplates, L"LoadTemplates", 960));
|
||||
|
||||
// Load the map, if one was specified
|
||||
if (pAttribs->m_MapFile.Length())
|
||||
@ -32,39 +31,23 @@ void CWorld::Initialize(CGameAttributes *pAttribs)
|
||||
|
||||
mapfilename += (CStr)pAttribs->m_MapFile;
|
||||
|
||||
CMapReader* reader = 0;
|
||||
try {
|
||||
CMapReader reader;
|
||||
reader.LoadMap(mapfilename, &m_Terrain, &m_UnitManager, &g_LightEnv);
|
||||
reader = new CMapReader;
|
||||
reader->LoadMap(mapfilename, &m_Terrain, &m_UnitManager, &g_LightEnv);
|
||||
// fails immediately, or registers for delay loading
|
||||
} catch (...) {
|
||||
delete reader;
|
||||
LOG(ERROR, LOG_CATEGORY, "Failed to load map %s", mapfilename.c_str());
|
||||
throw PSERROR_Game_World_MapLoadFailed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ThunkParams
|
||||
{
|
||||
CWorld* const this_;
|
||||
CGameAttributes* const pAttribs;
|
||||
ThunkParams(CWorld* this__, CGameAttributes* pAttribs_)
|
||||
: this_(this__), pAttribs(pAttribs_) {}
|
||||
};
|
||||
|
||||
static int LoadThunk(void* param, double time_left)
|
||||
{
|
||||
const ThunkParams* p = (const ThunkParams*)param;
|
||||
CWorld* const this_ = p->this_;
|
||||
CGameAttributes* const pAttribs = p->pAttribs;
|
||||
|
||||
this_->Initialize(pAttribs);
|
||||
delete p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CWorld::RegisterInit(CGameAttributes *pAttribs)
|
||||
{
|
||||
void* param = new ThunkParams(this, pAttribs);
|
||||
THROW_ERR(LDR_Register(LoadThunk, param, L"CWorld", 1000));
|
||||
Initialize(pAttribs);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1153,10 +1153,8 @@ inline void CopyTriple(unsigned char* dst,const unsigned char* src)
|
||||
// LoadAlphaMaps: load the 14 default alpha maps, pack them into one composite texture and
|
||||
// calculate the coordinate of each alphamap within this packed texture .. need to add
|
||||
// validation that all maps are the same size
|
||||
bool CRenderer::LoadAlphaMaps()
|
||||
void CRenderer::LoadAlphaMaps()
|
||||
{
|
||||
TIMER(__CRenderer__LoadAlphaMaps);
|
||||
|
||||
Handle textures[NumAlphaMaps];
|
||||
|
||||
|
||||
@ -1183,7 +1181,7 @@ bool CRenderer::LoadAlphaMaps()
|
||||
for (i=0;i<NumAlphaMaps;i++) {
|
||||
textures[i]=tex_load(fnames[i]);
|
||||
if (textures[i] <= 0) {
|
||||
return false;
|
||||
throw textures[i]; // FIXTHROW
|
||||
}
|
||||
}
|
||||
|
||||
@ -1253,8 +1251,6 @@ bool CRenderer::LoadAlphaMaps()
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
|
||||
|
||||
delete[] data;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -207,7 +207,7 @@ public:
|
||||
bool IsTextureTransparent(CTexture* texture);
|
||||
|
||||
// load the default set of alphamaps; return false if any alphamap fails to load, true otherwise
|
||||
bool LoadAlphaMaps();
|
||||
void LoadAlphaMaps();
|
||||
|
||||
void UnloadAlphaMaps();
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "Unit.h"
|
||||
#include "Model.h"
|
||||
#include "Loader.h"
|
||||
#include "LoaderThunks.h"
|
||||
|
||||
#include "gui/CGUI.h"
|
||||
|
||||
@ -39,29 +40,9 @@ void CSimulation::Initialize(CGameAttributes *pAttribs)
|
||||
}
|
||||
|
||||
|
||||
struct ThunkParams
|
||||
{
|
||||
CSimulation* const this_;
|
||||
CGameAttributes* const pAttribs;
|
||||
ThunkParams(CSimulation* this__, CGameAttributes* pAttribs_)
|
||||
: this_(this__), pAttribs(pAttribs_) {}
|
||||
};
|
||||
|
||||
static int LoadThunk(void* param, double time_left)
|
||||
{
|
||||
const ThunkParams* p = (const ThunkParams*)param;
|
||||
CSimulation* const this_ = p->this_;
|
||||
CGameAttributes* const pAttribs = p->pAttribs;
|
||||
|
||||
this_->Initialize(pAttribs);
|
||||
delete p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CSimulation::RegisterInit(CGameAttributes *pAttribs)
|
||||
{
|
||||
void* param = new ThunkParams(this, pAttribs);
|
||||
THROW_ERR(LDR_Register(LoadThunk, param, L"CSimulation", 1000));
|
||||
RegMemFun1(this, &CSimulation::Initialize, pAttribs, L"CSimulation", 31);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user