diff --git a/src/video/cocoa/CMakeLists.txt b/src/video/cocoa/CMakeLists.txt index 8bcc6b2e03..968a98a91d 100644 --- a/src/video/cocoa/CMakeLists.txt +++ b/src/video/cocoa/CMakeLists.txt @@ -4,6 +4,5 @@ add_files( cocoa_v.mm cocoa_wnd.h cocoa_wnd.mm - event.mm CONDITION APPLE ) diff --git a/src/video/cocoa/cocoa_v.h b/src/video/cocoa/cocoa_v.h index 0112f57515..8ebf5ba6e1 100644 --- a/src/video/cocoa/cocoa_v.h +++ b/src/video/cocoa/cocoa_v.h @@ -70,7 +70,7 @@ public: /* --- The following methods should be private, but can't be due to Obj-C limitations. --- */ /** Main game loop. */ - void GameLoop(); // In event.mm. + void GameLoop(); void AllocateBackingStore(); diff --git a/src/video/cocoa/cocoa_v.mm b/src/video/cocoa/cocoa_v.mm index 07640a0f83..c35ee9b7dd 100644 --- a/src/video/cocoa/cocoa_v.mm +++ b/src/video/cocoa/cocoa_v.mm @@ -27,16 +27,21 @@ #include "../../openttd.h" #include "../../debug.h" #include "../../core/geometry_type.hpp" +#include "../../core/math_func.hpp" #include "cocoa_v.h" #include "cocoa_wnd.h" #include "../../blitter/factory.hpp" +#include "../../framerate_type.h" +#include "../../network/network.h" #include "../../gfx_func.h" +#include "../../thread.h" +#include "../../core/random_func.hpp" +#include "../../settings_type.h" #include "../../window_func.h" #include "../../window_gui.h" -#include "../../core/math_func.hpp" -#include "../../framerate_type.h" #import /* for MAXPATHLEN */ +#import /* gettimeofday */ /** * Important notice regarding all modifications!!!!!!! @@ -55,6 +60,12 @@ bool _cocoa_video_started = false; +extern bool _tab_is_down; + +#ifdef _DEBUG +static uint32 _tEvent; +#endif + /** List of common display/window sizes. */ static const Dimension _default_resolutions[] = { @@ -75,6 +86,15 @@ static const Dimension _default_resolutions[] = { static FVideoDriver_Cocoa iFVideoDriver_Cocoa; +static uint32 GetTick() +{ + struct timeval tim; + + gettimeofday(&tim, NULL); + return tim.tv_usec / 1000 + tim.tv_sec * 1000; +} + + /* Subclass of OTTD_CocoaView to fix Quartz rendering */ @interface OTTD_QuartzView : NSView { VideoDriver_Cocoa *driver; @@ -578,6 +598,105 @@ void VideoDriver_Cocoa::CheckPaletteAnim() } +bool VideoDriver_Cocoa::PollEvent() +{ +#ifdef _DEBUG + uint32 et0 = GetTick(); +#endif + NSEvent *event = [ NSApp nextEventMatchingMask:NSAnyEventMask untilDate:[ NSDate distantPast ] inMode:NSDefaultRunLoopMode dequeue:YES ]; +#ifdef _DEBUG + _tEvent += GetTick() - et0; +#endif + + if (event == nil) return false; + + [ NSApp sendEvent:event ]; + + return true; +} + + +void VideoDriver_Cocoa::GameLoop() +{ + uint32 cur_ticks = GetTick(); + uint32 last_cur_ticks = cur_ticks; + uint32 next_tick = cur_ticks + MILLISECONDS_PER_TICK; + +#ifdef _DEBUG + uint32 et0 = GetTick(); + uint32 st = 0; +#endif + + for (;;) { + @autoreleasepool { + + uint32 prev_cur_ticks = cur_ticks; // to check for wrapping + InteractiveRandom(); // randomness + + while (this->PollEvent()) {} + + if (_exit_game) { + /* Restore saved resolution if in fullscreen mode. */ + if (this->IsFullscreen()) _cur_resolution = this->orig_res; + break; + } + + NSUInteger cur_mods = [ NSEvent modifierFlags ]; + +#if defined(_DEBUG) + if (cur_mods & NSShiftKeyMask) { +#else + if (_tab_is_down) { +#endif + if (!_networking && _game_mode != GM_MENU) _fast_forward |= 2; + } else if (_fast_forward & 2) { + _fast_forward = 0; + } + + cur_ticks = GetTick(); + if (cur_ticks >= next_tick || (_fast_forward && !_pause_mode) || cur_ticks < prev_cur_ticks) { + _realtime_tick += cur_ticks - last_cur_ticks; + last_cur_ticks = cur_ticks; + next_tick = cur_ticks + MILLISECONDS_PER_TICK; + + bool old_ctrl_pressed = _ctrl_pressed; + + _ctrl_pressed = (cur_mods & ( _settings_client.gui.right_mouse_btn_emulation != RMBE_CONTROL ? NSControlKeyMask : NSCommandKeyMask)) != 0; + _shift_pressed = (cur_mods & NSShiftKeyMask) != 0; + + if (old_ctrl_pressed != _ctrl_pressed) HandleCtrlChanged(); + + ::GameLoop(); + + UpdateWindows(); + this->CheckPaletteAnim(); + this->Draw(); + } else { +#ifdef _DEBUG + uint32 st0 = GetTick(); +#endif + CSleep(1); +#ifdef _DEBUG + st += GetTick() - st0; +#endif + NetworkDrawChatMessage(); + DrawMouseCursor(); + this->Draw(); + } + } + } + +#ifdef _DEBUG + uint32 et = GetTick(); + + DEBUG(driver, 1, "cocoa_v: nextEventMatchingMask took %i ms total", _tEvent); + DEBUG(driver, 1, "cocoa_v: game loop took %i ms total (%i ms without sleep)", et - et0, et - et0 - st); + DEBUG(driver, 1, "cocoa_v: (nextEventMatchingMask total)/(game loop total) is %f%%", (double)_tEvent / (double)(et - et0) * 100); + DEBUG(driver, 1, "cocoa_v: (nextEventMatchingMask total)/(game loop without sleep total) is %f%%", (double)_tEvent / (double)(et - et0 - st) * 100); +#endif +} + + @implementation OTTD_QuartzView - (instancetype)initWithFrame:(NSRect)frameRect andDriver:(VideoDriver_Cocoa *)drv diff --git a/src/video/cocoa/event.mm b/src/video/cocoa/event.mm deleted file mode 100644 index c7ab70538d..0000000000 --- a/src/video/cocoa/event.mm +++ /dev/null @@ -1,165 +0,0 @@ -/* - * This file is part of OpenTTD. - * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. - * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . - */ - -/****************************************************************************** - * Cocoa video driver * - * Known things left to do: * - * Nothing at the moment. * - ******************************************************************************/ - -#ifdef WITH_COCOA - -#include "../../stdafx.h" - -#define Rect OTTDRect -#define Point OTTDPoint -#import -#undef Rect -#undef Point - -#include "../../openttd.h" -#include "../../debug.h" -#include "../../settings_type.h" -#include "../../core/geometry_type.hpp" -#include "cocoa_v.h" -#include "cocoa_wnd.h" -#include "../../blitter/factory.hpp" -#include "../../gfx_func.h" -#include "../../network/network.h" -#include "../../core/random_func.hpp" -#include "../../core/math_func.hpp" -#include "../../texteff.hpp" -#include "../../window_func.h" -#include "../../thread.h" - -#import /* gettimeofday */ - -/** - * Important notice regarding all modifications!!!!!!! - * There are certain limitations because the file is objective C++. - * gdb has limitations. - * C++ and objective C code can't be joined in all cases (classes stuff). - * Read http://developer.apple.com/releasenotes/Cocoa/Objective-C++.html for more information. - */ - -extern bool _tab_is_down; - -#ifdef _DEBUG -static uint32 _tEvent; -#endif - - -static uint32 GetTick() -{ - struct timeval tim; - - gettimeofday(&tim, NULL); - return tim.tv_usec / 1000 + tim.tv_sec * 1000; -} - -bool VideoDriver_Cocoa::PollEvent() -{ -#ifdef _DEBUG - uint32 et0 = GetTick(); -#endif - NSEvent *event = [ NSApp nextEventMatchingMask:NSAnyEventMask - untilDate:[ NSDate distantPast ] - inMode:NSDefaultRunLoopMode dequeue:YES ]; -#ifdef _DEBUG - _tEvent += GetTick() - et0; -#endif - - if (event == nil) return false; - - [ NSApp sendEvent:event ]; - - return true; -} - - -void VideoDriver_Cocoa::GameLoop() -{ - uint32 cur_ticks = GetTick(); - uint32 last_cur_ticks = cur_ticks; - uint32 next_tick = cur_ticks + MILLISECONDS_PER_TICK; - -#ifdef _DEBUG - uint32 et0 = GetTick(); - uint32 st = 0; -#endif - - for (;;) { - @autoreleasepool { - - uint32 prev_cur_ticks = cur_ticks; // to check for wrapping - InteractiveRandom(); // randomness - - while (this->PollEvent()) {} - - if (_exit_game) { - /* Restore saved resolution if in fullscreen mode. */ - if (this->IsFullscreen()) _cur_resolution = this->orig_res; - break; - } - - NSUInteger cur_mods = [ NSEvent modifierFlags ]; - -#if defined(_DEBUG) - if (cur_mods & NSShiftKeyMask) -#else - if (_tab_is_down) -#endif - { - if (!_networking && _game_mode != GM_MENU) _fast_forward |= 2; - } else if (_fast_forward & 2) { - _fast_forward = 0; - } - - cur_ticks = GetTick(); - if (cur_ticks >= next_tick || (_fast_forward && !_pause_mode) || cur_ticks < prev_cur_ticks) { - _realtime_tick += cur_ticks - last_cur_ticks; - last_cur_ticks = cur_ticks; - next_tick = cur_ticks + MILLISECONDS_PER_TICK; - - bool old_ctrl_pressed = _ctrl_pressed; - - _ctrl_pressed = !!(cur_mods & ( _settings_client.gui.right_mouse_btn_emulation != RMBE_CONTROL ? NSControlKeyMask : NSCommandKeyMask)); - _shift_pressed = !!(cur_mods & NSShiftKeyMask); - - if (old_ctrl_pressed != _ctrl_pressed) HandleCtrlChanged(); - - ::GameLoop(); - - UpdateWindows(); - this->CheckPaletteAnim(); - this->Draw(); - } else { -#ifdef _DEBUG - uint32 st0 = GetTick(); -#endif - CSleep(1); -#ifdef _DEBUG - st += GetTick() - st0; -#endif - NetworkDrawChatMessage(); - DrawMouseCursor(); - this->Draw(); - } - } - } - -#ifdef _DEBUG - uint32 et = GetTick(); - - DEBUG(driver, 1, "cocoa_v: nextEventMatchingMask took %i ms total", _tEvent); - DEBUG(driver, 1, "cocoa_v: game loop took %i ms total (%i ms without sleep)", et - et0, et - et0 - st); - DEBUG(driver, 1, "cocoa_v: (nextEventMatchingMask total)/(game loop total) is %f%%", (double)_tEvent / (double)(et - et0) * 100); - DEBUG(driver, 1, "cocoa_v: (nextEventMatchingMask total)/(game loop without sleep total) is %f%%", (double)_tEvent / (double)(et - et0 - st) * 100); -#endif -} - -#endif /* WITH_COCOA */