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:
@@ -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)
|
||||||
@@ -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();
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
27
src/Interpreter/MachineState.cpp
Normal file
27
src/Interpreter/MachineState.cpp
Normal 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;
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user