From 091a5e3bf574550497315d6f316d0fe523a01b9e Mon Sep 17 00:00:00 2001 From: william Date: Sun, 14 Jan 2024 21:59:13 -0500 Subject: [PATCH] Window and cursor abstractions --- debugger/CMakeLists.txt | 6 ++- debugger/cursor.c | 78 ++++++++++++++++++++++++++++ debugger/cursor.h | 74 ++++++++++++++++++++++++++ debugger/debugger.c | 21 ++++---- debugger/debugger.h | 4 +- debugger/memory_view.c | 100 +++++++++++++++-------------------- debugger/memory_view.h | 21 +++----- debugger/program_view.c | 112 +++++++++++++++++++++++++++++++++------- debugger/program_view.h | 15 ++++-- debugger/window.c | 61 ++++++++++++++++++++++ debugger/window.h | 84 ++++++++++++++++++++++++++++++ test_roms/nestest.fdb | 1 + 12 files changed, 471 insertions(+), 106 deletions(-) create mode 100644 debugger/cursor.c create mode 100644 debugger/cursor.h create mode 100644 debugger/window.c create mode 100644 debugger/window.h diff --git a/debugger/CMakeLists.txt b/debugger/CMakeLists.txt index ecd1038..36cecb0 100644 --- a/debugger/CMakeLists.txt +++ b/debugger/CMakeLists.txt @@ -3,7 +3,11 @@ add_library(DEBUG memory_view.c dialog.c program_view.c - program_view.h) + program_view.h + cursor.c + cursor.h + window.c + window.h) find_package(Curses) diff --git a/debugger/cursor.c b/debugger/cursor.c new file mode 100644 index 0000000..7c59179 --- /dev/null +++ b/debugger/cursor.c @@ -0,0 +1,78 @@ +// +// Created by william on 1/12/24. +// + +#include +#include "cursor.h" + +void cursor_init(Cursor *cursor, WINDOW *window, int max_x, int max_y) { + cursor->window = window; + cursor->min_x = 1; + cursor->min_y = 1; + cursor->max_x = max_x; + cursor->max_y = max_y; + cursor->multiplier_x = 1; + cursor->multiplier_y = 1; + cursor->width = 1; + cursor->pos_x = 0; + cursor->pos_y = 0; + cursor->enabled = false; +} + +void cursor_set_at(Cursor *cursor, int at) { + int win_x = cursor->min_x + cursor->pos_x * cursor->multiplier_x; + int win_y = cursor->min_y + cursor->pos_y * cursor->multiplier_y; + + mvwchgat(cursor->window, win_y, win_x, cursor->width, at, 0, NULL); +} + +void cursor_enable(Cursor *cursor) { + cursor_set_at(cursor, CURSOR_AT_ENABLED); + cursor->enabled = true; +} + +void cursor_disable(Cursor *cursor) { + cursor_set_at(cursor, CURSOR_AT_DISABLED); + cursor->enabled = false; +} + +void cursor_set_pos(Cursor *cursor, int x, int y) { + assert(x >= 0); + assert(y >= 0); + + bool enabled = cursor->enabled; + if (enabled) { + // Remove the cursor from its old position + cursor_disable(cursor); + } + + cursor->pos_x = x; + cursor->pos_y = y; + + if (enabled) { + // Display the cursor in the new position + cursor_enable(cursor); + } +} + +int cursor_limit(int value, int limit) { + if (value < 0) { + return 0; + } + + if (value > limit) { + return limit; + } + + return value; +} + +void cursor_move(Cursor *cursor, int offset_x, int offset_y) { + int x = cursor->pos_x + offset_x; + x = cursor_limit(x, cursor->max_x); + + int y = cursor->pos_y + offset_y; + y = cursor_limit(y, cursor->max_y); + + cursor_set_pos(cursor, x, y); +} \ No newline at end of file diff --git a/debugger/cursor.h b/debugger/cursor.h new file mode 100644 index 0000000..24c5757 --- /dev/null +++ b/debugger/cursor.h @@ -0,0 +1,74 @@ +// +// Created by william on 1/12/24. +// +#ifndef NESEMULATOR_CURSOR_H +#define NESEMULATOR_CURSOR_H + +#include + +#define CURSOR_OFFSET_UP (-1) +#define CURSOR_OFFSET_DOWN 1 +#define CURSOR_OFFSET_LEFT (-1) +#define CURSOR_OFFSET_RIGHT 1 + +#define CURSOR_AT_ENABLED A_REVERSE +#define CURSOR_AT_DISABLED A_NORMAL + +typedef struct cursor { + WINDOW *window; + int min_x; + int min_y; + int max_x; + int max_y; + int multiplier_x; + int multiplier_y; + int width; + int pos_x; + int pos_y; + bool enabled; +} Cursor; + +/** + * Initializes a cursor with default values. + * + * @param cursor A reference to the cursor to initialize + * @param window The window the cursor is in + */ +void cursor_init(Cursor *cursor, WINDOW *window, int max_x, int max_y); + +/** + * Enables a cursor, making it visible in its window. + * + * @param cursor The cursor + */ +void cursor_enable(Cursor *cursor); + +/** + * Disables a cursor, removing it from the display. + * + * @param cursor The cursor + */ +void cursor_disable(Cursor *cursor); + +/** + * Sets the position of the cursor. + * The positions are from left to right (horizontal) and top to bottom (vertical). + * + * @param cursor The cursor + * @param x The new horizontal position + * @param y The new vertical position + */ +void cursor_set_pos(Cursor *cursor, int x, int y); + +/** + * Moves the position of the cursor by an offset. This function ensures that the cursor is kept in the window bounds. + * A negative offset moves the cursor position towards the 0 direction (left or top). + * A position offset moves it in the opposite direction (right or bottom). + * + * @param cursor The cursor + * @param offset_x The horizontal offset + * @param offset_y The vertical offset + */ +void cursor_move(Cursor *cursor, int offset_x, int offset_y); + +#endif //NESEMULATOR_CURSOR_H diff --git a/debugger/debugger.c b/debugger/debugger.c index 3d079fc..1086404 100644 --- a/debugger/debugger.c +++ b/debugger/debugger.c @@ -25,13 +25,13 @@ void create_window() { } void start_debugger(System *system) { - MemoryView m_view; - ProgramView p_view; + InteractWindow windows[2]; + InteractWindow *current_window; create_window(); - memory_view_init(&m_view, system->ram, 0, 0); - program_view_init(&p_view, MEMORY_VIEW_WIDTH, 0); + memory_view_init(&windows[0], system->ram, 0, 0); + program_view_init(&windows[1], system->ram, MEMORY_VIEW_WIDTH, 0); update_panels(); doupdate(); @@ -39,19 +39,19 @@ void start_debugger(System *system) { int keycode; while ((keycode = getch()) != CTRL_KEY_EXIT) { if (keycode == KEY_UP) { - memory_view_move_cursor(&m_view, 0, MEMORY_VIEW_DIRECTION_DOWN); + current_window->handle_cursor_move(current_window, 0, CURSOR_OFFSET_UP); } if (keycode == KEY_DOWN) { - memory_view_move_cursor(&m_view, 0, MEMORY_VIEW_DIRECTION_UP); + current_window->handle_cursor_move(current_window, 0, CURSOR_OFFSET_DOWN); } if (keycode == KEY_LEFT) { - memory_view_move_cursor(&m_view, MEMORY_VIEW_DIRECTION_LEFT, 0); + current_window->handle_cursor_move(current_window, CURSOR_OFFSET_LEFT, 0); } if (keycode == KEY_RIGHT) { - memory_view_move_cursor(&m_view, MEMORY_VIEW_DIRECTION_RIGHT, 0); + current_window->handle_cursor_move(current_window, CURSOR_OFFSET_RIGHT, 0); } if (keycode == CTRL_KEY_G) { @@ -63,7 +63,7 @@ void start_debugger(System *system) { if (!cancelled) { memory_view_goto(&m_view, input); - memory_view_set_cursor_addr(&m_view, input); + memory_view_cursor_set_addr(&m_view, input); } } @@ -71,5 +71,8 @@ void start_debugger(System *system) { doupdate(); } + window_inter_deinit(&windows[0]); + window_inter_deinit(&windows[1]); + endwin(); } \ No newline at end of file diff --git a/debugger/debugger.h b/debugger/debugger.h index e27eb35..6de8a78 100644 --- a/debugger/debugger.h +++ b/debugger/debugger.h @@ -2,11 +2,11 @@ // Created by william on 1/6/24. // -#include "../include/system.h" - #ifndef NESEMULATOR_DEBUGGER_H #define NESEMULATOR_DEBUGGER_H +#include "../include/system.h" + void start_debugger(System *system); #endif //NESEMULATOR_DEBUGGER_H diff --git a/debugger/memory_view.c b/debugger/memory_view.c index 2d7247e..eac4244 100644 --- a/debugger/memory_view.c +++ b/debugger/memory_view.c @@ -1,58 +1,47 @@ -#include -#include #include +#include #include "memory_view.h" // -// Created by william on 1/6/24. +// Created by william on 6/1/24. // - -void memory_view_highlight_cursor(MemoryView *view) { - int win_x = 8 + view->cursor_x * 3; - int win_y = 2 + view->cursor_y; - mvwchgat(view->panel->win, win_y, win_x, 2, A_REVERSE, 0, NULL); -} - -void memory_view_set_cursor_pos(MemoryView *view, int x, int y) { - assert(x >= 0); - assert(x <= 0xf); - assert(y >= 0); - assert(y <= 0xf); - - int old_win_x = 8 + view->cursor_x * 3; - int old_win_y = 2 + view->cursor_y; - - mvwchgat(view->panel->win, old_win_y, old_win_x, 2, A_NORMAL, 0, NULL); - - view->cursor_x = (char) x; - view->cursor_y = (char) y; - - memory_view_highlight_cursor(view); -} - -void memory_view_write_line(WINDOW *window, int line, address base_address, byte *data) { - mvwprintw(window, line + 2, 1, "[%04x]", base_address); +void memory_view_write_line(MemoryView *view, int line, address base_address, byte *data) { + window_inter_print(view->window, 0, line + 1, "[%04x]", base_address); for (int i = 0; i <= MEMORY_VIEW_LINE_BYTE_COUNT; i++) { - mvwprintw(window, line + 2, 8 + i * 3, "%02x", data[i]); + window_inter_print(view->window, 7 + i * 3, line + 1, "%02x", data[i]); } } -void memory_view_init(MemoryView *view, ram ram, int x, int y) { - WINDOW *window = newwin(MEMORY_VIEW_HEIGHT, MEMORY_VIEW_WIDTH, y, x); - box(window, 0, 0); +void memory_view_cursor_init(MemoryView *view) { + Cursor *cursor = &view->window->cursor; + window_inter_cursor_init(view->window, 0xf, 0xf); + cursor->min_x = 8; + cursor->min_y = 2; + cursor->multiplier_x = 3; + cursor->width = 2; - mvwprintw(window, 0, 1, " MEMORY VIEW "); - mvwprintw(window, 1, 1, " +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +a +b +c +d +e +f"); + cursor_enable(cursor); +} - view->panel = new_panel(window); +void memory_view_handle_key_down(InteractWindow *window, int keycode) { + +} + +void memory_view_init(InteractWindow *interact, ram ram, int x, int y) { + MemoryView *view = malloc(sizeof(MemoryView)); + view->window = interact; view->ram = ram; view->base_address = 0x0000; - view->cursor_x = 0; - view->cursor_y = 0; + + interact->view = view; + interact->handle_cursor_move = &memory_view_cursor_move; + interact->handle_key_down = &memory_view_handle_key_down; + window_inter_init(interact, x, y, MEMORY_VIEW_WIDTH, MEMORY_VIEW_HEIGHT, "MEMORY VIEW"); + window_inter_print(interact, 0, 0, " +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +a +b +c +d +e +f"); memory_view_print(view); - memory_view_set_cursor_pos(view, 0, 0); + memory_view_cursor_init(view); } void memory_view_print(MemoryView *view) { @@ -60,7 +49,7 @@ void memory_view_print(MemoryView *view) { address line_address = view->base_address + line * (MEMORY_VIEW_LINE_BYTE_COUNT + 1); byte *data = &view->ram[line_address]; - memory_view_write_line(view->panel->win, line, line_address, data); + memory_view_write_line(view, line, line_address, data); } } @@ -77,14 +66,14 @@ void memory_view_goto(MemoryView *view, address target) { memory_view_print(view); } -void memory_view_scroll(MemoryView *view, char direction) { - assert(direction == MEMORY_VIEW_DIRECTION_DOWN || direction == MEMORY_VIEW_DIRECTION_UP); +void memory_view_scroll(MemoryView *view, int direction) { + assert(direction == CURSOR_OFFSET_DOWN || direction == CURSOR_OFFSET_UP); int offset = 0; - if (direction == MEMORY_VIEW_DIRECTION_DOWN && view->base_address > MEMORY_VIEW_LINE_BYTE_COUNT) { + if (direction == CURSOR_OFFSET_UP && view->base_address > MEMORY_VIEW_LINE_BYTE_COUNT) { offset -= MEMORY_VIEW_LINE_BYTE_COUNT + 1; } - if (direction == MEMORY_VIEW_DIRECTION_UP && view->base_address < RAM_SIZE - MEMORY_VIEW_BYTE_COUNT) { + if (direction == CURSOR_OFFSET_DOWN && view->base_address < RAM_SIZE - MEMORY_VIEW_BYTE_COUNT) { offset += MEMORY_VIEW_LINE_BYTE_COUNT + 1; } @@ -92,28 +81,23 @@ void memory_view_scroll(MemoryView *view, char direction) { memory_view_goto(view, target); } -void memory_view_move_cursor(MemoryView *view, char horizontal, char vertical) { - if (horizontal == MEMORY_VIEW_DIRECTION_UP && view->cursor_x == 0xf || - horizontal == MEMORY_VIEW_DIRECTION_DOWN && view->cursor_x == 0) { - return; - } +void memory_view_cursor_move(InteractWindow *window, int horizontal, int vertical) { + MemoryView *view = (MemoryView *) window->view; - if (vertical == MEMORY_VIEW_DIRECTION_RIGHT && view->cursor_y == 0xf || - vertical == MEMORY_VIEW_DIRECTION_LEFT && view->cursor_y == 0) { + if (vertical == CURSOR_OFFSET_DOWN && view->window->cursor.pos_y == 0xf || + vertical == CURSOR_OFFSET_UP && view->window->cursor.pos_y == 0) { + // Scroll the view memory_view_scroll(view, vertical); - memory_view_highlight_cursor(view); - return; } - int target_x = view->cursor_x + horizontal; - int target_y = view->cursor_y + vertical; - memory_view_set_cursor_pos(view, target_x, target_y); + // We are not on any edge, move the cursor + cursor_move(&view->window->cursor, horizontal, vertical); } -void memory_view_set_cursor_addr(MemoryView *view, address target) { +void memory_view_cursor_set_addr(MemoryView *view, address target) { int view_byte = target - view->base_address; int x = view_byte & 0x0f; int y = (view_byte & 0xf0) >> 4; - memory_view_set_cursor_pos(view, x, y); + cursor_set_pos(&view->window->cursor, x, y); } \ No newline at end of file diff --git a/debugger/memory_view.h b/debugger/memory_view.h index 0e01c07..db15633 100644 --- a/debugger/memory_view.h +++ b/debugger/memory_view.h @@ -1,5 +1,5 @@ // -// Created by william on 1/6/24. +// Created by william on 6/1/24. // #ifndef NESEMULATOR_MEMORY_VIEW_H @@ -7,6 +7,8 @@ #include #include "../include/types.h" +#include "cursor.h" +#include "window.h" #define MEMORY_VIEW_HEIGHT 19 #define MEMORY_VIEW_WIDTH 56 @@ -14,17 +16,10 @@ #define MEMORY_VIEW_LINE_BYTE_COUNT 0xf #define MEMORY_VIEW_BYTE_COUNT 0xff -#define MEMORY_VIEW_DIRECTION_UP 1 -#define MEMORY_VIEW_DIRECTION_DOWN (-1) -#define MEMORY_VIEW_DIRECTION_RIGHT 1 -#define MEMORY_VIEW_DIRECTION_LEFT (-1) - typedef struct memory_view { - PANEL *panel; + InteractWindow *window; byte *ram; address base_address; - char cursor_x; - char cursor_y; } MemoryView; /** @@ -34,7 +29,7 @@ typedef struct memory_view { * @param view A pointer to the view to initialize * @param ram A pointer to the RAM */ -void memory_view_init(MemoryView *view, ram ram, int x, int y); +void memory_view_init(InteractWindow *interact, ram ram, int x, int y); /** * Prints the RAM content from the viewer base address. @@ -57,7 +52,7 @@ void memory_view_goto(MemoryView *view, address target); * @param view * @param direction The scroll direction */ -void memory_view_scroll(MemoryView *view, char direction); +void memory_view_scroll(MemoryView *view, int direction); /** * Moves the cursor up, down, right or left. @@ -66,7 +61,7 @@ void memory_view_scroll(MemoryView *view, char direction); * @param horizontal * @param vertical */ -void memory_view_move_cursor(MemoryView *view, char horizontal, char vertical); +void memory_view_cursor_move(InteractWindow *window, int horizontal, int vertical); /** * Moves the cursor to a specific memory address. @@ -75,6 +70,6 @@ void memory_view_move_cursor(MemoryView *view, char horizontal, char vertical); * @param view * @param target */ -void memory_view_set_cursor_addr(MemoryView *view, address target); +void memory_view_cursor_set_addr(MemoryView *view, address target); #endif //NESEMULATOR_MEMORY_VIEW_H diff --git a/debugger/program_view.c b/debugger/program_view.c index 4872295..5027514 100644 --- a/debugger/program_view.c +++ b/debugger/program_view.c @@ -2,42 +2,118 @@ // Created by william on 10/01/24. // +#include #include "program_view.h" #include "../cpu/op.h" -void decode_operands(byte *ram, address start_addr) { +void decode_operands(DebugOperand *operands, const byte *ram, address start_addr) { int pc = start_addr; - for (int i = 0; i < 10; i++) { DebugOperand operand; byte op_code = ram[pc]; + operand.addr = pc; operand.op_code = op_code; operand.addr_mode = get_op_addr_mode(op_code); + + pc += 1; + + if (operand.addr_mode == ADDR_MODE_ACCUMULATOR || operand.addr_mode == ADDR_MODE_IMPLICIT) { + operand.type = OPERAND_TYPE_ACCUMULATOR; + operand.value = 0; + } else if (operand.addr_mode == ADDR_MODE_IMMEDIATE) { + operand.type = OPERAND_TYPE_IMMEDIATE; + operand.value = ram[pc]; + pc += 1; + } else if (operand.addr_mode == ADDR_MODE_RELATIVE) { + operand.type = OPERAND_TYPE_ADDRESS; + operand.value = ram[pc]; + pc += 1; + } else { + operand.type = OPERAND_TYPE_ADDRESS; + operand.value = ram[pc]; + operand.value += ram[pc + 1] << 8; + pc += 2; + } + + operands[i] = operand; } } -void program_view_write_line(WINDOW *window, int line, address addr) { - mvwprintw(window, line + 1, 1, "%04x:", addr); - mvwprintw(window, line + 1, 7, "%s", "BRK"); -} - -void program_view_print(ProgramView *view) { - for (int line = 0; line <= 0xf; line++) { - address addr = 0x8000 + line; - - program_view_write_line(view->panel->win, line, addr); +char *get_addr_mode_format_str(AddressingMode addr_mode) { + switch (addr_mode) { + case ADDR_MODE_ABSOLUTE: + return "$%04x"; + case ADDR_MODE_ABSOLUTE_INDEXED_X: + return "$%04x,x"; + case ADDR_MODE_ABSOLUTE_INDEXED_Y: + return "$%04x,y"; + case ADDR_MODE_ACCUMULATOR: + return "A"; + case ADDR_MODE_IMMEDIATE: + return "#$%02x"; + case ADDR_MODE_IMPLICIT: + return ""; + case ADDR_MODE_INDIRECT_X: + return "($%04x,x)"; + case ADDR_MODE_INDIRECT_JUMP: + return "($%04x)"; + case ADDR_MODE_INDIRECT_Y: + return "($%04x),y"; + case ADDR_MODE_RELATIVE: + return "$%04x"; + case ADDR_MODE_ZERO_PAGE: + return "$%02x,y"; + case ADDR_MODE_ZERO_PAGE_INDEXED_X: + return "$%02x,x"; + case ADDR_MODE_ZERO_PAGE_INDEXED_Y: + return "$%02x,y"; } } -void program_view_init(ProgramView *view, ram ram, int x, int y) { - WINDOW *window = newwin(PROGRAM_VIEW_HEIGHT, PROGRAM_VIEW_WIDTH, y, x); - box(window, 0, 0); +void program_view_write_line(ProgramView *view, int line, DebugOperand *operand) { + char *op_name = get_op_code_name(operand->op_code); - mvwprintw(window, 0, 1, " PROGRAM VIEW "); + window_inter_print(view->window, 0, line, "%04x:", operand->addr); + window_inter_print(view->window, 6, line, "%s", op_name); - view->panel = new_panel(window); + char *format = get_addr_mode_format_str(operand->addr_mode); + window_inter_print(view->window, 10, line, format, operand->value); +} + +void program_view_print(ProgramView *view, DebugOperand *operands) { + for (int line = 0; line < 10; line++) { + program_view_write_line(view, line, &operands[line]); + } +} + +void program_view_cursor_init(ProgramView *view) { + window_inter_cursor_init(view->window, 0, 10); + view->window->cursor.width = PROGRAM_VIEW_WIDTH - 2; + cursor_enable(&view->window->cursor); +} + +void program_view_handle_cursor_move(InteractWindow *window, int horizontal, int vertical) { + cursor_move(&window->cursor, horizontal, vertical); +} + +void program_view_handle_key_down(InteractWindow *window, int keycode) { + +} + +void program_view_init(InteractWindow *interact, ram ram, int x, int y) { + ProgramView *view = malloc(sizeof(ProgramView)); + view->window = interact; view->ram = ram; - program_view_print(view); + interact->view = view; + interact->handle_cursor_move = &program_view_handle_cursor_move; + interact->handle_key_down = &program_view_handle_key_down; + window_inter_init(interact, x, y, PROGRAM_VIEW_WIDTH, PROGRAM_VIEW_HEIGHT, "PROGRAM VIEW"); + + DebugOperand operands[10]; + decode_operands(&operands[0], ram, 0xc004); + + program_view_print(view, &operands[0]); + program_view_cursor_init(view); } \ No newline at end of file diff --git a/debugger/program_view.h b/debugger/program_view.h index def6742..3f22ab9 100644 --- a/debugger/program_view.h +++ b/debugger/program_view.h @@ -2,27 +2,32 @@ // Created by william on 10/01/24. // +#ifndef NESEMULATOR_PROGRAM_VIEW_H +#define NESEMULATOR_PROGRAM_VIEW_H + #include #include "../include/types.h" #include "../cpu/decoding.h" - -#ifndef NESEMULATOR_PROGRAM_VIEW_H -#define NESEMULATOR_PROGRAM_VIEW_H +#include "cursor.h" +#include "window.h" #define PROGRAM_VIEW_HEIGHT 19 #define PROGRAM_VIEW_WIDTH 42 typedef struct program_view { - PANEL *panel; + InteractWindow *window; byte *ram; address base_address; } ProgramView; typedef struct debug_operand { + address addr; byte op_code; AddressingMode addr_mode; + enum OperandType type; + word value; } DebugOperand; -void program_view_init(ProgramView *view, ram ram, int x, int y); +void program_view_init(InteractWindow *interact, ram ram, int x, int y); #endif //NESEMULATOR_PROGRAM_VIEW_H \ No newline at end of file diff --git a/debugger/window.c b/debugger/window.c new file mode 100644 index 0000000..488fab8 --- /dev/null +++ b/debugger/window.c @@ -0,0 +1,61 @@ +// +// Created by william on 1/12/24. +// + +#include +#include +#include "window.h" + +void window_init(Window *window, int x, int y, int width, int height, char *title) { + assert(x >= 0); + assert(y >= 0); + assert(width > 0); + assert(height > 0); + + WINDOW *curse_win = newwin(height, width, y, x); + box(curse_win, 0, 0); + + mvwprintw(curse_win, 0, 1, " %s ", title); + + window->panel = new_panel(curse_win); + window->width = width; + window->height = height; +} + +void window_inter_init(InteractWindow *window, int x, int y, int width, int height, char *title) { + window_init(&window->window, x, y, width, height, title); +} + +void window_print_va(Window *window, int x, int y, const char *fmt, va_list args) { + assert(x >= 0); + assert(x < window->width - 1); + assert(y >= 0); + assert(y < window->height - 1); + + wmove(window->panel->win, y + 1, x + 1); + vw_printw(window->panel->win, fmt, args); +} + +void window_inter_cursor_init(InteractWindow *window, int max_x, int max_y) { + cursor_init(&window->cursor, window->window.panel->win, max_x, max_y); +} + +void window_print(Window *window, int x, int y, const char *fmt, ...) { + va_list args; + va_start(args, fmt); + window_print_va(window, x, y, fmt, args); + va_end(args); +} + +void window_inter_print(InteractWindow *window, int x, int y, const char *fmt, ...) { + va_list args; + va_start(args, fmt); + window_print_va(&window->window, x, y, fmt, args); + va_end(args); +} + +void window_inter_deinit(InteractWindow *window) { + assert(window->view != NULL); + + free(window->view); +} \ No newline at end of file diff --git a/debugger/window.h b/debugger/window.h new file mode 100644 index 0000000..1e59011 --- /dev/null +++ b/debugger/window.h @@ -0,0 +1,84 @@ +// +// Created by william on 1/12/24. +// + +#ifndef NESEMULATOR_WINDOW_H +#define NESEMULATOR_WINDOW_H + +#include +#include "cursor.h" + +typedef struct window { + PANEL *panel; + int width; + int height; +} Window; + +typedef struct interact_window { + Window window; + Cursor cursor; + void *view; + + void (*handle_cursor_move)(struct interact_window *window, int horizontal, int vertical); + + void (*handle_key_down)(struct interact_window *window, int keycode); +} InteractWindow; + +/** + * Initializes a window with a position, size and title. + * + * @param window The window to initialize + * @param x The horizontal position (left to right) + * @param y The vertical position (top to bottom) + * @param width The window width + * @param height The window height + * @param title The window title + */ +void window_init(Window *window, int x, int y, int width, int height, char *title); + +/** + * Initializes an interactable window with a position, size and title. + * + * @param window The window to initialize + * @param x The horizontal position (left to right) + * @param y The vertical position (top to bottom) + * @param width The window width + * @param height The window height + * @param title The window title + */ +void window_inter_init(InteractWindow *window, int x, int y, int width, int height, char *title); + +/** + * Initializes the cursor of an interactable window. + * + * @param window The window + * @param max_x The cursor's maximum horizontal position + * @param max_y The cursor's maximum vertical position + */ +void window_inter_cursor_init(InteractWindow *window, int max_x, int max_y); + +/** + * Prints text on a window. + * + * @param window The window + * @param x The horizontal position (left to right) + * @param y The vertical position (top to bottom) + * @param fmt A format string + * @param ... The format string arguments + */ +void window_print(Window *window, int x, int y, const char *fmt, ...); + +/** + * Prints text on an interactable window. + * + * @param window The window + * @param x The horizontal position (left to right) + * @param y The vertical position (top to bottom) + * @param fmt A format string + * @param ... The format string arguments + */ +void window_inter_print(InteractWindow *window, int x, int y, const char *fmt, ...); + +void window_inter_deinit(InteractWindow *window); + +#endif //NESEMULATOR_WINDOW_H diff --git a/test_roms/nestest.fdb b/test_roms/nestest.fdb index 46c2c6d..a972c53 100644 --- a/test_roms/nestest.fdb +++ b/test_roms/nestest.fdb @@ -1,3 +1,4 @@ BreakPoint: startAddr=00000014 endAddr=00000000 flags=ER--X- condition="" desc="" BreakPoint: startAddr=00000023 endAddr=00000000 flags=ER--X- condition="" desc="" BreakPoint: startAddr=00000000 endAddr=00000000 flags=EC--X- condition="" desc="" +Bookmark: addr=C10F desc=""