2018-06-27 01:56:27 +00:00
|
|
|
auto Program::updateVideoDriver() -> void {
|
|
|
|
video = Video::create(settings["Video/Driver"].text());
|
|
|
|
video->setContext(presentation->viewport.handle());
|
Update to 20180728 release.
byuu says:
Sigh, I seem to be spiraling a bit here ... but the work is very
important. Hopefully I can get a solid WIP together soon. But for now...
I've integrated dynamic rate control into ruby::Audio via
setDynamic(bool) for now. It's very demanding, as you would expect. When
it's not in use, I realized the OSS driver's performance was pretty bad
due to calling write() for every sample for every channel. I implemented
a tiny 256-sample buffer and bsnes went from 290fps to 330fps on my
FreeBSD desktop. It may be possible to do the same buffering with DRC,
but for now, I'm not doing so, and adjusting the audio input frequency
on every sample.
I also added ruby::Video::setFlush(bool), which is available only in the
OpenGL drivers, and this causes glFinish() to be called after swapping
display buffers. I really couldn't think of a good name for this, "hard
GPU sync" sounds kind of silly. In my view, flush is what commits queued
events. Eg fflush(). OpenGL of course treats glFlush differently (I
really don't even know what the point of it is even after reading the
manual ...), and then has glFinish ... meh, whatever. It's
setFlush(bool) until I come up with something better. Also as expected,
this one's a big hit to performance.
To implement the DRC, I started putting helper functions into the ruby
video/audio/input core classes. And then the XVideo driver started
crashing. It took hours and hours and hours to track down the problem:
you have to clear XSetWindowAttributes to zero before calling
XCreateWindow. No amount of `--sync`, `gdb break gdk_x_error`, `-Og`,
etc will make Xlib be even remotely helpful in debugging errors like
this.
The GLX, GLX2, and XVideo drivers basically worked by chance before. If
the stack frame had the right memory cleared, it worked. Otherwise it'd
crash with BadValue, and my changing things broke that condition on the
XVideo driver. So this has been fixed in all three now.
Once XVideo was running again, I realized that non-power of two video
sizes were completely broken for the YUV formats. It took a while, but I
managed to fix all of that as well.
At this point, most of ruby is going to be broken outside of FreeBSD, as
I still need to finish updating all the drivers.
2018-07-28 11:21:39 +00:00
|
|
|
updateVideoExclusive();
|
2018-06-27 01:56:27 +00:00
|
|
|
updateVideoBlocking();
|
|
|
|
updateVideoShader();
|
|
|
|
|
|
|
|
if(video->ready()) {
|
|
|
|
presentation->clearViewport();
|
|
|
|
updateVideoShader();
|
|
|
|
}
|
|
|
|
|
|
|
|
video->onUpdate([&](uint width, uint height) {
|
|
|
|
if(!emulator->loaded()) presentation->clearViewport();
|
|
|
|
});
|
|
|
|
|
|
|
|
settingsWindow->advanced.updateVideoDriver();
|
|
|
|
|
|
|
|
if(!video->ready()) {
|
|
|
|
MessageDialog({
|
|
|
|
"Error: failed to initialize [", settings["Video/Driver"].text(), "] video driver."
|
|
|
|
}).error();
|
|
|
|
settings["Video/Driver"].setValue("None");
|
|
|
|
return updateVideoDriver();
|
|
|
|
}
|
2018-07-08 04:58:27 +00:00
|
|
|
|
|
|
|
presentation->updateShaders();
|
2018-06-27 01:56:27 +00:00
|
|
|
}
|
|
|
|
|
Update to 20180728 release.
byuu says:
Sigh, I seem to be spiraling a bit here ... but the work is very
important. Hopefully I can get a solid WIP together soon. But for now...
I've integrated dynamic rate control into ruby::Audio via
setDynamic(bool) for now. It's very demanding, as you would expect. When
it's not in use, I realized the OSS driver's performance was pretty bad
due to calling write() for every sample for every channel. I implemented
a tiny 256-sample buffer and bsnes went from 290fps to 330fps on my
FreeBSD desktop. It may be possible to do the same buffering with DRC,
but for now, I'm not doing so, and adjusting the audio input frequency
on every sample.
I also added ruby::Video::setFlush(bool), which is available only in the
OpenGL drivers, and this causes glFinish() to be called after swapping
display buffers. I really couldn't think of a good name for this, "hard
GPU sync" sounds kind of silly. In my view, flush is what commits queued
events. Eg fflush(). OpenGL of course treats glFlush differently (I
really don't even know what the point of it is even after reading the
manual ...), and then has glFinish ... meh, whatever. It's
setFlush(bool) until I come up with something better. Also as expected,
this one's a big hit to performance.
To implement the DRC, I started putting helper functions into the ruby
video/audio/input core classes. And then the XVideo driver started
crashing. It took hours and hours and hours to track down the problem:
you have to clear XSetWindowAttributes to zero before calling
XCreateWindow. No amount of `--sync`, `gdb break gdk_x_error`, `-Og`,
etc will make Xlib be even remotely helpful in debugging errors like
this.
The GLX, GLX2, and XVideo drivers basically worked by chance before. If
the stack frame had the right memory cleared, it worked. Otherwise it'd
crash with BadValue, and my changing things broke that condition on the
XVideo driver. So this has been fixed in all three now.
Once XVideo was running again, I realized that non-power of two video
sizes were completely broken for the YUV formats. It took a while, but I
managed to fix all of that as well.
At this point, most of ruby is going to be broken outside of FreeBSD, as
I still need to finish updating all the drivers.
2018-07-28 11:21:39 +00:00
|
|
|
auto Program::updateVideoExclusive() -> void {
|
|
|
|
video->setExclusive(false);
|
|
|
|
if(video->hasExclusive()) {
|
|
|
|
settingsWindow->video.exclusiveMode.setEnabled(true).setChecked(settings["Video/Exclusive"].boolean());
|
|
|
|
} else {
|
|
|
|
settingsWindow->video.exclusiveMode.setEnabled(false).setChecked(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-27 01:56:27 +00:00
|
|
|
auto Program::updateVideoBlocking() -> void {
|
|
|
|
video->setBlocking(settings["Video/Blocking"].boolean());
|
|
|
|
}
|
|
|
|
|
|
|
|
auto Program::updateVideoShader() -> void {
|
|
|
|
if(settings["Video/Driver"].text() == "OpenGL"
|
|
|
|
&& settings["Video/Shader"].text() != "None"
|
|
|
|
&& settings["Video/Shader"].text() != "Blur"
|
|
|
|
) {
|
|
|
|
video->setSmooth(false);
|
|
|
|
video->setShader(settings["Video/Shader"].text());
|
|
|
|
} else {
|
|
|
|
video->setSmooth(settings["Video/Shader"].text() == "Blur");
|
|
|
|
video->setShader("");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
auto Program::updateVideoPalette() -> void {
|
Update to 20180726 release.
byuu says:
Once again, I wasn't able to complete a full WIP revision.
This WIP-WIP adds very sophisticated emulation of the Sega Genesis
Lock-On and Game Genie cartridges ... essentially, through recursion and
a linked list, higan supports an infinite nesting of cartridges.
Of course, on real hardware, after you stack more than three or four
cartridges, the power draw gets too high and things start glitching out
more and more as you keep stacking. I've heard that someone chained up
to ten Sonic & Knuckles cartridges before it finally became completely
unplayable.
And so of course, higan emulates this limitation as well ^-^. On the
fourth cartridge and beyond, it will become more and more likely that
address and/or data lines "glitch" out randomly, causing various
glitches. It's a completely silly easter egg that requires no speed
impact whatsoever beyond the impact of the new linked list cartridge
system.
I also designed the successor to Emulator::Interface::cap,get,set. Those
were holdovers from the older, since-removed ruby-style accessors.
In its place is the new Emulator::Interface::configuration,configure
API. There's the usual per-property access, and there's also access to
read and write all configurable options at once. In essence, this
enables introspection into core-specific features.
So far, you can control processor version#s, PPU VRAM size, video
settings, and hacks. As such, the .sys/manifest.bml files are no longer
necessary. Instead, it all goes into .sys/configuration.bml, which is
generated by the emulator if it's missing.
higan is going to take this even further and allow each option under
"Systems" to have its own editable configuration file. So if you wanted,
you could have a 1/1/1 SNES menu option, and a 2/1/3 SNES menu option.
Or a Model 1 Genesis option, and a Model 2 Genesis option. Or the
various Game Boy model revisions. Or an "SNES-Fast" and "SNES-Accurate"
option.
I've not fully settled on the syntax of the new configuration API. I
feel it might be useful to provide type information, but I really quite
passionately hate any<T> container objects. For now it's all
string-based, because strings can hold anything in nall.
I might also change the access rules. Right now it's like:
emulator→configure("video/blurEmulation", true); but it might be nicer
as "Video::Blur Emulation", or "Video.BlurEmulation", or something like
that.
2018-07-26 10:36:43 +00:00
|
|
|
emulator->configure("video/colorEmulation", false);
|
2018-06-27 01:56:27 +00:00
|
|
|
double luminance = settings["Video/Luminance"].natural() / 100.0;
|
|
|
|
double saturation = settings["Video/Saturation"].natural() / 100.0;
|
|
|
|
double gamma = settings["Video/Gamma"].natural() / 100.0;
|
|
|
|
Emulator::video.setLuminance(luminance);
|
|
|
|
Emulator::video.setSaturation(saturation);
|
|
|
|
Emulator::video.setGamma(gamma);
|
|
|
|
Emulator::video.setPalette();
|
|
|
|
}
|