Viendo organizacion para ejecucion de eventos desde el control panel u otros elementos de ui,

falta que el uimanager haga de intermediario entre los callbacks?
This commit is contained in:
2025-06-24 01:19:32 -04:00
parent de3b9f6769
commit b186b25a9c
10 changed files with 137 additions and 30 deletions

View File

@@ -1,13 +1,15 @@
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
main.cpp ${CHIP8_SOURCES}
Machine.h Machine.cpp ${CHIP8_HEADERS}
Interpreter/Interpreter.h Interpreter/Interpreter.cpp
Graphics/Graphics.h Graphics/Graphics.cpp
UI/UIManager.h UI/UIManager.cpp
UI/Display.h UI/Display.cpp
UI/ControlPanel.h UI/ControlPanel.cpp
) )
target_link_libraries(${PROJECT_NAME} PRIVATE vendor) target_link_libraries(${PROJECT_NAME} PRIVATE vendor)

View File

@@ -8,10 +8,6 @@
#include "imgui_impl_sdl3.h" #include "imgui_impl_sdl3.h"
#include "imgui_impl_sdlrenderer3.h" #include "imgui_impl_sdlrenderer3.h"
void SDLWindowDestroyer::operator()(SDL_Window* window) const {
SDL_DestroyWindow(window);
}
Graphics::Graphics(): window_width{1366}, window_height{768}, main_scale{1.0f} { Graphics::Graphics(): window_width{1366}, window_height{768}, main_scale{1.0f} {
create_sdl(); create_sdl();
create_imgui(); create_imgui();
@@ -41,7 +37,7 @@ void Graphics::create_sdl() {
throw std::runtime_error(std::format("Couldn't create window/renderer: {}", SDL_GetError())); throw std::runtime_error(std::format("Couldn't create window/renderer: {}", SDL_GetError()));
} }
this->window = std::unique_ptr<SDL_Window, SDLWindowDestroyer>(raw_window); this->window = std::shared_ptr<SDL_Window>(raw_window, SDL_DestroyWindow);
this->renderer = std::shared_ptr<SDL_Renderer>(raw_renderer, SDL_DestroyRenderer); this->renderer = std::shared_ptr<SDL_Renderer>(raw_renderer, SDL_DestroyRenderer);
SDL_SetRenderVSync(this->renderer.get(), 1); SDL_SetRenderVSync(this->renderer.get(), 1);
@@ -69,6 +65,9 @@ void Graphics::create_imgui() const {
std::shared_ptr<SDL_Renderer> Graphics::get_renderer() { std::shared_ptr<SDL_Renderer> Graphics::get_renderer() {
return this->renderer; return this->renderer;
} }
std::shared_ptr<SDL_Window> Graphics::get_window() {
return this->window;
}
void Graphics::start() const { void Graphics::start() const {
ImGui_ImplSDLRenderer3_NewFrame(); ImGui_ImplSDLRenderer3_NewFrame();

View File

@@ -13,7 +13,7 @@ class Graphics {
int window_height; int window_height;
float main_scale; float main_scale;
std::unique_ptr<SDL_Window, SDLWindowDestroyer> window; std::shared_ptr<SDL_Window> window;
std::shared_ptr<SDL_Renderer> renderer; std::shared_ptr<SDL_Renderer> renderer;
void create_sdl(); void create_sdl();
@@ -24,6 +24,7 @@ public:
void start() const; void start() const;
void end() const; void end() const;
std::shared_ptr<SDL_Renderer> get_renderer(); std::shared_ptr<SDL_Renderer> get_renderer();
std::shared_ptr<SDL_Window> get_window();
}; };
#endif //GRAPHICS_H #endif //GRAPHICS_H

View File

@@ -0,0 +1,27 @@
#include "MachineState.h"
MachineState::MachineState():
memory{},
v{},
stack{},
display{},
keyboard{0},
pc{0x200},
sp{0},
i{0},
dt{0},
st{0}
{}
void MachineState::reset() {
this->memory.fill(0);
this->v.fill(0);
this->stack.fill(0);
this->display.fill(false);
this->keyboard = 0;
this->pc = 0x200;
this->sp = 0;
this->i = 0;
this->dt = 0;
this->st = 0;
}

View File

@@ -4,16 +4,20 @@
#include <cstdint> #include <cstdint>
struct MachineState { struct MachineState {
std::array<uint8_t, 4096> memory{}; std::array<uint8_t, 4096> memory;
std::array<uint16_t, 16> v{}; std::array<uint16_t, 16> v;
std::array<uint16_t, 16> stack{}; std::array<uint16_t, 16> stack;
std::array<bool, 2048> display{}; std::array<bool, 2048> display;
uint16_t keyboard = 0; uint16_t keyboard;
uint16_t pc = 0x200; uint16_t pc;
uint8_t sp = 0; uint8_t sp;
uint16_t i = 0; uint16_t i;
uint8_t dt = 0; uint8_t dt;
uint8_t st = 0; uint8_t st;
MachineState();
void reset();
}; };
#endif //MACHINESTATE_H #endif //MACHINESTATE_H

View File

@@ -1,5 +1,8 @@
#include "Machine.h" #include "Machine.h"
#include <iostream>
#include <bits/ostream.tcc>
#include "Graphics/Graphics.h" #include "Graphics/Graphics.h"
#include "Interpreter/Interpreter.h" #include "Interpreter/Interpreter.h"
#include "SDL3/SDL.h" #include "SDL3/SDL.h"
@@ -18,7 +21,20 @@ Machine::Machine():
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} {
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();
@@ -49,3 +65,10 @@ void Machine::execute_interpreter() {
this->accumulator -= this->target_cycle_time; this->accumulator -= this->target_cycle_time;
} }
} }
void Machine::on_rom_load(const std::string& path) const {
std::cout << path << std::endl;
}
void Machine::on_reset() const {
this->machine_state->reset();
}

