Main and stream decored thread down-throttling, and game sleep when inactive (intended for portables and currently disabled in mainline); bug #1070; from Flandry

git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@3284 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
avolkov
2009-11-05 23:53:43 +00:00
parent a80d533fa7
commit ec9d3e4b72
9 changed files with 79 additions and 4 deletions
+2
View File
@@ -1,4 +1,6 @@
Changes towards version 0.7:
- Thread down-throttling and game sleep when inactive (currently disabled),
(bug #1070), from Flandry
- Internal changes: GOOD_GUY/BAD_GUY ship flags retired - Alex
- Fixed Melee menu timeout when both sides are Cyborgs (bug #1067) - Alex
- Fixed AI ship not moving on warp in (bug #648) - Alex
+13 -3
View File
@@ -56,6 +56,7 @@ TFB_GRAPHICS_BACKEND *graphics_backend = NULL;
int RenderedFrames = 0;
volatile int QuitPosted = 0;
volatile int GameActive = 1; // Track the SDL_ACTIVEEVENT state SDL_APPACTIVE
void
TFB_PreInit (void)
@@ -198,10 +199,19 @@ TFB_ProcessEvents ()
{
/* Run through the InputEvent filter. */
ProcessInputEvent (&Event);
/* Handle Graphics events. */
/* Handle graphics and exposure events. */
switch (Event.type) {
case SDL_ACTIVEEVENT: /* Lose/gain visibility */
// TODO
case SDL_ACTIVEEVENT: /* Lose/gain visibility or focus */
/* Up to three different state changes can occur in one event. */
/* Here, disregard least significant change (mouse focus). */
#if 0 /* Currently disabled in mainline */
// This controls the automatic sleep/pause when minimized.
// On small displays (e.g. mobile devices), APPINPUTFOCUS would
// be an appropriate substitution for APPACTIVE:
// if (Event.active.state & SDL_APPINPUTFOCUS)
if (Event.active.state & SDL_APPACTIVE)
GameActive = Event.active.gain;
#endif
break;
case SDL_QUIT:
QuitPosted = 1;
+1
View File
@@ -37,6 +37,7 @@ extern BYTE LocateMouse (SWORD *px, SWORD *py);
extern volatile int MouseButtonDown;
extern volatile int QuitPosted;
extern volatile int GameActive;
/* Functions for dealing with Character Mode */
+10 -1
View File
@@ -495,11 +495,12 @@ int
StreamDecoderTaskFunc (void *data)
{
Task task = (Task)data;
int active_streams;
int i;
while (!Task_ReadState (task, TASK_EXIT))
{
TaskSwitch ();
active_streams = 0;
for (i = MUSIC_SOURCE; i < NUM_SOUNDSOURCES; ++i)
{
@@ -517,9 +518,17 @@ StreamDecoderTaskFunc (void *data)
}
process_stream (source);
active_streams++;
UnlockMutex (source->stream_mutex);
}
if (active_streams == 0)
{ // Throttle down the thread when there are no active streams
SleepThread (ONE_SECOND / 10);
}
else
TaskSwitch ();
}
FinishTask (task);
+4
View File
@@ -433,6 +433,10 @@ main (int argc, char *argv[])
SignalStopMainThread ();
++i;
}
else if (!GameActive)
{ // Throttle down the main loop when game is inactive
SleepThread (ONE_SECOND / 4);
}
TFB_ProcessEvents ();
ProcessUtilityKeys ();
+1
View File
@@ -100,6 +100,7 @@ void SetMenuRepeatDelay (DWORD min, DWORD max, DWORD step, BOOLEAN gestalt);
void SetDefaultMenuRepeatDelay (void);
void ResetKeyRepeat (void);
BOOLEAN PauseGame (void);
void SleepGame (void);
BOOLEAN DoConfirmExit (void);
BOOLEAN WaitAnyButtonOrQuit (BOOLEAN CheckSpecial);
void WaitForNoInput (SIZE Duration);
+5
View File
@@ -228,6 +228,11 @@ UpdateInputState (void)
* UpdateInputState routinely, so we handle pause and exit
* state updates here. */
// Automatically pause and enter low-activity state while inactive,
// for example, window minimized.
if (!GameActive)
SleepGame ();
if (GamePaused)
PauseGame ();
+1
View File
@@ -106,6 +106,7 @@ SignalStopMainThread (void)
{
GamePaused = FALSE;
GLOBAL (CurrentActivity) |= CHECK_ABORT;
TaskSwitch ();
}
void
+42
View File
@@ -20,9 +20,11 @@
#include "controls.h"
#include "util.h"
#include "setup.h"
#include "settings.h"
#include "libs/inplib.h"
#include "libs/sound/trackplayer.h"
#include "libs/mathlib.h"
#include "libs/log.h"
void
@@ -250,3 +252,43 @@ WaitAnyButtonOrQuit (BOOLEAN CheckSpecial)
return (GLOBAL (CurrentActivity) & CHECK_ABORT) != 0;
}
// Stops game clock and music thread and minimizes interrupts/cycles
// based on value of global GameActive variable
// See similar sleep state for main thread in uqm.c:main()
void
SleepGame (void)
{
if (QuitPosted)
return; // Do not sleep the game when already asked to quit
log_add (log_Debug, "Game is going to sleep");
if (LOBYTE (GLOBAL (CurrentActivity)) != SUPER_MELEE &&
LOBYTE (GLOBAL (CurrentActivity)) != WON_LAST_BATTLE)
SuspendGameClock ();
if (CommData.ConversationPhrases && PlayingTrack ())
PauseTrack ();
PauseMusic ();
LockMutex (GraphicsLock);
while (!GameActive && !QuitPosted)
SleepThread (ONE_SECOND / 2);
log_add (log_Debug, "Game is waking up");
WaitForNoInput (ONE_SECOND / 10);
FlushInput ();
ResumeMusic ();
if (LOBYTE (GLOBAL (CurrentActivity)) != SUPER_MELEE &&
LOBYTE (GLOBAL (CurrentActivity)) != WON_LAST_BATTLE)
ResumeGameClock ();
if (CommData.ConversationPhrases && PlayingTrack ())
ResumeTrack ();
UnlockMutex (GraphicsLock);
TaskSwitch ();
}