1
0
Fork 0

Codechange: [OSX] Fold remaining Cocoa video subdriver into the main driver.

pull/8672/head
Michael Lutz 2021-01-22 22:29:46 +01:00
parent e6bea3961f
commit 88f6c7a9f3
5 changed files with 210 additions and 279 deletions

View File

@ -18,9 +18,37 @@ extern bool _cocoa_video_started;
class VideoDriver_Cocoa : public VideoDriver { class VideoDriver_Cocoa : public VideoDriver {
private: private:
Dimension orig_res; ///< Saved window size for non-fullscreen mode. Dimension orig_res; ///< Saved window size for non-fullscreen mode.
int device_width; ///< Width of device in pixel
int device_height; ///< Height of device in pixel
int device_depth; ///< Colour depth of device in bit
int window_width; ///< Current window width in pixel
int window_height; ///< Current window height in pixel
int window_pitch;
int buffer_depth; ///< Colour depth of used frame buffer
void *pixel_buffer; ///< used for direct pixel access
void *window_buffer; ///< Colour translation from palette to screen
# define MAX_DIRTY_RECTS 100
Rect dirty_rects[MAX_DIRTY_RECTS]; ///< dirty rectangles
int num_dirty_rects = MAX_DIRTY_RECTS; ///< Number of dirty rectangles
uint32 palette[256]; ///< Colour Palette
public: public:
bool active; ///< Whether the window is visible
bool setup;
id window; ///< Pointer to window object
id cocoaview; ///< Pointer to view object
CGColorSpaceRef color_space; ///< Window color space
CGContextRef cgcontext; ///< Context reference for Quartz subdriver
public:
VideoDriver_Cocoa();
const char *Start(const StringList &param) override; const char *Start(const StringList &param) override;
/** Stop the video driver */ /** Stop the video driver */
@ -70,26 +98,28 @@ public:
/** Main game loop. */ /** Main game loop. */
void GameLoop(); // In event.mm. void GameLoop(); // In event.mm.
/** Resize the window.
* @return whether the window was successfully resized
*/
bool WindowResized();
/** Convert local coordinate to window server (CoreGraphics) coordinate
* @param p local coordinates
* @return window driver coordinates
*/
CGPoint PrivateLocalToCG(NSPoint *p);
protected: protected:
Dimension GetScreenSize() const override; Dimension GetScreenSize() const override;
private: private:
friend class WindowQuartzSubdriver; bool PollEvent(); // In event.mm.
void MouseMovedEvent(int x, int y); // In event.mm.
void WarpCursor(int x, int y); // In event.mm.
void GameSizeChanged(); void GameSizeChanged();
void UpdateVideoModes(); void UpdateVideoModes();
};
class FVideoDriver_Cocoa : public DriverFactoryBase {
public:
FVideoDriver_Cocoa() : DriverFactoryBase(Driver::DT_VIDEO, 10, "cocoa", "Cocoa Video Driver") {}
Driver *CreateInstance() const override { return new VideoDriver_Cocoa(); }
};
class WindowQuartzSubdriver {
private:
/** /**
* This function copies 8bpp pixels from the screen buffer in 32bpp windowed mode. * This function copies 8bpp pixels from the screen buffer in 32bpp windowed mode.
* *
@ -103,48 +133,11 @@ private:
void GetDeviceInfo(); void GetDeviceInfo();
bool SetVideoMode(int width, int height, int bpp); bool SetVideoMode(int width, int height, int bpp);
public:
int device_width; ///< Width of device in pixel
int device_height; ///< Height of device in pixel
int device_depth; ///< Colour depth of device in bit
int window_width; ///< Current window width in pixel
int window_height; ///< Current window height in pixel
int window_pitch;
int buffer_depth; ///< Colour depth of used frame buffer
void *pixel_buffer; ///< used for direct pixel access
void *window_buffer; ///< Colour translation from palette to screen
# define MAX_DIRTY_RECTS 100
Rect dirty_rects[MAX_DIRTY_RECTS]; ///< dirty rectangles
int num_dirty_rects; ///< Number of dirty rectangles
uint32 palette[256]; ///< Colour Palette
bool active; ///< Whether the window is visible
bool setup;
id window; ///< Pointer to window object
id cocoaview; ///< Pointer to view object
CGColorSpaceRef color_space; ///< Window color space
CGContextRef cgcontext; ///< Context reference for Quartz subdriver
WindowQuartzSubdriver();
~WindowQuartzSubdriver();
/** Draw window /** Draw window
* @param force_update Whether to redraw unconditionally * @param force_update Whether to redraw unconditionally
*/ */
void Draw(bool force_update = false); void Draw(bool force_update = false);
/** Mark dirty a screen region
* @param left x-coordinate of left border
* @param top y-coordinate of top border
* @param width width or dirty rectangle
* @param height height of dirty rectangle
*/
void MakeDirty(int left, int top, int width, int height);
/** Update the palette */ /** Update the palette */
void UpdatePalette(uint first_color, uint num_colors); void UpdatePalette(uint first_color, uint num_colors);
@ -162,32 +155,11 @@ public:
*/ */
bool IsFullscreen(); bool IsFullscreen();
/** Toggle between fullscreen and windowed mode
* @return whether switch was successful
*/
bool ToggleFullscreen(bool fullscreen);
/** Return the width of the current view
* @return width of the current view
*/
int GetWidth() { return window_width; }
/** Return the height of the current view
* @return height of the current view
*/
int GetHeight() { return window_height; }
/** Return the current pixel buffer /** Return the current pixel buffer
* @return pixelbuffer * @return pixelbuffer
*/ */
void *GetPixelBuffer() { return buffer_depth == 8 ? pixel_buffer : window_buffer; } void *GetPixelBuffer() { return buffer_depth == 8 ? pixel_buffer : window_buffer; }
/** Convert local coordinate to window server (CoreGraphics) coordinate
* @param p local coordinates
* @return window driver coordinates
*/
CGPoint PrivateLocalToCG(NSPoint *p);
/** Return the mouse location /** Return the mouse location
* @param event UI event * @param event UI event
* @return mouse location as NSPoint * @return mouse location as NSPoint
@ -200,15 +172,13 @@ public:
*/ */
bool MouseIsInsideView(NSPoint *pt); bool MouseIsInsideView(NSPoint *pt);
/** Return whether the window is active (visible) */ void CheckPaletteAnim();
bool IsActive() { return active; }
/** Resize the window.
* @return whether the window was successfully resized
*/
bool WindowResized();
}; };
extern WindowQuartzSubdriver *_cocoa_subdriver; class FVideoDriver_Cocoa : public DriverFactoryBase {
public:
FVideoDriver_Cocoa() : DriverFactoryBase(Driver::DT_VIDEO, 10, "cocoa", "Cocoa Video Driver") {}
Driver *CreateInstance() const override { return new VideoDriver_Cocoa(); }
};
#endif /* VIDEO_COCOA_H */ #endif /* VIDEO_COCOA_H */

