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); }
}