Config callback system
No more hacks in options menu code to update stuff when a setting changes
This commit is contained in:
parent
32f7edd24e
commit
802cacb799
10 changed files with 218 additions and 106 deletions
90
src/config.c
90
src/config.c
|
@ -17,7 +17,7 @@
|
|||
static bool config_initialized = false;
|
||||
|
||||
CONFIGDEFS_EXPORT ConfigEntry configdefs[] = {
|
||||
#define CONFIGDEF(type,entryname,default,ufield) {type, entryname, {.ufield = default}},
|
||||
#define CONFIGDEF(type,entryname,default,ufield) {type, entryname, {.ufield = default}, NULL},
|
||||
#define CONFIGDEF_KEYBINDING(id,entryname,default) CONFIGDEF(CONFIG_TYPE_KEYBINDING, entryname, default, i)
|
||||
#define CONFIGDEF_GPKEYBINDING(id,entryname,default) CONFIGDEF(CONFIG_TYPE_INT, entryname, default, i)
|
||||
#define CONFIGDEF_INT(id,entryname,default) CONFIGDEF(CONFIG_TYPE_INT, entryname, default, i)
|
||||
|
@ -91,7 +91,7 @@ ConfigEntry* config_get(ConfigIndex idx) {
|
|||
}
|
||||
#endif
|
||||
|
||||
ConfigEntry* config_find_entry(char *name) {
|
||||
static ConfigEntry* config_find_entry(char *name) {
|
||||
ConfigEntry *e = configdefs;
|
||||
do if(!strcmp(e->name, name)) return e; while((++e)->name);
|
||||
return NULL;
|
||||
|
@ -139,7 +139,89 @@ KeyIndex config_key_from_gamepad_button(int btn) {
|
|||
return config_key_from_gamepad_key(config_gamepad_key_from_gamepad_button(btn));
|
||||
}
|
||||
|
||||
FILE* config_open(char *filename, char *mode) {
|
||||
static void config_set_val(ConfigIndex idx, ConfigValue v) {
|
||||
ConfigEntry *e = config_get(idx);
|
||||
ConfigCallback callback = e->callback;
|
||||
bool difference;
|
||||
|
||||
switch(e->type) {
|
||||
case CONFIG_TYPE_INT:
|
||||
case CONFIG_TYPE_KEYBINDING:
|
||||
difference = e->val.i != v.i;
|
||||
break;
|
||||
|
||||
case CONFIG_TYPE_FLOAT:
|
||||
difference = e->val.f != v.f;
|
||||
break;
|
||||
|
||||
case CONFIG_TYPE_STRING:
|
||||
difference = strcmp(e->val.s, v.s);
|
||||
break;
|
||||
}
|
||||
|
||||
if(!difference) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(callback) {
|
||||
e->callback = NULL;
|
||||
callback(idx, v);
|
||||
e->callback = callback;
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
#define PRINTVAL(t) printf("config_set_val(): %s:" #t " = %" #t "\n", e->name, e->val.t);
|
||||
#else
|
||||
#define PRINTVAL(t)
|
||||
#endif
|
||||
|
||||
switch(e->type) {
|
||||
case CONFIG_TYPE_INT:
|
||||
case CONFIG_TYPE_KEYBINDING:
|
||||
e->val.i = v.i;
|
||||
PRINTVAL(i)
|
||||
break;
|
||||
|
||||
case CONFIG_TYPE_FLOAT:
|
||||
e->val.f = v.f;
|
||||
PRINTVAL(f)
|
||||
break;
|
||||
|
||||
case CONFIG_TYPE_STRING:
|
||||
stralloc(&e->val.s, v.s);
|
||||
PRINTVAL(s)
|
||||
break;
|
||||
}
|
||||
|
||||
#undef PRINTVAL
|
||||
}
|
||||
|
||||
int config_set_int(ConfigIndex idx, int val) {
|
||||
ConfigValue v = {.i = val};
|
||||
config_set_val(idx, v);
|
||||
return config_get_int(idx);
|
||||
}
|
||||
|
||||
double config_set_float(ConfigIndex idx, double val) {
|
||||
ConfigValue v = {.f = val};
|
||||
config_set_val(idx, v);
|
||||
return config_get_float(idx);
|
||||
}
|
||||
|
||||
char* config_set_str(ConfigIndex idx, const char *val) {
|
||||
ConfigValue v = {.s = (char*)val};
|
||||
config_set_val(idx, v);
|
||||
return config_get_str(idx);
|
||||
}
|
||||
|
||||
void config_set_callback(ConfigIndex idx, ConfigCallback callback) {
|
||||
ConfigEntry *e = config_get(idx);
|
||||
assert(e->callback == NULL);
|
||||
e->callback = callback;
|
||||
}
|
||||
|
||||
static FILE* config_open(char *filename, char *mode) {
|
||||
char *buf;
|
||||
FILE *out;
|
||||
|
||||
|
@ -195,7 +277,7 @@ void config_save(char *filename) {
|
|||
#define INTOF(s) ((int)strtol(s, NULL, 10))
|
||||
#define FLOATOF(s) ((float)strtod(s, NULL))
|
||||
|
||||
void config_set(char *key, char *val) {
|
||||
static void config_set(char *key, char *val) {
|
||||
ConfigEntry *e = config_find_entry(key);
|
||||
|
||||
if(!e) {
|
||||
|
|
23
src/config.h
23
src/config.h
|
@ -10,6 +10,7 @@
|
|||
#define CONFIG_H
|
||||
|
||||
#include <SDL_keycode.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/*
|
||||
Define these macros, then use CONFIGDEFS to expand them all for all config entries, or KEYDEFS for just keybindings.
|
||||
|
@ -148,14 +149,19 @@ typedef enum ConfigEntryType {
|
|||
CONFIG_TYPE_FLOAT
|
||||
} ConfigEntryType;
|
||||
|
||||
typedef union ConfigValue {
|
||||
int i;
|
||||
double f;
|
||||
char *s;
|
||||
} ConfigValue;
|
||||
|
||||
typedef void (*ConfigCallback)(ConfigIndex, ConfigValue);
|
||||
|
||||
typedef struct ConfigEntry {
|
||||
ConfigEntryType type;
|
||||
char *name;
|
||||
union {
|
||||
int i;
|
||||
double f;
|
||||
char *s;
|
||||
} val;
|
||||
ConfigValue val;
|
||||
ConfigCallback callback;
|
||||
} ConfigEntry;
|
||||
|
||||
#define CONFIG_LOAD_BUFSIZE 256
|
||||
|
@ -171,6 +177,7 @@ void config_init(void);
|
|||
void config_uninit(void);
|
||||
void config_load(char *filename);
|
||||
void config_save(char *filename);
|
||||
void config_set_callback(ConfigIndex idx, ConfigCallback callback);
|
||||
|
||||
#ifndef DEBUG
|
||||
#define CONFIG_RAWACCESS
|
||||
|
@ -189,8 +196,8 @@ void config_save(char *filename);
|
|||
#define config_get_float(idx) (config_get(idx)->val.f)
|
||||
#define config_get_str(idx) (config_get(idx)->val.s)
|
||||
|
||||
#define config_set_int(idx,val) (config_get_int(idx) = val)
|
||||
#define config_set_float(idx,val) (config_get_float(idx) = val)
|
||||
#define config_set_str(idx,val) stralloc(&config_get_str(idx), val)
|
||||
int config_set_int(ConfigIndex idx, int val);
|
||||
double config_set_float(ConfigIndex idx, double val);
|
||||
char* config_set_str(ConfigIndex idx, const char *val);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -52,7 +52,8 @@ void handle_events(EventHandler handler, EventFlags flags, void *arg) {
|
|||
}
|
||||
|
||||
if((scan == SDL_SCANCODE_RETURN && (mod & KMOD_ALT)) || scan == config_get_int(CONFIG_KEY_FULLSCREEN)) {
|
||||
video_toggle_fullscreen();
|
||||
// video_toggle_fullscreen();
|
||||
config_set_int(CONFIG_FULLSCREEN, !config_get_int(CONFIG_FULLSCREEN));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -115,14 +115,6 @@ OptionBinding* bind_scale(int cfgentry, float smin, float smax, float step) {
|
|||
return bind;
|
||||
}
|
||||
|
||||
// BT_ScaleCallback: float values clamped to a range with callback
|
||||
OptionBinding* bind_scale_call(int cfgentry, float smin, float smax, float step, FloatSetter callback) {
|
||||
OptionBinding *bind = bind_scale(cfgentry, smin, smax, step);
|
||||
bind->type = BT_ScaleCallback;
|
||||
bind->callback = callback;
|
||||
return bind;
|
||||
}
|
||||
|
||||
// Returns a pointer to the first found binding that blocks input. If none found, returns NULL.
|
||||
OptionBinding* bind_getinputblocking(MenuData *m) {
|
||||
int i;
|
||||
|
@ -230,63 +222,6 @@ int bind_common_onoffset_inverted(void *b, int v) {
|
|||
|
||||
// --- Binding callbacks for individual options --- //
|
||||
|
||||
int bind_fullscreen_set(void *b, int v) {
|
||||
video_toggle_fullscreen();
|
||||
return bind_common_onoffset(b, v);
|
||||
}
|
||||
|
||||
int bind_noaudio_set(void *b, int v) {
|
||||
int i = bind_common_onoffset_inverted(b, v);
|
||||
|
||||
if(v)
|
||||
{
|
||||
shutdown_sfx();
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!init_sfx(NULL, NULL)) return 1;
|
||||
|
||||
load_resources();
|
||||
set_sfx_volume(config_get_float(CONFIG_SFX_VOLUME));
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
int bind_nomusic_set(void *b, int v) {
|
||||
int i = bind_common_onoffset_inverted(b, v);
|
||||
|
||||
if(v)
|
||||
{
|
||||
shutdown_bgm();
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!init_bgm(NULL, NULL)) return 1;
|
||||
|
||||
load_resources();
|
||||
set_bgm_volume(config_get_float(CONFIG_BGM_VOLUME));
|
||||
start_bgm("bgm_menu");
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
int bind_noshader_set(void *b, int v) {
|
||||
int i = bind_common_onoffset_inverted(b, v);
|
||||
|
||||
if(!v)
|
||||
load_resources();
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
int bind_vsync_set(void *b, int v) {
|
||||
int i = bind_common_onoffset(b, v);
|
||||
video_update_vsync();
|
||||
return i;
|
||||
}
|
||||
|
||||
bool bind_stagebg_fpslimit_dependence(void) {
|
||||
return config_get_int(CONFIG_NO_STAGEBG) == 2;
|
||||
}
|
||||
|
@ -358,17 +293,17 @@ void options_sub_video(MenuData *parent, void *arg) {
|
|||
);
|
||||
|
||||
add_menu_entry(m, "Fullscreen", do_nothing,
|
||||
b = bind_option(CONFIG_FULLSCREEN, bind_common_onoffget, bind_fullscreen_set)
|
||||
b = bind_option(CONFIG_FULLSCREEN, bind_common_onoffget, bind_common_onoffset)
|
||||
); bind_onoff(b);
|
||||
|
||||
add_menu_entry(m, "Vertical synchronization", do_nothing,
|
||||
b = bind_option(CONFIG_VSYNC, bind_common_onoffget, bind_vsync_set)
|
||||
b = bind_option(CONFIG_VSYNC, bind_common_onoffget, bind_common_onoffset)
|
||||
); bind_onoff(b);
|
||||
|
||||
add_menu_separator(m);
|
||||
|
||||
add_menu_entry(m, "Shaders", do_nothing,
|
||||
b = bind_option(CONFIG_NO_SHADER, bind_common_onoffget_inverted, bind_noshader_set)
|
||||
b = bind_option(CONFIG_NO_SHADER, bind_common_onoffget_inverted, bind_common_onoffset_inverted)
|
||||
); bind_onoff(b);
|
||||
|
||||
add_menu_entry(m, "Stage background", do_nothing,
|
||||
|
@ -605,8 +540,7 @@ void create_options_menu(MenuData *m) {
|
|||
add_menu_separator(m);
|
||||
|
||||
add_menu_entry(m, "Save replays", do_nothing,
|
||||
b = bind_option(CONFIG_SAVE_RPY, bind_saverpy_get,
|
||||
bind_saverpy_set)
|
||||
b = bind_option(CONFIG_SAVE_RPY, bind_saverpy_get, bind_saverpy_set)
|
||||
); bind_addvalue(b, "on");
|
||||
bind_addvalue(b, "off");
|
||||
bind_addvalue(b, "ask");
|
||||
|
@ -614,21 +548,21 @@ void create_options_menu(MenuData *m) {
|
|||
add_menu_separator(m);
|
||||
|
||||
add_menu_entry(m, "Sound effects", do_nothing,
|
||||
b = bind_option(CONFIG_NO_AUDIO, bind_common_onoffget_inverted,
|
||||
bind_noaudio_set)
|
||||
b = bind_option(CONFIG_NO_AUDIO, bind_common_onoffget_inverted,
|
||||
bind_common_onoffset_inverted)
|
||||
); bind_onoff(b);
|
||||
|
||||
add_menu_entry(m, "SFX volume level", do_nothing,
|
||||
bind_scale_call(CONFIG_SFX_VOLUME, 0, 1, 0.1, set_sfx_volume)
|
||||
bind_scale(CONFIG_SFX_VOLUME, 0, 1, 0.1)
|
||||
);
|
||||
|
||||
add_menu_entry(m, "Background music", do_nothing,
|
||||
b = bind_option(CONFIG_NO_MUSIC, bind_common_onoffget_inverted,
|
||||
bind_nomusic_set)
|
||||
b = bind_option(CONFIG_NO_MUSIC, bind_common_onoffget_inverted,
|
||||
bind_common_onoffset_inverted)
|
||||
); bind_onoff(b);
|
||||
|
||||
add_menu_entry(m, "Music volume level", do_nothing,
|
||||
bind_scale_call(CONFIG_BGM_VOLUME, 0, 1, 0.1, set_bgm_volume)
|
||||
bind_scale(CONFIG_BGM_VOLUME, 0, 1, 0.1)
|
||||
);
|
||||
|
||||
add_menu_separator(m);
|
||||
|
@ -780,8 +714,7 @@ void draw_options_menu(MenuData *menu) {
|
|||
break;
|
||||
}
|
||||
|
||||
case BT_Scale:
|
||||
case BT_ScaleCallback: {
|
||||
case BT_Scale: {
|
||||
int w = 200;
|
||||
int h = 5;
|
||||
int cw = 5;
|
||||
|
@ -930,10 +863,8 @@ static void options_input_event(EventType type, int state, void *arg) {
|
|||
if(bind) {
|
||||
if(bind->type == BT_IntValue || bind->type == BT_Resolution)
|
||||
bind_setprev(bind);
|
||||
else if((bind->type == BT_Scale) || (bind->type == BT_ScaleCallback)) {
|
||||
else if(bind->type == BT_Scale) {
|
||||
config_set_float(bind->configentry, clamp(config_get_float(bind->configentry) - bind->scale_step, bind->scale_min, bind->scale_max));
|
||||
if (bind->type == BT_ScaleCallback)
|
||||
bind->callback(config_get_float(bind->configentry));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -943,10 +874,8 @@ static void options_input_event(EventType type, int state, void *arg) {
|
|||
if(bind) {
|
||||
if(bind->type == BT_IntValue || bind->type == BT_Resolution)
|
||||
bind_setnext(bind);
|
||||
else if((bind->type == BT_Scale) || (bind->type == BT_ScaleCallback)) {
|
||||
else if(bind->type == BT_Scale) {
|
||||
config_set_float(bind->configentry, clamp(config_get_float(bind->configentry) + bind->scale_step, bind->scale_min, bind->scale_max));
|
||||
if (bind->type == BT_ScaleCallback)
|
||||
bind->callback(config_get_float(bind->configentry));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -22,15 +22,12 @@ typedef int (*BindingGetter)(void*);
|
|||
typedef int (*BindingSetter)(void*, int);
|
||||
typedef bool (*BindingDependence)(void);
|
||||
|
||||
typedef void (*FloatSetter)(float);
|
||||
|
||||
typedef enum BindingType {
|
||||
BT_IntValue,
|
||||
BT_KeyBinding,
|
||||
BT_StrValue,
|
||||
BT_Resolution,
|
||||
BT_Scale,
|
||||
BT_ScaleCallback,
|
||||
BT_GamepadKeyBinding
|
||||
} BindingType;
|
||||
|
||||
|
@ -45,7 +42,6 @@ typedef struct OptionBinding {
|
|||
float scale_step;
|
||||
BindingGetter getter;
|
||||
BindingSetter setter;
|
||||
FloatSetter callback;
|
||||
BindingDependence dependence;
|
||||
int selected;
|
||||
int configentry;
|
||||
|
|
|
@ -19,7 +19,14 @@
|
|||
int alut_loaded = 0;
|
||||
|
||||
int warn_alut_error(const char *when) {
|
||||
ALenum error = alutGetError();
|
||||
ALenum error = alGetError();
|
||||
|
||||
if(error != AL_NO_ERROR) {
|
||||
warnx("AL error %d while %s", error, when);
|
||||
return 1;
|
||||
}
|
||||
|
||||
error = alutGetError();
|
||||
if (error == ALUT_ERROR_NO_ERROR) return 0;
|
||||
warnx("ALUT error %d while %s: %s", error, when, alutGetErrorString(error));
|
||||
return 1;
|
||||
|
@ -56,8 +63,37 @@ int init_alut_if_needed(int *argc, char *argv[]) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
static void sfx_cfg_noaudio_callback(ConfigIndex idx, ConfigValue v) {
|
||||
config_set_int(idx, v.i);
|
||||
|
||||
if(v.i) {
|
||||
shutdown_sfx();
|
||||
return;
|
||||
}
|
||||
|
||||
if(!init_sfx(NULL, NULL)) {
|
||||
config_set_int(idx, true);
|
||||
return;
|
||||
}
|
||||
|
||||
load_resources();
|
||||
set_sfx_volume(config_get_float(CONFIG_SFX_VOLUME));
|
||||
}
|
||||
|
||||
static void sfx_cfg_volume_callback(ConfigIndex idx, ConfigValue v) {
|
||||
set_sfx_volume(config_set_float(idx, v.f));
|
||||
}
|
||||
|
||||
int init_sfx(int *argc, char *argv[])
|
||||
{
|
||||
static bool callbacks_set_up = false;
|
||||
|
||||
if(!callbacks_set_up) {
|
||||
config_set_callback(CONFIG_NO_AUDIO, sfx_cfg_noaudio_callback);
|
||||
config_set_callback(CONFIG_SFX_VOLUME, sfx_cfg_volume_callback);
|
||||
callbacks_set_up = true;
|
||||
}
|
||||
|
||||
if (config_get_int(CONFIG_NO_AUDIO)) return 1;
|
||||
if (!init_alut_if_needed(argc, argv)) return 0;
|
||||
|
||||
|
@ -81,7 +117,6 @@ void shutdown_sfx(void)
|
|||
delete_sounds();
|
||||
resources.state &= ~RS_SfxLoaded;
|
||||
}
|
||||
config_set_int(CONFIG_NO_AUDIO, 1);
|
||||
unload_alut_if_needed();
|
||||
}
|
||||
|
||||
|
|
|
@ -21,8 +21,38 @@ struct current_bgm_t current_bgm = { .name = NULL };
|
|||
|
||||
char *saved_bgm;
|
||||
|
||||
static void bgm_cfg_nomusic_callback(ConfigIndex idx, ConfigValue v) {
|
||||
config_set_int(idx, v.i);
|
||||
|
||||
if(v.i) {
|
||||
shutdown_bgm();
|
||||
return;
|
||||
}
|
||||
|
||||
if(!init_bgm(NULL, NULL)) {
|
||||
config_set_int(idx, true);
|
||||
return;
|
||||
}
|
||||
|
||||
load_resources();
|
||||
set_bgm_volume(config_get_float(CONFIG_BGM_VOLUME));
|
||||
start_bgm("bgm_menu"); // FIXME: start BGM that's supposed to be playing in the current context
|
||||
}
|
||||
|
||||
static void bgm_cfg_volume_callback(ConfigIndex idx, ConfigValue v) {
|
||||
set_bgm_volume(config_set_float(idx, v.f));
|
||||
}
|
||||
|
||||
int init_bgm(int *argc, char *argv[])
|
||||
{
|
||||
static bool callbacks_set_up = false;
|
||||
|
||||
if(!callbacks_set_up) {
|
||||
config_set_callback(CONFIG_NO_MUSIC, bgm_cfg_nomusic_callback);
|
||||
config_set_callback(CONFIG_BGM_VOLUME, bgm_cfg_volume_callback);
|
||||
callbacks_set_up = true;
|
||||
}
|
||||
|
||||
if (config_get_int(CONFIG_NO_MUSIC)) return 1;
|
||||
if (!init_alut_if_needed(argc, argv)) return 0;
|
||||
|
||||
|
@ -47,7 +77,6 @@ void shutdown_bgm(void)
|
|||
delete_music();
|
||||
resources.state &= ~RS_BgmLoaded;
|
||||
}
|
||||
config_set_int(CONFIG_NO_MUSIC, 1);
|
||||
unload_alut_if_needed();
|
||||
}
|
||||
|
||||
|
|
|
@ -63,7 +63,22 @@ void recurse_dir(char *path) {
|
|||
closedir(dir);
|
||||
}
|
||||
|
||||
static void resources_cfg_noshader_callback(ConfigIndex idx, ConfigValue v) {
|
||||
config_set_int(idx, v.i);
|
||||
|
||||
if(!v.i) {
|
||||
load_resources();
|
||||
}
|
||||
}
|
||||
|
||||
void load_resources(void) {
|
||||
static bool callbacks_set_up = false;
|
||||
|
||||
if(!callbacks_set_up) {
|
||||
config_set_callback(CONFIG_NO_SHADER, resources_cfg_noshader_callback);
|
||||
callbacks_set_up = true;
|
||||
}
|
||||
|
||||
printf("load_resources():\n");
|
||||
|
||||
char *path = malloc(strlen(get_prefix())+32);
|
||||
|
|
19
src/video.c
19
src/video.c
|
@ -9,7 +9,6 @@
|
|||
#include "global.h"
|
||||
#include "video.h"
|
||||
#include "taisei_err.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
static VideoMode common_modes[] = {
|
||||
{RESX, RESY},
|
||||
|
@ -133,8 +132,12 @@ int video_isfullscreen(void) {
|
|||
return !!(SDL_GetWindowFlags(video.window) & (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_FULLSCREEN_DESKTOP));
|
||||
}
|
||||
|
||||
void video_set_fullscreen(bool fullscreen) {
|
||||
video_setmode(video.intended.width, video.intended.height, fullscreen);
|
||||
}
|
||||
|
||||
void video_toggle_fullscreen(void) {
|
||||
video_setmode(video.intended.width, video.intended.height, !video_isfullscreen());
|
||||
video_set_fullscreen(!video_isfullscreen());
|
||||
}
|
||||
|
||||
void video_resize(int w, int h) {
|
||||
|
@ -143,6 +146,15 @@ void video_resize(int w, int h) {
|
|||
video_set_viewport();
|
||||
}
|
||||
|
||||
static void video_cfg_fullscreen_callback(ConfigIndex idx, ConfigValue v) {
|
||||
video_set_fullscreen(config_set_int(idx, v.i));
|
||||
}
|
||||
|
||||
static void video_cfg_vsync_callback(ConfigIndex idx, ConfigValue v) {
|
||||
config_set_int(idx, v.i);
|
||||
video_update_vsync();
|
||||
}
|
||||
|
||||
void video_init(void) {
|
||||
int i, s;
|
||||
bool fullscreen_available = false;
|
||||
|
@ -178,6 +190,9 @@ void video_init(void) {
|
|||
qsort(video.modes, video.mcount, sizeof(VideoMode), video_compare_modes);
|
||||
|
||||
video_setmode(config_get_int(CONFIG_VID_WIDTH), config_get_int(CONFIG_VID_HEIGHT), config_get_int(CONFIG_FULLSCREEN));
|
||||
|
||||
config_set_callback(CONFIG_FULLSCREEN, video_cfg_fullscreen_callback);
|
||||
config_set_callback(CONFIG_VSYNC, video_cfg_vsync_callback);
|
||||
}
|
||||
|
||||
void video_shutdown(void) {
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
#define WINDOW_TITLE "TaiseiProject"
|
||||
#define VIEWPORT_ASPECT_RATIO (4.0f/3.0f)
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct VideoMode {
|
||||
int width;
|
||||
int height;
|
||||
|
@ -34,6 +36,7 @@ void video_shutdown(void);
|
|||
void video_setmode(int w, int h, int fs);
|
||||
void video_set_viewport(void);
|
||||
int video_isfullscreen(void);
|
||||
void video_set_fullscreen(bool);
|
||||
void video_toggle_fullscreen(void);
|
||||
void video_resize(int w, int h);
|
||||
void video_update_vsync(void);
|
||||
|
|
Loading…
Reference in a new issue