rough but functional loading progress bar support.
numerous TODOs remaining - initial update instead of only after completing first job; fix GUI overdraw issue; decrease granularity (currently only 3 updates) This was SVN commit r2033.
This commit is contained in:
parent
5e3b0f06ec
commit
6d792365aa
@ -36,8 +36,16 @@
|
||||
<object type="button" name="loading_screen_titlebar_text" size="15%+54 4 85%-54 32" absolute="false" font="prospero18" z="165" text_align="center" text_valign="center" hidden="false"/>
|
||||
|
||||
<!-- progress bar -->
|
||||
<object type="button" name="loading_screen_progress_bar_text" size="0%+32 100%-205 100%-32 100%-185" font="tahoma14" textcolor="0 0 0" text_align="center" text_valign="center" z="165" hidden="false"/>
|
||||
<object type="progressbar" name="loading_screen_progress_bar" style="blue_bar_outlined" size="0%+32 100%-185 100%-32 100%-160" z="165" hidden="false"/>
|
||||
<object type="button" name="loading_screen_progress_bar_text" size="0%+32 100%-205 100%-32 100%-185" font="tahoma14" textcolor="0 0 0" text_align="center" text_valign="center" z="165" hidden="false">
|
||||
<action on="Progress">
|
||||
this.caption = g_LoadDescription;
|
||||
</action>
|
||||
</object>
|
||||
<object type="progressbar" name="loading_screen_progress_bar" style="blue_bar_outlined" size="0%+32 100%-185 100%-32 100%-160" z="165" hidden="false">
|
||||
<action on="Progress">
|
||||
this.caption = g_Progress;
|
||||
</action>
|
||||
</object>
|
||||
|
||||
<!-- concept image -->
|
||||
<object type="image" name="loading_screen_background_concept" sprite="black_bkg" size="32 32 33.3008%+32 88.9323%+32" z="110" hidden="false" />
|
||||
|
@ -42,24 +42,43 @@ function startLoadingScreen()
|
||||
getGUIObjectByName("loading_screen_tip").caption = "Wise man once say ...\nHe who thinks slow, he act in haste, be rash and quick and foolish. But he that thinks too much, acts too slowly. The stupid always win, Commandersan. Remember that. You are tiny grasshopper.";
|
||||
|
||||
// Begin game session.
|
||||
setTimeout( loadSession, 200 );
|
||||
// setTimeout( loadSession, 200 );
|
||||
startGame(); // new version returns quickly; we will hit the main loop
|
||||
// occasionally, so need for evil timeout hack
|
||||
}
|
||||
|
||||
// ====================================================================
|
||||
|
||||
function loadSession()
|
||||
{
|
||||
if (! startGame())
|
||||
{
|
||||
// Failed to start the game; go back to the main menu. TODO: display an error message.
|
||||
GUIObjectHide("loading_screen");
|
||||
GUIObjectUnhide("PREGAME_GUI");
|
||||
// Show an error message
|
||||
btCaptions = new Array("OK");
|
||||
btCode = new Array("");
|
||||
messageBox(400, 200, "The game could not be started with the given parameters. You probably have entered an invalid map name.", "Error", 0, btCaptions, btCode);
|
||||
}
|
||||
//function loadSession()
|
||||
//{
|
||||
// if (! startGame())
|
||||
// {
|
||||
// // Failed to start the game; go back to the main menu. TODO: display an error message.
|
||||
// GUIObjectHide("loading_screen");
|
||||
// GUIObjectUnhide("PREGAME_GUI");
|
||||
// // Show an error message
|
||||
// btCaptions = new Array("OK");
|
||||
// btCode = new Array("");
|
||||
// messageBox(400, 200, "The game could not be started with the given parameters. You probably have entered an invalid map name.", "Error", 0, btCaptions, btCode);
|
||||
// }
|
||||
//
|
||||
// // Create resource pools for each player, etc.
|
||||
// setupSession();
|
||||
//
|
||||
// FlipGUI(GUIType);
|
||||
//
|
||||
// // Select session peace track.
|
||||
// curr_session_playlist_1 = newRandomSound("music", "peace");
|
||||
// // Fade out main theme and fade in session theme.
|
||||
// CrossFade(curr_music, curr_session_playlist_1, 0.0001);
|
||||
//
|
||||
// // Switch GUI from main menu to game session.
|
||||
// GUIObjectHide("loading_screen");
|
||||
// GUIObjectUnhide("SESSION_GUI");
|
||||
//}
|
||||
|
||||
function reallyStartGame()
|
||||
{
|
||||
// Create resource pools for each player, etc.
|
||||
setupSession();
|
||||
|
||||
@ -68,7 +87,9 @@ function loadSession()
|
||||
// Select session peace track.
|
||||
curr_session_playlist_1 = newRandomSound("music", "peace");
|
||||
// Fade out main theme and fade in session theme.
|
||||
CrossFade(curr_music, curr_session_playlist_1, 0.0001);
|
||||
CrossFade(curr_music, curr_session_playlist_1, 0.1);
|
||||
// janwas: greatly accelerate this timesink;
|
||||
// will be replaced soon by native version that doesn't block.
|
||||
|
||||
// Switch GUI from main menu to game session.
|
||||
GUIObjectHide("loading_screen");
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "Pyrogenesis.h"
|
||||
#include "Hotkey.h"
|
||||
#include "ConfigDB.h"
|
||||
#include "Loader.h"
|
||||
|
||||
#include "Quaternion.h"
|
||||
#include "Unit.h"
|
||||
@ -69,6 +70,7 @@ CGameView::~CGameView()
|
||||
UnloadResources();
|
||||
}
|
||||
|
||||
|
||||
void CGameView::Initialize(CGameAttributes *pAttribs)
|
||||
{
|
||||
CConfigValue* cfg;
|
||||
@ -96,6 +98,32 @@ void CGameView::Initialize(CGameAttributes *pAttribs)
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
void CGameView::Render()
|
||||
{
|
||||
g_Renderer.SetCamera(m_Camera);
|
||||
|
@ -60,8 +60,9 @@ public:
|
||||
CGameView(CGame *pGame);
|
||||
~CGameView();
|
||||
|
||||
void RegisterInit(CGameAttributes *pAttribs);
|
||||
void Initialize(CGameAttributes *pGameAttributes);
|
||||
|
||||
|
||||
// Update: Update all the view information (i.e. rotate camera, scroll,
|
||||
// whatever). This will *not* change any World information - only the
|
||||
// *presentation*
|
||||
|
@ -118,6 +118,17 @@ STMT(\
|
||||
)
|
||||
#endif
|
||||
|
||||
#define THROW_ERR(func)\
|
||||
STMT(\
|
||||
int err__ = (int)((func) & UINT_MAX);\
|
||||
if(err__ < 0)\
|
||||
{\
|
||||
assert(0 && "FYI: CHECK_ERR reports that a function failed."\
|
||||
"feel free to ignore or suppress this warning.");\
|
||||
throw err__;\
|
||||
}\
|
||||
)
|
||||
|
||||
|
||||
|
||||
// useful because VC6 may return 0 on failure, instead of throwing.
|
||||
|
@ -26,8 +26,8 @@
|
||||
#endif
|
||||
#include "lib/res/cursor.h"
|
||||
|
||||
#include "ps/Loader.h"
|
||||
#include "ps/Font.h"
|
||||
|
||||
#include "ps/CConsole.h"
|
||||
|
||||
#include "ps/Game.h"
|
||||
@ -53,6 +53,7 @@
|
||||
#include "EntityManager.h"
|
||||
#include "PathfindEngine.h"
|
||||
#include "Scheduler.h"
|
||||
#include "StringConvert.h"
|
||||
|
||||
#include "scripting/ScriptingHost.h"
|
||||
#include "scripting/JSInterface_Entity.h"
|
||||
@ -481,7 +482,7 @@ static void Render()
|
||||
|
||||
oglCheck();
|
||||
|
||||
if (g_Game)
|
||||
if (g_Game && g_Game->IsGameStarted())
|
||||
{
|
||||
g_Game->GetView()->Render();
|
||||
|
||||
@ -943,6 +944,45 @@ TIMER(InitRenderer)
|
||||
g_Renderer.SetViewport(vp);
|
||||
}
|
||||
|
||||
|
||||
static int ProgressiveLoad()
|
||||
{
|
||||
wchar_t description[100];
|
||||
int progress_percent;
|
||||
int ret = LDR_ProgressiveLoad(100e-3, description, ARRAY_SIZE(description), &progress_percent);
|
||||
switch(ret)
|
||||
{
|
||||
// no load active => no-op (skip code below)
|
||||
case 1:
|
||||
return 1;
|
||||
// current task isn't complete (we don't care about this distinction)
|
||||
case ERR_TIMED_OUT:
|
||||
break;
|
||||
// just finished loading
|
||||
case 0:
|
||||
g_Game->ReallyStartGame();
|
||||
wcscpy_s(description, ARRAY_SIZE(description), L"Game is starting..");
|
||||
// LDR_ProgressiveLoad returns L""; set to valid text to
|
||||
// avoid problems in converting to JSString
|
||||
break;
|
||||
// error!
|
||||
default:
|
||||
CHECK_ERR(ret);
|
||||
// can't do this above due to legit ERR_TIMED_OUT
|
||||
break;
|
||||
}
|
||||
|
||||
// display progress / description in loading screen
|
||||
CStrW i18n_description = translate(description);
|
||||
JSString* js_desc = StringConvert::wstring_to_jsstring(g_ScriptingHost.getContext(), i18n_description);
|
||||
g_ScriptingHost.SetGlobal("g_Progress", INT_TO_JSVAL(progress_percent));
|
||||
g_ScriptingHost.SetGlobal("g_LoadDescription", STRING_TO_JSVAL(js_desc));
|
||||
g_GUI.SendEventToAll("progress");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
u64 PREVTSC;
|
||||
|
||||
static void Shutdown()
|
||||
@ -1227,6 +1267,9 @@ PREVTSC=CURTSC;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
static void Frame()
|
||||
@ -1244,11 +1287,11 @@ static void Frame()
|
||||
assert(TimeSinceLastFrame >= 0.0f);
|
||||
|
||||
MICROLOG(L"reload files");
|
||||
|
||||
res_reload_changed_files();
|
||||
|
||||
MICROLOG(L"input");
|
||||
ProgressiveLoad();
|
||||
|
||||
MICROLOG(L"input");
|
||||
in_get_events();
|
||||
g_SessionManager.Poll();
|
||||
|
||||
@ -1259,7 +1302,7 @@ static void Frame()
|
||||
if (g_Game && g_Game->IsGameStarted())
|
||||
{
|
||||
g_Game->Update(TimeSinceLastFrame);
|
||||
|
||||
|
||||
if (!g_FixedFrameTiming)
|
||||
g_Game->GetView()->Update(float(TimeSinceLastFrame));
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "gui/CGUI.h"
|
||||
#endif
|
||||
#include "timer.h"
|
||||
#include "Loader.h"
|
||||
|
||||
CGame *g_Game=NULL;
|
||||
|
||||
@ -39,6 +40,42 @@ CGame::~CGame()
|
||||
debug_out("CGame::~CGame(): Game object DESTROYED\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
PSRETURN CGame::RegisterInit(CGameAttributes* pAttribs)
|
||||
{
|
||||
LDR_BeginRegistering();
|
||||
|
||||
// RC, 040804 - GameView needs to be initialised before World, otherwise GameView initialisation
|
||||
// overwrites anything stored in the map file that gets loaded by CWorld::Initialize with default
|
||||
// values. At the minute, it's just lighting settings, but could be extended to store camera position.
|
||||
// Storing lighting settings in the gameview seems a little odd, but it's no big deal; maybe move it at
|
||||
// some point to be stored in the world object?
|
||||
m_GameView.RegisterInit(pAttribs);
|
||||
m_World.RegisterInit(pAttribs);
|
||||
m_Simulation.RegisterInit(pAttribs);
|
||||
|
||||
LDR_EndRegistering();
|
||||
return 0;
|
||||
}
|
||||
|
||||
PSRETURN CGame::ReallyStartGame()
|
||||
{
|
||||
jsval rval;
|
||||
JSBool ok = JS_CallFunctionName(g_ScriptingHost.getContext(),
|
||||
g_GUI.GetScriptObject(), "reallyStartGame", 0, NULL, &rval);
|
||||
assert(ok);
|
||||
|
||||
debug_out("GAME STARTED, ALL INIT COMPLETE\n");
|
||||
m_GameStarted=true;
|
||||
|
||||
#ifndef NO_GUI
|
||||
g_GUI.SendEventToAll("sessionstart");
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
PSRETURN CGame::StartGame(CGameAttributes *pAttribs)
|
||||
{
|
||||
try
|
||||
@ -54,21 +91,7 @@ PSRETURN CGame::StartGame(CGameAttributes *pAttribs)
|
||||
|
||||
m_pLocalPlayer=m_Players[1];
|
||||
|
||||
// RC, 040804 - GameView needs to be initialised before World, otherwise GameView initialisation
|
||||
// overwrites anything stored in the map file that gets loaded by CWorld::Initialize with default
|
||||
// values. At the minute, it's just lighting settings, but could be extended to store camera position.
|
||||
// Storing lighting settings in the gameview seems a little odd, but it's no big deal; maybe move it at
|
||||
// some point to be stored in the world object?
|
||||
m_GameView.Initialize(pAttribs);
|
||||
m_World.Initialize(pAttribs);
|
||||
m_Simulation.Initialize(pAttribs);
|
||||
|
||||
debug_out("GAME STARTED, ALL INIT COMPLETE\n");
|
||||
m_GameStarted=true;
|
||||
|
||||
#ifndef NO_GUI
|
||||
g_GUI.SendEventToAll("sessionstart");
|
||||
#endif
|
||||
RegisterInit(pAttribs);
|
||||
}
|
||||
catch (PSERROR_Game e)
|
||||
{
|
||||
|
@ -41,7 +41,8 @@ public:
|
||||
Return: 0 on OK - a PSRETURN code otherwise
|
||||
*/
|
||||
PSRETURN StartGame(CGameAttributes *pGameAttributes);
|
||||
|
||||
PSRETURN ReallyStartGame();
|
||||
|
||||
/*
|
||||
Perform all per-frame updates
|
||||
*/
|
||||
@ -74,6 +75,9 @@ public:
|
||||
{ return &m_GameView; }
|
||||
inline CSimulation *GetSimulation()
|
||||
{ return &m_Simulation; }
|
||||
|
||||
private:
|
||||
PSRETURN RegisterInit(CGameAttributes* pAttribs);
|
||||
};
|
||||
|
||||
extern CGame *g_Game;
|
||||
|
@ -158,7 +158,7 @@ static bool HaveTimeForNextTask(double time_left, double time_budget, int estima
|
||||
// (if it's less than that, we won't check the next task length)
|
||||
if(time_left < 0.40*time_budget)
|
||||
{
|
||||
const double estimated_duration = estimated_duration_ms * 1e-3;
|
||||
const double estimated_duration = estimated_duration_ms*1e-3;
|
||||
// .. and the upcoming task is expected to be long -
|
||||
// leave it for the next timeslice.
|
||||
if(estimated_duration > time_left + time_budget*0.20)
|
||||
@ -201,10 +201,10 @@ int LDR_ProgressiveLoad(double time_budget, wchar_t* description_,
|
||||
|
||||
while(!load_requests.empty())
|
||||
{
|
||||
const double time_left = end_time - get_time();
|
||||
const LoadRequest& lr = load_requests.front();
|
||||
double time_left = end_time - get_time();
|
||||
|
||||
// do actual work of loading
|
||||
const LoadRequest& lr = load_requests.front();
|
||||
ret = lr.func(lr.param, time_left);
|
||||
// .. either finished entirely, or failed => remove from queue
|
||||
if(ret != ERR_TIMED_OUT)
|
||||
@ -228,6 +228,7 @@ int LDR_ProgressiveLoad(double time_budget, wchar_t* description_,
|
||||
// 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))
|
||||
{
|
||||
ret = ERR_TIMED_OUT;
|
||||
@ -237,7 +238,6 @@ int LDR_ProgressiveLoad(double time_budget, wchar_t* description_,
|
||||
|
||||
// queue is empty, we just finished.
|
||||
state = IDLE;
|
||||
assert(progress_percent == 100);
|
||||
ret = 0;
|
||||
|
||||
// set output params (there are several return points above)
|
||||
@ -250,5 +250,7 @@ done:
|
||||
description = load_requests.front().description.c_str();
|
||||
wcscpy_s(description_, max_chars, description);
|
||||
|
||||
debug_out("LDR_ProgressiveLoad RETURNING; desc=%ls progress=%d\n", description_, progress_percent);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "BaseEntityCollection.h"
|
||||
#include "EntityManager.h"
|
||||
#include "timer.h"
|
||||
#include "Loader.h"
|
||||
|
||||
#define LOG_CATEGORY "world"
|
||||
|
||||
@ -41,6 +42,32 @@ void CWorld::Initialize(CGameAttributes *pAttribs)
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
CWorld::~CWorld()
|
||||
{
|
||||
// The Entity Manager should perhaps be converted into a CWorld member..
|
||||
|
@ -18,6 +18,7 @@ class CWorld
|
||||
// been converted
|
||||
CUnitManager &m_UnitManager;
|
||||
CEntityManager &m_EntityManager;
|
||||
|
||||
public:
|
||||
inline CWorld(CGame *pGame):
|
||||
m_pGame(pGame),
|
||||
@ -28,11 +29,13 @@ public:
|
||||
|
||||
~CWorld();
|
||||
|
||||
void RegisterInit(CGameAttributes *pGameAttributes);
|
||||
/*
|
||||
Initialize the World - load the map and all objects
|
||||
Initialize the World - load the map and all objects
|
||||
*/
|
||||
void Initialize(CGameAttributes *pGameAttributes);
|
||||
|
||||
|
||||
|
||||
inline CTerrain *GetTerrain()
|
||||
{ return &m_Terrain; }
|
||||
inline CUnitManager *GetUnitManager()
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "CConsole.h"
|
||||
#include "Unit.h"
|
||||
#include "Model.h"
|
||||
#include "Loader.h"
|
||||
|
||||
#include "gui/CGUI.h"
|
||||
|
||||
@ -37,6 +38,34 @@ void CSimulation::Initialize(CGameAttributes *pAttribs)
|
||||
g_EntityManager.InitializeAll();
|
||||
}
|
||||
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CSimulation::Update(double frameTime)
|
||||
{
|
||||
m_DeltaTime += frameTime;
|
||||
|
@ -33,8 +33,9 @@ public:
|
||||
inline CTurnManager *GetTurnManager()
|
||||
{ return m_pTurnManager; }
|
||||
|
||||
void RegisterInit(CGameAttributes *pGameAttributes);
|
||||
void Initialize(CGameAttributes *pGameAttributes);
|
||||
|
||||
|
||||
// Perform all CSimulation updates for the specified elapsed time.
|
||||
void Update(double frameTime);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user