Skip to content

Commit

Permalink
Added (All games): Darken the screen after the users quits from the m…
Browse files Browse the repository at this point in the history
…enu.

A quick new feature to distract from the monotony of the current work in mapcache2. Interestingly this has revealed a couple of issues that we should consider:
* When not quiting immediately the user is still able to open the console and execute commands. This is fine, we don't want to deprive the user from accessing the console. However many game-side commands should not be executed once game shutdown has begun. Adding a "is shutting down" test to each command seems clumsy.
* Using a gamestate for "a map is loaded" is rather awkward and will need a rethink.
  • Loading branch information
danij-deng committed Feb 28, 2010
1 parent 181e1c2 commit b73de6b
Show file tree
Hide file tree
Showing 17 changed files with 222 additions and 115 deletions.
4 changes: 4 additions & 0 deletions doomsday/plugins/common/src/g_controls.c
Expand Up @@ -50,6 +50,7 @@
#include "d_netsv.h"
#include "hu_menu.h"
#include "hu_msg.h"
#include "g_common.h"

// MACROS ------------------------------------------------------------------

Expand Down Expand Up @@ -481,6 +482,9 @@ void G_RegisterBindClasses(void)

DEFCC( CCmdPause )
{
if(G_GetGameAction() == GA_QUIT)
return false;

// Toggle pause.
G_SetPause(!(paused & 1));
return true;
Expand Down
201 changes: 149 additions & 52 deletions doomsday/plugins/common/src/g_game.c
Expand Up @@ -419,6 +419,9 @@ void G_Register(void)

void G_SetGameAction(gameaction_t action)
{
if(gameAction == GA_QUIT)
return;

if(gameAction != action)
gameAction = action;
}
Expand Down Expand Up @@ -776,6 +779,9 @@ void G_ChangeGameState(gamestate_t state)
boolean gameUIActive = false;
boolean gameActive = true;

if(G_GetGameAction() == GA_QUIT)
return;

if(state < 0 || state >= NUM_GAME_STATES)
Con_Error("G_ChangeGameState: Invalid state %i.\n", (int) state);

Expand Down Expand Up @@ -934,6 +940,9 @@ void G_DoLoadMap(void)
*/
boolean G_Responder(event_t *ev)
{
if(G_GetGameAction() == GA_QUIT)
return false; // Eat all events once shutdown has begun.

// With the menu active, none of these should respond to input events.
if(!Hu_MenuIsActive() && !Hu_IsMessageActive())
{
Expand Down Expand Up @@ -1036,60 +1045,79 @@ void G_UpdateGSVarsForPlayer(player_t* pl)
#endif
}

/**
* The core of the timing loop. Game state, game actions etc occur here.
*
* @param ticLength How long this tick is, in seconds.
*/
void G_Ticker(timespan_t ticLength)
static void runGameAction(void)
{
static gamestate_t oldGameState = -1;
static trigger_t fixed = {1.0 / TICSPERSEC};

int i;
gameaction_t currentAction;

// Always tic:
Hu_FogEffectTicker(ticLength);
Hu_MenuTicker(ticLength);
Hu_MsgTicker(ticLength);

if(IS_CLIENT && !Get(DD_GAME_READY))
return;

// Do player reborns if needed.
for(i = 0; i < MAXPLAYERS; ++i)
if(G_GetGameAction() == GA_QUIT)
{
player_t *plr = &players[i];
#define QUITWAIT_MILLISECONDS 1500

if(plr->plr->inGame && plr->playerState == PST_REBORN &&
!P_MobjIsCamera(plr->plr->mo))
G_DoReborn(i);
static uint quitTime = 0;

// Player has left?
if(plr->playerState == PST_GONE)
if(quitTime == 0)
{
plr->playerState = PST_REBORN;
if(plr->plr->mo)
quitTime = Sys_GetRealTime();

Hu_MenuCommand(MCMD_CLOSEFAST);

if(!IS_NETGAME)
{
if(!IS_CLIENT)
#if __JDOOM__ || __JDOOM64__
// Play an exit sound if it is enabled.
if(cfg.menuQuitSound)
{
P_SpawnTeleFog(plr->plr->mo->pos[VX],
plr->plr->mo->pos[VY],
plr->plr->mo->angle + ANG180);
static int quitsounds[8] = {
SFX_PLDETH,
SFX_DMPAIN,
SFX_POPAIN,
SFX_SLOP,
SFX_TELEPT,
SFX_POSIT1,
SFX_POSIT3,
SFX_SGTATK
};
static int quitsounds2[8] = {
SFX_VILACT,
SFX_GETPOW,
# if __JDOOM64__
SFX_PEPAIN,
# else
SFX_BOSCUB,
# endif
SFX_SLOP,
SFX_SKESWG,
SFX_KNTDTH,
SFX_BSPACT,
SFX_SGTATK
};

if(gameMode == commercial)
S_LocalSound(quitsounds2[P_Random() & 7], NULL);
else
S_LocalSound(quitsounds[P_Random() & 7], NULL);
}

// Let's get rid of the mobj.
#ifdef _DEBUG
Con_Message("G_Ticker: Removing player %i's mobj.\n", i);
#endif
P_MobjRemove(plr->plr->mo, true);
plr->plr->mo = NULL;
DD_Executef(true, "activatebcontext deui");
}
}

if(Sys_GetRealTime() > quitTime + QUITWAIT_MILLISECONDS)
{
Sys_Quit();
}
else
{
float t = (Sys_GetRealTime() - quitTime) / (float) QUITWAIT_MILLISECONDS;
quitDarkenOpacity = t*t*t;
}

// No game state changes occur once we have begun to quit.
return;

#undef QUITWAIT_MILLISECONDS
}

// Do things to change the game state.
{gameaction_t currentAction;
while((currentAction = G_GetGameAction()) != GA_NONE)
{
switch(currentAction)
Expand Down Expand Up @@ -1146,23 +1174,89 @@ Con_Message("G_Ticker: Removing player %i's mobj.\n", i);
default:
break;
}
}
}}
}

