mirror of
https://github.com/DerKoun/bsnes-hd.git
synced 2025-04-02 10:52:49 -04:00
153 lines
4.2 KiB
C++
153 lines
4.2 KiB
C++
auto Program::updateVideoDriver(Window parent) -> void {
|
|
auto changed = (bool)video;
|
|
video.create(settings.video.driver);
|
|
video.setContext(presentation.viewport.handle());
|
|
if(changed) {
|
|
settings.video.format = video.format();
|
|
}
|
|
updateVideoExclusive();
|
|
updateVideoBlocking();
|
|
updateVideoFlush();
|
|
updateVideoMonitor();
|
|
updateVideoFormat();
|
|
updateVideoShader();
|
|
|
|
if(video.ready()) {
|
|
video.clear();
|
|
updateVideoShader();
|
|
}
|
|
|
|
video.onUpdate([&](uint width, uint height) {
|
|
if(!emulator->loaded()) video.clear();
|
|
});
|
|
|
|
if(!video.ready()) {
|
|
MessageDialog({
|
|
"Error: failed to initialize [", settings.video.driver, "] video driver."
|
|
}).setAlignment(parent).error();
|
|
settings.video.driver = "None";
|
|
return updateVideoDriver(parent);
|
|
}
|
|
|
|
presentation.updateShaders();
|
|
}
|
|
|
|
auto Program::updateVideoExclusive() -> void {
|
|
video.setExclusive(settings.video.exclusive);
|
|
}
|
|
|
|
auto Program::updateVideoBlocking() -> void {
|
|
video.setBlocking(settings.video.blocking);
|
|
}
|
|
|
|
auto Program::updateVideoFlush() -> void {
|
|
video.setFlush(settings.video.flush);
|
|
}
|
|
|
|
auto Program::updateVideoMonitor() -> void {
|
|
if(!video.hasMonitor(settings.video.monitor)) {
|
|
settings.video.monitor = video.monitor();
|
|
}
|
|
video.setMonitor(settings.video.monitor);
|
|
}
|
|
|
|
auto Program::updateVideoFormat() -> void {
|
|
if(!video.hasFormat(settings.video.format)) {
|
|
settings.video.format = video.format();
|
|
}
|
|
video.setFormat(settings.video.format);
|
|
}
|
|
|
|
auto Program::updateVideoShader() -> void {
|
|
video.setShader(settings.video.shader);
|
|
}
|
|
|
|
auto Program::updateVideoPalette() -> void {
|
|
double luminance = settings.video.luminance / 100.0;
|
|
double saturation = settings.video.saturation / 100.0;
|
|
double gamma = settings.video.gamma / 100.0;
|
|
|
|
uint depth = 24;
|
|
if(video.format() == "RGB30") depth = 30;
|
|
|
|
for(uint color : range(32768)) {
|
|
uint16 r = (color >> 10) & 31;
|
|
uint16 g = (color >> 5) & 31;
|
|
uint16 b = (color >> 0) & 31;
|
|
|
|
r = r << 3 | r >> 2; r = r << 8 | r << 0;
|
|
g = g << 3 | g >> 2; g = g << 8 | g << 0;
|
|
b = b << 3 | b >> 2; b = b << 8 | b << 0;
|
|
|
|
if(saturation != 1.0) {
|
|
uint16 grayscale = uclamp<16>((r + g + b) / 3);
|
|
double inverse = max(0.0, 1.0 - saturation);
|
|
r = uclamp<16>(r * saturation + grayscale * inverse);
|
|
g = uclamp<16>(g * saturation + grayscale * inverse);
|
|
b = uclamp<16>(b * saturation + grayscale * inverse);
|
|
}
|
|
|
|
if(gamma != 1.0) {
|
|
double reciprocal = 1.0 / 32767.0;
|
|
r = r > 32767 ? r : uint16(32767 * pow(r * reciprocal, gamma));
|
|
g = g > 32767 ? g : uint16(32767 * pow(g * reciprocal, gamma));
|
|
b = b > 32767 ? b : uint16(32767 * pow(b * reciprocal, gamma));
|
|
}
|
|
|
|
if(luminance != 1.0) {
|
|
r = uclamp<16>(r * luminance);
|
|
g = uclamp<16>(g * luminance);
|
|
b = uclamp<16>(b * luminance);
|
|
}
|
|
|
|
switch(depth) {
|
|
case 24: palette[color] = r >> 8 << 16 | g >> 8 << 8 | b >> 8 << 0; break;
|
|
case 30: palette[color] = r >> 6 << 20 | g >> 6 << 10 | b >> 6 << 0; break;
|
|
}
|
|
|
|
r >>= 1;
|
|
g >>= 1;
|
|
b >>= 1;
|
|
|
|
switch(depth) {
|
|
case 24: paletteDimmed[color] = r >> 8 << 16 | g >> 8 << 8 | b >> 8 << 0; break;
|
|
case 30: paletteDimmed[color] = r >> 6 << 20 | g >> 6 << 10 | b >> 6 << 0; break;
|
|
}
|
|
}
|
|
|
|
emulator->configure("Video/ColorEmulation", false);
|
|
}
|
|
|
|
auto Program::updateVideoEffects() -> void {
|
|
emulator->configure("Video/BlurEmulation", settings.video.blur);
|
|
}
|
|
|
|
auto Program::toggleVideoFullScreen() -> void {
|
|
if(!video.hasFullScreen()) return;
|
|
if(presentation.fullScreen()) return;
|
|
|
|
video.clear();
|
|
|
|
if(!video.fullScreen()) {
|
|
video.setFullScreen(true);
|
|
if(!input.acquired() && (video.exclusive() || video.hasMonitors().size() == 1)) input.acquire();
|
|
} else {
|
|
if(input.acquired()) input.release();
|
|
video.setFullScreen(false);
|
|
presentation.viewport.setFocused();
|
|
}
|
|
}
|
|
|
|
auto Program::toggleVideoPseudoFullScreen() -> void {
|
|
if(video.fullScreen()) return;
|
|
|
|
if(!presentation.fullScreen()) {
|
|
presentation.setFullScreen(true);
|
|
presentation.menuBar.setVisible(false);
|
|
if(!input.acquired() && video.hasMonitors().size() == 1) input.acquire();
|
|
} else {
|
|
if(input.acquired()) input.release();
|
|
presentation.menuBar.setVisible(true);
|
|
presentation.setFullScreen(false);
|
|
}
|
|
}
|