View File

@@ -19,7 +19,9 @@ class Machine {
double accumulator; double accumulator;
double target_cycle_time; double target_cycle_time;
void execute_interpreter(); void execute_interpreter();
void on_rom_load(const std::string& path) const;
void on_reset() const;
public: public:
Machine(); Machine();

View File

@@ -3,17 +3,29 @@
#include <format> #include <format>
#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)}, ): graphics{std::move(graphics)},
machine_state{std::move(machine_state)} {} machine_state{std::move(machine_state)} {}
void ControlPanel::set_rom_load_callback(const std::function<void(std::string)>& callback) {
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);
if (ImGui::Begin("Chip-8 - Controls")) { if (ImGui::Begin("Chip-8 - Controls")) {
ImGui::Button("Load Rom", full_width); if (ImGui::Button("Load Rom", full_width)) {
this->on_click_load_rom();
}
if (ImGui::Button(run ? "Pause" : "Run", full_width)) { if (ImGui::Button(run ? "Pause" : "Run", full_width)) {
this->run = !run; this->run = !run;
} }
@@ -37,10 +49,36 @@ void ControlPanel::render() {
ImGui::SeparatorText(""); ImGui::SeparatorText("");
ImGui::Button("Reset", full_width); if (ImGui::Button("Reset", full_width)) {
if (this->reset_callback) {
this->reset_callback();
}
}
ImGui::Button("Reload ROM", full_width); ImGui::Button("Reload ROM", full_width);
} }
ImGui::End(); ImGui::End();
} }
void ControlPanel::on_click_load_rom() {
constexpr SDL_DialogFileFilter filters[] = {
{"CHIP8 ROMs", "ch8"},
{"All files", "*"}
};
SDL_ShowOpenFileDialog(on_callback_load_rom, this, graphics->get_window().get(), filters, std::size(filters), nullptr, false);
}
void ControlPanel::on_callback_load_rom(void* userdata, const char* const* filelist, int filter) {
const auto control_panel = static_cast<ControlPanel*>(userdata);
if (!control_panel->rom_load_callback) {
return;
}
if (!filelist || !*filelist) {
return;
}
control_panel->rom_load_callback(*filelist);
}

View File

@@ -1,5 +1,6 @@
#ifndef CONTROLPANEL_H #ifndef CONTROLPANEL_H
#define CONTROLPANEL_H #define CONTROLPANEL_H
#include <functional>
#include <memory> #include <memory>
#include "../Graphics/Graphics.h" #include "../Graphics/Graphics.h"
@@ -13,13 +14,23 @@ class ControlPanel {
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;
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
); );
void render() ; void set_rom_load_callback(const std::function<void(std::string)>& callback);
void set_reset_callback(const std::function<void()>& callback);
void render();
void on_click_load_rom();
}; };

View File

@@ -9,7 +9,7 @@
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;
public:
std::unique_ptr<Display> display; std::unique_ptr<Display> display;
std::unique_ptr<ControlPanel> control_panel; std::unique_ptr<ControlPanel> control_panel;