// Update the viewer's look angle
//G_LookAround(CONSOLEPLAYER);
/**
* The core of the timing loop. Game state, game actions etc occur here.
*
* @param ticLength How long this tick is, in seconds.
*/
void G_Ticker(timespan_t ticLength)
{
static gamestate_t oldGameState = -1;
static trigger_t fixed = {1.0 / TICSPERSEC};

if(!IS_CLIENT)
int i;

// Always tic:
Hu_FogEffectTicker(ticLength);
Hu_MenuTicker(ticLength);
Hu_MsgTicker(ticLength);

if(IS_CLIENT && !Get(DD_GAME_READY))
return;

// Do player reborns if needed.
for(i = 0; i < MAXPLAYERS; ++i)
{
// Enable/disable sending of frames (delta sets) to clients.
Set(DD_ALLOW_FRAMES, G_GetGameState() == GS_MAP);
player_t *plr = &players[i];

if(plr->plr->inGame && plr->playerState == PST_REBORN &&
!P_MobjIsCamera(plr->plr->mo))
G_DoReborn(i);

// Tell Doomsday when the game is paused (clients can't pause
// the game.)
Set(DD_CLIENT_PAUSED, P_IsPaused());
// Player has left?
if(plr->playerState == PST_GONE)
{
plr->playerState = PST_REBORN;
if(plr->plr->mo)
{
if(!IS_CLIENT)
{
P_SpawnTeleFog(plr->plr->mo->pos[VX],
plr->plr->mo->pos[VY],
plr->plr->mo->angle + ANG180);
}

// Let's get rid of the mobj.
#ifdef _DEBUG
Con_Message("G_Ticker: Removing player %i's mobj.\n", i);
#endif
P_MobjRemove(plr->plr->mo, true);
plr->plr->mo = NULL;
}
}
}

// Must be called on every tick.
P_RunPlayers(ticLength);
runGameAction();

if(G_GetGameAction() != GA_QUIT)
{
// Update the viewer's look angle
//G_LookAround(CONSOLEPLAYER);

if(!IS_CLIENT)
{
// Enable/disable sending of frames (delta sets) to clients.
Set(DD_ALLOW_FRAMES, G_GetGameState() == GS_MAP);

// Tell Doomsday when the game is paused (clients can't pause
// the game.)
Set(DD_CLIENT_PAUSED, P_IsPaused());
}

// Must be called on every tick.
P_RunPlayers(ticLength);
}
else
{
if(!IS_CLIENT)
{
// Disable sending of frames (delta sets) to clients.
Set(DD_ALLOW_FRAMES, false);
}
}

// The following is restricted to fixed 35 Hz ticks.
if(M_RunTrigger(&fixed, ticLength))
Expand Down Expand Up @@ -2562,7 +2656,10 @@ void G_DemoEnds(void)
G_ChangeGameState(GS_WAITING);

if(singledemo)
Sys_Quit();
{
G_SetGameAction(GA_QUIT);
return;
}

FI_DemoEnds();
}
Expand Down
3 changes: 3 additions & 0 deletions doomsday/plugins/common/src/hu_log.c
Expand Up @@ -901,6 +901,9 @@ DEFCC(CCmdMsgAction)
{
int toPlayer;

if(G_GetGameAction() == GA_QUIT)
return false;

if(chatOn)
{
if(!stricmp(argv[0], "chatcomplete")) // send the message
Expand Down
62 changes: 5 additions & 57 deletions doomsday/plugins/common/src/hu_menu.c
Expand Up @@ -249,10 +249,6 @@ static int editcolorindex = 0; // The index of the widgetcolors array of the ite

static float currentcolor[4] = {0, 0, 0, 0}; // Used by the widget as temporay values.

#if !defined( __JHEXEN__ ) && !defined( __JHERETIC__ )
static int quitYet = 0; // Prevents multiple quit responses.
#endif

// Used to fade out the background a little when a widget is active.
static float menu_calpha = 0;

Expand Down Expand Up @@ -3569,60 +3565,9 @@ void M_NewGame(int option, void* context)

int M_QuitResponse(msgresponse_t response, void* context)
{
#if __JDOOM__ || __JDOOM64__
static int quitsounds[8] = {
SFX_PLDETH,
SFX_DMPAIN,
SFX_POPAIN,
SFX_SLOP,
SFX_TELEPT,
SFX_POSIT1,
SFX_POSIT3,
SFX_SGTATK
};
static int quitsounds2[8] = {
SFX_VILACT,
SFX_GETPOW,
# if __JDOOM64__
SFX_PEPAIN,
# else
SFX_BOSCUB,
# endif
SFX_SLOP,
SFX_SKESWG,
SFX_KNTDTH,
SFX_BSPACT,
SFX_SGTATK
};
#endif

if(response == MSG_YES)
{
Hu_MenuCommand(MCMD_CLOSEFAST);

#if __JDOOM__ || __JDOOM64__
// Play an exit sound if it is enabled.
if(cfg.menuQuitSound && !IS_NETGAME)
{
if(!quitYet)
{
if(gameMode == commercial)
S_LocalSound(quitsounds2[((int)GAMETIC >> 2) & 7], NULL);
else
S_LocalSound(quitsounds[((int)GAMETIC >> 2) & 7], NULL);

// Wait for 1.5 seconds.
DD_Executef(true, "activatebcontext deui; after 53 quit!");
quitYet = true;
}
}
else
{
Sys_Quit();
}
#else
Sys_Quit();
#endif
G_SetGameAction(GA_QUIT);
}

return true;
Expand Down Expand Up @@ -4077,7 +4022,10 @@ void MN_DrawSlider(const menu_t* menu, int item, int width, int slot)
*/
DEFCC(CCmdMenuAction)
{
int mode = 0;
int mode = 0;

if(G_GetGameAction() == GA_QUIT)
return false;

if(!menuActive)
{
Expand Down
3 changes: 2 additions & 1 deletion doomsday/plugins/jdoom/include/d_event.h
Expand Up @@ -45,7 +45,8 @@ typedef enum {
GA_COMPLETED,
GA_VICTORY,
GA_LEAVEMAP,
GA_SCREENSHOT
GA_SCREENSHOT,
GA_QUIT
} gameaction_t;

/*
Expand Down
2 changes: 2 additions & 0 deletions doomsday/plugins/jdoom/include/d_refresh.h
Expand Up @@ -34,6 +34,8 @@

#include "p_mobj.h"

extern float quitDarkenOpacity;

void D_Display(int layer);
void D_Display2(void);

Expand Down

0 comments on commit b73de6b

Please sign in to comment.