diff --git a/src/debugger/NametableViewer.cpp b/src/debugger/NametableViewer.cpp index a529875..b36a0bc 100644 --- a/src/debugger/NametableViewer.cpp +++ b/src/debugger/NametableViewer.cpp @@ -5,17 +5,25 @@ #include "../Bus.hpp" NametableViewer::NametableViewer(Debugger* debugger, Bus* bus) : - DebugWindow("Nametable Viewer", debugger), bus(bus), texture(0) + DebugWindow("Nametable Viewer", debugger), bus(bus), texture(0), attributeTexture(0) { glCreateTextures(GL_TEXTURE_2D, 1, &texture); glTextureStorage2D(texture, 1, GL_R8, 32, 32); glTextureParameteri(texture, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTextureParameteri(texture, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + + glCreateTextures(GL_TEXTURE_2D, 1, &attributeTexture); + glTextureStorage2D(attributeTexture, 1, GL_R8, 16, 16); + + glTextureParameteri(attributeTexture, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTextureParameteri(attributeTexture, GL_TEXTURE_MAG_FILTER, GL_NEAREST); } NametableViewer::~NametableViewer() { + glDeleteTextures(1, &attributeTexture); glDeleteTextures(1, &texture); } @@ -32,7 +40,8 @@ void NametableViewer::OnRender() { if (ImGui::BeginMenu("Views")) { - ImGui::MenuItem("Rendered View", NULL, &renderNametable); + ImGui::MenuItem("Rendered Nametable", NULL, &renderNametable); + ImGui::MenuItem("Rendered Attribute Table", NULL, &renderAttributeTable); ImGui::EndMenu(); } @@ -48,11 +57,17 @@ void NametableViewer::OnRender() if (ImGui::BeginTabItem(baseAddress)) { DisplayNametable(index); + if (renderNametable) { glTextureSubImage2D(texture, 0, 0, 0, 32, 32, GL_RED, GL_UNSIGNED_BYTE, &bus->VRAM[0x400 * index]); } + if (renderAttributeTable) + { + RenderAttributeTable(index); + } + ImGui::EndTabItem(); } @@ -76,6 +91,23 @@ void NametableViewer::OnRender() ImGui::End(); } + if (renderAttributeTable) + { + ImGui::SetNextWindowSize(ImVec2(400, 400), ImGuiCond_FirstUseEver); + if (!ImGui::Begin("Rendered Attribute Table", &renderNametable)) + { + ImGui::End(); + return; + } + + float smallerSize = std::min(ImGui::GetWindowWidth(), ImGui::GetWindowHeight()) - 20.0f; + if (smallerSize < 40.0f) + smallerSize = 40.0f; + + ImGui::Image((ImTextureID)attributeTexture, ImVec2{ smallerSize, smallerSize - 20.0f }); + ImGui::End(); + } + ImGui::End(); } @@ -121,3 +153,27 @@ void NametableViewer::DisplayNametable(uint8_t index) ImGui::EndTable(); } } + +void NametableViewer::RenderAttributeTable(uint8_t index) +{ + Word baseAddr = 0x400 * index + 0x3C0; + std::vector pixels(16 * 16); + + for (int i = 0; i < 64; i++) + { + Byte attribute = bus->VRAM[baseAddr + i]; + + for (int y = 0; y < 2; y++) + { + for (int x = 0; x < 2; x++) + { + Byte color = (attribute & 0x3); + pixels[(32 * (i / 8) + 16 * y) + 2 * (i % 8) + x] = color * 80; + + attribute >>= 2; + } + } + } + + glTextureSubImage2D(attributeTexture, 0, 0, 0, 16, 16, GL_RED, GL_UNSIGNED_BYTE, (const void*)pixels.data()); +} diff --git a/src/debugger/NametableViewer.hpp b/src/debugger/NametableViewer.hpp index 37329df..cfd82e5 100644 --- a/src/debugger/NametableViewer.hpp +++ b/src/debugger/NametableViewer.hpp @@ -15,9 +15,12 @@ public: private: void DisplayNametable(uint8_t index); + void RenderAttributeTable(uint8_t index); private: Bus* bus; uint32_t texture; + uint32_t attributeTexture; bool renderNametable = false; + bool renderAttributeTable = false; };