diff --git a/binaries/data/config/system.cfg b/binaries/data/config/system.cfg index 8189266817..442832427a 100644 --- a/binaries/data/config/system.cfg +++ b/binaries/data/config/system.cfg @@ -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" ; diff --git a/source/graphics/GameView.cpp b/source/graphics/GameView.cpp index 9921eb7074..ae72021347 100755 --- a/source/graphics/GameView.cpp +++ b/source/graphics/GameView.cpp @@ -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 ); diff --git a/source/gui/CGUI.cpp b/source/gui/CGUI.cpp index 45c7dbd1ee..83ece1a1f9 100755 --- a/source/gui/CGUI.cpp +++ b/source/gui/CGUI.cpp @@ -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 ) { diff --git a/source/gui/CInput.cpp b/source/gui/CInput.cpp index 43810bd882..54fa4a3f28 100755 --- a/source/gui/CInput.cpp +++ b/source/gui/CInput.cpp @@ -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(); diff --git a/source/gui/MiniMap.cpp b/source/gui/MiniMap.cpp index 904bc54947..92ee3703f0 100755 --- a/source/gui/MiniMap.cpp +++ b/source/gui/MiniMap.cpp @@ -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) { diff --git a/source/lib/sysdep/win/wsdl.cpp b/source/lib/sysdep/win/wsdl.cpp index 7e28683e52..4b7adb2597 100755 --- a/source/lib/sysdep/win/wsdl.cpp +++ b/source/lib/sysdep/win/wsdl.cpp @@ -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 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(); - } - } -} -*/ diff --git a/source/lib/sysdep/win/wsdl.h b/source/lib/sysdep/win/wsdl.h index 4dcbeb086c..f0d7fbce33 100755 --- a/source/lib/sysdep/win/wsdl.h +++ b/source/lib/sysdep/win/wsdl.h @@ -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, diff --git a/source/main.cpp b/source/main.cpp index 021f1533c6..5f648d9f64 100755 --- a/source/main.cpp +++ b/source/main.cpp @@ -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; diff --git a/source/ps/CConsole.cpp b/source/ps/CConsole.cpp index a1821a5a78..e0f75cf8b1 100755 --- a/source/ps/CConsole.cpp +++ b/source/ps/CConsole.cpp @@ -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 ); diff --git a/source/ps/Hotkey.cpp b/source/ps/Hotkey.cpp index 9f1a4a6506..561f1b07c0 100755 --- a/source/ps/Hotkey.cpp +++ b/source/ps/Hotkey.cpp @@ -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; diff --git a/source/ps/Interact.cpp b/source/ps/Interact.cpp index 644ce50f0e..4b41b3a8f5 100755 --- a/source/ps/Interact.cpp +++ b/source/ps/Interact.cpp @@ -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;