GPCS4/GPCS4/GPCS4Main.cpp
2022-07-17 03:38:28 +08:00

89 lines
1.8 KiB
C++

#include "Emulator.h"
#include "Emulator/SceModuleSystem.h"
#include "Emulator/TLSHandler.h"
#include "Loader/ModuleLoader.h"
#include <cxxopts/cxxopts.hpp>
#include <memory>
LOG_CHANNEL(Main);
cxxopts::ParseResult processCommandLine(int argc, char* argv[])
{
cxxopts::Options opts("GPCS4", "PlayStation 4 Emulator");
opts.allow_unrecognised_options();
opts.add_options()("E,eboot", "Set main executable. The current working directory will be mapped to /app0.", cxxopts::value<std::string>())
("D,debug-channel", "Enable debug channel. 'ALL' for all channels.", cxxopts::value<std::vector<std::string>>())
("L,list-channels", "List debug channels.")
("H,help", "Print help message.");
// Backup arg count,
// because cxxopts will change argc value internally,
// which I think is a bad design.
const uint32_t argCount = argc;
auto optResult = opts.parse(argc, argv);
if (optResult.count("H") || argCount < 2)
{
auto helpString = opts.help();
printf("%s\n", helpString.c_str());
exit(-1);
}
return optResult;
}
int main(int argc, char* argv[])
{
int nRet = -1;
do
{
auto optResult = processCommandLine(argc, argv);
// Initialize log system.
logsys::init(optResult);
if (!optResult["E"].count())
{
break;
}
// Initialize the whole emulator.
LOG_DEBUG("GPCS4 start.");
if (!TheEmulator().Init())
{
break;
}
if (!installTLSManager())
{
break;
}
CLinker linker = { *CSceModuleSystem::instance() };
ModuleLoader loader = { *CSceModuleSystem::instance(), linker };
auto eboot = optResult["E"].as<std::string>();
NativeModule* ebootModule = nullptr;
if (!loader.loadModule(eboot, &ebootModule))
{
break;
}
if (!TheEmulator().Run(*ebootModule))
{
break;
}
uninstallTLSManager();
TheEmulator().Unit();
nRet = 0;
} while (false);
return nRet;
}