diff --git a/Debugger/Debugger.cpp b/Debugger/Debugger.cpp index 1940556..8498304 100644 --- a/Debugger/Debugger.cpp +++ b/Debugger/Debugger.cpp @@ -12,16 +12,25 @@ #include "ImguiWrapper/imgui_impl_glfw_gl3.h" #include "../CpuTypes.h" +#include "../Video.h" -Debugger::Debugger( Cpu *cpu, Memory *memory ) +Debugger::Debugger( Cpu *cpu, Memory *memory, Video *video ) : cpu( cpu ) - , memory ( memory ) + , memory( memory ) + , video( video ) , mode( DebuggerMode::IDLE ) , window( nullptr ) { } +Debugger::~Debugger() +{ + delete leftPatternTableBuffer; + delete rightPatternTableBuffer; +} + + void Debugger::StartDebugger() { glfwInit(); @@ -29,7 +38,7 @@ void Debugger::StartDebugger() glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 5 ); glfwWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE ); - window = glfwCreateWindow( 1024, 720, "PatNes", nullptr, nullptr ); + window = glfwCreateWindow( 1920, 1080, "PatNes", nullptr, nullptr ); if ( window == nullptr ) { glfwTerminate(); @@ -53,6 +62,14 @@ void Debugger::StartDebugger() ImGuiGLFW::Init( window, true ); ImGui::StyleColorsDark(); + leftPatternTableBuffer = new RGB[ 128 * 128 ]; + ImGuiGLFW::Texture leftPatternTexture = { 0, 128, 128, leftPatternTableBuffer }; + leftPatternTableTextureID = ImGuiGLFW::CreateTexture( leftPatternTexture ); + + rightPatternTableBuffer = new RGB[ 128 * 128 ]; + ImGuiGLFW::Texture rightPatternTexture = { 0, 128, 128, rightPatternTableBuffer }; + rightPatternTableTextureID = ImGuiGLFW::CreateTexture( rightPatternTexture ); + Update(0.f,0); } @@ -105,6 +122,18 @@ void Debugger::ComposeView( u32 cycles ) ImGuiGLFW::NewFrame(); cpuDebugger.ComposeView( *cpu, *memory, cycles, mode ); + + UpdatePatternTable( 0x0000, leftPatternTableBuffer ); + ImGui::SetNextWindowSize( ImVec2( 560, 560 ), ImGuiCond_FirstUseEver ); + ImGui::Begin( "VRAM Left" ); + ImGui::Image( leftPatternTableTextureID, ImVec2( 512, 512 ) ); + ImGui::End(); + + UpdatePatternTable( 0x1000, rightPatternTableBuffer ); + ImGui::SetNextWindowSize( ImVec2( 560, 560 ), ImGuiCond_FirstUseEver ); + ImGui::Begin( "VRAM Right" ); + ImGui::Image( rightPatternTableTextureID, ImVec2( 512, 512 ) ); + ImGui::End(); } void Debugger::Render() @@ -117,3 +146,43 @@ void Debugger::Render() ImGuiGLFW::RenderDrawLists( ImGui::GetDrawData() ); glfwSwapBuffers( window ); } + + +void Debugger::UpdatePatternTable( word address, RGB *buffer ) +{ + constexpr static RGB palette[4] = { { 255,255,255 },{ 0xCC,0xCC,0xCC },{ 0x77,0x77,0x77 }, { 0x0,0x0,0x0 } }; + + const byte * const ppuMemory = video->GetPPUMemory(); + assert( buffer != nullptr ); + assert( ppuMemory != nullptr ); + + u32 vramPosition = 0; + for ( u32 tile = 0; tile < 256; ++tile ) + { + const u32 tileAddress = (tile * 0x10) + address; + + u32 localvramPosition = vramPosition; + for ( byte row = 0; row < 8; ++row ) + { + const byte firstByte = ppuMemory[ tileAddress + row ]; + const byte secondByte = ppuMemory[ tileAddress + row + 0x07 ]; + + for ( byte column = 0; column < 8; ++column) + { + byte mask = 0x01 << column; + const byte value = ((secondByte & mask) >> column) << 1; + const byte value2 = (firstByte & mask) >> column; + const byte finalValue = value | value2; + + buffer[ localvramPosition + (7 - column) ] = palette[ finalValue ]; + } + localvramPosition += 128; + } + vramPosition += 8; + + if ( tile > 0 && (tile + 1) % 16 == 0) + { + vramPosition += 128 * 7; + } + } +} \ No newline at end of file diff --git a/Debugger/Debugger.h b/Debugger/Debugger.h index 4669702..b887a3f 100644 --- a/Debugger/Debugger.h +++ b/Debugger/Debugger.h @@ -13,12 +13,15 @@ enum class DebuggerMode : byte }; struct GLFWwindow; +class Video; class Debugger { public: - Debugger( Cpu *cpu, Memory *memory ); + Debugger( Cpu *cpu, Memory *memory, Video *video ); Debugger(Debugger &) = delete; + ~Debugger(); + void StartDebugger(); void Update( float deltaMilliseconds, u32 cycles ); @@ -26,16 +29,28 @@ class Debugger private: + using ImTextureID = void *; + /* Systems */ Cpu *cpu; Memory *memory; + Video *video; /* Specific Debuggers */ CpuDebugger cpuDebugger; + /* Textures */ + ImTextureID leftPatternTableTextureID; + RGB *leftPatternTableBuffer; + + ImTextureID rightPatternTableTextureID; + RGB *rightPatternTableBuffer; + GLFWwindow *window; DebuggerMode mode; void ComposeView( u32 cycles ); void Render(); + + void UpdatePatternTable( word address, RGB *buffer ); }; \ No newline at end of file diff --git a/Types.h b/Types.h index 961ff0a..8cc2ac4 100644 --- a/Types.h +++ b/Types.h @@ -21,6 +21,19 @@ union Register word value; }; +struct RGB +{ + byte red; + byte green; + byte blue; + + bool isEqual(RGB other) const + { + return red == other.red && green == other.green && blue == other.blue; + } +}; + +constexpr RGB PINK = { 0xFF, 0x00, 0x80 }; /* Operators */ diff --git a/Video.cpp b/Video.cpp index e7768dd..e5a47ed 100644 --- a/Video.cpp +++ b/Video.cpp @@ -25,3 +25,8 @@ void Video::MapCartridgeCHRToPPU() const u32 dataSize = header.chrRomSizeKB * 1_KB; memcpy( memory, &cartridgeRom[ offset ], dataSize ); } + +const byte * const Video::GetPPUMemory() const +{ + return memory; +} \ No newline at end of file diff --git a/Video.h b/Video.h index 9f1b9be..8dc5de1 100644 --- a/Video.h +++ b/Video.h @@ -39,6 +39,8 @@ class Video public: Video( Cartridge *memory ); + const byte * const GetPPUMemory() const; + private: /* Associated Systems */ diff --git a/main.cpp b/main.cpp index 692886a..da83ac3 100644 --- a/main.cpp +++ b/main.cpp @@ -3,6 +3,7 @@ #include "Cartridge.h" #include "Memory.h" #include "Cpu.h" +#include "Video.h" #include "Debugger/Debugger.h" static constexpr u32 AVERAGE_CYCLES_PER_FRAME = 29780; @@ -23,8 +24,9 @@ int main(int argc, char** argv) Memory memory( &cartridge ); Cpu cpu( &memory ); - - Debugger debugger( &cpu, &memory ); + Video video( &cartridge ); + + Debugger debugger( &cpu, &memory, &video ); debugger.StartDebugger(); /* Run the first frame for now */