Fixes #460 Pause the race when calling the Help menu + Use slow start manager when resuming + Resuming from F1 or Esc gets back to the currentPaused/Unpaused state + Workaround bloated help menu

git-svn-id: https://svn.code.sf.net/p/speed-dreams/code/trunk@4590 30fe4595-0a0c-4342-8851-515496e4dcbd

Former-commit-id: 2c29a5677c7fd3ce41369bc5b87a094fcb8cf4b7
Former-commit-id: 9d983487b343fdd02d259c1b8f8a93d4b8b15c1a
This commit is contained in:
pouillot 2012-03-18 11:23:59 +00:00
parent 494245e295
commit 60f8499d5c
5 changed files with 145 additions and 61 deletions

View file

@ -49,15 +49,29 @@ onDeactivate(void* /* dummy */)
/** Generate a help screen. /** Generate a help screen.
@ingroup gui @ingroup gui
@param prevScreen Previous screen to return to @param targetScreen The screen to display help for and to return to when exiting
@warning The help screen is activated. @warning The help screen is activated.
*/ */
void void
GfuiHelpScreen(void *prevScreen) GfuiHelpScreen(void *targetScreen)
{ {
tGfuiScreen *pscr = (tGfuiScreen*)prevScreen; GfuiHelpScreen(targetScreen, 0);
}
// Create screen, load menu XML descriptor and create static controls. /** Generate a help screen.
@ingroup gui
@param targetScreen The screen to display help for
@param returnScreen The screen to return to when exiting
@warning The help screen is activated.
*/
void
GfuiHelpScreen(void *targetScreen, void *returnScreen)
{
// The return screen is the target screen if not specified (0).
if (!returnScreen)
returnScreen = targetScreen;
// Create help screen, load menu XML descriptor and create static controls.
void* scrHandle = GfuiScreenCreate(0, 0, onActivate, 0, onDeactivate); void* scrHandle = GfuiScreenCreate(0, 0, onActivate, 0, onDeactivate);
void *hmenu = GfuiMenuLoad("helpmenu.xml"); void *hmenu = GfuiMenuLoad("helpmenu.xml");
@ -75,8 +89,12 @@ GfuiHelpScreen(void *prevScreen)
int ys = nYTopLine; int ys = nYTopLine;
int yn = nYTopLine; int yn = nYTopLine;
tGfuiKey *curKey = pscr->userKeys; tGfuiScreen *pscrTgt = (tGfuiScreen*)targetScreen;
tGfuiKey *curKey = pscrTgt->userKeys;
do { do {
// Decide if this key goes on the left of right column.
bool bLeft;
if (curKey) { if (curKey) {
curKey = curKey->next; curKey = curKey->next;
switch(curKey->key) { switch(curKey->key) {
@ -105,31 +123,45 @@ GfuiHelpScreen(void *prevScreen)
case GFUIK_DELETE: case GFUIK_DELETE:
case GFUIK_CLEAR: case GFUIK_CLEAR:
case GFUIK_PAUSE: case GFUIK_PAUSE:
GfuiMenuCreateLabelControl(scrHandle, hmenu, "keyName", true, // from template bLeft = true;
curKey->name, nXLeftColumn, ys);
GfuiMenuCreateLabelControl(scrHandle, hmenu, "keyDesc", true, // from template
curKey->descr, nXLeftColumn + nNameFieldWidth, ys);
ys -= nLineShift;
break; break;
default: default:
GfuiMenuCreateLabelControl(scrHandle, hmenu, "keyName", true, // from template bLeft = curKey->modifier != GFUIM_NONE;
curKey->name, nXRightColumn, yn);
GfuiMenuCreateLabelControl(scrHandle, hmenu, "keyDesc", true, // from template
curKey->descr, nXRightColumn + nNameFieldWidth, yn);
yn -= nLineShift;
break; break;
} }
} }
if (curKey == pscr->userKeys) // Determine control coordinates, whether left or right column.
int x, y;
if (bLeft)
{
x = nXLeftColumn;
y = ys;
ys -= nLineShift;
}
else
{
x = nXRightColumn;
y = yn;
yn -= nLineShift;
}
// Create label controls.
GfuiMenuCreateLabelControl(scrHandle, hmenu, "keyName", true, // from template
curKey->name, x, y);
GfuiMenuCreateLabelControl(scrHandle, hmenu, "keyDesc", true, // from template
curKey->descr, x + nNameFieldWidth, y);
// Stop if no more keys to explain.
if (curKey == pscrTgt->userKeys)
curKey = (tGfuiKey*)NULL; curKey = (tGfuiKey*)NULL;
} while (curKey); } while (curKey);
// Create Back button. // Create Back button.
GfuiMenuCreateButtonControl(scrHandle, hmenu, "backbutton", prevScreen, GfuiScreenReplace); GfuiMenuCreateButtonControl(scrHandle, hmenu, "backbutton", targetScreen, GfuiScreenReplace);
// Create version label. // Create version label.
const int versionId = GfuiMenuCreateLabelControl(scrHandle, hmenu, "versionlabel"); const int versionId = GfuiMenuCreateLabelControl(scrHandle, hmenu, "versionlabel");
@ -139,8 +171,8 @@ GfuiHelpScreen(void *prevScreen)
GfParmReleaseHandle(hmenu); GfParmReleaseHandle(hmenu);
// Add keyboard shortcuts. // Add keyboard shortcuts.
GfuiAddKey(scrHandle, GFUIK_ESCAPE, "Back to the menu", prevScreen, GfuiScreenReplace, NULL); GfuiAddKey(scrHandle, GFUIK_ESCAPE, "Back to the menu", returnScreen, GfuiScreenReplace, NULL);
GfuiAddKey(scrHandle, GFUIK_RETURN, "Back to the menu", prevScreen, GfuiScreenReplace, NULL); GfuiAddKey(scrHandle, GFUIK_RETURN, "Back to the menu", returnScreen, GfuiScreenReplace, NULL);
if (NRecursions == 0) if (NRecursions == 0)
GfuiAddKey(scrHandle, GFUIK_F1, "Help on Help menu", scrHandle, GfuiHelpScreen, NULL); GfuiAddKey(scrHandle, GFUIK_F1, "Help on Help menu", scrHandle, GfuiHelpScreen, NULL);
GfuiAddKey(scrHandle, GFUIK_F12, "Screen-shot", NULL, GfuiScreenShot, NULL); GfuiAddKey(scrHandle, GFUIK_F12, "Screen-shot", NULL, GfuiScreenShot, NULL);

View file

@ -276,7 +276,8 @@ TGFCLIENT_API void GfuiAddKey(void *scr, int key, int modifier, const char *desc
TGFCLIENT_API void GfuiRegisterKey(int key, const char *descr, TGFCLIENT_API void GfuiRegisterKey(int key, const char *descr,
void *userData, tfuiCallback onKeyPressed, tfuiCallback onKeyReleased); void *userData, tfuiCallback onKeyPressed, tfuiCallback onKeyReleased);
TGFCLIENT_API void GfuiSetKeyAutoRepeat(void *scr, int on); TGFCLIENT_API void GfuiSetKeyAutoRepeat(void *scr, int on);
TGFCLIENT_API void GfuiHelpScreen(void *prevScreen); TGFCLIENT_API void GfuiHelpScreen(void *targetScreen);
TGFCLIENT_API void GfuiHelpScreen(void *targetScreen, void *returnScreen);
TGFCLIENT_API void GfuiScreenShot(void *notused); TGFCLIENT_API void GfuiScreenShot(void *notused);
TGFCLIENT_API void GfuiScreenAddBgImg(void *scr, const char *filename); TGFCLIENT_API void GfuiScreenAddBgImg(void *scr, const char *filename);
TGFCLIENT_API void GfuiKeyEventRegister(void *scr, tfuiKeyCallback onKeyAction); TGFCLIENT_API void GfuiKeyEventRegister(void *scr, tfuiKeyCallback onKeyAction);

View file

@ -71,9 +71,17 @@ const double RmProgressiveTimeModifier::_sfTimeLapse = 2;
RmProgressiveTimeModifier rmProgressiveTimeModifier; RmProgressiveTimeModifier rmProgressiveTimeModifier;
RmProgressiveTimeModifier::RmProgressiveTimeModifier() RmProgressiveTimeModifier::RmProgressiveTimeModifier()
: _bExecRunning(false), _fExecStartTime(0), _fWholeTimeLapse(0),
_fOldTimeMultiplier(_sfTimeMultiplier), _fResetterTimeMultiplier(1)
{ {
reset();
}
void RmProgressiveTimeModifier::reset()
{
_bExecRunning = false;
_fExecStartTime = 0;
_fWholeTimeLapse = 0;
_fOldTimeMultiplier = _sfTimeMultiplier;
_fResetterTimeMultiplier = 1;
} }
void RmProgressiveTimeModifier::start() void RmProgressiveTimeModifier::start()
@ -140,8 +148,8 @@ void RmProgressiveTimeModifier::execute()
void RmProgressiveTimeModifier::terminate() void RmProgressiveTimeModifier::terminate()
{ {
// Seems we have done our work. Lets be quiet untill next start() call. // Seems we have done our work. Lets keep quiet until next time start() is called.
_bExecRunning = false; reset();
} }
/***************************************************************************/ /***************************************************************************/
@ -159,6 +167,16 @@ rmUpdateRaceEngine()
static std::string rmStrCurMsg; static std::string rmStrCurMsg;
static std::string rmStrCurBigMsg; static std::string rmStrCurBigMsg;
// Race pause flag
// There are 2 concepts of "Pause" here, and they can overlap each other :
// 1) the race engine : LmRaceEngine().outData()->s->_raceState & RM_RACE_PAUSED
// which matches with the in-game 'P' key shortcut to freeze the race screen,
// 2) the menu one : you can also pause the game through the 'Esc' key (=> Stop Race menu)
// and through the 'F1' key (=> help menu).
// This flag is for the 2nd one :
// when you unpause in the 2nd one meaning, you may stay paused in the 1st one meaning.
static bool rmRacePaused = false;
// Flag to know if the menu state has been changed (and thus needs a redraw+redisplay). // Flag to know if the menu state has been changed (and thus needs a redraw+redisplay).
static bool rmbMenuChanged = false; static bool rmbMenuChanged = false;
@ -202,6 +220,7 @@ rmInitMovieCapture()
strcmp(GfParmGetStr(hparmRaceEng, RM_SECT_MOVIE_CAPTURE, RM_ATT_CAPTURE_ENABLE, strcmp(GfParmGetStr(hparmRaceEng, RM_SECT_MOVIE_CAPTURE, RM_ATT_CAPTURE_ENABLE,
RM_VAL_NO), RM_VAL_NO),
RM_VAL_NO) ? true : false; RM_VAL_NO) ? true : false;
rmMovieCapture.active = false;
if (!rmMovieCapture.enabled) if (!rmMovieCapture.enabled)
{ {
rmMovieCapture.outputBase = 0; rmMovieCapture.outputBase = 0;
@ -209,7 +228,6 @@ rmInitMovieCapture()
} }
else else
{ {
rmMovieCapture.active = false;
rmMovieCapture.frameRate = rmMovieCapture.frameRate =
GfParmGetNum(hparmRaceEng, RM_SECT_MOVIE_CAPTURE, RM_ATT_CAPTURE_FPS, NULL, 25.0); GfParmGetNum(hparmRaceEng, RM_SECT_MOVIE_CAPTURE, RM_ATT_CAPTURE_FPS, NULL, 25.0);
rmMovieCapture.simuRate = 1.0 / RCM_MAX_DT_SIMU; rmMovieCapture.simuRate = 1.0 / RCM_MAX_DT_SIMU;
@ -339,6 +357,10 @@ rmRedisplay()
GfuiApp().eventLoop().postRedisplay(); GfuiApp().eventLoop().postRedisplay();
} }
// Warning : This function is called when the race is actually starting in "non-blind" mode,
// but also when coming back from the Stop Race menu (the user chose "Resume")
// or from the Help menu. It must also consider that the race may be currently paused !
static void static void
rmScreenActivate(void * /* dummy */) rmScreenActivate(void * /* dummy */)
{ {
@ -361,23 +383,21 @@ rmScreenActivate(void * /* dummy */)
#endif #endif
// Hide the on-screen pause indicator in case it is visible.
GfuiVisibilitySet(rmScreenHandle, rmPauseId, GFUI_INVISIBLE);
// Reset normal sound volume in any case.
if (LegacyMenu::self().soundEngine())
LegacyMenu::self().soundEngine()->mute(false);
// Deactivate the movie capture mode in any case.
rmMovieCapture.active = false;
// Configure the event loop. // Configure the event loop.
GfuiApp().eventLoop().setRecomputeCB(rmUpdateRaceEngine); GfuiApp().eventLoop().setRecomputeCB(rmUpdateRaceEngine);
GfuiApp().eventLoop().setRedisplayCB(rmRedisplay); GfuiApp().eventLoop().setRedisplayCB(rmRedisplay);
// Resynchronize the race engine. // If not paused ...
LmRaceEngine().start(); if (!rmRacePaused)
{
// Reset normal sound volume.
if (LegacyMenu::self().soundEngine())
LegacyMenu::self().soundEngine()->mute(false);
// Resynchronize the race engine.
LmRaceEngine().start();
}
// Request a redisplay for the next event loop. // Request a redisplay for the next event loop.
GfuiApp().eventLoop().postRedisplay(); GfuiApp().eventLoop().postRedisplay();
@ -388,7 +408,7 @@ rmScreenActivate(void * /* dummy */)
static void static void
rmRacePause(void * /* vboard */) rmRacePause(void * /* vboard */)
{ {
if (LmRaceEngine().outData()->s->_raceState & RM_RACE_PAUSED) if (rmRacePaused)
{ {
if (LegacyMenu::self().soundEngine()) if (LegacyMenu::self().soundEngine())
LegacyMenu::self().soundEngine()->mute(false); LegacyMenu::self().soundEngine()->mute(false);
@ -421,6 +441,9 @@ rmRacePause(void * /* vboard */)
GfuiVisibilitySet(rmScreenHandle, rmMsgId, GFUI_INVISIBLE); GfuiVisibilitySet(rmScreenHandle, rmMsgId, GFUI_INVISIBLE);
} }
// Toggle the race-paused flag.
rmRacePaused = !rmRacePaused;
// The menu changed. // The menu changed.
rmbMenuChanged = true; rmbMenuChanged = true;
} }
@ -509,10 +532,12 @@ rmApplyState(void *pvState)
static void static void
rmOpenHelpScreen(void * /* dummy */) rmOpenHelpScreen(void * /* dummy */)
{ {
LmRaceEngine().stop();
if (LegacyMenu::self().soundEngine()) if (LegacyMenu::self().soundEngine())
LegacyMenu::self().soundEngine()->mute(true); LegacyMenu::self().soundEngine()->mute(true);
GfuiHelpScreen(rmScreenHandle); GfuiHelpScreen(rmScreenHandle, RmBackToRaceHookInit());
} }
static void static void
@ -540,9 +565,6 @@ rmAddKeys()
void * void *
RmScreenInit() RmScreenInit()
{ {
// Initialize the movie capture system.
rmInitMovieCapture();
// Release screen if was initialized. // Release screen if was initialized.
RmScreenShutdown(); RmScreenShutdown();
@ -562,9 +584,17 @@ RmScreenInit()
// Register keyboard shortcuts. // Register keyboard shortcuts.
rmAddKeys(); rmAddKeys();
// Hide the Pause label for the moment. // We are starting "unpaused".
GfuiVisibilitySet(rmScreenHandle, rmPauseId, 0); GfuiVisibilitySet(rmScreenHandle, rmPauseId, GFUI_INVISIBLE);
rmRacePaused = false;
// Re-initialize the progressive time modifier,
// in case the race was exited while it was running.
rmProgressiveTimeModifier.reset();
// Initialize the movie capture system.
rmInitMovieCapture();
return rmScreenHandle; return rmScreenHandle;
} }
@ -651,6 +681,9 @@ rmResScreenActivate(void * /* dummy */)
GfuiApp().eventLoop().setRecomputeCB(rmUpdateRaceEngine); GfuiApp().eventLoop().setRecomputeCB(rmUpdateRaceEngine);
GfuiApp().eventLoop().setRedisplayCB(rmResRedisplay); GfuiApp().eventLoop().setRedisplayCB(rmResRedisplay);
// Resynchronize the race engine.
LmRaceEngine().start();
// Request a redisplay for the next event loop. // Request a redisplay for the next event loop.
GfuiApp().eventLoop().postRedisplay(); GfuiApp().eventLoop().postRedisplay();

View file

@ -85,6 +85,7 @@ extern void RmGameScreen();
extern void RmShowResults(void * /* prevHdle */, tRmInfo * /* info */); extern void RmShowResults(void * /* prevHdle */, tRmInfo * /* info */);
extern void* RmBackToRaceHookInit();
extern void RmStopRaceMenu(); extern void RmStopRaceMenu();
extern void RmStopRaceMenuShutdown(); extern void RmStopRaceMenuShutdown();
@ -141,14 +142,25 @@ extern void *RmRaceSelectMenuHandle;
class RmProgressiveTimeModifier class RmProgressiveTimeModifier
{ {
public: public:
//! Constructor.
RmProgressiveTimeModifier(); RmProgressiveTimeModifier();
//! Reset state as if just born.
void reset();
//! Start the ramp up.
void start(); void start();
//! Simulation step : aimed at being called at each display loop.
void execute(); void execute();
private: private:
//! For when the ramp up is over.
void terminate(); void terminate();
private: private:
// Should we run the manager at next simu step ? // Should we run the manager at next simu step ?
bool _bExecRunning; bool _bExecRunning;
@ -165,12 +177,12 @@ private:
// Log the integrated time acceleration change (needed when multiple start without terminate) // Log the integrated time acceleration change (needed when multiple start without terminate)
double _fResetterTimeMultiplier; double _fResetterTimeMultiplier;
private: private:
// Config: Set how much time will take to restore to normal speed (after the delay) // Config: Set how much time will take to restore to normal speed (after the delay)
static const double _sfTimeMultiplier; static const double _sfTimeMultiplier;
// Config: Set how much we wait befor starting to apply the time acceleration // Config: Set how much we wait before starting to apply the time acceleration
static const double _sfDelay; static const double _sfDelay;
// Config: Set how much the time will be initially changed (as a fraction of the current time) // Config: Set how much the time will be initially changed (as a fraction of the current time)

View file

@ -34,7 +34,7 @@ rmAbortRaceHookActivate(void * /* dummy */)
static void *pvAbortRaceHookHandle = 0; static void *pvAbortRaceHookHandle = 0;
static void * static void *
rmAbortRaceHookInit(void) rmAbortRaceHookInit()
{ {
if (!pvAbortRaceHookHandle) if (!pvAbortRaceHookHandle)
pvAbortRaceHookHandle = GfuiHookCreate(0, rmAbortRaceHookActivate); pvAbortRaceHookHandle = GfuiHookCreate(0, rmAbortRaceHookActivate);
@ -52,7 +52,7 @@ rmSkipSessionHookActivate(void * /* dummy */)
static void *pvSkipSessionHookHandle = 0; static void *pvSkipSessionHookHandle = 0;
static void * static void *
rmSkipSessionHookInit(void) rmSkipSessionHookInit()
{ {
if (!pvSkipSessionHookHandle) if (!pvSkipSessionHookHandle)
pvSkipSessionHookHandle = GfuiHookCreate(0, rmSkipSessionHookActivate); pvSkipSessionHookHandle = GfuiHookCreate(0, rmSkipSessionHookActivate);
@ -64,8 +64,14 @@ rmSkipSessionHookInit(void)
static void static void
rmBackToRaceHookActivate(void * /* dummy */) rmBackToRaceHookActivate(void * /* dummy */)
{ {
LmRaceEngine().start(); // Temporary hack for the Paused race case, in order
// the race does not get ended (as is is currently stopped)
// TODO: Activate the Stop Race menu directly, as for the Help menu (F1),
// and no more through changing the race engine state to STOP
// But beware of the other hooks ...
LmRaceEngine().inData()->_reState = RE_STATE_RACE;
// Back to the race screen in next display loop.
LegacyMenu::self().activateGameScreen(); LegacyMenu::self().activateGameScreen();
// Launch the "slow resume race" manager if non-blind mode. // Launch the "slow resume race" manager if non-blind mode.
@ -75,8 +81,8 @@ rmBackToRaceHookActivate(void * /* dummy */)
static void *pvBackToRaceHookHandle = 0; static void *pvBackToRaceHookHandle = 0;
static void * void *
rmBackToRaceHookInit(void) RmBackToRaceHookInit()
{ {
if (!pvBackToRaceHookHandle) if (!pvBackToRaceHookHandle)
pvBackToRaceHookHandle = GfuiHookCreate(0, rmBackToRaceHookActivate); pvBackToRaceHookHandle = GfuiHookCreate(0, rmBackToRaceHookActivate);
@ -94,7 +100,7 @@ rmRestartRaceHookActivate(void * /* dummy */)
static void *pvRestartRaceHookHandle = 0; static void *pvRestartRaceHookHandle = 0;
static void * static void *
rmRestartRaceHookInit(void) rmRestartRaceHookInit()
{ {
if (!pvRestartRaceHookHandle) if (!pvRestartRaceHookHandle)
pvRestartRaceHookHandle = GfuiHookCreate(0, rmRestartRaceHookActivate); pvRestartRaceHookHandle = GfuiHookCreate(0, rmRestartRaceHookActivate);
@ -115,7 +121,7 @@ rmQuitHookActivate(void * /* dummy */)
static void *pvQuitHookHandle = 0; static void *pvQuitHookHandle = 0;
static void * static void *
rmQuitHookInit(void) rmQuitHookInit()
{ {
if (!pvQuitHookHandle) if (!pvQuitHookHandle)
pvQuitHookHandle = GfuiHookCreate(0, rmQuitHookActivate); pvQuitHookHandle = GfuiHookCreate(0, rmQuitHookActivate);
@ -239,7 +245,7 @@ RmStopRaceMenu()
{ {
rmStopScrHandle = rmStopScrHandle =
rmStopRaceMenu rmStopRaceMenu
("resume", rmBackToRaceHookInit(), ("resume", RmBackToRaceHookInit(),
"skip", rmSkipSessionHookInit(), "skip", rmSkipSessionHookInit(),
"abort", rmAbortRaceHookInit(), "abort", rmAbortRaceHookInit(),
"quit", rmQuitHookInit()); "quit", rmQuitHookInit());
@ -248,7 +254,7 @@ RmStopRaceMenu()
{ {
rmStopScrHandle = rmStopScrHandle =
rmStopRaceMenu rmStopRaceMenu
("resume", rmBackToRaceHookInit(), ("resume", RmBackToRaceHookInit(),
"abort", rmAbortRaceHookInit(), "abort", rmAbortRaceHookInit(),
"quit", rmQuitHookInit()); "quit", rmQuitHookInit());
} }
@ -259,7 +265,7 @@ RmStopRaceMenu()
{ {
rmStopScrHandle = rmStopScrHandle =
rmStopRaceMenu rmStopRaceMenu
("resume", rmBackToRaceHookInit(), ("resume", RmBackToRaceHookInit(),
"skip", rmSkipSessionHookInit(), "skip", rmSkipSessionHookInit(),
"restart", rmRestartRaceHookInit(), "restart", rmRestartRaceHookInit(),
"abort", rmAbortRaceHookInit(), "abort", rmAbortRaceHookInit(),
@ -269,7 +275,7 @@ RmStopRaceMenu()
{ {
rmStopScrHandle = rmStopScrHandle =
rmStopRaceMenu rmStopRaceMenu
("resume", rmBackToRaceHookInit(), ("resume", RmBackToRaceHookInit(),
"restart", rmRestartRaceHookInit(), "restart", rmRestartRaceHookInit(),
"abort", rmAbortRaceHookInit(), "abort", rmAbortRaceHookInit(),
"quit", rmQuitHookInit()); "quit", rmQuitHookInit());