Iniciando un buen sistema de callbacks!
This commit is contained in:
1
.idea/editor.xml
generated
1
.idea/editor.xml
generated
@@ -117,6 +117,7 @@
|
|||||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMismatchedClassTags/@EntryIndexedValue" value="WARNING" type="string" />
|
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMismatchedClassTags/@EntryIndexedValue" value="WARNING" type="string" />
|
||||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMissingIncludeGuard/@EntryIndexedValue" value="WARNING" type="string" />
|
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMissingIncludeGuard/@EntryIndexedValue" value="WARNING" type="string" />
|
||||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMissingKeywordThrow/@EntryIndexedValue" value="WARNING" type="string" />
|
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMissingKeywordThrow/@EntryIndexedValue" value="WARNING" type="string" />
|
||||||
|
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppModulePartitionWithSeveralPartitionUnits/@EntryIndexedValue" value="WARNING" type="string" />
|
||||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtAddressOfClassRValue/@EntryIndexedValue" value="WARNING" type="string" />
|
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtAddressOfClassRValue/@EntryIndexedValue" value="WARNING" type="string" />
|
||||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtBindingRValueToLvalueReference/@EntryIndexedValue" value="WARNING" type="string" />
|
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtBindingRValueToLvalueReference/@EntryIndexedValue" value="WARNING" type="string" />
|
||||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtCopyElisionInCopyInitDeclarator/@EntryIndexedValue" value="WARNING" type="string" />
|
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtCopyElisionInCopyInitDeclarator/@EntryIndexedValue" value="WARNING" type="string" />
|
||||||
|
|||||||
@@ -1,15 +1,30 @@
|
|||||||
add_executable(${PROJECT_NAME})
|
add_executable(${PROJECT_NAME})
|
||||||
|
|
||||||
file(GLOB CHIP8_SOURCES "*.cpp" "**/*.cpp")
|
|
||||||
file(GLOB CHIP8_HEADERS "*.h" "**/*.h")
|
|
||||||
message(CHIP8_SOURCES="${CHIP8_SOURCES}")
|
|
||||||
message(CHIP8_HEADERS="${CHIP8_HEADERS}")
|
|
||||||
|
|
||||||
target_sources(
|
target_sources(
|
||||||
${PROJECT_NAME}
|
${PROJECT_NAME}
|
||||||
PRIVATE
|
PRIVATE
|
||||||
${CHIP8_SOURCES}
|
main.cpp
|
||||||
${CHIP8_HEADERS}
|
Machine.cpp
|
||||||
|
Machine.h
|
||||||
|
Graphics/Graphics.cpp
|
||||||
|
Graphics/Graphics.h
|
||||||
|
Graphics/Color.h
|
||||||
|
Interpreter/Interpreter.cpp
|
||||||
|
Interpreter/Interpreter.h
|
||||||
|
Interpreter/Instruction.h
|
||||||
|
Interpreter/MachineState.cpp
|
||||||
|
Interpreter/MachineState.h
|
||||||
|
Interpreter/OpCode.h
|
||||||
|
UI/CallbackManager.cpp
|
||||||
|
UI/CallbackManager.h
|
||||||
|
UI/ControlPanel.cpp
|
||||||
|
UI/ControlPanel.h
|
||||||
|
UI/Display.cpp
|
||||||
|
UI/Display.h
|
||||||
|
UI/UIManager.cpp
|
||||||
|
UI/UIManager.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
add_compile_options(-Wall -Wextra -Wpedantic -Werror)
|
||||||
|
|
||||||
target_link_libraries(${PROJECT_NAME} PRIVATE vendor)
|
target_link_libraries(${PROJECT_NAME} PRIVATE vendor)
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
#include "Machine.h"
|
#include "Machine.h"
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <iterator>
|
||||||
#include <bits/ostream.tcc>
|
#include <bits/ostream.tcc>
|
||||||
|
|
||||||
#include "Graphics/Graphics.h"
|
#include "Graphics/Graphics.h"
|
||||||
@@ -11,31 +13,21 @@
|
|||||||
|
|
||||||
#include "imgui_impl_sdl3.h"
|
#include "imgui_impl_sdl3.h"
|
||||||
|
|
||||||
Machine::Machine():
|
Machine::Machine() :
|
||||||
machine_state{std::make_shared<MachineState>()},
|
machine_state{std::make_shared<MachineState>()},
|
||||||
graphics{std::make_shared<Graphics>()},
|
graphics{std::make_shared<Graphics>()},
|
||||||
|
callback_manager(std::make_shared<CallbackManager>()),
|
||||||
|
|
||||||
interpreter{std::make_unique<Interpreter>(this->machine_state)},
|
interpreter{std::make_unique<Interpreter>(this->machine_state)},
|
||||||
ui_manager{std::make_unique<UIManager>(this->graphics, this->machine_state)},
|
ui_manager{std::make_unique<UIManager>(this->graphics, this->machine_state, this->callback_manager)},
|
||||||
|
|
||||||
ips{700},
|
ips{700},
|
||||||
last_update_time{0},
|
last_update_time{0},
|
||||||
accumulator{0},
|
accumulator{0},
|
||||||
target_cycle_time{1.0 / this->ips} {
|
target_cycle_time{1.0 / this->ips} {
|
||||||
|
this->register_callbacks();
|
||||||
ui_manager->control_panel->set_rom_load_callback(std::bind(
|
|
||||||
&Machine::on_rom_load,
|
|
||||||
this,
|
|
||||||
std::placeholders::_1
|
|
||||||
));
|
|
||||||
|
|
||||||
ui_manager->control_panel->set_reset_callback(std::bind(
|
|
||||||
&Machine::on_reset,
|
|
||||||
this
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Machine::iterate() {
|
void Machine::iterate() {
|
||||||
this->execute_interpreter();
|
this->execute_interpreter();
|
||||||
|
|
||||||
@@ -66,9 +58,43 @@ void Machine::execute_interpreter() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Machine::on_rom_load(const std::string& path) const {
|
void Machine::register_callbacks() {
|
||||||
std::cout << path << std::endl;
|
callback_manager->set_rom_load_callback(std::bind(
|
||||||
|
&Machine::on_rom_load,
|
||||||
|
this,
|
||||||
|
std::placeholders::_1
|
||||||
|
));
|
||||||
|
callback_manager->set_reset_callback(std::bind(
|
||||||
|
&Machine::on_reset,
|
||||||
|
this
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Machine::on_rom_load(const std::string& path) const {
|
||||||
|
std::ifstream file(path, std::ios::binary);
|
||||||
|
file.unsetf(std::ios::skipws);
|
||||||
|
|
||||||
|
file.seekg(0, std::ios::end);
|
||||||
|
const std::streampos file_size = file.tellg();
|
||||||
|
file.seekg(0, std::ios::beg);
|
||||||
|
|
||||||
|
// La memoria para los rom es desde 0x200 hasta el final de 0x1000
|
||||||
|
// Por lo que un rom sería muy grande si sobrepasa este tamaño
|
||||||
|
if (file_size >= 0x1000 - 0x200 ) {
|
||||||
|
std::cout << "File too large!" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->machine_state->reset();
|
||||||
|
std::copy(
|
||||||
|
std::istream_iterator<uint8_t>(file),
|
||||||
|
std::istream_iterator<uint8_t>(),
|
||||||
|
this->machine_state->memory.begin() + 0x200
|
||||||
|
);
|
||||||
|
|
||||||
|
std::cout << "Cargado rom: " << path << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
void Machine::on_reset() const {
|
void Machine::on_reset() const {
|
||||||
this->machine_state->reset();
|
this->machine_state->reset();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
class Machine {
|
class Machine {
|
||||||
std::shared_ptr<MachineState> machine_state;
|
std::shared_ptr<MachineState> machine_state;
|
||||||
std::shared_ptr<Graphics> graphics;
|
std::shared_ptr<Graphics> graphics;
|
||||||
|
std::shared_ptr<CallbackManager> callback_manager;
|
||||||
|
|
||||||
std::unique_ptr<Interpreter> interpreter;
|
std::unique_ptr<Interpreter> interpreter;
|
||||||
std::unique_ptr<UIManager> ui_manager;
|
std::unique_ptr<UIManager> ui_manager;
|
||||||
@@ -24,6 +25,7 @@ class Machine {
|
|||||||
void on_reset() const;
|
void on_reset() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
void register_callbacks();
|
||||||
Machine();
|
Machine();
|
||||||
void iterate();
|
void iterate();
|
||||||
bool on_event(const SDL_Event* event) const;
|
bool on_event(const SDL_Event* event) const;
|
||||||
|
|||||||
19
src/UI/CallbackManager.cpp
Normal file
19
src/UI/CallbackManager.cpp
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#include "CallbackManager.h"
|
||||||
|
|
||||||
|
void CallbackManager::set_rom_load_callback(const RomLoadCallback& callback) {
|
||||||
|
this->rom_load_callback = callback;
|
||||||
|
}
|
||||||
|
void CallbackManager::set_reset_callback(const ResetCallback& callback) {
|
||||||
|
this->reset_callback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CallbackManager::trigger_rom_load(const std::string& path) {
|
||||||
|
if (this->rom_load_callback) {
|
||||||
|
this->rom_load_callback(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void CallbackManager::trigger_reset() {
|
||||||
|
if (this->reset_callback) {
|
||||||
|
this->reset_callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
24
src/UI/CallbackManager.h
Normal file
24
src/UI/CallbackManager.h
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#ifndef CALLBACKMANAGER_H
|
||||||
|
#define CALLBACKMANAGER_H
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
struct CallbackManager {
|
||||||
|
using RomLoadCallback = std::function<void(const std::string&)>;
|
||||||
|
using ResetCallback = std::function<void()>;
|
||||||
|
|
||||||
|
void set_rom_load_callback(const RomLoadCallback& callback);
|
||||||
|
void set_reset_callback(const ResetCallback& callback);
|
||||||
|
|
||||||
|
void trigger_rom_load(const std::string& path);
|
||||||
|
void trigger_reset();
|
||||||
|
|
||||||
|
private:
|
||||||
|
RomLoadCallback rom_load_callback;
|
||||||
|
ResetCallback reset_callback;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //CALLBACKMANAGER_H
|
||||||
@@ -1,22 +1,18 @@
|
|||||||
#include "ControlPanel.h"
|
#include "ControlPanel.h"
|
||||||
|
|
||||||
#include <format>
|
#include <format>
|
||||||
|
#include <ranges>
|
||||||
|
|
||||||
#include "imgui.h"
|
#include "imgui.h"
|
||||||
|
|
||||||
|
|
||||||
ControlPanel::ControlPanel(
|
ControlPanel::ControlPanel(
|
||||||
std::shared_ptr<Graphics> graphics,
|
std::shared_ptr<Graphics> graphics,
|
||||||
std::shared_ptr<MachineState> machine_state
|
std::shared_ptr<MachineState> machine_state,
|
||||||
): graphics{std::move(graphics)},
|
std::shared_ptr<CallbackManager> callback_manager
|
||||||
machine_state{std::move(machine_state)} {}
|
) : graphics{std::move(graphics)},
|
||||||
|
machine_state{std::move(machine_state)},
|
||||||
void ControlPanel::set_rom_load_callback(const std::function<void(std::string)>& callback) {
|
callback_manager{std::move(callback_manager)} {}
|
||||||
this->rom_load_callback = callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ControlPanel::set_reset_callback(const std::function<void()>& callback) {
|
|
||||||
this->reset_callback = callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ControlPanel::render() {
|
void ControlPanel::render() {
|
||||||
constexpr auto full_width = ImVec2(-FLT_MIN, 0.0f);
|
constexpr auto full_width = ImVec2(-FLT_MIN, 0.0f);
|
||||||
@@ -50,9 +46,7 @@ void ControlPanel::render() {
|
|||||||
ImGui::SeparatorText("");
|
ImGui::SeparatorText("");
|
||||||
|
|
||||||
if (ImGui::Button("Reset", full_width)) {
|
if (ImGui::Button("Reset", full_width)) {
|
||||||
if (this->reset_callback) {
|
this->callback_manager->trigger_reset();
|
||||||
this->reset_callback();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ImGui::Button("Reload ROM", full_width);
|
ImGui::Button("Reload ROM", full_width);
|
||||||
}
|
}
|
||||||
@@ -66,19 +60,23 @@ void ControlPanel::on_click_load_rom() {
|
|||||||
{"All files", "*"}
|
{"All files", "*"}
|
||||||
};
|
};
|
||||||
|
|
||||||
SDL_ShowOpenFileDialog(on_callback_load_rom, this, graphics->get_window().get(), filters, std::size(filters), nullptr, false);
|
SDL_ShowOpenFileDialog(
|
||||||
|
on_callback_load_rom,
|
||||||
|
this,
|
||||||
|
graphics->get_window().get(),
|
||||||
|
filters,
|
||||||
|
std::size(filters),
|
||||||
|
SDL_GetCurrentDirectory(),
|
||||||
|
false
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControlPanel::on_callback_load_rom(void* userdata, const char* const* filelist, int filter) {
|
void ControlPanel::on_callback_load_rom(void* self, const char* const* filelist, int filter) {
|
||||||
const auto control_panel = static_cast<ControlPanel*>(userdata);
|
const auto control_panel = static_cast<ControlPanel*>(self);
|
||||||
|
|
||||||
if (!control_panel->rom_load_callback) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!filelist || !*filelist) {
|
if (!filelist || !*filelist) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
control_panel->rom_load_callback(*filelist);
|
control_panel->callback_manager->trigger_rom_load(filelist[0]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,9 @@
|
|||||||
#define CONTROLPANEL_H
|
#define CONTROLPANEL_H
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <variant>
|
||||||
|
|
||||||
|
#include "CallbackManager.h"
|
||||||
#include "../Graphics/Graphics.h"
|
#include "../Graphics/Graphics.h"
|
||||||
#include "../Interpreter/MachineState.h"
|
#include "../Interpreter/MachineState.h"
|
||||||
|
|
||||||
@@ -10,25 +12,21 @@
|
|||||||
class ControlPanel {
|
class ControlPanel {
|
||||||
std::shared_ptr<Graphics> graphics;
|
std::shared_ptr<Graphics> graphics;
|
||||||
std::shared_ptr<MachineState> machine_state;
|
std::shared_ptr<MachineState> machine_state;
|
||||||
|
std::shared_ptr<CallbackManager> callback_manager;
|
||||||
|
|
||||||
bool run = false;
|
bool run = false;
|
||||||
int steps = 1;
|
int steps = 1;
|
||||||
int speed = 100;
|
int speed = 100;
|
||||||
|
|
||||||
std::function<void(std::string)> rom_load_callback;
|
static SDLCALL void on_callback_load_rom(void* self, const char* const* filelist, int filter);
|
||||||
std::function<void()> reset_callback;
|
|
||||||
|
|
||||||
static SDLCALL void on_callback_load_rom(void* userdata, const char* const* filelist, int filter);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ControlPanel(
|
ControlPanel(
|
||||||
std::shared_ptr<Graphics> graphics,
|
std::shared_ptr<Graphics> graphics,
|
||||||
std::shared_ptr<MachineState> machine_state
|
std::shared_ptr<MachineState> machine_state,
|
||||||
|
std::shared_ptr<CallbackManager> callback_manager
|
||||||
);
|
);
|
||||||
|
|
||||||
void set_rom_load_callback(const std::function<void(std::string)>& callback);
|
|
||||||
void set_reset_callback(const std::function<void()>& callback);
|
|
||||||
|
|
||||||
void render();
|
void render();
|
||||||
void on_click_load_rom();
|
void on_click_load_rom();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,10 +1,15 @@
|
|||||||
#include "UIManager.h"
|
#include "UIManager.h"
|
||||||
|
|
||||||
UIManager::UIManager(std::shared_ptr<Graphics> graphics, std::shared_ptr<MachineState> machine_state):
|
UIManager::UIManager(
|
||||||
|
std::shared_ptr<Graphics> graphics,
|
||||||
|
std::shared_ptr<MachineState> machine_state,
|
||||||
|
std::shared_ptr<CallbackManager> callback_manager
|
||||||
|
) :
|
||||||
graphics{std::move(graphics)},
|
graphics{std::move(graphics)},
|
||||||
machine_state{std::move(machine_state)},
|
machine_state{std::move(machine_state)},
|
||||||
|
callback_manager{std::move(callback_manager)},
|
||||||
display{std::make_unique<Display>(this->graphics, this->machine_state)},
|
display{std::make_unique<Display>(this->graphics, this->machine_state)},
|
||||||
control_panel{std::make_unique<ControlPanel>(this->graphics, this->machine_state)} {}
|
control_panel{std::make_unique<ControlPanel>(this->graphics, this->machine_state, this->callback_manager)} {}
|
||||||
|
|
||||||
void UIManager::render() {
|
void UIManager::render() {
|
||||||
this->display->render();
|
this->display->render();
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#define UIMANAGER_H
|
#define UIMANAGER_H
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
#include "CallbackManager.h"
|
||||||
#include "ControlPanel.h"
|
#include "ControlPanel.h"
|
||||||
#include "Display.h"
|
#include "Display.h"
|
||||||
#include "../Graphics/Graphics.h"
|
#include "../Graphics/Graphics.h"
|
||||||
@@ -9,12 +10,17 @@
|
|||||||
class UIManager {
|
class UIManager {
|
||||||
std::shared_ptr<Graphics> graphics;
|
std::shared_ptr<Graphics> graphics;
|
||||||
std::shared_ptr<MachineState> machine_state;
|
std::shared_ptr<MachineState> machine_state;
|
||||||
|
std::shared_ptr<CallbackManager> callback_manager;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::unique_ptr<Display> display;
|
std::unique_ptr<Display> display;
|
||||||
std::unique_ptr<ControlPanel> control_panel;
|
std::unique_ptr<ControlPanel> control_panel;
|
||||||
|
|
||||||
public:
|
UIManager(
|
||||||
UIManager(std::shared_ptr<Graphics> graphics, std::shared_ptr<MachineState> machine_state);
|
std::shared_ptr<Graphics> graphics,
|
||||||
|
std::shared_ptr<MachineState> machine_state,
|
||||||
|
std::shared_ptr<CallbackManager> callback_manager
|
||||||
|
);
|
||||||
|
|
||||||
void render() ;
|
void render() ;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user