From 135b90e1759b951f3935a912c27085457a87de1b Mon Sep 17 00:00:00 2001 From: Nathaniel Walizer Date: Sun, 11 May 2025 20:49:25 -0700 Subject: [PATCH] Add text drawing API; refactor start sequence to prepare for menus --- src/action.h | 20 ++++++++++++++ src/linux/port.c | 70 ++++++++++++++++++++++++++++++------------------ src/port.h | 8 ++++++ src/sdl/draw.c | 42 +++++++++++++++++++++++++++++ src/sdl/draw.h | 30 +++++++++++++++++++++ src/sdl/render.c | 5 ++-- 6 files changed, 147 insertions(+), 28 deletions(-) create mode 100644 src/action.h create mode 100644 src/sdl/draw.c create mode 100644 src/sdl/draw.h diff --git a/src/action.h b/src/action.h new file mode 100644 index 0000000..b6bab17 --- /dev/null +++ b/src/action.h @@ -0,0 +1,20 @@ +#ifndef NESE_ACTION_H_ +#define NESE_ACTION_H_ + + +typedef enum { + Action_Error = -1, + Action_OK, + Action_Quit, + Action_Reset, + Action_Load, + Action_Save, + Action_Menu, + Action_Cancel, + Action_FPS, + Action_Turbo, + Action_Max +} nese_Action; + + +#endif // NESE_ACTION_H_ \ No newline at end of file diff --git a/src/linux/port.c b/src/linux/port.c index 022cdfd..78626fc 100644 --- a/src/linux/port.c +++ b/src/linux/port.c @@ -7,12 +7,13 @@ #include #include +#include "action.h" #include "cart.h" #include "nese.h" #include "overlay.h" #include "port.h" #include "save.h" -#include "render.h" +#include "draw.h" #include "cartinfo.h" #define NESE_DEBUG "Port" @@ -97,20 +98,6 @@ typedef struct { /* Input */ -typedef enum { - Action_Error = -1, - Action_OK, - Action_Quit, - Action_Reset, - Action_Load, - Action_Save, - Action_Menu, - Action_Cancel, - Action_FPS, - Action_Turbo, - Action_Max -} nese_Action; - int nese_update_input(void* plat_data, nes_Input* input) { // Gamepad states are already updated in nese_frame_ready() return 0; @@ -151,7 +138,6 @@ static int keycode_index(int keycode, const int* codes, int n_codes) { return index; } -// TODO: Return an action enum? static nese_Action process_events(nes* sys) { nese_Action action = Action_OK; nes_Input* input = &sys->core.memory.input; @@ -365,6 +351,27 @@ int nese_frame_ready(void* plat_data) { } +/* Drawing */ + +void nese_draw_begin(void* plat_data, int dim) { + draw_begin(&((platform_data*)plat_data)->renderer, dim); +} + +void nese_draw_text(void* plat_data, const char* str, int x, int y, uint32_t c) { + draw_text(&((platform_data*)plat_data)->renderer, + &((platform_data*)plat_data)->overlay.font, + str, x, y, c); +} + +void nese_text_size(void* plat_data, const char* str, int* w, int* h) { + overlay_font_measure(&((platform_data*)plat_data)->overlay.font, str, w, h); +} + +void nese_draw_finish(void* plat_data) { + render_frame_end(&((platform_data*)plat_data)->renderer); +} + + /* Audio */ int nese_get_audio_frequency(void*) { @@ -409,21 +416,32 @@ int main(int argc, char* argv[]) { .sys = &sys, }; - if (argc <= 1) { - LOGE("No ROM file provided."); - status = -1; - } - - if (0 == status) { - status = load_cart(&plat.cart, argv[1], &sys); - } - if (0 == status) { status = plat_init(&plat); } if (0 == status) { - status = nese_start(&sys, &plat); + if (argc <= 1) { + LOGI("No ROM file provided."); + status = -1; + + } else { + status = load_cart(&plat.cart, argv[1], &sys); + if (0 != status) { + LOGE("Failed to load %s", argv[1]); + // TODO: Error modal on load failure + } + } + + if (NULL == sys.cart_header) { + // TODO: ROM selection menu + status = -1; + } + + // This shall invoke menus as needed + if (0 == status) { + status = nese_start(&sys, &plat); + } } unload_cart(&plat.cart); diff --git a/src/port.h b/src/port.h index 15a7c6d..1abd841 100644 --- a/src/port.h +++ b/src/port.h @@ -22,7 +22,9 @@ int nese_mkdir(const char* dirname); int nese_frame_start(void*, uint8_t background); int nese_line_ready(void*, uint8_t* buffer, int line); int nese_frame_ready(void*); + int nese_update_input(void*, nes_Input*); + int nese_get_audio_frequency(void*); @@ -31,4 +33,10 @@ void* nese_alloc_cpu(int); void* nese_alloc(int); +void nese_draw_begin(void*, int dim); +void nese_draw_text(void*, const char*, int x, int y, uint32_t color); +void nese_text_size(void*, const char*, int* w, int* h); +void nese_draw_finish(void*); + + #endif // NESE_PORT_H_ diff --git a/src/sdl/draw.c b/src/sdl/draw.c new file mode 100644 index 0000000..7653118 --- /dev/null +++ b/src/sdl/draw.c @@ -0,0 +1,42 @@ +#include "port.h" +#include "render.h" +#include "overlay.h" + + +void draw_begin(Render_Info* renderer, int dim) { + SDL_RenderFlush(renderer->renderer); + + if (dim) { + SDL_SetTextureAlphaMod(renderer->texture, 0x7F); + SDL_SetTextureBlendMode(renderer->texture, + SDL_BLENDMODE_BLEND); + } + + SDL_RenderClear(renderer->renderer); + + SDL_UnlockTexture(renderer->texture); + SDL_RenderCopy(renderer->renderer, renderer->texture, + NULL, &renderer->view); + SDL_LockTextureToSurface(renderer->texture, NULL, &renderer->target); + + if (dim) { + SDL_SetTextureBlendMode(renderer->texture, + SDL_BLENDMODE_NONE); + } +} + +void draw_finish(Render_Info* renderer) { + SDL_RenderPresent(renderer->renderer); +} + +void draw_text(Render_Info* renderer, Overlay_font* font, + const char* str, int x, int y, uint32_t color) { + const SDL_Rect target = { + .x = x, + .y = y, + .w = nes_ppu_render_w, + .h = nes_ppu_render_h, + }; + overlay_font_render(font, str, &target, &renderer->view, + color, renderer->renderer); +} diff --git a/src/sdl/draw.h b/src/sdl/draw.h new file mode 100644 index 0000000..04c86c1 --- /dev/null +++ b/src/sdl/draw.h @@ -0,0 +1,30 @@ +#ifndef NESE_DRAW_H_ +#define NESE_DRAW_H_ + +#include "overlay.h" +#include "render.h" + + +#define color_white (0xFFffffffU) +#define color_black (0xFF000000U) +#define color_red (0xFFff371aU) +#define color_orange (0xFFff7b59U) +#define color_yellow (0xFFffa233U) +#define color_green (0xFF51d96aU) +#define color_blue (0xFF6f84ffU) +#define color_purple (0xFFd56fffU) + + +#define color_background color_blue +#define color_menu color_white +#define color_highlight color_yellow +#define color_error color_red + + +void draw_begin(Render_Info*, int dim); +void draw_text(Render_Info*, Overlay_font*, const char*, + int x, int y, uint32_t color); +void draw_finish(Render_Info*); + + +#endif // NESE_DRAW_H_ \ No newline at end of file diff --git a/src/sdl/render.c b/src/sdl/render.c index 39d1ac3..c103dd4 100644 --- a/src/sdl/render.c +++ b/src/sdl/render.c @@ -1,4 +1,5 @@ #include "render.h" +#include "draw.h" #define NESE_DEBUG "SDL" #include "log.h" @@ -43,7 +44,7 @@ int render_frame(Render_Info* renderer) { SDL_UnlockTexture(renderer->texture); SDL_RenderCopy(renderer->renderer, renderer->texture, - NULL, NULL); + NULL, &renderer->view); SDL_LockTextureToSurface(renderer->texture, NULL, &renderer->target); @@ -105,7 +106,7 @@ int render_info_init(Render_Info* renderer, nes* sys) { } else { SDL_LockTextureToSurface(renderer->texture, NULL, &renderer->target); -// SDL_FillRect(data->target, NULL, color_background); + SDL_FillRect(renderer->target, NULL, color_background); } }