1
0
forked from 0ad/0ad

GameView: move camera lock params here

wsdl: add proper event queuing mechanism (no longer requires hacky
polling for changes and avoids WM_USER)
rename keys[] and mouse_buttons to g_keys and g_mouse_buttons
fix flipped mouse wheel direction; wsdl now sends up AND down event
(removed 'reset' hack in main.cpp)
main: clean up event handler and kill_mainloop

This was SVN commit r2934.
This commit is contained in:
janwas 2005-10-13 18:05:55 +00:00
parent 991d6c438c
commit 7b31f0372b
11 changed files with 290 additions and 454 deletions

View File

@ -118,8 +118,8 @@ hotkey.camera.reset = "H" ; Reset camera rotation to default.
hotkey.camera.reset.origin = "Ctrl+H" ; Reset camera to origin.
hotkey.camera.zoom.in = Plus, Equals, NumPlus ; Zoom camera in.
hotkey.camera.zoom.out = Minus, NumMinus ; Zoom camera out.
hotkey.camera.zoom.wheel.in = WheelDown ; Zoom camera in (wheel speed).
hotkey.camera.zoom.wheel.out = WheelUp ; Zoom camera out (wheel speed).
hotkey.camera.zoom.wheel.in = WheelUp ; Zoom camera in (wheel speed).
hotkey.camera.zoom.wheel.out = WheelDown ; Zoom camera out (wheel speed).
hotkey.camera.rotate = "Ctrl+MouseMiddle" ; Rotate view by moving mouse, maintaining the
; absolute position of the camera
hotkey.camera.rotate.keyboard = "Shift" ;

View File

@ -36,8 +36,9 @@
#include "lib.h"
#include "timer.h"
extern float g_MaxZoomHeight;
extern float g_YMinOffset;
float g_MaxZoomHeight=350.0f; //note: Max terrain height is this minus YMinOffset
float g_YMinOffset=50.0f;
extern int g_xres, g_yres;
extern bool g_active;
@ -619,8 +620,8 @@ int CGameView::HandleEvent(const SDL_Event* ev)
return( EV_HANDLED );
// Mouse wheel must be treated using events instead of polling,
// because SDL auto-generates a sequence of mousedown/mouseup events automatically
// on Linux, and we never get to see the "down" state inside Update().
// because SDL auto-generates a sequence of mousedown/mouseup events
// and we never get to see the "down" state inside Update().
case HOTKEY_CAMERA_ZOOM_WHEEL_IN:
m_ZoomDelta += m_ViewZoomSensitivityWheel;
return( EV_HANDLED );

View File

