bsnes/ruby/video/cgl.cpp
Tim Allen 0b6f1df987 Update to v103r27 release.
byuu says:

Changelog:

  - hiro/windows: set dpiAware=false, fixes icarus window sizes relative
    to higan window sizes
  - higan, icarus, hiro, ruby: add support for high resolution displays
    on macOS [ncbncb]
  - processor/lr35902-legacy: removed
  - processor/arm7tdmi: new processor core started; intended to one day
    be a replacement for processor/arm

It will probably take several WIPs to get the new ARM core up and
running. It's the last processor rewrite. After this, all processor
cores will be up to date with all my current programming conventions.
2017-08-06 23:36:26 +10:00

166 lines
4.1 KiB
C++

#define GL_ALPHA_TEST 0x0bc0
#include "opengl/opengl.hpp"
struct VideoCGL;
@interface RubyVideoCGL : NSOpenGLView {
@public
VideoCGL* video;
}
-(id) initWith:(VideoCGL*)video pixelFormat:(NSOpenGLPixelFormat*)pixelFormat;
-(void) reshape;
@end
struct VideoCGL : Video, OpenGL {
VideoCGL() { initialize(); }
~VideoCGL() { terminate(); }
auto ready() -> bool { return _ready; }
auto context() -> uintptr { return (uintptr)_context; }
auto blocking() -> bool { return _blocking; }
auto smooth() -> bool { return _smooth; }
auto shader() -> string { return _shader; }
auto setContext(uintptr context) -> bool {
if(_context == (NSView*)context) return true;
_context = (NSView*)context;
return initialize();
}
auto setBlocking(bool blocking) -> bool {
if(_blocking == blocking) return true;
_blocking = blocking;
if(!view) return true;
@autoreleasepool {
[[view openGLContext] makeCurrentContext];
int blocking = _blocking;
[[view openGLContext] setValues:&blocking forParameter:NSOpenGLCPSwapInterval];
}
return true;
}
auto setSmooth(bool smooth) -> bool {
if(_smooth == smooth) return true;
_smooth = smooth;
if(!_shader) OpenGL::filter = _smooth ? GL_LINEAR : GL_NEAREST;
return true;
}
auto setShader(string shader) -> bool {
if(_shader == shader) return true;
OpenGL::shader(_shader = shader);
if(!_shader) OpenGL::filter = _smooth ? GL_LINEAR : GL_NEAREST;
return true;
}
auto clear() -> void {
if(!ready()) return;
@autoreleasepool {
[view lockFocus];
OpenGL::clear();
[[view openGLContext] flushBuffer];
[view unlockFocus];
}
}
auto lock(uint32_t*& data, uint& pitch, uint width, uint height) -> bool {
if(!ready()) return false;
OpenGL::size(width, height);
return OpenGL::lock(data, pitch);
}
auto unlock() -> void {
if(!ready()) return;
}
auto output() -> void {
if(!ready()) return;
@autoreleasepool {
if([view lockFocusIfCanDraw]) {
auto area = [view convertRectToBacking:[view bounds]];
OpenGL::outputWidth = area.size.width;
OpenGL::outputHeight = area.size.height;
OpenGL::output();
[[view openGLContext] flushBuffer];
[view unlockFocus];
}
}
}
private:
auto initialize() -> bool {
terminate();
if(!_context) return false;
@autoreleasepool {
NSOpenGLPixelFormatAttribute attributeList[] = {
NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,
NSOpenGLPFAColorSize, 24,
NSOpenGLPFAAlphaSize, 8,
NSOpenGLPFADoubleBuffer,
0
};
auto size = [_context frame].size;
auto format = [[[NSOpenGLPixelFormat alloc] initWithAttributes:attributeList] autorelease];
auto context = [[[NSOpenGLContext alloc] initWithFormat:format shareContext:nil] autorelease];
view = [[RubyVideoCGL alloc] initWith:this pixelFormat:format];
[view setOpenGLContext:context];
[view setFrame:NSMakeRect(0, 0, size.width, size.height)];
[view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
[view setWantsBestResolutionOpenGLSurface:YES];
[_context addSubview:view];
[context setView:view];
[view lockFocus];
OpenGL::initialize();
int blocking = _blocking;
[[view openGLContext] setValues:&blocking forParameter:NSOpenGLCPSwapInterval];
[view unlockFocus];
}
clear();
return _ready = true;
}
auto terminate() -> void {
_ready = false;
OpenGL::terminate();
if(!view) return;
@autoreleasepool {
[view removeFromSuperview];
[view release];
view = nil;
}
}
RubyVideoCGL* view = nullptr;
bool _ready = false;
NSView* _context = nullptr;
bool _blocking = false;
bool _smooth = true;
string _shader;
};
@implementation RubyVideoCGL : NSOpenGLView
-(id) initWith:(VideoCGL*)videoPointer pixelFormat:(NSOpenGLPixelFormat*)pixelFormat {
if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0) pixelFormat:pixelFormat]) {
video = videoPointer;
}
return self;
}
-(void) reshape {
video->output();
}
@end