diff --git a/Makefile b/Makefile index 91e73a3..b1ad697 100644 --- a/Makefile +++ b/Makefile @@ -15,13 +15,13 @@ debug_build: meson compile -j 4 -C builddir run: build - ./builddir/chip8.exe 1 1 ./roms/test_opcode.ch8 + ./builddir/b8rk.exe 1 1 ./roms/test_opcode.ch8 debug: build gdb --nx -x .gdbinit --ex run --args builddir/runtests.exe debug_run: build - gdb --nx -x .gdbinit --batch --ex run --ex bt --ex q --args builddir/chip8.exe 1 1 ./roms/test_opcode.ch8 + gdb --nx -x .gdbinit --batch --ex run --ex bt --ex q --args builddir/b8rk.exe 1 1 ./roms/test_opcode.ch8 clean: meson compile --clean -C builddir diff --git a/meson.build b/meson.build index 40386af..b4e4114 100644 --- a/meson.build +++ b/meson.build @@ -1,4 +1,4 @@ -project('chip8', 'cpp', +project('b8rk', 'cpp', version: '0.1.0', default_options: [ 'cpp_std=c++23', @@ -83,9 +83,10 @@ dependencies += [ sources = [ 'src/dbc.cpp', 'src/chip8.cpp', + 'src/stats.cpp', ] -executable('chip8', +executable('b8rk', sources + [ 'src/main.cpp' ], cpp_args: cpp_args, link_args: link_args, diff --git a/roms/test_opcode.ch8 b/roms/test_opcode.ch8 new file mode 100644 index 0000000..f540f69 Binary files /dev/null and b/roms/test_opcode.ch8 differ diff --git a/src/chip8.cpp b/src/chip8.cpp index b9867e4..b1dc33f 100644 --- a/src/chip8.cpp +++ b/src/chip8.cpp @@ -106,9 +106,6 @@ void Chip8::Cycle() { if(soundTimer > 0) { --soundTimer; } - - fmt::println("opcode: {}, delay: {}, sound: {}, pc: {}", - opcode, delayTimer, soundTimer, pc); } diff --git a/src/main.cpp b/src/main.cpp index 44c9163..c1c27b8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -10,7 +10,7 @@ #include #include "dbc.hpp" #include "chip8.hpp" - +#include "stats.hpp" struct Display { sf::RenderWindow& window; @@ -92,10 +92,27 @@ int main(int argc, char* argv[]) { window.setVerticalSyncEnabled(true); Display display{window, {0, 0}, {1000, 1000}}; + Stats cycle_stats; + Stats render_stats; + + while (display.active()) { + auto currentTime = std::chrono::high_resolution_clock::now(); + float dt = std::chrono::duration(currentTime - lastCycleTime).count(); + + if (dt > cycleDelay) + { + lastCycleTime = currentTime; + auto t = cycle_stats.time_start(); + chip8.Cycle(); + cycle_stats.sample_time(t); + } - while (true) { - chip8.Cycle(); + auto t = render_stats.time_start(); display.update(chip8); display.render(); + render_stats.sample_time(t); } + + cycle_stats.dump("cycle times"); + render_stats.dump("render times"); } diff --git a/src/stats.cpp b/src/stats.cpp new file mode 100644 index 0000000..eb15f47 --- /dev/null +++ b/src/stats.cpp @@ -0,0 +1,11 @@ +#include "stats.hpp" +#include +#include "dbc.hpp" + +void Stats::dump(std::string msg) +{ + dbc::log($F("{}: sum: {}, sumsq: {}, n: {}, " + "min: {}, max: {}, mean: {}, stddev: {}", + msg, sum, sumsq, n, min, max, mean(), + stddev())); +} diff --git a/src/stats.hpp b/src/stats.hpp new file mode 100644 index 0000000..8c8749e --- /dev/null +++ b/src/stats.hpp @@ -0,0 +1,59 @@ +#pragma once +#include +#include + +struct Stats { + using TimeBullshit = std::chrono::time_point; + + double sum = 0.0; + double sumsq = 0.0; + double n = 0.0; + double min = 0.0; + double max = 0.0; + + inline void reset() { + sum = 0.0; + sumsq = 0.0; + n = 0.0; + min = 0.0; + max = 0.0; + } + + inline double mean() { + return sum / n; + } + + inline double stddev() { + return std::sqrt((sumsq - (sum * sum / n)) / (n - 1)); + } + + inline void sample(double s) { + sum += s; + sumsq += s * s; + + if (n == 0) { + min = s; + max = s; + } else { + if (min > s) min = s; + if (max < s) max = s; + } + + n += 1; + } + + inline TimeBullshit time_start() { + return std::chrono::high_resolution_clock::now(); + } + + inline void sample_time(TimeBullshit start) { + auto end = std::chrono::high_resolution_clock::now(); + auto elapsed = std::chrono::duration(end - start); + + if(elapsed.count() > 0.0) { + sample(1.0/elapsed.count()); + } + } + + void dump(std::string msg=""); +};