#include #include #include #include #include KaizenGui::KaizenGui() noexcept : window("Kaizen", 800, 600), core(std::make_shared()), vulkanWidget(core, window.getHandle()), emuThread(core, fpsCounter, vulkanWidget, settingsWindow) { gui::Initialize(core->parallel.wsi, window.getHandle()); emuExitFunc = [&]() { quit = true; if (emuThread.isRunning) { emuThread.requestInterruption(); while (emuThread.isRunning) {} } }; about.setFunc([&]() { ImGui::Text("Kaizen is a Nintendo 64 emulator that strives"); ImGui::Text("to offer a friendly user experience and compatibility."); ImGui::Text("Kaizen is licensed under the BSD 3-clause license."); ImGui::Text("Nintendo 64 is a registered trademark of Nintendo Co., Ltd."); if(ImGui::Button("OK")) { about.setOpened(false); ImGui::CloseCurrentPopup(); } }); statusBar.setFunc([&]() { ImGui::Text("GUI FPS: %.2f, Emulation FPS: %s", ImGui::GetIO().Framerate, fmt::format(fpsCounter > 0 ? fmt::runtime("{0:.2f}") : fmt::runtime("{1}"), fpsCounter, "Not playing").c_str()); }); menuBar.addMenu({"File", { {"Open", [&]() { NFD::Guard guard; NFD::UniquePath path; nfdfilteritem_t filterItem = {"Nintendo 64 roms", "n64,z64,v64,N64,Z64,V64"}; auto result = NFD::OpenDialog(path, &filterItem, 1); if(result == NFD_CANCEL) return; if(result == NFD_ERROR) Util::panic("Error: {}", NFD::GetError()); LoadROM(path.get()); }}, {"Exit", std::move(emuExitFunc)} } }); menuBar.addMenu({ "Emulation", { actionPause, actionStop, actionReset, {"Settings", [&]() { settingsWindow.popup.setOpened(true); }}, }}); menuBar.addMenu({ "Help", { {"About", [&]() { about.setOpened(true); }}, }}); } void KaizenGui::RenderUI() { gui::StartFrame(); menuBar.render(); about.render(); statusBar.render(); settingsWindow.render(); gui::EndFrame(); if (core->render) { core->parallel.UpdateScreen(core->cpu->GetMem().mmio.vi); } else { core->parallel.UpdateScreen(core->cpu->GetMem().mmio.vi, false); } } void KaizenGui::LoadROM(const std::string &path) noexcept { actionPause.setEnabled(true); actionReset.setEnabled(true); actionStop.setEnabled(true); emuThread.start(); emuThread.core->LoadROM(path); const auto gameNameDB = emuThread.core->cpu->GetMem().rom.gameNameDB; Util::RPC::GetInstance().Update(Util::RPC::Playing, gameNameDB); } int KaizenGui::run() { while(!quit) { if(vulkanWidget.wsiPlatform->quitRequested) { emuExitFunc(); } RenderUI(); } return 0; } void KaizenGui::LoadTAS(const std::string &path) const noexcept { if (emuThread.core->LoadTAS(fs::path(path))) { const auto gameNameDB = emuThread.core->cpu->GetMem().rom.gameNameDB; const auto movieName = fs::path(path).stem().string(); Util::RPC::GetInstance().Update(Util::RPC::MovieReplay, gameNameDB, movieName); return; } Util::panic("Could not load TAS movie {}!", path); }