diff --git a/src/Machine.cpp b/src/Machine.cpp index 7b19d77..e36ee62 100644 --- a/src/Machine.cpp +++ b/src/Machine.cpp @@ -20,6 +20,7 @@ Machine::Machine() : interpreter{std::make_unique(this->machine_state)}, ui_manager{std::make_unique(this->graphics, this->machine_state, this->callback_manager)}, + running{false}, ips{700}, last_update_time{0}, accumulator{0}, @@ -30,7 +31,10 @@ Machine::Machine() : void Machine::iterate() { - this->execute_interpreter(); + if (running) + { + this->execute_interpreter(); + } this->graphics->start(); this->ui_manager->render(); @@ -74,9 +78,31 @@ void Machine::register_callbacks() &Machine::on_reset, this )); + callback_manager->set_stop_callback(std::bind( + &Machine::on_stop, + this + )); + callback_manager->set_resume_callback(std::bind( + &Machine::on_resume, + this + )); + callback_manager->set_step_callback(std::bind( + &Machine::on_step, + this, + std::placeholders::_1 + )); + callback_manager->set_ips_callback(std::bind( + &Machine::on_speed_change, + this, + std::placeholders::_1 + )); + callback_manager->set_reload_callback(std::bind( + &Machine::on_reload, + this + )); } -void Machine::on_rom_load(const std::string& path) const +void Machine::on_rom_load(const std::string& path) { std::ifstream file(path, std::ios::binary); file.unsetf(std::ios::skipws); @@ -100,6 +126,7 @@ void Machine::on_rom_load(const std::string& path) const this->machine_state->memory.begin() + 0x200 ); + this->rom = path; std::cout << "Cargado rom: " << path << std::endl; } @@ -107,3 +134,43 @@ void Machine::on_reset() const { this->machine_state->reset(); } + +void Machine::on_stop() +{ + this->running = false; + this->accumulator = 0; +} + +void Machine::on_resume() +{ + this->running = true; + this->last_update_time = SDL_GetTicks(); + this->accumulator = 0; +} + +void Machine::on_step(int steps) +{ + for (int i = 0; i < steps; i++) + { + this->interpreter->tick(); + } +} + +void Machine::on_speed_change(const int ips) +{ + this->ips = ips; + if (this->ips > 0) + { + this->target_cycle_time = 1.0 / this->ips; + } + else + { + this->target_cycle_time = std::numeric_limits::infinity(); + } +} + +void Machine::on_reload() +{ + this->on_reset(); + this->on_rom_load(this->rom); +} diff --git a/src/Machine.h b/src/Machine.h index d5cd816..542e960 100644 --- a/src/Machine.h +++ b/src/Machine.h @@ -21,9 +21,17 @@ class Machine double accumulator; double target_cycle_time; + std::string rom; + bool running; + void execute_interpreter(); - void on_rom_load(const std::string& path) const; + void on_rom_load(const std::string& path); void on_reset() const; + void on_stop(); + void on_resume(); + void on_step(int steps); + void on_speed_change(int ips); + void on_reload(); public: void register_callbacks(); @@ -32,4 +40,4 @@ public: bool on_event(const SDL_Event* event) const; }; -#endif //MACHINE_H \ No newline at end of file +#endif //MACHINE_H diff --git a/src/UI/CallbackManager.cpp b/src/UI/CallbackManager.cpp index 4159bda..bd7f8b9 100644 --- a/src/UI/CallbackManager.cpp +++ b/src/UI/CallbackManager.cpp @@ -1,5 +1,8 @@ #include "CallbackManager.h" +//---------------------------------------------------------------- +// SET CALLBACKS +//---------------------------------------------------------------- void CallbackManager::set_rom_load_callback(const RomLoadCallback& callback) { this->rom_load_callback = callback; @@ -10,6 +13,34 @@ void CallbackManager::set_reset_callback(const ResetCallback& callback) this->reset_callback = callback; } +void CallbackManager::set_resume_callback(const ResumeCallback& callback) +{ + this->resume_callback = callback; +} + +void CallbackManager::set_stop_callback(const StopCallback& callback) +{ + this->stop_callback = callback; +} + +void CallbackManager::set_step_callback(const StepCallback& callback) +{ + this->step_callback = callback; +} + +void CallbackManager::set_ips_callback(const IPSCallback& callback) +{ + this->ips_callback = callback; +} + +void CallbackManager::set_reload_callback(const ReloadCallback& callback) +{ + this->reload_callback = callback; +} + +//---------------------------------------------------------------- +// TRIGGER CALLBACKS +//---------------------------------------------------------------- void CallbackManager::trigger_rom_load(const std::string& path) { if (this->rom_load_callback) @@ -24,4 +55,41 @@ void CallbackManager::trigger_reset() { this->reset_callback(); } -} \ No newline at end of file +} + +void CallbackManager::trigger_resume() +{ + if (this->resume_callback) + { + this->resume_callback(); + } +} + +void CallbackManager::trigger_stop() +{ + if (this->stop_callback) + { + this->stop_callback(); + } +} + +void CallbackManager::trigger_step(int steps) +{ + if (this->step_callback) + { + this->step_callback(steps); + } +} + +void CallbackManager::trigger_ips(int speed) +{ + if (this->ips_callback) + { + this->ips_callback(speed); + } +} + +void CallbackManager::trigger_reload() +{ + if (this->reload_callback) this->reload_callback(); +} diff --git a/src/UI/CallbackManager.h b/src/UI/CallbackManager.h index 5497d12..d6fce9f 100644 --- a/src/UI/CallbackManager.h +++ b/src/UI/CallbackManager.h @@ -7,19 +7,39 @@ struct CallbackManager { - using RomLoadCallback = std::function; + using RomLoadCallback = std::function; using ResetCallback = std::function; + using ResumeCallback = std::function; + using StopCallback = std::function; + using StepCallback = std::function; + using IPSCallback = std::function; + using ReloadCallback = std::function; void set_rom_load_callback(const RomLoadCallback& callback); void set_reset_callback(const ResetCallback& callback); + void set_resume_callback(const ResumeCallback& callback); + void set_stop_callback(const StopCallback& callback); + void set_step_callback(const StepCallback& callback); + void set_ips_callback(const IPSCallback& callback); + void set_reload_callback(const ReloadCallback& callback); void trigger_rom_load(const std::string& path); void trigger_reset(); + void trigger_resume(); + void trigger_stop(); + void trigger_step(int); + void trigger_ips(int); + void trigger_reload(); private: RomLoadCallback rom_load_callback; ResetCallback reset_callback; + ResumeCallback resume_callback; + StopCallback stop_callback; + StepCallback step_callback; + IPSCallback ips_callback; + ReloadCallback reload_callback; }; -#endif //CALLBACKMANAGER_H \ No newline at end of file +#endif //CALLBACKMANAGER_H diff --git a/src/UI/ControlPanel.cpp b/src/UI/ControlPanel.cpp index 72f1015..5f13db0 100644 --- a/src/UI/ControlPanel.cpp +++ b/src/UI/ControlPanel.cpp @@ -18,6 +18,8 @@ ControlPanel::ControlPanel( void ControlPanel::render() { + int starting_speed = this->ips; + constexpr auto full_width = ImVec2(-FLT_MIN, 0.0f); if (ImGui::Begin("Chip-8 - Controls")) @@ -30,14 +32,31 @@ void ControlPanel::render() if (ImGui::Button(run ? "Pause" : "Run", full_width)) { this->run = !run; + if (this->run) + { + this->callback_manager->trigger_resume(); + } + else + { + this->callback_manager->trigger_stop(); + } } ImGui::Text("Status: %s", "Stopped"); ImGui::SeparatorText("Debug"); - ImGui::Button("Step One", full_width); - ImGui::Button(std::format("Step +{}", steps).data(), full_width); + + if (ImGui::Button("Step One", full_width)) + { + this->callback_manager->trigger_step(1); + } + + if (ImGui::Button(std::format("Step +{}", steps).data(), full_width)) + { + this->callback_manager->trigger_step(steps); + } + ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x); ImGui::InputInt("##steps", &steps); ImGui::PopItemWidth(); @@ -46,7 +65,7 @@ void ControlPanel::render() ImGui::SeparatorText("Emulation speed (IPS)"); ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x); - ImGui::InputInt("##speed", &speed); + ImGui::InputInt("##speed", &ips); ImGui::PopItemWidth(); ImGui::SeparatorText(""); @@ -55,7 +74,15 @@ void ControlPanel::render() { this->callback_manager->trigger_reset(); } - ImGui::Button("Reload ROM", full_width); + if (ImGui::Button("Reload ROM", full_width)) + { + this->callback_manager->trigger_reload(); + } + } + + if (starting_speed != this->ips) + { + this->callback_manager->trigger_ips(this->ips); } ImGui::End(); @@ -89,4 +116,4 @@ void ControlPanel::on_callback_load_rom(void* self, const char* const* filelist, } control_panel->callback_manager->trigger_rom_load(filelist[0]); -} \ No newline at end of file +} diff --git a/src/UI/ControlPanel.h b/src/UI/ControlPanel.h index c0fadbb..ce94494 100644 --- a/src/UI/ControlPanel.h +++ b/src/UI/ControlPanel.h @@ -1,8 +1,6 @@ #ifndef CONTROLPANEL_H #define CONTROLPANEL_H -#include #include -#include #include "CallbackManager.h" #include "../Graphics/Graphics.h" @@ -17,7 +15,7 @@ class ControlPanel bool run = false; int steps = 1; - int speed = 100; + int ips = 700; static SDLCALL void on_callback_load_rom(void* self, const char* const* filelist, int filter); @@ -33,4 +31,4 @@ public: }; -#endif //CONTROLPANEL_H \ No newline at end of file +#endif //CONTROLPANEL_H