Can now pause, step, play, and restart the VM. Gross implementation but it's a start.

master
Zed A. Shaw 1 month ago
parent 89ce8b460d
commit 1c5f5de100
  1. 2
      src/chip8.hpp
  2. 47
      src/control_panel.cpp
  3. 3
      src/control_panel.hpp
  4. 1
      src/display.cpp
  5. 14
      src/main.cpp

@ -41,6 +41,8 @@ class Chip8 {
0xF0, 0x80, 0xF0, 0x80, 0x80 // F 0xF0, 0x80, 0xF0, 0x80, 0x80 // F
}; };
bool needs_render = true; bool needs_render = true;
bool needs_restart = false;
bool paused = false;
std::default_random_engine randGen; std::default_random_engine randGen;
std::uniform_int_distribution<uint8_t> randByte; std::uniform_int_distribution<uint8_t> randByte;

@ -8,23 +8,38 @@ ControlPanel::ControlPanel() {
void ControlPanel::init(sf::Vector2f size) { void ControlPanel::init(sf::Vector2f size) {
$gui.position(0, size.y, size.x, WINDOW_HEIGHT - size.y); $gui.position(0, size.y, size.x, WINDOW_HEIGHT - size.y);
$gui.layout( $gui.layout(
"[pause |*%(200, 400)code|_]" "[Pause |*%(200, 400)code|_]"
"[step |_|_]" "[Step |_|_]"
"[play |_|_]" "[Play |_|_]"
"[restart|_|_]" "[Restart|_|_]"
); );
for(auto& [name, cell] : $gui.cells()) { for(auto& [name, cell] : $gui.cells()) {
auto id = $gui.entity(name); auto id = $gui.entity(name);
$gui.set<guecs::Rectangle>(id, {}); $gui.set<guecs::Rectangle>(id, {});
$gui.set<guecs::Text>(id, {guecs::to_wstring(name)}); $gui.set<guecs::Text>(id, {guecs::to_wstring(name)});
if(name != "code") {
$gui.set<guecs::Clickable>(id, {[name](auto) {
fmt::println("CLICKED {}", name);
}});
}
} }
auto id = $gui.entity("Pause");
$gui.set<guecs::Clickable>(id, {[&](auto) {
$paused = true;
}});
id = $gui.entity("Step");
$gui.set<guecs::Clickable>(id, {[&](auto) {
$step = true;
}});
id = $gui.entity("Play");
$gui.set<guecs::Clickable>(id, {[&](auto) {
$paused = false;
}});
id = $gui.entity("Restart");
$gui.set<guecs::Clickable>(id, {[&](auto) {
$restart = true;
}});
$gui.init(); $gui.init();
} }
@ -33,6 +48,20 @@ void ControlPanel::render(sf::RenderTarget& window) {
} }
void ControlPanel::update(Chip8& vm) { void ControlPanel::update(Chip8& vm) {
if($restart) {
vm.needs_restart = true;
$restart = false;
return;
}
vm.paused = $paused;
if($step && $paused) {
vm.Cycle();
vm.needs_render = true;
}
$step = false;
} }
bool ControlPanel::mouse(float x, float y, guecs::Modifiers mods) { bool ControlPanel::mouse(float x, float y, guecs::Modifiers mods) {

@ -6,6 +6,9 @@
struct ControlPanel { struct ControlPanel {
guecs::UI $gui; guecs::UI $gui;
bool $paused = false;
bool $step = false;
bool $restart = false;
ControlPanel(); ControlPanel();

@ -53,6 +53,7 @@ void Display::update(Chip8& vm) {
handle_inputs(vm); handle_inputs(vm);
$texture.update((uint8_t *)(vm.video), {64, 32}, {0,0}); $texture.update((uint8_t *)(vm.video), {64, 32}, {0,0});
$status.update(vm); $status.update(vm);
$control.update(vm);
} }
void Display::render() { void Display::render() {

@ -36,9 +36,11 @@ int main(int argc, char* argv[]) {
Stats update_stats; Stats update_stats;
while (display.active()) { while (display.active()) {
auto t = cycle_stats.time_start(); if(!chip8.paused) {
chip8.Cycle(); auto t = cycle_stats.time_start();
cycle_stats.sample_time(t); chip8.Cycle();
cycle_stats.sample_time(t);
}
if(chip8.needs_render) { if(chip8.needs_render) {
auto ut = update_stats.time_start(); auto ut = update_stats.time_start();
@ -49,6 +51,12 @@ int main(int argc, char* argv[]) {
display.render(); display.render();
render_stats.sample_time(rt); render_stats.sample_time(rt);
} }
if(chip8.needs_restart) {
Chip8 new_chip8;
new_chip8.LoadROM(romFilename);
chip8 = new_chip8;
}
} }
cycle_stats.dump("CYCLE TIMES"); cycle_stats.dump("CYCLE TIMES");

Loading…
Cancel
Save