Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a new Settings UI to facilitate the implementation of new settings #79

Merged
merged 1 commit into from
Mar 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 42 additions & 32 deletions include/app/app.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,41 +30,41 @@
struct ImGuiIO;

enum texture_filter_kind {
TEXTURE_FILTER_MIN = 0,

TEXTURE_FILTER_NEAREST = 0,
TEXTURE_FILTER_LINEAR = 1,

TEXTURE_FILTER_LEN,
TEXTURE_FILTER_MIN = 0,
TEXTURE_FILTER_MAX = 1,
};

enum pixel_color_effect_kind {
PIXEL_COLOR_EFFECT_MIN = 0,

PIXEL_COLOR_EFFECT_NONE = 0,
PIXEL_COLOR_EFFECT_COLOR_CORRECTION = 1,
PIXEL_COLOR_EFFECT_GREY_SCALE = 2,
enum pixel_color_filter_kind {
PIXEL_COLOR_FILTER_NONE = 0,
PIXEL_COLOR_FILTER_COLOR_CORRECTION = 1,
PIXEL_COLOR_FILTER_GREY_SCALE = 2,

PIXEL_COLOR_EFFECT_MAX = 2,
PIXEL_COLOR_FILTER_LEN,
PIXEL_COLOR_FILTER_MIN = 0,
PIXEL_COLOR_FILTER_MAX = 2,
};

enum pixel_scaler_effect_kind {
PIXEL_SCALER_EFFECT_MIN = 0,
enum pixel_scaling_filter_kind {
PIXEL_SCALING_FILTER_NONE = 0,
PIXEL_SCALING_FILTER_LCD_GRID = 1,
PIXEL_SCALING_FILTER_LCD_GRID_WITH_RGB_STRIPES = 2,

PIXEL_SCALER_EFFECT_NONE = 0,
PIXEL_SCALER_EFFECT_LCD_GRID = 1,
PIXEL_SCALER_EFFECT_LCD_GRID_WITH_RGB_STRIPES = 2,

PIXEL_SCALER_EFFECT_MAX = 2,
PIXEL_SCALING_FILTER_LEN,
PIXEL_SCALING_FILTER_MIN = 0,
PIXEL_SCALING_FILTER_MAX = 2,
};

enum aspect_ratio {
ASPECT_RATIO_MIN = 0,

ASPECT_RATIO_RESIZE = 0,
ASPECT_RATIO_BORDERS = 1,
ASPECT_RATIO_STRETCH = 2,

ASPECT_RATIO_LEN,
ASPECT_RATIO_MIN = 0,
ASPECT_RATIO_MAX = 2,
};

Expand Down Expand Up @@ -113,6 +113,15 @@ enum ui_notification_kind {
UI_NOTIFICATION_ERROR,
};

enum menu_kind {
MENU_EMULATION,
MENU_VIDEO,
MENU_AUDIO,
MENU_BINDINGS,

MENU_MAX,
};

struct ui_notification {
enum ui_notification_kind kind;
char *msg;
Expand Down Expand Up @@ -201,7 +210,7 @@ struct app {

GLuint game_texture;
GLuint pixel_color_texture;
GLuint pixel_scaler_texture;
GLuint pixel_scaling_texture;
GLuint fbo;
GLuint vao;
GLuint vbo;
Expand All @@ -212,11 +221,9 @@ struct app {
GLuint program_lcd_grid_with_rgb_stripes;

GLuint pixel_color_program;
bool use_pixel_color_program;

GLuint pixel_scaler_program;
size_t pixel_scaler_size;
bool use_pixel_scaler_program;
GLuint pixel_scaling_program;
size_t pixel_scaling_size;
} gfx;

struct {
Expand All @@ -240,8 +247,8 @@ struct app {
enum aspect_ratio aspect_ratio;
bool vsync;
enum texture_filter_kind texture_filter;
enum pixel_color_effect_kind pixel_color_effect;
enum pixel_scaler_effect_kind pixel_scaler_effect;
enum pixel_color_filter_kind pixel_color_filter;
enum pixel_scaling_filter_kind pixel_scaling_filter;
} video;

struct {
Expand Down Expand Up @@ -314,11 +321,14 @@ struct app {

struct {
bool open;
bool visible;

SDL_Keycode *keyboard_target;
SDL_GameControllerButton *controller_target;
} keybindings_editor;
uint32_t menu;

struct {
SDL_Keycode *keyboard_target;
SDL_GameControllerButton *controller_target;
} keybindings_editor;
} settings;

struct ui_notification *notifications;
} ui;
Expand Down Expand Up @@ -388,16 +398,16 @@ extern char const *SHADER_VERTEX_COMMON;
/* app/windows/game.c */
void app_win_game(struct app *app);

/* app/windows/keybinds.c */
void app_win_keybinds_editor(struct app *app);

/* app/windows/menubar.c */
void app_win_menubar(struct app *app);

/* app/windows/notif.c */
void app_new_notification(struct app *app, enum ui_notification_kind, char const *msg, ...);
void app_win_notifications(struct app *app);

/* app/windows/settings.c */
void app_win_settings(struct app *app);

/* args.c */
void app_args_parse(struct app *app, int argc, char * const argv[]);

Expand Down
1 change: 0 additions & 1 deletion include/gba/memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,6 @@ enum backup_storage_types {
BACKUP_LEN = BACKUP_MAX + 1,
};


static char const * const backup_storage_names[] = {
"None",
"EEPROM 4k",
Expand Down
20 changes: 10 additions & 10 deletions source/app/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,14 +120,14 @@ app_config_load(
app->video.texture_filter = max(TEXTURE_FILTER_MIN, min(app->video.texture_filter, TEXTURE_FILTER_MAX));
}

if (mjson_get_number(data, data_len, "$.video.pixel_color_effect", &d)) {
app->video.pixel_color_effect = (int)d;
app->video.pixel_color_effect = max(PIXEL_COLOR_EFFECT_MIN, min(app->video.pixel_color_effect, PIXEL_COLOR_EFFECT_MAX));
if (mjson_get_number(data, data_len, "$.video.pixel_color_filter", &d)) {
app->video.pixel_color_filter = (int)d;
app->video.pixel_color_filter = max(PIXEL_COLOR_FILTER_MIN, min(app->video.pixel_color_filter, PIXEL_COLOR_FILTER_MAX));
}

if (mjson_get_number(data, data_len, "$.video.pixel_scaler_effect", &d)) {
app->video.pixel_scaler_effect = (int)d;
app->video.pixel_scaler_effect = max(PIXEL_SCALER_EFFECT_MIN, min(app->video.pixel_scaler_effect, PIXEL_SCALER_EFFECT_MAX));
if (mjson_get_number(data, data_len, "$.video.pixel_scaling_filter", &d)) {
app->video.pixel_scaling_filter = (int)d;
app->video.pixel_scaling_filter = max(PIXEL_SCALING_FILTER_MIN, min(app->video.pixel_scaling_filter, PIXEL_SCALING_FILTER_MAX));
}
}

Expand Down Expand Up @@ -236,8 +236,8 @@ app_config_save(
"aspect_ratio": %d,
"vsync": %B,
"texture_filter": %d,
"pixel_color_effect": %d,
"pixel_scaler_effect": %d
"pixel_color_filter": %d,
"pixel_scaling_filter": %d
},

// Audio
Expand All @@ -263,8 +263,8 @@ app_config_save(
(int)app->video.aspect_ratio,
(int)app->video.vsync,
(int)app->video.texture_filter,
(int)app->video.pixel_color_effect,
(int)app->video.pixel_scaler_effect,
(int)app->video.pixel_color_filter,
(int)app->video.pixel_scaling_filter,
(int)app->audio.mute,
app->audio.level
);
Expand Down
3 changes: 2 additions & 1 deletion source/app/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ main(
app.emulation.rtc.autodetect = true;
app.emulation.rtc.enabled = true;
app.file.bios_path = strdup("./bios.bin");
app.video.pixel_color_effect = PIXEL_COLOR_EFFECT_COLOR_CORRECTION;
app.video.pixel_color_filter = PIXEL_COLOR_FILTER_COLOR_CORRECTION;
app.video.pixel_scaling_filter = PIXEL_SCALING_FILTER_LCD_GRID;
app.video.vsync = false;
app.video.display_size = 3;
app.video.aspect_ratio = ASPECT_RATIO_RESIZE;
Expand Down
2 changes: 1 addition & 1 deletion source/app/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,9 @@ libapp = static_library(
'shaders/frag-lcd-grid.c',
'shaders/vertex-common.c',
'windows/game.c',
'windows/keybinds.c',
'windows/menubar.c',
'windows/notif.c',
'windows/settings.c',
'args.c',
'config.c',
'emulator.c',
Expand Down
40 changes: 22 additions & 18 deletions source/app/sdl/event.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,23 +122,25 @@ app_sdl_handle_events(
break;
}

/* Handle the special case where we are creating new keybindings. */
if (app->ui.keybindings_editor.visible) {
/*
** Ignore keys if the settings are open except the special case where we are creating new bindings.
*/
if (app->ui.settings.open) {
if (event.type == SDL_KEYDOWN) {
// The `Escape` key is used to clear a bind.
if (event.key.keysym.sym == SDLK_ESCAPE) {
if (app->ui.keybindings_editor.keyboard_target) {
*app->ui.keybindings_editor.keyboard_target = SDLK_UNKNOWN;
app->ui.keybindings_editor.keyboard_target = NULL;
if (app->ui.settings.keybindings_editor.keyboard_target) {
*app->ui.settings.keybindings_editor.keyboard_target = SDLK_UNKNOWN;
app->ui.settings.keybindings_editor.keyboard_target = NULL;
}
if (app->ui.keybindings_editor.controller_target) {
*app->ui.keybindings_editor.controller_target = SDL_CONTROLLER_BUTTON_INVALID;
app->ui.keybindings_editor.controller_target = NULL;
if (app->ui.settings.keybindings_editor.controller_target) {
*app->ui.settings.keybindings_editor.controller_target = SDL_CONTROLLER_BUTTON_INVALID;
app->ui.settings.keybindings_editor.controller_target = NULL;
}
} else if (app->ui.keybindings_editor.keyboard_target) {
} else if (app->ui.settings.keybindings_editor.keyboard_target) {
app_bindings_keyboard_clear(app, event.key.keysym.sym);
*app->ui.keybindings_editor.keyboard_target = event.key.keysym.sym;
app->ui.keybindings_editor.keyboard_target = NULL;
*app->ui.settings.keybindings_editor.keyboard_target = event.key.keysym.sym;
app->ui.settings.keybindings_editor.keyboard_target = NULL;
}
}
break ;
Expand All @@ -162,12 +164,14 @@ app_sdl_handle_events(
case SDL_CONTROLLERBUTTONDOWN: {
size_t i;

/* Handle the special case where we are creating new keybindings. */
if (app->ui.keybindings_editor.visible) {
if (event.type == SDL_CONTROLLERBUTTONDOWN && app->ui.keybindings_editor.controller_target) {
/*
** Ignore buttons if the settings are open except the special case where we are creating new bindings.
*/
if (app->ui.settings.open) {
if (event.type == SDL_CONTROLLERBUTTONDOWN && app->ui.settings.keybindings_editor.controller_target) {
app_bindings_controller_clear(app, event.cbutton.button);
*app->ui.keybindings_editor.controller_target = event.cbutton.button;
app->ui.keybindings_editor.controller_target = NULL;
*app->ui.settings.keybindings_editor.controller_target = event.cbutton.button;
app->ui.settings.keybindings_editor.controller_target = NULL;
}
break ;
}
Expand All @@ -189,8 +193,8 @@ app_sdl_handle_events(
bool state_a;
bool state_b;

/* Disable the joysticks if the keybindings editor is visible */
if (app->ui.keybindings_editor.visible) {
/* Disable the joysticks if the settings are visible */
if (app->ui.settings.open) {
break;
}

Expand Down
46 changes: 21 additions & 25 deletions source/app/sdl/video.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ app_sdl_video_init(
/* Create the OpenGL objects required to build the pipeline */
glGenTextures(1, &app->gfx.game_texture);
glGenTextures(1, &app->gfx.pixel_color_texture);
glGenTextures(1, &app->gfx.pixel_scaler_texture);
glGenTextures(1, &app->gfx.pixel_scaling_texture);
glGenFramebuffers(1, &app->gfx.fbo);
glGenVertexArrays(1, &app->gfx.vao);
glGenBuffers(1, &app->gfx.vbo);
Expand Down Expand Up @@ -220,20 +220,17 @@ app_sdl_video_rebuild_pipeline(
NULL
);

switch (app->video.pixel_color_effect) {
case PIXEL_COLOR_EFFECT_COLOR_CORRECTION: {
switch (app->video.pixel_color_filter) {
case PIXEL_COLOR_FILTER_COLOR_CORRECTION: {
app->gfx.pixel_color_program = app->gfx.program_color_correction;
app->gfx.use_pixel_color_program = true;
break;
};
case PIXEL_COLOR_EFFECT_GREY_SCALE: {
case PIXEL_COLOR_FILTER_GREY_SCALE: {
app->gfx.pixel_color_program = app->gfx.program_grey_scale;
app->gfx.use_pixel_color_program = true;
break;
};
default: {
app->gfx.pixel_color_program = 0;
app->gfx.use_pixel_color_program = false;
break;
};
}
Expand All @@ -256,39 +253,36 @@ app_sdl_video_rebuild_pipeline(
NULL
);

switch (app->video.pixel_scaler_effect) {
case PIXEL_SCALER_EFFECT_LCD_GRID: {
app->gfx.pixel_scaler_program = app->gfx.program_lcd_grid;
app->gfx.pixel_scaler_size = 3;
app->gfx.use_pixel_scaler_program = true;
switch (app->video.pixel_scaling_filter) {
case PIXEL_SCALING_FILTER_LCD_GRID: {
app->gfx.pixel_scaling_program = app->gfx.program_lcd_grid;
app->gfx.pixel_scaling_size = 3;
break;
};
case PIXEL_SCALER_EFFECT_LCD_GRID_WITH_RGB_STRIPES: {
app->gfx.pixel_scaler_program = app->gfx.program_lcd_grid_with_rgb_stripes;
app->gfx.pixel_scaler_size = 3;
app->gfx.use_pixel_scaler_program = true;
case PIXEL_SCALING_FILTER_LCD_GRID_WITH_RGB_STRIPES: {
app->gfx.pixel_scaling_program = app->gfx.program_lcd_grid_with_rgb_stripes;
app->gfx.pixel_scaling_size = 3;
break;
};
default: {
app->gfx.pixel_scaler_program = 0;
app->gfx.pixel_scaler_size = 1;
app->gfx.use_pixel_scaler_program = false;
app->gfx.pixel_scaling_program = 0;
app->gfx.pixel_scaling_size = 1;
break;
};
}

// Setup the pixel scaler texture
// Setup the pixel scaling texture
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, app->gfx.pixel_scaler_texture);
glBindTexture(GL_TEXTURE_2D, app->gfx.pixel_scaling_texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, texture_filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, texture_filter);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGBA,
GBA_SCREEN_WIDTH * app->gfx.pixel_scaler_size,
GBA_SCREEN_HEIGHT * app->gfx.pixel_scaler_size,
GBA_SCREEN_WIDTH * app->gfx.pixel_scaling_size,
GBA_SCREEN_HEIGHT * app->gfx.pixel_scaling_size,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
Expand Down Expand Up @@ -434,7 +428,7 @@ app_sdl_video_cleanup(
glDeleteFramebuffers(1, &app->gfx.fbo);
glDeleteTextures(1, &app->gfx.game_texture);
glDeleteTextures(1, &app->gfx.pixel_color_texture);
glDeleteTextures(1, &app->gfx.pixel_scaler_texture);
glDeleteTextures(1, &app->gfx.pixel_scaling_texture);
SDL_GL_DeleteContext(app->gfx.gl_context);

// Close the Wingowd
Expand All @@ -458,7 +452,9 @@ app_sdl_video_render_frame(
app_win_game(app);
}

app_win_keybinds_editor(app);
if (app->ui.settings.open) {
app_win_settings(app);
}

app_win_notifications(app);

Expand Down
Loading