#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()); actionPause.setFunc([&]() { if(ImGui::IsItemClicked()) { actionPause.setLabel(actionPause.getLabel() == "Pause" ? "Resume" : "Pause"); core->TogglePause(); } }); actionStop.setFunc([&]() { if(ImGui::IsItemClicked()) { actionStop.setEnabled(false); actionPause.setEnabled(false); actionReset.setEnabled(false); core->Stop(); } }); 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; static const std::vector filterItems = { {"Nintendo 64 rom archive", "rar,RAR,tar,TAR,zip,ZIP,7z,7Z"}, {"Nintendo 64 rom", "n64,z64,v64,N64,Z64,V64"} }; auto result = NFD::OpenDialog(path, filterItems.data(), filterItems.size()); if(result == NFD_CANCEL) return; if(result == NFD_ERROR) Util::panic("Error: {}", NFD::GetError()); LoadROM(path.get()); }}, {"Exit", [&]() { quit = true; emuThread.Stop(); }} } }); menuBar.addMenu({ "Emulation", { actionPause, actionStop, actionReset, {"Settings", [&]() { settingsWindow.popup.setOpened(true); }}, }}); menuBar.addMenu({ "Help", { {"About", [&]() { about.setOpened(true); }}, }}); } KaizenGui::~KaizenGui() { gui::Cleanup(); } void KaizenGui::RenderUI() { gui::StartFrame(); statusBar.render(); menuBar.render(); settingsWindow.render(); about.render(); ImGui::Render(); if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable){ ImGui::UpdatePlatformWindows(); ImGui::RenderPlatformWindowsDefault(); } if(!core->pause) { core->parallel.UpdateScreen(*core.get()); return; } core->parallel.UpdateScreen(*core.get(), false); } void KaizenGui::LoadROM(const std::string &path) noexcept { actionPause.setEnabled(true); actionReset.setEnabled(true); actionStop.setEnabled(true); emuThread.core->LoadROM(path); const auto gameNameDB = emuThread.core->cpu->GetMem().rom.gameNameDB; Util::RPC::GetInstance().Update(Util::RPC::Playing, gameNameDB); } void KaizenGui::run() { while(!quit) { emuThread.run(); SDL_Event e; while (SDL_PollEvent(&e)) { ImGui_ImplSDL3_ProcessEvent(&e); switch(e.type) { case SDL_EVENT_QUIT: quit = true; emuThread.Stop(); break; } } RenderUI(); } } 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); }