bsnes/higan/target-bsnes/presentation/presentation.cpp

387 lines
13 KiB
C++
Raw Normal View History

#include "../bsnes.hpp"
#include "about.cpp"
unique_pointer<AboutWindow> aboutWindow;
unique_pointer<Presentation> presentation;
Presentation::Presentation() {
presentation = this;
systemMenu.setText("System");
loadGame.setText("Load Game ...").onActivate([&] {
program->load();
});
loadRecentGame.setText("Load Recent Game");
updateRecentGames();
resetSystem.setText("Reset System").setEnabled(false).onActivate([&] {
if(emulator->loaded()) emulator->reset();
});
unloadGame.setText("Unload Game").setEnabled(false).onActivate([&] {
program->unload();
});
controllerPort1.setText("Controller Port 1");
controllerPort2.setText("Controller Port 2");
for(auto& port : emulator->ports) {
Menu* menu = nullptr;
if(port.name == "Controller Port 1") menu = &controllerPort1;
if(port.name == "Controller Port 2") menu = &controllerPort2;
if(!menu) continue;
Group devices;
for(auto& device : port.devices) {
if(device.name == "None") continue;
MenuRadioItem item{menu};
item.setText(device.name).onActivate([=] {
auto path = string{"Emulator/", port.name}.replace(" ", "");
settings(path).setValue(device.name);
emulator->connect(port.id, device.id);
});
devices.append(item);
}
auto path = string{"Emulator/", port.name}.replace(" ", "");
auto device = settings(path).text();
bool found = false;
if(devices.objectCount() > 1) {
for(auto item : devices.objects<MenuRadioItem>()) {
if(item.text() == device) item.setChecked(), found = true;
}
}
//select the first device when a new settings file is being created
if(devices.objectCount() && !found) {
devices.objects<MenuRadioItem>()(0).doActivate();
}
}
quit.setText("Quit").onActivate([&] { program->quit(); });
settingsMenu.setText("Settings");
viewMenu.setText("View");
smallView.setText("Small").onActivate([&] {
settings["View/Size"].setValue("Small");
resizeWindow();
});
mediumView.setText("Medium").onActivate([&] {
settings["View/Size"].setValue("Medium");
resizeWindow();
});
largeView.setText("Large").onActivate([&] {
settings["View/Size"].setValue("Large");
resizeWindow();
});
aspectCorrection.setText("Aspect Correction").setChecked(settings["View/AspectCorrection"].boolean()).onToggle([&] {
settings["View/AspectCorrection"].setValue(aspectCorrection.checked());
resizeWindow();
});
overscanCropping.setText("Overscan Cropping").setChecked(settings["View/OverscanCropping"].boolean()).onToggle([&] {
settings["View/OverscanCropping"].setValue(overscanCropping.checked());
resizeWindow();
});
integralScaling.setText("Integral Scaling").setChecked(settings["View/IntegralScaling"].boolean()).onToggle([&] {
settings["View/IntegralScaling"].setValue(integralScaling.checked());
resizeViewport();
});
blurEmulation.setText("Blur Emulation").setChecked(settings["View/BlurEmulation"].boolean()).onToggle([&] {
settings["View/BlurEmulation"].setValue(blurEmulation.checked());
emulator->set("Blur Emulation", blurEmulation.checked());
}).doToggle();
colorEmulation.setText("Color Emulation").setChecked(settings["View/ColorEmulation"].boolean()).onToggle([&] {
settings["View/ColorEmulation"].setValue(colorEmulation.checked());
emulator->set("Color Emulation", colorEmulation.checked());
}).doToggle();
shaderMenu.setText("Shader");
updateShaders();
muteAudio.setText("Mute Audio").setChecked(settings["Audio/Mute"].boolean()).onToggle([&] {
settings["Audio/Mute"].setValue(muteAudio.checked());
});
showStatusBar.setText("Show Status Bar").setChecked(settings["UserInterface/ShowStatusBar"].boolean()).onToggle([&] {
settings["UserInterface/ShowStatusBar"].setValue(showStatusBar.checked());
statusBar.setVisible(showStatusBar.checked());
if(visible()) resizeWindow();
});
inputSettings.setText("Input ...").onActivate([&] { settingsWindow->show(0); });
hotkeySettings.setText("Hotkeys ...").onActivate([&] { settingsWindow->show(1); });
pathSettings.setText("Paths ...").onActivate([&] { settingsWindow->show(2); });
Update to v106r27 release. byuu says: Changelog: - nall: merged Path::config() and Path::local() to Path::userData() - ~/.local/share or %appdata or ~/Library/ApplicationSupport - higan, bsnes: render main window icon onto viewport instead of canvas - should hopefully fix a brief flickering glitch that appears on Windows - icarus: improved Super Famicom heuristics for Starfox / Starwing RAM - ruby/Direct3D: handle viewport size changes in lock() instead of output() - fixes icon disappearing when resizing main window - hiro/Windows: remove WS_DISABLED from StatusBar to fix window resize grip - this is experimental: I initially used WS_DISABLED to work around a focus bug - yet trying things now, said bug seems(?) to have gone away at some point ... - bsnes: added advanced settings panel with real-time driver change support I'd like feedback on the real-time driver change, for possible consideration into adding this to higan as well. Some drivers just crash, it's a fact of life. The ASIO driver in particular likes to crash inside the driver itself, without any error messages ever returned to try and catch. When you try to change a driver with a game loaded, it gives you a scary warning, asking if you want to proceed. When you change a driver, it sets a crash flag, and if the driver crashes while initializing, then restarting bsnes will disable the errant driver. If it fails in a recoverable way, then it sets the driver to “None” and warns you that the driver cannot be used. What I'm thinking of further adding is to call emulator→save() to write out the save RAM contents beforehand (although the periodic auto-saving RAM will handle this anyway when it's enabled), and possibly it might be wise to capture an emulator save state, although those can't be taken without advancing the emulator to the next frame, so that might not be a good idea. I'm also thinking we should show some kind of message somewhere when a driver is set to “None”. The status bar can be hidden, so perhaps on the title bar? Or maybe just a warning on startup that a driver is set to “None”.
2018-05-25 08:02:38 +00:00
advancedSettings.setText("Advanced ...").onActivate([&] { settingsWindow->show(3); });
toolsMenu.setText("Tools");
saveState.setText("Save State").setEnabled(false);
saveState1.setText("Slot 1").onActivate([&] { program->saveState(1); });
saveState2.setText("Slot 2").onActivate([&] { program->saveState(2); });
saveState3.setText("Slot 3").onActivate([&] { program->saveState(3); });
saveState4.setText("Slot 4").onActivate([&] { program->saveState(4); });
saveState5.setText("Slot 5").onActivate([&] { program->saveState(5); });
loadState.setText("Load State").setEnabled(false);
loadState1.setText("Slot 1").onActivate([&] { program->loadState(1); });
loadState2.setText("Slot 2").onActivate([&] { program->loadState(2); });
loadState3.setText("Slot 3").onActivate([&] { program->loadState(3); });
loadState4.setText("Slot 4").onActivate([&] { program->loadState(4); });
loadState5.setText("Slot 5").onActivate([&] { program->loadState(5); });
pauseEmulation.setText("Pause Emulation").onToggle([&] {
if(pauseEmulation.checked()) audio->clear();
});
helpMenu.setText("Help");
about.setText("About ...").onActivate([&] {
aboutWindow->setCentered(*this).setVisible().setFocused();
});
viewport.setDroppable().onDrop([&](auto locations) {
program->gameQueue = locations;
program->load();
presentation->setFocused();
});
statusBar.setFont(Font().setBold());
statusBar.setVisible(settings["UserInterface/ShowStatusBar"].boolean());
onClose([&] {
program->quit();
});
onSize([&] {
resizeViewport();
});
setTitle({"bsnes v", Emulator::Version});
setBackgroundColor({0, 0, 0});
resizeWindow();
setCentered();
#if defined(PLATFORM_WINDOWS)
Update to v106r27 release. byuu says: Changelog: - nall: merged Path::config() and Path::local() to Path::userData() - ~/.local/share or %appdata or ~/Library/ApplicationSupport - higan, bsnes: render main window icon onto viewport instead of canvas - should hopefully fix a brief flickering glitch that appears on Windows - icarus: improved Super Famicom heuristics for Starfox / Starwing RAM - ruby/Direct3D: handle viewport size changes in lock() instead of output() - fixes icon disappearing when resizing main window - hiro/Windows: remove WS_DISABLED from StatusBar to fix window resize grip - this is experimental: I initially used WS_DISABLED to work around a focus bug - yet trying things now, said bug seems(?) to have gone away at some point ... - bsnes: added advanced settings panel with real-time driver change support I'd like feedback on the real-time driver change, for possible consideration into adding this to higan as well. Some drivers just crash, it's a fact of life. The ASIO driver in particular likes to crash inside the driver itself, without any error messages ever returned to try and catch. When you try to change a driver with a game loaded, it gives you a scary warning, asking if you want to proceed. When you change a driver, it sets a crash flag, and if the driver crashes while initializing, then restarting bsnes will disable the errant driver. If it fails in a recoverable way, then it sets the driver to “None” and warns you that the driver cannot be used. What I'm thinking of further adding is to call emulator→save() to write out the save RAM contents beforehand (although the periodic auto-saving RAM will handle this anyway when it's enabled), and possibly it might be wise to capture an emulator save state, although those can't be taken without advancing the emulator to the next frame, so that might not be a good idea. I'm also thinking we should show some kind of message somewhere when a driver is set to “None”. The status bar can be hidden, so perhaps on the title bar? Or maybe just a warning on startup that a driver is set to “None”.
2018-05-25 08:02:38 +00:00
Application::Windows::onModalChange([&](bool modal) {
if(modal && audio) audio->clear();
});
Update to v106r27 release. byuu says: Changelog: - nall: merged Path::config() and Path::local() to Path::userData() - ~/.local/share or %appdata or ~/Library/ApplicationSupport - higan, bsnes: render main window icon onto viewport instead of canvas - should hopefully fix a brief flickering glitch that appears on Windows - icarus: improved Super Famicom heuristics for Starfox / Starwing RAM - ruby/Direct3D: handle viewport size changes in lock() instead of output() - fixes icon disappearing when resizing main window - hiro/Windows: remove WS_DISABLED from StatusBar to fix window resize grip - this is experimental: I initially used WS_DISABLED to work around a focus bug - yet trying things now, said bug seems(?) to have gone away at some point ... - bsnes: added advanced settings panel with real-time driver change support I'd like feedback on the real-time driver change, for possible consideration into adding this to higan as well. Some drivers just crash, it's a fact of life. The ASIO driver in particular likes to crash inside the driver itself, without any error messages ever returned to try and catch. When you try to change a driver with a game loaded, it gives you a scary warning, asking if you want to proceed. When you change a driver, it sets a crash flag, and if the driver crashes while initializing, then restarting bsnes will disable the errant driver. If it fails in a recoverable way, then it sets the driver to “None” and warns you that the driver cannot be used. What I'm thinking of further adding is to call emulator→save() to write out the save RAM contents beforehand (although the periodic auto-saving RAM will handle this anyway when it's enabled), and possibly it might be wise to capture an emulator save state, although those can't be taken without advancing the emulator to the next frame, so that might not be a good idea. I'm also thinking we should show some kind of message somewhere when a driver is set to “None”. The status bar can be hidden, so perhaps on the title bar? Or maybe just a warning on startup that a driver is set to “None”.
2018-05-25 08:02:38 +00:00
Application::Windows::onScreenSaver([&]() -> bool {
if(emulator->loaded()) {
if(pauseEmulation.checked()) return true;
if(!program->focused() && settingsWindow->input.pauseEmulation.checked()) return true;
return false;
}
return true;
});
#endif
#if defined(PLATFORM_MACOS)
Application::Cocoa::onAbout([&] { about.doActivate(); });
Application::Cocoa::onActivate([&] { setFocused(); });
Application::Cocoa::onPreferences([&] { settingsWindow->show(0); });
Application::Cocoa::onQuit([&] { doClose(); });
#endif
}
Update to v106r27 release. byuu says: Changelog: - nall: merged Path::config() and Path::local() to Path::userData() - ~/.local/share or %appdata or ~/Library/ApplicationSupport - higan, bsnes: render main window icon onto viewport instead of canvas - should hopefully fix a brief flickering glitch that appears on Windows - icarus: improved Super Famicom heuristics for Starfox / Starwing RAM - ruby/Direct3D: handle viewport size changes in lock() instead of output() - fixes icon disappearing when resizing main window - hiro/Windows: remove WS_DISABLED from StatusBar to fix window resize grip - this is experimental: I initially used WS_DISABLED to work around a focus bug - yet trying things now, said bug seems(?) to have gone away at some point ... - bsnes: added advanced settings panel with real-time driver change support I'd like feedback on the real-time driver change, for possible consideration into adding this to higan as well. Some drivers just crash, it's a fact of life. The ASIO driver in particular likes to crash inside the driver itself, without any error messages ever returned to try and catch. When you try to change a driver with a game loaded, it gives you a scary warning, asking if you want to proceed. When you change a driver, it sets a crash flag, and if the driver crashes while initializing, then restarting bsnes will disable the errant driver. If it fails in a recoverable way, then it sets the driver to “None” and warns you that the driver cannot be used. What I'm thinking of further adding is to call emulator→save() to write out the save RAM contents beforehand (although the periodic auto-saving RAM will handle this anyway when it's enabled), and possibly it might be wise to capture an emulator save state, although those can't be taken without advancing the emulator to the next frame, so that might not be a good idea. I'm also thinking we should show some kind of message somewhere when a driver is set to “None”. The status bar can be hidden, so perhaps on the title bar? Or maybe just a warning on startup that a driver is set to “None”.
2018-05-25 08:02:38 +00:00
auto Presentation::drawIcon(uint32_t* output, uint length, uint width, uint height) -> void {
int ox = width - 144;
int oy = height - 128;
if(ox >= 0 && oy >= 0) {
image icon{Resource::Icon};
icon.alphaBlend(0xff000000);
for(uint y : range(128)) {
auto target = output + (y + oy) * (length >> 2) + ox;
auto source = (uint32_t*)icon.data() + y * 128;
memory::copy<uint32_t>(target, source, 128);
Update to v106r27 release. byuu says: Changelog: - nall: merged Path::config() and Path::local() to Path::userData() - ~/.local/share or %appdata or ~/Library/ApplicationSupport - higan, bsnes: render main window icon onto viewport instead of canvas - should hopefully fix a brief flickering glitch that appears on Windows - icarus: improved Super Famicom heuristics for Starfox / Starwing RAM - ruby/Direct3D: handle viewport size changes in lock() instead of output() - fixes icon disappearing when resizing main window - hiro/Windows: remove WS_DISABLED from StatusBar to fix window resize grip - this is experimental: I initially used WS_DISABLED to work around a focus bug - yet trying things now, said bug seems(?) to have gone away at some point ... - bsnes: added advanced settings panel with real-time driver change support I'd like feedback on the real-time driver change, for possible consideration into adding this to higan as well. Some drivers just crash, it's a fact of life. The ASIO driver in particular likes to crash inside the driver itself, without any error messages ever returned to try and catch. When you try to change a driver with a game loaded, it gives you a scary warning, asking if you want to proceed. When you change a driver, it sets a crash flag, and if the driver crashes while initializing, then restarting bsnes will disable the errant driver. If it fails in a recoverable way, then it sets the driver to “None” and warns you that the driver cannot be used. What I'm thinking of further adding is to call emulator→save() to write out the save RAM contents beforehand (although the periodic auto-saving RAM will handle this anyway when it's enabled), and possibly it might be wise to capture an emulator save state, although those can't be taken without advancing the emulator to the next frame, so that might not be a good idea. I'm also thinking we should show some kind of message somewhere when a driver is set to “None”. The status bar can be hidden, so perhaps on the title bar? Or maybe just a warning on startup that a driver is set to “None”.
2018-05-25 08:02:38 +00:00
}
}
}
auto Presentation::clearViewport() -> void {
if(!video) return;
Update to v106r27 release. byuu says: Changelog: - nall: merged Path::config() and Path::local() to Path::userData() - ~/.local/share or %appdata or ~/Library/ApplicationSupport - higan, bsnes: render main window icon onto viewport instead of canvas - should hopefully fix a brief flickering glitch that appears on Windows - icarus: improved Super Famicom heuristics for Starfox / Starwing RAM - ruby/Direct3D: handle viewport size changes in lock() instead of output() - fixes icon disappearing when resizing main window - hiro/Windows: remove WS_DISABLED from StatusBar to fix window resize grip - this is experimental: I initially used WS_DISABLED to work around a focus bug - yet trying things now, said bug seems(?) to have gone away at some point ... - bsnes: added advanced settings panel with real-time driver change support I'd like feedback on the real-time driver change, for possible consideration into adding this to higan as well. Some drivers just crash, it's a fact of life. The ASIO driver in particular likes to crash inside the driver itself, without any error messages ever returned to try and catch. When you try to change a driver with a game loaded, it gives you a scary warning, asking if you want to proceed. When you change a driver, it sets a crash flag, and if the driver crashes while initializing, then restarting bsnes will disable the errant driver. If it fails in a recoverable way, then it sets the driver to “None” and warns you that the driver cannot be used. What I'm thinking of further adding is to call emulator→save() to write out the save RAM contents beforehand (although the periodic auto-saving RAM will handle this anyway when it's enabled), and possibly it might be wise to capture an emulator save state, although those can't be taken without advancing the emulator to the next frame, so that might not be a good idea. I'm also thinking we should show some kind of message somewhere when a driver is set to “None”. The status bar can be hidden, so perhaps on the title bar? Or maybe just a warning on startup that a driver is set to “None”.
2018-05-25 08:02:38 +00:00
if(!emulator->loaded()) {
viewport.setGeometry({0, 0, geometry().width(), geometry().height()});
}
uint32_t* output;
uint length;
uint width = viewport.geometry().width();
uint height = viewport.geometry().height();
if(video->lock(output, length, width, height)) {
for(uint y : range(height)) {
auto line = output + y * (length >> 2);
for(uint x : range(width)) *line++ = 0xff000000;
}
Update to v106r27 release. byuu says: Changelog: - nall: merged Path::config() and Path::local() to Path::userData() - ~/.local/share or %appdata or ~/Library/ApplicationSupport - higan, bsnes: render main window icon onto viewport instead of canvas - should hopefully fix a brief flickering glitch that appears on Windows - icarus: improved Super Famicom heuristics for Starfox / Starwing RAM - ruby/Direct3D: handle viewport size changes in lock() instead of output() - fixes icon disappearing when resizing main window - hiro/Windows: remove WS_DISABLED from StatusBar to fix window resize grip - this is experimental: I initially used WS_DISABLED to work around a focus bug - yet trying things now, said bug seems(?) to have gone away at some point ... - bsnes: added advanced settings panel with real-time driver change support I'd like feedback on the real-time driver change, for possible consideration into adding this to higan as well. Some drivers just crash, it's a fact of life. The ASIO driver in particular likes to crash inside the driver itself, without any error messages ever returned to try and catch. When you try to change a driver with a game loaded, it gives you a scary warning, asking if you want to proceed. When you change a driver, it sets a crash flag, and if the driver crashes while initializing, then restarting bsnes will disable the errant driver. If it fails in a recoverable way, then it sets the driver to “None” and warns you that the driver cannot be used. What I'm thinking of further adding is to call emulator→save() to write out the save RAM contents beforehand (although the periodic auto-saving RAM will handle this anyway when it's enabled), and possibly it might be wise to capture an emulator save state, although those can't be taken without advancing the emulator to the next frame, so that might not be a good idea. I'm also thinking we should show some kind of message somewhere when a driver is set to “None”. The status bar can be hidden, so perhaps on the title bar? Or maybe just a warning on startup that a driver is set to “None”.
2018-05-25 08:02:38 +00:00
if(!emulator->loaded()) drawIcon(output, length, width, height);
video->unlock();
video->output();
}
}
auto Presentation::resizeViewport() -> void {
uint windowWidth = geometry().width();
uint windowHeight = geometry().height();
Update to v106r27 release. byuu says: Changelog: - nall: merged Path::config() and Path::local() to Path::userData() - ~/.local/share or %appdata or ~/Library/ApplicationSupport - higan, bsnes: render main window icon onto viewport instead of canvas - should hopefully fix a brief flickering glitch that appears on Windows - icarus: improved Super Famicom heuristics for Starfox / Starwing RAM - ruby/Direct3D: handle viewport size changes in lock() instead of output() - fixes icon disappearing when resizing main window - hiro/Windows: remove WS_DISABLED from StatusBar to fix window resize grip - this is experimental: I initially used WS_DISABLED to work around a focus bug - yet trying things now, said bug seems(?) to have gone away at some point ... - bsnes: added advanced settings panel with real-time driver change support I'd like feedback on the real-time driver change, for possible consideration into adding this to higan as well. Some drivers just crash, it's a fact of life. The ASIO driver in particular likes to crash inside the driver itself, without any error messages ever returned to try and catch. When you try to change a driver with a game loaded, it gives you a scary warning, asking if you want to proceed. When you change a driver, it sets a crash flag, and if the driver crashes while initializing, then restarting bsnes will disable the errant driver. If it fails in a recoverable way, then it sets the driver to “None” and warns you that the driver cannot be used. What I'm thinking of further adding is to call emulator→save() to write out the save RAM contents beforehand (although the periodic auto-saving RAM will handle this anyway when it's enabled), and possibly it might be wise to capture an emulator save state, although those can't be taken without advancing the emulator to the next frame, so that might not be a good idea. I'm also thinking we should show some kind of message somewhere when a driver is set to “None”. The status bar can be hidden, so perhaps on the title bar? Or maybe just a warning on startup that a driver is set to “None”.
2018-05-25 08:02:38 +00:00
if(!emulator->loaded()) {
viewport.setGeometry({0, 0, windowWidth, windowHeight});
return clearViewport();
}
double width = 224 * (settings["View/AspectCorrection"].boolean() ? 8.0 / 7.0 : 1.0);
double height = (settings["View/OverscanCropping"].boolean() ? 224.0 : 240.0);
if(settings["View/IntegralScaling"].boolean()) {
uint widthMultiplier = windowWidth / width;
uint heightMultiplier = windowHeight / height;
uint multiplier = min(widthMultiplier, heightMultiplier);
uint viewportWidth = width * multiplier;
uint viewportHeight = height * multiplier;
viewport.setGeometry({
(windowWidth - viewportWidth) / 2, (windowHeight - viewportHeight) / 2,
viewportWidth, viewportHeight
});
} else {
double widthMultiplier = windowWidth / width;
double heightMultiplier = windowHeight / height;
double multiplier = min(widthMultiplier, heightMultiplier);
uint viewportWidth = width * multiplier;
uint viewportHeight = height * multiplier;
viewport.setGeometry({
(windowWidth - viewportWidth) / 2, (windowHeight - viewportHeight) / 2,
viewportWidth, viewportHeight
});
}
clearViewport();
}
auto Presentation::resizeWindow() -> void {
double width = 224 * (settings["View/AspectCorrection"].boolean() ? 8.0 / 7.0 : 1.0);
double height = (settings["View/OverscanCropping"].boolean() ? 224.0 : 240.0);
uint multiplier = 2;
if(settings["View/Size"].text() == "Small" ) multiplier = 2;
if(settings["View/Size"].text() == "Medium") multiplier = 3;
if(settings["View/Size"].text() == "Large" ) multiplier = 4;
setSize({width * multiplier, height * multiplier});
resizeViewport();
}
auto Presentation::toggleFullscreenMode() -> void {
if(!fullScreen()) {
statusBar.setVisible(false);
menuBar.setVisible(false);
setFullScreen(true);
video->setExclusive(settings["Video/Exclusive"].boolean());
if(video->exclusive()) setVisible(false);
if(!input->acquired()) input->acquire();
} else {
if(input->acquired()) input->release();
if(video->exclusive()) setVisible(true);
video->setExclusive(false);
setFullScreen(false);
menuBar.setVisible(true);
statusBar.setVisible(settings["UserInterface/ShowStatusBar"].boolean());
}
Update to v106r27 release. byuu says: Changelog: - nall: merged Path::config() and Path::local() to Path::userData() - ~/.local/share or %appdata or ~/Library/ApplicationSupport - higan, bsnes: render main window icon onto viewport instead of canvas - should hopefully fix a brief flickering glitch that appears on Windows - icarus: improved Super Famicom heuristics for Starfox / Starwing RAM - ruby/Direct3D: handle viewport size changes in lock() instead of output() - fixes icon disappearing when resizing main window - hiro/Windows: remove WS_DISABLED from StatusBar to fix window resize grip - this is experimental: I initially used WS_DISABLED to work around a focus bug - yet trying things now, said bug seems(?) to have gone away at some point ... - bsnes: added advanced settings panel with real-time driver change support I'd like feedback on the real-time driver change, for possible consideration into adding this to higan as well. Some drivers just crash, it's a fact of life. The ASIO driver in particular likes to crash inside the driver itself, without any error messages ever returned to try and catch. When you try to change a driver with a game loaded, it gives you a scary warning, asking if you want to proceed. When you change a driver, it sets a crash flag, and if the driver crashes while initializing, then restarting bsnes will disable the errant driver. If it fails in a recoverable way, then it sets the driver to “None” and warns you that the driver cannot be used. What I'm thinking of further adding is to call emulator→save() to write out the save RAM contents beforehand (although the periodic auto-saving RAM will handle this anyway when it's enabled), and possibly it might be wise to capture an emulator save state, although those can't be taken without advancing the emulator to the next frame, so that might not be a good idea. I'm also thinking we should show some kind of message somewhere when a driver is set to “None”. The status bar can be hidden, so perhaps on the title bar? Or maybe just a warning on startup that a driver is set to “None”.
2018-05-25 08:02:38 +00:00
//hack: give window geometry time to update after toggling fullscreen and menu/status bars
usleep(20 * 1000);
Application::processEvents();
resizeViewport();
}
auto Presentation::updateRecentGames() -> void {
loadRecentGame.reset();
for(auto index : range(5)) {
MenuItem item;
if(auto game = settings[string{"Game/Recent/", 1 + index}].text()) {
string displayName;
auto games = game.split("|");
for(auto& part : games) {
displayName.append(Location::prefix(part), " + ");
}
displayName.trimRight(" + ", 1L);
item.setText(displayName).onActivate([=] {
program->gameQueue = games;
program->load();
});
} else {
item.setText("<empty>").setEnabled(false);
}
loadRecentGame.append(item);
}
loadRecentGame.append(MenuSeparator());
loadRecentGame.append(MenuItem().setText("Clear List").onActivate([&] {
settings("Game/Recent/1").setValue("");
settings("Game/Recent/2").setValue("");
settings("Game/Recent/3").setValue("");
settings("Game/Recent/4").setValue("");
settings("Game/Recent/5").setValue("");
updateRecentGames();
}));
}
auto Presentation::addRecentGame(string location) -> void {
auto game1 = settings["Game/Recent/1"].text();
auto game2 = settings["Game/Recent/2"].text();
auto game3 = settings["Game/Recent/3"].text();
auto game4 = settings["Game/Recent/4"].text();
auto game5 = settings["Game/Recent/5"].text();
if(game1 == location) {
game1 = location;
} else if(game2 == location) {
game2 = game1;
game1 = location;
} else if(game3 == location) {
game3 = game2;
game2 = game1;
game1 = location;
} else if(game4 == location) {
game4 = game3;
game3 = game2;
game2 = game1;
game1 = location;
} else {
game5 = game4;
game4 = game3;
game3 = game2;
game2 = game1;
game1 = location;
}
settings("Game/Recent/1").setValue(game1);
settings("Game/Recent/2").setValue(game2);
settings("Game/Recent/3").setValue(game3);
settings("Game/Recent/4").setValue(game4);
settings("Game/Recent/5").setValue(game5);
updateRecentGames();
}
auto Presentation::updateShaders() -> void {
shaderMenu.reset();
Group shaders;
MenuRadioItem none{&shaderMenu};
none.setText("None").onActivate([&] {
settings["Video/Shader"].setValue("None");
program->updateVideoShader();
});
shaders.append(none);
MenuRadioItem blur{&shaderMenu};
blur.setText("Blur").onActivate([&] {
settings["Video/Shader"].setValue("Blur");
program->updateVideoShader();
});
shaders.append(blur);
auto location = locate("shaders/");
if(settings["Video/Driver"].text() == "OpenGL") {
for(auto shader : directory::folders(location, "*.shader")) {
if(shaders.objectCount() == 2) shaderMenu.append(MenuSeparator());
MenuRadioItem item{&shaderMenu};
item.setText(string{shader}.trimRight(".shader", 1L)).onActivate([=] {
settings["Video/Shader"].setValue({location, shader});
program->updateVideoShader();
});
shaders.append(item);
}
}
if(settings["Video/Shader"].text() == "None") none.setChecked();
if(settings["Video/Shader"].text() == "Blur") blur.setChecked();
for(auto item : shaders.objects<MenuRadioItem>()) {
if(settings["Video/Shader"].text() == string{location, item.text(), ".shader/"}) {
item.setChecked();
}
}
}