From 9856e730fd838f2cfa9c9f5a556e4052554155e4 Mon Sep 17 00:00:00 2001 From: Lauchmelder Date: Fri, 4 Mar 2022 14:16:41 +0100 Subject: [PATCH] added pattern table viewer --- src/Bus.cpp | 2 + src/CMakeLists.txt | 2 +- src/Mapper.hpp | 1 + src/PPU.cpp | 3 + src/debugger/Debugger.cpp | 2 + src/debugger/NametableViewer.cpp | 2 - src/debugger/Palettes.cpp | 61 +++++++++---------- src/debugger/Palettes.hpp | 5 +- src/debugger/PatternTableViewer.cpp | 90 +++++++++++++++++++++++++++++ src/debugger/PatternTableViewer.hpp | 24 ++++++++ src/mappers/Mapper000.cpp | 2 +- 11 files changed, 157 insertions(+), 37 deletions(-) create mode 100644 src/debugger/PatternTableViewer.cpp create mode 100644 src/debugger/PatternTableViewer.hpp diff --git a/src/Bus.cpp b/src/Bus.cpp index 894893f..9bfcb86 100644 --- a/src/Bus.cpp +++ b/src/Bus.cpp @@ -164,6 +164,8 @@ void Bus::WriteCPU(Word addr, Byte val) { if (0x0000 <= addr && addr < 0x2000) { + if (addr == 0x0348) + volatile int jdfkdf = 3; RAM[addr & 0x7FF] = val; } else if (0x2000 <= addr && addr < 0x4000) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0f8c80c..2d14af9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -13,7 +13,7 @@ add_executable(nesemu "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/NametableViewer.cpp" "ControllerPort.cpp" "controllers/StandardController.cpp" "gfx/Input.cpp" "debugger/ControllerPortViewer.cpp" "gfx/Screen.cpp" "debugger/Palettes.cpp" "APU.cpp" "debugger/PatternTableViewer.cpp") target_include_directories(nesemu PRIVATE mappers diff --git a/src/Mapper.hpp b/src/Mapper.hpp index c3b871d..28e3418 100644 --- a/src/Mapper.hpp +++ b/src/Mapper.hpp @@ -6,6 +6,7 @@ class Mapper { friend class Disassembler; + friend class PatternTableViewer; public: virtual Byte ReadCPU(Word addr) = 0; diff --git a/src/PPU.cpp b/src/PPU.cpp index 543353f..0569256 100644 --- a/src/PPU.cpp +++ b/src/PPU.cpp @@ -184,7 +184,10 @@ void PPU::Tick() volatile int dfjk = 3; screen->SetPixel(x, y, colorTable[colorVal]); + } + if (cycleType == CycleType::Fetching || cycleType == CycleType::PreFetching) + { loTile.Raw <<= 1; hiTile.Raw <<= 1; loAttribute.Raw <<= 1; diff --git a/src/debugger/Debugger.cpp b/src/debugger/Debugger.cpp index 5d8d84b..4cef7a1 100644 --- a/src/debugger/Debugger.cpp +++ b/src/debugger/Debugger.cpp @@ -10,6 +10,7 @@ #include "Disassembler.hpp" #include "MemoryViewer.hpp" #include "NametableViewer.hpp" +#include "PatternTableViewer.hpp" #include "ControllerPortViewer.hpp" #include "Palettes.hpp" @@ -26,6 +27,7 @@ Debugger::Debugger(Bus* bus) : windows.push_back(new MemoryViewer(this, bus)); windows.push_back(new NametableViewer(this, 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)); } diff --git a/src/debugger/NametableViewer.cpp b/src/debugger/NametableViewer.cpp index f595fb0..a529875 100644 --- a/src/debugger/NametableViewer.cpp +++ b/src/debugger/NametableViewer.cpp @@ -68,8 +68,6 @@ void NametableViewer::OnRender() return; } - - float smallerSize = std::min(ImGui::GetWindowWidth(), ImGui::GetWindowHeight()) - 20.0f; if (smallerSize < 40.0f) smallerSize = 40.0f; diff --git a/src/debugger/Palettes.cpp b/src/debugger/Palettes.cpp index 1662510..2e460b7 100644 --- a/src/debugger/Palettes.cpp +++ b/src/debugger/Palettes.cpp @@ -10,28 +10,22 @@ Palettes::Palettes(Debugger* debugger, Bus* bus) : DebugWindow("Palettes", debugger), bus(bus) { - glCreateTextures(GL_TEXTURE_2D, 4, backgroundPalettes.data()); - glCreateTextures(GL_TEXTURE_2D, 4, spritePalettes.data()); + glCreateTextures(GL_TEXTURE_2D, 1, &backgroundPalettes); + glCreateTextures(GL_TEXTURE_2D, 1, &spritePalettes); - for (GLuint texture : backgroundPalettes) - { - glTextureStorage2D(texture, 1, GL_RGB8, 4, 1); - glTextureParameteri(texture, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTextureParameteri(texture, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - } + glTextureStorage2D(backgroundPalettes, 1, GL_RGB8, 4, 4); + glTextureParameteri(backgroundPalettes, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTextureParameteri(backgroundPalettes, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - for (GLuint texture : spritePalettes) - { - glTextureStorage2D(texture, 1, GL_RGB8, 4, 1); - glTextureParameteri(texture, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTextureParameteri(texture, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - } + glTextureStorage2D(spritePalettes, 1, GL_RGB8, 4, 4); + glTextureParameteri(spritePalettes, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTextureParameteri(spritePalettes, GL_TEXTURE_MAG_FILTER, GL_NEAREST); } Palettes::~Palettes() { - glDeleteTextures(4, spritePalettes.data()); - glDeleteTextures(4, backgroundPalettes.data()); + glDeleteTextures(1, &spritePalettes); + glDeleteTextures(1, &backgroundPalettes); } void Palettes::OnRender() @@ -43,8 +37,9 @@ void Palettes::OnRender() return; } - Color palette[4]; - palette[0] = PPU::colorTable[bus->palettes[0]]; + Color palette[4 * 4]; + + ImVec2 size = ImGui::GetWindowSize(); size.x /= 2; size.y = size.x / 4; @@ -52,26 +47,32 @@ void Palettes::OnRender() { for (int i = 0; i < 4; i++) { - palette[1] = PPU::colorTable[bus->palettes[i * 4 + 1]]; - palette[2] = PPU::colorTable[bus->palettes[i * 4 + 2]]; - palette[3] = PPU::colorTable[bus->palettes[i * 4 + 3]]; - - glTextureSubImage2D(backgroundPalettes[i], 0, 0, 0, 4, 1, GL_RGB, GL_UNSIGNED_BYTE, (const void*)palette); - ImGui::Image((ImTextureID)backgroundPalettes[i], size); + palette[4 * i + 0] = PPU::colorTable[bus->palettes[0]]; + palette[4 * i + 1] = PPU::colorTable[bus->palettes[i * 4 + 1]]; + palette[4 * i + 2] = PPU::colorTable[bus->palettes[i * 4 + 2]]; + palette[4 * i + 3] = PPU::colorTable[bus->palettes[i * 4 + 3]]; } + + glTextureSubImage2D(backgroundPalettes, 0, 0, 0, 4, 4, GL_RGB, GL_UNSIGNED_BYTE, (const void*)palette); + + for(float i = 0; i < 1.0f; i += 0.25f) + ImGui::Image((ImTextureID)backgroundPalettes, size, ImVec2(0, i), ImVec2(1, i + 0.25f)); } if (ImGui::CollapsingHeader("Sprites")) { for (int i = 0; i < 4; i++) { - palette[1] = PPU::colorTable[bus->palettes[0x10 + i * 4 + 1]]; - palette[2] = PPU::colorTable[bus->palettes[0x10 + i * 4 + 2]]; - palette[3] = PPU::colorTable[bus->palettes[0x10 + i * 4 + 3]]; - - glTextureSubImage2D(spritePalettes[i], 0, 0, 0, 4, 1, GL_RGB, GL_UNSIGNED_BYTE, (const void*)palette); - ImGui::Image((ImTextureID)spritePalettes[i], size); + palette[4 * i + 0] = PPU::colorTable[bus->palettes[0]]; + palette[4 * i + 1] = PPU::colorTable[bus->palettes[0x10 + i * 4 + 1]]; + palette[4 * i + 2] = PPU::colorTable[bus->palettes[0x10 + i * 4 + 2]]; + palette[4 * i + 3] = PPU::colorTable[bus->palettes[0x10 + i * 4 + 3]]; } + + glTextureSubImage2D(spritePalettes, 0, 0, 0, 4, 4, GL_RGB, GL_UNSIGNED_BYTE, (const void*)palette); + + for (float i = 0; i < 1.0f; i += 0.25f) + ImGui::Image((ImTextureID)spritePalettes, size, ImVec2(0, i), ImVec2(1, i + 0.25f)); } ImGui::End(); diff --git a/src/debugger/Palettes.hpp b/src/debugger/Palettes.hpp index 38fbaff..e9528c0 100644 --- a/src/debugger/Palettes.hpp +++ b/src/debugger/Palettes.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include "DebugWindow.hpp" class Bus; @@ -17,6 +16,6 @@ public: private: Bus* bus; - std::array backgroundPalettes; - std::array spritePalettes; + uint32_t backgroundPalettes; + uint32_t spritePalettes; }; diff --git a/src/debugger/PatternTableViewer.cpp b/src/debugger/PatternTableViewer.cpp new file mode 100644 index 0000000..79f9db0 --- /dev/null +++ b/src/debugger/PatternTableViewer.cpp @@ -0,0 +1,90 @@ +#include "PatternTableViewer.hpp" + +#include +#include +#include "Mapper000.hpp" + +PatternTableViewer::PatternTableViewer(Debugger* debugger, Mapper* mapper) : + DebugWindow("Pattern Table Viewer", debugger), mapper(mapper) +{ + glCreateTextures(GL_TEXTURE_2D, 1, &texture); + glTextureStorage2D(texture, 1, GL_RGB8, 128 * 2, 128); + + glTextureParameteri(texture, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTextureParameteri(texture, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + std::vector pixels(128 * 128); + for (int i = 0; i < 2; i++) + { + DecodePatternTable(i, pixels); + glTextureSubImage2D(texture, 0, 128 * i, 0, 128, 128, GL_RGB, GL_UNSIGNED_BYTE, (const void*)pixels.data()); + } +} + +PatternTableViewer::~PatternTableViewer() +{ + glDeleteTextures(1, &texture); +} + +void PatternTableViewer::OnRender() +{ + if (!ImGui::Begin("Pattern Table Viewer", &isOpen)) + { + ImGui::End(); + return; + } + + float smallerSize = std::min(ImGui::GetWindowWidth(), ImGui::GetWindowHeight()) - 20.0f; + if (smallerSize < 40.0f) + smallerSize = 40.0f; + + if (ImGui::BeginTabBar("pattern_tables")) + { + if (ImGui::BeginTabItem("Table 1")) + { + ImGui::Image((ImTextureID)texture, ImVec2(smallerSize, smallerSize - 40.0f), ImVec2(0.0f, 0.0f), ImVec2(0.5f, 1.0f)); + ImGui::EndTabItem(); + } + + if (ImGui::BeginTabItem("Table 2")) + { + ImGui::Image((ImTextureID)texture, ImVec2(smallerSize, smallerSize - 40.0f), ImVec2(0.5f, 0.0f), ImVec2(1.0f, 1.0f)); + ImGui::EndTabItem(); + } + + ImGui::EndTabBar(); + } + + + ImGui::End(); +} + +void PatternTableViewer::DecodePatternTable(int index, std::vector& buffer) +{ + // uint8_t stride = 128; + Word baseAddr = 0x1000 * index; + + for (int y = 0; y < 16; y++) + { + for (int x = 0; x < 16; x++) + { + Word tileAddress = baseAddr + (16 * 16 * y) + (16 * x); + + for(int l = 0; l < 8; l++) + { + uint8_t loColor = mapper->CHR_ROM[tileAddress + l]; + uint8_t hiColor = mapper->CHR_ROM[tileAddress + 8 + l]; + + for (int k = 0; k < 8; k++) + { + uint8_t color = ((loColor & 0x80) >> 7) | ((hiColor & 0x80) >> 6); + color *= 80; + buffer[(y * 8 + l) * 128 + (x * 8 + k)] = Color{ color, color, color }; + + loColor <<= 1; + hiColor <<= 1; + } + } + } + } +} diff --git a/src/debugger/PatternTableViewer.hpp b/src/debugger/PatternTableViewer.hpp new file mode 100644 index 0000000..8fb9ea3 --- /dev/null +++ b/src/debugger/PatternTableViewer.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include +#include "DebugWindow.hpp" +#include "../Types.hpp" + +class Mapper; + +class PatternTableViewer : + public DebugWindow +{ +public: + PatternTableViewer(Debugger* debugger, Mapper* mapper); + ~PatternTableViewer(); + + virtual void OnRender() override; + +private: + void DecodePatternTable(int index, std::vector& buffer); + +private: + Mapper* mapper; + uint32_t texture; +}; diff --git a/src/mappers/Mapper000.cpp b/src/mappers/Mapper000.cpp index e5f45b2..38df639 100644 --- a/src/mappers/Mapper000.cpp +++ b/src/mappers/Mapper000.cpp @@ -21,7 +21,7 @@ Byte Mapper000::ReadCPU(Word addr) { if (0x8000 <= addr && addr <= 0xFFFF) { - return PRG_ROM[addr & (prgBanks * 0x4000 - 1)]; + return PRG_ROM[addr & (0x4000 * prgBanks - 1)]; } return 0x00;