Factorizing some Lua out of UI, forcing the tests to use -no-ui, and trying to set up the CIs accordingly.

This commit is contained in:
Nicolas Pixel Noble 2023-04-07 19:19:02 -07:00
parent 6f7f2f8c0d
commit 394d0f8ff9
15 changed files with 132 additions and 63 deletions

View file

@ -24,10 +24,19 @@ jobs:
- name: Build OpenBIOS
run: make -C src/mips/openbios -j2
- name: Upload results for MacOS build job
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: OpenBIOS
path: src/mips/openbios/openbios.bin
- name: Build tests
run: |
make -C src/mips/openbios -j 2 clean
make -C src/mips/tests -j 2 PCSX_TESTS=true
- name: Upload results for MacOS build job
uses: actions/upload-artifact@v3
with:
name: tests
path: **/*.ps-exe
macos-build-and-test:
runs-on: macOS-latest
@ -41,12 +50,22 @@ jobs:
run: ./.github/scripts/install-brew-dependencies.sh
- name: Fetch submodules
run: git submodule update --init --recursive
- name: Build pcsx-redux
run: make -j2
- name: Build PCSX-Redux
run: make -j 2 all pcsx-redux-tests
- name: Download OpenBIOS build
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: OpenBIOS
- name: Download mips tests
uses: actions/download-artifact@v3
with:
name: tests
- name: Test
run: |
export GTEST_OUTPUT=xml:/tmp/test-results/
mkdir -p /tmp/test-results
cp openbios.bin src/mips/openbios/
./pcsx-redux-tests
- name: Bundle
run: ./.github/scripts/create-app.sh
- name: Create BUILD environment

View file

@ -71,7 +71,6 @@ steps:
**\*.exe
!**\exe2elf.exe
!**\exe2iso.exe
!**\pcsxrunner.exe
!**\pcsx-wrapper.exe
!**\pcsx-redux.exe
!**\psyq-obj-parser.exe

View file

@ -172,3 +172,13 @@ steps:
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
ArtifactName: 'bios'
publishLocation: 'Container'
- task: Bash@3
inputs:
filePath: 'dockermake.sh'
arguments: '-C src/mips/openbios -j deepclean'
- task: Bash@3
inputs:
filePath: 'dockermake.sh'
arguments: '-C src/mips/tests -j 2 PCSX_TESTS=true'

View file

@ -79,7 +79,6 @@ steps:
**\*.exe
!**\exe2elf.exe
!**\exe2iso.exe
!**\pcsxrunner.exe
!**\pcsx-redux.main
!**\pcsx-redux.exe
!**\psyq-obj-parser.exe

View file

@ -147,8 +147,6 @@ class Emulator {
type;
};
typedef SettingNested<TYPESTRING("Debug"), DebugSettings::type> SettingDebugSettings;
typedef Setting<bool, TYPESTRING("Stdout")> SettingStdout;
typedef SettingPath<TYPESTRING("Logfile")> SettingLogfile;
typedef SettingPath<TYPESTRING("Mcd1")> SettingMcd1;
typedef SettingPath<TYPESTRING("Mcd2")> SettingMcd2;
typedef SettingPath<TYPESTRING("Bios")> SettingBios;
@ -186,7 +184,7 @@ class Emulator {
typedef SettingPath<TYPESTRING("EXP1BrowsePath")> SettingEXP1BrowsePath;
typedef Setting<bool, TYPESTRING("PIOConnected")> SettingPIOConnected;
Settings<SettingStdout, SettingLogfile, SettingMcd1, SettingMcd2, SettingBios, SettingPpfDir, SettingPsxExe,
Settings<SettingMcd1, SettingMcd2, SettingBios, SettingPpfDir, SettingPsxExe,
SettingXa, SettingSpuIrq, SettingBnWMdec, SettingScaler, SettingAutoVideo, SettingVideo, SettingFastBoot,
SettingDebugSettings, SettingRCntFix, SettingIsoPath, SettingLocale, SettingMcd1Inserted,
SettingMcd2Inserted, SettingDynarec, Setting8MB, SettingGUITheme, SettingDither, SettingGLErrorReporting,

View file

@ -53,3 +53,34 @@ void PCSX::UI::finishLoadSettings() {
g_system->activateLocale(emuSettings.get<Emulator::SettingLocale>());
g_system->m_eventBus->signal(Events::SettingsLoaded{safeMode});
}
void PCSX::UI::setLuaCommon(Lua L) {
L.load(R"(
print("PCSX-Redux Lua Console")
print(jit.version)
print((function(status, ...)
local ret = "JIT: " .. (status and "ON" or "OFF")
for i, v in ipairs({...}) do
ret = ret .. " " .. v
end
return ret
end)(jit.status()))
)",
"ui startup");
}
void PCSX::UI::tick() {
uv_run(g_system->getLoop(), UV_RUN_NOWAIT);
auto L = *g_emulator->m_lua;
L.getfield("AfterPollingCleanup", LUA_GLOBALSINDEX);
if (!L.isnil()) {
try {
L.pcall();
} catch (...) {
}
L.push();
L.setfield("AfterPollingCleanup", LUA_GLOBALSINDEX);
} else {
L.pop();
}
}

View file

@ -65,6 +65,8 @@ class UI {
bool loadSettings();
void finishLoadSettings();
void setLuaCommon(Lua L);
void tick();
};
} // namespace PCSX

View file

@ -280,18 +280,7 @@ void PCSX::GUI::glErrorCallback(GLenum source, GLenum type, GLuint id, GLenum se
}
void PCSX::GUI::setLua(Lua L) {
L.load(R"(
print("PCSX-Redux Lua Console")
print(jit.version)
print((function(status, ...)
local ret = "JIT: " .. (status and "ON" or "OFF")
for i, v in ipairs({...}) do
ret = ret .. " " .. v
end
return ret
end)(jit.status()))
)",
"gui startup");
setLuaCommon(L);
LoadImguiBindings(L.getState());
LuaFFI::open_gl(L);
L.getfieldtable("PCSX", LUA_GLOBALSINDEX);
@ -667,19 +656,7 @@ void PCSX::GUI::glfwKeyCallback(GLFWwindow* window, int key, int scancode, int a
void PCSX::GUI::startFrame() {
ZoneScoped;
uv_run(g_system->getLoop(), UV_RUN_NOWAIT);
auto L = *g_emulator->m_lua;
L.getfield("AfterPollingCleanup", LUA_GLOBALSINDEX);
if (!L.isnil()) {
try {
L.pcall();
} catch (...) {
}
L.push();
L.setfield("AfterPollingCleanup", LUA_GLOBALSINDEX);
} else {
L.pop();
}
tick();
if (glfwWindowShouldClose(m_window)) g_system->quit();
glfwPollEvents();

View file

@ -81,7 +81,7 @@ class SystemImpl final : public PCSX::System {
if (!m_noGuiLog) {
s_ui->addLuaLog(s, error);
}
if ((error && m_inStartup) || args.get<bool>("lua_stdout", false)) {
if ((error && m_inStartup) || args.get<bool>("lua_stdout", false) || args.get<bool>("no-ui", false)) {
if (error) {
fprintf(stderr, "%s\n", s.c_str());
} else {
@ -169,11 +169,13 @@ struct Cleaner {
int pcsxMain(int argc, char **argv) {
ZoneScoped;
// Command line arguments are parsed after this point.
const CommandLine::args args(argc, argv);
// The UvFile and UvFifo should work past this point.
PCSX::UvThreadOp::UvThread uvThread;
#if defined(_WIN32) || defined(_WIN64)
if (args.get<bool>("stdout")) {
if (args.get<bool>("stdout", false) || args.get<bool>("no-ui", false)) {
if (AllocConsole()) {
freopen("CONIN$", "r", stdin);
freopen("CONOUT$", "w", stdout);
@ -182,20 +184,24 @@ int pcsxMain(int argc, char **argv) {
}
#endif
// This is an easy early-out.
if (args.get<bool>("dumpproto")) {
PCSX::SaveStates::ProtoFile::dumpSchema(std::cout);
return 0;
}
// Creating the "system" global object first, making sure anything logging-related is
// enabled as much as possible.
SystemImpl *system = new SystemImpl(args);
if (args.get<bool>("testmode").value_or(false)) {
if (args.get<bool>("testmode", false)) {
system->setTestmode();
}
if (args.get<bool>("stdout").value_or(false)) system->m_enableStdout = true;
if (args.get<bool>("stdout", false) && !args.get<bool>("tui", false)) system->m_enableStdout = true;
if (args.get<bool>("no-ui", false)) system->m_enableStdout = true;
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);
if (args.get<bool>("testmode").value_or(false) || args.get<bool>("no-gui-log").value_or(false)) {
if (args.get<bool>("testmode", false) || args.get<bool>("no-gui-log", false)) {
system->m_noGuiLog = true;
}
PCSX::g_system = system;
@ -204,7 +210,8 @@ int pcsxMain(int argc, char **argv) {
system->setBinDir(binDir);
system->loadAllLocales();
if (args.get<bool>("version").value_or(false)) {
// This is another early out, which can only be done once we have a system object.
if (args.get<bool>("version", false)) {
auto &version = system->getVersion();
if (version.failed()) {
fmt::print("Failed to load version.json\n");
@ -217,12 +224,18 @@ int pcsxMain(int argc, char **argv) {
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").value_or(false) ? reinterpret_cast<PCSX::UI *>(new PCSX::TUI(args))
: reinterpret_cast<PCSX::UI *>(new PCSX::GUI(args));
s_ui = args.get<bool>("no-ui", false) ? reinterpret_cast<PCSX::UI *>(new PCSX::TUI(args))
: reinterpret_cast<PCSX::UI *>(new PCSX::GUI(args));
// Settings will be loaded after this initialization.
s_ui->init();
// After settings are loaded, we're fine setting the SPU part of the emulation.
emulator->m_spu->init();
// 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()) {
@ -266,6 +279,7 @@ int pcsxMain(int argc, char **argv) {
emuSettings.get<PCSX::Emulator::Setting8MB>().value = true;
}
// Now it's time to mount our filesystems; iso and pcdrv.
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", "");
@ -279,32 +293,31 @@ int pcsxMain(int argc, char **argv) {
debugSettings.get<PCSX::Emulator::DebugSettings::PCdrvBase>().value = argPCdrvBase.value();
}
if (!args.get<bool>("stdout", false)) {
system->m_enableStdout = emulator->settings.get<PCSX::Emulator::SettingStdout>();
}
const PCSX::u8string &logfileSet = emulator->settings.get<PCSX::Emulator::SettingLogfile>().string();
if (logfileArg.empty() && !logfileSet.empty()) system->useLogfile(logfileSet);
// Make sure the Lua environment is set.
emulator->setLua();
s_ui->setLua(*emulator->m_lua);
emulator->m_spu->init();
emulator->m_spu->setLua(*emulator->m_lua);
emulator->m_spu->open();
assert(emulator->m_lua->gettop() == 0);
// Starting up the whole emulator; we delay setting the GPU only now because why not.
emulator->m_spu->open();
emulator->init();
emulator->m_gpu->init(s_ui);
emulator->m_gpu->setDither(emuSettings.get<PCSX::Emulator::SettingDither>());
emulator->m_gpu->setLinearFiltering();
emulator->reset();
// Looking at setting up what to run exactly within the emulator, if requested.
if (args.get<bool>("run", false)) 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()));
assert(emulator->m_lua->gettop() == 0);
auto luaexecs = args.values("exec");
// 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]() {
emulator->m_spu->close();
emulator->m_cdrom->clearIso();
@ -323,6 +336,9 @@ int pcsxMain(int argc, char **argv) {
PCSX::g_system = nullptr;
});
try {
// Before going into the main loop, let's run all of the Lua "exec" commands
// specified on the command line.
auto luaexecs = args.values("exec");
for (auto &luaexec : luaexecs) {
try {
emulator->m_lua->load(luaexec.data(), "cmdline", false);
@ -334,14 +350,23 @@ int pcsxMain(int argc, char **argv) {
system->m_inStartup = false;
// And finally, main loop.
while (!system->quitting()) {
if (system->running()) {
// This will run until paused or interrupted somehow.
emulator->m_cpu->Execute();
} else {
// The "update" method will be called periodically by the emulator while
// meaning if we want our UI to work, we have to manually call "update"
// when the emulator is paused.
s_ui->update();
}
}
} catch (...) {
// This will ensure we don't do certain cleanups that are awaiting other tasks,
// which could result in deadlocks on exit in case we encountered a serious problem.
// This may cause data loss when writing files, but that's life when encountering
// a serious problem in a software.
system->setEmergencyExit();
uvThread.setEmergencyExit();
throw;

View file

@ -19,6 +19,9 @@
#include "main/textui.h"
#include <chrono>
#include <thread>
PCSX::TUI::TUI(const CommandLine::args &args) : UI(args) {}
PCSX::TUI::~TUI() {}
@ -31,10 +34,16 @@ void PCSX::TUI::init() {
finishLoadSettings();
}
void PCSX::TUI::setLua(Lua L) {}
void PCSX::TUI::setLua(Lua L) { setLuaCommon(L); }
void PCSX::TUI::close() {}
void PCSX::TUI::update(bool vsync) {}
void PCSX::TUI::update(bool vsync) {
tick();
if (!g_system->running()) {
using namespace std::chrono_literals;
std::this_thread::sleep_for(10ms);
}
}
void PCSX::TUI::addNotification(const std::string &notification) {}

View file

@ -21,14 +21,14 @@
#include "main/main.h"
TEST(Basic, Interpreter) {
MainInvoker invoker("-run", "-stdout", "-bios", "src/mips/openbios/openbios.bin", "-testmode", "-interpreter",
MainInvoker invoker("-no-ui", "-run", "-bios", "src/mips/openbios/openbios.bin", "-testmode", "-interpreter",
"-loadexe", "src/mips/tests/basic/basic.ps-exe");
int ret = invoker.invoke();
EXPECT_EQ(ret, 0);
}
TEST(Basic, Dynarec) {
MainInvoker invoker("-run", "-stdout", "-bios", "src/mips/openbios/openbios.bin", "-testmode", "-dynarec",
MainInvoker invoker("-no-ui", "-run", "-bios", "src/mips/openbios/openbios.bin", "-testmode", "-dynarec",
"-loadexe", "src/mips/tests/basic/basic.ps-exe");
int ret = invoker.invoke();
EXPECT_EQ(ret, 0);

View file

@ -21,7 +21,7 @@
#include "main/main.h"
TEST(COP0, Interpreter) {
MainInvoker invoker("-run", "-stdout", "-bios", "src/mips/openbios/openbios.bin", "-testmode", "-interpreter",
MainInvoker invoker("-no-ui", "-run", "-bios", "src/mips/openbios/openbios.bin", "-testmode", "-interpreter",
"-debugger", "-loadexe", "src/mips/tests/cop0/cop0.ps-exe");
int ret = invoker.invoke();
EXPECT_EQ(ret, 0);

View file

@ -21,14 +21,14 @@
#include "main/main.h"
TEST(CPU, Interpreter) {
MainInvoker invoker("-run", "-stdout", "-bios", "src/mips/openbios/openbios.bin", "-testmode", "-interpreter",
MainInvoker invoker("-no-ui", "-run", "-bios", "src/mips/openbios/openbios.bin", "-testmode", "-interpreter",
"-loadexe", "src/mips/tests/cpu/cpu.ps-exe");
int ret = invoker.invoke();
EXPECT_EQ(ret, 0);
}
TEST(CPU, Dynarec) {
MainInvoker invoker("-run", "-stdout", "-bios", "src/mips/openbios/openbios.bin", "-testmode", "-dynarec",
MainInvoker invoker("-no-ui", "-run", "-bios", "src/mips/openbios/openbios.bin", "-testmode", "-dynarec",
"-loadexe", "src/mips/tests/cpu/cpu.ps-exe");
int ret = invoker.invoke();
EXPECT_EQ(ret, 0);

View file

@ -21,14 +21,14 @@
#include "main/main.h"
TEST(libc, Interpreter) {
MainInvoker invoker("-run", "-stdout", "-bios", "src/mips/openbios/openbios.bin", "-testmode", "-interpreter",
MainInvoker invoker("-no-ui", "-run", "-bios", "src/mips/openbios/openbios.bin", "-testmode", "-interpreter",
"-loadexe", "src/mips/tests/libc/libc.ps-exe");
int ret = invoker.invoke();
EXPECT_EQ(ret, 0);
}
TEST(libc, Dynarec) {
MainInvoker invoker("-run", "-stdout", "-bios", "src/mips/openbios/openbios.bin", "-testmode", "-dynarec",
MainInvoker invoker("-no-ui", "-run", "-bios", "src/mips/openbios/openbios.bin", "-testmode", "-dynarec",
"-loadexe", "src/mips/tests/libc/libc.ps-exe");
int ret = invoker.invoke();
EXPECT_EQ(ret, 0);

View file

@ -21,14 +21,14 @@
#include "main/main.h"
TEST(PCdrv, Interpreter) {
MainInvoker invoker("-run", "-stdout", "-pcdrv", "-pcdrvbase", ".", "-bios", "src/mips/openbios/openbios.bin",
MainInvoker invoker("-no-ui", "-run", "-pcdrv", "-pcdrvbase", ".", "-bios", "src/mips/openbios/openbios.bin",
"-testmode", "-interpreter", "-loadexe", "src/mips/tests/pcdrv/pcdrv.ps-exe");
int ret = invoker.invoke();
EXPECT_EQ(ret, 0);
}
TEST(PCdrv, Dynarec) {
MainInvoker invoker("-run", "-stdout", "-pcdrv", "-pcdrvbase", ".", "-bios", "src/mips/openbios/openbios.bin",
MainInvoker invoker("-no-ui", "-run", "-pcdrv", "-pcdrvbase", ".", "-bios", "src/mips/openbios/openbios.bin",
"-testmode", "-dynarec", "-loadexe", "src/mips/tests/pcdrv/pcdrv.ps-exe");
int ret = invoker.invoke();
EXPECT_EQ(ret, 0);