View File

@ -55,7 +55,6 @@
#endif #endif
bool _cocoa_video_started = false; bool _cocoa_video_started = false;
WindowQuartzSubdriver *_cocoa_subdriver = NULL;
/** List of common display/window sizes. */ /** List of common display/window sizes. */
@ -74,31 +73,28 @@ static const Dimension _default_resolutions[] = {
{ 2560, 1440 } { 2560, 1440 }
}; };
/**
* Update the video modus.
*/
void VideoDriver_Cocoa::UpdateVideoModes()
{
_resolutions.clear();
if (_cocoa_subdriver != nullptr && _cocoa_subdriver->IsFullscreen()) {
/* Full screen, there is only one possible resolution. */
NSSize screen = [ [ _cocoa_subdriver->window screen ] frame ].size;
_resolutions.emplace_back((uint)screen.width, (uint)screen.height);
} else {
/* Windowed; offer a selection of common window sizes up until the
* maximum usable screen space. This excludes the menu and dock areas. */
NSSize maxSize = [ [ NSScreen mainScreen] visibleFrame ].size;
for (const auto &d : _default_resolutions) {
if (d.width < maxSize.width && d.height < maxSize.height) _resolutions.push_back(d);
}
_resolutions.emplace_back((uint)maxSize.width, (uint)maxSize.height);
}
}
static FVideoDriver_Cocoa iFVideoDriver_Cocoa; static FVideoDriver_Cocoa iFVideoDriver_Cocoa;
VideoDriver_Cocoa::VideoDriver_Cocoa()
{
this->window_width = 0;
this->window_height = 0;
this->buffer_depth = 0;
this->window_buffer = nullptr;
this->pixel_buffer = nullptr;
this->active = false;
this->setup = false;
this->window = nil;
this->cocoaview = nil;
this->color_space = nullptr;
this->cgcontext = nullptr;
this->num_dirty_rects = MAX_DIRTY_RECTS;
}
/** /**
* Stop the cocoa video subdriver. * Stop the cocoa video subdriver.
*/ */
@ -108,8 +104,14 @@ void VideoDriver_Cocoa::Stop()
CocoaExitApplication(); CocoaExitApplication();
delete _cocoa_subdriver; /* Release window mode resources */
_cocoa_subdriver = nullptr; if (this->window != nil) [ this->window close ];
CGContextRelease(this->cgcontext);
CGColorSpaceRelease(this->color_space);
free(this->window_buffer);
free(this->pixel_buffer);
_cocoa_video_started = false; _cocoa_video_started = false;
} }
@ -139,18 +141,17 @@ const char *VideoDriver_Cocoa::Start(const StringList &parm)
return "The cocoa quartz subdriver only supports 8 and 32 bpp."; return "The cocoa quartz subdriver only supports 8 and 32 bpp.";
} }
_cocoa_subdriver = new WindowQuartzSubdriver(); if (!this->ChangeResolution(width, height, bpp)) {
if (!_cocoa_subdriver->ChangeResolution(width, height, bpp)) {
Stop(); Stop();
return "Could not create subdriver"; return "Could not create subdriver";
} }
if (_fullscreen) _cocoa_subdriver->ToggleFullscreen(_fullscreen); if (_fullscreen) this->ToggleFullscreen(_fullscreen);
this->GameSizeChanged(); this->GameSizeChanged();
this->UpdateVideoModes(); this->UpdateVideoModes();
return NULL; return nullptr;
} }
/** /**
@ -163,9 +164,13 @@ const char *VideoDriver_Cocoa::Start(const StringList &parm)
*/ */
void VideoDriver_Cocoa::MakeDirty(int left, int top, int width, int height) void VideoDriver_Cocoa::MakeDirty(int left, int top, int width, int height)
{ {
assert(_cocoa_subdriver != NULL); if (this->num_dirty_rects < MAX_DIRTY_RECTS) {
dirty_rects[this->num_dirty_rects].left = left;
_cocoa_subdriver->MakeDirty(left, top, width, height); dirty_rects[this->num_dirty_rects].top = top;
dirty_rects[this->num_dirty_rects].right = left + width;
dirty_rects[this->num_dirty_rects].bottom = top + height;
}
this->num_dirty_rects++;
} }
/** /**
@ -190,12 +195,8 @@ void VideoDriver_Cocoa::MainLoop()
*/ */
bool VideoDriver_Cocoa::ChangeResolution(int w, int h) bool VideoDriver_Cocoa::ChangeResolution(int w, int h)
{ {
assert(_cocoa_subdriver != NULL); bool ret = this->ChangeResolution(w, h, BlitterFactory::GetCurrentBlitter()->GetScreenDepth());
bool ret = _cocoa_subdriver->ChangeResolution(w, h, BlitterFactory::GetCurrentBlitter()->GetScreenDepth());
this->GameSizeChanged(); this->GameSizeChanged();
return ret; return ret;
} }
@ -207,11 +208,15 @@ bool VideoDriver_Cocoa::ChangeResolution(int w, int h)
*/ */
bool VideoDriver_Cocoa::ToggleFullscreen(bool full_screen) bool VideoDriver_Cocoa::ToggleFullscreen(bool full_screen)
{ {
assert(_cocoa_subdriver != NULL); if (this->IsFullscreen() == full_screen) return true;
bool res = _cocoa_subdriver->ToggleFullscreen(full_screen); if ([ this->window respondsToSelector:@selector(toggleFullScreen:) ]) {
this->UpdateVideoModes(); [ this->window performSelector:@selector(toggleFullScreen:) withObject:this->window ];
return res; this->UpdateVideoModes();
return true;
}
return false;
} }
/** /**
@ -229,7 +234,7 @@ bool VideoDriver_Cocoa::AfterBlitterChange()
*/ */
void VideoDriver_Cocoa::EditBoxLostFocus() void VideoDriver_Cocoa::EditBoxLostFocus()
{ {
if (_cocoa_subdriver != NULL) [ [ _cocoa_subdriver->cocoaview inputContext ] discardMarkedText ]; [ [ this->cocoaview inputContext ] discardMarkedText ];
/* Clear any marked string from the current edit box. */ /* Clear any marked string from the current edit box. */
HandleTextInput(NULL, true); HandleTextInput(NULL, true);
} }
@ -248,16 +253,14 @@ Dimension VideoDriver_Cocoa::GetScreenSize() const
*/ */
void VideoDriver_Cocoa::GameSizeChanged() void VideoDriver_Cocoa::GameSizeChanged()
{ {
if (_cocoa_subdriver == nullptr) return;
/* Tell the game that the resolution has changed */ /* Tell the game that the resolution has changed */
_screen.width = _cocoa_subdriver->GetWidth(); _screen.width = this->window_width;
_screen.height = _cocoa_subdriver->GetHeight(); _screen.height = this->window_height;
_screen.pitch = _cocoa_subdriver->GetWidth(); _screen.pitch = this->window_width;
_screen.dst_ptr = _cocoa_subdriver->GetPixelBuffer(); _screen.dst_ptr = this->GetPixelBuffer();
/* Store old window size if we entered fullscreen mode. */ /* Store old window size if we entered fullscreen mode. */
bool fullscreen = _cocoa_subdriver->IsFullscreen(); bool fullscreen = this->IsFullscreen();
if (fullscreen && !_fullscreen) this->orig_res = _cur_resolution; if (fullscreen && !_fullscreen) this->orig_res = _cur_resolution;
_fullscreen = fullscreen; _fullscreen = fullscreen;
@ -266,18 +269,16 @@ void VideoDriver_Cocoa::GameSizeChanged()
::GameSizeChanged(); ::GameSizeChanged();
} }
class WindowQuartzSubdriver;
/* Subclass of OTTD_CocoaView to fix Quartz rendering */ /* Subclass of OTTD_CocoaView to fix Quartz rendering */
@interface OTTD_QuartzView : OTTD_CocoaView @interface OTTD_QuartzView : OTTD_CocoaView
- (void)setDriver:(WindowQuartzSubdriver *)drv; - (void)setDriver:(VideoDriver_Cocoa *)drv;
- (void)drawRect:(NSRect)invalidRect; - (void)drawRect:(NSRect)invalidRect;
@end @end
@implementation OTTD_QuartzView @implementation OTTD_QuartzView
- (void)setDriver:(WindowQuartzSubdriver *)drv - (void)setDriver:(VideoDriver_Cocoa *)drv
{ {
driver = drv; driver = drv;
} }
@ -360,7 +361,29 @@ class WindowQuartzSubdriver;
@end @end
void WindowQuartzSubdriver::GetDeviceInfo() /**
* Update the video modus.
*/
void VideoDriver_Cocoa::UpdateVideoModes()
{
_resolutions.clear();
if (this->IsFullscreen()) {
/* Full screen, there is only one possible resolution. */
NSSize screen = [ [ this->window screen ] frame ].size;
_resolutions.emplace_back((uint)screen.width, (uint)screen.height);
} else {
/* Windowed; offer a selection of common window sizes up until the
* maximum usable screen space. This excludes the menu and dock areas. */
NSSize maxSize = [ [ NSScreen mainScreen] visibleFrame ].size;
for (const auto &d : _default_resolutions) {
if (d.width < maxSize.width && d.height < maxSize.height) _resolutions.push_back(d);
}
_resolutions.emplace_back((uint)maxSize.width, (uint)maxSize.height);
}
}
void VideoDriver_Cocoa::GetDeviceInfo()
{ {
/* Initialize the video settings; this data persists between mode switches /* Initialize the video settings; this data persists between mode switches
* and gather some information that is useful to know about the display */ * and gather some information that is useful to know about the display */
@ -375,27 +398,12 @@ void WindowQuartzSubdriver::GetDeviceInfo()
CGDisplayModeRelease(cur_mode); CGDisplayModeRelease(cur_mode);
} }
bool WindowQuartzSubdriver::IsFullscreen() bool VideoDriver_Cocoa::IsFullscreen()
{ {
return this->window != nil && ([ this->window styleMask ] & NSWindowStyleMaskFullScreen) != 0; return this->window != nil && ([ this->window styleMask ] & NSWindowStyleMaskFullScreen) != 0;
} }
/** Switch to full screen mode on OSX 10.7 bool VideoDriver_Cocoa::SetVideoMode(int width, int height, int bpp)
* @return Whether we switched to full screen
*/
bool WindowQuartzSubdriver::ToggleFullscreen(bool fullscreen)
{
if (this->IsFullscreen() == fullscreen) return true;
if ([ this->window respondsToSelector:@selector(toggleFullScreen:) ]) {
[ this->window performSelector:@selector(toggleFullScreen:) withObject:this->window ];
return true;
}
return false;
}
bool WindowQuartzSubdriver::SetVideoMode(int width, int height, int bpp)
{ {
this->setup = true; this->setup = true;
this->GetDeviceInfo(); this->GetDeviceInfo();
@ -508,7 +516,7 @@ bool WindowQuartzSubdriver::SetVideoMode(int width, int height, int bpp)
return ret; return ret;
} }
void WindowQuartzSubdriver::BlitIndexedToView32(int left, int top, int right, int bottom) void VideoDriver_Cocoa::BlitIndexedToView32(int left, int top, int right, int bottom)
{ {
const uint32 *pal = this->palette; const uint32 *pal = this->palette;
const uint8 *src = (uint8*)this->pixel_buffer; const uint8 *src = (uint8*)this->pixel_buffer;
@ -524,37 +532,7 @@ void WindowQuartzSubdriver::BlitIndexedToView32(int left, int top, int right, in
} }
WindowQuartzSubdriver::WindowQuartzSubdriver() void VideoDriver_Cocoa::Draw(bool force_update)
{
this->window_width = 0;
this->window_height = 0;
this->buffer_depth = 0;
this->window_buffer = NULL;
this->pixel_buffer = NULL;
this->active = false;
this->setup = false;
this->window = nil;
this->cocoaview = nil;
this->cgcontext = NULL;
this->num_dirty_rects = MAX_DIRTY_RECTS;
}
WindowQuartzSubdriver::~WindowQuartzSubdriver()
{
/* Release window mode resources */
if (this->window != nil) [ this->window close ];
CGContextRelease(this->cgcontext);
CGColorSpaceRelease(this->color_space);
free(this->window_buffer);
free(this->pixel_buffer);
}
void WindowQuartzSubdriver::Draw(bool force_update)
{ {
PerformanceMeasurer framerate(PFE_VIDEO); PerformanceMeasurer framerate(PFE_VIDEO);
@ -596,18 +574,7 @@ void WindowQuartzSubdriver::Draw(bool force_update)
this->num_dirty_rects = 0; this->num_dirty_rects = 0;
} }
void WindowQuartzSubdriver::MakeDirty(int left, int top, int width, int height) void VideoDriver_Cocoa::UpdatePalette(uint first_color, uint num_colors)
{
if (this->num_dirty_rects < MAX_DIRTY_RECTS) {
dirty_rects[this->num_dirty_rects].left = left;
dirty_rects[this->num_dirty_rects].top = top;
dirty_rects[this->num_dirty_rects].right = left + width;
dirty_rects[this->num_dirty_rects].bottom = top + height;
}
this->num_dirty_rects++;
}
void WindowQuartzSubdriver::UpdatePalette(uint first_color, uint num_colors)
{ {
if (this->buffer_depth != 8) return; if (this->buffer_depth != 8) return;
@ -622,7 +589,7 @@ void WindowQuartzSubdriver::UpdatePalette(uint first_color, uint num_colors)
this->num_dirty_rects = MAX_DIRTY_RECTS; this->num_dirty_rects = MAX_DIRTY_RECTS;
} }
bool WindowQuartzSubdriver::ChangeResolution(int w, int h, int bpp) bool VideoDriver_Cocoa::ChangeResolution(int w, int h, int bpp)
{ {
int old_width = this->window_width; int old_width = this->window_width;
int old_height = this->window_height; int old_height = this->window_height;
@ -635,7 +602,7 @@ bool WindowQuartzSubdriver::ChangeResolution(int w, int h, int bpp)
} }
/* Convert local coordinate to window server (CoreGraphics) coordinate */ /* Convert local coordinate to window server (CoreGraphics) coordinate */
CGPoint WindowQuartzSubdriver::PrivateLocalToCG(NSPoint *p) CGPoint VideoDriver_Cocoa::PrivateLocalToCG(NSPoint *p)
{ {
p->y = this->window_height - p->y; p->y = this->window_height - p->y;
@ -651,7 +618,7 @@ CGPoint WindowQuartzSubdriver::PrivateLocalToCG(NSPoint *p)
return cgp; return cgp;
} }
NSPoint WindowQuartzSubdriver::GetMouseLocation(NSEvent *event) NSPoint VideoDriver_Cocoa::GetMouseLocation(NSEvent *event)
{ {
NSPoint pt; NSPoint pt;
@ -666,7 +633,7 @@ NSPoint WindowQuartzSubdriver::GetMouseLocation(NSEvent *event)
return pt; return pt;
} }
bool WindowQuartzSubdriver::MouseIsInsideView(NSPoint *pt) bool VideoDriver_Cocoa::MouseIsInsideView(NSPoint *pt)
{ {
return [ cocoaview mouse:*pt inRect:[ this->cocoaview bounds ] ]; return [ cocoaview mouse:*pt inRect:[ this->cocoaview bounds ] ];
} }
@ -682,7 +649,7 @@ static void ClearWindowBuffer(uint32 *buffer, uint32 pitch, uint32 height)
} }
} }
bool WindowQuartzSubdriver::WindowResized() bool VideoDriver_Cocoa::WindowResized()
{ {
if (this->window == nil || this->cocoaview == nil) return true; if (this->window == nil || this->cocoaview == nil) return true;
@ -722,7 +689,7 @@ bool WindowQuartzSubdriver::WindowResized()
} }
} }
static_cast<VideoDriver_Cocoa *>(VideoDriver::GetInstance())->GameSizeChanged(); this->GameSizeChanged();
/* Redraw screen */ /* Redraw screen */
this->num_dirty_rects = MAX_DIRTY_RECTS; this->num_dirty_rects = MAX_DIRTY_RECTS;
@ -730,4 +697,28 @@ bool WindowQuartzSubdriver::WindowResized()
return true; return true;
} }
void VideoDriver_Cocoa::CheckPaletteAnim()
{
if (_cur_palette.count_dirty != 0) {
Blitter *blitter = BlitterFactory::GetCurrentBlitter();
switch (blitter->UsePaletteAnimation()) {
case Blitter::PALETTE_ANIMATION_VIDEO_BACKEND:
this->UpdatePalette(_cur_palette.first_dirty, _cur_palette.count_dirty);
break;
case Blitter::PALETTE_ANIMATION_BLITTER:
blitter->PaletteAnimate(_cur_palette);
break;
case Blitter::PALETTE_ANIMATION_NONE:
break;
default:
NOT_REACHED();
}
_cur_palette.count_dirty = 0;
}
}
#endif /* WITH_COCOA */ #endif /* WITH_COCOA */

