From 9ce2fa6124abb1c16352293307b27e3f2a61dbe0 Mon Sep 17 00:00:00 2001 From: Robert Date: Sat, 28 Jan 2023 03:41:04 +0100 Subject: [PATCH 1/5] supply rom as cmd line argument --- src/Application.cpp | 8 ++++---- src/Application.hpp | 4 ++-- src/Bus.cpp | 4 ++-- src/Bus.hpp | 2 +- src/debugger/Debugger.cpp | 2 +- src/debugger/imgui.ini | 13 +++++++++++++ src/main.cpp | 10 ++++++++-- 7 files changed, 31 insertions(+), 12 deletions(-) create mode 100644 src/debugger/imgui.ini diff --git a/src/Application.cpp b/src/Application.cpp index 62f4570..d6d5599 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -14,14 +14,14 @@ #include "Debugger.hpp" #include "gfx/Window.hpp" -void Application::Launch() +void Application::Launch(const char* rom) { glfwInit(); Application* app = nullptr; try { - app = new Application; + app = new Application(rom); } catch (const std::runtime_error& err) { @@ -43,7 +43,7 @@ void Application::Launch() glfwTerminate(); } -Application::Application() : +Application::Application(const char* rom) : bus(nullptr), window(nullptr) { LOG_CORE_INFO("Creating window"); @@ -93,7 +93,7 @@ Application::Application() : throw err; } - bus = new Bus(screen); + bus = new Bus(rom, screen); debugger = new Debugger(bus); } diff --git a/src/Application.hpp b/src/Application.hpp index 1001bd4..16ba5ff 100644 --- a/src/Application.hpp +++ b/src/Application.hpp @@ -14,10 +14,10 @@ public: /** * @brief Create and launch a new application. */ - static void Launch(); + static void Launch(const char* rom); private: - Application(); + Application(const char* rom); ~Application(); /** diff --git a/src/Bus.cpp b/src/Bus.cpp index cc9a5d9..cc1e167 100644 --- a/src/Bus.cpp +++ b/src/Bus.cpp @@ -5,7 +5,7 @@ #include "controllers/StandardController.hpp" -Bus::Bus(Screen* screen) : +Bus::Bus(const char* rom, Screen* screen) : cpu(this), ppu(this, screen), apu(this), cartridge(this) { LOG_CORE_INFO("Allocating RAM"); @@ -16,7 +16,7 @@ Bus::Bus(Screen* screen) : palettes = std::vector(0x20, 0); LOG_CORE_INFO("Inserting cartridge"); - cartridge.Load("roms/mario.nes"); + cartridge.Load(rom); LOG_CORE_INFO("Powering up CPU"); cpu.Powerup(); diff --git a/src/Bus.hpp b/src/Bus.hpp index 9a65c9b..5536f6d 100644 --- a/src/Bus.hpp +++ b/src/Bus.hpp @@ -25,7 +25,7 @@ class Bus friend class Palettes; public: - Bus(Screen* screen); + Bus(const char* rom, Screen* screen); /** * @brief Reboot the NES. diff --git a/src/debugger/Debugger.cpp b/src/debugger/Debugger.cpp index 772911d..17b4386 100644 --- a/src/debugger/Debugger.cpp +++ b/src/debugger/Debugger.cpp @@ -61,7 +61,7 @@ bool Debugger::Frame() return true; } - return false; + return true; } bool Debugger::Update() diff --git a/src/debugger/imgui.ini b/src/debugger/imgui.ini new file mode 100644 index 0000000..a04ff2b --- /dev/null +++ b/src/debugger/imgui.ini @@ -0,0 +1,13 @@ +[Window][Debug##Default] +Pos=60,60 +Size=400,400 +Collapsed=0 + +[Window][Debugger] +ViewportPos=1419,173 +ViewportId=0x289D2C3F +Size=400,600 +Collapsed=0 + +[Docking][Data] + diff --git a/src/main.cpp b/src/main.cpp index 75ba410..0339887 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,10 +1,16 @@ #include "Application.hpp" #include "Log.hpp" -int main() +int main(int argc, char** argv) { Log::Init(); - Application::Launch(); + + if (argc != 2) { + LOG_CORE_FATAL("Usage: {0} ", argv[0]); + return -1; + } + + Application::Launch(argv[1]); return 0; } From e9264127c5c0a0f7c942e57da543e85bddff1822 Mon Sep 17 00:00:00 2001 From: Robert Date: Sun, 29 Jan 2023 17:42:46 +0100 Subject: [PATCH 2/5] add framerate limiter --- imgui.ini | 13 +++++++++++++ src/Application.cpp | 8 ++++++++ src/Application.hpp | 4 ++++ src/debugger/Debugger.cpp | 4 ++++ src/gfx/Window.cpp | 2 ++ src/gfx/imgui.ini | 12 ++++++++++++ src/imgui.ini | 30 ++++++++++++++++++++++++++++++ 7 files changed, 73 insertions(+) create mode 100644 imgui.ini create mode 100644 src/gfx/imgui.ini create mode 100644 src/imgui.ini diff --git a/imgui.ini b/imgui.ini new file mode 100644 index 0000000..67c9899 --- /dev/null +++ b/imgui.ini @@ -0,0 +1,13 @@ +[Window][Debug##Default] +Pos=60,60 +Size=400,400 +Collapsed=0 + +[Window][Debugger] +ViewportPos=1587,230 +ViewportId=0x289D2C3F +Size=400,600 +Collapsed=0 + +[Docking][Data] + diff --git a/src/Application.cpp b/src/Application.cpp index d6d5599..af1c3b3 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -140,5 +140,13 @@ bool Application::Update() debugger->Render(); window->End(); + std::chrono::microseconds frametime = std::chrono::duration_cast(std::chrono::steady_clock::now() - lastFrameTime); + lastFrameTime = std::chrono::steady_clock::now(); + + if (frametime < std::chrono::microseconds(1000000 / 60)) { + std::this_thread::sleep_for(std::chrono::microseconds(1000000 / 60) - frametime); + } + + return !window->ShouldClose(); } diff --git a/src/Application.hpp b/src/Application.hpp index 16ba5ff..02d4168 100644 --- a/src/Application.hpp +++ b/src/Application.hpp @@ -1,5 +1,7 @@ #pragma once +#include + class Bus; class Window; class Debugger; @@ -33,4 +35,6 @@ private: Bus* bus; Screen* screen; Debugger* debugger; + + std::chrono::steady_clock::time_point lastFrameTime; }; diff --git a/src/debugger/Debugger.cpp b/src/debugger/Debugger.cpp index 17b4386..f745ff0 100644 --- a/src/debugger/Debugger.cpp +++ b/src/debugger/Debugger.cpp @@ -161,6 +161,10 @@ void Debugger::Render() ImGui::InputScalar("Reset Vector", ImGuiDataType_U16, &resetVector, (const void*)0, (const void*)0, "%04X", ImGuiInputTextFlags_CharsHexadecimal); } + ImGui::Separator(); + + ImGui::Text("FPS: %f", ImGui::GetIO().Framerate); + for (DebugWindow* window : windows) { if (window->isOpen) window->OnRender(); diff --git a/src/gfx/Window.cpp b/src/gfx/Window.cpp index 795067d..7cd0707 100644 --- a/src/gfx/Window.cpp +++ b/src/gfx/Window.cpp @@ -11,6 +11,7 @@ Window::Window(uint16_t width, uint16_t height, const std::string& title) : handle(nullptr) { glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); + handle = glfwCreateWindow(width, height, title.c_str(), nullptr, nullptr); if (handle == nullptr) { @@ -20,6 +21,7 @@ Window::Window(uint16_t width, uint16_t height, const std::string& title) : } glfwMakeContextCurrent(handle); + glfwSwapInterval(1); Input::SetWindow(this); } diff --git a/src/gfx/imgui.ini b/src/gfx/imgui.ini new file mode 100644 index 0000000..8eea4ed --- /dev/null +++ b/src/gfx/imgui.ini @@ -0,0 +1,12 @@ +[Window][Debug##Default] +Pos=60,60 +Size=400,400 +Collapsed=0 + +[Window][Debugger] +Pos=217,104 +Size=400,325 +Collapsed=0 + +[Docking][Data] + diff --git a/src/imgui.ini b/src/imgui.ini new file mode 100644 index 0000000..c011a8d --- /dev/null +++ b/src/imgui.ini @@ -0,0 +1,30 @@ +[Window][Debug##Default] +Pos=60,60 +Size=400,400 +Collapsed=0 + +[Window][Debugger] +Pos=506,49 +Size=490,229 +Collapsed=0 + +[Window][Disassembler] +ViewportPos=1326,634 +ViewportId=0x85E8BACF +Size=400,400 +Collapsed=0 + +[Window][CPU Watch] +ViewportPos=915,545 +ViewportId=0x759989B3 +Size=400,400 +Collapsed=0 + +[Window][Palettes] +ViewportPos=1756,613 +ViewportId=0x550214C1 +Size=400,291 +Collapsed=0 + +[Docking][Data] + From 57e0eb2fbe38245a635531da8f2963ec54f38141 Mon Sep 17 00:00:00 2001 From: Robert Date: Sun, 29 Jan 2023 20:02:20 +0100 Subject: [PATCH 3/5] remove ini files --- imgui.ini | 13 ------------- src/debugger/imgui.ini | 13 ------------- src/gfx/Window.cpp | 2 +- src/gfx/imgui.ini | 12 ------------ src/imgui.ini | 30 ------------------------------ 5 files changed, 1 insertion(+), 69 deletions(-) delete mode 100644 imgui.ini delete mode 100644 src/debugger/imgui.ini delete mode 100644 src/gfx/imgui.ini delete mode 100644 src/imgui.ini diff --git a/imgui.ini b/imgui.ini deleted file mode 100644 index 67c9899..0000000 --- a/imgui.ini +++ /dev/null @@ -1,13 +0,0 @@ -[Window][Debug##Default] -Pos=60,60 -Size=400,400 -Collapsed=0 - -[Window][Debugger] -ViewportPos=1587,230 -ViewportId=0x289D2C3F -Size=400,600 -Collapsed=0 - -[Docking][Data] - diff --git a/src/debugger/imgui.ini b/src/debugger/imgui.ini deleted file mode 100644 index a04ff2b..0000000 --- a/src/debugger/imgui.ini +++ /dev/null @@ -1,13 +0,0 @@ -[Window][Debug##Default] -Pos=60,60 -Size=400,400 -Collapsed=0 - -[Window][Debugger] -ViewportPos=1419,173 -ViewportId=0x289D2C3F -Size=400,600 -Collapsed=0 - -[Docking][Data] - diff --git a/src/gfx/Window.cpp b/src/gfx/Window.cpp index 7cd0707..15f3885 100644 --- a/src/gfx/Window.cpp +++ b/src/gfx/Window.cpp @@ -21,7 +21,7 @@ Window::Window(uint16_t width, uint16_t height, const std::string& title) : } glfwMakeContextCurrent(handle); - glfwSwapInterval(1); + glfwSwapInterval(0); Input::SetWindow(this); } diff --git a/src/gfx/imgui.ini b/src/gfx/imgui.ini deleted file mode 100644 index 8eea4ed..0000000 --- a/src/gfx/imgui.ini +++ /dev/null @@ -1,12 +0,0 @@ -[Window][Debug##Default] -Pos=60,60 -Size=400,400 -Collapsed=0 - -[Window][Debugger] -Pos=217,104 -Size=400,325 -Collapsed=0 - -[Docking][Data] - diff --git a/src/imgui.ini b/src/imgui.ini deleted file mode 100644 index c011a8d..0000000 --- a/src/imgui.ini +++ /dev/null @@ -1,30 +0,0 @@ -[Window][Debug##Default] -Pos=60,60 -Size=400,400 -Collapsed=0 - -[Window][Debugger] -Pos=506,49 -Size=490,229 -Collapsed=0 - -[Window][Disassembler] -ViewportPos=1326,634 -ViewportId=0x85E8BACF -Size=400,400 -Collapsed=0 - -[Window][CPU Watch] -ViewportPos=915,545 -ViewportId=0x759989B3 -Size=400,400 -Collapsed=0 - -[Window][Palettes] -ViewportPos=1756,613 -ViewportId=0x550214C1 -Size=400,291 -Collapsed=0 - -[Docking][Data] - From f495a88081081147f4688dce17df61476858b82e Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 30 Jan 2023 15:46:43 +0100 Subject: [PATCH 4/5] add prototype for mapper 01 --- .gitignore | 1 + src/mappers/Mapper001.cpp | 2 +- vendor/imgui | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 7c329a2..3f787ef 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ out/ build/ *.json +*.ini *.nes !roms/nestest.nes diff --git a/src/mappers/Mapper001.cpp b/src/mappers/Mapper001.cpp index 0e22acf..6973ca3 100644 --- a/src/mappers/Mapper001.cpp +++ b/src/mappers/Mapper001.cpp @@ -36,7 +36,7 @@ Byte Mapper001::ReadCPU(Word addr) break; } - return PRG_ROM[addr & (0x4000 * selectedBank - 1)]; + return PRG_ROM[(addr & (0x4000 * selectedBank - 1)) & 0x7FFF]; } return 0x00; diff --git a/vendor/imgui b/vendor/imgui index 8639a2f..88dfd85 160000 --- a/vendor/imgui +++ b/vendor/imgui @@ -1 +1 @@ -Subproject commit 8639a2f9f8d6d53f4c7a221579de5871051153d9 +Subproject commit 88dfd85e9296fc03ac858f66cc6507ba443294ef From 650414865461c075ec4efd00c4ee947ccb1d1bfb Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 30 Jan 2023 17:14:20 +0100 Subject: [PATCH 5/5] add logger module --- CMakeLists.txt | 3 ++ src/CMakeLists.txt | 15 +++++++- src/debugger/Debugger.cpp | 5 +++ src/debugger/Logger.cpp | 80 +++++++++++++++++++++++++++++++++++++++ src/debugger/Logger.hpp | 29 ++++++++++++++ 5 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 src/debugger/Logger.cpp create mode 100644 src/debugger/Logger.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index f72251b..92952b7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,6 +5,9 @@ cmake_minimum_required (VERSION 3.8) project ("NES Emulator") +set(CMAKE_CXX_STANDARD_REQUIRED 17) +set(CMAKE_CXX_STANDARD 17) + find_package(glfw3) if(NOT glfw3_FOUND) add_subdirectory("vendor/glfw") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 593c13c..00cd492 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -7,13 +7,26 @@ add_executable(nesemu "mappers/Mapper000.cpp" "Log.cpp" "PPU.cpp" + "APU.cpp" "gfx/Window.cpp" + "gfx/Input.cpp" + "gfx/Screen.cpp" "debugger/CPUWatcher.cpp" "debugger/Debugger.cpp" "debugger/PPUWatcher.cpp" "debugger/Disassembler.cpp" "debugger/MemoryViewer.cpp" - "debugger/NametableViewer.cpp" "ControllerPort.cpp" "controllers/StandardController.cpp" "gfx/Input.cpp" "debugger/ControllerPortViewer.cpp" "gfx/Screen.cpp" "debugger/Palettes.cpp" "APU.cpp" "debugger/PatternTableViewer.cpp" "mappers/Mapper003.cpp" "mappers/Mapper001.cpp" "debugger/OAMViewer.cpp") + "debugger/NametableViewer.cpp" + "debugger/ControllerPortViewer.cpp" + "debugger/PatternTableViewer.cpp" + "debugger/OAMViewer.cpp" + "debugger/Palettes.cpp" + "debugger/Logger.cpp" + "ControllerPort.cpp" + "controllers/StandardController.cpp" + "mappers/Mapper003.cpp" + "mappers/Mapper001.cpp" + ) target_include_directories(nesemu PRIVATE mappers diff --git a/src/debugger/Debugger.cpp b/src/debugger/Debugger.cpp index f745ff0..b00e058 100644 --- a/src/debugger/Debugger.cpp +++ b/src/debugger/Debugger.cpp @@ -14,6 +14,7 @@ #include "PatternTableViewer.hpp" #include "ControllerPortViewer.hpp" #include "Palettes.hpp" +#include "Logger.hpp" Debugger::Debugger(Bus* bus) : bus(bus) @@ -32,6 +33,9 @@ Debugger::Debugger(Bus* bus) : windows.push_back(new PatternTableViewer(this, bus->cartridge.GetMapper())); windows.push_back(new ControllerPortViewer(this, &bus->controllerPort)); windows.push_back(new Palettes(this, bus)); + + Logger::Init(this); + windows.push_back(Logger::GetInstance()); } Debugger::~Debugger() @@ -42,6 +46,7 @@ Debugger::~Debugger() bool Debugger::Frame() { + Logger::GetInstance()->Log("Debugger", "Frame!\n"); try { while (!bus->ppu.IsFrameDone()) diff --git a/src/debugger/Logger.cpp b/src/debugger/Logger.cpp new file mode 100644 index 0000000..73b7fd8 --- /dev/null +++ b/src/debugger/Logger.cpp @@ -0,0 +1,80 @@ +#include "Logger.hpp" + +#include + +Logger::Logger(Debugger* debugger) : + DebugWindow("Log", debugger), autoScroll(true) +{ + buffer.clear(); + + offsets.clear(); + offsets.push_back(0); +} + +void Logger::Init(Debugger* debugger) +{ + if (Logger::instance != nullptr) { + return; + } + + Logger::instance = new Logger(debugger); +} + +void Logger::Log(const char* module, const char* fmt, ...) +{ + int old_size = buffer.size(); + va_list args; + va_start(args, fmt); + + buffer.appendf("[%s] ", module); + buffer.appendfv(fmt, args); + va_end(args); + + for (int new_size = buffer.size(); old_size < new_size; old_size++) { + if (buffer[old_size] == '\n') { + offsets.push_back(old_size + 1); + } + } +} + +void Logger::OnRender() +{ + ImGui::SetNextWindowSize(ImVec2(400, 400), ImGuiCond_FirstUseEver); + + if (!ImGui::Begin(title.c_str(), &isOpen)) { + ImGui::End(); + return; + } + + if (ImGui::BeginPopup("Options")) { + ImGui::Checkbox("Auto scroll", &autoScroll); + ImGui::EndPopup(); + } + + if (ImGui::BeginChild("scrolling", ImVec2(0, 0), false, ImGuiWindowFlags_HorizontalScrollbar)) + { + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0)); + const char* buf = buffer.begin(); + const char* buf_end = buffer.end(); + + ImGuiListClipper clipper; + clipper.Begin((int)offsets.size()); + while (clipper.Step()) + { + for (int line_no = clipper.DisplayStart; line_no < clipper.DisplayEnd; line_no++) + { + const char* line_start = buf + offsets[line_no]; + const char* line_end = (line_no + 1 < offsets.size()) ? (buf + offsets[line_no + 1] - 1) : buf_end; + ImGui::TextUnformatted(line_start, line_end); + } + } + clipper.End(); + ImGui::PopStyleVar(); + + if (autoScroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY()) + ImGui::SetScrollHereY(1.0f); + } + ImGui::EndChild(); + + ImGui::End(); +} \ No newline at end of file diff --git a/src/debugger/Logger.hpp b/src/debugger/Logger.hpp new file mode 100644 index 0000000..d8a861c --- /dev/null +++ b/src/debugger/Logger.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include +#include +#include "DebugWindow.hpp" + +class Logger final: + public DebugWindow +{ +public: + static void Init(Debugger* debugger); + + static Logger* GetInstance() { + return instance; + } + + void Log(const char* module, const char* fmt, ...); + virtual void OnRender() override; + +private: + Logger(Debugger* debugger); + +private: + inline static Logger* instance = nullptr; + + ImGuiTextBuffer buffer; + std::vector offsets; + bool autoScroll; +}; \ No newline at end of file