mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-08-27 10:25:24 +02:00
Update to v106r55 release.
byuu says: Everything *should* be working again, but of course that won't actually be the case. Here's where things stand: - bsnes, higan, icarus, and genius compile and run fine on FreeBSD with GTK - ruby video and audio drivers are untested on Windows, macOS, and Linux - hiro is untested on macOS - bsnes' status bar is not showing up properly with hiro/qt - bsnes and higan's about screen is not showing up properly with hiro/qt (1x1 window size) - bsnes on Windows crashes often when saving states, and I'm not sure why ... it happens inside Encode::RLE - bsnes on Windows crashes with ruby.input.windows (unsure why) - bsnes on Windows fails to show the verified emblem on the status bar properly - hiro on Windows flickers when changing tabs To build the Windows bsnes and higan ports, use ruby="video.gdi audio.directsound" Compilation error logs for Linux will help me fix the inevitable list of typos there. I can fix the typos on other platforms, I just haven't gotten to it yet.
This commit is contained in:
@@ -11,10 +11,15 @@ struct VideoCGL;
|
||||
-(void) reshape;
|
||||
@end
|
||||
|
||||
struct VideoCGL : Video, OpenGL {
|
||||
VideoCGL() { initialize(); }
|
||||
struct VideoCGL : VideoDriver, OpenGL {
|
||||
VideoCGL& self = *this;
|
||||
VideoCGL(Video& super) : VideoDriver(super) {}
|
||||
~VideoCGL() { terminate(); }
|
||||
|
||||
auto create() -> bool override {
|
||||
return initialize();
|
||||
}
|
||||
|
||||
auto driver() -> string override { return "OpenGL"; }
|
||||
auto ready() -> bool override { return _ready; }
|
||||
|
||||
@@ -25,14 +30,10 @@ struct VideoCGL : Video, OpenGL {
|
||||
auto hasShader() -> bool override { return true; }
|
||||
|
||||
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 override {
|
||||
if(blocking == Video::blocking()) return true;
|
||||
if(!Video::setBlocking(blocking)) return false;
|
||||
if(!view) return true;
|
||||
@autoreleasepool {
|
||||
[[view openGLContext] makeCurrentContext];
|
||||
@@ -43,28 +44,21 @@ struct VideoCGL : Video, OpenGL {
|
||||
}
|
||||
|
||||
auto setFlush(bool flush) -> bool override {
|
||||
if(flush == Video::flush()) return true;
|
||||
if(!Video::setFlush(flush)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
auto setSmooth(bool) -> bool override {
|
||||
if(!self.shader) OpenGL::filter = self.smooth ? GL_LINEAR : GL_NEAREST;
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
auto setShader(string) -> bool override {
|
||||
OpenGL::setShader(self.shader);
|
||||
if(!self.shader) OpenGL::filter = self.smooth ? GL_LINEAR : GL_NEAREST;
|
||||
return true;
|
||||
}
|
||||
|
||||
auto clear() -> void override {
|
||||
if(!ready()) return;
|
||||
@autoreleasepool {
|
||||
[view lockFocus];
|
||||
OpenGL::clear();
|
||||
@@ -74,17 +68,14 @@ struct VideoCGL : Video, OpenGL {
|
||||
}
|
||||
|
||||
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 release() -> void override {
|
||||
if(!ready()) return;
|
||||
}
|
||||
|
||||
auto output() -> void override {
|
||||
if(!ready()) return;
|
||||
@autoreleasepool {
|
||||
if([view lockFocusIfCanDraw]) {
|
||||
auto area = [view convertRectToBacking:[view bounds]];
|
||||
@@ -92,7 +83,7 @@ struct VideoCGL : Video, OpenGL {
|
||||
OpenGL::outputHeight = area.size.height;
|
||||
OpenGL::output();
|
||||
[[view openGLContext] flushBuffer];
|
||||
if(flush()) glFinish();
|
||||
if(self.flush) glFinish();
|
||||
[view unlockFocus];
|
||||
}
|
||||
}
|
||||
@@ -101,7 +92,7 @@ struct VideoCGL : Video, OpenGL {
|
||||
private:
|
||||
auto initialize() -> bool {
|
||||
terminate();
|
||||
if(!_context) return false;
|
||||
if(!self.context) return false;
|
||||
|
||||
@autoreleasepool {
|
||||
NSOpenGLPixelFormatAttribute attributeList[] = {
|
||||
@@ -112,7 +103,7 @@ private:
|
||||
0
|
||||
};
|
||||
|
||||
auto context = (NSView*)_context;
|
||||
auto context = (NSView*)self.context;
|
||||
auto size = [context frame].size;
|
||||
auto format = [[[NSOpenGLPixelFormat alloc] initWithAttributes:attributeList] autorelease];
|
||||
auto openGLContext = [[[NSOpenGLContext alloc] initWithFormat:format shareContext:nil] autorelease];
|
||||
@@ -129,7 +120,7 @@ private:
|
||||
|
||||
OpenGL::initialize();
|
||||
|
||||
int blocking = _blocking;
|
||||
int blocking = self.blocking;
|
||||
[[view openGLContext] setValues:&blocking forParameter:NSOpenGLCPSwapInterval];
|
||||
|
||||
[view unlockFocus];
|
||||
|
@@ -7,10 +7,15 @@ static LRESULT CALLBACK VideoDirect3D_WindowProcedure(HWND hwnd, UINT msg, WPARA
|
||||
return DefWindowProc(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
|
||||
struct VideoDirect3D : Video {
|
||||
VideoDirect3D() { initialize(); }
|
||||
struct VideoDirect3D : VideoDriver {
|
||||
VideoDirect3D& self = *this;
|
||||
VideoDirect3D(Video& super) : VideoDriver(super) {}
|
||||
~VideoDirect3D() { terminate(); }
|
||||
|
||||
auto create() -> bool override {
|
||||
return initialize();
|
||||
}
|
||||
|
||||
auto driver() -> string override { return "Direct3D"; }
|
||||
auto ready() -> bool override { return _ready; }
|
||||
|
||||
@@ -19,30 +24,10 @@ struct VideoDirect3D : Video {
|
||||
auto hasBlocking() -> bool override { return true; }
|
||||
auto hasSmooth() -> bool override { return true; }
|
||||
|
||||
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 override {
|
||||
if(context == Video::context()) return true;
|
||||
if(!Video::setContext(context)) return false;
|
||||
return initialize();
|
||||
}
|
||||
|
||||
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 override {
|
||||
if(smooth == Video::smooth()) return true;
|
||||
if(!Video::setSmooth(smooth)) return false;
|
||||
if(ready()) updateFilter();
|
||||
return true;
|
||||
}
|
||||
auto setExclusive(bool exclusive) -> bool override { return initialize(); }
|
||||
auto setContext(uintptr context) -> bool override { return initialize(); }
|
||||
auto setBlocking(bool blocking) -> bool override { return true; }
|
||||
auto setSmooth(bool smooth) -> bool override { return updateFilter(); }
|
||||
|
||||
auto clear() -> void override {
|
||||
if(!ready()) return;
|
||||
@@ -66,7 +51,6 @@ struct VideoDirect3D : Video {
|
||||
}
|
||||
|
||||
auto acquire(uint32_t*& data, uint& pitch, uint width, uint height) -> bool override {
|
||||
if(!ready()) return false;
|
||||
if(_lost && !recover()) return false;
|
||||
|
||||
//if output size changed, driver must be re-initialized.
|
||||
@@ -90,14 +74,12 @@ struct VideoDirect3D : Video {
|
||||
}
|
||||
|
||||
auto release() -> void override {
|
||||
if(!ready()) return;
|
||||
_surface->UnlockRect();
|
||||
_surface->Release();
|
||||
_surface = nullptr;
|
||||
}
|
||||
|
||||
auto output() -> void override {
|
||||
if(!ready()) return;
|
||||
if(_lost && !recover()) return;
|
||||
|
||||
_device->BeginScene();
|
||||
@@ -183,13 +165,14 @@ private:
|
||||
(D3DPOOL)_texturePool, &_texture, nullptr);
|
||||
}
|
||||
|
||||
auto updateFilter() -> void {
|
||||
if(!_device) return;
|
||||
if(_lost && !recover()) return;
|
||||
auto updateFilter() -> bool {
|
||||
if(!_device) return false;
|
||||
if(_lost && !recover()) return false;
|
||||
|
||||
auto filter = !_smooth ? D3DTEXF_POINT : D3DTEXF_LINEAR;
|
||||
_device->SetSamplerState(0, D3DSAMP_MINFILTER, filter);
|
||||
_device->SetSamplerState(0, D3DSAMP_MAGFILTER, filter);
|
||||
return true;
|
||||
}
|
||||
|
||||
//(x,y) screen coordinates, in pixels
|
||||
|
@@ -1,10 +1,15 @@
|
||||
#include <ddraw.h>
|
||||
#undef interface
|
||||
|
||||
struct VideoDirectDraw : Video {
|
||||
VideoDirectDraw() { initialize(); }
|
||||
struct VideoDirectDraw : VideoDriver {
|
||||
VideoDirectDraw& self = *this;
|
||||
VideoDirectDraw(Video& super) : VideoDriver(super) {}
|
||||
~VideoDirectDraw() { terminate(); }
|
||||
|
||||
auto create() -> bool override {
|
||||
return initialize();
|
||||
}
|
||||
|
||||
auto driver() -> string override { return "DirectDraw"; }
|
||||
auto ready() -> bool override { return _ready; }
|
||||
|
||||
@@ -12,19 +17,14 @@ struct VideoDirectDraw : Video {
|
||||
auto hasBlocking() -> bool override { return true; }
|
||||
|
||||
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 override {
|
||||
if(blocking == Video::blocking()) return true;
|
||||
if(!Video::setBlocking(blocking)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
auto clear() -> void override {
|
||||
if(!ready()) return;
|
||||
DDBLTFX fx = {};
|
||||
fx.dwSize = sizeof(DDBLTFX);
|
||||
fx.dwFillColor = 0x00000000;
|
||||
@@ -33,7 +33,6 @@ struct VideoDirectDraw : Video {
|
||||
}
|
||||
|
||||
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 = {};
|
||||
description.dwSize = sizeof(DDSURFACEDESC2);
|
||||
@@ -46,13 +45,11 @@ struct VideoDirectDraw : Video {
|
||||
}
|
||||
|
||||
auto release() -> void override {
|
||||
if(!ready()) return;
|
||||
_raster->Unlock(0);
|
||||
}
|
||||
|
||||
auto output() -> void override {
|
||||
if(!ready()) return;
|
||||
if(_blocking) while(true) {
|
||||
if(self.blocking) while(true) {
|
||||
BOOL vblank;
|
||||
_interface->GetVerticalBlankStatus(&vblank);
|
||||
if(vblank) break;
|
||||
@@ -62,10 +59,10 @@ struct VideoDirectDraw : Video {
|
||||
SetRect(&source, 0, 0, _width, _height);
|
||||
|
||||
POINT point = {0, 0};
|
||||
ClientToScreen((HWND)_context, &point);
|
||||
ClientToScreen((HWND)self.context, &point);
|
||||
|
||||
RECT target;
|
||||
GetClientRect((HWND)_context, &target);
|
||||
GetClientRect((HWND)self.context, &target);
|
||||
OffsetRect(&target, point.x, point.y);
|
||||
|
||||
if(_screen->Blt(&target, _raster, &source, DDBLT_WAIT, 0) == DDERR_SURFACELOST) {
|
||||
@@ -77,14 +74,14 @@ struct VideoDirectDraw : Video {
|
||||
private:
|
||||
auto initialize() -> bool {
|
||||
terminate();
|
||||
if(!_context) return false;
|
||||
if(!self.context) return false;
|
||||
|
||||
LPDIRECTDRAW interface = nullptr;
|
||||
DirectDrawCreate(0, &interface, 0);
|
||||
interface->QueryInterface(IID_IDirectDraw7, (void**)&_interface);
|
||||
interface->Release();
|
||||
|
||||
_interface->SetCooperativeLevel((HWND)_context, DDSCL_NORMAL);
|
||||
_interface->SetCooperativeLevel((HWND)self.context, DDSCL_NORMAL);
|
||||
|
||||
DDSURFACEDESC2 description = {};
|
||||
description.dwSize = sizeof(DDSURFACEDESC2);
|
||||
@@ -93,7 +90,7 @@ private:
|
||||
_interface->CreateSurface(&description, &_screen, 0);
|
||||
|
||||
_interface->CreateClipper(0, &_clipper, 0);
|
||||
_clipper->SetHWnd(0, (HWND)_context);
|
||||
_clipper->SetHWnd(0, (HWND)self.context);
|
||||
_screen->SetClipper(_clipper);
|
||||
|
||||
_raster = nullptr;
|
||||
|
@@ -1,25 +1,20 @@
|
||||
struct VideoGDI : Video {
|
||||
VideoGDI() { initialize(); }
|
||||
struct VideoGDI : VideoDriver {
|
||||
VideoGDI& self = *this;
|
||||
VideoGDI(Video& super) : VideoDriver(super) {}
|
||||
~VideoGDI() { terminate(); }
|
||||
|
||||
auto create() -> bool override {
|
||||
return initialize();
|
||||
}
|
||||
|
||||
auto driver() -> string override { return "GDI"; }
|
||||
auto ready() -> bool override { return _ready; }
|
||||
|
||||
auto hasContext() -> bool override { return true; }
|
||||
|
||||
auto setContext(uintptr context) -> bool override {
|
||||
if(context == Video::context()) return true;
|
||||
if(!Video::setContext(context)) return false;
|
||||
return initialize();
|
||||
}
|
||||
|
||||
auto clear() -> void override {
|
||||
if(!ready()) return;
|
||||
}
|
||||
auto setContext(uintptr context) -> bool override { return initialize(); }
|
||||
|
||||
auto acquire(uint32_t*& data, uint& pitch, uint width, uint height) -> bool override {
|
||||
if(!ready()) return false;
|
||||
|
||||
if(!_buffer || _width != width || _height != height) {
|
||||
if(_buffer) delete[] _buffer;
|
||||
if(_bitmap) DeleteObject(_bitmap);
|
||||
@@ -29,11 +24,11 @@ struct VideoGDI : Video {
|
||||
_width = width;
|
||||
_height = height;
|
||||
|
||||
HDC hdc = GetDC((HWND)_context);
|
||||
HDC hdc = GetDC((HWND)self.context);
|
||||
_dc = CreateCompatibleDC(hdc);
|
||||
_bitmap = CreateCompatibleBitmap(hdc, width, height);
|
||||
SelectObject(_dc, _bitmap);
|
||||
ReleaseDC((HWND)_context, hdc);
|
||||
ReleaseDC((HWND)self.context, hdc);
|
||||
|
||||
memory::fill(&_info, sizeof(BITMAPINFO));
|
||||
_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
@@ -50,25 +45,22 @@ struct VideoGDI : Video {
|
||||
}
|
||||
|
||||
auto release() -> void override {
|
||||
if(!ready()) return;
|
||||
}
|
||||
|
||||
auto output() -> void override {
|
||||
if(!ready()) return;
|
||||
|
||||
RECT rc;
|
||||
GetClientRect((HWND)_context, &rc);
|
||||
GetClientRect((HWND)self.context, &rc);
|
||||
|
||||
SetDIBits(_dc, _bitmap, 0, _height, (void*)_buffer, &_info, DIB_RGB_COLORS);
|
||||
HDC hdc = GetDC((HWND)_context);
|
||||
HDC hdc = GetDC((HWND)self.context);
|
||||
StretchBlt(hdc, rc.left, rc.top, rc.right, rc.bottom, _dc, 0, 0, _width, _height, SRCCOPY);
|
||||
ReleaseDC((HWND)_context, hdc);
|
||||
ReleaseDC((HWND)self.context, hdc);
|
||||
}
|
||||
|
||||
private:
|
||||
auto initialize() -> bool {
|
||||
terminate();
|
||||
if(!_context) return false;
|
||||
if(!self.context) return false;
|
||||
|
||||
_width = 0;
|
||||
_height = 0;
|
||||
|
@@ -7,47 +7,43 @@ auto VideoGLX_X11ErrorHandler(Display*, XErrorEvent*) -> int {
|
||||
return 0; //suppress errors
|
||||
}
|
||||
|
||||
struct VideoGLX : Video, OpenGL {
|
||||
VideoGLX() { initialize(); }
|
||||
struct VideoGLX : VideoDriver, OpenGL {
|
||||
VideoGLX& self = *this;
|
||||
VideoGLX(Video& super) : VideoDriver(super) {}
|
||||
~VideoGLX() { terminate(); }
|
||||
|
||||
auto create() -> bool override {
|
||||
super.setFormat("RGB24");
|
||||
return initialize();
|
||||
}
|
||||
|
||||
auto driver() -> string override { return "OpenGL"; }
|
||||
auto ready() -> bool override { return _ready; }
|
||||
|
||||
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 hasShader() -> bool override { return true; }
|
||||
|
||||
auto availableFormats() -> vector<string> override {
|
||||
return {"RGB24", "RGB30"};
|
||||
auto hasFormats() -> vector<string> override {
|
||||
return {"RGB24"}; //"RGB30"
|
||||
}
|
||||
|
||||
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 override {
|
||||
if(blocking == Video::blocking()) return true;
|
||||
if(!Video::setBlocking(blocking)) return false;
|
||||
if(glXSwapInterval) glXSwapInterval(blocking);
|
||||
return true;
|
||||
}
|
||||
|
||||
auto setFlush(bool flush) -> bool override {
|
||||
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") {
|
||||
OpenGL::inputFormat = GL_RGBA8;
|
||||
return true;
|
||||
@@ -61,46 +57,37 @@ struct VideoGLX : Video, OpenGL {
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
auto setSmooth(bool) -> bool override {
|
||||
if(!self.shader) OpenGL::filter = self.smooth ? GL_LINEAR : GL_NEAREST;
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
auto setShader(string) -> bool override {
|
||||
OpenGL::setShader(self.shader);
|
||||
if(!self.shader) OpenGL::filter = self.smooth ? GL_LINEAR : GL_NEAREST;
|
||||
return true;
|
||||
}
|
||||
|
||||
auto clear() -> void override {
|
||||
if(!ready()) return;
|
||||
OpenGL::clear();
|
||||
if(_doubleBuffer) glXSwapBuffers(_display, _glXWindow);
|
||||
}
|
||||
|
||||
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 release() -> void override {
|
||||
if(!ready()) return;
|
||||
}
|
||||
|
||||
auto output() -> void override {
|
||||
if(!ready()) return;
|
||||
|
||||
//we must ensure that the child window is the same size as the parent window.
|
||||
//unfortunately, we cannot hook the parent window resize event notification,
|
||||
//as we did not create the parent window, nor have any knowledge of the toolkit used.
|
||||
//therefore, inelegant as it may be, we query each window size and resize as needed.
|
||||
XWindowAttributes parent, child;
|
||||
XGetWindowAttributes(_display, (Window)_context, &parent);
|
||||
XGetWindowAttributes(_display, (Window)self.context, &parent);
|
||||
XGetWindowAttributes(_display, (Window)_window, &child);
|
||||
if(child.width != parent.width || child.height != parent.height) {
|
||||
XResizeWindow(_display, _window, parent.width, parent.height);
|
||||
@@ -110,7 +97,7 @@ struct VideoGLX : Video, OpenGL {
|
||||
OpenGL::outputHeight = parent.height;
|
||||
OpenGL::output();
|
||||
if(_doubleBuffer) glXSwapBuffers(_display, _glXWindow);
|
||||
if(flush()) glFinish();
|
||||
if(self.flush) glFinish();
|
||||
}
|
||||
|
||||
auto poll() -> void override {
|
||||
@@ -120,7 +107,7 @@ struct VideoGLX : Video, OpenGL {
|
||||
if(event.type == Expose) {
|
||||
XWindowAttributes attributes;
|
||||
XGetWindowAttributes(_display, _window, &attributes);
|
||||
doUpdate(attributes.width, attributes.height);
|
||||
super.doUpdate(attributes.width, attributes.height);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -128,7 +115,7 @@ struct VideoGLX : Video, OpenGL {
|
||||
private:
|
||||
auto initialize() -> bool {
|
||||
terminate();
|
||||
if(!_context) return false;
|
||||
if(!self.context) return false;
|
||||
|
||||
_display = XOpenDisplay(nullptr);
|
||||
_screen = DefaultScreen(_display);
|
||||
@@ -138,11 +125,11 @@ private:
|
||||
if(_versionMajor < 1 || (_versionMajor == 1 && _versionMinor < 2)) return false;
|
||||
|
||||
XWindowAttributes windowAttributes;
|
||||
XGetWindowAttributes(_display, (Window)_context, &windowAttributes);
|
||||
XGetWindowAttributes(_display, (Window)self.context, &windowAttributes);
|
||||
|
||||
int redDepth = Video::format() == "RGB30" ? 10 : 8;
|
||||
int greenDepth = Video::format() == "RGB30" ? 10 : 8;
|
||||
int blueDepth = Video::format() == "RGB30" ? 10 : 8;
|
||||
int redDepth = VideoDriver::format == "RGB30" ? 10 : 8;
|
||||
int greenDepth = VideoDriver::format == "RGB30" ? 10 : 8;
|
||||
int blueDepth = VideoDriver::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
|
||||
@@ -162,7 +149,7 @@ private:
|
||||
|
||||
XVisualInfo* vi = glXGetVisualFromFBConfig(_display, fbConfig[0]);
|
||||
|
||||
//(Window)_context has already been realized, most likely with DefaultVisual.
|
||||
//(Window)self.context has already been realized, most likely with DefaultVisual.
|
||||
//GLX requires that the GL output window has the same Visual as the GLX context.
|
||||
//it is not possible to change the Visual of an already realized (created) window.
|
||||
//therefore a new child window, using the same GLX Visual, must be created and binded to it.
|
||||
@@ -170,7 +157,7 @@ private:
|
||||
XSetWindowAttributes attributes = {};
|
||||
attributes.colormap = _colormap;
|
||||
attributes.border_pixel = 0;
|
||||
_window = XCreateWindow(_display, /* parent = */ (Window)_context,
|
||||
_window = XCreateWindow(_display, /* parent = */ (Window)self.context,
|
||||
/* x = */ 0, /* y = */ 0, windowAttributes.width, windowAttributes.height,
|
||||
/* border_width = */ 0, vi->depth, InputOutput, vi->visual,
|
||||
CWColormap | CWBorderPixel, &attributes);
|
||||
@@ -219,7 +206,7 @@ private:
|
||||
return false;
|
||||
}
|
||||
|
||||
if(glXSwapInterval) glXSwapInterval(_blocking);
|
||||
if(glXSwapInterval) glXSwapInterval(self.blocking);
|
||||
|
||||
//read attributes of frame buffer for later use, as requested attributes from above are not always granted
|
||||
int value = 0;
|
||||
|
@@ -22,6 +22,7 @@
|
||||
#endif
|
||||
|
||||
struct VideoGLX2 : VideoDriver {
|
||||
VideoGLX2& self = *this;
|
||||
VideoGLX2(Video& super) : VideoDriver(super) {}
|
||||
~VideoGLX2() { terminate(); }
|
||||
|
||||
@@ -260,8 +261,6 @@ private:
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _glWidth, _glHeight, 0, GL_BGRA, _glFormat, _glBuffer);
|
||||
}
|
||||
|
||||
VideoGLX2& self = *this;
|
||||
|
||||
bool _ready = false;
|
||||
|
||||
Display* _display = nullptr;
|
||||
|
@@ -3,10 +3,15 @@
|
||||
#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
|
||||
#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
|
||||
|
||||
struct VideoWGL : Video, OpenGL {
|
||||
VideoWGL() { initialize(); }
|
||||
struct VideoWGL : VideoDriver, OpenGL {
|
||||
VideoWGL& self = *this;
|
||||
VideoWGL(Video& super) : VideoDriver(super) {}
|
||||
~VideoWGL() { terminate(); }
|
||||
|
||||
auto create() -> bool override {
|
||||
return initialize();
|
||||
}
|
||||
|
||||
auto driver() -> string override { return "OpenGL"; }
|
||||
auto ready() -> bool override { return _ready; }
|
||||
|
||||
@@ -17,70 +22,56 @@ struct VideoWGL : Video, OpenGL {
|
||||
auto hasShader() -> bool override { return true; }
|
||||
|
||||
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 override {
|
||||
if(blocking == Video::blocking()) return true;
|
||||
if(!Video::setBlocking(blocking)) return false;
|
||||
if(wglSwapInterval) wglSwapInterval(blocking);
|
||||
return true;
|
||||
}
|
||||
|
||||
auto setFlush(bool flush) -> bool override {
|
||||
if(flush == Video::flush()) return true;
|
||||
if(!Video::setFlush(flush)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
auto setSmooth(bool) -> bool override {
|
||||
if(!self.shader) OpenGL::filter = self.smooth ? GL_LINEAR : GL_NEAREST;
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
auto setShader(string) -> bool override {
|
||||
OpenGL::setShader(self.shader);
|
||||
if(!self.shader) OpenGL::filter = self.smooth ? GL_LINEAR : GL_NEAREST;
|
||||
return true;
|
||||
}
|
||||
|
||||
auto clear() -> void override {
|
||||
if(!ready()) return;
|
||||
OpenGL::clear();
|
||||
SwapBuffers(_display);
|
||||
}
|
||||
|
||||
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 release() -> void override {
|
||||
if(!ready()) return;
|
||||
}
|
||||
|
||||
auto output() -> void override {
|
||||
if(!ready()) return;
|
||||
RECT rectangle;
|
||||
GetClientRect((HWND)_context, &rectangle);
|
||||
GetClientRect((HWND)self.context, &rectangle);
|
||||
OpenGL::outputWidth = rectangle.right - rectangle.left;
|
||||
OpenGL::outputHeight = rectangle.bottom - rectangle.top;
|
||||
OpenGL::output();
|
||||
SwapBuffers(_display);
|
||||
if(flush()) glFinish();
|
||||
if(self.flush) glFinish();
|
||||
}
|
||||
|
||||
private:
|
||||
auto initialize() -> bool {
|
||||
terminate();
|
||||
if(!_context) return false;
|
||||
if(!self.context) return false;
|
||||
|
||||
PIXELFORMATDESCRIPTOR descriptor = {};
|
||||
descriptor.nSize = sizeof(PIXELFORMATDESCRIPTOR);
|
||||
@@ -88,7 +79,7 @@ private:
|
||||
descriptor.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
|
||||
descriptor.iPixelType = PFD_TYPE_RGBA;
|
||||
|
||||
_display = GetDC((HWND)_context);
|
||||
_display = GetDC((HWND)self.context);
|
||||
GLuint pixelFormat = ChoosePixelFormat(_display, &descriptor);
|
||||
SetPixelFormat(_display, pixelFormat, &descriptor);
|
||||
|
||||
@@ -112,7 +103,7 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
if(wglSwapInterval) wglSwapInterval(_blocking);
|
||||
if(wglSwapInterval) wglSwapInterval(self.blocking);
|
||||
return _ready = OpenGL::initialize();
|
||||
}
|
||||
|
||||
|
@@ -9,10 +9,11 @@
|
||||
#include <X11/extensions/XShm.h>
|
||||
|
||||
struct VideoXShm : VideoDriver {
|
||||
VideoXShm& self = *this;
|
||||
VideoXShm(Video& super) : VideoDriver(super) {}
|
||||
~VideoXShm() { terminate(); }
|
||||
|
||||
auto create() -> bool {
|
||||
auto create() -> bool override {
|
||||
return initialize();
|
||||
}
|
||||
|
||||
@@ -184,8 +185,6 @@ private:
|
||||
return cr << 16 | cg << 8 | cb << 0;
|
||||
}
|
||||
|
||||
VideoXShm& self = *this;
|
||||
|
||||
bool _ready = false;
|
||||
|
||||
uint32_t* _inputBuffer = nullptr;
|
||||
|
@@ -6,36 +6,35 @@
|
||||
|
||||
extern "C" auto XvShmCreateImage(Display*, XvPortID, int, char*, int, int, XShmSegmentInfo*) -> XvImage*;
|
||||
|
||||
struct VideoXVideo : Video {
|
||||
VideoXVideo() { initialize(); }
|
||||
struct VideoXVideo : VideoDriver {
|
||||
VideoXVideo& self = *this;
|
||||
VideoXVideo(Video& super) : VideoDriver(super) {}
|
||||
~VideoXVideo() { terminate(); }
|
||||
|
||||
auto create() -> bool override {
|
||||
return initialize();
|
||||
}
|
||||
|
||||
auto driver() -> string override { return "XVideo"; }
|
||||
auto ready() -> bool override { return _ready; }
|
||||
|
||||
auto hasContext() -> bool override { return true; }
|
||||
auto hasBlocking() -> bool override { return true; }
|
||||
auto hasFormat() -> bool override { return true; }
|
||||
|
||||
auto availableFormats() -> vector<string> override {
|
||||
auto hasFormats() -> vector<string> override {
|
||||
return _formatNames;
|
||||
}
|
||||
|
||||
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 override {
|
||||
if(blocking == Video::blocking()) return true;
|
||||
if(!Video::setBlocking(blocking)) return false;
|
||||
|
||||
bool result = false;
|
||||
Display* display = XOpenDisplay(nullptr);
|
||||
Atom atom = XInternAtom(display, "XV_SYNC_TO_VBLANK", true);
|
||||
if(atom != None && _port >= 0) {
|
||||
XvSetPortAttribute(display, _port, atom, _blocking);
|
||||
XvSetPortAttribute(display, _port, atom, self.blocking);
|
||||
result = true;
|
||||
}
|
||||
XCloseDisplay(display);
|
||||
@@ -43,13 +42,10 @@ struct VideoXVideo : Video {
|
||||
}
|
||||
|
||||
auto setFormat(string format) -> bool override {
|
||||
if(format == Video::format()) return true;
|
||||
if(!Video::setFormat(format)) return false;
|
||||
return initialize();
|
||||
}
|
||||
|
||||
auto clear() -> void override {
|
||||
if(!ready()) return;
|
||||
memory::fill<uint32_t>(_buffer, _bufferWidth * _bufferHeight);
|
||||
//clear twice in case video is double buffered ...
|
||||
output();
|
||||
@@ -57,19 +53,15 @@ struct VideoXVideo : Video {
|
||||
}
|
||||
|
||||
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 release() -> void override {
|
||||
if(!ready()) return;
|
||||
}
|
||||
|
||||
auto output() -> void override {
|
||||
if(!ready()) return;
|
||||
|
||||
XWindowAttributes target;
|
||||
XGetWindowAttributes(_display, _window, &target);
|
||||
|
||||
@@ -78,7 +70,7 @@ struct VideoXVideo : Video {
|
||||
//as we did not create the parent window, nor have any knowledge of the toolkit used.
|
||||
//therefore, query each window size and resize as needed.
|
||||
XWindowAttributes parent;
|
||||
XGetWindowAttributes(_display, (Window)_context, &parent);
|
||||
XGetWindowAttributes(_display, (Window)self.context, &parent);
|
||||
if(target.width != parent.width || target.height != parent.height) {
|
||||
XResizeWindow(_display, _window, parent.width, parent.height);
|
||||
}
|
||||
@@ -109,7 +101,7 @@ struct VideoXVideo : Video {
|
||||
if(event.type == Expose) {
|
||||
XWindowAttributes attributes;
|
||||
XGetWindowAttributes(_display, _window, &attributes);
|
||||
doUpdate(attributes.width, attributes.height);
|
||||
super.doUpdate(attributes.width, attributes.height);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -117,7 +109,7 @@ struct VideoXVideo : Video {
|
||||
private:
|
||||
auto initialize() -> bool {
|
||||
terminate();
|
||||
if(!_context) return false;
|
||||
if(!self.context) return false;
|
||||
|
||||
_display = XOpenDisplay(nullptr);
|
||||
|
||||
@@ -154,7 +146,7 @@ private:
|
||||
//this is so that even if parent window visual depth doesn't match Xv visual
|
||||
//(common with composited windows), Xv can still render to child window.
|
||||
XWindowAttributes windowAttributes;
|
||||
XGetWindowAttributes(_display, (Window)_context, &windowAttributes);
|
||||
XGetWindowAttributes(_display, (Window)self.context, &windowAttributes);
|
||||
|
||||
XVisualInfo visualTemplate;
|
||||
visualTemplate.visualid = visualID;
|
||||
@@ -169,11 +161,11 @@ private:
|
||||
return false;
|
||||
}
|
||||
|
||||
_colormap = XCreateColormap(_display, (Window)_context, visualInfo->visual, AllocNone);
|
||||
_colormap = XCreateColormap(_display, (Window)self.context, visualInfo->visual, AllocNone);
|
||||
XSetWindowAttributes attributes = {};
|
||||
attributes.colormap = _colormap;
|
||||
attributes.border_pixel = 0;
|
||||
_window = XCreateWindow(_display, /* parent = */ (Window)_context,
|
||||
_window = XCreateWindow(_display, /* parent = */ (Window)self.context,
|
||||
/* x = */ 0, /* y = */ 0, windowAttributes.width, windowAttributes.height,
|
||||
/* border_width = */ 0, depth, InputOutput, visualInfo->visual,
|
||||
CWColormap | CWBorderPixel | CWEventMask, &attributes);
|
||||
@@ -200,13 +192,13 @@ private:
|
||||
print("XVideo: unable to find a supported image format.\n");
|
||||
return false;
|
||||
}
|
||||
if(auto match = _formatNames.find(Video::format())) {
|
||||
if(auto match = _formatNames.find(self.format)) {
|
||||
_formatID = _formatIDs[match()];
|
||||
_formatName = _formatNames[match()];
|
||||
} else {
|
||||
_formatID = _formatIDs[0];
|
||||
_formatName = _formatNames[0];
|
||||
Video::setFormat(_formatName);
|
||||
self.format = _formatName;
|
||||
}
|
||||
|
||||
_ready = true;
|
||||
|
Reference in New Issue
Block a user