View File

@ -12,7 +12,7 @@
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
class WindowQuartzSubdriver; class VideoDriver_Cocoa;
extern NSString *OTTDMainLaunchGameEngine; extern NSString *OTTDMainLaunchGameEngine;
@ -23,10 +23,10 @@ extern NSString *OTTDMainLaunchGameEngine;
/** Subclass of NSWindow to cater our special needs */ /** Subclass of NSWindow to cater our special needs */
@interface OTTD_CocoaWindow : NSWindow { @interface OTTD_CocoaWindow : NSWindow {
WindowQuartzSubdriver *driver; VideoDriver_Cocoa *driver;
} }
- (void)setDriver:(WindowQuartzSubdriver *)drv; - (void)setDriver:(VideoDriver_Cocoa *)drv;
- (void)miniaturize:(id)sender; - (void)miniaturize:(id)sender;
- (void)display; - (void)display;
@ -39,10 +39,10 @@ extern NSString *OTTDMainLaunchGameEngine;
/** Subclass of NSView to fix Quartz rendering and mouse awareness */ /** Subclass of NSView to fix Quartz rendering and mouse awareness */
@interface OTTD_CocoaView : NSView <NSTextInputClient> @interface OTTD_CocoaView : NSView <NSTextInputClient>
{ {
WindowQuartzSubdriver *driver; VideoDriver_Cocoa *driver;
NSTrackingRectTag trackingtag; NSTrackingRectTag trackingtag;
} }
- (void)setDriver:(WindowQuartzSubdriver *)drv; - (void)setDriver:(VideoDriver_Cocoa *)drv;
- (void)drawRect:(NSRect)rect; - (void)drawRect:(NSRect)rect;
- (BOOL)isOpaque; - (BOOL)isOpaque;
- (BOOL)acceptsFirstResponder; - (BOOL)acceptsFirstResponder;
@ -59,10 +59,10 @@ extern NSString *OTTDMainLaunchGameEngine;
/** Delegate for our NSWindow to send ask for quit on close */ /** Delegate for our NSWindow to send ask for quit on close */
@interface OTTD_CocoaWindowDelegate : NSObject <NSWindowDelegate> @interface OTTD_CocoaWindowDelegate : NSObject <NSWindowDelegate>
{ {
WindowQuartzSubdriver *driver; VideoDriver_Cocoa *driver;
} }
- (void)setDriver:(WindowQuartzSubdriver *)drv; - (void)setDriver:(VideoDriver_Cocoa *)drv;
- (BOOL)windowShouldClose:(id)sender; - (BOOL)windowShouldClose:(id)sender;
- (void)windowDidEnterFullScreen:(NSNotification *)aNotification; - (void)windowDidEnterFullScreen:(NSNotification *)aNotification;

