Unify config loading in net and video subsystems.feature/data-structs
@@ -65,29 +65,44 @@ void IZ_AppTeardown(struct IZ_App* app) { | |||||
SDL_Quit(); | SDL_Quit(); | ||||
} | } | ||||
void IZ_AppPrintHelpOptions() { | |||||
printf("\n"); | |||||
printf("Options:\n"); | |||||
printf("\n"); | |||||
printf( | |||||
"\n" | |||||
"Options:\n" | |||||
"\n" | |||||
" -c <path> Specifies the path to the config file. (default: \"./config-game.ini\")\n" | |||||
" -f <value> Specifies the frames per second. (default: 30)\n" | |||||
" -h Displays this help screen.\n" | |||||
" -i <value> Specifies the interval of sending packets (default: 200)\n" | |||||
" in milliseconds.\n" | |||||
); | |||||
} | |||||
void IZ_AppPrintHelpUsage() { | |||||
printf("\n"); | |||||
printf("Usage:"); | |||||
printf(" %s [options]\n", "game.exe"); | |||||
} | |||||
void IZ_AppPrintHelpHeader() { | |||||
printf("\n"); | |||||
printf("%s - %s\n", IZ_APP_NAME, IZ_APP_DESCRIPTION); | |||||
} | |||||
void IZ_AppPrintHelp() { | |||||
IZ_AppPrintHelpHeader(); | |||||
IZ_AppPrintHelpUsage(); | |||||
IZ_AppPrintHelpOptions(); | |||||
} | |||||
IZ_ProcedureResult IZ_AppRun(struct IZ_App* app, u8 argc, const char* argv[]) { | IZ_ProcedureResult IZ_AppRun(struct IZ_App* app, u8 argc, const char* argv[]) { | ||||
// TODO have a config subsystem that handles these. | |||||
if (IZ_ConfigGetCommandlineOption(argc, argv, "-h")) { | if (IZ_ConfigGetCommandlineOption(argc, argv, "-h")) { | ||||
printf( | |||||
( | |||||
"\n" | |||||
"%s - %s\n" | |||||
"\n" | |||||
"Usage:\n" | |||||
"\n" | |||||
" %s [options]\n" | |||||
"\n" | |||||
"Options:\n" | |||||
"\n" | |||||
" -c <path> Specifies the path to the config file. (default: \"./config-game.ini\")\n" | |||||
" -f <value> Specifies the frames per second. (default: 30)\n" | |||||
" -h Displays this help file.\n" | |||||
" -i <value> Specifies the interval of sending packets (default: 200)\n" | |||||
" in milliseconds.\n" | |||||
), | |||||
IZ_APP_NAME, | |||||
IZ_APP_DESCRIPTION, | |||||
"game.exe" | |||||
); | |||||
IZ_AppPrintHelp(); | |||||
return IZ_APP_RUN_RESULT_OK; | return IZ_APP_RUN_RESULT_OK; | ||||
} | } | ||||
@@ -33,3 +33,238 @@ const char* IZ_ConfigGetCommandlineOption(u8 argc, const char* argv[], const cha | |||||
return NULL; | return NULL; | ||||
} | } | ||||
typedef bool IZ_ConfigLoadParamsStringValidator(const char*); | |||||
typedef bool IZ_ConfigLoadParamsU16Validator(u16); | |||||
typedef bool IZ_ConfigLoadParamsU8Validator(u8); | |||||
void IZ_ConfigEnsureValidString(IZ_ConfigItem item, char* buffer) { | |||||
char dest[item.dest_size]; | |||||
if (item.validator) { | |||||
IZ_ConfigLoadParamsStringValidator* validator = item.validator; | |||||
if (validator(buffer)) { | |||||
memcpy_s(dest, item.dest_size, buffer, item.dest_size); | |||||
item.dest = &dest; | |||||
return; | |||||
} | |||||
memcpy_s(dest, item.dest_size, item.default_value, item.dest_size); | |||||
item.dest = &dest; | |||||
return; | |||||
} | |||||
memcpy_s(dest, item.dest_size, buffer, item.dest_size); | |||||
item.dest = &dest; | |||||
} | |||||
void IZ_ConfigLoadString(IZ_ConfigItem item, const char* config_path) { | |||||
char buffer[item.dest_size]; | |||||
ini_gets(item.section, item.key, item.default_value, buffer, item.dest_size, config_path); | |||||
IZ_ConfigEnsureValidString(item, buffer); | |||||
} | |||||
void IZ_ConfigEnsureValidU8(IZ_ConfigItem item, u8 raw_value, u8 default_value) { | |||||
if (item.validator) { | |||||
IZ_ConfigLoadParamsU8Validator* validator = item.validator; | |||||
if (validator(raw_value)) { | |||||
item.dest = &raw_value; | |||||
return; | |||||
} | |||||
item.dest = &default_value; | |||||
return; | |||||
} | |||||
item.dest = &raw_value; | |||||
} | |||||
void IZ_ConfigLoadU8(IZ_ConfigItem item, const char* config_path) { | |||||
static u8 raw_value; | |||||
static u8 default_value; | |||||
default_value = *((u8*) item.default_value); | |||||
raw_value = ini_getl(item.section, item.key, default_value, config_path); | |||||
IZ_ConfigEnsureValidU8(item, raw_value, default_value); | |||||
} | |||||
void IZ_ConfigEnsureValidU16(IZ_ConfigItem item, u16 raw_value, u16 default_value) { | |||||
if (item.validator) { | |||||
IZ_ConfigLoadParamsU16Validator* validator = item.validator; | |||||
if (validator(raw_value)) { | |||||
item.dest = &raw_value; | |||||
return; | |||||
} | |||||
item.dest = &default_value; | |||||
return; | |||||
} | |||||
item.dest = &raw_value; | |||||
} | |||||
void IZ_ConfigLoadU16(IZ_ConfigItem item, const char* config_path) { | |||||
static u16 raw_value; | |||||
static u16 default_value; | |||||
default_value = *((u16*) item.default_value); | |||||
raw_value = ini_getl(item.section, item.key, default_value, config_path); | |||||
IZ_ConfigEnsureValidU16(item, raw_value, default_value); | |||||
} | |||||
void IZ_ConfigLoad(IZ_ConfigItem item[], const char* config_path) { | |||||
u8 i; | |||||
for (i = 0; item[i].type != IZ_CONFIG_TYPE_VOID; i += 1) { | |||||
switch (item[i].type) { | |||||
case IZ_CONFIG_TYPE_STRING: | |||||
IZ_ConfigLoadString(item[i], config_path); | |||||
break; | |||||
case IZ_CONFIG_TYPE_U8: | |||||
IZ_ConfigLoadU8(item[i], config_path); | |||||
break; | |||||
case IZ_CONFIG_TYPE_U16: | |||||
IZ_ConfigLoadU16(item[i], config_path); | |||||
break; | |||||
default: | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
IZ_ProcedureResult IZ_ConfigSaveU8(IZ_ConfigItem item, const char* config_path) { | |||||
u8 dest = *((u8*) item.dest); | |||||
if (item.validator) { | |||||
IZ_ConfigLoadParamsU8Validator* validator = item.validator; | |||||
if (!validator(dest)) { | |||||
dest = *((const u8*) item.default_value); | |||||
} | |||||
} | |||||
if (!ini_putl(item.section, item.key, dest, config_path)) { | |||||
return -1; | |||||
} | |||||
return 0; | |||||
} | |||||
IZ_ProcedureResult IZ_ConfigSaveU16(IZ_ConfigItem item, const char* config_path) { | |||||
u16 dest = *((u16*) item.dest); | |||||
if (item.validator) { | |||||
IZ_ConfigLoadParamsU8Validator* validator = item.validator; | |||||
if (!validator(dest)) { | |||||
dest = *((const u16*) item.default_value); | |||||
} | |||||
} | |||||
if (!ini_putl(item.section, item.key, dest, config_path)) { | |||||
return -1; | |||||
} | |||||
return 0; | |||||
} | |||||
IZ_ProcedureResult IZ_ConfigSaveString(IZ_ConfigItem item, const char* config_path) { | |||||
const char* dest = (const char*) item.dest; | |||||
if (item.validator) { | |||||
IZ_ConfigLoadParamsStringValidator* validator = item.validator; | |||||
if (!validator(dest)) { | |||||
dest = (const char*) item.default_value; | |||||
} | |||||
} | |||||
if (!ini_puts(item.section, item.key, dest, config_path)) { | |||||
return -1; | |||||
} | |||||
return 0; | |||||
} | |||||
IZ_ProcedureResult IZ_ConfigSave(IZ_ConfigItem item[], const char* config_path) { | |||||
u8 i; | |||||
u16 problems = 0; | |||||
for (i = 0; item[i].type != IZ_CONFIG_TYPE_VOID; i += 1) { | |||||
switch (item[i].type) { | |||||
case IZ_CONFIG_TYPE_STRING: | |||||
IZ_ConfigSaveString(item[i], config_path); | |||||
break; | |||||
case IZ_CONFIG_TYPE_U8: | |||||
IZ_ConfigSaveU8(item[i], config_path); | |||||
break; | |||||
case IZ_CONFIG_TYPE_U16: | |||||
IZ_ConfigSaveU16(item[i], config_path); | |||||
break; | |||||
default: | |||||
break; | |||||
} | |||||
} | |||||
return -problems; | |||||
} | |||||
void IZ_ConfigOverrideU8(IZ_ConfigItem item, u8 argc, const char* argv[]) { | |||||
if (!item.cmdline_option) { | |||||
return; | |||||
} | |||||
const char* cmdline_buffer; | |||||
char* rest_of_string; | |||||
static u8 dest; | |||||
static u8 default_value; | |||||
default_value = *((u16*) item.default_value); | |||||
if ((cmdline_buffer = IZ_ConfigGetCommandlineOption(argc, argv, item.cmdline_option))) { | |||||
dest = strtol(cmdline_buffer, &rest_of_string, 10); | |||||
if (strcmp(cmdline_buffer, rest_of_string) != 0) { | |||||
IZ_ConfigEnsureValidU8(item, dest, default_value); | |||||
return; | |||||
} | |||||
item.dest = &default_value; | |||||
} | |||||
} | |||||
void IZ_ConfigOverrideU16(IZ_ConfigItem item, u8 argc, const char* argv[]) { | |||||
if (!item.cmdline_option) { | |||||
return; | |||||
} | |||||
const char* cmdline_buffer; | |||||
char* rest_of_string; | |||||
static u16 dest; | |||||
static u16 default_value; | |||||
default_value = *((u16*) item.default_value); | |||||
if ((cmdline_buffer = IZ_ConfigGetCommandlineOption(argc, argv, item.cmdline_option))) { | |||||
dest = strtol(cmdline_buffer, &rest_of_string, 10); | |||||
if (strcmp(cmdline_buffer, rest_of_string) != 0) { | |||||
IZ_ConfigEnsureValidU16(item, dest, default_value); | |||||
return; | |||||
} | |||||
item.dest = &default_value; | |||||
} | |||||
} | |||||
void IZ_ConfigOverrideString(IZ_ConfigItem item, u8 argc, const char* argv[]) { | |||||
if (!item.cmdline_option) { | |||||
return; | |||||
} | |||||
const char* cmdline_buffer; | |||||
if ((cmdline_buffer = IZ_ConfigGetCommandlineOption(argc, argv, item.cmdline_option))) { | |||||
IZ_ConfigEnsureValidString(item, cmdline_buffer); | |||||
} | |||||
} | |||||
void IZ_ConfigOverride(IZ_ConfigItem item[], u8 argc, const char* argv[]) { | |||||
u8 i; | |||||
for (i = 0; item[i].type != IZ_CONFIG_TYPE_VOID; i += 1) { | |||||
switch (item[i].type) { | |||||
case IZ_CONFIG_TYPE_U8: | |||||
IZ_ConfigOverrideU8(item[i], argc, argv); | |||||
break; | |||||
case IZ_CONFIG_TYPE_U16: | |||||
IZ_ConfigOverrideU16(item[i], argc, argv); | |||||
break; | |||||
case IZ_CONFIG_TYPE_STRING: | |||||
IZ_ConfigOverrideString(item[i], argc, argv); | |||||
break; | |||||
default: | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
void IZ_ConfigInit(IZ_ConfigItem item[], const char* config_path, u8 argc, const char* argv[]) { | |||||
IZ_ConfigLoad(item, config_path); | |||||
if (IZ_ConfigSave(item, config_path)) { | |||||
// TODO log errors in saving | |||||
} | |||||
IZ_ConfigOverride(item, argc, argv); | |||||
} |
@@ -3,11 +3,34 @@ | |||||
#include <SDL_filesystem.h> | #include <SDL_filesystem.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <minIni.h> | |||||
#include <stdlib.h> | |||||
#include "IZ_common.h" | #include "IZ_common.h" | ||||
// TODO unify loading of config from cmdline and config file | |||||
typedef enum { | |||||
IZ_CONFIG_TYPE_VOID, | |||||
IZ_CONFIG_TYPE_STRING, | |||||
IZ_CONFIG_TYPE_U8, | |||||
IZ_CONFIG_TYPE_U16 | |||||
} IZ_ConfigType; | |||||
typedef struct { | |||||
IZ_ConfigType type; | |||||
size_t dest_size; | |||||
const char* section; | |||||
const char* key; | |||||
const char* cmdline_option; | |||||
const void* default_value; | |||||
void* validator; | |||||
void* dest; | |||||
} IZ_ConfigItem; | |||||
void IZ_ConfigGetDefaultPath(const char*, size_t); | void IZ_ConfigGetDefaultPath(const char*, size_t); | ||||
const char* IZ_ConfigGetCommandlineOption(u8, const char**, const char*); | const char* IZ_ConfigGetCommandlineOption(u8, const char**, const char*); | ||||
void IZ_ConfigInit(IZ_ConfigItem[], const char*, u8, const char**); | |||||
IZ_ProcedureResult IZ_ConfigSave(IZ_ConfigItem[], const char*); | |||||
#endif | #endif |
@@ -1,57 +1,66 @@ | |||||
#include "IZ_net.h" | #include "IZ_net.h" | ||||
void IZ_NetLoadConfig(IZ_NetState* state, const char* config_path) { | |||||
char buffer[32]; | |||||
ini_gets("Network", "Username", IZ_NET_DEFAULT_STATE.config.username, buffer, 32, config_path); | |||||
memcpy_s(state->config.username, 32, buffer, 32); | |||||
state->config.packet_interval_ms = ini_getl("Network", "PacketIntervalMs", IZ_NET_DEFAULT_STATE.config.packet_interval_ms, config_path); | |||||
if (!(100 <= state->config.packet_interval_ms && state->config.packet_interval_ms <= 500)) { | |||||
state->config.packet_interval_ms = IZ_NET_DEFAULT_STATE.config.packet_interval_ms; | |||||
} | |||||
state->config.max_reconnect_retries = ini_getl("Network", "MaxReconnectRetries", IZ_NET_DEFAULT_STATE.config.max_reconnect_retries, config_path); | |||||
if (!(0 <= state->config.max_reconnect_retries && state->config.max_reconnect_retries <= 8)) { | |||||
state->config.max_reconnect_retries = IZ_NET_DEFAULT_STATE.config.max_reconnect_retries; | |||||
} | |||||
state->config.reconnect_interval_secs = ini_getl("Network", "ReconnectIntervalSeconds", IZ_NET_DEFAULT_STATE.config.reconnect_interval_secs, config_path); | |||||
if (!(3 <= state->config.reconnect_interval_secs && state->config.reconnect_interval_secs <= 10)) { | |||||
state->config.reconnect_interval_secs = IZ_NET_DEFAULT_STATE.config.reconnect_interval_secs; | |||||
} | |||||
bool IZ_NetIsValidPacketIntervalMs(long packet_interval_ms) { | |||||
return (100 <= packet_interval_ms && packet_interval_ms <= 500); | |||||
} | } | ||||
IZ_ProcedureResult IZ_NetSaveConfig(IZ_NetState* state, const char* config_path) { | |||||
if (!ini_puts("Network", "Username", state->config.username, config_path)) { | |||||
return -1; | |||||
} | |||||
if (!ini_putl("Network", "PacketIntervalMs", state->config.packet_interval_ms, config_path)) { | |||||
return -1; | |||||
} | |||||
if (!ini_putl("Network", "MaxReconnectRetries", state->config.max_reconnect_retries, config_path)) { | |||||
return -1; | |||||
} | |||||
bool IZ_NetIsValidMaxReconnectRetries(long max_reconnect_retries) { | |||||
return (0 <= max_reconnect_retries && max_reconnect_retries <= 8); | |||||
} | |||||
if (!ini_putl("Network", "ReconnectIntervalSeconds", state->config.reconnect_interval_secs, config_path)) { | |||||
return -1; | |||||
} | |||||
bool IZ_NetIsValidReconnectIntervalSeconds(long reconnect_interval_secs) { | |||||
return (3 <= reconnect_interval_secs && reconnect_interval_secs <= 10); | |||||
} | |||||
return 0; | |||||
static IZ_ConfigItem net_config_items[] = { | |||||
{ | |||||
IZ_CONFIG_TYPE_STRING, | |||||
32, | |||||
"Network", | |||||
"Username", | |||||
NULL, | |||||
&IZ_NET_DEFAULT_STATE.config.username, | |||||
NULL | |||||
}, | |||||
{ | |||||
IZ_CONFIG_TYPE_U16, | |||||
sizeof(u16), | |||||
"Network", | |||||
"PacketIntervalMs", | |||||
"-i", | |||||
&IZ_NET_DEFAULT_STATE.config.packet_interval_ms, | |||||
IZ_NetIsValidPacketIntervalMs, | |||||
}, | |||||
{ | |||||
IZ_CONFIG_TYPE_U8, | |||||
sizeof(u8), | |||||
"Network", | |||||
"MaxReconnectRetries", | |||||
NULL, | |||||
&IZ_NET_DEFAULT_STATE.config.max_reconnect_retries, | |||||
IZ_NetIsValidMaxReconnectRetries, | |||||
}, | |||||
{ | |||||
IZ_CONFIG_TYPE_U8, | |||||
sizeof(u8), | |||||
"Network", | |||||
"ReconnectIntervalSeconds", | |||||
NULL, | |||||
&IZ_NET_DEFAULT_STATE.config.reconnect_interval_secs, | |||||
IZ_NetIsValidReconnectIntervalSeconds, | |||||
}, | |||||
}; | |||||
void IZ_NetBindStateToConfig(IZ_NetState* state, IZ_ConfigItem config_items[]) { | |||||
config_items[0].dest = &state->config.username; | |||||
config_items[1].dest = &state->config.packet_interval_ms; | |||||
config_items[2].dest = &state->config.max_reconnect_retries; | |||||
config_items[3].dest = &state->config.reconnect_interval_secs; | |||||
} | } | ||||
void IZ_NetOverrideConfig(IZ_NetState* state, u8 argc, const char* argv[]) { | |||||
const char* cmdline_buffer; | |||||
char* rest_of_string; | |||||
u16 packet_interval_ms; | |||||
if ((cmdline_buffer = IZ_ConfigGetCommandlineOption(argc, argv, "-i"))) { | |||||
packet_interval_ms = strtol(cmdline_buffer, &rest_of_string, 10); | |||||
if (strcmp(cmdline_buffer, rest_of_string) != 0) { | |||||
state->config.packet_interval_ms = packet_interval_ms; | |||||
} | |||||
} | |||||
IZ_ProcedureResult IZ_NetSaveConfig(IZ_NetState* state, const char* config_path) { | |||||
IZ_NetBindStateToConfig(state, net_config_items); | |||||
return IZ_ConfigSave(net_config_items, config_path); | |||||
} | } | ||||
IZ_ProcedureResult IZ_NetInitialize( | IZ_ProcedureResult IZ_NetInitialize( | ||||
@@ -63,11 +72,8 @@ IZ_ProcedureResult IZ_NetInitialize( | |||||
const char* argv[] | const char* argv[] | ||||
) { | ) { | ||||
memcpy_s(state, sizeof(IZ_NetState), &IZ_NET_DEFAULT_STATE, sizeof(IZ_NetState)); | memcpy_s(state, sizeof(IZ_NetState), &IZ_NET_DEFAULT_STATE, sizeof(IZ_NetState)); | ||||
IZ_NetLoadConfig(state, config_path); | |||||
if (IZ_NetSaveConfig(state, config_path) < 0) { | |||||
return -1; | |||||
} | |||||
IZ_NetOverrideConfig(state, argc, argv); | |||||
IZ_NetBindStateToConfig(state, net_config_items); | |||||
IZ_ConfigInit(net_config_items, config_path, argc, argv); | |||||
if (!user_data) { | if (!user_data) { | ||||
return -2; | return -2; | ||||
} | } | ||||
@@ -1,45 +1,64 @@ | |||||
#include "IZ_video.h" | #include "IZ_video.h" | ||||
IZ_ProcedureResult IZ_VideoSaveConfig(IZ_VideoState* state, const char* config_path) { | |||||
if (!ini_putl("Video", "Width", state->config.width, config_path)) { | |||||
return -1; | |||||
} | |||||
if (!ini_putl("Video", "Height", state->config.height, config_path)) { | |||||
return -1; | |||||
} | |||||
if (!ini_putl("Video", "MaxFps", state->config.max_fps, config_path)) { | |||||
return -1; | |||||
} | |||||
bool IZ_VideoIsValidWidth(u16 width) { | |||||
// TODO check screen size | |||||
return (320 <= width && width <= 16384); | |||||
} | |||||
return 0; | |||||
bool IZ_VideoIsValidHeight(u16 height) { | |||||
// TODO check screen size | |||||
return (240 <= height && height <= 8192); | |||||
} | } | ||||
void IZ_VideoLoadConfig(IZ_VideoState* state, const char* config_path) { | |||||
state->config.width = ini_getl("Video", "Width", IZ_DEFAULT_VIDEO_STATE.config.width, config_path); | |||||
state->config.height = ini_getl("Video", "Height", IZ_DEFAULT_VIDEO_STATE.config.height, config_path); | |||||
state->config.max_fps = ini_getl("Video", "MaxFps", IZ_DEFAULT_VIDEO_STATE.config.max_fps, config_path); | |||||
bool IZ_VideoIsValidMaxFPS(u8 max_fps) { | |||||
return (10 <= max_fps && max_fps <= 200); | |||||
} | } | ||||
void IZ_VideoOverrideConfig(IZ_VideoState* state, u8 argc, const char* argv[]) { | |||||
const char* cmdline_buffer; | |||||
char* rest_of_string; | |||||
u8 max_fps; | |||||
if ((cmdline_buffer = IZ_ConfigGetCommandlineOption(argc, argv, "-f"))) { | |||||
max_fps = strtol(cmdline_buffer, &rest_of_string, 10); | |||||
if (strcmp(cmdline_buffer, rest_of_string) != 0) { | |||||
state->config.max_fps = max_fps; | |||||
} | |||||
} | |||||
static IZ_ConfigItem video_config_items[] = { | |||||
{ | |||||
IZ_CONFIG_TYPE_U16, | |||||
sizeof(u16), | |||||
"Video", | |||||
"Width", | |||||
NULL, | |||||
&IZ_VIDEO_DEFAULT_STATE.config.width, | |||||
IZ_VideoIsValidWidth, | |||||
}, | |||||
{ | |||||
IZ_CONFIG_TYPE_U16, | |||||
sizeof(u16), | |||||
"Video", | |||||
"Height", | |||||
NULL, | |||||
&IZ_VIDEO_DEFAULT_STATE.config.height, | |||||
IZ_VideoIsValidHeight, | |||||
}, | |||||
{ | |||||
IZ_CONFIG_TYPE_U8, | |||||
sizeof(u8), | |||||
"Video", | |||||
"MaxFps", | |||||
"-f", | |||||
&IZ_VIDEO_DEFAULT_STATE.config.max_fps, | |||||
IZ_VideoIsValidMaxFPS, | |||||
}, | |||||
}; | |||||
void IZ_VideoBindStateToConfig(IZ_VideoState* state, IZ_ConfigItem config_items[]) { | |||||
config_items[0].dest = &state->config.width; | |||||
config_items[1].dest = &state->config.height; | |||||
config_items[2].dest = &state->config.max_fps; | |||||
} | } | ||||
IZ_ProcedureResult IZ_VideoInitialize(IZ_VideoState* state, void* user_data, const char* config_path, u8 argc, const char* argv[]) { | |||||
SDL_memcpy(state, &IZ_DEFAULT_VIDEO_STATE, sizeof(IZ_VideoState)); | |||||
IZ_ProcedureResult IZ_VideoSaveConfig(IZ_VideoState* state, const char* config_path) { | |||||
IZ_VideoBindStateToConfig(state, video_config_items); | |||||
return IZ_ConfigSave(video_config_items, config_path); | |||||
} | |||||
IZ_VideoLoadConfig(state, config_path); | |||||
if (IZ_VideoSaveConfig(state, config_path)) { | |||||
// fprintf_s(stderr, "Error committing video config.\n"); | |||||
} | |||||
IZ_VideoOverrideConfig(state, argc, argv); | |||||
IZ_ProcedureResult IZ_VideoInitialize(IZ_VideoState* state, void* user_data, const char* config_path, u8 argc, const char* argv[]) { | |||||
SDL_memcpy(state, &IZ_VIDEO_DEFAULT_STATE, sizeof(IZ_VideoState)); | |||||
IZ_VideoBindStateToConfig(state, video_config_items); | |||||
IZ_ConfigInit(video_config_items, config_path, argc, argv); | |||||
state->last_update_at = 0u; | state->last_update_at = 0u; | ||||
state->user_data = user_data; | state->user_data = user_data; | ||||
@@ -30,7 +30,7 @@ typedef struct { | |||||
IZ_Sprite active_sprites[MAX_ACTIVE_SPRITES]; | IZ_Sprite active_sprites[MAX_ACTIVE_SPRITES]; | ||||
} IZ_VideoState; | } IZ_VideoState; | ||||
static const IZ_VideoState IZ_DEFAULT_VIDEO_STATE = { | |||||
static const IZ_VideoState IZ_VIDEO_DEFAULT_STATE = { | |||||
.user_data = NULL, | .user_data = NULL, | ||||
.config = { | .config = { | ||||
.width = 320u, | .width = 320u, | ||||
@@ -41,31 +41,45 @@ void IZ_AppTeardown(IZ_App* app) { | |||||
lwsl_user("Server closed. Bye!\n"); | lwsl_user("Server closed. Bye!\n"); | ||||
} | } | ||||
void IZ_AppPrintHelpOptions() { | |||||
printf("\n"); | |||||
printf("Options:\n"); | |||||
printf("\n"); | |||||
printf( | |||||
"\n" | |||||
"Options:\n" | |||||
"\n" | |||||
" -c <path> Specifies the path to the config file. (default: \"./config-server.ini\")\n" | |||||
" -d <path> Specifies the path to the database. (default: \"./db.sqlite\")\n" | |||||
" -h Displays this help screen.\n" | |||||
" -m <value> Specifies the message of the day. (default: \"\")\n" | |||||
" -n <value> Specifies the name of the server. (default: \"%s\")\n" | |||||
" -p <value> Specifies the port where the server runs. (default: 42069)\n", | |||||
IZ_APP_NAME | |||||
); | |||||
} | |||||
void IZ_AppPrintHelpUsage() { | |||||
printf("\n"); | |||||
printf("Usage:"); | |||||
printf(" %s [options]\n", "server.exe"); | |||||
} | |||||
void IZ_AppPrintHelpHeader() { | |||||
printf("\n"); | |||||
printf("%s - %s\n", IZ_APP_NAME, IZ_APP_SERVER_DESCRIPTION); | |||||
} | |||||
void IZ_AppPrintHelp() { | |||||
IZ_AppPrintHelpHeader(); | |||||
IZ_AppPrintHelpUsage(); | |||||
IZ_AppPrintHelpOptions(); | |||||
} | |||||
IZ_ProcedureResult IZ_AppRun(IZ_App *app, u8 argc, const char **argv) { | IZ_ProcedureResult IZ_AppRun(IZ_App *app, u8 argc, const char **argv) { | ||||
// TODO have a config subsystem that handles these. | |||||
if (IZ_ConfigGetCommandlineOption(argc, argv, "-h")) { | if (IZ_ConfigGetCommandlineOption(argc, argv, "-h")) { | ||||
printf( | |||||
( | |||||
"\n" | |||||
"%s - %s\n" | |||||
"\n" | |||||
"Usage:\n" | |||||
"\n" | |||||
" %s [options]\n" | |||||
"\n" | |||||
"Options:\n" | |||||
"\n" | |||||
" -c <path> Specifies the path to the config file. (default: \"./config-server.ini\")\n" | |||||
" -d <path> Specifies the path to the database. (default: \"./db.sqlite\")\n" | |||||
" -h Displays this help file.\n" | |||||
" -m <value> Specifies the message of the day. (default: \"\")\n" | |||||
" -n <value> Specifies the name of the server. (default: \"%s\")\n" | |||||
" -p <value> Specifies the port where the server runs. (default: 42069)\n" | |||||
), | |||||
IZ_APP_NAME, | |||||
IZ_APP_SERVER_DESCRIPTION, | |||||
"server.exe", | |||||
IZ_APP_NAME | |||||
); | |||||
IZ_AppPrintHelp(); | |||||
return 0; | return 0; | ||||
} | } | ||||