Index: variables.h =================================================================== --- variables.h (revision 7151) +++ variables.h (working copy) @@ -282,7 +282,6 @@ VARDEF uint32 _decode_parameters[20]; -VARDEF uint32 _pressed_key; // Low 8 bits = ASCII, High 16 bits = keycode VARDEF bool _ctrl_pressed; // Is Ctrl pressed? VARDEF bool _shift_pressed; // Is Shift pressed? VARDEF byte _dirkeys; // 1 = left, 2 = up, 4 = right, 8 = down Index: video/cocoa_v.m =================================================================== --- video/cocoa_v.m (revision 7151) +++ video/cocoa_v.m (working copy) @@ -347,8 +347,9 @@ } if (down) { - _pressed_key = QZ_MapKey(keycode) | unicode; - DEBUG(driver, 2)("cocoa_v: QZ_KeyEvent: %x (%x), down, mapping: %x", keycode, unicode, _pressed_key); + uint32 pressed_key = QZ_MapKey(keycode) | unicode; + HandleKeypress(pressed_key); + DEBUG(driver, 2)("cocoa_v: QZ_KeyEvent: %x (%x), down, mapping: %x", keycode, unicode, pressed_key); } else { DEBUG(driver, 2)("cocoa_v: QZ_KeyEvent: %x (%x), up", keycode, unicode); } Index: video/sdl_v.c =================================================================== --- video/sdl_v.c (revision 7151) +++ video/sdl_v.c (working copy) @@ -325,6 +325,7 @@ _cursor.pos.y = ev.motion.y; _cursor.dirty = true; } + HandleMouseEvents(); break; case SDL_MOUSEBUTTONDOWN: @@ -347,6 +348,7 @@ default: break; } + HandleMouseEvents(); break; case SDL_MOUSEBUTTONUP: @@ -360,6 +362,7 @@ } else if (ev.button.button == SDL_BUTTON_RIGHT) { _right_button_down = false; } + HandleMouseEvents(); break; case SDL_ACTIVEEVENT: @@ -380,9 +383,9 @@ (ev.key.keysym.sym == SDLK_RETURN || ev.key.keysym.sym == SDLK_f)) { ToggleFullScreen(!_fullscreen); } else { - _pressed_key = ConvertSdlKeyIntoMy(&ev.key.keysym); + uint32 pressed_key = ConvertSdlKeyIntoMy(&ev.key.keysym); + HandleKeypress(pressed_key); } - break; case SDL_VIDEORESIZE: { Index: video/win32_v.c =================================================================== --- video/win32_v.c (revision 7151) +++ video/win32_v.c (working copy) @@ -266,23 +266,27 @@ case WM_LBUTTONDOWN: SetCapture(hwnd); _left_button_down = true; + HandleMouseEvents(); return 0; case WM_LBUTTONUP: ReleaseCapture(); _left_button_down = false; _left_button_clicked = false; + HandleMouseEvents(); return 0; case WM_RBUTTONDOWN: SetCapture(hwnd); _right_button_down = true; _right_button_clicked = true; + HandleMouseEvents(); return 0; case WM_RBUTTONUP: ReleaseCapture(); _right_button_down = false; + HandleMouseEvents(); return 0; case WM_MOUSELEAVE: @@ -290,6 +294,7 @@ _cursor.in_window = false; if (!_left_button_down && !_right_button_down) MyShowCursor(true); + HandleMouseEvents(); return 0; case WM_MOUSEMOVE: { @@ -337,6 +342,7 @@ _cursor.dirty = true; } MyShowCursor(false); + HandleMouseEvents(); return 0; } @@ -346,27 +352,30 @@ WORD w = 0; byte ks[256]; uint scancode; + uint32 pressed_key; GetKeyboardState(ks); if (ToAscii(wParam, 0, ks, &w, 0) == 0) { w = 0; // no translation was possible } - _pressed_key = w | MapWindowsKey(wParam) << 16; + pressed_key = w | MapWindowsKey(wParam) << 16; scancode = GB(lParam, 16, 8); - if (scancode == 41) _pressed_key = w | WKC_BACKQUOTE << 16; + if (scancode == 41) pressed_key = w | WKC_BACKQUOTE << 16; - if ((_pressed_key >> 16) == ('D' | WKC_CTRL) && !_wnd.fullscreen) { + if ((pressed_key >> 16) == ('D' | WKC_CTRL) && !_wnd.fullscreen) { _double_size ^= 1; _wnd.double_size = _double_size; ClientSizeChanged(_wnd.width, _wnd.height); MarkWholeScreenDirty(); } + HandleKeypress(pressed_key); break; } - case WM_SYSKEYDOWN: /* user presses F10 or Alt, both activating the title-menu */ + case WM_SYSKEYDOWN: {/* user presses F10 or Alt, both activating the title-menu */ + uint32 pressed_key; switch (wParam) { case VK_RETURN: case 'F': /* Full Screen on ALT + ENTER/F */ @@ -377,15 +386,17 @@ return 0; // do nothing case VK_F10: /* F10, ignore activation of menu */ - _pressed_key = MapWindowsKey(wParam) << 16; + pressed_key = MapWindowsKey(wParam) << 16; + HandleKeypress(pressed_key); return 0; default: /* ALT in combination with something else */ - _pressed_key = MapWindowsKey(wParam) << 16; + pressed_key = MapWindowsKey(wParam) << 16; + HandleKeypress(pressed_key); break; } break; - + } case WM_SIZE: if (wParam != SIZE_MINIMIZED) { /* Set maximized flag when we maximize (obviously), but also when we @@ -481,6 +492,7 @@ } else if (delta > 0) { _cursor.wheel--; } + HandleMouseEvents(); return 0; } @@ -775,6 +787,24 @@ _wnd.running = true; for (;;) { + /* get status of shift and ctrl buttons just before the message loop gets processed */ + _ctrl_pressed = _wnd.has_focus && GetAsyncKeyState(VK_CONTROL) < 0; + _shift_pressed = _wnd.has_focus && GetAsyncKeyState(VK_SHIFT) < 0; +#ifdef _DEBUG + _dbg_screen_rect = _wnd.has_focus && GetAsyncKeyState(VK_CAPITAL) < 0; +#endif + + // determine which directional keys are down + if (_wnd.has_focus) { + _dirkeys = + (GetAsyncKeyState(VK_LEFT) < 0 ? 1 : 0) + + (GetAsyncKeyState(VK_UP) < 0 ? 2 : 0) + + (GetAsyncKeyState(VK_RIGHT) < 0 ? 4 : 0) + + (GetAsyncKeyState(VK_DOWN) < 0 ? 8 : 0); + } else { + _dirkeys = 0; + } + /* Note that the following message loop now invokes InputLoop() whenever the user input is detected */ while (PeekMessage(&mesg, NULL, 0, 0, PM_REMOVE)) { InteractiveRandom(); // randomness TranslateMessage(&mesg); @@ -789,7 +819,7 @@ if (_wnd.has_focus && GetAsyncKeyState(VK_TAB) < 0) { /* Disable speeding up game with ALT+TAB (if syskey is pressed, the * real key is in the upper 16 bits (see WM_SYSKEYDOWN in WndProcGdi()) */ - if (GetAsyncKeyState(VK_MENU) >= 0 && + if (GetAsyncKeyState(VK_MENU) >= 0 && #endif !_networking && _game_mode != GM_MENU) _fast_forward |= 2; @@ -803,23 +833,7 @@ if (cur_ticks == next_tick) { next_tick += 30; - _ctrl_pressed = _wnd.has_focus && GetAsyncKeyState(VK_CONTROL)<0; - _shift_pressed = _wnd.has_focus && GetAsyncKeyState(VK_SHIFT)<0; -#ifdef _DEBUG - _dbg_screen_rect = _wnd.has_focus && GetAsyncKeyState(VK_CAPITAL)<0; -#endif - // determine which directional keys are down - if (_wnd.has_focus) { - _dirkeys = - (GetAsyncKeyState(VK_LEFT) < 0 ? 1 : 0) + - (GetAsyncKeyState(VK_UP) < 0 ? 2 : 0) + - (GetAsyncKeyState(VK_RIGHT) < 0 ? 4 : 0) + - (GetAsyncKeyState(VK_DOWN) < 0 ? 8 : 0); - } else { - _dirkeys = 0; - } - GameLoop(); _cursor.delta.x = _cursor.delta.y = 0; Index: window.c =================================================================== --- window.c (revision 7151) +++ window.c (working copy) @@ -1397,7 +1397,7 @@ } } -static void HandleKeypress(uint32 key) +void HandleKeypress(uint32 key) { Window *w; WindowEvent e; @@ -1406,6 +1406,17 @@ * to thein this main toolbar. */ bool query_open = false; + /* + * During the generation of the world, there might be + * another thread that is currently building for example + * a road. To not interfere with those tasks, we should + * NOT change the _current_player here. + * + * This is not necessary either, as the only events that + * can be handled are the 'close application' events + */ + if (!IsGeneratingWorld()) _current_player = _local_player; + // Setup event e.event = WE_KEYPRESS; e.we.keypress.ascii = key & 0xFF; @@ -1447,8 +1458,48 @@ extern void UpdateTileSelection(void); extern bool VpHandlePlaceSizingDrag(void); -static void MouseLoop(int click, int mousewheel) +static int _input_events_this_tick = 0; + +void HandleAutoscroll(void) { + Window *w; + ViewPort *vp; + int x = _cursor.pos.x; + int y = _cursor.pos.y; + + if (_input_events_this_tick != 0) { + /* HandleAutoscroll is called only once per GameLoop() - so we can clear the counter here */ + _input_events_this_tick = 0; + /* there were some inputs this tick, don't scroll ??? */ + return; + } + + if (_patches.autoscroll && _game_mode != GM_MENU && !IsGeneratingWorld()) { + w = FindWindowFromPt(x, y); + if (w == NULL || w->flags4 & WF_DISABLE_VP_SCROLL) return; + vp = IsPtInWindowViewport(w, x, y); + if (vp != NULL) { + x -= vp->left; + y -= vp->top; + //here allows scrolling in both x and y axis +#define scrollspeed 3 + if (x - 15 < 0) { + WP(w, vp_d).scrollpos_x += (x - 15) * scrollspeed << vp->zoom; + } else if (15 - (vp->width - x) > 0) { + WP(w, vp_d).scrollpos_x += (15 - (vp->width - x)) * scrollspeed << vp->zoom; + } + if (y - 15 < 0) { + WP(w, vp_d).scrollpos_y += (y - 15) * scrollspeed << vp->zoom; + } else if (15 - (vp->height - y) > 0) { + WP(w,vp_d).scrollpos_y += (15 - (vp->height - y)) * scrollspeed << vp->zoom; + } +#undef scrollspeed + } + } +} + +void MouseLoop(int click, int mousewheel) +{ int x,y; Window *w; ViewPort *vp; @@ -1467,31 +1518,7 @@ x = _cursor.pos.x; y = _cursor.pos.y; - if (click == 0 && mousewheel == 0) { - if (_patches.autoscroll && _game_mode != GM_MENU && !IsGeneratingWorld()) { - w = FindWindowFromPt(x, y); - if (w == NULL || w->flags4 & WF_DISABLE_VP_SCROLL) return; - vp = IsPtInWindowViewport(w, x, y); - if (vp != NULL) { - x -= vp->left; - y -= vp->top; - //here allows scrolling in both x and y axis -#define scrollspeed 3 - if (x - 15 < 0) { - WP(w, vp_d).scrollpos_x += (x - 15) * scrollspeed << vp->zoom; - } else if (15 - (vp->width - x) > 0) { - WP(w, vp_d).scrollpos_x += (15 - (vp->width - x)) * scrollspeed << vp->zoom; - } - if (y - 15 < 0) { - WP(w, vp_d).scrollpos_y += (y - 15) * scrollspeed << vp->zoom; - } else if (15 - (vp->height - y) > 0) { - WP(w,vp_d).scrollpos_y += (15 - (vp->height - y)) * scrollspeed << vp->zoom; - } -#undef scrollspeed - } - } - return; - } + if (click == 0 && mousewheel == 0) return; w = FindWindowFromPt(x, y); if (w == NULL) return; @@ -1548,48 +1575,51 @@ } } -void InputLoop(void) +void HandleMouseEvents(void) { int click; int mousewheel; /* - * During the generation of the world, there might be - * another thread that is currently building for example - * a road. To not interfere with those tasks, we should - * NOT change the _current_player here. - * - * This is not necessary either, as the only events that - * can be handled are the 'close application' events - */ + * During the generation of the world, there might be + * another thread that is currently building for example + * a road. To not interfere with those tasks, we should + * NOT change the _current_player here. + * + * This is not necessary either, as the only events that + * can be handled are the 'close application' events + */ if (!IsGeneratingWorld()) _current_player = _local_player; - // Handle pressed keys - if (_pressed_key != 0) { - HandleKeypress(_pressed_key); - _pressed_key = 0; - } - // Mouse event? click = 0; if (_left_button_down && !_left_button_clicked) { _left_button_clicked = true; click = 1; + _input_events_this_tick++; } else if (_right_button_clicked) { _right_button_clicked = false; click = 2; + _input_events_this_tick++; } mousewheel = 0; if (_cursor.wheel) { mousewheel = _cursor.wheel; _cursor.wheel = 0; + _input_events_this_tick++; } MouseLoop(click, mousewheel); } +void InputLoop(void) +{ + HandleMouseEvents(); + HandleAutoscroll(); +} + static int _we4_timer; void UpdateWindows(void) Index: window.h =================================================================== --- window.h (revision 7151) +++ window.h (working copy) @@ -801,6 +801,8 @@ void ResetWindowSystem(void); int GetMenuItemIndex(const Window *w, int x, int y); void InputLoop(void); +void HandleMouseEvents(void); +void HandleKeypress(uint32 key); // key: Low 8 bits = ASCII, High 16 bits = keycode void UpdateWindows(void); void InvalidateWidget(const Window *w, byte widget_index); void InvalidateThisWindowData(Window *w);