144 lines
3.4 KiB
C++
144 lines
3.4 KiB
C++
#include "ControlPanel.h"
|
|
|
|
#include <format>
|
|
#include <iostream>
|
|
#include <ranges>
|
|
|
|
#include "CallbackManager.h"
|
|
#include "imgui.h"
|
|
|
|
|
|
ControlPanel::ControlPanel(
|
|
std::shared_ptr<Graphics> graphics,
|
|
std::shared_ptr<MachineState> machine_state,
|
|
std::shared_ptr<CallbackManager> callback_manager
|
|
) : graphics{std::move(graphics)},
|
|
machine_state{std::move(machine_state)},
|
|
callback_manager{std::move(callback_manager)}
|
|
{
|
|
this->callback_manager->ips_callback.push_back(std::bind(
|
|
&ControlPanel::initial_ips_load,
|
|
this,
|
|
std::placeholders::_1
|
|
));
|
|
}
|
|
|
|
void ControlPanel::render()
|
|
{
|
|
int starting_speed = this->ips;
|
|
|
|
constexpr auto full_width = ImVec2(-FLT_MIN, 0.0f);
|
|
|
|
if (ImGui::Begin("Chip-8 - Controls"))
|
|
{
|
|
if (ImGui::Button("Load Rom", full_width))
|
|
{
|
|
this->on_click_load_rom();
|
|
}
|
|
|
|
if (ImGui::Button(run ? "Pause" : "Run", full_width))
|
|
{
|
|
this->run = !run;
|
|
if (this->run)
|
|
{
|
|
this->callback_manager->trigger(this->callback_manager->resume_callback);
|
|
}
|
|
else
|
|
{
|
|
this->callback_manager->trigger(this->callback_manager->stop_callback);
|
|
}
|
|
}
|
|
|
|
ImGui::Text("Status: %s", "Stopped");
|
|
|
|
ImGui::SeparatorText("Debug");
|
|
|
|
|
|
if (ImGui::Button("Step One", full_width))
|
|
{
|
|
this->callback_manager->trigger(this->callback_manager->step_callback, 1);
|
|
}
|
|
|
|
if (ImGui::Button(std::format("Step +{}", steps).data(), full_width))
|
|
{
|
|
this->callback_manager->trigger(this->callback_manager->step_callback, steps);
|
|
}
|
|
|
|
ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x);
|
|
ImGui::InputInt("##steps", &steps);
|
|
ImGui::PopItemWidth();
|
|
|
|
|
|
ImGui::SeparatorText("Emulation speed (IPS)");
|
|
|
|
ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x);
|
|
ImGui::InputInt("##speed", &ips);
|
|
ImGui::PopItemWidth();
|
|
|
|
ImGui::SeparatorText("");
|
|
|
|
if (ImGui::Button("Reset", full_width))
|
|
{
|
|
this->callback_manager->trigger(this->callback_manager->reset_callback);
|
|
}
|
|
if (ImGui::Button("Reload ROM", full_width))
|
|
{
|
|
this->callback_manager->trigger(this->callback_manager->reload_callback);
|
|
}
|
|
}
|
|
|
|
if (ips < 0)
|
|
{
|
|
ips = 0;
|
|
}
|
|
if (steps < 1)
|
|
{
|
|
steps = 1;
|
|
}
|
|
|
|
if (starting_speed != ips)
|
|
{
|
|
this->callback_manager->trigger(this->callback_manager->ips_callback, ips);
|
|
}
|
|
|
|
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),
|
|
SDL_GetCurrentDirectory(),
|
|
false
|
|
);
|
|
}
|
|
|
|
void ControlPanel::on_callback_load_rom(void* self, const char* const* filelist, int)
|
|
{
|
|
const auto control_panel = static_cast<ControlPanel*>(self);
|
|
|
|
if (!filelist || !*filelist)
|
|
{
|
|
return;
|
|
}
|
|
|
|
control_panel->callback_manager->trigger(
|
|
control_panel->callback_manager->rom_load_callback,
|
|
std::string(filelist[0])
|
|
);
|
|
}
|
|
|
|
void ControlPanel::initial_ips_load(int ips)
|
|
{
|
|
this->ips = ips;
|
|
}
|