View File

@ -70,7 +70,7 @@ static OTTDMain *_ottd_main;
- (void)launchGameEngine: (NSNotification*) note - (void)launchGameEngine: (NSNotification*) note
{ {
/* Setup cursor for the current _game_mode. */ /* Setup cursor for the current _game_mode. */
[ _cocoa_subdriver->cocoaview resetCursorRects ]; [ static_cast<VideoDriver_Cocoa *>(VideoDriver::GetInstance())->cocoaview resetCursorRects ];
/* Hand off to main application code. */ /* Hand off to main application code. */
static_cast<VideoDriver_Cocoa *>(VideoDriver::GetInstance())->GameLoop(); static_cast<VideoDriver_Cocoa *>(VideoDriver::GetInstance())->GameLoop();
@ -282,7 +282,7 @@ void CocoaDialog(const char *title, const char *message, const char *buttonLabel
@implementation OTTD_CocoaWindow @implementation OTTD_CocoaWindow
- (void)setDriver:(WindowQuartzSubdriver *)drv - (void)setDriver:(VideoDriver_Cocoa *)drv
{ {
driver = drv; driver = drv;
} }
@ -404,7 +404,7 @@ static const char *Utf8AdvanceByUtf16Units(const char *str, NSUInteger count)
/** /**
* Initialize the driver * Initialize the driver
*/ */
- (void)setDriver:(WindowQuartzSubdriver *)drv - (void)setDriver:(VideoDriver_Cocoa *)drv
{ {
driver = drv; driver = drv;
} }
@ -491,7 +491,7 @@ static const char *Utf8AdvanceByUtf16Units(const char *str, NSUInteger count)
*/ */
- (void)mouseExited:(NSEvent *)theEvent - (void)mouseExited:(NSEvent *)theEvent
{ {
if (_cocoa_subdriver != NULL) UndrawMouseCursor(); if (driver->window != nil) UndrawMouseCursor();
_cursor.in_window = false; _cursor.in_window = false;
} }
@ -810,7 +810,7 @@ static const char *Utf8AdvanceByUtf16Units(const char *str, NSUInteger count)
@implementation OTTD_CocoaWindowDelegate @implementation OTTD_CocoaWindowDelegate
/** Initialize the video driver */ /** Initialize the video driver */
- (void)setDriver:(WindowQuartzSubdriver *)drv - (void)setDriver:(VideoDriver_Cocoa *)drv
{ {
driver = drv; driver = drv;
} }

View File

@ -73,15 +73,13 @@ static uint32 GetTick()
return tim.tv_usec / 1000 + tim.tv_sec * 1000; return tim.tv_usec / 1000 + tim.tv_sec * 1000;
} }
static void QZ_WarpCursor(int x, int y) void VideoDriver_Cocoa::WarpCursor(int x, int y)
{ {
assert(_cocoa_subdriver != NULL);
/* Only allow warping when in foreground */ /* Only allow warping when in foreground */
if (![ NSApp isActive ]) return; if (![ NSApp isActive ]) return;
NSPoint p = NSMakePoint(x, y); NSPoint p = NSMakePoint(x, y);
CGPoint cgp = _cocoa_subdriver->PrivateLocalToCG(&p); CGPoint cgp = this->PrivateLocalToCG(&p);
/* Do the actual warp */ /* Do the actual warp */
CGWarpMouseCursorPosition(cgp); CGWarpMouseCursorPosition(cgp);
@ -90,32 +88,6 @@ static void QZ_WarpCursor(int x, int y)
} }
static void QZ_CheckPaletteAnim()
{
if (_cur_palette.count_dirty != 0) {
Blitter *blitter = BlitterFactory::GetCurrentBlitter();
switch (blitter->UsePaletteAnimation()) {
case Blitter::PALETTE_ANIMATION_VIDEO_BACKEND:
_cocoa_subdriver->UpdatePalette(_cur_palette.first_dirty, _cur_palette.count_dirty);
break;
case Blitter::PALETTE_ANIMATION_BLITTER:
blitter->PaletteAnimate(_cur_palette);
break;
case Blitter::PALETTE_ANIMATION_NONE:
break;
default:
NOT_REACHED();
}
_cur_palette.count_dirty = 0;
}
}
struct VkMapping { struct VkMapping {
unsigned short vk_from; unsigned short vk_from;
byte map_to; byte map_to;
@ -343,10 +315,10 @@ static void QZ_DoUnsidedModifiers(unsigned int newMods)
_current_mods = newMods; _current_mods = newMods;
} }
static void QZ_MouseMovedEvent(int x, int y) void VideoDriver_Cocoa::MouseMovedEvent(int x, int y)
{ {
if (_cursor.UpdateCursorPosition(x, y, false)) { if (_cursor.UpdateCursorPosition(x, y, false)) {
QZ_WarpCursor(_cursor.pos.x, _cursor.pos.y); this->WarpCursor(_cursor.pos.x, _cursor.pos.y);
} }
HandleMouseEvents(); HandleMouseEvents();
} }
@ -380,10 +352,8 @@ static void QZ_MouseButtonEvent(int button, BOOL down)
static bool QZ_PollEvent() bool VideoDriver_Cocoa::PollEvent()
{ {
assert(_cocoa_subdriver != NULL);
#ifdef _DEBUG #ifdef _DEBUG
uint32 et0 = GetTick(); uint32 et0 = GetTick();
#endif #endif
@ -395,7 +365,7 @@ static bool QZ_PollEvent()
#endif #endif
if (event == nil) return false; if (event == nil) return false;
if (!_cocoa_subdriver->IsActive()) { if (!this->active) {
[ NSApp sendEvent:event ]; [ NSApp sendEvent:event ];
return true; return true;
} }
@ -408,18 +378,18 @@ static bool QZ_PollEvent()
case NSMouseMoved: case NSMouseMoved:
case NSOtherMouseDragged: case NSOtherMouseDragged:
case NSLeftMouseDragged: case NSLeftMouseDragged:
pt = _cocoa_subdriver->GetMouseLocation(event); pt = this->GetMouseLocation(event);
if (!_cocoa_subdriver->MouseIsInsideView(&pt) && !_emulating_right_button) { if (!this->MouseIsInsideView(&pt) && !_emulating_right_button) {
[ NSApp sendEvent:event ]; [ NSApp sendEvent:event ];
break; break;
} }
QZ_MouseMovedEvent((int)pt.x, (int)pt.y); this->MouseMovedEvent((int)pt.x, (int)pt.y);
break; break;
case NSRightMouseDragged: case NSRightMouseDragged:
pt = _cocoa_subdriver->GetMouseLocation(event); pt = this->GetMouseLocation(event);
QZ_MouseMovedEvent((int)pt.x, (int)pt.y); this->MouseMovedEvent((int)pt.x, (int)pt.y);
break; break;
case NSLeftMouseDown: case NSLeftMouseDown:
@ -428,13 +398,13 @@ static bool QZ_PollEvent()
if (_settings_client.gui.right_mouse_btn_emulation == RMBE_COMMAND) keymask |= NSCommandKeyMask; if (_settings_client.gui.right_mouse_btn_emulation == RMBE_COMMAND) keymask |= NSCommandKeyMask;
if (_settings_client.gui.right_mouse_btn_emulation == RMBE_CONTROL) keymask |= NSControlKeyMask; if (_settings_client.gui.right_mouse_btn_emulation == RMBE_CONTROL) keymask |= NSControlKeyMask;
pt = _cocoa_subdriver->GetMouseLocation(event); pt = this->GetMouseLocation(event);
if (!([ event modifierFlags ] & keymask) || !_cocoa_subdriver->MouseIsInsideView(&pt)) { if (!([ event modifierFlags ] & keymask) || !this->MouseIsInsideView(&pt)) {
[ NSApp sendEvent:event ]; [ NSApp sendEvent:event ];
} }
QZ_MouseMovedEvent((int)pt.x, (int)pt.y); this->MouseMovedEvent((int)pt.x, (int)pt.y);
/* Right mouse button emulation */ /* Right mouse button emulation */
if ([ event modifierFlags ] & keymask) { if ([ event modifierFlags ] & keymask) {
@ -448,9 +418,9 @@ static bool QZ_PollEvent()
case NSLeftMouseUp: case NSLeftMouseUp:
[ NSApp sendEvent:event ]; [ NSApp sendEvent:event ];
pt = _cocoa_subdriver->GetMouseLocation(event); pt = this->GetMouseLocation(event);
QZ_MouseMovedEvent((int)pt.x, (int)pt.y); this->MouseMovedEvent((int)pt.x, (int)pt.y);
/* Right mouse button emulation */ /* Right mouse button emulation */
if (_emulating_right_button) { if (_emulating_right_button) {
@ -462,24 +432,24 @@ static bool QZ_PollEvent()
break; break;
case NSRightMouseDown: case NSRightMouseDown:
pt = _cocoa_subdriver->GetMouseLocation(event); pt = this->GetMouseLocation(event);
if (!_cocoa_subdriver->MouseIsInsideView(&pt)) { if (!this->MouseIsInsideView(&pt)) {
[ NSApp sendEvent:event ]; [ NSApp sendEvent:event ];
break; break;
} }
QZ_MouseMovedEvent((int)pt.x, (int)pt.y); this->MouseMovedEvent((int)pt.x, (int)pt.y);
QZ_MouseButtonEvent(1, YES); QZ_MouseButtonEvent(1, YES);
break; break;
case NSRightMouseUp: case NSRightMouseUp:
pt = _cocoa_subdriver->GetMouseLocation(event); pt = this->GetMouseLocation(event);
if (!_cocoa_subdriver->MouseIsInsideView(&pt)) { if (!this->MouseIsInsideView(&pt)) {
[ NSApp sendEvent:event ]; [ NSApp sendEvent:event ];
break; break;
} }
QZ_MouseMovedEvent((int)pt.x, (int)pt.y); this->MouseMovedEvent((int)pt.x, (int)pt.y);
QZ_MouseButtonEvent(1, NO); QZ_MouseButtonEvent(1, NO);
break; break;
@ -492,7 +462,7 @@ static bool QZ_PollEvent()
break; break;
} }
QZ_MouseMovedEvent((int)pt.x, (int)pt.y); this->MouseMovedEvent((int)pt.x, (int)pt.y);
QZ_MouseButtonEvent([ event buttonNumber ], YES); QZ_MouseButtonEvent([ event buttonNumber ], YES);
break; break;
@ -503,7 +473,7 @@ static bool QZ_PollEvent()
break; break;
} }
QZ_MouseMovedEvent((int)pt.x, (int)pt.y); this->MouseMovedEvent((int)pt.x, (int)pt.y);
QZ_MouseButtonEvent([ event buttonNumber ], NO); QZ_MouseButtonEvent([ event buttonNumber ], NO);
break; break;
#endif #endif
@ -524,7 +494,7 @@ static bool QZ_PollEvent()
unsigned short unicode = [ chars length ] > 0 ? [ chars characterAtIndex:0 ] : 0; unsigned short unicode = [ chars length ] > 0 ? [ chars characterAtIndex:0 ] : 0;
if (EditBoxInGlobalFocus()) { if (EditBoxInGlobalFocus()) {
if (QZ_KeyEvent([ event keyCode ], unicode, YES)) { if (QZ_KeyEvent([ event keyCode ], unicode, YES)) {
[ _cocoa_subdriver->cocoaview interpretKeyEvents:[ NSArray arrayWithObject:event ] ]; [ this->cocoaview interpretKeyEvents:[ NSArray arrayWithObject:event ] ];
} }
} else { } else {
QZ_KeyEvent([ event keyCode ], unicode, YES); QZ_KeyEvent([ event keyCode ], unicode, YES);
@ -629,32 +599,32 @@ void VideoDriver_Cocoa::GameLoop()
#endif #endif
DisplaySplashImage(); DisplaySplashImage();
QZ_CheckPaletteAnim(); this->CheckPaletteAnim();
_cocoa_subdriver->Draw(true); this->Draw(true);
CSleep(1); CSleep(1);
for (int i = 0; i < 2; i++) ::GameLoop(); for (int i = 0; i < 2; i++) ::GameLoop();
UpdateWindows(); UpdateWindows();
QZ_CheckPaletteAnim(); this->CheckPaletteAnim();
_cocoa_subdriver->Draw(); this->Draw();
CSleep(1); CSleep(1);
/* Set the proper OpenTTD palette which got spoilt by the splash /* Set the proper OpenTTD palette which got spoilt by the splash
* image when using 8bpp blitter */ * image when using 8bpp blitter */
GfxInitPalettes(); GfxInitPalettes();
QZ_CheckPaletteAnim(); this->CheckPaletteAnim();
_cocoa_subdriver->Draw(true); this->Draw(true);
for (;;) { for (;;) {
uint32 prev_cur_ticks = cur_ticks; // to check for wrapping uint32 prev_cur_ticks = cur_ticks; // to check for wrapping
InteractiveRandom(); // randomness InteractiveRandom(); // randomness
while (QZ_PollEvent()) {} while (this->PollEvent()) {}
if (_exit_game) { if (_exit_game) {
/* Restore saved resolution if in fullscreen mode. */ /* Restore saved resolution if in fullscreen mode. */
if (_cocoa_subdriver->IsFullscreen()) _cur_resolution = this->orig_res; if (this->IsFullscreen()) _cur_resolution = this->orig_res;
break; break;
} }
@ -685,8 +655,8 @@ void VideoDriver_Cocoa::GameLoop()
::GameLoop(); ::GameLoop();
UpdateWindows(); UpdateWindows();
QZ_CheckPaletteAnim(); this->CheckPaletteAnim();
_cocoa_subdriver->Draw(); this->Draw();
} else { } else {
#ifdef _DEBUG #ifdef _DEBUG
uint32 st0 = GetTick(); uint32 st0 = GetTick();
@ -697,7 +667,7 @@ void VideoDriver_Cocoa::GameLoop()
#endif #endif
NetworkDrawChatMessage(); NetworkDrawChatMessage();
DrawMouseCursor(); DrawMouseCursor();
_cocoa_subdriver->Draw(); this->Draw();
} }
} }