Skip to content

Adding signals support. #1700

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 9, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions src/main/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
***************************************************************************/

#include <csignal>
#include <filesystem>
#include <iostream>
#include <map>
Expand Down Expand Up @@ -191,217 +192,221 @@
// Creating the "system" global object first, making sure anything logging-related is
// enabled as much as possible.
SystemImpl *system = new SystemImpl(args);
PCSX::g_system = system;
auto sigint = std::signal(SIGINT, [](auto signal) { PCSX::g_system->quit(-1); });
auto sigterm = std::signal(SIGTERM, [](auto signal) { PCSX::g_system->quit(-1); });
const auto &logfileArgOpt = args.get<std::string>("logfile");
const PCSX::u8string logfileArg = MAKEU8(logfileArgOpt.has_value() ? logfileArgOpt->c_str() : "");
if (!logfileArg.empty()) system->useLogfile(logfileArg);
PCSX::g_system = system;
std::filesystem::path self = PCSX::BinPath::getExecutablePath();
std::filesystem::path binDir = std::filesystem::absolute(self).parent_path();
system->setBinDir(binDir);
system->loadAllLocales();

// This is another early out, which can only be done once we have a system object.
if (args.get<bool>("version")) {
auto &version = system->getVersion();
if (version.failed()) {
fmt::print("Failed to load version.json\n");
return 1;
}
fmt::print(
"{{\n \"version\": \"{}\",\n \"changeset\": \"{}\",\n \"timestamp\": \"{}\",\n \"timestampDecoded\": "
"\"{:%Y-%m-%d %H:%M:%S}\"\n}}\n",
version.version, version.changeset, version.timestamp, fmt::localtime(version.timestamp));
return 0;
}

// At this point, we're committed to run the emulator, so we first create it, and the UI next.
PCSX::Emulator *emulator = new PCSX::Emulator();
PCSX::g_emulator = emulator;

s_ui = args.get<bool>("no-ui") || args.get<bool>("cli") ? reinterpret_cast<PCSX::UI *>(new PCSX::TUI())
: reinterpret_cast<PCSX::UI *>(new PCSX::GUI());
// Settings will be loaded after this initialization.
s_ui->init([&emulator, &args, &system]() {
// Start tweaking / sanitizing settings a bit, while continuing to parse the command line
// to handle overrides properly.
auto &emuSettings = emulator->settings;
auto &debugSettings = emuSettings.get<PCSX::Emulator::SettingDebugSettings>();
if (emuSettings.get<PCSX::Emulator::SettingMcd1>().empty()) {
emuSettings.get<PCSX::Emulator::SettingMcd1>() = MAKEU8(u8"memcard1.mcd");
}

if (emuSettings.get<PCSX::Emulator::SettingMcd2>().empty()) {
emuSettings.get<PCSX::Emulator::SettingMcd2>() = MAKEU8(u8"memcard2.mcd");
}

auto argPath1 = args.get<std::string>("memcard1");
auto argPath2 = args.get<std::string>("memcard2");
if (argPath1.has_value()) emuSettings.get<PCSX::Emulator::SettingMcd1>() = argPath1.value();
if (argPath2.has_value()) emuSettings.get<PCSX::Emulator::SettingMcd2>() = argPath1.value();
PCSX::u8string path1 = emuSettings.get<PCSX::Emulator::SettingMcd1>().string();
PCSX::u8string path2 = emuSettings.get<PCSX::Emulator::SettingMcd2>().string();

emulator->m_sio->loadMcds(path1, path2);
auto biosCfg = args.get<std::string>("bios");
if (biosCfg.has_value()) emuSettings.get<PCSX::Emulator::SettingBios>() = biosCfg.value();

system->activateLocale(emuSettings.get<PCSX::Emulator::SettingLocale>());

if (args.get<bool>("debugger")) {
debugSettings.get<PCSX::Emulator::DebugSettings::Debug>() = true;
}
if (args.get<bool>("no-debugger")) {
debugSettings.get<PCSX::Emulator::DebugSettings::Debug>() = false;
}

if (args.get<bool>("trace")) {
debugSettings.get<PCSX::Emulator::DebugSettings::Trace>() = true;
}
if (args.get<bool>("no-trace")) {
debugSettings.get<PCSX::Emulator::DebugSettings::Trace>() = false;
}

if (args.get<bool>("8mb")) {
emuSettings.get<PCSX::Emulator::Setting8MB>() = true;
}
if (args.get<bool>("2mb")) {
emuSettings.get<PCSX::Emulator::Setting8MB>() = false;
}

if (args.get<bool>("fastboot")) {
emuSettings.get<PCSX::Emulator::SettingFastBoot>() = true;
}
if (args.get<bool>("no-fastboot")) {
emuSettings.get<PCSX::Emulator::SettingFastBoot>() = false;
}

if (args.get<bool>("gdb")) {
debugSettings.get<PCSX::Emulator::DebugSettings::GdbServer>() = true;
}
if (args.get<bool>("no-gdb")) {
debugSettings.get<PCSX::Emulator::DebugSettings::GdbServer>() = false;
}

if (args.get<int>("gdb-port")) {
debugSettings.get<PCSX::Emulator::DebugSettings::GdbServerPort>() = args.get<int>("gdb-port").value();
}

auto argPCdrvBase = args.get<std::string>("pcdrvbase");
if (args.get<bool>("pcdrv")) {
debugSettings.get<PCSX::Emulator::DebugSettings::PCdrv>() = true;
}
if (args.get<bool>("no-pcdrv")) {
debugSettings.get<PCSX::Emulator::DebugSettings::PCdrv>() = false;
}
if (argPCdrvBase.has_value()) {
debugSettings.get<PCSX::Emulator::DebugSettings::PCdrvBase>() = argPCdrvBase.value();
}

if (args.get<bool>("dynarec")) {
emuSettings.get<PCSX::Emulator::SettingDynarec>() = true;
}
if (args.get<bool>("interpreter")) {
emuSettings.get<PCSX::Emulator::SettingDynarec>() = false;
}

if (args.get<bool>("openglgpu")) {
emuSettings.get<PCSX::Emulator::SettingHardwareRenderer>() = true;
}

if (args.get<bool>("softgpu")) {
emuSettings.get<PCSX::Emulator::SettingHardwareRenderer>() = false;
}

if (args.get<bool>("kiosk")) {
emuSettings.get<PCSX::Emulator::SettingKioskMode>() = true;
}
if (args.get<bool>("no-kiosk")) {
emuSettings.get<PCSX::Emulator::SettingKioskMode>() = false;
}
});

