mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-08-31 04:40:00 +02:00
Update to 20180729 release.
byuu wrote: Sigh ... asio.hpp needs #include <nall/windows/registry.hpp> [Since the last WIP, byuu also posted the following message. -Ed.] ruby drivers have all been updated (but not tested outside of BSD), and I redesigned the settings window. The driver functionality all exists on a new "Drivers" panel, the emulator/hack settings go to a "Configuration" panel, and the video/audio panels lose driver settings. As does the settings menu and its synchronize options. I want to start pushing toward a v107 release. Critically, I will need DirectSound and ALSA to support dynamic rate control. I'd also like to eliminate the other system manifest.bml files. I need to update the cheat code database format, and bundle at least a few quark shaders -- although I still need to default to Direct3D on Windows. Turbo keys would be nice, if it's not too much effort. Aside from netplay, it's the last significant feature I'm missing. I think for v107, higan is going to be a bit rough around the edges compared to bsnes. And I don't think it's practical to finish the bsnes localization support. I'm thinking we probably want another WIP to iron out any critical issues, but this time there should be a feature freeze with the next WIP.
This commit is contained in:
@@ -15,22 +15,24 @@ struct VideoCGL : Video, OpenGL {
|
||||
VideoCGL() { initialize(); }
|
||||
~VideoCGL() { terminate(); }
|
||||
|
||||
auto ready() -> bool { return _ready; }
|
||||
auto driver() -> string override { return "OpenGL"; }
|
||||
auto ready() -> bool override { return _ready; }
|
||||
|
||||
auto context() -> uintptr { return (uintptr)_context; }
|
||||
auto blocking() -> bool { return _blocking; }
|
||||
auto smooth() -> bool { return _smooth; }
|
||||
auto shader() -> string { return _shader; }
|
||||
auto hasContext() -> bool override { return true; }
|
||||
auto hasBlocking() -> bool override { return true; }
|
||||
auto hasFlush() -> bool override { return true; }
|
||||
auto hasSmooth() -> bool override { return true; }
|
||||
auto hasShader() -> bool override { return true; }
|
||||
|
||||
auto setContext(uintptr context) -> bool {
|
||||
if(_context == (NSView*)context) return true;
|
||||
_context = (NSView*)context;
|
||||
auto setContext(uintptr context) -> bool override {
|
||||
if(context == Video::context()) return true;
|
||||
if(!Video::setContext(context)) return false;
|
||||
return initialize();
|
||||
}
|
||||
|
||||
auto setBlocking(bool blocking) -> bool {
|
||||
if(_blocking == blocking) return true;
|
||||
_blocking = blocking;
|
||||
auto setBlocking(bool blocking) -> bool override {
|
||||
if(blocking == Video::blocking()) return true;
|
||||
if(!Video::setBlocking(blocking)) return false;
|
||||
if(!view) return true;
|
||||
@autoreleasepool {
|
||||
[[view openGLContext] makeCurrentContext];
|
||||
@@ -40,21 +42,28 @@ struct VideoCGL : Video, OpenGL {
|
||||
return true;
|
||||
}
|
||||
|
||||
auto setSmooth(bool smooth) -> bool {
|
||||
if(_smooth == smooth) return true;
|
||||
_smooth = smooth;
|
||||
if(!_shader) OpenGL::filter = _smooth ? GL_LINEAR : GL_NEAREST;
|
||||
auto setFlush(bool flush) -> bool override {
|
||||
if(flush == Video::flush()) return true;
|
||||
if(!Video::setFlush(flush)) return false;
|
||||
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;
|
||||
auto setSmooth(bool smooth) -> bool override {
|
||||
if(smooth == Video::smooth()) return true;
|
||||
if(!Video::setSmooth(smooth)) return false;
|
||||
if(!shader()) OpenGL::filter = smooth ? GL_LINEAR : GL_NEAREST;
|
||||
return true;
|
||||
}
|
||||
|
||||
auto clear() -> void {
|
||||
auto setShader(string shader) -> bool override {
|
||||
if(shader == Video::shader()) return true;
|
||||
if(!Video::setShader(shader)) return false;
|
||||
OpenGL::setShader(shader);
|
||||
if(!shader) OpenGL::filter = smooth() ? GL_LINEAR : GL_NEAREST;
|
||||
return true;
|
||||
}
|
||||
|
||||
auto clear() -> void override {
|
||||
if(!ready()) return;
|
||||
@autoreleasepool {
|
||||
[view lockFocus];
|
||||
@@ -64,17 +73,17 @@ struct VideoCGL : Video, OpenGL {
|
||||
}
|
||||
}
|
||||
|
||||
auto lock(uint32_t*& data, uint& pitch, uint width, uint height) -> bool {
|
||||
auto acquire(uint32_t*& data, uint& pitch, uint width, uint height) -> bool override {
|
||||
if(!ready()) return false;
|
||||
OpenGL::size(width, height);
|
||||
return OpenGL::lock(data, pitch);
|
||||
}
|
||||
|
||||
auto unlock() -> void {
|
||||
auto release() -> void override {
|
||||
if(!ready()) return;
|
||||
}
|
||||
|
||||
auto output() -> void {
|
||||
auto output() -> void override {
|
||||
if(!ready()) return;
|
||||
@autoreleasepool {
|
||||
if([view lockFocusIfCanDraw]) {
|
||||
@@ -83,6 +92,7 @@ struct VideoCGL : Video, OpenGL {
|
||||
OpenGL::outputHeight = area.size.height;
|
||||
OpenGL::output();
|
||||
[[view openGLContext] flushBuffer];
|
||||
if(flush()) glFinish();
|
||||
[view unlockFocus];
|
||||
}
|
||||
}
|
||||
@@ -102,17 +112,18 @@ private:
|
||||
0
|
||||
};
|
||||
|
||||
auto size = [_context frame].size;
|
||||
auto context = (NSView*)_context;
|
||||
auto size = [context frame].size;
|
||||
auto format = [[[NSOpenGLPixelFormat alloc] initWithAttributes:attributeList] autorelease];
|
||||
auto context = [[[NSOpenGLContext alloc] initWithFormat:format shareContext:nil] autorelease];
|
||||
auto openGLContext = [[[NSOpenGLContext alloc] initWithFormat:format shareContext:nil] autorelease];
|
||||
|
||||
view = [[RubyVideoCGL alloc] initWith:this pixelFormat:format];
|
||||
[view setOpenGLContext:context];
|
||||
[view setOpenGLContext:openGLContext];
|
||||
[view setFrame:NSMakeRect(0, 0, size.width, size.height)];
|
||||
[view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
|
||||
[view setWantsBestResolutionOpenGLSurface:YES];
|
||||
[_context addSubview:view];
|
||||
[context setView:view];
|
||||
[context addSubview:view];
|
||||
[openGLContext setView:view];
|
||||
|
||||
[view lockFocus];
|
||||
|
||||
@@ -143,10 +154,6 @@ private:
|
||||
RubyVideoCGL* view = nullptr;
|
||||
|
||||
bool _ready = false;
|
||||
NSView* _context = nullptr;
|
||||
bool _blocking = false;
|
||||
bool _smooth = true;
|
||||
string _shader;
|
||||
};
|
||||
|
||||
@implementation RubyVideoCGL : NSOpenGLView
|
||||
|
@@ -11,37 +11,40 @@ struct VideoDirect3D : Video {
|
||||
VideoDirect3D() { initialize(); }
|
||||
~VideoDirect3D() { terminate(); }
|
||||
|
||||
auto ready() -> bool { return _ready; }
|
||||
auto driver() -> string override { return "Direct3D"; }
|
||||
auto ready() -> bool override { return _ready; }
|
||||
|
||||
auto exclusive() -> bool { return _exclusive; }
|
||||
auto context() -> uintptr { return _context; }
|
||||
auto blocking() -> bool { return _blocking; }
|
||||
auto smooth() -> bool { return _smooth; }
|
||||
auto hasExclusive() -> bool override { return true; }
|
||||
auto hasContext() -> bool override { return true; }
|
||||
auto hasBlocking() -> bool override { return true; }
|
||||
auto hasSmooth() -> bool override { return true; }
|
||||
|
||||
auto setExclusive(bool exclusive) -> bool {
|
||||
if(_exclusive == exclusive) return true;
|
||||
_exclusive = exclusive;
|
||||
auto setExclusive(bool exclusive) -> bool override {
|
||||
if(exclusive == Video::exclusive()) return true;
|
||||
if(!Video::setExclusive(exclusive)) return false;
|
||||
return initialize();
|
||||
}
|
||||
|
||||
auto setContext(uintptr context) -> bool {
|
||||
if(_context == context) return true;
|
||||
_context = context;
|
||||
auto setContext(uintptr context) -> bool override {
|
||||
if(context == Video::context()) return true;
|
||||
if(!Video::setContext(context)) return false;
|
||||
return initialize();
|
||||
}
|
||||
|
||||
auto setBlocking(bool blocking) -> bool {
|
||||
_blocking = blocking;
|
||||
auto setBlocking(bool blocking) -> bool override {
|
||||
if(blocking == Video::blocking()) return true;
|
||||
if(!Video::setBlocking(blocking)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
auto setSmooth(bool smooth) -> bool {
|
||||
_smooth = smooth;
|
||||
if(_ready) updateFilter();
|
||||
auto setSmooth(bool smooth) -> bool override {
|
||||
if(smooth == Video::smooth()) return true;
|
||||
if(!Video::setSmooth(smooth)) return false;
|
||||
if(ready()) updateFilter();
|
||||
return true;
|
||||
}
|
||||
|
||||
auto clear() -> void {
|
||||
auto clear() -> void override {
|
||||
if(!ready()) return;
|
||||
if(_lost && !recover()) return;
|
||||
|
||||
@@ -62,7 +65,7 @@ struct VideoDirect3D : Video {
|
||||
}
|
||||
}
|
||||
|
||||
auto lock(uint32_t*& data, uint& pitch, uint width, uint height) -> bool {
|
||||
auto acquire(uint32_t*& data, uint& pitch, uint width, uint height) -> bool override {
|
||||
if(!ready()) return false;
|
||||
if(_lost && !recover()) return false;
|
||||
|
||||
@@ -86,14 +89,14 @@ struct VideoDirect3D : Video {
|
||||
return data = (uint32_t*)lockedRectangle.pBits;
|
||||
}
|
||||
|
||||
auto unlock() -> void {
|
||||
auto release() -> void override {
|
||||
if(!ready()) return;
|
||||
_surface->UnlockRect();
|
||||
_surface->Release();
|
||||
_surface = nullptr;
|
||||
}
|
||||
|
||||
auto output() -> void {
|
||||
auto output() -> void override {
|
||||
if(!ready()) return;
|
||||
if(_lost && !recover()) return;
|
||||
|
||||
@@ -327,12 +330,7 @@ private:
|
||||
float u, v; //texture coordinates
|
||||
};
|
||||
|
||||
bool _exclusive = false;
|
||||
bool _ready = false;
|
||||
uintptr _context = 0;
|
||||
bool _blocking = false;
|
||||
bool _smooth = true;
|
||||
|
||||
uintptr _exclusiveContext = 0;
|
||||
|
||||
LPDIRECT3D9 _instance = nullptr;
|
||||
|
@@ -5,24 +5,25 @@ struct VideoDirectDraw : Video {
|
||||
VideoDirectDraw() { initialize(); }
|
||||
~VideoDirectDraw() { terminate(); }
|
||||
|
||||
auto ready() -> bool { return _ready; }
|
||||
auto driver() -> string override { return "DirectDraw"; }
|
||||
auto ready() -> bool override { return _ready; }
|
||||
|
||||
auto context() -> uintptr { return _context; }
|
||||
auto blocking() -> bool { return _blocking; }
|
||||
auto hasContext() -> bool override { return true; }
|
||||
auto hasBlocking() -> bool override { return true; }
|
||||
|
||||
auto setContext(uintptr context) -> bool {
|
||||
if(_context == context) return true;
|
||||
_context = context;
|
||||
auto setContext(uintptr context) -> bool override {
|
||||
if(context == Video::context()) return true;
|
||||
if(!Video::setContext(context)) return false;
|
||||
return initialize();
|
||||
}
|
||||
|
||||
auto setBlocking(bool blocking) -> bool {
|
||||
if(_blocking == blocking) return true;
|
||||
_blocking = blocking;
|
||||
auto setBlocking(bool blocking) -> bool override {
|
||||
if(blocking == Video::blocking()) return true;
|
||||
if(!Video::setBlocking(blocking)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
auto clear() -> void {
|
||||
auto clear() -> void override {
|
||||
if(!ready()) return;
|
||||
DDBLTFX fx = {};
|
||||
fx.dwSize = sizeof(DDBLTFX);
|
||||
@@ -31,7 +32,7 @@ struct VideoDirectDraw : Video {
|
||||
_raster->Blt(0, 0, 0, DDBLT_WAIT | DDBLT_COLORFILL, &fx);
|
||||
}
|
||||
|
||||
auto lock(uint32_t*& data, uint& pitch, uint width, uint height) -> bool {
|
||||
auto acquire(uint32_t*& data, uint& pitch, uint width, uint height) -> bool override {
|
||||
if(!ready()) return false;
|
||||
if(width != _width || height != _height) resize(_width = width, _height = height);
|
||||
DDSURFACEDESC2 description = {};
|
||||
@@ -44,12 +45,12 @@ struct VideoDirectDraw : Video {
|
||||
return data = (uint32_t*)description.lpSurface;
|
||||
}
|
||||
|
||||
auto unlock() -> void {
|
||||
auto release() -> void override {
|
||||
if(!ready()) return;
|
||||
_raster->Unlock(0);
|
||||
}
|
||||
|
||||
auto output() -> void {
|
||||
auto output() -> void override {
|
||||
if(!ready()) return;
|
||||
if(_blocking) while(true) {
|
||||
BOOL vblank;
|
||||
@@ -152,8 +153,6 @@ private:
|
||||
}
|
||||
|
||||
bool _ready = false;
|
||||
uintptr _context = 0;
|
||||
bool _blocking = false;
|
||||
|
||||
uint _width = 0;
|
||||
uint _height = 0;
|
||||
|
@@ -2,21 +2,22 @@ struct VideoGDI : Video {
|
||||
VideoGDI() { initialize(); }
|
||||
~VideoGDI() { terminate(); }
|
||||
|
||||
auto ready() -> bool { return _ready; }
|
||||
auto driver() -> string override { return "GDI"; }
|
||||
auto ready() -> bool override { return _ready; }
|
||||
|
||||
auto context() -> uintptr { return _context; }
|
||||
auto hasContext() -> bool override { return true; }
|
||||
|
||||
auto setContext(uintptr context) -> bool {
|
||||
if(_context == context) return true;
|
||||
_context = context;
|
||||
auto setContext(uintptr context) -> bool override {
|
||||
if(context == Video::context()) return true;
|
||||
if(!Video::setContext(context)) return false;
|
||||
return initialize();
|
||||
}
|
||||
|
||||
auto clear() -> void {
|
||||
auto clear() -> void override {
|
||||
if(!ready()) return;
|
||||
}
|
||||
|
||||
auto lock(uint32_t*& data, uint& pitch, uint width, uint height) -> bool {
|
||||
auto acquire(uint32_t*& data, uint& pitch, uint width, uint height) -> bool override {
|
||||
if(!ready()) return false;
|
||||
|
||||
if(!_buffer || _width != width || _height != height) {
|
||||
@@ -48,11 +49,11 @@ struct VideoGDI : Video {
|
||||
return data = _buffer;
|
||||
}
|
||||
|
||||
auto unlock() -> void {
|
||||
auto release() -> void override {
|
||||
if(!ready()) return;
|
||||
}
|
||||
|
||||
auto output() -> void {
|
||||
auto output() -> void override {
|
||||
if(!ready()) return;
|
||||
|
||||
RECT rc;
|
||||
@@ -82,7 +83,6 @@ private:
|
||||
}
|
||||
|
||||
bool _ready = false;
|
||||
uintptr _context = 0;
|
||||
|
||||
uint32_t* _buffer = nullptr;
|
||||
uint _width = 0;
|
||||
|
@@ -14,10 +14,6 @@ struct VideoGLX : Video, OpenGL {
|
||||
auto driver() -> string override { return "OpenGL"; }
|
||||
auto ready() -> bool override { return _ready; }
|
||||
|
||||
auto availableFormats() -> vector<string> override {
|
||||
return {"R8G8B8", "R10G10B10"};
|
||||
}
|
||||
|
||||
auto hasContext() -> bool override { return true; }
|
||||
auto hasBlocking() -> bool override { return true; }
|
||||
auto hasFlush() -> bool override { return true; }
|
||||
@@ -25,6 +21,10 @@ struct VideoGLX : Video, OpenGL {
|
||||
auto hasSmooth() -> bool override { return true; }
|
||||
auto hasShader() -> bool override { return true; }
|
||||
|
||||
auto availableFormats() -> vector<string> override {
|
||||
return {"RGB24", "RGB30"};
|
||||
}
|
||||
|
||||
auto setContext(uintptr context) -> bool override {
|
||||
if(context == Video::context()) return true;
|
||||
if(!Video::setContext(context)) return false;
|
||||
@@ -34,7 +34,7 @@ struct VideoGLX : Video, OpenGL {
|
||||
auto setBlocking(bool blocking) -> bool override {
|
||||
if(blocking == Video::blocking()) return true;
|
||||
if(!Video::setBlocking(blocking)) return false;
|
||||
if(glXSwapInterval) glXSwapInterval(_blocking);
|
||||
if(glXSwapInterval) glXSwapInterval(blocking);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -48,12 +48,12 @@ struct VideoGLX : Video, OpenGL {
|
||||
if(format == Video::format()) return true;
|
||||
if(!Video::setFormat(format)) return false;
|
||||
|
||||
if(format == "R8G8B8") {
|
||||
if(format == "RGB24") {
|
||||
OpenGL::inputFormat = GL_RGBA8;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(format == "R10G10B10") {
|
||||
if(format == "RGB30") {
|
||||
OpenGL::inputFormat = GL_RGB10_A2;
|
||||
return true;
|
||||
}
|
||||
@@ -82,13 +82,13 @@ struct VideoGLX : Video, OpenGL {
|
||||
if(_doubleBuffer) glXSwapBuffers(_display, _glXWindow);
|
||||
}
|
||||
|
||||
auto lock(uint32_t*& data, uint& pitch, uint width, uint height) -> bool override {
|
||||
auto acquire(uint32_t*& data, uint& pitch, uint width, uint height) -> bool override {
|
||||
if(!ready()) return false;
|
||||
OpenGL::size(width, height);
|
||||
return OpenGL::lock(data, pitch);
|
||||
}
|
||||
|
||||
auto unlock() -> void override {
|
||||
auto release() -> void override {
|
||||
if(!ready()) return;
|
||||
}
|
||||
|
||||
@@ -140,9 +140,9 @@ private:
|
||||
XWindowAttributes windowAttributes;
|
||||
XGetWindowAttributes(_display, (Window)_context, &windowAttributes);
|
||||
|
||||
int redDepth = Video::format() == "R10G10B10" ? 10 : 8;
|
||||
int greenDepth = Video::format() == "R10G10B10" ? 10 : 8;
|
||||
int blueDepth = Video::format() == "R10G10B10" ? 10 : 8;
|
||||
int redDepth = Video::format() == "RGB30" ? 10 : 8;
|
||||
int greenDepth = Video::format() == "RGB30" ? 10 : 8;
|
||||
int blueDepth = Video::format() == "RGB30" ? 10 : 8;
|
||||
|
||||
//let GLX determine the best Visual to use for GL output; provide a few hints
|
||||
//note: some video drivers will override double buffering attribute
|
||||
|
@@ -31,29 +31,51 @@ struct VideoGLX2 : Video {
|
||||
auto hasContext() -> bool override { return true; }
|
||||
auto hasBlocking() -> bool override { return true; }
|
||||
auto hasFlush() -> bool override { return true; }
|
||||
auto hasFormat() -> bool override { return true; }
|
||||
auto hasSmooth() -> bool override { return true; }
|
||||
|
||||
auto availableFormats() -> vector<string> override {
|
||||
return {"RGB24", "RGB30"};
|
||||
}
|
||||
|
||||
auto setContext(uintptr context) -> bool override {
|
||||
if(context == this->context()) return true;
|
||||
if(context == Video::context()) return true;
|
||||
if(!Video::setContext(context)) return false;
|
||||
return initialize();
|
||||
}
|
||||
|
||||
auto setBlocking(bool blocking) -> bool override {
|
||||
if(blocking == this->blocking()) return true;
|
||||
if(blocking == Video::blocking()) return true;
|
||||
if(!Video::setBlocking(blocking)) return false;
|
||||
if(ready() && glXSwapInterval) glXSwapInterval(_blocking);
|
||||
if(glXSwapInterval) glXSwapInterval(blocking);
|
||||
return true;
|
||||
}
|
||||
|
||||
auto setFlush(bool flush) -> bool override {
|
||||
if(flush == this->flush()) return true;
|
||||
if(flush == Video::flush()) return true;
|
||||
if(!Video::setFlush(flush)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
auto setFormat(string format) -> bool override {
|
||||
if(format == Video::format()) return true;
|
||||
if(!Video::setFormat(format)) return false;
|
||||
|
||||
if(format == "RGB24") {
|
||||
_glFormat = GL_UNSIGNED_INT_8_8_8_8_REV;
|
||||
return initialize();
|
||||
}
|
||||
|
||||
if(format == "RGB30") {
|
||||
_glFormat = GL_UNSIGNED_INT_2_10_10_10_REV;
|
||||
return initialize();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
auto setSmooth(bool smooth) -> bool override {
|
||||
if(smooth == this->smooth()) return true;
|
||||
if(smooth == Video::smooth()) return true;
|
||||
if(!Video::setSmooth(smooth)) return false;
|
||||
return true;
|
||||
}
|
||||
@@ -67,14 +89,14 @@ struct VideoGLX2 : Video {
|
||||
if(_isDoubleBuffered) glXSwapBuffers(_display, _glXWindow);
|
||||
}
|
||||
|
||||
auto lock(uint32_t*& data, uint& pitch, uint width, uint height) -> bool override {
|
||||
auto acquire(uint32_t*& data, uint& pitch, uint width, uint height) -> bool override {
|
||||
if(!ready()) return false;
|
||||
if(width != _width || height != _height) resize(width, height);
|
||||
pitch = _glWidth * sizeof(uint32_t);
|
||||
return data = _glBuffer;
|
||||
}
|
||||
|
||||
auto unlock() -> void override {
|
||||
auto release() -> void override {
|
||||
if(!ready()) return;
|
||||
}
|
||||
|
||||
@@ -101,7 +123,7 @@ struct VideoGLX2 : Video {
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, _glWidth);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, _width, _height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, _glBuffer);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, _width, _height, GL_BGRA, _glFormat, _glBuffer);
|
||||
|
||||
double w = (double)_width / (double)_glWidth;
|
||||
double h = (double)_height / (double)_glHeight;
|
||||
@@ -147,13 +169,17 @@ private:
|
||||
XWindowAttributes windowAttributes;
|
||||
XGetWindowAttributes(_display, (Window)_context, &windowAttributes);
|
||||
|
||||
int redDepth = Video::format() == "RGB30" ? 10 : 8;
|
||||
int greenDepth = Video::format() == "RGB30" ? 10 : 8;
|
||||
int blueDepth = Video::format() == "RGB30" ? 10 : 8;
|
||||
|
||||
int attributeList[] = {
|
||||
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
|
||||
GLX_RENDER_TYPE, GLX_RGBA_BIT,
|
||||
GLX_DOUBLEBUFFER, True,
|
||||
GLX_RED_SIZE, 8,
|
||||
GLX_GREEN_SIZE, 8,
|
||||
GLX_BLUE_SIZE, 8,
|
||||
GLX_RED_SIZE, redDepth,
|
||||
GLX_GREEN_SIZE, greenDepth,
|
||||
GLX_BLUE_SIZE, blueDepth,
|
||||
None
|
||||
};
|
||||
|
||||
@@ -253,7 +279,7 @@ private:
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, _glTexture);
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, _glWidth);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _glWidth, _glHeight, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, _glBuffer);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _glWidth, _glHeight, 0, GL_BGRA, _glFormat, _glBuffer);
|
||||
}
|
||||
|
||||
auto (*glXSwapInterval)(int) -> int = nullptr;
|
||||
@@ -277,4 +303,5 @@ private:
|
||||
uint32_t* _glBuffer = nullptr;
|
||||
uint _glWidth = 0;
|
||||
uint _glHeight = 0;
|
||||
uint _glFormat = GL_UNSIGNED_INT_8_8_8_8_REV;
|
||||
};
|
||||
|
@@ -7,57 +7,66 @@ struct VideoWGL : Video, OpenGL {
|
||||
VideoWGL() { initialize(); }
|
||||
~VideoWGL() { terminate(); }
|
||||
|
||||
auto ready() -> bool { return _ready; }
|
||||
auto driver() -> string override { return "OpenGL"; }
|
||||
auto ready() -> bool override { return _ready; }
|
||||
|
||||
auto context() -> uintptr { return _context; }
|
||||
auto blocking() -> bool { return _blocking; }
|
||||
auto smooth() -> bool { return _smooth; }
|
||||
auto shader() -> string { return _shader; }
|
||||
auto hasContext() -> bool override { return true; }
|
||||
auto hasBlocking() -> bool override { return true; }
|
||||
auto hasFlush() -> bool override { return true; }
|
||||
auto hasSmooth() -> bool override { return true; }
|
||||
auto hasShader() -> bool override { return true; }
|
||||
|
||||
auto setContext(uintptr context) -> bool {
|
||||
if(_context == context) return true;
|
||||
_context = context;
|
||||
auto setContext(uintptr context) -> bool override {
|
||||
if(context == Video::context()) return true;
|
||||
if(!Video::setContext(context)) return false;
|
||||
return initialize();
|
||||
}
|
||||
|
||||
auto setBlocking(bool blocking) -> bool {
|
||||
if(_blocking == blocking) return true;
|
||||
_blocking = blocking;
|
||||
if(wglSwapInterval) wglSwapInterval(_blocking);
|
||||
auto setBlocking(bool blocking) -> bool override {
|
||||
if(blocking == Video::blocking()) return true;
|
||||
if(!Video::setBlocking(blocking)) return false;
|
||||
if(wglSwapInterval) wglSwapInterval(blocking);
|
||||
return true;
|
||||
}
|
||||
|
||||
auto setSmooth(bool smooth) -> bool {
|
||||
if(_smooth == smooth) return true;
|
||||
_smooth = smooth;
|
||||
if(!_shader) OpenGL::filter = _smooth ? GL_LINEAR : GL_NEAREST;
|
||||
auto setFlush(bool flush) -> bool override {
|
||||
if(flush == Video::flush()) return true;
|
||||
if(!Video::setFlush(flush)) return false;
|
||||
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;
|
||||
auto setSmooth(bool smooth) -> bool override {
|
||||
if(smooth == Video::smooth()) return true;
|
||||
if(!Video::setSmooth(smooth)) return false;
|
||||
if(!shader()) OpenGL::filter = smooth ? GL_LINEAR : GL_NEAREST;
|
||||
return true;
|
||||
}
|
||||
|
||||
auto clear() -> void {
|
||||
auto setShader(string shader) -> bool override {
|
||||
if(shader == Video::shader()) return true;
|
||||
if(!Video::setShader(shader)) return false;
|
||||
OpenGL::setShader(shader);
|
||||
if(!shader) OpenGL::filter = smooth() ? GL_LINEAR : GL_NEAREST;
|
||||
return true;
|
||||
}
|
||||
|
||||
auto clear() -> void override {
|
||||
if(!ready()) return;
|
||||
OpenGL::clear();
|
||||
SwapBuffers(_display);
|
||||
}
|
||||
|
||||
auto lock(uint32_t*& data, uint& pitch, uint width, uint height) -> bool {
|
||||
auto acquire(uint32_t*& data, uint& pitch, uint width, uint height) -> bool override {
|
||||
if(!ready()) return false;
|
||||
OpenGL::size(width, height);
|
||||
return OpenGL::lock(data, pitch);
|
||||
}
|
||||
|
||||
auto unlock() -> void {
|
||||
auto release() -> void override {
|
||||
if(!ready()) return;
|
||||
}
|
||||
|
||||
auto output() -> void {
|
||||
auto output() -> void override {
|
||||
if(!ready()) return;
|
||||
RECT rectangle;
|
||||
GetClientRect((HWND)_context, &rectangle);
|
||||
@@ -65,6 +74,7 @@ struct VideoWGL : Video, OpenGL {
|
||||
OpenGL::outputHeight = rectangle.bottom - rectangle.top;
|
||||
OpenGL::output();
|
||||
SwapBuffers(_display);
|
||||
if(flush()) glFinish();
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -120,10 +130,6 @@ private:
|
||||
auto (APIENTRY* wglSwapInterval)(int) -> BOOL = nullptr;
|
||||
|
||||
bool _ready = false;
|
||||
uintptr _context = 0;
|
||||
bool _blocking = false;
|
||||
bool _smooth = true;
|
||||
string _shader;
|
||||
|
||||
HDC _display = nullptr;
|
||||
HGLRC _wglContext = nullptr;
|
||||
|
@@ -18,6 +18,14 @@ struct VideoXShm : Video {
|
||||
auto hasContext() -> bool override { return true; }
|
||||
auto hasSmooth() -> bool override { return true; }
|
||||
|
||||
auto availableFormats() -> vector<string> { return {"RGB24"}; }
|
||||
|
||||
auto exclusive() -> bool override { return false; }
|
||||
auto blocking() -> bool override { return false; }
|
||||
auto flush() -> bool override { return false; }
|
||||
auto format() -> string override { return "RGB24"; }
|
||||
auto shader() -> string override { return ""; }
|
||||
|
||||
auto setContext(uintptr context) -> bool override {
|
||||
if(context == this->context()) return true;
|
||||
if(!Video::setContext(context)) return false;
|
||||
@@ -38,7 +46,7 @@ struct VideoXShm : Video {
|
||||
output();
|
||||
}
|
||||
|
||||
auto lock(uint32_t*& data, uint& pitch, uint width, uint height) -> bool override {
|
||||
auto acquire(uint32_t*& data, uint& pitch, uint width, uint height) -> bool override {
|
||||
if(!ready()) return false;
|
||||
if(!_inputBuffer || _inputWidth != width || _inputHeight != height) {
|
||||
if(_inputBuffer) delete[] _inputBuffer;
|
||||
@@ -52,7 +60,7 @@ struct VideoXShm : Video {
|
||||
return true;
|
||||
}
|
||||
|
||||
auto unlock() -> void override {
|
||||
auto release() -> void override {
|
||||
if(!ready()) return;
|
||||
}
|
||||
|
||||
|
@@ -13,14 +13,14 @@ struct VideoXVideo : Video {
|
||||
auto driver() -> string override { return "XVideo"; }
|
||||
auto ready() -> bool override { return _ready; }
|
||||
|
||||
auto availableFormats() -> vector<string> override {
|
||||
return _formatNames;
|
||||
}
|
||||
|
||||
auto hasContext() -> bool override { return true; }
|
||||
auto hasBlocking() -> bool override { return true; }
|
||||
auto hasFormat() -> bool override { return true; }
|
||||
|
||||
auto availableFormats() -> vector<string> override {
|
||||
return _formatNames;
|
||||
}
|
||||
|
||||
auto setContext(uintptr context) -> bool override {
|
||||
if(context == Video::context()) return true;
|
||||
if(!Video::setContext(context)) return false;
|
||||
@@ -56,14 +56,14 @@ struct VideoXVideo : Video {
|
||||
output();
|
||||
}
|
||||
|
||||
auto lock(uint32_t*& data, uint& pitch, uint width, uint height) -> bool override {
|
||||
auto acquire(uint32_t*& data, uint& pitch, uint width, uint height) -> bool override {
|
||||
if(!ready()) return false;
|
||||
if(width != _width || height != _height) resize(_width = width, _height = height);
|
||||
pitch = _bufferWidth * 4;
|
||||
return data = _buffer;
|
||||
}
|
||||
|
||||
auto unlock() -> void override {
|
||||
auto release() -> void override {
|
||||
if(!ready()) return;
|
||||
}
|
||||
|
||||
@@ -87,14 +87,14 @@ struct VideoXVideo : Video {
|
||||
XGetWindowAttributes(_display, _window, &target);
|
||||
|
||||
auto& name = _formatName;
|
||||
if(name == "RGB32") renderRGB32(_width, _height);
|
||||
if(name == "RGB24") renderRGB24(_width, _height);
|
||||
if(name == "RGB16") renderRGB16(_width, _height);
|
||||
if(name == "RGB15") renderRGB15(_width, _height);
|
||||
if(name == "UYVY" ) renderUYVY (_width, _height);
|
||||
if(name == "YUY2" ) renderYUY2 (_width, _height);
|
||||
if(name == "YV12" ) renderYV12 (_width, _height);
|
||||
if(name == "I420" ) renderI420 (_width, _height);
|
||||
if(name == "RGB24" ) renderRGB24 (_width, _height);
|
||||
if(name == "RGB24P") renderRGB24P(_width, _height);
|
||||
if(name == "RGB16" ) renderRGB16 (_width, _height);
|
||||
if(name == "RGB15" ) renderRGB15 (_width, _height);
|
||||
if(name == "UYVY" ) renderUYVY (_width, _height);
|
||||
if(name == "YUY2" ) renderYUY2 (_width, _height);
|
||||
if(name == "YV12" ) renderYV12 (_width, _height);
|
||||
if(name == "I420" ) renderI420 (_width, _height);
|
||||
|
||||
XvShmPutImage(_display, _port, _window, _gc, _image,
|
||||
0, 0, _width, _height,
|
||||
@@ -275,8 +275,8 @@ private:
|
||||
for(uint n : range(4)) if(char c = order[n]) components.append(c);
|
||||
|
||||
if(type == XvRGB) {
|
||||
if(sort == 0 && depth == 32) ids.append(id), names.append("RGB32");
|
||||
if(sort == 1 && depth == 24) ids.append(id), names.append("RGB24");
|
||||
if(sort == 0 && depth == 32) ids.append(id), names.append("RGB24");
|
||||
if(sort == 1 && depth == 24) ids.append(id), names.append("RGB24P");
|
||||
if(sort == 2 && depth <= 16 && redMask == 0xf800) ids.append(id), names.append("RGB16");
|
||||
if(sort == 3 && depth <= 16 && redMask == 0x7c00) ids.append(id), names.append("RGB15");
|
||||
}
|
||||
@@ -326,7 +326,7 @@ private:
|
||||
_buffer = new uint32_t[_bufferWidth * _bufferHeight];
|
||||
}
|
||||
|
||||
auto renderRGB32(uint width, uint height) -> void {
|
||||
auto renderRGB24(uint width, uint height) -> void {
|
||||
for(uint y : range(height)) {
|
||||
auto input = (const uint32_t*)_buffer + y * width;
|
||||
auto output = (uint32_t*)_image->data + y * (_image->pitches[0] >> 2);
|
||||
@@ -338,7 +338,7 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
auto renderRGB24(uint width, uint height) -> void {
|
||||
auto renderRGB24P(uint width, uint height) -> void {
|
||||
for(uint y : range(height)) {
|
||||
auto input = (const uint32_t*)_buffer + y * width;
|
||||
auto output = (uint8_t*)_image->data + y * _image->pitches[0];
|
||||
|
Reference in New Issue
Block a user