1
0
forked from 0ad/0ad

replace g_active with more clear g_app_has_focus and g_app_minimized

reinstate g_keys - realized that atlas mode cannot call SDL_GetKeyState
main: use g_app_minimized etc. to use up less CPU time when app isn't
active (makes debugging more bearable)

This was SVN commit r3070.
This commit is contained in:
janwas 2005-10-31 18:36:36 +00:00
parent 8c76dc34af
commit 6af5888866
12 changed files with 159 additions and 168 deletions

View File

@ -25,6 +25,7 @@
#include "Loader.h"
#include "Profile.h"
#include "ps/LoaderThunks.h"
#include "ps/Globals.h"
#include "Quaternion.h"
#include "Unit.h"
@ -40,7 +41,6 @@ float g_YMinOffset=25.0f;
extern int g_xres, g_yres;
extern bool g_active;
static CVector3D cameraBookmarks[10];
static bool bookmarkInUse[10] = { false, false, false, false, false, false, false, false, false, false };
@ -344,7 +344,7 @@ void CGameView::RotateAboutTarget()
void CGameView::Update(float DeltaTime)
{
if (!g_active)
if (!g_app_has_focus)
return;
float delta = powf( m_ViewSnapSmoothness, DeltaTime );
@ -592,7 +592,7 @@ InReaction game_view_handler(const SDL_Event* ev)
{
// put any events that must be processed even if inactive here
if(!g_active || !g_Game)
if(!g_app_has_focus || !g_Game)
return IN_PASS;
CGameView *pView=g_Game->GetView();

View File

@ -255,12 +255,11 @@ InReaction CGUI::HandleEvent(const SDL_Event* ev)
// Handle keys for input boxes
if (GetFocusedObject())
{
Uint8* keys = SDL_GetKeyState(0);
if (
(ev->type == SDL_KEYDOWN &&
ev->key.keysym.sym != SDLK_ESCAPE &&
!keys[SDLK_LCTRL] && !keys[SDLK_RCTRL] &&
!keys[SDLK_LALT] && !keys[SDLK_RALT])
!g_keys[SDLK_LCTRL] && !g_keys[SDLK_RCTRL] &&
!g_keys[SDLK_LALT] && !g_keys[SDLK_RALT])
|| ev->type == SDL_HOTKEYDOWN
)
{

View File

@ -63,8 +63,6 @@ InReaction CInput::ManuallyHandleEvent(const SDL_Event* ev)
// pointer and edit that.
CStrW *pCaption = (CStrW*)m_Settings["caption"].m_pSetting;
Uint8* keys = SDL_GetKeyState(0);
if (ev->type == SDL_HOTKEYDOWN)
{
if (ev->user.code == HOTKEY_CONSOLE_PASTE)
@ -151,7 +149,7 @@ InReaction CInput::ManuallyHandleEvent(const SDL_Event* ev)
case SDLK_HOME:
// If there's not a selection, we should create one now
if (!keys[SDLK_RSHIFT] && !keys[SDLK_LSHIFT])
if (!g_keys[SDLK_RSHIFT] && !g_keys[SDLK_LSHIFT])
{
// Make sure a selection isn't created.
m_iBufferPos_Tail = -1;
@ -170,7 +168,7 @@ InReaction CInput::ManuallyHandleEvent(const SDL_Event* ev)
case SDLK_END:
// If there's not a selection, we should create one now
if (!keys[SDLK_RSHIFT] && !keys[SDLK_LSHIFT])
if (!g_keys[SDLK_RSHIFT] && !g_keys[SDLK_LSHIFT])
{
// Make sure a selection isn't created.
m_iBufferPos_Tail = -1;
@ -213,11 +211,11 @@ InReaction CInput::ManuallyHandleEvent(const SDL_Event* ev)
// reset m_WantedX, very important
m_WantedX=0.f;
if (keys[SDLK_RSHIFT] || keys[SDLK_LSHIFT] ||
if (g_keys[SDLK_RSHIFT] || g_keys[SDLK_LSHIFT] ||
!SelectingText())
{
// If there's not a selection, we should create one now
if (!SelectingText() && !keys[SDLK_RSHIFT] && !keys[SDLK_LSHIFT])
if (!SelectingText() && !g_keys[SDLK_RSHIFT] && !g_keys[SDLK_LSHIFT])
{
// Make sure a selection isn't created.
m_iBufferPos_Tail = -1;
@ -245,11 +243,11 @@ InReaction CInput::ManuallyHandleEvent(const SDL_Event* ev)
case SDLK_RIGHT:
m_WantedX=0.f;
if (keys[SDLK_RSHIFT] || keys[SDLK_LSHIFT] ||
if (g_keys[SDLK_RSHIFT] || g_keys[SDLK_LSHIFT] ||
!SelectingText())
{
// If there's not a selection, we should create one now
if (!SelectingText() && !keys[SDLK_RSHIFT] && !keys[SDLK_LSHIFT])
if (!SelectingText() && !g_keys[SDLK_RSHIFT] && !g_keys[SDLK_LSHIFT])
{
// Make sure a selection isn't created.
m_iBufferPos_Tail = -1;
@ -298,7 +296,7 @@ InReaction CInput::ManuallyHandleEvent(const SDL_Event* ev)
case SDLK_UP:
{
// If there's not a selection, we should create one now
if (!keys[SDLK_RSHIFT] && !keys[SDLK_LSHIFT])
if (!g_keys[SDLK_RSHIFT] && !g_keys[SDLK_LSHIFT])
{
// Make sure a selection isn't created.
m_iBufferPos_Tail = -1;
@ -346,7 +344,7 @@ InReaction CInput::ManuallyHandleEvent(const SDL_Event* ev)
case SDLK_DOWN:
{
// If there's not a selection, we should create one now
if (!keys[SDLK_RSHIFT] && !keys[SDLK_LSHIFT])
if (!g_keys[SDLK_RSHIFT] && !g_keys[SDLK_LSHIFT])
{
// Make sure a selection isn't created.
m_iBufferPos_Tail = -1;
@ -454,8 +452,6 @@ void CInput::HandleMessage(const SGUIMessage &Message)
// TODO Gee:
IGUIScrollBarOwner::HandleMessage(Message);
Uint8* keys = SDL_GetKeyState(0);
switch (Message.type)
{
case GUIM_SETTINGS_UPDATED:
@ -533,7 +529,7 @@ void CInput::HandleMessage(const SGUIMessage &Message)
// instance, if we press between a and b, the point
// should of course be placed accordingly. Other
// special cases are handled like the input box norms.
if (keys[SDLK_RSHIFT] || keys[SDLK_LSHIFT])
if (g_keys[SDLK_RSHIFT] || g_keys[SDLK_LSHIFT])
{
m_iBufferPos = GetMouseHoveringTextPosition();
}

View File

@ -96,8 +96,6 @@ static HGLRC hGLRC = (HGLRC)INVALID_HANDLE_VALUE;
static int depth_bits = 24; // depth buffer size; set via SDL_GL_SetAttribute
static u16 mouse_x, mouse_y;
Uint8 SDL_GetAppState()
{
@ -352,6 +350,22 @@ Uint8* SDL_GetKeyState(int* num_keys)
}
//----------------------------------------------------------------------------
static u16 mouse_x, mouse_y;
static uint mouse_buttons;
Uint8 SDL_GetMouseState(int* x, int* y)
{
if(x)
*x = (int)mouse_x;
if(y)
*y = (int)mouse_y;
return (Uint8)mouse_buttons;
}
//----------------------------------------------------------------------------
static LRESULT CALLBACK wndproc(HWND hWnd, uint uMsg, WPARAM wParam, LPARAM lParam)
@ -545,6 +559,12 @@ static LRESULT CALLBACK wndproc(HWND hWnd, uint uMsg, WPARAM wParam, LPARAM lPar
outstanding_press_events = 0;
}
// update bits
if(state == SDL_PRESSED)
mouse_buttons |= SDL_BUTTON(button);
else
mouse_buttons &= ~SDL_BUTTON(button);
uint x = LOWORD(lParam);
uint y = HIWORD(lParam);
queue_button_event(button, state, x, y);

View File

@ -213,6 +213,11 @@ enum SDL_MouseButtonEvent_button
SDL_BUTTON_WHEELDOWN = 5
};
#define SDL_BUTTON(b) (SDL_PRESSED << (b-1))
#define SDL_BUTTON_LMASK SDL_BUTTON(SDL_BUTTON_LEFT)
#define SDL_BUTTON_MMASK SDL_BUTTON(SDL_BUTTON_MIDDLE)
#define SDL_BUTTON_RMASK SDL_BUTTON(SDL_BUTTON_RIGHT)
enum SDL_MouseButtonEvent_state
{
SDL_RELEASED = 0,
@ -283,94 +288,10 @@ extern int SDL_PushEvent(SDL_Event* ev);
extern void SDL_WM_SetCaption(const char *title, const char *icon);
extern Uint8* SDL_GetKeyState(int* num_keys);
extern Uint8 SDL_GetMouseState(int* x, int* y);
// glutInitDisplayMode
#define GLUT_RGB 0
#define GLUT_DOUBLE 0
#define GLUT_DEPTH 0
// mouse buttons
enum
{
GLUT_LEFT_BUTTON,
GLUT_RIGHT_BUTTON,
GLUT_MIDDLE_BUTTON // also wheel, if avail
};
// mouse button state
enum
{
GLUT_DOWN,
GLUT_UP
};
// keys
enum
{
GLUT_KEY_LEFT = 0x25, // VK_*
GLUT_KEY_RIGHT = 0x27,
GLUT_KEY_UP = 0x26,
GLUT_KEY_DOWN = 0x28
};
// glutSetCursor
#define GLUT_CURSOR_INHERIT 32512 // IDC_*
#define GLUT_CURSOR_WAIT 32514
#define GLUT_CURSOR_DESTROY 32648
#define GLUT_CURSOR_NONE 0
// glutGet
enum
{
GLUT_ELAPSED_TIME,
GLUT_SCREEN_WIDTH,
GLUT_SCREEN_HEIGHT,
GLUT_GAME_MODE_WIDTH,
GLUT_GAME_MODE_HEIGHT,
GLUT_GAME_MODE_PIXEL_DEPTH,
GLUT_GAME_MODE_REFRESH_RATE
};
extern void glutIdleFunc(void(*)());
extern void glutDisplayFunc(void(*)());
extern void glutKeyboardFunc(void(*)(int, int, int));
extern void glutSpecialFunc(void(*)(int, int, int));
extern void glutMouseFunc(void(*)(int, int, int, int));
#define glutInitDisplayMode(a) // pixel format is hardwired
extern int glutGameModeString(const char* str);
extern void glutInit(int* argc, char* argv[]);
extern int glutGet(int arg);
extern int glutEnterGameMode(void);
extern void glutMainLoop(void);
extern void glutPostRedisplay(void);
extern void glutSetCursor(int);
#define glutSwapBuffers SDL_GL_SwapBuffers
//( SDLMod and KMOD_* already defined by SDL_keysym.h)
extern SDLMod SDL_GetModState(void);
#ifdef __cplusplus

View File

@ -26,16 +26,17 @@ that of Atlas depending on commandline parameters.
#include "ps/GameSetup/Atlas.h"
#include "ps/GameSetup/Config.h"
#include "ps/Loader.h"
#include "gui/GUI.h"
#include "ps/CConsole.h"
#include "ps/Profile.h"
#include "ps/Util.h"
#include "ps/Game.h"
#include "ps/Hotkey.h"
#include "ps/Globals.h"
#include "ps/Interact.h"
#include "ps/Network/SessionManager.h"
#include "simulation/Scheduler.h"
#include "sound/CMusicPlayer.h"
#include "gui/GUI.h"
#define LOG_CATEGORY "main"
@ -129,54 +130,87 @@ static void Frame()
MICROLOG(L"Frame");
oglCheck();
const uint app_state = SDL_GetAppState();
PROFILE_START( "update music" );
music_player.update();
PROFILE_END( "update music" );
// get elapsed time
calc_fps();
// old method - "exact" but contains jumps
// .. old method - "exact" but contains jumps
#if 0
static double last_time;
const double time = get_time();
const float TimeSinceLastFrame = (float)(time-last_time);
last_time = time;
ONCE(return); // first call: set last_time and return
// new method - filtered and more smooth, but errors may accumulate
// .. new method - filtered and more smooth, but errors may accumulate
#else
const float TimeSinceLastFrame = spf;
#endif
debug_assert(TimeSinceLastFrame >= 0.0f);
PROFILE_START( "reload changed files" );
MICROLOG(L"reload files");
// decide if update/render is necessary
bool need_render, need_update;
if(g_app_minimized)
{
// TODO: eventually update ought to be re-enabled so the server host
// can Alt+Tab out without the match hanging. however, game updates
// are currently really slow and disabling them makes debugging nicer.
need_update = false;
need_render = false;
// inactive; relinquish CPU for a little while
// don't use SDL_WaitEvent: don't want the main loop to freeze until app focus is restored
SDL_Delay(10);
}
else if(!g_app_has_focus)
{
need_update = false; // see above
need_render = true;
SDL_Delay(5); // see above
}
// active
else
{
need_update = true;
need_render = true;
}
// TODO: throttling: limit update and render frequency to the minimum.
// this is mostly relevant for "inactive" state, so that other windows
// get enough CPU time, but it's always nice for power+thermal management.
PROFILE_START( "update music" );
music_player.update();
PROFILE_END( "update music" );
PROFILE_START("reload changed files");
MICROLOG(L"reload changed files");
vfs_reload_changed_files();
PROFILE_END( "reload changed files" );
PROFILE_END( "reload changed files");
PROFILE_START( "progressive load" );
PROFILE_START("progressive load");
MICROLOG(L"progressive load");
ProgressiveLoad();
PROFILE_END( "progressive load" );
PROFILE_END( "progressive load");
PROFILE_START( "input" );
PROFILE_START("input");
MICROLOG(L"input");
PumpEvents();
g_SessionManager.Poll();
PROFILE_END( "input" );
PROFILE_END("input");
oglCheck();
PROFILE_START( "gui tick" );
PROFILE_START("gui tick");
MICROLOG(L"gui tick");
#ifndef NO_GUI
g_GUI.TickObjects();
#endif
PROFILE_END( "gui tick" );
PROFILE_END("gui tick");
oglCheck();
PROFILE_START( "game logic" );
if (g_Game && g_Game->IsGameStarted())
if (g_Game && g_Game->IsGameStarted() && need_update)
{
PROFILE_START( "simulation update" );
g_Game->Update(TimeSinceLastFrame);
@ -221,11 +255,9 @@ static void Frame()
g_Console->Update(TimeSinceLastFrame);
PROFILE_END( "update console" );
PROFILE_START( "render" );
PROFILE_START("render");
oglCheck();
if(app_state & SDL_APPACTIVE)
if(need_render)
{
MICROLOG(L"render");
Render();
@ -234,20 +266,14 @@ static void Frame()
SDL_GL_SwapBuffers();
PROFILE_END( "swap buffers" );
}
// inactive; relinquish CPU for a little while
// don't use SDL_WaitEvent: don't want the main loop to freeze until app focus is restored
else
SDL_Delay(5);
oglCheck();
PROFILE_END( "render" );
PROFILE_END("render");
g_Profiler.Frame();
if(g_FixedFrameTiming && frameCount==100)
kill_mainloop();
// clear terrain modified flag
g_TerrainModified = false;
}

View File

@ -280,6 +280,7 @@ void CConsole::DrawBuffer(void)
void CConsole::DrawCursor(void)
{
// (glPushMatrix is necessary because glwprintf does glTranslatef)
glPushMatrix();
// Slightly translucent yellow
glColor4f(1.0f, 1.0f, 0.0f, 0.8f);
@ -301,8 +302,6 @@ void CConsole::InsertChar(const int szChar, const wchar_t cooked )
if (!m_bVisible) return;
Uint8* keys = SDL_GetKeyState(0);
switch (szChar){
case '\r':
case '\n':
@ -346,7 +345,7 @@ void CConsole::InsertChar(const int szChar, const wchar_t cooked )
return;
case SDLK_HOME:
if (keys[SDLK_RCTRL] || keys[SDLK_LCTRL])
if (g_keys[SDLK_RCTRL] || g_keys[SDLK_LCTRL])
{
int linesShown = (int)m_fHeight/m_iFontHeight - 4;
m_iMsgHistPos = clamp((int)m_deqMsgHistory.size() - linesShown, 1, (int)m_deqMsgHistory.size());
@ -358,7 +357,7 @@ void CConsole::InsertChar(const int szChar, const wchar_t cooked )
return;
case SDLK_END:
if (keys[SDLK_RCTRL] || keys[SDLK_LCTRL])
if (g_keys[SDLK_RCTRL] || g_keys[SDLK_LCTRL])
{
m_iMsgHistPos = 1;
}
@ -673,8 +672,8 @@ InReaction conInputHandler(const SDL_Event* ev)
// SB: Not safe, really.. Swedish keyboards have {[]} on AltGr (Ctrl-Alt)
// for example, so I commented those tests.
if( ( ev->key.keysym.sym != SDLK_ESCAPE ) &&
/*!keys[SDLK_LCTRL] && !keys[SDLK_RCTRL] &&
!keys[SDLK_LALT] && !keys[SDLK_RALT] &&*/
/*!g_keys[SDLK_LCTRL] && !g_keys[SDLK_RCTRL] &&
!g_keys[SDLK_LALT] && !g_keys[SDLK_RALT] &&*/
!hotkeys[HOTKEY_CONSOLE_TOGGLE] )
g_Console->InsertChar(sym, (wchar_t)ev->key.keysym.unicode );

View File

@ -4,14 +4,15 @@
#include "Globals.h"
bool g_active = true;
bool g_app_minimized = false;
bool g_app_has_focus = true;
bool g_keys[SDLK_LAST];
bool g_keys[SDLK_LAST] = {0};
int g_mouse_x = 50, g_mouse_y = 50;
// unused, left, right, middle, wheel up, wheel down
// (order is given by SDL_BUTTON_* constants).
bool g_mouse_buttons[6];
bool g_mouse_buttons[6] = {0};
// updates the state of the above; never swallows messages.
@ -23,7 +24,9 @@ InReaction GlobalsInputHandler(const SDL_Event* ev)
{
case SDL_ACTIVEEVENT:
if(ev->active.state & SDL_APPACTIVE)
g_active = (ev->active.gain != 0);
g_app_minimized = (ev->active.gain == 0); // negated
if(ev->active.state & SDL_APPINPUTFOCUS)
g_app_has_focus = (ev->active.gain != 0);
return IN_PASS;
case SDL_MOUSEMOTION:
@ -40,6 +43,19 @@ InReaction GlobalsInputHandler(const SDL_Event* ev)
debug_warn("invalid mouse button");
return IN_PASS;
case SDL_KEYDOWN:
case SDL_KEYUP:
c = ev->key.keysym.sym;
if(c < ARRAY_SIZE(g_keys))
g_keys[c] = (ev->type == SDL_KEYDOWN);
else
{
// don't complain: this happens when the hotkey system
// spoofs keys (it assigns values starting from SDLK_LAST)
//debug_warn("invalid key");
}
return IN_PASS;
default:
return IN_PASS;
}

View File

@ -1,14 +1,30 @@
extern bool g_active;
#include "lib/input.h"
#include "lib/sdl.h"
// thin abstraction layer on top of SDL.
// game code should use it instead of SDL_GetMouseState etc. because
// Atlas does not completely emulate SDL (it can only send events).
extern bool g_app_minimized;
extern bool g_app_has_focus;
extern int g_mouse_x, g_mouse_y;
/**
* g_keys: Key states, indexed by SDLK* constants. If an entry is true,
* it represents a pressed key.
* Updated by GlobalsInputHandler in response to key press/release events.
*/
extern bool g_keys[SDLK_LAST];
/**
* g_mouse_buttons: Mouse buttons states, indexed by SDL_BUTTON_* constants. If an entry
* is true, it represents a pressed button.
* g_mouse_buttons: Mouse buttons states, indexed by SDL_BUTTON_* constants.
* If an entry is true, it represents a pressed button.
* Updated by GlobalsInputHandler in response to mouse button up/down events.
*
* Be aware that SDL_BUTTON_* constants start at 1. Therefore, g_mouse_buttons[0] is unused.
* Thus, the order of entries is { unused, left, right, middle, wheel up, wheel down }
* Be aware that SDL_BUTTON_* constants start at 1. Therefore,
* g_mouse_buttons[0] is unused. The order of entries is:
* { unused, left, right, middle, wheel up, wheel down }
*/
extern bool g_mouse_buttons[6];

View File

@ -10,7 +10,7 @@
extern CConsole* g_Console;
static Uint8 unified[5];
static bool unified[5];
/* SDL-type */
@ -47,7 +47,7 @@ const int HK_MAX_KEYCODES = UNIFIED_SUPER + 1;
static KeyMapping hotkeyMap[HK_MAX_KEYCODES];
// An array of the status of virtual keys
Uint8 hotkeys[HOTKEY_LAST];
bool hotkeys[HOTKEY_LAST];
struct SHotkeyInfo
@ -320,7 +320,6 @@ void hotkeyRegisterGUIObject( const CStr& objName, const CStr& hotkeyName )
InReaction hotkeyInputHandler( const SDL_Event* ev )
{
int keycode = 0;
Uint8* keys = SDL_GetKeyState(0);
switch( ev->type )
{
@ -426,17 +425,17 @@ InReaction hotkeyInputHandler( const SDL_Event* ev )
for( itKey = it->requires.begin(); itKey != it->requires.end(); itKey++ )
{
int keyCode = *itKey & ~HOTKEY_NEGATION_FLAG; // Clear the negation-modifier bit
Uint8 rqdState = ( *itKey & HOTKEY_NEGATION_FLAG ) == 0;
bool rqdState = ( *itKey & HOTKEY_NEGATION_FLAG ) == 0;
// debug_assert( !rqdState );
if( keyCode < SDLK_LAST )
{
if( keys[keyCode] != rqdState ) accept = false;
if( g_keys[keyCode] != rqdState ) accept = false;
}
else if( keyCode < UNIFIED_SHIFT )
{
if( (Uint8)g_mouse_buttons[keyCode-SDLK_LAST] != rqdState ) accept = false;
if( g_mouse_buttons[keyCode-SDLK_LAST] != rqdState ) accept = false;
}
else if( (uint)(keyCode-UNIFIED_SHIFT) < ARRAY_SIZE(unified) )
{
@ -497,15 +496,15 @@ InReaction hotkeyInputHandler( const SDL_Event* ev )
for( itKey = itGUI->requires.begin(); itKey != itGUI->requires.end(); itKey++ )
{
int keyCode = *itKey & ~HOTKEY_NEGATION_FLAG; // Clear the negation-modifier bit
Uint8 rqdState = ( *itKey & HOTKEY_NEGATION_FLAG ) == 0;
bool rqdState = ( *itKey & HOTKEY_NEGATION_FLAG ) == 0;
if( keyCode < SDLK_LAST )
{
if( keys[keyCode] != rqdState ) accept = false;
if( g_keys[keyCode] != rqdState ) accept = false;
}
else if( keyCode < UNIFIED_SHIFT )
{
if( (Uint8)g_mouse_buttons[keyCode-SDLK_LAST] != rqdState ) accept = false;
if( g_mouse_buttons[keyCode-SDLK_LAST] != rqdState ) accept = false;
}
else if( (uint)(keyCode-UNIFIED_SHIFT) < ARRAY_SIZE(unified) )
{
@ -572,7 +571,7 @@ InReaction hotkeyInputHandler( const SDL_Event* ev )
{
if( *itKey < SDLK_LAST )
{
if( !keys[*itKey] ) accept = false;
if( !g_keys[*itKey] ) accept = false;
}
else if( *itKey < UNIFIED_SHIFT )
{

View File

@ -112,4 +112,4 @@ extern int getKeyCode( CStr keyname );
extern bool keyRespondsTo( int hotkey, int sdlkey );
extern Uint8 hotkeys[HOTKEY_LAST];
extern bool hotkeys[HOTKEY_LAST];

View File

@ -10,6 +10,7 @@
#include "Hotkey.h"
#include "timer.h"
#include "Game.h"
#include "ps/Globals.h"
#include "Network/NetMessage.h"
#include "BoundingObjects.h"
#include "Unit.h"
@ -20,8 +21,6 @@
#include "MathUtil.h"
extern CConsole* g_Console;
extern int g_mouse_x, g_mouse_y;
extern bool g_active;
extern CStr g_CursorName;
static const double SELECT_DBLCLICK_RATE = 0.5;
@ -827,7 +826,7 @@ void MouseButtonUpHandler(const SDL_Event *ev, int clicks)
InReaction interactInputHandler( const SDL_Event* ev )
{
if (!g_active || !g_Game)
if (!g_app_has_focus || !g_Game)
return IN_PASS;
CGameView *pView=g_Game->GetView();