diff --git a/command.c b/command.c index 7c07c5d371..cf48797e75 100644 --- a/command.c +++ b/command.c @@ -463,7 +463,11 @@ bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, CommandCallback *callback, _docommand_recursive = 1; // cost estimation only? - if (!IsGeneratingWorld() && _shift_pressed && IsLocalPlayer() && !(cmd & (CMD_NETWORK_COMMAND | CMD_SHOW_NO_ERROR))) { + if (!IsGeneratingWorld() && + _shift_pressed && + IsLocalPlayer() && + !(cmd & (CMD_NETWORK_COMMAND | CMD_SHOW_NO_ERROR)) && + (cmd & 0xFF) != CMD_PAUSE) { // estimate the cost. res = proc(tile, flags, p1, p2); if (CmdFailed(res)) { diff --git a/main_gui.c b/main_gui.c index 845295035a..abee2978b4 100644 --- a/main_gui.c +++ b/main_gui.c @@ -2308,6 +2308,8 @@ static void MainWindowWndProc(Window *w, WindowEvent *e) const NetworkClientInfo *cio = NetworkFindClientInfoFromIndex(_network_own_client_index); bool teamchat = false; + if (cio == NULL) break; + /* Only players actually playing can speak to team. Eg spectators cannot */ if (_patches.prefer_teamchat && IsValidPlayer(cio->client_playas)) { const NetworkClientInfo *ci; @@ -2329,8 +2331,10 @@ static void MainWindowWndProc(Window *w, WindowEvent *e) case WKC_CTRL | WKC_RETURN: case WKC_CTRL | 'T': // send text to all team mates if (_networking) { - const NetworkClientInfo *ci = NetworkFindClientInfoFromIndex(_network_own_client_index); - ShowNetworkChatQueryWindow(DESTTYPE_TEAM, ci->client_playas); + const NetworkClientInfo *cio = NetworkFindClientInfoFromIndex(_network_own_client_index); + if (cio == NULL) break; + + ShowNetworkChatQueryWindow(DESTTYPE_TEAM, cio->client_playas); } break; #endif diff --git a/video/cocoa_v.m b/video/cocoa_v.m index ba36f85e06..65bb021dfb 100644 --- a/video/cocoa_v.m +++ b/video/cocoa_v.m @@ -652,8 +652,8 @@ static bool QZ_PollEvent(void) static void QZ_GameLoop(void) { - uint32 next_tick = GetTick() + 30; - uint32 cur_ticks; + uint32 cur_ticks = GetTick(); + uint32 next_tick = cur_ticks + 30; uint32 pal_tick = 0; #ifdef _DEBUG uint32 et0, et, st0, st; @@ -682,6 +682,7 @@ static void QZ_GameLoop(void) CSleep(1); for (;;) { + uint32 prev_cur_ticks = cur_ticks; // to check for wrapping InteractiveRandom(); // randomness while (QZ_PollEvent()) {} @@ -700,11 +701,8 @@ static void QZ_GameLoop(void) } cur_ticks = GetTick(); - if ((_fast_forward && !_pause) || cur_ticks > next_tick) - next_tick = cur_ticks; - - if (cur_ticks == next_tick) { - next_tick += 30; + if (cur_ticks >= next_tick || (_fast_forward && !_pause) || cur_ticks < prev_cur_ticks) { + next_tick = cur_ticks + 30; _ctrl_pressed = !!(_cocoa_video_data.current_mods & NSControlKeyMask); _shift_pressed = !!(_cocoa_video_data.current_mods & NSShiftKeyMask); diff --git a/video/dedicated_v.c b/video/dedicated_v.c index e0124e02c0..968899c49e 100644 --- a/video/dedicated_v.c +++ b/video/dedicated_v.c @@ -224,10 +224,8 @@ static void DedicatedHandleKeyInput(void) static void DedicatedVideoMainLoop(void) { - uint32 next_tick; - uint32 cur_ticks; - - next_tick = GetTime() + 30; + uint32 cur_ticks = GetTime(); + uint32 next_tick = cur_ticks + 30; /* Signal handlers */ #ifdef UNIX @@ -269,15 +267,15 @@ static void DedicatedVideoMainLoop(void) } while (!_exit_game) { + uint32 prev_cur_ticks = cur_ticks; // to check for wrapping InteractiveRandom(); // randomness if (!_dedicated_forks) DedicatedHandleKeyInput(); cur_ticks = GetTime(); - - if (cur_ticks >= next_tick) { - next_tick += 30; + if (cur_ticks >= next_tick || cur_ticks < prev_cur_ticks) { + next_tick = cur_ticks + 30; GameLoop(); _screen.dst_ptr = _dedicated_video_mem; diff --git a/video/sdl_v.c b/video/sdl_v.c index 11a65bda9d..f52809446a 100644 --- a/video/sdl_v.c +++ b/video/sdl_v.c @@ -422,14 +422,15 @@ static void SdlVideoStop(void) static void SdlVideoMainLoop(void) { - uint32 next_tick = SDL_CALL SDL_GetTicks() + 30; - uint32 cur_ticks; + uint32 cur_ticks = SDL_CALL SDL_GetTicks(); + uint32 next_tick = cur_ticks + 30; uint32 pal_tick = 0; uint32 mod; int numkeys; Uint8 *keys; for (;;) { + uint32 prev_cur_ticks = cur_ticks; // to check for wrapping InteractiveRandom(); // randomness while (PollEvent() == -1) {} @@ -451,11 +452,8 @@ static void SdlVideoMainLoop(void) } cur_ticks = SDL_CALL SDL_GetTicks(); - if ((_fast_forward && !_pause) || cur_ticks > next_tick) - next_tick = cur_ticks; - - if (cur_ticks == next_tick) { - next_tick += 30; + if (cur_ticks >= next_tick || (_fast_forward && !_pause) || cur_ticks < prev_cur_ticks) { + next_tick = cur_ticks + 30; _ctrl_pressed = !!(mod & KMOD_CTRL); _shift_pressed = !!(mod & KMOD_SHIFT); diff --git a/video/win32_v.c b/video/win32_v.c index e9fb1ca78e..8c90d351ad 100644 --- a/video/win32_v.c +++ b/video/win32_v.c @@ -786,11 +786,14 @@ static void CheckPaletteAnim(void) static void Win32GdiMainLoop(void) { MSG mesg; - uint32 next_tick = GetTickCount() + 30, cur_ticks; + uint32 cur_ticks = GetTickCount(); + uint32 next_tick = cur_ticks + 30; _wnd.running = true; for (;;) { + uint32 prev_cur_ticks = cur_ticks; // to check for wrapping + while (PeekMessage(&mesg, NULL, 0, 0, PM_REMOVE)) { InteractiveRandom(); // randomness DispatchMessage(&mesg); @@ -810,11 +813,8 @@ static void Win32GdiMainLoop(void) } cur_ticks = GetTickCount(); - if ((_fast_forward && !_pause) || cur_ticks > next_tick) - next_tick = cur_ticks; - - if (cur_ticks == next_tick) { - next_tick += 30; + if (cur_ticks >= next_tick || (_fast_forward && !_pause) || cur_ticks < prev_cur_ticks) { + next_tick = cur_ticks + 30; _ctrl_pressed = _wnd.has_focus && GetAsyncKeyState(VK_CONTROL)<0; _shift_pressed = _wnd.has_focus && GetAsyncKeyState(VK_SHIFT)<0; #ifdef _DEBUG