Skip to content

Commit

Permalink
Cleanup|Win32: Moved message pump away from main loop
Browse files Browse the repository at this point in the history
The Win32 message pump is better located in the input subsystem
so that it gets called also during busy mode. Also replaced the global
variables suspendMsgPump and appShutdown with internal API
functions.
  • Loading branch information
skyjake committed Feb 6, 2012
1 parent 8dd648f commit 1f15dd4
Show file tree
Hide file tree
Showing 9 changed files with 82 additions and 62 deletions.
6 changes: 6 additions & 0 deletions doomsday/engine/portable/include/dd_input.h
Expand Up @@ -174,6 +174,12 @@ void DD_StartInput(void);
void DD_StopInput(void);
boolean DD_IgnoreInput(boolean ignore);

#ifdef WIN32
void DD_Win32_SuspendMessagePump(boolean suspend);
#else
# define DD_Win32_SuspendMessagePump(s) // nop
#endif

void DD_ReadKeyboard(void);
void DD_ReadMouse(timespan_t ticLength);
void DD_ReadJoystick(void);
Expand Down
6 changes: 1 addition & 5 deletions doomsday/engine/portable/include/dd_loop.h
Expand Up @@ -29,11 +29,6 @@
#ifndef __DOOMSDAY_BASELOOP_H__
#define __DOOMSDAY_BASELOOP_H__

extern boolean appShutdown;
#ifdef WIN32
extern boolean suspendMsgPump;
#endif

extern int rFrameCount;
extern timespan_t sysTime, gameTime, demoTime, ddMapTime;
extern boolean tickFrame;
Expand All @@ -47,5 +42,6 @@ float DD_GetFrameRate(void);
void DD_ResetTimer(void);
boolean DD_IsSharpTick(void);
boolean DD_IsFrameTimeAdvancing(void);
void DD_SetGameLoopExitCode(int code);

#endif
42 changes: 42 additions & 0 deletions doomsday/engine/portable/src/dd_input.c
Expand Up @@ -31,13 +31,15 @@
#include <ctype.h>
#include <math.h>

#include "de_platform.h"
#include "de_base.h"
#include "de_console.h"
#include "de_infine.h"
#include "de_system.h"
#include "de_misc.h"
#include "de_ui.h"

#include "con_busy.h"
#include "gl_main.h"

// MACROS ------------------------------------------------------------------
Expand Down Expand Up @@ -94,6 +96,10 @@ inputdev_t inputDevices[NUM_INPUT_DEVICES];

// PRIVATE DATA DEFINITIONS ------------------------------------------------

#ifdef WIN32
static boolean suspendMsgPump = false; // Set to true to disable checking windows msgs.
#endif

static boolean ignoreInput = false;

static byte shiftKeyMappings[NUMKKEYS], altKeyMappings[NUMKKEYS];
Expand Down Expand Up @@ -968,11 +974,46 @@ static void dispatchEvents(eventqueue_t* q, timespan_t ticLength)
}
}

#ifdef WIN32
void DD_Win32_SuspendMessagePump(boolean suspend)
{
suspendMsgPump = suspend;
}
#endif

