2022-04-06 09:24:53 -04:00
|
|
|
#include "Emulator.h"
|
2019-09-28 01:43:05 -04:00
|
|
|
#include "Emulator/SceModuleSystem.h"
|
2019-10-06 00:35:18 -04:00
|
|
|
#include "Emulator/TLSHandler.h"
|
2020-02-01 06:33:38 -05:00
|
|
|
#include "Loader/ModuleLoader.h"
|
2019-10-06 00:35:18 -04:00
|
|
|
|
2020-02-01 06:33:38 -05:00
|
|
|
#include <cxxopts/cxxopts.hpp>
|
2019-06-20 13:35:04 -04:00
|
|
|
#include <memory>
|
|
|
|
|
2020-02-01 07:42:36 -05:00
|
|
|
LOG_CHANNEL(Main);
|
2020-01-11 18:34:41 -05:00
|
|
|
|
2020-02-01 06:33:38 -05:00
|
|
|
cxxopts::ParseResult processCommandLine(int argc, char* argv[])
|
2019-06-20 13:35:04 -04:00
|
|
|
{
|
2020-02-01 06:33:38 -05:00
|
|
|
cxxopts::Options opts("GPCS4", "PlayStation 4 Emulator");
|
2020-02-01 07:40:25 -05:00
|
|
|
opts.allow_unrecognised_options();
|
2022-07-12 15:51:22 -04:00
|
|
|
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.");
|
2020-02-01 07:40:25 -05:00
|
|
|
|
2020-02-02 10:08:54 -05:00
|
|
|
// Backup arg count,
|
|
|
|
// because cxxopts will change argc value internally,
|
|
|
|
// which I think is a bad design.
|
|
|
|
const uint32_t argCount = argc;
|
2020-02-01 07:40:25 -05:00
|
|
|
|
2022-03-24 14:31:58 -04:00
|
|
|
auto optResult = opts.parse(argc, argv);
|
2020-02-02 10:08:54 -05:00
|
|
|
if (optResult.count("H") || argCount < 2)
|
2020-02-01 07:40:25 -05:00
|
|
|
{
|
|
|
|
auto helpString = opts.help();
|
|
|
|
printf("%s\n", helpString.c_str());
|
|
|
|
exit(-1);
|
|
|
|
}
|
2019-06-20 13:35:04 -04:00
|
|
|
|
2020-02-01 07:40:25 -05:00
|
|
|
return optResult;
|
2020-02-01 06:33:38 -05:00
|
|
|
}
|
|
|
|
|
2022-03-24 14:31:58 -04:00
|
|
|
int main(int argc, char* argv[])
|
2020-02-01 06:33:38 -05:00
|
|
|
{
|
2022-03-24 18:37:37 -04:00
|
|
|
int nRet = -1;
|
2020-02-01 06:33:38 -05:00
|
|
|
|
2019-10-06 00:35:18 -04:00
|
|
|
do
|
2019-06-20 13:35:04 -04:00
|
|
|
{
|
2020-02-01 06:33:38 -05:00
|
|
|
auto optResult = processCommandLine(argc, argv);
|
|
|
|
|
2020-02-01 07:42:36 -05:00
|
|
|
// Initialize log system.
|
|
|
|
logsys::init(optResult);
|
|
|
|
|
2020-02-01 07:40:25 -05:00
|
|
|
if (!optResult["E"].count())
|
2019-07-10 03:41:32 -04:00
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
2020-02-01 06:33:38 -05:00
|
|
|
|
|
|
|
// Initialize the whole emulator.
|
2019-07-10 03:41:32 -04:00
|
|
|
|
2020-02-01 06:33:38 -05:00
|
|
|
LOG_DEBUG("GPCS4 start.");
|
2019-07-10 03:41:32 -04:00
|
|
|
|
2022-03-24 18:37:37 -04:00
|
|
|
if (!TheEmulator().Init())
|
2019-06-20 13:35:04 -04:00
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2020-01-11 18:34:41 -05:00
|
|
|
if (!installTLSManager())
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
2019-10-06 00:35:18 -04:00
|
|
|
|
2022-07-16 15:38:28 -04:00
|
|
|
CLinker linker = { *CSceModuleSystem::instance() };
|
|
|
|
ModuleLoader loader = { *CSceModuleSystem::instance(), linker };
|
2019-10-06 00:35:18 -04:00
|
|
|
|
2022-03-24 14:31:58 -04:00
|
|
|
auto eboot = optResult["E"].as<std::string>();
|
|
|
|
NativeModule* ebootModule = nullptr;
|
2020-02-01 06:33:38 -05:00
|
|
|
if (!loader.loadModule(eboot, &ebootModule))
|
2019-10-06 00:35:18 -04:00
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2022-03-24 18:37:37 -04:00
|
|
|
if (!TheEmulator().Run(*ebootModule))
|
2019-06-20 13:35:04 -04:00
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
2019-10-04 02:37:30 -04:00
|
|
|
|
2020-01-11 18:34:41 -05:00
|
|
|
uninstallTLSManager();
|
2022-03-24 18:37:37 -04:00
|
|
|
TheEmulator().Unit();
|
2022-03-24 14:31:58 -04:00
|
|
|
|
2019-06-20 13:35:04 -04:00
|
|
|
nRet = 0;
|
|
|
|
} while (false);
|
|
|
|
|
|
|
|
return nRet;
|
2019-11-23 22:18:11 -05:00
|
|
|
}
|