summaryrefslogtreecommitdiff
path: root/src/video/cocoa
diff options
context:
space:
mode:
authorMichael Lutz <michi@icosahedron.de>2021-02-06 00:23:29 +0100
committerMichael Lutz <michi@icosahedron.de>2021-02-13 22:21:17 +0100
commitbd42fc94cc1dc064d0c20cfa4fad108dc64931c6 (patch)
tree6f84e05b4d9b2f7639f9eaa4409a0c59eca24204 /src/video/cocoa
parent965ce1294726427bf31da33bb5c7650773f8aada (diff)
downloadopenttd-bd42fc94cc1dc064d0c20cfa4fad108dc64931c6.tar.xz
Codechange: [OSX] Move some things from video driver to our NSView.
Diffstat (limited to 'src/video/cocoa')
-rw-r--r--src/video/cocoa/cocoa_v.h6
-rw-r--r--src/video/cocoa/cocoa_v.mm221
-rw-r--r--src/video/cocoa/cocoa_wnd.mm10
3 files changed, 116 insertions, 121 deletions
diff --git a/src/video/cocoa/cocoa_v.h b/src/video/cocoa/cocoa_v.h
index 0961e1660..4c53cdb8f 100644
--- a/src/video/cocoa/cocoa_v.h
+++ b/src/video/cocoa/cocoa_v.h
@@ -17,6 +17,8 @@
extern bool _cocoa_video_started;
@class OTTD_CocoaWindowDelegate;
+@class OTTD_CocoaWindow;
+@class OTTD_CocoaView;
class VideoDriver_Cocoa : public VideoDriver {
private:
@@ -40,8 +42,8 @@ public:
bool active; ///< Whether the window is visible
bool setup;
- id window; ///< Pointer to window object
- id cocoaview; ///< Pointer to view object
+ OTTD_CocoaWindow *window; ///< Pointer to window object
+ OTTD_CocoaView *cocoaview; ///< Pointer to view object
CGColorSpaceRef color_space; ///< Window color space
CGContextRef cgcontext; ///< Context reference for Quartz subdriver
diff --git a/src/video/cocoa/cocoa_v.mm b/src/video/cocoa/cocoa_v.mm
index 185f28c84..88f461234 100644
--- a/src/video/cocoa/cocoa_v.mm
+++ b/src/video/cocoa/cocoa_v.mm
@@ -26,7 +26,6 @@
#include "../../openttd.h"
#include "../../debug.h"
-#include "../../rev.h"
#include "../../core/geometry_type.hpp"
#include "cocoa_v.h"
#include "cocoa_wnd.h"
@@ -311,111 +310,6 @@ void VideoDriver_Cocoa::GameSizeChanged()
::GameSizeChanged();
}
-
-
-@implementation OTTD_QuartzView
-
-- (instancetype)initWithFrame:(NSRect)frameRect andDriver:(VideoDriver_Cocoa *)drv
-{
- if (self = [ super initWithFrame:frameRect ]) {
- self->driver = drv;
- }
- return self;
-}
-
-- (BOOL)acceptsFirstResponder
-{
- return NO;
-}
-
-/**
- * Define the opaqueness of the window / screen
- * @return opaqueness of window / screen
- */
-- (BOOL)isOpaque
-{
- return YES;
-}
-
-- (void)drawRect:(NSRect)invalidRect
-{
- if (driver->cgcontext == NULL) return;
-
- CGContextRef viewContext = (CGContextRef)[ [ NSGraphicsContext currentContext ] graphicsPort ];
- CGContextSetShouldAntialias(viewContext, FALSE);
- CGContextSetInterpolationQuality(viewContext, kCGInterpolationNone);
-
- /* The obtained 'rect' is actually a union of all dirty rects, let's ask for an explicit list of rects instead */
- const NSRect *dirtyRects;
- NSInteger dirtyRectCount;
- [ self getRectsBeingDrawn:&dirtyRects count:&dirtyRectCount ];
-
- /* We need an Image in order to do blitting, but as we don't touch the context between this call and drawing no copying will actually be done here */
- CGImageRef fullImage = CGBitmapContextCreateImage(driver->cgcontext);
-
- /* Calculate total area we are blitting */
- uint32 blitArea = 0;
- for (int n = 0; n < dirtyRectCount; n++) {
- blitArea += (uint32)(dirtyRects[n].size.width * dirtyRects[n].size.height);
- }
-
- /*
- * This might be completely stupid, but in my extremely subjective opinion it feels faster
- * The point is, if we're blitting less than 50% of the dirty rect union then it's still a good idea to blit each dirty
- * rect separately but if we blit more than that, it's just cheaper to blit the entire union in one pass.
- * Feel free to remove or find an even better value than 50% ... / blackis
- */
- NSRect frameRect = [ self frame ];
- if (blitArea / (float)(invalidRect.size.width * invalidRect.size.height) > 0.5f) {
- NSRect rect = invalidRect;
- CGRect clipRect;
- CGRect blitRect;
-
- blitRect.origin.x = rect.origin.x;
- blitRect.origin.y = rect.origin.y;
- blitRect.size.width = rect.size.width;
- blitRect.size.height = rect.size.height;
-
- clipRect.origin.x = rect.origin.x;
- clipRect.origin.y = frameRect.size.height - rect.origin.y - rect.size.height;
-
- clipRect.size.width = rect.size.width;
- clipRect.size.height = rect.size.height;
-
- /* Blit dirty part of image */
- CGImageRef clippedImage = CGImageCreateWithImageInRect(fullImage, clipRect);
- CGContextDrawImage(viewContext, blitRect, clippedImage);
- CGImageRelease(clippedImage);
- } else {
- for (int n = 0; n < dirtyRectCount; n++) {
- NSRect rect = dirtyRects[n];
- CGRect clipRect;
- CGRect blitRect;
-
- blitRect.origin.x = rect.origin.x;
- blitRect.origin.y = rect.origin.y;
- blitRect.size.width = rect.size.width;
- blitRect.size.height = rect.size.height;
-
- clipRect.origin.x = rect.origin.x;
- clipRect.origin.y = frameRect.size.height - rect.origin.y - rect.size.height;
-
- clipRect.size.width = rect.size.width;
- clipRect.size.height = rect.size.height;
-
- /* Blit dirty part of image */
- CGImageRef clippedImage = CGImageCreateWithImageInRect(fullImage, clipRect);
- CGContextDrawImage(viewContext, blitRect, clippedImage);
- CGImageRelease(clippedImage);
- }
- }
-
- CGImageRelease(fullImage);
-}
-
-@end
-
-
/**
* Update the video modus.
*/
@@ -476,21 +370,10 @@ bool VideoDriver_Cocoa::MakeWindow(int width, int height)
[ fullscreenButton setTarget:this->window ];
}
- char caption[50];
- snprintf(caption, sizeof(caption), "OpenTTD %s", _openttd_revision);
- NSString *nsscaption = [ [ NSString alloc ] initWithUTF8String:caption ];
- [ this->window setTitle:nsscaption ];
- [ this->window setMiniwindowTitle:nsscaption ];
- [ nsscaption release ];
-
- [ this->window setContentMinSize:NSMakeSize(64.0f, 64.0f) ];
-
this->delegate = [ [ OTTD_CocoaWindowDelegate alloc ] initWithDriver:this ];
[ this->window setDelegate:this->delegate ];
- [ this->window setAcceptsMouseMovedEvents:YES ];
- [ this->window setViewsNeedDisplay:NO ];
- [ (OTTD_CocoaWindow *)this->window center ];
+ [ this->window center ];
[ this->window makeKeyAndOrderFront:nil ];
/* Create wrapper view for text input. */
@@ -501,7 +384,7 @@ bool VideoDriver_Cocoa::MakeWindow(int width, int height)
this->setup = false;
return false;
}
- [ (NSView *)this->cocoaview setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable ];
+ [ this->cocoaview setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable ];
/* Create content view. */
NSView *draw_view = [ [ OTTD_QuartzView alloc ] initWithFrame:[ this->cocoaview bounds ] andDriver:this ];
@@ -744,4 +627,104 @@ void VideoDriver_Cocoa::CheckPaletteAnim()
}
}
+
+@implementation OTTD_QuartzView
+
+- (instancetype)initWithFrame:(NSRect)frameRect andDriver:(VideoDriver_Cocoa *)drv
+{
+ if (self = [ super initWithFrame:frameRect ]) {
+ self->driver = drv;
+ }
+ return self;
+}
+
+- (BOOL)acceptsFirstResponder
+{
+ return NO;
+}
+
+- (BOOL)isOpaque
+{
+ return YES;
+}
+
+- (void)drawRect:(NSRect)invalidRect
+{
+ if (driver->cgcontext == nullptr) return;
+
+ NSGraphicsContext *ctx = [ NSGraphicsContext currentContext ];
+ CGContextRef viewContext = [ ctx respondsToSelector:@selector(CGContext) ] ? [ ctx CGContext ] : (CGContextRef)[ ctx graphicsPort ];
+ CGContextSetShouldAntialias(viewContext, FALSE);
+ CGContextSetInterpolationQuality(viewContext, kCGInterpolationNone);
+
+ /* The obtained 'rect' is actually a union of all dirty rects, let's ask for an explicit list of rects instead */
+ const NSRect *dirtyRects;
+ NSInteger dirtyRectCount;
+ [ self getRectsBeingDrawn:&dirtyRects count:&dirtyRectCount ];
+
+ /* We need an Image in order to do blitting, but as we don't touch the context between this call and drawing no copying will actually be done here */
+ CGImageRef fullImage = CGBitmapContextCreateImage(driver->cgcontext);
+
+ /* Calculate total area we are blitting */
+ uint32 blitArea = 0;
+ for (int n = 0; n < dirtyRectCount; n++) {
+ blitArea += (uint32)(dirtyRects[n].size.width * dirtyRects[n].size.height);
+ }
+
+ /*
+ * This might be completely stupid, but in my extremely subjective opinion it feels faster
+ * The point is, if we're blitting less than 50% of the dirty rect union then it's still a good idea to blit each dirty
+ * rect separately but if we blit more than that, it's just cheaper to blit the entire union in one pass.
+ * Feel free to remove or find an even better value than 50% ... / blackis
+ */
+ NSRect frameRect = [ self frame ];
+ if (blitArea / (float)(invalidRect.size.width * invalidRect.size.height) > 0.5f) {
+ NSRect rect = invalidRect;
+ CGRect clipRect;
+ CGRect blitRect;
+
+ blitRect.origin.x = rect.origin.x;
+ blitRect.origin.y = rect.origin.y;
+ blitRect.size.width = rect.size.width;
+ blitRect.size.height = rect.size.height;
+
+ clipRect.origin.x = rect.origin.x;
+ clipRect.origin.y = frameRect.size.height - rect.origin.y - rect.size.height;
+
+ clipRect.size.width = rect.size.width;
+ clipRect.size.height = rect.size.height;
+
+ /* Blit dirty part of image */
+ CGImageRef clippedImage = CGImageCreateWithImageInRect(fullImage, clipRect);
+ CGContextDrawImage(viewContext, blitRect, clippedImage);
+ CGImageRelease(clippedImage);
+ } else {
+ for (int n = 0; n < dirtyRectCount; n++) {
+ NSRect rect = dirtyRects[n];
+ CGRect clipRect;
+ CGRect blitRect;
+
+ blitRect.origin.x = rect.origin.x;
+ blitRect.origin.y = rect.origin.y;
+ blitRect.size.width = rect.size.width;
+ blitRect.size.height = rect.size.height;
+
+ clipRect.origin.x = rect.origin.x;
+ clipRect.origin.y = frameRect.size.height - rect.origin.y - rect.size.height;
+
+ clipRect.size.width = rect.size.width;
+ clipRect.size.height = rect.size.height;
+
+ /* Blit dirty part of image */
+ CGImageRef clippedImage = CGImageCreateWithImageInRect(fullImage, clipRect);
+ CGContextDrawImage(viewContext, blitRect, clippedImage);
+ CGImageRelease(clippedImage);
+ }
+ }
+
+ CGImageRelease(fullImage);
+}
+
+@end
+
#endif /* WITH_COCOA */
diff --git a/src/video/cocoa/cocoa_wnd.mm b/src/video/cocoa/cocoa_wnd.mm
index 8f72836cc..dd1d269f8 100644
--- a/src/video/cocoa/cocoa_wnd.mm
+++ b/src/video/cocoa/cocoa_wnd.mm
@@ -24,6 +24,7 @@
#include "../../openttd.h"
#include "../../debug.h"
+#include "../../rev.h"
#include "cocoa_v.h"
#include "cocoa_wnd.h"
#include "../../string_func.h"
@@ -345,6 +346,15 @@ void CocoaDialog(const char *title, const char *message, const char *buttonLabel
selector:@selector(appDidUnhide:) name:NSApplicationDidUnhideNotification object:NSApp ];
self->driver = drv;
+
+ [ self setContentMinSize:NSMakeSize(64.0f, 64.0f) ];
+ [ self setAcceptsMouseMovedEvents:YES ];
+
+ std::string caption = std::string{"OpenTTD "} + _openttd_revision;
+ NSString *nsscaption = [ [ NSString alloc ] initWithUTF8String:caption.c_str() ];
+ [ self setTitle:nsscaption ];
+ [ self setMiniwindowTitle:nsscaption ];
+ [ nsscaption release ];
}
return self;