/**
* Poll all event sources (i.e., input devices) and post events.
*/
static void postEvents(timespan_t ticLength)
{
#ifdef WIN32
if(!Con_IsBusyWorker())
{
MSG msg;

/**
* Checking native Windows messages. This must be in the same thread as
* that which registered the window it is handling messages for (main
* thread).
*/
while(!suspendMsgPump &&
PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) > 0)
{
if(msg.message == WM_QUIT)
{
DD_Win32_SuspendMessagePump(true);
DD_SetGameLoopExitCode(msg.wParam);
Sys_Quit();
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
#endif

if(ArgExists("-noinput")) return;

DD_ReadKeyboard();
Expand All @@ -987,6 +1028,7 @@ static void postEvents(timespan_t ticLength)

/**
* Process all incoming input for the given timestamp.
* This is called only in the main thread, and also from the busy loop.
*
* This gets called at least 35 times per second. Usually more frequently
* than that.
Expand Down
52 changes: 14 additions & 38 deletions doomsday/engine/portable/src/dd_loop.c
Expand Up @@ -80,11 +80,6 @@ void DD_RunTics(void);

// PUBLIC DATA DEFINITIONS -------------------------------------------------

boolean appShutdown = false; // Set to true when we should exit (normally).
#ifdef WIN32
boolean suspendMsgPump = false; // Set to true to disable checking windows msgs.
#endif

int maxFrameRate = 200; // Zero means 'unlimited'.
// Refresh frame count (independant of the viewport-specific frameCount).
int rFrameCount = 0;
Expand All @@ -100,6 +95,8 @@ boolean drawGame = true; // If false the game viewport won't be rendered

// PRIVATE DATA DEFINITIONS ------------------------------------------------

static int gameLoopExitCode = 0;

static double lastFrameTime;
static float fps;
static int lastFrameCount;
Expand All @@ -120,57 +117,36 @@ void DD_RegisterLoop(void)
CVF_NO_ARCHIVE | CVF_PROTECTED, 0, 0);
}

void DD_SetGameLoopExitCode(int code)
{
gameLoopExitCode = code;
}

/**
* This is the refresh thread (the main thread).
*/
int DD_GameLoop(void)
{
int exitCode = 0;
#ifdef WIN32
MSG msg;
#endif

// Limit the frame rate to 35 when running in dedicated mode.
if(isDedicated)
{
maxFrameRate = 35;
}

while(!appShutdown)
while(!Sys_IsShuttingDown())
{
#ifdef WIN32
/**
* Start by checking Windows messages.
* \note Must be in the same thread as that which registered the
* window it is handling messages for - DJS.
*/
while(!suspendMsgPump &&
PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) > 0)
{
if(msg.message == WM_QUIT)
{
appShutdown = true;
suspendMsgPump = true;
exitCode = msg.wParam;
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

if(appShutdown)
continue;
#endif

// Frame syncronous I/O operations.
DD_StartFrame();

// Run at least one tic. If no tics are available (maxfps interval
// not reached yet), the function blocks.
DD_RunTics();

// We may have received a Quit message from the windowing system
// during events/tics processing.
if(Sys_IsShuttingDown())
continue;

// Update clients.
Sv_TransmitFrame();

Expand All @@ -186,7 +162,7 @@ int DD_GameLoop(void)
DD_CheckTimeDemo();
}

return exitCode;
return gameLoopExitCode;
}

/**
Expand Down
4 changes: 2 additions & 2 deletions doomsday/engine/portable/src/dd_pinit.c
Expand Up @@ -95,11 +95,11 @@ void DD_ErrorBox(boolean error, char* format, ...)
va_end(args);

#ifdef WIN32
suspendMsgPump = true;
DD_Win32_SuspendMessagePump(true);
MessageBox(NULL, WIN_STRING(buff),
TEXT(DOOMSDAY_NICENAME) DOOMSDAY_VERSION_TEXT_WSTR,
(UINT) (MB_OK | (error ? MB_ICONERROR : MB_ICONWARNING)));
suspendMsgPump = false;
DD_Win32_SuspendMessagePump(false);
#endif

#ifdef UNIX
Expand Down
8 changes: 4 additions & 4 deletions doomsday/engine/portable/src/gl_main.c
Expand Up @@ -207,11 +207,11 @@ void GL_GetGammaRamp(unsigned short *ramp)

if(!hWnd)
{
suspendMsgPump = true;
DD_Win32_SuspendMessagePump(true);
MessageBox(HWND_DESKTOP,
TEXT("GL_GetGammaRamp: Main window not available."), NULL,
MB_ICONERROR | MB_OK);
suspendMsgPump = false;
DD_Win32_SuspendMessagePump(false);
}
else
{
Expand Down Expand Up @@ -299,9 +299,9 @@ void GL_SetGammaRamp(unsigned short* ramp)
}
else
{
suspendMsgPump = true;
DD_Win32_SuspendMessagePump(true);
MessageBox(HWND_DESKTOP, TEXT("GL_SetGammaRamp: Main window not available."), 0, MB_ICONERROR | MB_OK);
suspendMsgPump = false;
DD_Win32_SuspendMessagePump(false);
}}
#endif

Expand Down
20 changes: 11 additions & 9 deletions doomsday/engine/portable/src/sys_system.c
Expand Up @@ -45,9 +45,11 @@
#include "de_audio.h"
#include "de_misc.h"

//int systics = 0; // System tics (every game tic).
int novideo; // if true, stay in text mode for debugging

static boolean appShutdown = false; // Set to true when we should exit (normally).


#ifdef WIN32
/**
* Borrowed from Lee Killough.
Expand Down Expand Up @@ -156,19 +158,19 @@ static int showCriticalMessage(const char* msg)

if(!hWnd)
{
suspendMsgPump = true;
DD_Win32_SuspendMessagePump(true);
MessageBox(HWND_DESKTOP, TEXT("Sys_CriticalMessage: Main window not available."),
NULL, MB_ICONERROR | MB_OK);
suspendMsgPump = false;
DD_Win32_SuspendMessagePump(false);
return false;
}

ShowCursor(TRUE);
ShowCursor(TRUE);
suspendMsgPump = true;
DD_Win32_SuspendMessagePump(true);
GetWindowText(hWnd, buf, 255);
ret = (MessageBox(hWnd, WIN_STRING(msg), buf, MB_OK | MB_ICONEXCLAMATION) == IDYES);
suspendMsgPump = false;
DD_Win32_SuspendMessagePump(false);
ShowCursor(FALSE);
ShowCursor(FALSE);
return ret;
Expand Down Expand Up @@ -265,19 +267,19 @@ void Sys_MessageBox(const char *msg, boolean iserror)

if(!hWnd)
{
suspendMsgPump = true;
DD_Win32_SuspendMessagePump(true);
MessageBox(HWND_DESKTOP,
TEXT("Sys_MessageBox: Main window not available."), NULL,
MB_ICONERROR | MB_OK);
suspendMsgPump = false;
DD_Win32_SuspendMessagePump(false);
return;
}

suspendMsgPump = true;
DD_Win32_SuspendMessagePump(true);
GetWindowText(hWnd, title, 300);
MessageBox(hWnd, WIN_STRING(msg), title,
MB_OK | (iserror ? MB_ICONERROR : MB_ICONINFORMATION));
suspendMsgPump = false;
DD_Win32_SuspendMessagePump(false);
#endif
#ifdef UNIX
fprintf(stderr, "%s %s\n", iserror ? "**ERROR**" : "---", msg);
Expand Down
2 changes: 0 additions & 2 deletions doomsday/engine/win32/include/dd_winit.h
Expand Up @@ -41,8 +41,6 @@ typedef struct {
#else
LPCSTR className;
#endif
BOOL suspendMsgPump; /// @c true = do not pump the Windows message thread.

/// @c true = We are using a custom user dir specified on the command line.
BOOL usingUserDir;

Expand Down
4 changes: 2 additions & 2 deletions doomsday/engine/win32/src/dd_winit.c
Expand Up @@ -515,7 +515,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
switch(msg)
{
case WM_SIZE:
if(!appShutdown)
if(!Sys_IsShuttingDown())
{
switch(wParam)
{
Expand Down Expand Up @@ -599,7 +599,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
break;

case WM_ACTIVATE:
if(!appShutdown)
if(!Sys_IsShuttingDown())
{
if(LOWORD(wParam) == WA_ACTIVE || (!HIWORD(wParam) && LOWORD(wParam) == WA_CLICKACTIVE))
{
Expand Down

0 comments on commit 1f15dd4

Please sign in to comment.