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:
Tim Allen
2018-07-29 23:24:38 +10:00
parent 716c95f279
commit 5deba5cbc1
182 changed files with 1533 additions and 2674 deletions

View File

@@ -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

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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;
};

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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];