diff --git a/CubeChip (SDL).vcxproj b/CubeChip (SDL).vcxproj index 0a7d797..78697dc 100644 --- a/CubeChip (SDL).vcxproj +++ b/CubeChip (SDL).vcxproj @@ -29,13 +29,6 @@ - - - - - - - @@ -56,9 +49,6 @@ - - - diff --git a/CubeChip (SDL).vcxproj.filters b/CubeChip (SDL).vcxproj.filters index 338d996..455ddad 100644 --- a/CubeChip (SDL).vcxproj.filters +++ b/CubeChip (SDL).vcxproj.filters @@ -90,27 +90,6 @@ Source Files\VM Guest - - to_be_removed - - - to_be_removed - - - to_be_removed\InstructionSets - - - to_be_removed\InstructionSets - - - to_be_removed\InstructionSets - - - to_be_removed\InstructionSets - - - to_be_removed\InstructionSets - @@ -176,14 +155,5 @@ Header Files\VM Guest - - to_be_removed - - - to_be_removed - - - to_be_removed\InstructionSets - \ No newline at end of file diff --git a/src/CubeChip.cpp b/src/CubeChip.cpp index 5910fa2..1f79077 100644 --- a/src/CubeChip.cpp +++ b/src/CubeChip.cpp @@ -6,12 +6,10 @@ #include "Assistants/FrameLimiter.hpp" #include -#include #define SDL_MAIN_USE_CALLBACKS #include -#include #include #include @@ -22,18 +20,7 @@ #include "HostClass/Host.hpp" -struct { - std::optional HDM; - std::optional BVS; - std::optional BAS; - FrameLimiter Limiter; - std::unique_ptr Host; - std::mutex Mut; -} global; - -SDL_AppResult SDL_AppInit(void **appstate, int argc, char* argv[]) { - - SDL_InitSubSystem(SDL_INIT_EVENTS); +SDL_AppResult SDL_AppInit(void **Host, int argc, char* argv[]) { // VS OTHER #if !defined(NDEBUG) || defined(DEBUG) @@ -61,51 +48,58 @@ SDL_AppResult SDL_AppInit(void **appstate, int argc, char* argv[]) { #endif SDL_SetHint(SDL_HINT_APP_NAME, "CubeChip"); - global.Mut.lock(); - - try { - global.HDM.emplace("CubeChip_SDL"); - global.BVS.emplace(); - global.BAS.emplace(); - } catch (...) { return SDL_APP_FAILURE; } + *Host = VM_Host::initialize(argc <= 1 ? nullptr : argv[1]); - global.Host = std::make_unique( - argc <= 1 ? nullptr : argv[1], - *global.HDM, *global.BVS, *global.BAS - ); - global.Host->prepareGuest(global.Limiter); - - global.Mut.unlock(); - - return SDL_APP_CONTINUE; + if (Host) { return SDL_APP_CONTINUE; } + else { return SDL_APP_FAILURE; } } -SDL_AppResult SDL_AppIterate(void* appstate) { - global.Mut.lock(); +SDL_AppResult SDL_AppIterate(void* Host_ptr) { + auto& Host{ *static_cast(Host_ptr) }; - if (!global.Host->runFrame(global.Limiter)) { - global.Mut.unlock(); - return SDL_APP_SUCCESS; - } - - global.Host->BVS.renderPresent(); + Host.Mutex.lock(); + switch (Host.runFrame()) { + case SDL_APP_SUCCESS: + Host.Mutex.unlock(); + return SDL_APP_SUCCESS; - global.Mut.unlock(); + case SDL_APP_CONTINUE: + Host.Mutex.unlock(); + return SDL_APP_CONTINUE; - return SDL_APP_CONTINUE; + case SDL_APP_FAILURE: + Host.Mutex.unlock(); + return SDL_APP_FAILURE; + } } -SDL_AppResult SDL_AppEvent(void *appstate, const SDL_Event *event) { - global.Mut.lock(); - - if (!global.Host->handleEventSDL(global.Limiter, event)) { - global.Mut.unlock(); - return SDL_APP_SUCCESS; +SDL_AppResult SDL_AppEvent(void* Host_ptr, const SDL_Event* Event) { + auto& Host{ *static_cast(Host_ptr) }; + + switch (Event->type) { + case SDL_EVENT_QUIT: + return SDL_APP_SUCCESS; + + case SDL_EVENT_DROP_FILE: + Host.Mutex.lock(); + Host.loadGameFile(Event->drop.data, true); + Host.Mutex.unlock(); + break; + + case SDL_EVENT_WINDOW_MINIMIZED: + Host.Mutex.lock(); + Host.pauseSystem(true); + Host.Mutex.unlock(); + break; + + case SDL_EVENT_WINDOW_RESTORED: + Host.Mutex.lock(); + Host.pauseSystem(false); + Host.Mutex.unlock(); + break; } - - global.Mut.unlock(); return SDL_APP_CONTINUE; } -void SDL_AppQuit(void *appstate) {} +void SDL_AppQuit(void*) {} diff --git a/src/HostClass/BasicAudioSpec.cpp b/src/HostClass/BasicAudioSpec.cpp index 9a70413..c4400fd 100644 --- a/src/HostClass/BasicAudioSpec.cpp +++ b/src/HostClass/BasicAudioSpec.cpp @@ -26,7 +26,6 @@ BasicAudioSpec::BasicAudioSpec() } BasicAudioSpec::~BasicAudioSpec() { - if (stream) SDL_DestroyAudioStream(stream); SDL_QuitSubSystem(SDL_INIT_AUDIO); } diff --git a/src/HostClass/BasicVideoSpec.cpp b/src/HostClass/BasicVideoSpec.cpp index 8e3f162..7ee9509 100644 --- a/src/HostClass/BasicVideoSpec.cpp +++ b/src/HostClass/BasicVideoSpec.cpp @@ -25,9 +25,6 @@ BasicVideoSpec::BasicVideoSpec() } BasicVideoSpec::~BasicVideoSpec() { - quitTexture(); - quitRenderer(); - quitWindow(); SDL_QuitSubSystem(SDL_INIT_VIDEO); } diff --git a/src/HostClass/HomeDirManager.cpp b/src/HostClass/HomeDirManager.cpp index c9a6766..e890ca2 100644 --- a/src/HostClass/HomeDirManager.cpp +++ b/src/HostClass/HomeDirManager.cpp @@ -79,6 +79,7 @@ bool HomeDirManager::validateGameFile(const char* inputPath) noexcept { const auto tempStem{ gamePath.stem().string() }; const auto tempExts{ gamePath.extension().string() }; const auto tempSHA1{ SHA1::from_file(tempPath) }; + const auto tempTime{ fs::last_write_time(gamePath) }; const bool gameApproved{ checkGame(tempSize, tempExts, tempSHA1) }; @@ -88,6 +89,7 @@ bool HomeDirManager::validateGameFile(const char* inputPath) noexcept { mFileStem = tempStem; mFileExts = tempExts; mFileSHA1 = tempSHA1; + mFileTime = tempTime; mFileSize = tempSize; } diff --git a/src/HostClass/Host.hpp b/src/HostClass/Host.hpp index 3aaf3f2..5bdf731 100644 --- a/src/HostClass/Host.hpp +++ b/src/HostClass/Host.hpp @@ -6,6 +6,11 @@ #pragma once +#include +#include + +#include + class HomeDirManager; class BasicVideoSpec; class BasicAudioSpec; @@ -13,35 +18,32 @@ class BasicAudioSpec; class FrameLimiter; class EmuInterface; -union SDL_Event; - class VM_Host final { std::unique_ptr iGuest; - bool _doBench{}; + std::unique_ptr Limiter; + std::unique_ptr HDM; + std::unique_ptr BVS; + std::unique_ptr BAS; - [[nodiscard]] - bool doBench() const noexcept; - void doBench(bool) noexcept; + bool runBenchmark{}; bool initGameCore(); + void replaceGuest(const bool); + + VM_Host(const char* const); + VM_Host(const VM_Host&) = delete; + VM_Host& operator=(const VM_Host&) = delete; public: - HomeDirManager& HDM; - BasicVideoSpec& BVS; - BasicAudioSpec& BAS; - - explicit VM_Host( - const char* const, - HomeDirManager&, - BasicVideoSpec&, - BasicAudioSpec& - ); - ~VM_Host(); - - void prepareGuest(FrameLimiter&); - bool handleEventSDL(FrameLimiter&, const SDL_Event*); - bool runFrame(FrameLimiter& Limiter); + std::mutex Mutex; + + static VM_Host* initialize(const char* const); + + void pauseSystem(const bool state) const noexcept; + void loadGameFile(const char* const, const bool = false); + + SDL_AppResult runFrame(); }; diff --git a/src/HostClass/HostFunctions.cpp b/src/HostClass/HostFunctions.cpp index 23dce4c..619499d 100644 --- a/src/HostClass/HostFunctions.cpp +++ b/src/HostClass/HostFunctions.cpp @@ -26,99 +26,99 @@ using namespace bic; /* class VM_Host */ /*------------------------------------------------------------------*/ -VM_Host::~VM_Host() = default; -VM_Host::VM_Host( - const char* const filename, - HomeDirManager& ref_HDM, - BasicVideoSpec& ref_BVS, - BasicAudioSpec& ref_BAS -) - : HDM{ ref_HDM } - , BVS{ ref_BVS } - , BAS{ ref_BAS } +VM_Host::VM_Host(const char* const filename) + : HDM { std::make_unique("CubeChip") } + , BVS { std::make_unique() } + , BAS { std::make_unique() } + , Limiter{ std::make_unique() } { - HDM.setValidator(GameFileChecker::validate); - HDM.validateGameFile(filename); + HDM->setValidator(GameFileChecker::validate); + loadGameFile(filename); } -bool VM_Host::doBench() const noexcept { return _doBench; } -void VM_Host::doBench(const bool state) noexcept { _doBench = state; } +VM_Host* VM_Host::initialize(const char* const filename) { + try { + static VM_Host self(filename); + return &self; + } catch (...) { + return nullptr; + } +} bool VM_Host::initGameCore() { - iGuest = std::move(GameFileChecker::initializeCore(HDM, BVS, BAS)); + iGuest = std::move(GameFileChecker::initializeCore(*HDM, *BVS, *BAS)); return iGuest ? true : false; } -bool VM_Host::runFrame(FrameLimiter& Limiter) { +SDL_AppResult VM_Host::runFrame() { using namespace bic; - if (!Limiter.checkTime()) [[likely]] { return true; } + if (!Limiter->checkTime()) [[likely]] { return SDL_APP_CONTINUE; } if (kb.isPressed(KEY(RIGHT))) { - BAS.changeVolume(+15); + BAS->changeVolume(+15); } if (kb.isPressed(KEY(LEFT))) { - BAS.changeVolume(-15); + BAS->changeVolume(-15); } if (iGuest) { if (kb.isPressed(KEY(ESCAPE))) { - BVS.resetWindow(); - GameFileChecker::delCore(); - prepareGuest(Limiter); - // continue - return true; + replaceGuest(true); + return SDL_APP_CONTINUE; } if (kb.isPressed(KEY(BACKSPACE))) { - if (HDM.validateGameFile(HDM.getFilePath().c_str())) { - prepareGuest(Limiter); - } - // continue - return true; + loadGameFile(HDM->getFilePath().c_str()); + return SDL_APP_CONTINUE; } if (kb.isPressed(KEY(RSHIFT))) { - if (doBench()) { - doBench(false); - BVS.changeTitle(HDM.getFileStem().c_str()); + if (runBenchmark) { + runBenchmark = false; + BVS->changeTitle(HDM->getFileStem().c_str()); std::cout << "\33[1;1H\33[3J" << std::endl; } else { - doBench(true); - BVS.changeTitle(std::to_string(iGuest->fetchCPF())); + runBenchmark = true; + BVS->changeTitle(std::to_string(iGuest->fetchCPF())); std::cout << "\33[1;1H\33[2J" << "Cycle time: . ms" << "\nTime since last frame: " - << "\nCPF: "; + #ifndef SDL_PLATFORM_WIN32 + << "\nCPF: " + #endif + << std::endl; } } if (kb.isPressed(KEY(PAGEDOWN))){ - BVS.changeFrameMultiplier(-1); + BVS->changeFrameMultiplier(-1); } if (kb.isPressed(KEY(PAGEUP))) { - BVS.changeFrameMultiplier(+1); + BVS->changeFrameMultiplier(+1); } - if (doBench()) [[likely]] { + if (runBenchmark) [[likely]] { if (kb.isPressed(KEY(UP))) { - BVS.changeTitle(std::to_string(iGuest->changeCPF(+50'000))); + BVS->changeTitle(std::to_string(iGuest->changeCPF(+50'000))); } if (kb.isPressed(KEY(DOWN))){ - BVS.changeTitle(std::to_string(iGuest->changeCPF(-50'000))); + BVS->changeTitle(std::to_string(iGuest->changeCPF(-50'000))); } iGuest->processFrame(); - if (Limiter.getValidFrameCounter() & 0x1) { - const auto micros{ Limiter.getElapsedMicrosSince() }; + if (Limiter->getValidFrameCounter() & 0x1) { + const auto micros{ Limiter->getElapsedMicrosSince() }; std::cout << "\33[1;12H" << std::setfill(' ') << std::setw(4) << micros / 1000 << "\33[1C" << std::setfill('0') << std::setw(3) << micros % 1000 << "\33[2;25H" - << Limiter.getElapsedMillisLast() + << Limiter->getElapsedMillisLast() + #ifndef SDL_PLATFORM_WIN32 << "\33[3;6H" << iGuest->fetchCPF() << " " + #endif << std::endl; } } else { @@ -126,48 +126,43 @@ bool VM_Host::runFrame(FrameLimiter& Limiter) { } } else { if (kb.isPressed(KEY(ESCAPE))) { - // this one stops execution - return false; + return SDL_APP_SUCCESS; } } + BVS->renderPresent(); + bic::kb.updateCopy(); bic::mb.updateCopy(); - return true; + + return SDL_APP_CONTINUE; } -void VM_Host::prepareGuest(FrameLimiter& Frame) { +void VM_Host::replaceGuest(const bool disable) { bic::kb.updateCopy(); bic::mb.updateCopy(); + if (disable) { + BVS->resetWindow(); + GameFileChecker::delCore(); + } + if (initGameCore()) { - Frame.setLimiter(iGuest->fetchFramerate()); - BVS.changeTitle(HDM.getFileStem().c_str()); + Limiter->setLimiter(iGuest->fetchFramerate()); + BVS->changeTitle(HDM->getFileStem().c_str()); } else { - Frame.setLimiter(30.0f); - HDM.clearCachedFileData(); + Limiter->setLimiter(30.0f); + HDM->clearCachedFileData(); } } -bool VM_Host::handleEventSDL(FrameLimiter& Frame, const SDL_Event* Event) { - switch (Event->type) { - case SDL_EVENT_QUIT: - return false; - - case SDL_EVENT_DROP_FILE: - BVS.raiseWindow(); - if (HDM.validateGameFile(Event->drop.data)) { - prepareGuest(Frame); - } - break; - - case SDL_EVENT_WINDOW_MINIMIZED: - if (iGuest) { iGuest->isSystemStopped(true); } - break; - - case SDL_EVENT_WINDOW_RESTORED: - if (iGuest) { iGuest->isSystemStopped(false); } - break; +void VM_Host::loadGameFile(const char* const filename, const bool alert) { + if (alert) { BVS->raiseWindow(); } + if (HDM->validateGameFile(filename)) { + replaceGuest(false); } - return true; +} + +void VM_Host::pauseSystem(const bool state) const noexcept { + if (iGuest) { iGuest->isSystemStopped(state); } }