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:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 ();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 ();
|
||||
|
||||
|
||||
@@ -106,6 +106,7 @@ SignalStopMainThread (void)
|
||||
{
|
||||
GamePaused = FALSE;
|
||||
GLOBAL (CurrentActivity) |= CHECK_ABORT;
|
||||
TaskSwitch ();
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -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 ();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user