@ -55,7 +55,7 @@ JSClass GUIClass = {
// Globals used.
extern int g_xres, g_yres;
extern bool keys[SDLK_LAST];
extern bool g_keys[];
//-------------------------------------------------------------------
// called from main loop when (input) events are received.
@ -164,8 +164,6 @@ int CGUI::HandleEvent(const SDL_Event* ev)
}
break;
// TODO Gee (!!!): This is weird, I've tested this, and mousewheelup is
// what I would call mousewheeldown!
case SDL_BUTTON_WHEELDOWN: // wheel down
if (pNearest)
{
@ -247,8 +245,8 @@ int CGUI::HandleEvent(const SDL_Event* ev)
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

@ -20,8 +20,8 @@ gee@pyro.nu
#include "ps/CLogger.h"
#define LOG_CATEGORY "gui"
extern bool keys[SDLK_LAST];
extern bool mouse_buttons[5];
extern bool g_keys[];
extern bool g_mouse_buttons[];
using namespace std;
@ -151,7 +151,7 @@ int 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 +170,7 @@ int 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 +213,11 @@ int 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 +245,11 @@ int 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 +298,7 @@ int 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 +346,7 @@ int 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;
@ -531,7 +531,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();
}
@ -562,7 +562,7 @@ void CInput::HandleMessage(const SGUIMessage &Message)
{
// Actually, first we need to re-check that the mouse button is
// really pressed (it can be released while outside the control.
if (!mouse_buttons[SDL_BUTTON_LEFT])
if (!g_mouse_buttons[SDL_BUTTON_LEFT])
m_SelectingText = false;
else
m_iBufferPos = GetMouseHoveringTextPosition();

View File

@ -19,7 +19,7 @@
extern bool mouse_buttons[5];
extern bool g_mouse_buttons[5];
extern int g_mouse_x, g_mouse_y;
extern float g_MaxZoomHeight, g_YMinOffset;
bool HasClicked=false;
@ -142,13 +142,13 @@ void CMiniMap::Draw()
CCamera &g_Camera=*g_Game->GetView()->GetCamera();
//Check for a click
if(mouse_buttons[0]==true)
if(g_mouse_buttons[0]==true)
{
HasClicked=true;
}
//Check to see if left button is false (meaning it's been lifted)
if (mouse_buttons[0]==false && HasClicked==true)
if (g_mouse_buttons[0]==false && HasClicked==true)
{

View File

@ -178,75 +178,6 @@ int SDL_SetGamma(float r, float g, float b)
//----------------------------------------------------------------------------
// shared msg handler
// SDL and GLUT have separate pumps; messages are handled there
// evil no-good hack: this msg is apparently sent directly to the wndproc,
// so we have to pass it on to SDL_PollEvent.
static bool got_quit_msg;
static LRESULT CALLBACK wndproc(HWND hWnd, unsigned int uMsg, WPARAM wParam, LPARAM lParam)
{
if(is_shutdown)
return DefWindowProc(hWnd, uMsg, wParam, lParam);
switch(uMsg)
{
case WM_DESTROY:
got_quit_msg = true;
break;
case WM_PAINT:
PAINTSTRUCT ps;
BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
return 0;
case WM_ERASEBKGND:
return 0;
case WM_ACTIVATE:
app_active = (wParam & 0xffff) != 0;
gamma_swap(app_active? GAMMA_LATCH_NEW_RAMP : GAMMA_RESTORE_ORIGINAL);
if(fullscreen)
// (re)activating
if(app_active)
{
ChangeDisplaySettings(&dm, CDS_FULLSCREEN);
ShowWindow(hWnd, SW_RESTORE);
}
// deactivating
else
{
ChangeDisplaySettings(0, 0);
ShowWindow(hWnd, SW_MINIMIZE);
}
break;
// prevent selecting menu in fullscreen mode
case WM_NCHITTEST:
if(fullscreen)
return HTCLIENT;
break;
default:;
// can't call DefWindowProc here: some messages
// are only conditionally 'grabbed' (e.g. NCHITTEST)
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
// always on (we don't care about the extra overhead)
int SDL_EnableUNICODE(int UNUSED(enable))
{
return 1;
}
// Translate Windows VK's into our SDLK's for keys that must be translated
static void init_vkmap(SDLKey (&VK_keymap)[256])
{
int i;
@ -342,9 +273,190 @@ inline SDLKey vkmap(int vk)
}
//----------------------------------------------------------------------------
typedef std::queue<SDL_Event> Queue;
static Queue queue;
static void queue_event(const SDL_Event& ev)
{
queue.push(ev);
}
static bool dequeue_event(SDL_Event* ev)
{
if(queue.empty())
return false;
*ev = queue.front();
queue.pop();
return true;
}
static inline void queue_active_event()
{
// SDL says this event is not generated when the window is created;
// therefore, skip the first time.
ONCE(return);
SDL_Event ev;
ev.type = SDL_ACTIVEEVENT;
ev.active.state = SDL_APPACTIVE;
ev.active.gain = (u8)app_active;
queue_event(ev);
}
static void queue_quit_event()
{
SDL_Event ev;
ev.type = SDL_QUIT;
queue_event(ev);
}
static void queue_button_event(uint button, uint state, LPARAM lParam)
{
SDL_Event ev;
ev.type = (state == SDL_PRESSED)? SDL_MOUSEBUTTONDOWN : SDL_MOUSEBUTTONUP;
ev.button.button = (u8)button;
ev.button.state = (u8)state;
ev.button.x = LOWORD(lParam);
ev.button.y = HIWORD(lParam);
queue_event(ev);
}
static LRESULT CALLBACK wndproc(HWND hWnd, uint uMsg, WPARAM wParam, LPARAM lParam)
{
if(is_shutdown)
return DefWindowProc(hWnd, uMsg, wParam, lParam);
switch(uMsg)
{
case WM_PAINT:
PAINTSTRUCT ps;
BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
return 0;
case WM_ERASEBKGND:
return 0;
// prevent selecting menu in fullscreen mode
case WM_NCHITTEST:
if(fullscreen)
return HTCLIENT;
break;
case WM_ACTIVATE:
app_active = LOWORD(wParam) != 0;
gamma_swap(app_active? GAMMA_LATCH_NEW_RAMP : GAMMA_RESTORE_ORIGINAL);
if(fullscreen)
{
// (re)activating
if(app_active)
{
ChangeDisplaySettings(&dm, CDS_FULLSCREEN);
ShowWindow(hWnd, SW_RESTORE);
}
// deactivating
else
{
ChangeDisplaySettings(0, 0);
ShowWindow(hWnd, SW_MINIMIZE);
}
}
queue_active_event();
break;
case WM_DESTROY:
queue_quit_event();
break;
case WM_SYSCOMMAND:
switch(wParam)
{
// prevent moving, sizing, screensaver, and power-off in fullscreen mode
case SC_MOVE:
case SC_SIZE:
case SC_MAXIMIZE:
case SC_MONITORPOWER:
if(fullscreen)
return 1;
break;
// Alt+F4 or system menu doubleclick/exit
case SC_CLOSE:
queue_quit_event();
break;
}
break;
case WM_SYSKEYUP:
case WM_KEYUP:
// TODO Mappings for left/right modifier keys
// TODO Modifier statekeeping
{
SDL_Event ev;
ev.type = SDL_KEYUP;
ev.key.keysym.sym = vkmap((int)wParam);
ev.key.keysym.unicode = 0;
queue_event(ev);
}
return 1;
case WM_MOUSEWHEEL:
{
short delta = (short)HIWORD(wParam);
uint button = (delta < 0)? SDL_BUTTON_WHEELDOWN : SDL_BUTTON_WHEELUP;
// SDL says this sends a down message followed by up.
queue_button_event(button, SDL_PRESSED, lParam);
queue_button_event(button, SDL_RELEASED, lParam);
}
break;
case WM_LBUTTONDOWN:
queue_button_event(SDL_BUTTON_LEFT, SDL_PRESSED, lParam);
break;
case WM_LBUTTONUP:
queue_button_event(SDL_BUTTON_LEFT, SDL_RELEASED, lParam);
break;
case WM_RBUTTONDOWN:
queue_button_event(SDL_BUTTON_RIGHT, SDL_PRESSED, lParam);
break;
case WM_RBUTTONUP:
queue_button_event(SDL_BUTTON_RIGHT, SDL_RELEASED, lParam);
break;
case WM_MBUTTONDOWN:
queue_button_event(SDL_BUTTON_MIDDLE, SDL_PRESSED, lParam);
break;
case WM_MBUTTONUP:
queue_button_event(SDL_BUTTON_MIDDLE, SDL_RELEASED, lParam);
break;
default:
// can't call DefWindowProc here: some messages
// are only conditionally 'grabbed' (e.g. NCHITTEST)
break;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
// always on (we don't care about the extra overhead)
int SDL_EnableUNICODE(int UNUSED(enable))
{
return 1;
}
// Translate Windows VK's into our SDLK's for keys that must be translated
int SDL_WaitEvent(SDL_Event* ev)
{
debug_assert(ev == 0 && "can't store event, since wsdl doesn't have a real queue");
debug_assert(ev == 0 && "storing ev isn't implemented");
WaitMessage();
return 0;
}
@ -384,124 +496,59 @@ return_char:
}
if(dequeue_event(ev))
return 1;
// events that trigger messages (mouse done below)
MSG msg;
while(PeekMessageW(&msg, 0, 0, 0, PM_REMOVE))
{
DispatchMessageW(&msg);
int sdl_btn = -1;
switch(msg.message)
{
case WM_SYSCOMMAND:
switch(msg.wParam)
{
// prevent moving, sizing, screensaver, and power-off in fullscreen mode
case SC_MOVE:
case SC_SIZE:
case SC_MAXIMIZE:
case SC_MONITORPOWER:
if(fullscreen)
return 1;
break;
case SC_CLOSE:
ev->type = SDL_QUIT;
return 1;
default:
break;
}
break;
case WM_SYSKEYDOWN:
case WM_KEYDOWN:
{
UINT vk = (UINT)msg.wParam;
UINT scancode = (UINT)((msg.lParam >> 16) & 0xff);
u8 key_states[256];
GetKeyboardState(key_states);
{
UINT vk = (UINT)msg.wParam;
UINT scancode = (UINT)((msg.lParam >> 16) & 0xff);
u8 key_states[256];
GetKeyboardState(key_states);
num_chars = ToUnicode(vk, scancode, key_states, char_buf, CHAR_BUF_SIZE, 0);
next_char_idx = 0;
if(num_chars > 0)
{
// Translation complete: Produce one or more Unicode chars
char_buf[num_chars]=0;
translated_keysym=vkmap(vk);
//wprintf(L"ToUnicode: Translated %02x to [%s], %d chars, SDLK %02x. Extended flag %d, scancode %d\n", vk, char_buf, num_chars, translated_keysym, msg.lParam & 0x01000000, scancode);
goto return_char;
}
else if (num_chars == -1)
{
// Dead Key: Don't produce an event for this one
//printf("ToUnicode: Dead Key %02x [%c] [%c] SDLK %02x\n", vk, vk, char_buf[0], vkmap(vk));
num_chars = 0;
break;
num_chars = ToUnicode(vk, scancode, key_states, char_buf, CHAR_BUF_SIZE, 0);
next_char_idx = 0;
if(num_chars > 0)
{
// Translation complete: Produce one or more Unicode chars
char_buf[num_chars]=0;
translated_keysym=vkmap(vk);
//wprintf(L"ToUnicode: Translated %02x to [%s], %d chars, SDLK %02x. Extended flag %d, scancode %d\n", vk, char_buf, num_chars, translated_keysym, msg.lParam & 0x01000000, scancode);
goto return_char;
}
else if (num_chars == -1)
{
// Dead Key: Don't produce an event for this one
//printf("ToUnicode: Dead Key %02x [%c] [%c] SDLK %02x\n", vk, vk, char_buf[0], vkmap(vk));
num_chars = 0;
break;
// leave the switch statement; get next message.
}
// num_chars == 0: No translation: Just produce a plain KEYDOWN event
}
// num_chars == 0: No translation: Just produce a plain KEYDOWN event
// TODO Mappings for left/right modifier keys
// TODO Modifier statekeeping
// TODO Mappings for left/right modifier keys
// TODO Modifier statekeeping
ev->type = SDL_KEYDOWN;
ev->key.keysym.sym = vkmap(vk);
ev->key.keysym.unicode = 0;
ev->type = SDL_KEYDOWN;
ev->key.keysym.sym = vkmap(vk);
ev->key.keysym.unicode = 0;
//printf("ToUnicode: No translation for %02x, extended flag %d, scancode %d, SDLK %02x [%c]\n", vk, msg.lParam & 0x01000000, scancode, ev->key.keysym.sym, ev->key.keysym.sym);
//printf("ToUnicode: No translation for %02x, extended flag %d, scancode %d, SDLK %02x [%c]\n", vk, msg.lParam & 0x01000000, scancode, ev.key.keysym.sym, ev.key.keysym.sym);
return 1;
}
case WM_SYSKEYUP:
case WM_KEYUP:
// TODO Mappings for left/right modifier keys
// TODO Modifier statekeeping
ev->type = SDL_KEYUP;
ev->key.keysym.sym = vkmap((int)msg.wParam);
ev->key.keysym.unicode = 0;
return 1;
case WM_MOUSEWHEEL:
sdl_btn = (msg.wParam & BIT(31))? SDL_BUTTON_WHEELUP : SDL_BUTTON_WHEELDOWN;
break; // event filled in mouse code below
default:
if( ( msg.message >= WM_APP ) && ( msg.message < 0xC000 ) ) // 0xC000 = maximum application message
{
debug_assert( SDL_USEREVENT+(msg.message-WM_APP) <= 0xff && "Message too far above WM_APP");
ev->type = (u8)(SDL_USEREVENT+(msg.message-WM_APP));
ev->user.code = (int)msg.wParam;
return 1;
}
break;
}
// mouse button
// map Win L(up,down,double),R(),M() to L,R,M with up flag
uint btn = msg.message-0x201; // 0..8 if it's a valid button;
if(btn < 9 && btn%3 != 2) // every third msg is dblclick
sdl_btn = SDL_BUTTON_LEFT + btn/3; // assumes L,R,M
if(sdl_btn != -1)
{
ev->type = (u8)(SDL_MOUSEBUTTONDOWN + btn%3);
ev->button.button = (u8)sdl_btn;
ev->button.x = (u16)(msg.lParam & 0xffff);
ev->button.y = (u16)((msg.lParam >> 16) & 0xffff);
return 1;
}
}
if(got_quit_msg)
{
got_quit_msg = false;
ev->type = SDL_QUIT;
return 1;
}
// mouse motion
//
// don't use DirectInput, because we want to respect the user's mouse
@ -517,30 +564,12 @@ return_char:
return 1;
}
// app activate
// WM_ACTIVATE is only sent to the wndproc, apparently,
// so we have to poll here.
static bool last_app_active = true;
// true => suppress first event (as documented by SDL)
if(app_active != last_app_active)
{
last_app_active = app_active;
ev->type = SDL_ACTIVEEVENT;
ev->active.state = SDL_APPACTIVE;
ev->active.gain = (u8)app_active;
return 1;
}
return 0;
}
int SDL_PushEvent(SDL_Event* ev)
{
if( ev->type < SDL_USEREVENT )
return -1;
// Use Windows app-global user events.
PostMessage(NULL, WM_APP + ( ev->type - SDL_USEREVENT ), ev->user.code, 0);
queue_event(*ev);
return 0;
}
@ -771,7 +800,7 @@ keep:
RECT r;
r.left = r.top = 0;
r.right = w; r.bottom = h;
if (AdjustWindowRectEx(&r, windowStyle, false, 0))
if (AdjustWindowRectEx(&r, windowStyle, FALSE, 0))
{
w = r.right - r.left;
h = r.bottom - r.top;
@ -1086,181 +1115,3 @@ int SDL_KillThread(SDL_Thread* thread)
return 0;
}
/*
static bool need_redisplay; // display callback should be called in next main loop iteration
// glut callbacks
static void (*idle)();
static void (*display)();
static void (*key)(int, int, int);
static void (*special)(int, int, int);
static void (*mouse)(int, int, int, int);
void glutIdleFunc(void (*func)())
{ idle = func; }
void glutDisplayFunc(void (*func)())
{ display = func; }
void glutKeyboardFunc(void (*func)(int, int, int))
{ key = func; }
void glutSpecialFunc(void (*func)(int, int, int))
{ special = func; }
void glutMouseFunc(void (*func)(int, int, int, int))
{ mouse = func; }
void glutInit(int* UNUSED(argc), char* UNUSED(argv)[])
{
SDL_Init(0);
atexit(SDL_Quit);
}
int glutGet(int arg)
{
if(arg == GLUT_ELAPSED_TIME)
return GetTickCount();
dm.dmSize = sizeof(DEVMODE);
EnumDisplaySettings(0, ENUM_CURRENT_SETTINGS, &dm);
if(arg == GLUT_SCREEN_WIDTH)
return dm.dmPelsWidth;
if(arg == GLUT_SCREEN_HEIGHT)
return dm.dmPelsHeight;
return 0;
}
static int w, h, bpp, refresh;
int glutGameModeString(const char* str)
{
// default = "don't care", in case string doesn't specify all values
w = 0, h = 0, bpp = 0, refresh = 0;
sscanf(str, "%dx%d:%d@%d", &w, &h, &bpp, &refresh);
return 1;
}
int glutEnterGameMode()
{
return SDL_SetVideoMode(w, h, bpp, SDL_OPENGL|SDL_FULLSCREEN);
}
inline void glutPostRedisplay()
{
need_redisplay = true;
}
void glutSetCursor(int cursor)
{
SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(cursor)));
}
// GLUT message handler
// message also goes to the shared wndproc
//
// not done in wndproc to separate GLUT and SDL;
// split out of glutMainLoop for clarity.
static void glut_process_msg(MSG* msg)
{
switch(msg->message)
{
case WM_PAINT:
need_redisplay = true;
break;
case WM_CHAR:
if(key)
key((int)msg->wParam, mouse_x, mouse_y);
break;
case WM_KEYDOWN:
if(special)
special((int)msg->wParam, mouse_x, mouse_y);
break;
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN: // FIXME: only left/right clicks, assume GLUT_LEFT|RIGHT_BUTTON == 0, 1
if(mouse)
mouse(msg->message == WM_RBUTTONDOWN, GLUT_DOWN, (int)(msg->lParam & 0xffff), (int)(msg->lParam >> 16));
break;
case WM_MOUSEWHEEL:
if(mouse)
mouse(GLUT_MIDDLE_BUTTON, ((short)(msg->wParam >> 16) > 0)? GLUT_UP : GLUT_DOWN, 0, 0);
break;
}
}
void glutMainLoop()
{
for(;;)
{
if(!app_active)
WaitMessage();
MSG msg;
if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
glut_process_msg(&msg);
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if(idle)
idle();
if(need_redisplay)
{
need_redisplay = false;
display();
}
}
}
*/

View File

@ -202,8 +202,7 @@ typedef struct
}
SDL_QuitEvent;
// SDL_MouseButtonEvent.button
enum
enum SDL_MouseButtonEvent_button
{
// do not change order or values
// ... but if you do, update lib/sdl.h so that SDL_BUTTON_TO_INDEX still
@ -216,6 +215,12 @@ enum
SDL_BUTTON_WHEELDOWN=4
};
enum SDL_MouseButtonEvent_state
{
SDL_RELEASED = 0,
SDL_PRESSED = 1
};
typedef struct
{
Uint8 type;
@ -225,8 +230,7 @@ typedef struct
}
SDL_MouseButtonEvent;
// SDL_ActiveEvent.state
enum
enum SDL_ActiveEvent_state
{
SDL_APPACTIVE = 1,
SDL_APPMOUSEFOCUS = 2,
@ -248,8 +252,7 @@ typedef struct
}
SDL_UserEvent;
// SDL_Event.type
enum
enum SDL_Event_type
{
SDL_KEYDOWN,
SDL_KEYUP,

View File

@ -40,25 +40,21 @@ that of Atlas depending on commandline parameters.
#define LOG_CATEGORY "main"
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
void kill_mainloop();
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//
// main app message handler
//
bool keys[SDLK_LAST];
bool mouse_buttons[6]; // CAN REMOVE AFTER MOVING RESET TO WSDL
bool g_active = true;
bool g_keys[SDLK_LAST];
int g_mouse_x = 50, g_mouse_y = 50;
float g_MaxZoomHeight=350.0f; //note: Max terrain height is this minus YMinOffset
float g_YMinOffset=50.0f;
// left, right, middle, wheel up, wheel down
// (order is given by SDL_BUTTON_* constants).
bool g_mouse_buttons[5];
static int MainInputHandler(const SDL_Event* ev)
{
@ -74,46 +70,48 @@ static int MainInputHandler(const SDL_Event* ev)
g_active = (ev->active.gain != 0);
break;
case SDL_MOUSEMOTION:
g_mouse_x = ev->motion.x;
g_mouse_y = ev->motion.y;
break;
case SDL_KEYDOWN:
case SDL_KEYUP:
c = ev->key.keysym.sym;
// Prevent out-of-range writes on faked key events
if (c < SDLK_LAST)
keys[c] = (ev->type == SDL_KEYDOWN);
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("MainInputHandler: invalid key");
}
break;
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
c = ev->button.button;
if(c < ARRAY_SIZE(mouse_buttons))
mouse_buttons[c] = (ev->type == SDL_MOUSEBUTTONDOWN);
if(c < ARRAY_SIZE(g_mouse_buttons))
g_mouse_buttons[c] = (ev->type == SDL_MOUSEBUTTONDOWN);
else
debug_warn("MainInputHandler: invalid mouse button");
break;
case SDL_MOUSEMOTION:
g_mouse_x = ev->motion.x;
g_mouse_y = ev->motion.y;
break;
case SDL_HOTKEYDOWN:
switch(ev->user.code)
{
case HOTKEY_EXIT:
kill_mainloop();
break;
return EV_HANDLED;
case HOTKEY_SCREENSHOT:
WriteScreenshot("png");
break;
case HOTKEY_PLAYMUSIC:
break;
return EV_HANDLED;
default:
return EV_PASS;
break;
}
return EV_HANDLED;
break;
}
return EV_PASS;
@ -255,21 +253,6 @@ static void Frame()
g_Console->Update(TimeSinceLastFrame);
PROFILE_END( "update console" );
// TODO: ugly, but necessary. these are one-shot events, have to be reset.
// Spoof mousebuttonup events for the hotkey system
SDL_Event spoof;
spoof.type = SDL_MOUSEBUTTONUP;
spoof.button.button = SDL_BUTTON_WHEELUP;
if( mouse_buttons[SDL_BUTTON_WHEELUP] )
hotkeyInputHandler( &spoof );
spoof.button.button = SDL_BUTTON_WHEELDOWN;
if( mouse_buttons[SDL_BUTTON_WHEELDOWN] )
hotkeyInputHandler( &spoof );
mouse_buttons[SDL_BUTTON_WHEELUP] = false;
mouse_buttons[SDL_BUTTON_WHEELDOWN] = false;
PROFILE_START( "render" );
oglCheck();
@ -322,7 +305,8 @@ static void MainControllerShutdown()
static bool quit = false; // break out of main loop
// HACK: Let code from other files (i.e. the scripting system) quit
// stop the main loop and trigger orderly shutdown. called from several
// places: the event handler (SDL_QUIT and hotkey) and JS exitProgram.
void kill_mainloop()
{
quit = true;

View File

@ -18,7 +18,7 @@
#include "Interact.h"
extern bool keys[SDLK_LAST];
extern bool g_keys[];
CConsole* g_Console = 0;
@ -345,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());
@ -357,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;
}
@ -674,8 +674,8 @@ int 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

@ -8,8 +8,8 @@
#include "CStr.h"
extern CConsole* g_Console;
extern bool keys[SDLK_LAST];
extern bool mouse_buttons[5];
extern bool g_keys[];
extern bool g_mouse_buttons[];
bool unified[5];
/* SDL-type */
@ -423,11 +423,11 @@ int hotkeyInputHandler( const SDL_Event* ev )
if( keyCode < SDLK_LAST )
{
if( keys[keyCode] != rqdState ) accept = false;
if( g_keys[keyCode] != rqdState ) accept = false;
}
else if( keyCode < UNIFIED_SHIFT )
{
if( 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) )
{
@ -490,11 +490,11 @@ int hotkeyInputHandler( const SDL_Event* ev )
if( keyCode < SDLK_LAST )
{
if( keys[keyCode] != rqdState ) accept = false;
if( g_keys[keyCode] != rqdState ) accept = false;
}
else if( keyCode < UNIFIED_SHIFT )
{
if( 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) )
{
@ -561,11 +561,11 @@ int 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 )
{
if( !mouse_buttons[(*itKey)-SDLK_LAST] ) accept = false;
if( !g_mouse_buttons[(*itKey)-SDLK_LAST] ) accept = false;
}
else
if( !unified[(*itKey)-UNIFIED_SHIFT] ) accept = false;

View File

@ -21,7 +21,6 @@
extern CConsole* g_Console;
extern int g_mouse_x, g_mouse_y;
extern bool keys[SDLK_LAST];
extern bool g_active;
extern CStr g_CursorName;