From 9a3d53ae510d48b9573fb26180becc757188c3dd Mon Sep 17 00:00:00 2001 From: Lior Halphon Date: Mon, 11 Jun 2018 20:23:51 +0300 Subject: [PATCH] Remove OpenGL specific code from GBView --- Cocoa/Document.xib | 4 +- Cocoa/{GBShader.h => GBGLShader.h} | 2 +- Cocoa/{GBShader.m => GBGLShader.m} | 4 +- Cocoa/GBOpenGLView.h | 6 +++ Cocoa/GBOpenGLView.m | 42 ++++++++++++++++ Cocoa/GBView.h | 8 +-- Cocoa/GBView.m | 80 +++++++++++------------------- Cocoa/GBViewGL.h | 5 ++ Cocoa/GBViewGL.m | 26 ++++++++++ 9 files changed, 119 insertions(+), 58 deletions(-) rename Cocoa/{GBShader.h => GBGLShader.h} (85%) rename Cocoa/{GBShader.m => GBGLShader.m} (99%) create mode 100644 Cocoa/GBOpenGLView.h create mode 100644 Cocoa/GBOpenGLView.m create mode 100644 Cocoa/GBViewGL.h create mode 100644 Cocoa/GBViewGL.m diff --git a/Cocoa/Document.xib b/Cocoa/Document.xib index 18114a3..88c5275 100644 --- a/Cocoa/Document.xib +++ b/Cocoa/Document.xib @@ -54,10 +54,10 @@ - + - + diff --git a/Cocoa/GBShader.h b/Cocoa/GBGLShader.h similarity index 85% rename from Cocoa/GBShader.h rename to Cocoa/GBGLShader.h index d2c4477..76291fb 100644 --- a/Cocoa/GBShader.h +++ b/Cocoa/GBGLShader.h @@ -1,6 +1,6 @@ #import -@interface GBShader : NSObject +@interface GBGLShader : NSObject - (instancetype)initWithName:(NSString *) shaderName; - (void) renderBitmap: (void *)bitmap previous:(void*) previous inSize:(NSSize)size scale: (double) scale; @end diff --git a/Cocoa/GBShader.m b/Cocoa/GBGLShader.m similarity index 99% rename from Cocoa/GBShader.m rename to Cocoa/GBGLShader.m index 63bfaac..1fa2ba3 100644 --- a/Cocoa/GBShader.m +++ b/Cocoa/GBGLShader.m @@ -1,4 +1,4 @@ -#import "GBShader.h" +#import "GBGLShader.h" #import /* @@ -16,7 +16,7 @@ void main(void) {\n\ }\n\ "; -@implementation GBShader +@implementation GBGLShader { GLuint resolution_uniform; GLuint texture_uniform; diff --git a/Cocoa/GBOpenGLView.h b/Cocoa/GBOpenGLView.h new file mode 100644 index 0000000..5f875ab --- /dev/null +++ b/Cocoa/GBOpenGLView.h @@ -0,0 +1,6 @@ +#import +#import "GBGLShader.h" + +@interface GBOpenGLView : NSOpenGLView +@property GBGLShader *shader; +@end diff --git a/Cocoa/GBOpenGLView.m b/Cocoa/GBOpenGLView.m new file mode 100644 index 0000000..505f5db --- /dev/null +++ b/Cocoa/GBOpenGLView.m @@ -0,0 +1,42 @@ +#import "GBOpenGLView.h" +#import "GBView.h" +#include + +@implementation GBOpenGLView + +- (void)drawRect:(NSRect)dirtyRect { + if (!self.shader) { + self.shader = [[GBGLShader alloc] initWithName:[[NSUserDefaults standardUserDefaults] objectForKey:@"GBFilter"]]; + } + + GBView *gbview = (GBView *)self.superview; + double scale = self.window.backingScaleFactor; + glViewport(0, 0, self.bounds.size.width * scale, self.bounds.size.height * scale); + + if (gbview.shouldBlendFrameWithPrevious) { + [self.shader renderBitmap:gbview.currentBuffer + previous:gbview.previousBuffer + inSize:self.bounds.size + scale:scale]; + } + else { + [self.shader renderBitmap:gbview.currentBuffer + previous:NULL + inSize:self.bounds.size + scale:scale]; + } + glFlush(); +} + +- (instancetype)initWithFrame:(NSRect)frameRect pixelFormat:(NSOpenGLPixelFormat *)format +{ + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(filterChanged) name:@"GBFilterChanged" object:nil]; + return [super initWithFrame:frameRect pixelFormat:format]; +} + +- (void) filterChanged +{ + self.shader = nil; + [self setNeedsDisplay:YES]; +} +@end diff --git a/Cocoa/GBView.h b/Cocoa/GBView.h index ffd6dc0..c054e09 100644 --- a/Cocoa/GBView.h +++ b/Cocoa/GBView.h @@ -1,14 +1,16 @@ #import #include #import "GBJoystickListener.h" -#import "GBShader.h" -@interface GBView : NSOpenGLView +@interface GBView : NSView - (void) flip; - (uint32_t *) pixels; @property GB_gameboy_t *gb; @property (nonatomic) BOOL shouldBlendFrameWithPrevious; -@property GBShader *shader; @property (getter=isMouseHidingEnabled) BOOL mouseHidingEnabled; @property bool isRewinding; +@property NSView *internalView; +- (void) createInternalView; +- (uint32_t *)currentBuffer; +- (uint32_t *)previousBuffer; @end diff --git a/Cocoa/GBView.m b/Cocoa/GBView.m index d329328..92d0d5c 100644 --- a/Cocoa/GBView.m +++ b/Cocoa/GBView.m @@ -1,6 +1,6 @@ -#import #import #import "GBView.h" +#import "GBViewGL.h" #import "GBButtons.h" #import "NSString+StringForKey.h" @@ -17,29 +17,26 @@ NSEventModifierFlags previousModifiers; } -- (void) awakeFromNib ++ (instancetype)alloc { - NSOpenGLPixelFormatAttribute attrs[] = - { - NSOpenGLPFAOpenGLProfile, - NSOpenGLProfileVersion3_2Core, - 0 - }; - - NSOpenGLPixelFormat *pf = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs] ; - - if (!pf) - { - NSLog(@"No OpenGL pixel format"); + if (self == [GBView class]) { + return [GBViewGL alloc]; } - - NSOpenGLContext* context = [[NSOpenGLContext alloc] initWithFormat:pf shareContext:nil] ; - - [self setPixelFormat:pf]; - - [self setOpenGLContext:context]; + return [super alloc]; } ++ (instancetype)allocWithZone:(struct _NSZone *)zone +{ + if (self == [GBView class]) { + return [GBViewGL allocWithZone: zone]; + } + return [super allocWithZone:zone]; +} + +- (void) createInternalView +{ + assert(false && "createInternalView must not be inherited"); +} - (void) _init { @@ -47,7 +44,6 @@ image_buffers[1] = malloc(160 * 144 * 4); image_buffers[2] = malloc(160 * 144 * 4); _shouldBlendFrameWithPrevious = 1; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(filterChanged) name:@"GBFilterChanged" object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(ratioKeepingChanged) name:@"GBAspectChanged" object:nil]; tracking_area = [ [NSTrackingArea alloc] initWithRect:(NSRect){} options:NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways | NSTrackingInVisibleRect @@ -55,12 +51,9 @@ userInfo:nil]; [self addTrackingArea:tracking_area]; clockMultiplier = 1.0; -} - -- (void) filterChanged -{ - [self setNeedsDisplay:YES]; - self.shader = nil; + [self createInternalView]; + [self addSubview:self.internalView]; + self.internalView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable; } - (void) ratioKeepingChanged @@ -132,29 +125,6 @@ [super setFrame:frame]; } -- (void)drawRect:(NSRect)dirtyRect { - if (!self.shader) { - self.shader = [[GBShader alloc] initWithName:[[NSUserDefaults standardUserDefaults] objectForKey:@"GBFilter"]]; - } - - double scale = self.window.backingScaleFactor; - glViewport(0, 0, self.bounds.size.width * scale, self.bounds.size.height * scale); - - if (_shouldBlendFrameWithPrevious) { - [self.shader renderBitmap:image_buffers[current_buffer] - previous:image_buffers[(current_buffer + 2) % self.numberOfBuffers] - inSize:self.bounds.size - scale:scale]; - } - else { - [self.shader renderBitmap:image_buffers[current_buffer] - previous:NULL - inSize:self.bounds.size - scale:scale]; - } - glFlush(); -} - - (void) flip { if (underclockKeyDown && clockMultiplier > 0.5) { @@ -362,4 +332,14 @@ previousModifiers = event.modifierFlags; } +- (uint32_t *)currentBuffer +{ + return image_buffers[current_buffer]; +} + +- (uint32_t *)previousBuffer +{ + return image_buffers[(current_buffer + 2) % self.numberOfBuffers]; +} + @end diff --git a/Cocoa/GBViewGL.h b/Cocoa/GBViewGL.h new file mode 100644 index 0000000..28db484 --- /dev/null +++ b/Cocoa/GBViewGL.h @@ -0,0 +1,5 @@ +#import "GBView.h" + +@interface GBViewGL : GBView + +@end diff --git a/Cocoa/GBViewGL.m b/Cocoa/GBViewGL.m new file mode 100644 index 0000000..d678cfe --- /dev/null +++ b/Cocoa/GBViewGL.m @@ -0,0 +1,26 @@ +#import "GBViewGL.h" +#import "GBOpenGLView.h" + +@implementation GBViewGL + +- (void)createInternalView +{ + NSOpenGLPixelFormatAttribute attrs[] = + { + NSOpenGLPFAOpenGLProfile, + NSOpenGLProfileVersion3_2Core, + 0 + }; + + NSOpenGLPixelFormat *pf = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs]; + + assert(pf); + + NSOpenGLContext *context = [[NSOpenGLContext alloc] initWithFormat:pf shareContext:nil]; + + self.internalView = [[GBOpenGLView alloc] initWithFrame:self.frame pixelFormat:pf]; + ((GBOpenGLView *)self.internalView).wantsBestResolutionOpenGLSurface = YES; + ((GBOpenGLView *)self.internalView).openGLContext = context; +} + +@end