diff options
-rw-r--r-- | src/video/cocoa/cocoa_v.h | 6 | ||||
-rw-r--r-- | src/video/cocoa/cocoa_v.mm | 221 | ||||
-rw-r--r-- | src/video/cocoa/cocoa_wnd.mm | 10 |
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; |