From 139966c4cf2942d482e4aadceda5dac3c49e96ca Mon Sep 17 00:00:00 2001 From: william Date: Tue, 23 Jul 2024 18:50:11 -0400 Subject: [PATCH] Nametable debugger --- gui/CMakeLists.txt | 4 ++-- gui/dbg_nametable.c | 21 +++++++++++++++++++++ gui/dbg_nametable.h | 36 ++++++++++++++++++++++++++++++++++++ gui/dbg_pattern_table.c | 21 +++++++++++++++------ gui/dbg_pattern_table.h | 36 +++++++++++++++++++++++++++++++++--- gui/nametable_window.c | 30 ++++++------------------------ gui/nametable_window.h | 3 ++- gui/pattern_window.c | 6 ------ gui/pattern_window.h | 1 + 9 files changed, 116 insertions(+), 42 deletions(-) create mode 100644 gui/dbg_nametable.c create mode 100644 gui/dbg_nametable.h diff --git a/gui/CMakeLists.txt b/gui/CMakeLists.txt index 4b1be7a..9740bdc 100644 --- a/gui/CMakeLists.txt +++ b/gui/CMakeLists.txt @@ -1,5 +1,5 @@ -set(HEADERS canvas.h gui.h window.h main_window.h char_map.h pattern_display.h pattern_window.h nametable_window.h dbg_pattern_table.h) -set(SOURCE canvas.c gui.c window.c main_window.c char_map.c pattern_display.c pattern_window.c nametable_window.c dbg_pattern_table.c) +set(HEADERS canvas.h gui.h window.h main_window.h char_map.h pattern_display.h pattern_window.h nametable_window.h dbg_pattern_table.h dbg_nametable.h) +set(SOURCE canvas.c gui.c window.c main_window.c char_map.c pattern_display.c pattern_window.c nametable_window.c dbg_pattern_table.c dbg_nametable.c) add_library(nes_gui ${SOURCE} ${HEADERS}) diff --git a/gui/dbg_nametable.c b/gui/dbg_nametable.c new file mode 100644 index 0000000..b1409e6 --- /dev/null +++ b/gui/dbg_nametable.c @@ -0,0 +1,21 @@ +// +// Created by william on 7/23/24. +// + +#include "dbg_nametable.h" +#include "../include/ppu.h" + +DebugNameTable dbg_nametable; + +void dbg_nametable_build_bank(byte* nametable, DebugTile *bank) { + for (int i = 0; i < NAMETABLE_BANK_SIZE; i++) { + DebugTile *tile = &bank[i]; + + tile->tile_id = nametable[i]; + } +} + +void dbg_nametable_update() { + dbg_nametable_build_bank(ppu_get_state()->memory.nametable_0, dbg_nametable.bank_0); + dbg_nametable_build_bank(ppu_get_state()->memory.nametable_1, dbg_nametable.bank_1); +} \ No newline at end of file diff --git a/gui/dbg_nametable.h b/gui/dbg_nametable.h new file mode 100644 index 0000000..6988d7f --- /dev/null +++ b/gui/dbg_nametable.h @@ -0,0 +1,36 @@ +// +// Created by william on 7/23/24. +// + +#ifndef NES_EMULATOR_DBG_NAMETABLE_H +#define NES_EMULATOR_DBG_NAMETABLE_H + +#include +#include "../include/types.h" +#include "dbg_pattern_table.h" + +#define NAMETABLE_BANK_SIZE 0x3bf + +typedef struct db_tile { + byte tile_id; +} DebugTile; + +typedef struct dbg_nametable { + DebugTile bank_0[NAMETABLE_BANK_SIZE]; + DebugTile bank_1[NAMETABLE_BANK_SIZE]; + bool vertical_mirroring; +} DebugNameTable; + +/** + * Updates the debug nametable. Updates the tiles from the PPU memory. + */ +void dbg_nametable_update(); + +/** + * Renders a nametable bank to a buffer. + * @param bank + * @param buffer + */ +void dbg_nametable_render_bank(int bank, pixel *buffer); + +#endif //NES_EMULATOR_DBG_NAMETABLE_H diff --git a/gui/dbg_pattern_table.c b/gui/dbg_pattern_table.c index 217a83a..21c591f 100644 --- a/gui/dbg_pattern_table.c +++ b/gui/dbg_pattern_table.c @@ -4,6 +4,7 @@ #include #include +#include #include "dbg_pattern_table.h" #include "../include/ppu.h" #include "../include/system.h" @@ -27,19 +28,27 @@ void dbg_pattern_table_init() { dbg_pattern_table_build_bank(pattern_table.bank_1, &pattern_memory[PATTERN_BANK_SIZE]); } -DebugPattern dbg_pattern_get(int x, int y, int bank) { - address pattern_addr = x + y * PATTERN_TABLE_WIDTH; - +DebugPattern dbg_pattern_get(int pattern_id, int bank) { switch (bank) { case PATTERN_BANK_0: - return pattern_table.bank_0[pattern_addr]; + return pattern_table.bank_0[pattern_id]; case PATTERN_BANK_1: - return pattern_table.bank_1[pattern_addr]; + return pattern_table.bank_1[pattern_id]; default: assert(false); } } +DebugPattern dbg_pattern_get_pos(int x, int y, int bank) { + assert(x >= 0); + assert(x < PATTERN_TABLE_WIDTH); + assert(y >= 0); + assert(y < PATTERN_TABLE_WIDTH); + + address pattern_addr = x + y * PATTERN_TABLE_WIDTH; + return dbg_pattern_get(pattern_addr, bank); +} + void dbg_pattern_draw_borders(pixel *buffer, int buffer_width) { for (int by = 0; by < PATTERN_DRAW_SIZE; by++) { address pixel_addr = (by * buffer_width) + PATTERN_DRAW_SIZE - 1; @@ -53,7 +62,7 @@ void dbg_pattern_draw_borders(pixel *buffer, int buffer_width) { } void dbg_pattern_draw(int x, int y, int bank, pixel *buffer, int buffer_width) { - DebugPattern pattern = dbg_pattern_get(x, y, bank); + DebugPattern pattern = dbg_pattern_get_pos(x, y, bank); for (int fine_y = 0; fine_y < PATTERN_SIZE; fine_y++) { byte data_high = pattern.data_high[fine_y]; byte data_low = pattern.data_low[fine_y]; diff --git a/gui/dbg_pattern_table.h b/gui/dbg_pattern_table.h index cfe60d2..28f90ee 100644 --- a/gui/dbg_pattern_table.h +++ b/gui/dbg_pattern_table.h @@ -5,7 +5,6 @@ #ifndef NES_EMULATOR_DBG_PATTERN_TABLE_H #define NES_EMULATOR_DBG_PATTERN_TABLE_H -#include #include "../include/types.h" #define PATTERN_BANK_SIZE 0x1000 @@ -32,12 +31,43 @@ typedef struct dbg_pattern_table { DebugPattern bank_1[PATTERN_TABLE_SIZE]; } DebugPatternTable; +/** + * Initializes the debug pattern table. Build the two pattern banks from the currently loaded ROM. + */ void dbg_pattern_table_init(); -DebugPattern dbg_pattern_get(int x, int y, int bank); +/** + * Gets a debug pattern from the debug pattern table by its ID. + * @param pattern_id The ID of the pattern + * @param bank The bank of the pattern (0 -> 0x0000, 1 -> 0x1000) + * @return The data of the pattern matching the given ID. + */ +DebugPattern dbg_pattern_get(int pattern_id, int bank); -void dbg_pattern_draw(int x, int y, int bank, pixel *buffer, int buffer_width); +/** + * Gets a debug pattern from the debug pattern table by its position. + * @param x The horizontal position of the pattern + * @param y The vertical position of the pattern + * @param bank The bank of the pattern (0 -> 0x0000, 1 -> 0x1000) + * @return The data of the pattern matching the given positions. + */ +DebugPattern dbg_pattern_get_pos(int x, int y, int bank); +/** + * Draws a pattern to a buffer. The pattern is determined by its position. + * @param x The x position of the pattern in the table + * @param y The y position of the pattern in the table + * @param bank The bank of the pattern + * @param buffer The buffer to write the pattern data to + * @param buffer_width The width of a pixel row in the buffer + */ +void dbg_pattern_draw(int x, int y, int bank, pixel *dbgdbgbuffer, int buffer_width); + +/** + * Draws a pattern bank to a buffer. + * @param bank The bank to draw (0 -> 0x0000, 1 -> 0x1000) + * @param buffer The buffer to write the patterns data to. + */ void dbg_pattern_draw_bank(int bank, pixel *buffer); #endif //NES_EMULATOR_DBG_PATTERN_TABLE_H diff --git a/gui/nametable_window.c b/gui/nametable_window.c index 906f473..9acc440 100644 --- a/gui/nametable_window.c +++ b/gui/nametable_window.c @@ -6,49 +6,31 @@ #include "nametable_window.h" #define NAMETABLE_BANK_SIZE 0x0400 +#define NW_WIDTH (NW_ROW_TILE_COUNT * PATTERN_DRAW_SIZE) +#define NW_HEIGHT (NW_ROW_COUNT * PATTERN_DRAW_SIZE) void nametable_window_init(NesNametableWindow *window) { int win_size = pattern_display_get_size(NW_ROW_TILE_COUNT); window->sdl_context = window_init("Nametable", win_size, win_size, NW_SCALE); - pattern_display_init(&window->pattern_display, window->sdl_context.renderer, NW_ROW_TILE_COUNT, NW_ROW_TILE_COUNT - 2, - PATTERN_DISPLAY_DYNAMIC); + window->texture = SDL_CreateTexture(window->sdl_context.renderer, SDL_PIXELFORMAT_ARGB8888, + SDL_TEXTUREACCESS_STREAMING, NW_WIDTH, NW_HEIGHT); } void nametable_window_uninit(NesNametableWindow *window) { - pattern_display_uninit(&window->pattern_display); + SDL_DestroyTexture(window->texture); window_uninit(window->sdl_context); } -static byte *nametable_window_read_byte(address addr, void *data) { - assert(addr < NAMETABLE_BANK_SIZE * 4); - assert(data != NULL); - - byte **nametables = (byte **) data; - - int bank = addr / NAMETABLE_BANK_SIZE; - int bank_addr = addr % NAMETABLE_BANK_SIZE; - - switch (bank) { - case 0: - case 1: - return &nametables[0][bank_addr]; - default: - return &nametables[1][bank_addr]; - } -} - void nametable_window_update(NesNametableWindow *window, byte *nametable_0, byte *nametable_1) { byte **nametables[2]; nametables[0] = &nametable_0; nametables[1] = &nametable_1; - - pattern_display_build(&window->pattern_display, &nametable_window_read_byte, nametables); } void nametable_window_render(NesNametableWindow *window) { SDL_RenderClear(window->sdl_context.renderer); - pattern_display_render(&window->pattern_display, window->sdl_context.renderer); + SDL_RenderCopy(window->sdl_context.renderer, window->texture, NULL, NULL); } void nametable_window_present(NesNametableWindow *window) { diff --git a/gui/nametable_window.h b/gui/nametable_window.h index 1383046..b8cc44b 100644 --- a/gui/nametable_window.h +++ b/gui/nametable_window.h @@ -10,11 +10,12 @@ #include "pattern_display.h" #define NW_SCALE 2 +#define NW_ROW_COUNT 30 #define NW_ROW_TILE_COUNT 32 typedef struct nes_nametable_window { NesSdlContext sdl_context; - PatternDisplay pattern_display; + SDL_Texture *texture; } NesNametableWindow; void nametable_window_init(NesNametableWindow *window); diff --git a/gui/pattern_window.c b/gui/pattern_window.c index bd47da1..d8f6dea 100644 --- a/gui/pattern_window.c +++ b/gui/pattern_window.c @@ -5,7 +5,6 @@ #include "pattern_window.h" #include "dbg_pattern_table.h" -#define PW_SCALE 2 #define PW_WIDTH (PW_ROW_TILE_COUNT * PATTERN_DRAW_SIZE) #define PW_HEIGHT (PW_WIDTH * 2) #define PW_BUFFER_SIZE (PW_WIDTH * PW_HEIGHT) @@ -16,14 +15,10 @@ void pattern_window_init(NesPatternWindow *window) { window->texture = SDL_CreateTexture(window->sdl_context.renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, PW_WIDTH, PW_HEIGHT); - -// pattern_display_init(&window->pattern_display, window->sdl_context.renderer, PW_ROW_TILE_COUNT, -// PW_ROW_TILE_COUNT * 2, PATTERN_DISPLAY_STATIC); } void pattern_window_uninit(NesPatternWindow *window) { SDL_DestroyTexture(window->texture); -// pattern_display_uninit(&window->pattern_display); window_uninit(window->sdl_context); } @@ -38,7 +33,6 @@ void pattern_window_build_table(NesPatternWindow *window) { void pattern_window_render(NesPatternWindow *window) { SDL_RenderClear(window->sdl_context.renderer); SDL_RenderCopy(window->sdl_context.renderer, window->texture, NULL, NULL); -// pattern_display_render(&window->pattern_display, window->sdl_context.renderer); } void pattern_window_present(NesPatternWindow *window) { diff --git a/gui/pattern_window.h b/gui/pattern_window.h index c78386f..7f53187 100644 --- a/gui/pattern_window.h +++ b/gui/pattern_window.h @@ -9,6 +9,7 @@ #include "window.h" #include "pattern_display.h" +#define PW_SCALE 2 #define PW_ROW_TILE_COUNT 16 typedef struct nes_pattern_window {