// Now it's time to mount our iso filesystem
std::filesystem::path isoToOpen = args.get<std::string>("iso", "");
if (isoToOpen.empty()) isoToOpen = args.get<std::string>("loadiso", "");
if (isoToOpen.empty()) isoToOpen = args.get<std::string>("disk", "");
if (!isoToOpen.empty()) emulator->m_cdrom->setIso(new PCSX::CDRIso(isoToOpen));
emulator->m_cdrom->check();

// After settings are loaded, we're fine setting the SPU part of the emulation.
emulator->m_spu->init();

// Make sure the Lua environment is set.
bool luacovEnabled = false;
if (args.get<bool>("luacov")) {
auto L = *emulator->m_lua;
L.load(
"package.path = package.path .. "
"';./lua_modules/share/lua/5.1/?.lua;../../../third_party/luacov/src/?.lua;./third_party/luacov/src/?.lua'",
"internal:package.path.lua");
try {
L.load(R"(
local runner = require 'luacov.runner'
runner.init({
nameparser = function(name)
if name:sub(1, 4) == 'src:' then
return 'src/' .. name:sub(5)
elseif name:sub(1, 12) == 'third_party:' then
return 'third_party/' .. name:sub(13)
end
return nil
end,
}))",
"internal:luacov.lua");
luacovEnabled = true;
} catch (...) {
luacovEnabled = false;
}
}
emulator->setLua();
s_ui->setLua(*emulator->m_lua);
emulator->m_spu->setLua(*emulator->m_lua);
assert(emulator->m_lua->gettop() == 0);

// Starting up the whole emulator; we delay setting the GPU only now because why not.
auto &emuSettings = emulator->settings;
emulator->m_spu->open();
emulator->init();
emulator->m_gpu->init(s_ui);
emulator->m_gpu->setDither(emuSettings.get<PCSX::Emulator::SettingDither>());
emulator->m_gpu->setCachedDithering(emuSettings.get<PCSX::Emulator::SettingCachedDithering>());
emulator->m_gpu->setLinearFiltering();
emulator->reset();

// Looking at setting up what to run exactly within the emulator, if requested.
if (args.get<bool>("run")) system->resume();
s_ui->m_exeToLoad.set(MAKEU8(args.get<std::string>("loadexe", "").c_str()));
if (s_ui->m_exeToLoad.empty()) s_ui->m_exeToLoad.set(MAKEU8(args.get<std::string>("exe", "").c_str()));

// And finally, let's run things.
int exitCode = 0;
{
// First, set up a closer. This makes sure that everything is shut down gracefully,
// in the right order, once we exit the scope. This is because of how we're still
// allowing exceptions to occur.
Cleaner cleaner([&emulator, &system, &exitCode, luacovEnabled]() {
Cleaner cleaner([&emulator, &system, &exitCode, luacovEnabled, sigint, sigterm]() {
emulator->m_spu->close();
emulator->m_cdrom->clearIso();

emulator->m_spu->shutdown();
emulator->m_gpu->shutdown();
emulator->shutdown();
s_ui->close();
delete s_ui;

if (luacovEnabled) {
auto L = *emulator->m_lua;
L.load("(require 'luacov.runner').shutdown()", "internal:luacov-shutdown.lua");
}

delete emulator;
PCSX::g_emulator = nullptr;

exitCode = system->exitCode();
std::signal(SIGINT, sigint);
std::signal(SIGTERM, sigterm);

Check warning on line 409 in src/main/main.cc

View check run for this annotation

CodeScene Delta Analysis / CodeScene Cloud Delta Analysis (main)

❌ Getting worse: Complex Method

pcsxMain already has high cyclomatic complexity, and now it increases in Lines of Code from 228 to 232. This function has many conditional statements (e.g. if, for, while), leading to lower code health. Avoid adding more conditionals and code to it without refactoring.
delete system;
PCSX::g_system = nullptr;
});
Expand Down
Loading