// // Created by william on 16/05/24. // #include #include "log.h" #include "gui.h" #include "main_window.h" #include "pattern_window.h" #include "../include/system.h" #include "nametable_window.h" #include "dbg_pattern_table.h" #include "dbg_nametable.h" #include "char_map.h" #include "dbg_palette.h" #if DEBUG #define WINDOW_ID_MAIN 3 #else #define WINDOW_ID_MAIN 1 #endif typedef struct nes_gui { NesMainWindow main_window; NesPatternWindow pattern_window; NesNametableWindow nametable_window; TTF_Font *font; Uint32 last_frame_tick; Uint32 frame_delay; #if DEBUG unsigned long tick; #endif } NesGui; NesGui gui; bool gui_init() { TTF_Init(); gui.font = TTF_OpenFont("./nintendo-nes-font.ttf", 16); if (gui.font == NULL) { log_error("Failed to open TTF font"); return false; } #if DEBUG gui.tick = 0; pattern_window_init(&gui.pattern_window); nametable_window_init(&gui.nametable_window); char_map_init(gui.main_window.window.sdl_context.renderer, gui.font); #endif main_window_init(&gui.main_window); return true; } void gui_uninit() { main_window_uninit(&gui.main_window); #if DEBUG char_map_uninit(); pattern_window_uninit(&gui.pattern_window); nametable_window_uninit(&gui.nametable_window); #endif TTF_CloseFont(gui.font); } void gui_post_sysinit() { #if DEBUG dbg_palette_init(); dbg_pattern_table_init(); dbg_nametable_init(); // TODO: The background_texture is rendered before the palette data is in the PPU memory, so the only color is grey pattern_window_build_table(&gui.pattern_window); nametable_window_update(&gui.nametable_window); #endif } bool lctrl = false; int gui_input() { SDL_Event event; #if DEBUG PPUDebugFlags *ppu_debug = &ppu_get_state()->debug; #endif while (SDL_PollEvent(&event)) { if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE) { return -1; } if (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_LCTRL) { lctrl = true; } if (event.type == SDL_KEYUP) { switch (event.key.keysym.sym) { case SDLK_LCTRL: lctrl = false; break; case SDLK_p: system_toggle_pause(lctrl); break; #if DEBUG case SDLK_t: ppu_debug->flags.tile_debugger = !ppu_debug->flags.tile_debugger; break; case SDLK_n: ppu_debug->flags.tile_debugger_pattern_half = (ppu_debug->flags.tile_debugger_pattern_half + 1) % 3; break; default: pattern_window_key_up(&gui.pattern_window, event.key.keysym.sym); break; #else default: break; #endif } } if (event.type == SDL_MOUSEMOTION) { int x = event.motion.x; int y = event.motion.y; if (event.window.windowID == WINDOW_ID_MAIN) { main_window_mouse_motion(&gui.main_window, x, y); } } if (event.type == SDL_MOUSEBUTTONUP && event.window.windowID == WINDOW_ID_MAIN) { main_window_mouse_click(&gui.main_window); } } return 1; } void gui_render() { main_window_render(&gui.main_window, ppu_get_state()->pixels); #if DEBUG dbg_palette_init(); pattern_window_render(&gui.pattern_window); nametable_window_update(&gui.nametable_window); nametable_window_render(&gui.nametable_window); gui.tick++; #endif } void gui_present() { #if DEBUG pattern_window_present(&gui.pattern_window); nametable_window_present(&gui.nametable_window); #endif } void gui_delay() { Uint32 tick_now = SDL_GetTicks(); gui.frame_delay = tick_now - gui.last_frame_tick; if (gui.frame_delay < 16) { Uint32 additional_delay = 16 - gui.frame_delay; SDL_Delay(additional_delay); gui.frame_delay += additional_delay; } gui.last_frame_tick = SDL_GetTicks(); } TTF_Font *gui_get_font() { return gui.font; } unsigned int gui_get_frame_delay() { return gui.frame_delay; }