diff --git a/src/emulator.c b/src/emulator.c index 49f8f069..2248eac3 100644 --- a/src/emulator.c +++ b/src/emulator.c @@ -211,6 +211,9 @@ static void emu_close(void *data) { } static void emu_paint(struct emu *emu) { + float w = (float)win_width(emu->win); + float h = (float)win_height(emu->win); + prof_counter_add(COUNTER_frames, 1); r_clear_viewport(emu->r); @@ -221,9 +224,6 @@ static void emu_paint(struct emu *emu) { struct frame *frame = emu_pop_frame(emu); if (frame) { - float w = (float)emu->win->width; - float h = (float)emu->win->height; - struct vertex2 verts[6] = { /* triangle 1, top left */ {{0.0f, 0.0f}, {0.0f, 1.0f}, 0xffffffff}, @@ -264,8 +264,7 @@ static void emu_paint(struct emu *emu) { /* render debug menus */ if (emu->debug_menu) { struct nk_context *ctx = &emu->nk->ctx; - struct nk_rect bounds = {0.0f, 0.0f, (float)emu->win->width, - DEBUG_MENU_HEIGHT}; + struct nk_rect bounds = {0.0f, 0.0f, w, DEBUG_MENU_HEIGHT}; nk_style_default(ctx); @@ -275,9 +274,10 @@ static void emu_paint(struct emu *emu) { ctx->style.window.padding = nk_vec2(0.0f, 0.0f); if (nk_begin(ctx, "debug menu", bounds, NK_WINDOW_NO_SCROLLBAR)) { + static int max_debug_menus = 32; + nk_menubar_begin(ctx); - nk_layout_row_begin(ctx, NK_STATIC, DEBUG_MENU_HEIGHT, - MAX_WINDOW_LISTENERS + 2); + nk_layout_row_begin(ctx, NK_STATIC, DEBUG_MENU_HEIGHT, max_debug_menus); /* add our own debug menu */ nk_layout_row_push(ctx, 30.0f); @@ -285,7 +285,7 @@ static void emu_paint(struct emu *emu) { nk_vec2(140.0f, 200.0f))) { nk_layout_row_dynamic(ctx, DEBUG_MENU_HEIGHT, 1); - int fullscreen = emu->win->fullscreen; + int fullscreen = win_fullscreen(emu->win); if (nk_checkbox_label(ctx, "fullscreen", &fullscreen)) { win_set_fullscreen(emu->win, fullscreen); } @@ -310,8 +310,7 @@ static void emu_paint(struct emu *emu) { snprintf(status, sizeof(status), "FPS %3d RPS %3d VBS %3d SH4 %4d ARM %d", frames, ta_renders, pvr_vblanks, sh4_instrs, arm7_instrs); - nk_layout_row_push( - ctx, (float)emu->win->width - ctx->current->layout->row.item_offset); + nk_layout_row_push(ctx, w - ctx->current->layout->row.item_offset); nk_label(ctx, status, NK_TEXT_RIGHT); nk_layout_row_end(ctx); diff --git a/src/tracer.c b/src/tracer.c index f82fc1db..4c8f5d32 100644 --- a/src/tracer.c +++ b/src/tracer.c @@ -286,6 +286,8 @@ static const float SCRUBBER_WINDOW_HEIGHT = 20.0f; static void tracer_render_scrubber_menu(struct tracer *tracer) { struct nk_context *ctx = &tracer->nk->ctx; + float width = (float)win_width(tracer->win); + float height = (float)win_height(tracer->win); nk_style_default(ctx); @@ -293,9 +295,8 @@ static void tracer_render_scrubber_menu(struct tracer *tracer) { ctx->style.window.padding = nk_vec2(0.0f, 0.0f); ctx->style.window.spacing = nk_vec2(0.0f, 0.0f); - struct nk_rect bounds = {0.0f, - (float)tracer->win->height - SCRUBBER_WINDOW_HEIGHT, - (float)tracer->win->width, SCRUBBER_WINDOW_HEIGHT}; + struct nk_rect bounds = {0.0f, height - SCRUBBER_WINDOW_HEIGHT, width, + SCRUBBER_WINDOW_HEIGHT}; nk_flags flags = NK_WINDOW_NO_SCROLLBAR; if (nk_begin(ctx, "context scrubber", bounds, flags)) { @@ -571,12 +572,14 @@ static void tracer_param_tooltip(struct tracer *tracer, static void tracer_render_side_menu(struct tracer *tracer) { struct nk_context *ctx = &tracer->nk->ctx; + float width = (float)win_width(tracer->win); + float height = (float)win_height(tracer->win); /* transparent menu backgrounds / selectables */ { struct nk_rect bounds = {0.0f, 0.0, 240.0f, - tracer->win->height - SCRUBBER_WINDOW_HEIGHT}; + height - SCRUBBER_WINDOW_HEIGHT}; nk_style_default(ctx); @@ -657,8 +660,8 @@ static void tracer_render_side_menu(struct tracer *tracer) { } { - struct nk_rect bounds = {tracer->win->width - 240.0f, 0.0, 240.0f, - tracer->win->height - SCRUBBER_WINDOW_HEIGHT}; + struct nk_rect bounds = {width - 240.0f, 0.0, 240.0f, + height - SCRUBBER_WINDOW_HEIGHT}; nk_style_default(ctx); diff --git a/src/ui/microprofile.cc b/src/ui/microprofile.cc index cfce6941..3af29d82 100644 --- a/src/ui/microprofile.cc +++ b/src/ui/microprofile.cc @@ -25,7 +25,7 @@ static const int MAX_2D_VERTICES = 32768; static const int MAX_2D_SURFACES = 256; struct microprofile { - struct window *window; + struct window *win; struct render_backend *r; struct window_listener listener; texture_handle_t font_texture; @@ -236,8 +236,11 @@ static void mp_draw_line(struct microprofile *mp, float *verts, int num_verts, void mp_render(struct microprofile *mp) { s_mp = mp; + int width = win_width(mp->win); + int height = win_height(mp->win); + /* update draw surfaces */ - MicroProfileDraw(mp->window->width, mp->window->height); + MicroProfileDraw(width, height); /* render the surfaces */ r_begin_ortho(mp->r); @@ -259,22 +262,21 @@ void mp_render(struct microprofile *mp) { void mp_destroy(struct microprofile *mp) { r_destroy_texture(mp->r, mp->font_texture); - win_remove_listener(mp->window, &mp->listener); + win_remove_listener(mp->win, &mp->listener); free(mp); } -struct microprofile *mp_create(struct window *window, - struct render_backend *r) { +struct microprofile *mp_create(struct window *win, struct render_backend *r) { struct microprofile *mp = reinterpret_cast( calloc(1, sizeof(struct microprofile))); - mp->window = window; + mp->win = win; mp->r = r; /* add input event listeners */ mp->listener = {mp, NULL, NULL, &mp_keydown, &mp_mousemove, NULL, {}}; - win_add_listener(mp->window, &mp->listener); + win_add_listener(mp->win, &mp->listener); /* register and enable cpu and gpu groups by default */ uint16_t cpu_group = MicroProfileGetGroup("cpu", MicroProfileTokenTypeCpu); diff --git a/src/ui/microprofile.h b/src/ui/microprofile.h index d069dea4..ae09bc7e 100644 --- a/src/ui/microprofile.h +++ b/src/ui/microprofile.h @@ -5,7 +5,7 @@ struct microprofile; struct render_backend; struct window; -struct microprofile *mp_create(struct window *window, struct render_backend *r); +struct microprofile *mp_create(struct window *win, struct render_backend *r); void mp_destroy(struct microprofile *mp); void mp_render(struct microprofile *mp); diff --git a/src/ui/nuklear.c b/src/ui/nuklear.c index 74c5eadc..e25bf598 100644 --- a/src/ui/nuklear.c +++ b/src/ui/nuklear.c @@ -51,6 +51,8 @@ static void nk_mousemove(void *data, int x, int y) { } void nk_render(struct nuklear *nk) { + float height = (float)win_height(nk->win); + /* convert draw list into vertex / element buffers */ static const struct nk_draw_vertex_layout_element vertex_layout[] = { {NK_VERTEX_POSITION, NK_FORMAT_FLOAT, NK_OFFSETOF(struct vertex2, xy)}, @@ -95,8 +97,7 @@ void nk_render(struct nuklear *nk) { surf.texture = (texture_handle_t)cmd->texture.id; surf.scissor_rect[0] = cmd->clip_rect.x; - surf.scissor_rect[1] = - nk->window->height - (cmd->clip_rect.y + cmd->clip_rect.h); + surf.scissor_rect[1] = height - (cmd->clip_rect.y + cmd->clip_rect.h); surf.scissor_rect[2] = cmd->clip_rect.w; surf.scissor_rect[3] = cmd->clip_rect.h; surf.first_vert = offset; @@ -138,21 +139,21 @@ void nk_destroy(struct nuklear *nk) { r_destroy_texture(nk->r, nk->font_texture); - win_remove_listener(nk->window, &nk->listener); + win_remove_listener(nk->win, &nk->listener); free(nk); } -struct nuklear *nk_create(struct window *window, struct render_backend *r) { +struct nuklear *nk_create(struct window *win, struct render_backend *r) { struct nuklear *nk = calloc(1, sizeof(struct nuklear)); - nk->window = window; + nk->win = win; nk->r = r; /* add input event listeners */ nk->listener = (struct window_listener){ nk, NULL, NULL, &nk_keydown, &nk_mousemove, NULL, {0}}; - win_add_listener(nk->window, &nk->listener); + win_add_listener(nk->win, &nk->listener); /* create default font texture */ nk_font_atlas_init_default(&nk->atlas); diff --git a/src/ui/nuklear.h b/src/ui/nuklear.h index 766530bf..9b6c0cfb 100644 --- a/src/ui/nuklear.h +++ b/src/ui/nuklear.h @@ -19,7 +19,7 @@ struct render_backend; struct nuklear { - struct window *window; + struct window *win; struct render_backend *r; struct window_listener listener; @@ -42,7 +42,7 @@ struct nuklear { int shift[2]; }; -struct nuklear *nk_create(struct window *window, struct render_backend *r); +struct nuklear *nk_create(struct window *win, struct render_backend *r); void nk_destroy(struct nuklear *nk); void nk_update_input(struct nuklear *nk); diff --git a/src/ui/window.c b/src/ui/window.c index 12e40455..297bd783 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -9,9 +9,29 @@ #define DEFAULT_WIDTH 640 #define DEFAULT_HEIGHT 480 +#define MAX_WINDOW_LISTENERS 8 +#define MAX_JOYSTICKS 4 + +#define NUM_JOYSTICK_AXES ((K_AXIS25 - K_AXIS0) + 1) +#define NUM_JOYSTICK_KEYS ((K_JOY31 - K_JOY0) + 1) +#define NUM_JOYSTICK_HATS (((K_HAT15 - K_HAT0) + 1) / 4) /* 4 keys per hat */ + #define KEY_UP INT16_MIN #define KEY_DOWN INT16_MAX +struct window { + struct SDL_Window *handle; + + int width; + int height; + int fullscreen; + + struct list listeners; + char status[256]; + struct _SDL_Joystick *joysticks[MAX_JOYSTICKS]; + uint8_t hat_state[MAX_JOYSTICKS][NUM_JOYSTICK_HATS]; +}; + static void win_destroy_joystick(struct window *win, SDL_Joystick *del) { for (int i = 0; i < MAX_JOYSTICKS; i++) { SDL_Joystick **joy = &win->joysticks[i]; @@ -813,6 +833,18 @@ void win_pump_events(struct window *win) { win_pump_sdl(win); } +int win_width(struct window *win) { + return win->width; +} + +int win_height(struct window *win) { + return win->height; +} + +int win_fullscreen(struct window *win) { + return win->fullscreen; +} + void win_set_fullscreen(struct window *win, int fullscreen) { win->fullscreen = fullscreen; diff --git a/src/ui/window.h b/src/ui/window.h index 40204cbf..218ac5c0 100644 --- a/src/ui/window.h +++ b/src/ui/window.h @@ -5,27 +5,9 @@ #include "core/list.h" #include "ui/keycode.h" -struct imgui; -struct microprofile; -struct nuklear; -struct nk_context; -struct render_backend; -struct window; -struct window_listener; - -struct _SDL_Joystick; -struct SDL_Window; - -#define MAX_WINDOW_LISTENERS 8 - #define DEBUG_MENU_HEIGHT 23.0f -#define MAX_JOYSTICKS 4 - -#define NUM_JOYSTICK_AXES ((K_AXIS25 - K_AXIS0) + 1) -#define NUM_JOYSTICK_KEYS ((K_JOY31 - K_JOY0) + 1) -#define NUM_JOYSTICK_HATS (((K_HAT15 - K_HAT0) + 1) / 4) /* 4 keys per hat */ - +struct window; typedef void *glcontext_t; struct window_listener { @@ -39,22 +21,6 @@ struct window_listener { struct list_node it; }; -struct window { - /* public */ - struct SDL_Window *handle; - - /* read only */ - int width; - int height; - int fullscreen; - - /* private state */ - struct list listeners; - char status[256]; - struct _SDL_Joystick *joysticks[MAX_JOYSTICKS]; - uint8_t hat_state[MAX_JOYSTICKS][NUM_JOYSTICK_HATS]; -}; - struct window *win_create(); void win_destroy(struct window *win); @@ -67,6 +33,10 @@ void win_gl_destroy_context(struct window *win, glcontext_t ctx); void win_add_listener(struct window *win, struct window_listener *listener); void win_remove_listener(struct window *win, struct window_listener *listener); +int win_width(struct window *win); +int win_height(struct window *win); + +int win_fullscreen(struct window *win); void win_set_fullscreen(struct window *win, int fullscreen); void win_pump_events(struct window *win); diff --git a/src/video/gl_backend.c b/src/video/gl_backend.c index 31a4a3f5..997aed51 100644 --- a/src/video/gl_backend.c +++ b/src/video/gl_backend.c @@ -655,15 +655,17 @@ void r_end_ortho(struct render_backend *r) { } void r_begin_ortho(struct render_backend *r) { - float ortho[16]; + int width = win_width(r->win); + int height = win_height(r->win); - ortho[0] = 2.0f / (float)r->win->width; + float ortho[16]; + ortho[0] = 2.0f / (float)width; ortho[4] = 0.0f; ortho[8] = 0.0f; ortho[12] = -1.0f; ortho[1] = 0.0f; - ortho[5] = -2.0f / (float)r->win->height; + ortho[5] = -2.0f / (float)height; ortho[9] = 0.0f; ortho[13] = 1.0f; @@ -691,9 +693,12 @@ void r_swap_buffers(struct render_backend *r) { } void r_clear_viewport(struct render_backend *r) { + int width = win_width(r->win); + int height = win_height(r->win); + r_set_depth_mask(r, 1); - glViewport(0, 0, r->win->width, r->win->height); + glViewport(0, 0, width, height); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } @@ -828,6 +833,9 @@ void r_bind_framebuffer(struct render_backend *r, framebuffer_handle_t handle) { framebuffer_handle_t r_create_framebuffer(struct render_backend *r, texture_handle_t *color_component) { + int width = win_width(r->win); + int height = win_height(r->win); + /* find next open framebuffer handle */ int entry; for (entry = 0; entry < MAX_FRAMEBUFFERS; entry++) { @@ -843,8 +851,8 @@ framebuffer_handle_t r_create_framebuffer(struct render_backend *r, /* create color component */ glGenTextures(1, &fb->color_component); glBindTexture(GL_TEXTURE_2D, fb->color_component); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, r->win->width, r->win->height, 0, - GL_RGBA, GL_UNSIGNED_BYTE, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, + GL_UNSIGNED_BYTE, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glBindTexture(GL_TEXTURE_2D, 0); @@ -852,8 +860,7 @@ framebuffer_handle_t r_create_framebuffer(struct render_backend *r, /* create depth component */ glGenRenderbuffers(1, &fb->depth_component); glBindRenderbuffer(GL_RENDERBUFFER, fb->depth_component); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, r->win->width, - r->win->height); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height); glBindRenderbuffer(GL_RENDERBUFFER, 0); /* create fbo */