mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-08-31 11:21:49 +02:00
Update to v093r12a release.
byuu says: Not an official WIP (a WIP WIP? A meta-WIP?), just throwing in the new fullscreen code, and I noticed that OpenGL colors in 30-bit mode are all fucked up now for some strange reason. So I'm just using this snapshot to debug the issue.
This commit is contained in:
@@ -66,8 +66,8 @@ struct pVideoGLX : OpenGL {
|
||||
if(depth > DefaultDepth(display, screen)) return false;
|
||||
|
||||
switch(depth) {
|
||||
case 24: format = GL_RGBA8; inputFormat = GL_UNSIGNED_INT_8_8_8_8_REV; break;
|
||||
case 30: format = GL_RGB10_A2; inputFormat = GL_UNSIGNED_INT_2_10_10_10_REV; break;
|
||||
case 24: format = GL_RGBA8; break;
|
||||
case 30: format = GL_RGB10_A2; break;
|
||||
default: return false;
|
||||
}
|
||||
|
||||
|
@@ -2,9 +2,6 @@ void OpenGL::shader(const char* pathname) {
|
||||
for(auto& program : programs) program.release();
|
||||
programs.reset();
|
||||
|
||||
for(auto& frame : frames) glDeleteTextures(1, &frame.texture);
|
||||
frames.reset();
|
||||
|
||||
settings.reset();
|
||||
|
||||
format = GL_RGBA8;
|
||||
@@ -13,6 +10,7 @@ void OpenGL::shader(const char* pathname) {
|
||||
absoluteWidth = 0, absoluteHeight = 0;
|
||||
relativeWidth = 0, relativeHeight = 0;
|
||||
|
||||
unsigned historySize = 0;
|
||||
if(pathname) {
|
||||
auto document = Markup::Document(file::read({pathname, "manifest.bml"}));
|
||||
|
||||
@@ -20,27 +18,51 @@ void OpenGL::shader(const char* pathname) {
|
||||
settings.insert({node.name, node.text()});
|
||||
}
|
||||
|
||||
for(auto& node : document["input"]) {
|
||||
if(node.name == "history") historySize = node.decimal();
|
||||
if(node.name == "format") format = glrFormat(node.text());
|
||||
if(node.name == "filter") filter = glrFilter(node.text());
|
||||
if(node.name == "wrap") wrap = glrWrap(node.text());
|
||||
}
|
||||
|
||||
for(auto& node : document["output"]) {
|
||||
string text = node.text();
|
||||
if(node.name == "width") {
|
||||
if(text.endsWith("%")) relativeWidth = real(text.rtrim<1>("%")) / 100.0;
|
||||
else absoluteWidth = decimal(text);
|
||||
}
|
||||
if(node.name == "height") {
|
||||
if(text.endsWith("%")) relativeHeight = real(text.rtrim<1>("%")) / 100.0;
|
||||
else absoluteHeight = decimal(text);
|
||||
}
|
||||
}
|
||||
|
||||
for(auto& node : document.find("program")) {
|
||||
unsigned n = programs.size();
|
||||
programs(n).bind(this, node, pathname);
|
||||
}
|
||||
|
||||
bind(document, pathname);
|
||||
OpenGLProgram::bind(this, document["output"], pathname);
|
||||
} else {
|
||||
//no shader; assign default values
|
||||
history.length = 0;
|
||||
history.format = GL_RGBA8;
|
||||
history.filter = GL_LINEAR;
|
||||
history.wrap = GL_CLAMP_TO_BORDER;
|
||||
}
|
||||
|
||||
//changing shaders may change input format, which requires the input texture to be recreated
|
||||
if(texture) { glDeleteTextures(1, &texture); texture = 0; }
|
||||
glGenTextures(1, &texture);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, getFormat(), getType(), buffer);
|
||||
allocateHistory(historySize);
|
||||
}
|
||||
|
||||
void OpenGL::bind(const Markup::Node& node, const string& pathname) {
|
||||
history.length = node["history/frames"].decimal();
|
||||
if(node["history/format"].exists()) history.format = glrFormat(node["history/format"].text());
|
||||
if(node["history/filter"].exists()) history.filter = glrFilter(node["history/filter"].text());
|
||||
if(node["history/wrap"].exists()) history.wrap = glrWrap(node["history/wrap"].text());
|
||||
void OpenGL::allocateHistory(unsigned size) {
|
||||
for(auto& frame : history) glDeleteTextures(1, &frame.texture);
|
||||
history.reset();
|
||||
while(size--) {
|
||||
OpenGLTexture frame;
|
||||
frame.filter = filter;
|
||||
frame.wrap = wrap;
|
||||
glGenTextures(1, &frame.texture);
|
||||
glBindTexture(GL_TEXTURE_2D, frame.texture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, format, frame.width = width, frame.height = height, 0, getFormat(), getType(), buffer);
|
||||
history.append(frame);
|
||||
}
|
||||
}
|
||||
|
||||
bool OpenGL::lock(uint32_t*& data, unsigned& pitch) {
|
||||
@@ -64,20 +86,9 @@ void OpenGL::clear() {
|
||||
void OpenGL::refresh() {
|
||||
clear();
|
||||
|
||||
//frame[] must always contain max# of previous frames: allocate them now, so first few frames can use them
|
||||
while(frames.size() < history.length) {
|
||||
OpenGLTexture frame;
|
||||
glGenTextures(1, &frame.texture);
|
||||
glBindTexture(GL_TEXTURE_2D, frame.texture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, frame.format = history.format, frame.width = width, frame.height = height, 0, GL_BGRA, inputFormat, buffer);
|
||||
frame.filter = history.filter;
|
||||
frame.wrap = history.wrap;
|
||||
frames.append(frame);
|
||||
}
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_BGRA, inputFormat, buffer);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, getFormat(), getType(), buffer);
|
||||
|
||||
struct Source {
|
||||
GLuint texture;
|
||||
@@ -85,31 +96,29 @@ void OpenGL::refresh() {
|
||||
GLuint filter, wrap;
|
||||
};
|
||||
vector<Source> sources;
|
||||
|
||||
unsigned sourceWidth = width, sourceHeight = height;
|
||||
sources.prepend({texture, sourceWidth, sourceHeight, filter, wrap});
|
||||
sources.prepend({texture, width, height, filter, wrap});
|
||||
|
||||
for(auto& p : programs) {
|
||||
unsigned targetWidth = p.absoluteWidth ? p.absoluteWidth : outputWidth;
|
||||
unsigned targetHeight = p.absoluteHeight ? p.absoluteHeight : outputHeight;
|
||||
if(p.relativeWidth) targetWidth = sourceWidth * p.relativeWidth;
|
||||
if(p.relativeHeight) targetHeight = sourceHeight * p.relativeHeight;
|
||||
if(p.relativeWidth) targetWidth = sources[0].width * p.relativeWidth;
|
||||
if(p.relativeHeight) targetHeight = sources[0].height * p.relativeHeight;
|
||||
|
||||
p.size(targetWidth, targetHeight);
|
||||
glUseProgram(p.program);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, p.framebuffer);
|
||||
|
||||
glrUniform1i("phase", p.phase);
|
||||
glrUniform1i("frameLength", frames.size());
|
||||
glrUniform1i("historyLength", history.size());
|
||||
glrUniform1i("sourceLength", sources.size());
|
||||
glrUniform1i("pixmapLength", p.pixmaps.size());
|
||||
glrUniform4f("targetSize", targetWidth, targetHeight, 1.0 / targetWidth, 1.0 / targetHeight);
|
||||
glrUniform4f("outputSize", outputWidth, outputHeight, 1.0 / outputWidth, 1.0 / outputHeight);
|
||||
|
||||
unsigned aid = 0;
|
||||
for(auto& frame : frames) {
|
||||
glrUniform1i({"frame[", aid, "]"}, aid);
|
||||
glrUniform4f({"frameSize[", aid, "]"}, frame.width, frame.height, 1.0 / frame.width, 1.0 / frame.height);
|
||||
for(auto& frame : history) {
|
||||
glrUniform1i({"history[", aid, "]"}, aid);
|
||||
glrUniform4f({"historySize[", aid, "]"}, frame.width, frame.height, 1.0 / frame.width, 1.0 / frame.height);
|
||||
glActiveTexture(GL_TEXTURE0 + (aid++));
|
||||
glBindTexture(GL_TEXTURE_2D, frame.texture);
|
||||
glrParameters(frame.filter, frame.wrap);
|
||||
@@ -134,19 +143,18 @@ void OpenGL::refresh() {
|
||||
}
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glrParameters(p.filter, p.wrap);
|
||||
p.render(sourceWidth, sourceHeight, targetWidth, targetHeight);
|
||||
glrParameters(sources[0].filter, sources[0].wrap);
|
||||
p.render(sources[0].width, sources[0].height, targetWidth, targetHeight);
|
||||
glBindTexture(GL_TEXTURE_2D, p.texture);
|
||||
|
||||
p.phase = (p.phase + 1) % p.modulo;
|
||||
sourceWidth = p.width, sourceHeight = p.height;
|
||||
sources.prepend({p.texture, sourceWidth, sourceHeight, p.filter, p.wrap});
|
||||
sources.prepend({p.texture, p.width, p.height, p.filter, p.wrap});
|
||||
}
|
||||
|
||||
unsigned targetWidth = absoluteWidth ? absoluteWidth : outputWidth;
|
||||
unsigned targetHeight = absoluteHeight ? absoluteHeight : outputHeight;
|
||||
if(relativeWidth) targetWidth = sourceWidth * relativeWidth;
|
||||
if(relativeHeight) targetHeight = sourceHeight * relativeHeight;
|
||||
if(relativeWidth) targetWidth = sources[0].width * relativeWidth;
|
||||
if(relativeHeight) targetHeight = sources[0].height * relativeHeight;
|
||||
|
||||
glUseProgram(program);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
@@ -155,20 +163,20 @@ void OpenGL::refresh() {
|
||||
glrUniform4f("targetSize", targetWidth, targetHeight, 1.0 / targetWidth, 1.0 / targetHeight);
|
||||
glrUniform4f("outputSize", outputWidth, outputHeight, 1.0 / outputWidth, 1.0 / outputHeight);
|
||||
|
||||
glrParameters(filter, wrap);
|
||||
render(sourceWidth, sourceHeight, outputWidth, outputHeight);
|
||||
glrParameters(sources[0].filter, sources[0].wrap);
|
||||
render(sources[0].width, sources[0].height, outputWidth, outputHeight);
|
||||
|
||||
if(frames.size() > 0) {
|
||||
OpenGLTexture frame = frames.take();
|
||||
if(history.size() > 0) {
|
||||
OpenGLTexture frame = history.takeLast();
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, frame.texture);
|
||||
if(width == frame.width && height == frame.height) {
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_BGRA, inputFormat, buffer);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, getFormat(), getType(), buffer);
|
||||
} else {
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, frame.format, frame.width = width, frame.height = height, 0, GL_BGRA, inputFormat, buffer);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, format, frame.width = width, frame.height = height, 0, getFormat(), getType(), buffer);
|
||||
}
|
||||
|
||||
frames.prepend(frame);
|
||||
history.prepend(frame);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -28,6 +28,9 @@ struct OpenGLTexture {
|
||||
GLuint format = GL_RGBA8;
|
||||
GLuint filter = GL_LINEAR;
|
||||
GLuint wrap = GL_CLAMP_TO_BORDER;
|
||||
|
||||
GLuint getFormat() const;
|
||||
GLuint getType() const;
|
||||
};
|
||||
|
||||
struct OpenGLSurface : OpenGLTexture {
|
||||
@@ -47,7 +50,6 @@ struct OpenGLSurface : OpenGLTexture {
|
||||
};
|
||||
|
||||
struct OpenGLProgram : OpenGLSurface {
|
||||
//configuration
|
||||
unsigned phase = 0; //frame counter
|
||||
unsigned modulo = 0; //frame counter modulus
|
||||
unsigned absoluteWidth = 0;
|
||||
@@ -63,18 +65,9 @@ struct OpenGLProgram : OpenGLSurface {
|
||||
|
||||
struct OpenGL : OpenGLProgram {
|
||||
vector<OpenGLProgram> programs;
|
||||
vector<OpenGLTexture> frames;
|
||||
struct History {
|
||||
unsigned length = 0;
|
||||
GLuint format = GL_RGBA8;
|
||||
GLuint filter = GL_LINEAR;
|
||||
GLuint wrap = GL_CLAMP_TO_BORDER;
|
||||
} history;
|
||||
|
||||
GLuint inputFormat = GL_UNSIGNED_INT_8_8_8_8_REV;
|
||||
vector<OpenGLTexture> history;
|
||||
unsigned outputWidth = 0;
|
||||
unsigned outputHeight = 0;
|
||||
|
||||
struct Setting {
|
||||
string name;
|
||||
string value;
|
||||
@@ -87,7 +80,7 @@ struct OpenGL : OpenGLProgram {
|
||||
set<Setting> settings;
|
||||
|
||||
void shader(const char* pathname);
|
||||
void bind(const Markup::Node& node, const string& pathname);
|
||||
void allocateHistory(unsigned size);
|
||||
bool lock(uint32_t*& data, unsigned& pitch);
|
||||
void clear();
|
||||
void refresh();
|
||||
@@ -95,6 +88,7 @@ struct OpenGL : OpenGLProgram {
|
||||
void term();
|
||||
};
|
||||
|
||||
#include "texture.hpp"
|
||||
#include "surface.hpp"
|
||||
#include "program.hpp"
|
||||
#include "main.hpp"
|
||||
|
@@ -9,7 +9,6 @@ void OpenGLProgram::bind(OpenGL* instance, const Markup::Node& node, const strin
|
||||
if(h.endsWith("%")) relativeHeight = real(h.rtrim<1>("%")) / 100.0;
|
||||
else absoluteHeight = decimal(h);
|
||||
|
||||
if(node.name != "program") return;
|
||||
format = glrFormat(node["format"].text());
|
||||
|
||||
program = glCreateProgram();
|
||||
@@ -62,8 +61,8 @@ void OpenGLProgram::bind(OpenGL* instance, const Markup::Node& node, const strin
|
||||
unsigned w = glrSize(image.width), h = glrSize(image.height);
|
||||
uint32_t* buffer = new uint32_t[w * h]();
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, pixmaps(n).format, w, h, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, buffer);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, image.width, image.height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, image.data);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, pixmaps(n).format, w, h, 0, pixmaps(n).getFormat(), pixmaps(n).getType(), buffer);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, image.width, image.height, getFormat(), getType(), image.data);
|
||||
delete[] buffer;
|
||||
}
|
||||
|
||||
|
@@ -15,7 +15,7 @@ void OpenGLSurface::size(unsigned w, unsigned h) {
|
||||
buffer = new uint32_t[w * h]();
|
||||
glGenTextures(1, &texture);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, buffer);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, getFormat(), getType(), buffer);
|
||||
|
||||
if(framebuffer) {
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
|
||||
|
12
ruby/video/opengl/texture.hpp
Normal file
12
ruby/video/opengl/texture.hpp
Normal file
@@ -0,0 +1,12 @@
|
||||
GLuint OpenGLTexture::getFormat() const {
|
||||
if(format == GL_R32I) return GL_RED_INTEGER;
|
||||
if(format == GL_R32UI) return GL_RED_INTEGER;
|
||||
return GL_BGRA;
|
||||
}
|
||||
|
||||
GLuint OpenGLTexture::getType() const {
|
||||
if(format == GL_R32I) return GL_UNSIGNED_INT;
|
||||
if(format == GL_R32UI) return GL_UNSIGNED_INT;
|
||||
if(format == GL_RGB10_A2) return GL_UNSIGNED_INT_2_10_10_10_REV;
|
||||
return GL_UNSIGNED_INT_8_8_8_8_REV;
|
||||
}
|
@@ -4,6 +4,8 @@ static unsigned glrSize(unsigned size) {
|
||||
}
|
||||
|
||||
static GLuint glrFormat(const string& format) {
|
||||
if(format == "r32i" ) return GL_R32I;
|
||||
if(format == "r32ui" ) return GL_R32UI;
|
||||
if(format == "rgba8" ) return GL_RGBA8;
|
||||
if(format == "rgb10a2") return GL_RGB10_A2;
|
||||
if(format == "rgba12" ) return GL_RGBA12;
|
||||
|
@@ -4,33 +4,45 @@
|
||||
namespace ruby {
|
||||
|
||||
struct pVideoXShm {
|
||||
struct {
|
||||
Display* display;
|
||||
struct Device {
|
||||
Display* display = nullptr;
|
||||
int screen;
|
||||
Visual *visual;
|
||||
int depth;
|
||||
Visual* visual = nullptr;
|
||||
Window window;
|
||||
|
||||
XShmSegmentInfo shmInfo;
|
||||
XImage* image;
|
||||
uint32_t* buffer;
|
||||
XImage* image = nullptr;
|
||||
uint32_t* buffer = nullptr;
|
||||
unsigned width, height;
|
||||
} device;
|
||||
|
||||
struct {
|
||||
struct Settings {
|
||||
uintptr_t handle;
|
||||
unsigned depth = 24;
|
||||
|
||||
uint32_t* buffer;
|
||||
uint32_t* buffer = nullptr;
|
||||
unsigned width, height;
|
||||
} settings;
|
||||
|
||||
struct Color {
|
||||
unsigned depth;
|
||||
unsigned shift;
|
||||
|
||||
unsigned idepth;
|
||||
unsigned ishift;
|
||||
} red, green, blue;
|
||||
|
||||
bool cap(const string& name) {
|
||||
if(name == Video::Handle) return true;
|
||||
if(name == Video::Depth) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
any get(const string& name) {
|
||||
if(name == Video::Handle) return settings.handle;
|
||||
if(name == Video::Depth) return settings.depth;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool set(const string& name, const any& value) {
|
||||
@@ -38,6 +50,9 @@ struct pVideoXShm {
|
||||
settings.handle = any_cast<uintptr_t>(value);
|
||||
return true;
|
||||
}
|
||||
if(name == Video::Depth) {
|
||||
return setDepth(any_cast<unsigned>(value));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -66,7 +81,7 @@ struct pVideoXShm {
|
||||
if(settings.buffer == nullptr) return;
|
||||
size();
|
||||
|
||||
float xRatio = (float)settings.width / (float)device.width;
|
||||
float xRatio = (float)settings.width / (float)device.width;
|
||||
float yRatio = (float)settings.height / (float)device.height;
|
||||
float yStep = 0;
|
||||
for(unsigned y = 0; y < device.height; y++) {
|
||||
@@ -77,7 +92,12 @@ struct pVideoXShm {
|
||||
for(unsigned x = 0; x < device.width; x++) {
|
||||
uint32_t color = sp[(unsigned)xStep];
|
||||
xStep += xRatio;
|
||||
*dp++ = ((color >> 20) & 0x000003ff) | ((color) & 0x000ffc00) | ((color << 20) & 0x3ff00000);
|
||||
unsigned r = (color >> red.ishift ) & ((1 << red.idepth ) - 1);
|
||||
unsigned g = (color >> green.ishift) & ((1 << green.idepth) - 1);
|
||||
unsigned b = (color >> blue.ishift ) & ((1 << blue.idepth ) - 1);
|
||||
*dp++ = image::normalize(r, red.idepth, red.depth ) << red.shift
|
||||
| image::normalize(g, green.idepth, green.depth) << green.shift
|
||||
| image::normalize(b, blue.idepth, blue.depth ) << blue.shift;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,15 +113,36 @@ struct pVideoXShm {
|
||||
bool init() {
|
||||
device.display = XOpenDisplay(0);
|
||||
device.screen = DefaultScreen(device.display);
|
||||
device.visual = DefaultVisual(device.display, device.screen);
|
||||
device.depth = DefaultDepth(device.display, device.screen);
|
||||
|
||||
XSetWindowAttributes attributes;
|
||||
attributes.border_pixel = 0;
|
||||
XWindowAttributes getAttributes;
|
||||
XGetWindowAttributes(device.display, (Window)settings.handle, &getAttributes);
|
||||
device.depth = getAttributes.depth;
|
||||
device.visual = getAttributes.visual;
|
||||
unsigned visualID = XVisualIDFromVisual(device.visual);
|
||||
|
||||
XVisualInfo visualTemplate = {0};
|
||||
visualTemplate.screen = device.screen;
|
||||
visualTemplate.depth = device.depth;
|
||||
int visualsMatched = 0;
|
||||
XVisualInfo* visualList = XGetVisualInfo(device.display, VisualScreenMask | VisualDepthMask, &visualTemplate, &visualsMatched);
|
||||
for(unsigned n = 0; n < visualsMatched; n++) {
|
||||
auto& v = visualList[n];
|
||||
if(v.visualid == visualID) {
|
||||
red.depth = bit::count(v.red_mask), red.shift = bit::first(v.red_mask);
|
||||
green.depth = bit::count(v.green_mask), green.shift = bit::first(v.green_mask);
|
||||
blue.depth = bit::count(v.blue_mask), blue.shift = bit::first(v.blue_mask);
|
||||
break;
|
||||
}
|
||||
}
|
||||
XFree(visualList);
|
||||
setDepth(settings.depth);
|
||||
|
||||
XSetWindowAttributes setAttributes = {0};
|
||||
setAttributes.border_pixel = 0;
|
||||
device.window = XCreateWindow(device.display, (Window)settings.handle,
|
||||
0, 0, 256, 256,
|
||||
0, device.depth, InputOutput, device.visual,
|
||||
CWBorderPixel, &attributes
|
||||
0, 0, 256, 256, 0,
|
||||
getAttributes.depth, InputOutput, getAttributes.visual,
|
||||
CWBorderPixel, &setAttributes
|
||||
);
|
||||
XSetWindowBackground(device.display, device.window, 0);
|
||||
XMapWindow(device.display, device.window);
|
||||
@@ -118,12 +159,8 @@ struct pVideoXShm {
|
||||
|
||||
void term() {
|
||||
free();
|
||||
}
|
||||
|
||||
pVideoXShm() {
|
||||
device.buffer = nullptr;
|
||||
|
||||
settings.buffer = nullptr;
|
||||
if(device.display) { XCloseDisplay(device.display); device.display = nullptr; }
|
||||
}
|
||||
|
||||
~pVideoXShm() {
|
||||
@@ -131,6 +168,26 @@ struct pVideoXShm {
|
||||
}
|
||||
|
||||
//internal:
|
||||
bool setDepth(unsigned depth) {
|
||||
if(depth == 24) {
|
||||
settings.depth = 24;
|
||||
red.idepth = 8, red.ishift = 16;
|
||||
green.idepth = 8, green.ishift = 8;
|
||||
blue.idepth = 8, blue.ishift = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(depth == 30) {
|
||||
settings.depth = 30;
|
||||
red.idepth = 10, red.ishift = 20;
|
||||
green.idepth = 10, green.ishift = 10;
|
||||
blue.idepth = 10, blue.ishift = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool size() {
|
||||
XWindowAttributes windowAttributes;
|
||||
XGetWindowAttributes(device.display, settings.handle, &windowAttributes);
|
||||
|
Reference in New Issue
Block a user