attempt moving core to separate thread again
This commit is contained in:
+34
-31
@@ -1,52 +1,55 @@
|
|||||||
#include <Core.hpp>
|
#include <Core.hpp>
|
||||||
#include <EmuThread.hpp>
|
#include <EmuThread.hpp>
|
||||||
#include <KaizenGui.hpp>
|
#include <KaizenGui.hpp>
|
||||||
|
#include <chrono>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
EmuThread::EmuThread(double &fps, SettingsWindow &settings) noexcept : settings(settings), fps(fps) {}
|
EmuThread::EmuThread(double &fps, SettingsWindow &settings) noexcept : settings(settings), fps(fps) {}
|
||||||
|
|
||||||
void EmuThread::run() const noexcept {
|
void EmuThread::run() noexcept {
|
||||||
n64::Core& core = n64::Core::GetInstance();
|
n64::Core& core = n64::Core::GetInstance();
|
||||||
if(!core.romLoaded) return;
|
rdramCopy = core.GetMem().GetRDRAM();
|
||||||
|
|
||||||
auto lastSample = std::chrono::high_resolution_clock::now();
|
|
||||||
auto avgFps = 16.667;
|
|
||||||
auto sampledFps = 0;
|
|
||||||
static bool oneSecondPassed = false;
|
|
||||||
|
|
||||||
fps = 1000.0 / avgFps;
|
while(!shouldExit) {
|
||||||
|
if(!core.romLoaded) {
|
||||||
const auto startFrameTime = std::chrono::high_resolution_clock::now();
|
std::this_thread::sleep_for(1ms);
|
||||||
if (!core.pause) {
|
continue;
|
||||||
core.Run(settings.getVolumeL(), settings.getVolumeR());
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto endFrameTime = std::chrono::high_resolution_clock::now();
|
|
||||||
using namespace std::chrono_literals;
|
|
||||||
const auto frameTimeMs = std::chrono::duration<double>(endFrameTime - startFrameTime) / 1ms;
|
|
||||||
avgFps += frameTimeMs;
|
|
||||||
|
|
||||||
sampledFps++;
|
|
||||||
|
|
||||||
if (const auto elapsedSinceLastSample = std::chrono::duration<double>(endFrameTime - lastSample) / 1s;
|
|
||||||
elapsedSinceLastSample >= 1.0) {
|
|
||||||
if (!oneSecondPassed) {
|
|
||||||
oneSecondPassed = true;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
avgFps /= sampledFps;
|
|
||||||
fps = 1000.0 / avgFps;
|
if(core.pause) {
|
||||||
|
std::this_thread::sleep_for(1ms);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
core.Run(settings.getVolumeL(), settings.getVolumeR());
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lk(presentMutex);
|
||||||
|
memcpy(rdramCopy.data(), core.GetMem().GetRDRAMPtr(), RDRAM_SIZE);
|
||||||
|
}
|
||||||
|
readyForPresentation.notify_all();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EmuThread::create() noexcept {
|
||||||
|
shouldExit.store(false, std::memory_order_release);
|
||||||
|
std::thread worker(&EmuThread::run, this);
|
||||||
|
worker.detach();
|
||||||
|
}
|
||||||
|
|
||||||
void EmuThread::TogglePause() const noexcept {
|
void EmuThread::TogglePause() const noexcept {
|
||||||
n64::Core::GetInstance().TogglePause();
|
n64::Core::GetInstance().TogglePause();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuThread::Reset() const noexcept {
|
void EmuThread::Reset() noexcept {
|
||||||
n64::Core::GetInstance().Reset();
|
n64::Core& core = n64::Core::GetInstance();
|
||||||
|
core.Reset();
|
||||||
|
rdramCopy = core.GetMem().GetRDRAM();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuThread::Stop() const noexcept {
|
void EmuThread::Stop() noexcept {
|
||||||
|
shouldExit.store(true, std::memory_order_release);
|
||||||
n64::Core& core = n64::Core::GetInstance();
|
n64::Core& core = n64::Core::GetInstance();
|
||||||
core.Stop();
|
core.Stop();
|
||||||
core.rom = {};
|
core.rom = {};
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#include <RenderWidget.hpp>
|
#include <RenderWidget.hpp>
|
||||||
#include <SettingsWindow.hpp>
|
#include <SettingsWindow.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
namespace n64 {
|
namespace n64 {
|
||||||
struct Core;
|
struct Core;
|
||||||
@@ -12,12 +13,17 @@ class EmuThread final {
|
|||||||
public:
|
public:
|
||||||
explicit EmuThread(double &, SettingsWindow &) noexcept;
|
explicit EmuThread(double &, SettingsWindow &) noexcept;
|
||||||
~EmuThread() = default;
|
~EmuThread() = default;
|
||||||
void run() const noexcept;
|
void create() noexcept;
|
||||||
|
void run() noexcept;
|
||||||
void TogglePause() const noexcept;
|
void TogglePause() const noexcept;
|
||||||
void Reset() const noexcept;
|
void Reset() noexcept;
|
||||||
void Stop() const noexcept;
|
void Stop() noexcept;
|
||||||
|
|
||||||
bool interruptionRequested = false, parallelRDPInitialized = false;
|
bool interruptionRequested = false, parallelRDPInitialized = false;
|
||||||
SettingsWindow &settings;
|
SettingsWindow &settings;
|
||||||
double& fps;
|
double& fps;
|
||||||
|
std::atomic_bool shouldExit = false;
|
||||||
|
std::mutex presentMutex;
|
||||||
|
std::condition_variable readyForPresentation;
|
||||||
|
std::vector<u8> rdramCopy;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,8 +4,11 @@
|
|||||||
#include <ImGuiImpl/ProgressIndicators.hpp>
|
#include <ImGuiImpl/ProgressIndicators.hpp>
|
||||||
#include <ImGuiImpl/StatusBar.hpp>
|
#include <ImGuiImpl/StatusBar.hpp>
|
||||||
#include <resources/gamecontrollerdb.h>
|
#include <resources/gamecontrollerdb.h>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
KaizenGui::KaizenGui() noexcept : window("Kaizen " KAIZEN_VERSION_STR, 1280, 720), settingsWindow(window), vulkanWidget(window.getHandle()), emuThread(fpsCounter, settingsWindow) {
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
|
KaizenGui::KaizenGui() noexcept : window("Kaizen " KAIZEN_VERSION_STR, 1280, 720), settingsWindow(window), emuThread(fpsCounter, settingsWindow), vulkanWidget(window.getHandle(), emuThread.rdramCopy.data()) {
|
||||||
gui::Initialize(n64::Core::GetInstance().parallel.wsi, window.getHandle());
|
gui::Initialize(n64::Core::GetInstance().parallel.wsi, window.getHandle());
|
||||||
SDL_InitSubSystem(SDL_INIT_GAMEPAD);
|
SDL_InitSubSystem(SDL_INIT_GAMEPAD);
|
||||||
|
|
||||||
@@ -412,16 +415,21 @@ void KaizenGui::RenderUI() {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if(core.romLoaded) {
|
if(core.romLoaded) {
|
||||||
core.parallel.UpdateScreen<true>();
|
std::unique_lock<std::mutex> lk(emuThread.presentMutex);
|
||||||
|
if(emuThread.readyForPresentation.wait_for(lk, 16.6667ms) == std::cv_status::no_timeout)
|
||||||
|
core.parallel.UpdateScreen<true>();
|
||||||
|
else
|
||||||
|
core.parallel.UpdateScreen<false>();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
core.parallel.UpdateScreen<false>();
|
core.parallel.UpdateScreen<false>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void KaizenGui::LoadROM(const std::string &path) noexcept {
|
void KaizenGui::LoadROM(const std::string &path) noexcept {
|
||||||
n64::Core& core = n64::Core::GetInstance();
|
n64::Core& core = n64::Core::GetInstance();
|
||||||
core.LoadROM(path);
|
core.LoadROM(path);
|
||||||
|
emuThread.create();
|
||||||
const auto gameNameDB = n64::Core::GetMem().rom.gameNameDB;
|
const auto gameNameDB = n64::Core::GetMem().rom.gameNameDB;
|
||||||
SDL_SetWindowTitle(window.getHandle(), ("Kaizen " KAIZEN_VERSION_STR " - " + gameNameDB).c_str());
|
SDL_SetWindowTitle(window.getHandle(), ("Kaizen " KAIZEN_VERSION_STR " - " + gameNameDB).c_str());
|
||||||
}
|
}
|
||||||
@@ -449,8 +457,6 @@ void KaizenGui::run() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SDL_GetWindowSize(window.getHandle(), &width, &height);
|
SDL_GetWindowSize(window.getHandle(), &width, &height);
|
||||||
|
|
||||||
emuThread.run();
|
|
||||||
RenderUI();
|
RenderUI();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ public:
|
|||||||
bool minimized = false;
|
bool minimized = false;
|
||||||
|
|
||||||
SettingsWindow settingsWindow;
|
SettingsWindow settingsWindow;
|
||||||
RenderWidget vulkanWidget;
|
|
||||||
EmuThread emuThread;
|
EmuThread emuThread;
|
||||||
|
RenderWidget vulkanWidget;
|
||||||
Debugger debugger;
|
Debugger debugger;
|
||||||
|
|
||||||
SDL_Gamepad* gamepad = nullptr;
|
SDL_Gamepad* gamepad = nullptr;
|
||||||
|
|||||||
@@ -4,9 +4,9 @@
|
|||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
#include <imgui_impl_sdl3.h>
|
#include <imgui_impl_sdl3.h>
|
||||||
|
|
||||||
RenderWidget::RenderWidget(SDL_Window* window) {
|
RenderWidget::RenderWidget(SDL_Window* window, u8* rdram) {
|
||||||
wsiPlatform = std::make_shared<SDLWSIPlatform>(window);
|
wsiPlatform = std::make_shared<SDLWSIPlatform>(window);
|
||||||
windowInfo = std::make_shared<SDLParallelRdpWindowInfo>(window);
|
windowInfo = std::make_shared<SDLParallelRdpWindowInfo>(window);
|
||||||
n64::Core& core = n64::Core::GetInstance();
|
n64::Core& core = n64::Core::GetInstance();
|
||||||
core.parallel.Init(wsiPlatform, windowInfo, core.GetMem().GetRDRAMPtr());
|
core.parallel.Init(wsiPlatform, windowInfo, rdram);
|
||||||
}
|
}
|
||||||
@@ -72,7 +72,7 @@ private:
|
|||||||
|
|
||||||
class RenderWidget final {
|
class RenderWidget final {
|
||||||
public:
|
public:
|
||||||
explicit RenderWidget(SDL_Window*);
|
explicit RenderWidget(SDL_Window*, u8* rdram);
|
||||||
|
|
||||||
std::shared_ptr<ParallelRDP::WindowInfo> windowInfo;
|
std::shared_ptr<ParallelRDP::WindowInfo> windowInfo;
|
||||||
std::shared_ptr<SDLWSIPlatform> wsiPlatform;
|
std::shared_ptr<SDLWSIPlatform> wsiPlatform;
|
||||||
|
|||||||
Reference in New Issue
Block a user