// // 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" 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.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 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 } int gui_input() { SDL_Event event; while (SDL_PollEvent(&event)) { if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE) { return -1; } if (event.type == SDL_KEYUP) { if (event.key.keysym.sym == SDLK_p) { system_toggle_pause(); } else { #if DEBUG if (event.key.keysym.sym == SDLK_t) { PPUDebugFlags *ppu_debug = &ppu_get_state()->debug; ppu_debug->flags.tile_debugger = !ppu_debug->flags.tile_debugger; } else { pattern_window_key_up(&gui.pattern_window, event.key.keysym.sym); } #endif } } } return 1; } void gui_render() { #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 main_window_render(&gui.main_window, ppu_get_state()->pixels); } void gui_present() { #if DEBUG pattern_window_present(&gui.pattern_window); nametable_window_present(&gui.nametable_window); #endif main_window_present(&gui.main_window); } 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(); } unsigned int gui_get_frame_delay() { return gui.frame_delay; }