Add templates for config item types. Also updated server's config to use the global config module.feature/data-structs
@@ -17,7 +17,7 @@ add_definitions( | |||
-DIZ_APP_NAME="Izanagi" | |||
-DIZ_APP_DESCRIPTION="Run and gun game" | |||
-DIZ_APP_SERVER_DESCRIPTION="Dedicated server" | |||
-DIZ_PLAYERS=1 | |||
-DIZ_PLAYERS=2 | |||
) | |||
if (${CMAKE_BUILD_TYPE} STREQUAL "Debug") | |||
@@ -2,6 +2,9 @@ | |||
Width=320 | |||
Height=240 | |||
MaxFps=30 | |||
[Joystick.0] | |||
DeviceID=0 | |||
AxisThreshold=8000 | |||
[Joystick.0.ControlMapping] | |||
Affirm=11 | |||
Negate=10 | |||
@@ -15,9 +18,6 @@ Action6=8 | |||
Action7=9 | |||
Action8=13 | |||
Action9=14 | |||
[Joystick.0] | |||
DeviceID=0 | |||
AxisThreshold=8000 | |||
[Keyboard.0.ControlMapping] | |||
Up=Up | |||
Right=Right | |||
@@ -35,6 +35,9 @@ Action6=C | |||
Action7=V | |||
Action8=W | |||
Action9=E | |||
[MIDIInput.0] | |||
DeviceID=0 | |||
Channel=0 | |||
[MIDIInput.0.ControlMapping] | |||
Up="A#5" | |||
Right=C6 | |||
@@ -52,11 +55,64 @@ Action6="F#4" | |||
Action7=G4 | |||
Action8="G#4" | |||
Action9=A4 | |||
[MIDIInput.0] | |||
Channel=0 | |||
DeviceID=0 | |||
[Network] | |||
Username=Player | |||
PacketIntervalMs=200 | |||
MaxReconnectRetries=3 | |||
ReconnectIntervalSeconds=3 | |||
[Network.0] | |||
Username=Player 1 | |||
[Joystick.1] | |||
DeviceID=1 | |||
AxisThreshold=8000 | |||
[Joystick.1.ControlMapping] | |||
Affirm=11 | |||
Negate=10 | |||
Action0=1 | |||
Action1=0 | |||
Action2=4 | |||
Action3=3 | |||
Action4=6 | |||
Action5=7 | |||
Action6=8 | |||
Action7=9 | |||
Action8=13 | |||
Action9=14 | |||
[Keyboard.1.ControlMapping] | |||
Up=Keypad 8 | |||
Right=Keypad 6 | |||
Down=Keypad 5 | |||
Left=Keypad 4 | |||
Affirm=Keypad Enter | |||
Negate=Keypad - | |||
Action0=J | |||
Action1=K | |||
Action2=L | |||
Action3=";" | |||
Action4=M | |||
Action5=, | |||
Action6=. | |||
Action7=/ | |||
Action8=I | |||
Action9=O | |||
[MIDIInput.1] | |||
DeviceID=1 | |||
Channel=1 | |||
[MIDIInput.1.ControlMapping] | |||
Up="A#5" | |||
Right=C6 | |||
Down=B5 | |||
Left=A5 | |||
Affirm=F5 | |||
Negate=E5 | |||
Action0=C4 | |||
Action1="C#4" | |||
Action2=D4 | |||
Action3="D#4" | |||
Action4=E4 | |||
Action5=F4 | |||
Action6="F#4" | |||
Action7=G4 | |||
Action8="G#4" | |||
Action9=A4 | |||
[Network.1] | |||
Username=Player 2 |
@@ -23,75 +23,140 @@ const char* IZ_ConfigGetCommandlineOption(u8 argc, const char* argv[], const cha | |||
return NULL; | |||
} | |||
typedef bool IZ_ConfigLoadParamsStringValidator(const char*); | |||
typedef bool IZ_ConfigLoadParamsU16Validator(u16); | |||
#define IZ_CONFIG_REGISTER_INT_TYPE(ID, T) \ | |||
typedef bool IZ_ConfigValidate##ID(T); \ | |||
\ | |||
typedef T IZ_ConfigDeserialize##ID(const char*); \ | |||
\ | |||
typedef void IZ_ConfigSerialize##ID(T, const char[128]); \ | |||
\ | |||
void IZ_ConfigEnsureValid##ID(IZ_ConfigItem* item, T raw_value, T default_value) { \ | |||
T* dest = item->dest; \ | |||
if (item->validator) { \ | |||
IZ_ConfigValidate##ID* validate = item->validator; \ | |||
if (validate(raw_value)) { \ | |||
*dest = raw_value; \ | |||
return; \ | |||
} \ | |||
*dest = default_value; \ | |||
return; \ | |||
} \ | |||
*dest = raw_value; \ | |||
} \ | |||
\ | |||
void IZ_ConfigLoad##ID(IZ_ConfigItem* item, const char* config_path) { \ | |||
static T raw_value; \ | |||
static T default_value; \ | |||
default_value = *((T*) item->default_value); \ | |||
if (item->transformer.deserialize && item->transformer.serialize) { \ | |||
IZ_ConfigDeserialize##ID* deserialize = item->transformer.deserialize; \ | |||
IZ_ConfigSerialize##ID* serialize = item->transformer.serialize; \ | |||
const char serialized_default_value[128]; \ | |||
if (default_value) { \ | |||
serialize(default_value, serialized_default_value); \ | |||
} \ | |||
char buffer[128]; \ | |||
ini_gets(item->section, item->key, serialized_default_value, buffer, 128, config_path); \ | |||
raw_value = deserialize(buffer); \ | |||
} else { \ | |||
raw_value = ini_getl(item->section, item->key, default_value, config_path); \ | |||
} \ | |||
IZ_ConfigEnsureValid##ID(item, raw_value, default_value); \ | |||
} \ | |||
\ | |||
IZ_ProcedureResult IZ_ConfigSave##ID(IZ_ConfigItem* item, const char* config_path) { \ | |||
T dest = *((T*) item->dest); \ | |||
if (item->validator) { \ | |||
IZ_ConfigValidate##ID* validate = item->validator; \ | |||
if (!validate(dest)) { \ | |||
dest = *((const T*) item->default_value); \ | |||
} \ | |||
} \ | |||
\ | |||
if (item->transformer.deserialize && item->transformer.serialize) { \ | |||
IZ_ConfigSerialize##ID* serialize = item->transformer.serialize; \ | |||
const char serialized_value[128]; \ | |||
serialize(dest, serialized_value); \ | |||
if (!ini_puts(item->section, item->key, serialized_value, config_path)) { \ | |||
return -1; \ | |||
} \ | |||
return 0; \ | |||
} \ | |||
\ | |||
if (!ini_putl(item->section, item->key, dest, config_path)) { \ | |||
return -1; \ | |||
} \ | |||
\ | |||
return 0; \ | |||
} \ | |||
\ | |||
void IZ_ConfigOverride##ID(IZ_ConfigItem* item, u8 argc, const char* argv[]) { \ | |||
if (!item->cmdline_option) { \ | |||
return; \ | |||
} \ | |||
const char* cmdline_buffer; \ | |||
char* rest_of_string; \ | |||
static T dest; \ | |||
static T config_value; \ | |||
config_value = *((T*) item->dest); \ | |||
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_ConfigEnsureValid##ID(item, dest, config_value); \ | |||
return; \ | |||
} \ | |||
} \ | |||
} | |||
IZ_CONFIG_REGISTER_INT_TYPE(U8, u8); | |||
IZ_CONFIG_REGISTER_INT_TYPE(U16, u16); | |||
IZ_CONFIG_REGISTER_INT_TYPE(I32, i32); | |||
typedef bool IZ_ConfigLoadParamsU8Validator(u8); | |||
typedef bool IZ_ConfigLoadParamsStringValidator(const char*); | |||
void IZ_ConfigEnsureValidString(IZ_ConfigItem item, const char* buffer) { | |||
char dest[item.dest_size]; | |||
if (item.validator) { | |||
IZ_ConfigLoadParamsStringValidator* validator = item.validator; | |||
void IZ_ConfigEnsureValidString(IZ_ConfigItem* item, const char* buffer) { | |||
if (item->validator) { | |||
IZ_ConfigLoadParamsStringValidator* validator = item->validator; | |||
if (validator(buffer)) { | |||
memcpy_s(dest, item.dest_size, buffer, item.dest_size); | |||
item.dest = &dest; | |||
memcpy_s(item->dest, item->dest_size, buffer, item->dest_size); | |||
return; | |||
} | |||
memcpy_s(dest, item.dest_size, item.default_value, item.dest_size); | |||
item.dest = &dest; | |||
memcpy_s(item->dest, item->dest_size, item->default_value, item->dest_size); | |||
return; | |||
} | |||
memcpy_s(dest, item.dest_size, buffer, item.dest_size); | |||
item.dest = &dest; | |||
memcpy_s(item->dest, item->dest_size, buffer, item->dest_size); | |||
} | |||
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, (i32) item.dest_size, config_path); | |||
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, (i32) 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; | |||
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; | |||
} | |||
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); | |||
if (!ini_puts(item->section, item->key, dest, config_path)) { | |||
return -1; | |||
} | |||
return 0; | |||
} | |||
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; | |||
void IZ_ConfigOverrideString(IZ_ConfigItem* item, u8 argc, const char* argv[]) { | |||
if (!item->cmdline_option) { | |||
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); | |||
const char* cmdline_buffer; | |||
if ((cmdline_buffer = IZ_ConfigGetCommandlineOption(argc, argv, item->cmdline_option))) { | |||
IZ_ConfigEnsureValidString(item, cmdline_buffer); | |||
} | |||
} | |||
void IZ_ConfigLoad(IZ_ConfigItem item[], const char* config_path) { | |||
@@ -99,82 +164,38 @@ void IZ_ConfigLoad(IZ_ConfigItem item[], const char* config_path) { | |||
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); | |||
IZ_ConfigLoadString(&item[i], config_path); | |||
break; | |||
case IZ_CONFIG_TYPE_U8: | |||
IZ_ConfigLoadU8(item[i], config_path); | |||
IZ_ConfigLoadU8(&item[i], config_path); | |||
break; | |||
case IZ_CONFIG_TYPE_U16: | |||
IZ_ConfigLoadU16(item[i], config_path); | |||
IZ_ConfigLoadU16(&item[i], config_path); | |||
break; | |||
case IZ_CONFIG_TYPE_I32: | |||
IZ_ConfigLoadI32(&item[i], config_path); | |||
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); | |||
IZ_ConfigSaveString(&item[i], config_path); | |||
break; | |||
case IZ_CONFIG_TYPE_U8: | |||
IZ_ConfigSaveU8(item[i], config_path); | |||
IZ_ConfigSaveU8(&item[i], config_path); | |||
break; | |||
case IZ_CONFIG_TYPE_U16: | |||
IZ_ConfigSaveU16(item[i], config_path); | |||
IZ_ConfigSaveU16(&item[i], config_path); | |||
break; | |||
case IZ_CONFIG_TYPE_I32: | |||
IZ_ConfigSaveI32(&item[i], config_path); | |||
default: | |||
break; | |||
} | |||
@@ -183,66 +204,21 @@ IZ_ProcedureResult IZ_ConfigSave(IZ_ConfigItem item[], const char* config_path) | |||
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_STRING: | |||
IZ_ConfigOverrideString(&item[i], argc, argv); | |||
break; | |||
case IZ_CONFIG_TYPE_U8: | |||
IZ_ConfigOverrideU8(item[i], argc, argv); | |||
IZ_ConfigOverrideU8(&item[i], argc, argv); | |||
break; | |||
case IZ_CONFIG_TYPE_U16: | |||
IZ_ConfigOverrideU16(item[i], argc, argv); | |||
IZ_ConfigOverrideU16(&item[i], argc, argv); | |||
break; | |||
case IZ_CONFIG_TYPE_STRING: | |||
IZ_ConfigOverrideString(item[i], argc, argv); | |||
case IZ_CONFIG_TYPE_I32: | |||
IZ_ConfigOverrideI32(&item[i], argc, argv); | |||
break; | |||
default: | |||
break; | |||
@@ -250,10 +226,12 @@ void IZ_ConfigOverride(IZ_ConfigItem item[], u8 argc, const char* argv[]) { | |||
} | |||
} | |||
void IZ_ConfigInit(IZ_ConfigItem item[], const char* config_path, u8 argc, const char* argv[]) { | |||
IZ_ProcedureResult IZ_ConfigInitialize(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 | |||
i32 save_result = IZ_ConfigSave(item, config_path); | |||
if (save_result < 0) { | |||
return -1; | |||
} | |||
IZ_ConfigOverride(item, argc, argv); | |||
return save_result > 0 ? 1 : 0; | |||
} |
@@ -10,9 +10,15 @@ typedef enum { | |||
IZ_CONFIG_TYPE_VOID, | |||
IZ_CONFIG_TYPE_STRING, | |||
IZ_CONFIG_TYPE_U8, | |||
IZ_CONFIG_TYPE_U16 | |||
IZ_CONFIG_TYPE_U16, | |||
IZ_CONFIG_TYPE_I32, | |||
} IZ_ConfigType; | |||
typedef struct { | |||
void* serialize; | |||
void* deserialize; | |||
} IZ_ConfigSerializerPair; | |||
typedef struct { | |||
IZ_ConfigType type; | |||
size_t dest_size; | |||
@@ -21,6 +27,7 @@ typedef struct { | |||
const char* cmdline_option; | |||
const void* default_value; | |||
void* validator; | |||
IZ_ConfigSerializerPair transformer; | |||
void* dest; | |||
} IZ_ConfigItem; | |||
@@ -28,8 +35,23 @@ void IZ_ConfigGetDefaultPath(const char*, size_t); | |||
const char* IZ_ConfigGetCommandlineOption(u8, const char*[], const char*); | |||
void IZ_ConfigInit(IZ_ConfigItem[], const char*, u8, const char*[]); | |||
IZ_ProcedureResult IZ_ConfigInitialize(IZ_ConfigItem[], const char*, u8, const char*[]); | |||
IZ_ProcedureResult IZ_ConfigSave(IZ_ConfigItem[], const char*); | |||
#define IZ_CONFIG_ITEM_NULL (IZ_ConfigItem) { \ | |||
IZ_CONFIG_TYPE_VOID, \ | |||
0, \ | |||
NULL, \ | |||
NULL, \ | |||
NULL, \ | |||
NULL, \ | |||
NULL, \ | |||
{ \ | |||
.serialize = NULL, \ | |||
.deserialize = NULL, \ | |||
}, \ | |||
NULL, \ | |||
} | |||
#endif |
@@ -35,7 +35,7 @@ void IZ_VideoUpdateForDebugInput(IZ_VideoState* video_state, IZ_InputState* inpu | |||
u8 control_index; | |||
for (player_index = 0; player_index < IZ_PLAYERS; player_index += 1) { | |||
IZ_Action the_action = input_state->action[player_index]; | |||
for (control_index = 0; control_index < CONTROLS; control_index += 1) { | |||
for (control_index = 0; control_index < IZ_CONTROLS; control_index += 1) { | |||
column = (control_index % 4) + (player_index * 4); | |||
row = control_index / 4; | |||
@@ -87,7 +87,7 @@ void IZ_VideoUpdateForDebugNet(IZ_VideoState* video_state, IZ_NetClientState* ne | |||
u8 control_index; | |||
for (player_index = 0; player_index < IZ_PLAYERS; player_index += 1) { | |||
IZ_Action the_action = net_state->action[player_index]; | |||
for (control_index = 0; control_index < CONTROLS; control_index += 1) { | |||
for (control_index = 0; control_index < IZ_CONTROLS; control_index += 1) { | |||
column = (control_index % 4) + (player_index * 4); | |||
row = control_index / 4; | |||
@@ -3,11 +3,11 @@ | |||
#include "../../common/IZ_common.h" | |||
#define CONTROLS (unsigned char) 16 | |||
#define IZ_CONTROLS (unsigned char) 16 | |||
typedef u16 IZ_Action; | |||
static const char* ACTION_NAMES[CONTROLS] = { | |||
static const char* IZ_ACTION_NAMES[IZ_CONTROLS] = { | |||
"Up", | |||
"Right", | |||
"Down", | |||
@@ -19,15 +19,15 @@ IZ_ProcedureResult IZ_InputInitialize(IZ_InputState* state, const char* config_p | |||
IZ_ProcedureResult result = 0; | |||
if (IZ_JoystickInitialize(&state->joystick_state, config_path, argc, argv)) { | |||
if (IZ_JoystickInitialize(&state->joystick_state, config_path, argc, argv) < 0) { | |||
result |= 1; | |||
} | |||
if (IZ_KeyboardInitialize(&state->keyboard_state, config_path, argc, argv)) { | |||
if (IZ_KeyboardInitialize(&state->keyboard_state, config_path, argc, argv) < 0) { | |||
result |= 2; | |||
} | |||
if (IZ_MIDIInputInitialize(&state->midi_input_state, config_path, argc, argv)) { | |||
if (IZ_MIDIInputInitialize(&state->midi_input_state, config_path, argc, argv) < 0) { | |||
result |= 4; | |||
} | |||
@@ -1,5 +1,11 @@ | |||
#include "IZ_joystick.h" | |||
static IZ_ConfigItem joystick_config_items[IZ_PLAYERS * (IZ_CONTROLS - 4 + 2) + 1]; | |||
bool IZ_JoystickIsValidAxisThreshold(u16 value) { | |||
return (4000 <= value && value <= 12000); | |||
} | |||
void IZ_JoystickHandleDeviceEvents(IZ_JoystickState* state, SDL_Event e) { | |||
if (e.type == SDL_JOYDEVICEADDED) { | |||
if (SDL_NumJoysticks() <= IZ_PLAYERS && !state->device) { | |||
@@ -66,7 +72,7 @@ void IZ_JoystickHandleHatEvents(IZ_Action* action, SDL_Event e) { | |||
void IZ_JoystickHandleButtonEvents(IZ_JoystickState* state, IZ_Action* action, SDL_Event e) { | |||
u8 control_index; | |||
for (control_index = 4; control_index < CONTROLS; control_index += 1) { | |||
for (control_index = 4; control_index < IZ_CONTROLS; control_index += 1) { | |||
if (e.jbutton.button == state->config.control_mapping[control_index]) { | |||
const u16 bitflag = (0x1 << control_index); | |||
@@ -93,84 +99,100 @@ void IZ_JoystickHandleEvents(IZ_JoystickState(* state)[IZ_PLAYERS], IZ_Action(* | |||
} | |||
} | |||
void IZ_JoystickLoadConfig(IZ_JoystickState(* state)[IZ_PLAYERS], const char* config_path) { | |||
char control_mapping_section_name[26]; | |||
char main_section_name[11]; | |||
void IZ_JoystickBindStateToConfig(IZ_JoystickState(* state)[IZ_PLAYERS], IZ_ConfigItem config_items[]) { | |||
u8 player_index; | |||
u8 control_index; | |||
for (player_index = 0; player_index < IZ_PLAYERS; player_index += 1) { | |||
sprintf_s(control_mapping_section_name, 26, "Joystick.%d.ControlMapping", player_index); | |||
for (control_index = 4; control_index < CONTROLS; control_index += 1) { | |||
(*state)[player_index].config.control_mapping[control_index] = ini_getl( | |||
control_mapping_section_name, | |||
ACTION_NAMES[control_index], | |||
IZ_JOYSTICK_DEFAULT_STATE[player_index].config.control_mapping[control_index], | |||
config_path | |||
); | |||
u8 base_index = (player_index * (IZ_CONTROLS - 4 + 2)); | |||
config_items[base_index].dest = &((*state)[player_index].config.device_id); | |||
config_items[base_index + 1].dest = &((*state)[player_index].config.axis_threshold); | |||
for (control_index = 4; control_index < IZ_CONTROLS; control_index += 1) { | |||
config_items[base_index + 2 + (control_index - 4)].dest = &((*state)[player_index].config.control_mapping[control_index]); | |||
} | |||
sprintf_s(main_section_name, 11, "Joystick.%d", player_index); | |||
(*state)[player_index].config.axis_threshold = ini_getl(main_section_name, "AxisThreshold", IZ_DEFAULT_AXIS_THRESHOLD, config_path); | |||
(*state)[player_index].config.device_id = ini_getl(main_section_name, "DeviceID", player_index, config_path); | |||
} | |||
} | |||
IZ_ProcedureResult IZ_JoystickSaveConfig(IZ_JoystickState(* state)[IZ_PLAYERS], const char* config_path) { | |||
u8 problem = 0; | |||
char control_mapping_section_name[26]; | |||
char main_section_name[11]; | |||
IZ_JoystickBindStateToConfig(state, joystick_config_items); | |||
return IZ_ConfigSave(joystick_config_items, config_path); | |||
} | |||
void IZ_JoystickInitializeConfigItems(IZ_ConfigItem config_items[]) { | |||
u8 player_index; | |||
u8 control_index; | |||
char* main_section_name; | |||
char* control_mapping_section_name; | |||
for (player_index = 0; player_index < IZ_PLAYERS; player_index += 1) { | |||
sprintf_s(control_mapping_section_name, 26, "Joystick.%d.ControlMapping", player_index); | |||
for (control_index = 4; control_index < CONTROLS; control_index += 1) { | |||
if (!ini_putl( | |||
control_mapping_section_name, | |||
ACTION_NAMES[control_index], | |||
(*state)[player_index].config.control_mapping[control_index], | |||
config_path | |||
)) { | |||
problem |= (1 << player_index); | |||
} | |||
} | |||
sprintf_s(main_section_name, 11, "Joystick.%d", player_index); | |||
if (!ini_putl( | |||
main_section_name = SDL_malloc(sizeof(char) * 64); | |||
sprintf_s(main_section_name, 64, "Joystick.%d", player_index); | |||
u8 base_index = (player_index * (IZ_CONTROLS - 4 + 2)); | |||
config_items[base_index] = (IZ_ConfigItem) { | |||
IZ_CONFIG_TYPE_I32, | |||
sizeof(i32), | |||
main_section_name, | |||
"DeviceID", | |||
(*state)[player_index].config.device_id, | |||
config_path | |||
)) { | |||
problem |= (1 << player_index); | |||
} | |||
if (!ini_putl( | |||
NULL, | |||
&IZ_JOYSTICK_DEFAULT_STATE[player_index].config.device_id, | |||
NULL, | |||
NULL, | |||
}; | |||
config_items[base_index + 1] = (IZ_ConfigItem) { | |||
IZ_CONFIG_TYPE_U16, | |||
sizeof(u16), | |||
main_section_name, | |||
"AxisThreshold", | |||
(*state)[player_index].config.axis_threshold, | |||
config_path | |||
)) { | |||
problem |= (1 << player_index); | |||
NULL, | |||
&IZ_JOYSTICK_DEFAULT_STATE[player_index].config.axis_threshold, | |||
IZ_JoystickIsValidAxisThreshold, | |||
NULL, | |||
}; | |||
control_mapping_section_name = SDL_malloc(sizeof(char) * 64); | |||
sprintf_s(control_mapping_section_name, 64, "Joystick.%d.ControlMapping", player_index); | |||
for (control_index = 4; control_index < IZ_CONTROLS; control_index += 1) { | |||
config_items[base_index + 2 + (control_index - 4)] = (IZ_ConfigItem) { | |||
IZ_CONFIG_TYPE_U8, | |||
sizeof(u8), | |||
control_mapping_section_name, | |||
IZ_ACTION_NAMES[control_index], | |||
NULL, | |||
&IZ_JOYSTICK_DEFAULT_STATE[player_index].config.control_mapping[control_index], | |||
NULL, | |||
NULL, | |||
}; | |||
} | |||
} | |||
return -problem; | |||
config_items[IZ_PLAYERS * (IZ_CONTROLS - 4 + 2)] = (IZ_ConfigItem) { | |||
IZ_CONFIG_TYPE_VOID, | |||
0, | |||
NULL, | |||
NULL, | |||
NULL, | |||
NULL, | |||
NULL, | |||
NULL, | |||
}; | |||
} | |||
IZ_ProcedureResult IZ_JoystickInitialize(IZ_JoystickState(* state)[IZ_PLAYERS], const char* config_path, u8 argc, const char* argv[]) { | |||
SDL_memcpy(state, &IZ_JOYSTICK_DEFAULT_STATE, sizeof(IZ_JoystickState)); | |||
IZ_JoystickLoadConfig(state, config_path); | |||
if (IZ_JoystickSaveConfig(state, config_path) < 0) { | |||
IZ_ProcedureResult IZ_JoystickInitializeConfig(IZ_JoystickState(* state)[IZ_PLAYERS], const char* config_path, u8 argc, const char* argv[]) { | |||
IZ_JoystickInitializeConfigItems(joystick_config_items); | |||
IZ_JoystickBindStateToConfig(state, joystick_config_items); | |||
if (IZ_ConfigInitialize(joystick_config_items, config_path, argc, argv) < 0) { | |||
return -1; | |||
} | |||
return 0; | |||
} | |||
IZ_ProcedureResult IZ_JoystickInitialize(IZ_JoystickState(* state)[IZ_PLAYERS], const char* config_path, u8 argc, const char* argv[]) { | |||
SDL_memcpy(state, &IZ_JOYSTICK_DEFAULT_STATE, sizeof(IZ_JoystickState) * IZ_PLAYERS); | |||
if (IZ_JoystickInitializeConfig(state, config_path, argc, argv) < 0) { | |||
return -2; | |||
} | |||
u8 joysticks_count = SDL_NumJoysticks(); | |||
u8 player_index; | |||
u8 joysticks_count = SDL_NumJoysticks(); | |||
for (player_index = 0; player_index < joysticks_count; player_index += 1) { | |||
if (player_index >= IZ_PLAYERS) { | |||
break; | |||
@@ -5,6 +5,7 @@ | |||
#include <SDL_joystick.h> | |||
#include <SDL_events.h> | |||
#include <minIni.h> | |||
#include "../../config/IZ_config.h" | |||
#include "IZ_action.h" | |||
typedef u8 IZ_PadButton; | |||
@@ -21,7 +22,7 @@ typedef enum { | |||
typedef struct { | |||
u16 axis_threshold; | |||
SDL_JoystickID device_id; | |||
IZ_PadButton control_mapping[CONTROLS]; | |||
IZ_PadButton control_mapping[IZ_CONTROLS]; | |||
} IZ_JoystickConfig; | |||
typedef struct { | |||
@@ -55,6 +56,7 @@ static const IZ_JoystickState IZ_JOYSTICK_DEFAULT_STATE[IZ_PLAYERS] = { | |||
}, | |||
.device = NULL, | |||
}, | |||
#if IZ_PLAYERS > 1 | |||
{ | |||
.config = { | |||
.control_mapping = { | |||
@@ -80,6 +82,7 @@ static const IZ_JoystickState IZ_JOYSTICK_DEFAULT_STATE[IZ_PLAYERS] = { | |||
}, | |||
.device = NULL, | |||
}, | |||
#endif | |||
}; | |||
IZ_ProcedureResult IZ_JoystickSaveConfig(IZ_JoystickState(*)[IZ_PLAYERS], const char*); | |||
@@ -1,8 +1,19 @@ | |||
#include "IZ_keyboard.h" | |||
static IZ_ConfigItem keyboard_config_items[IZ_PLAYERS * IZ_CONTROLS + 1]; | |||
void IZ_KeyboardSerializeControl(i32 value, char control[128]) { | |||
const char* serialized = SDL_GetKeyName(value); | |||
memcpy_s(control, 128, serialized, 128); | |||
} | |||
i32 IZ_KeyboardDeserializeControl(const char* control) { | |||
return SDL_GetKeyFromName(control); | |||
} | |||
void IZ_KeyboardHandleKeyUpDownEvents(IZ_KeyboardState* state, IZ_Action* action, SDL_Event e) { | |||
u8 control_index; | |||
for (control_index = 0; control_index < CONTROLS; control_index += 1) { | |||
for (control_index = 0; control_index < IZ_CONTROLS; control_index += 1) { | |||
if (e.key.keysym.sym == state->config.control_mapping[control_index]) { | |||
const u16 bitflag = (0x1 << control_index); | |||
if (e.type == SDL_KEYDOWN) { | |||
@@ -23,54 +34,63 @@ void IZ_KeyboardHandleEvents(IZ_KeyboardState(* state)[IZ_PLAYERS], IZ_Action(* | |||
} | |||
} | |||
IZ_ProcedureResult IZ_KeyboardSaveConfig(IZ_KeyboardState(* state)[IZ_PLAYERS], const char* config_path) { | |||
u8 problem = 0; | |||
char control_mapping_section_name[26]; | |||
void IZ_KeyboardBindStateToConfig(IZ_KeyboardState(* state)[IZ_PLAYERS], IZ_ConfigItem config_items[]) { | |||
u8 player_index; | |||
u8 control_index; | |||
for (player_index = 0; player_index < IZ_PLAYERS; player_index += 1) { | |||
sprintf_s(control_mapping_section_name, 26, "Keyboard.%d.ControlMapping", player_index); | |||
for (control_index = 0; control_index < CONTROLS; control_index += 1) { | |||
if (!ini_puts( | |||
control_mapping_section_name, | |||
ACTION_NAMES[control_index], | |||
SDL_GetKeyName((*state)[player_index].config.control_mapping[control_index]), | |||
config_path | |||
)) { | |||
problem |= (1 << player_index); | |||
} | |||
for (control_index = 0; control_index < IZ_CONTROLS; control_index += 1) { | |||
config_items[player_index * IZ_CONTROLS + control_index].dest = &((*state)[player_index].config.control_mapping[control_index]); | |||
} | |||
} | |||
return problem; | |||
} | |||
void IZ_KeyboardLoadConfig(IZ_KeyboardState(* state)[IZ_PLAYERS], const char* config_path) { | |||
char buffer[128]; | |||
char keyboard_section_name[26]; | |||
IZ_ProcedureResult IZ_KeyboardSaveConfig(IZ_KeyboardState(* state)[IZ_PLAYERS], const char* config_path) { | |||
IZ_KeyboardBindStateToConfig(state, keyboard_config_items); | |||
return IZ_ConfigSave(keyboard_config_items, config_path); | |||
} | |||
void IZ_KeyboardInitializeConfigItems(IZ_ConfigItem config_items[]) { | |||
u8 player_index; | |||
u8 control_index; | |||
char* control_mapping_section_name; | |||
for (player_index = 0; player_index < IZ_PLAYERS; player_index += 1) { | |||
sprintf_s(keyboard_section_name, 26, "Keyboard.%d.ControlMapping", player_index); | |||
for (control_index = 0; control_index < CONTROLS; control_index += 1) { | |||
ini_gets( | |||
keyboard_section_name, | |||
ACTION_NAMES[control_index], | |||
SDL_GetKeyName(IZ_KEYBOARD_DEFAULT_STATE[player_index].config.control_mapping[control_index]), | |||
buffer, | |||
128, | |||
config_path | |||
); | |||
(*state)[player_index].config.control_mapping[control_index] = SDL_GetKeyFromName(buffer); | |||
control_mapping_section_name = SDL_malloc(sizeof(char) * 64); | |||
sprintf_s(control_mapping_section_name, 64, "Keyboard.%d.ControlMapping", player_index); | |||
for (control_index = 0; control_index < IZ_CONTROLS; control_index += 1) { | |||
config_items[player_index * IZ_CONTROLS + control_index] = (IZ_ConfigItem) { | |||
IZ_CONFIG_TYPE_I32, | |||
sizeof(i32), | |||
control_mapping_section_name, | |||
IZ_ACTION_NAMES[control_index], | |||
NULL, | |||
&IZ_KEYBOARD_DEFAULT_STATE[player_index].config.control_mapping[control_index], | |||
NULL, | |||
{ | |||
.serialize = IZ_KeyboardSerializeControl, | |||
.deserialize = IZ_KeyboardDeserializeControl, | |||
}, | |||
NULL, | |||
}; | |||
} | |||
} | |||
config_items[IZ_PLAYERS * IZ_CONTROLS] = IZ_CONFIG_ITEM_NULL; | |||
} | |||
IZ_ProcedureResult IZ_KeyboardInitializeConfig(IZ_KeyboardState(* state)[IZ_PLAYERS], const char* config_path, u8 argc, const char* argv[]) { | |||
IZ_KeyboardInitializeConfigItems(keyboard_config_items); | |||
IZ_KeyboardBindStateToConfig(state, keyboard_config_items); | |||
if (IZ_ConfigInitialize(keyboard_config_items, config_path, argc, argv) < 0) { | |||
return -1; | |||
} | |||
return 0; | |||
} | |||
IZ_ProcedureResult IZ_KeyboardInitialize(IZ_KeyboardState(* state)[IZ_PLAYERS], const char* config_path, u8 argc, const char* argv[]) { | |||
SDL_memcpy(state, &IZ_KEYBOARD_DEFAULT_STATE, sizeof(IZ_KeyboardState)); | |||
IZ_KeyboardLoadConfig(state, config_path); | |||
return IZ_KeyboardSaveConfig(state, config_path); | |||
SDL_memcpy(state, &IZ_KEYBOARD_DEFAULT_STATE, sizeof(IZ_KeyboardState) * IZ_PLAYERS); | |||
if (IZ_KeyboardInitializeConfig(state, config_path, argc, argv) < 0) { | |||
return -2; | |||
} | |||
return 0; | |||
} |
@@ -5,10 +5,11 @@ | |||
#include <SDL_keyboard.h> | |||
#include <SDL_events.h> | |||
#include <minIni.h> | |||
#include "../../config/IZ_config.h" | |||
#include "IZ_action.h" | |||
typedef struct { | |||
SDL_KeyCode control_mapping[CONTROLS]; | |||
SDL_KeyCode control_mapping[IZ_CONTROLS]; | |||
} IZ_KeyboardConfig; | |||
typedef struct { | |||
@@ -38,6 +39,7 @@ static const IZ_KeyboardState IZ_KEYBOARD_DEFAULT_STATE[IZ_PLAYERS] = { | |||
}, | |||
}, | |||
}, | |||
#if IZ_PLAYERS > 1 | |||
{ | |||
.config = { | |||
.control_mapping = { | |||
@@ -60,6 +62,7 @@ static const IZ_KeyboardState IZ_KEYBOARD_DEFAULT_STATE[IZ_PLAYERS] = { | |||
}, | |||
}, | |||
}, | |||
#endif | |||
}; | |||
IZ_ProcedureResult IZ_KeyboardSaveConfig(IZ_KeyboardState(*)[IZ_PLAYERS], const char*); | |||
@@ -1,5 +1,20 @@ | |||
#include "IZ_midi.h" | |||
static IZ_ConfigItem midi_input_config_items[(IZ_PLAYERS * (IZ_CONTROLS + 2)) + 1]; | |||
bool IZ_MIDIInputIsValidChannel(u8 value) { | |||
return (0 <= value && value <= 15); | |||
} | |||
void IZ_MIDIInputSerializeControl(i32 value, char* control[128]) { | |||
const char* serialized = IZ_MIDIGetNoteName(value); | |||
memcpy_s(control, 128, serialized, 128); | |||
} | |||
i32 IZ_MIDIInputDeserializeControl(const char* control) { | |||
return IZ_MIDIGetNoteFromName(control); | |||
} | |||
void IZ_MIDIInputHandleNoteOnOffEvents(IZ_MIDIInputState* state, IZ_Action* action, PmEvent e) { | |||
u32 message = e.message; | |||
u8 status = message & 0xF0u; | |||
@@ -8,7 +23,7 @@ void IZ_MIDIInputHandleNoteOnOffEvents(IZ_MIDIInputState* state, IZ_Action* acti | |||
// u8 data2 = (message >> 16) & 0xFFu; | |||
u8 control_index; | |||
for (control_index = 0; control_index < CONTROLS; control_index += 1) { | |||
for (control_index = 0; control_index < IZ_CONTROLS; control_index += 1) { | |||
if ( | |||
data1 == state->config.control_mapping[control_index] | |||
&& ( | |||
@@ -36,87 +51,105 @@ void IZ_MIDIInputHandleEvents(IZ_MIDIInputState(* state)[IZ_PLAYERS], IZ_Action( | |||
} | |||
} | |||
IZ_ProcedureResult IZ_MIDIInputSaveConfig(IZ_MIDIInputState(* state)[IZ_PLAYERS], const char* config_path) { | |||
u8 problem = 0; | |||
char control_mapping_section_name[27]; | |||
char main_section_name[12]; | |||
void IZ_MIDIInputBindStateToConfig(IZ_MIDIInputState(* state)[IZ_PLAYERS], IZ_ConfigItem config_items[]) { | |||
u8 player_index; | |||
u8 control_index; | |||
for (player_index = 0; player_index < IZ_PLAYERS; player_index += 1) { | |||
sprintf_s(control_mapping_section_name, 27, "MIDIInput.%d.ControlMapping", player_index); | |||
for (control_index = 0; control_index < CONTROLS; control_index += 1) { | |||
if (!ini_puts( | |||
control_mapping_section_name, | |||
ACTION_NAMES[control_index], | |||
IZ_MIDIGetNoteName((*state)[player_index].config.control_mapping[control_index]), | |||
config_path | |||
)) { | |||
problem |= (1 << player_index); | |||
} | |||
} | |||
sprintf_s(main_section_name, 12, "MIDIInput.%d", player_index); | |||
if (!ini_putl( | |||
main_section_name, | |||
"Channel", | |||
(*state)[player_index].config.channel, | |||
config_path | |||
)) { | |||
problem |= (1 << player_index); | |||
} | |||
if (!ini_putl( | |||
main_section_name, | |||
"DeviceID", | |||
(*state)[player_index].config.device_id, | |||
config_path | |||
)) { | |||
problem |= (1 << player_index); | |||
u8 base_index = (player_index * (IZ_CONTROLS + 2)); | |||
config_items[base_index].dest = &((*state)[player_index].config.device_id); | |||
config_items[base_index + 1].dest = &((*state)[player_index].config.channel); | |||
for (control_index = 0; control_index < IZ_CONTROLS; control_index += 1) { | |||
config_items[base_index + 2 + control_index].dest = &((*state)[player_index].config.control_mapping[control_index]); | |||
} | |||
} | |||
return problem; | |||
} | |||
void IZ_MIDIInputLoadConfig(IZ_MIDIInputState(* state)[IZ_PLAYERS], const char* config_path) { | |||
char buffer[128]; | |||
char control_mapping_section_name[27]; | |||
char main_section_name[12]; | |||
IZ_ProcedureResult IZ_MIDIInputSaveConfig(IZ_MIDIInputState(* state)[IZ_PLAYERS], const char* config_path) { | |||
IZ_MIDIInputBindStateToConfig(state, midi_input_config_items); | |||
return IZ_ConfigSave(midi_input_config_items, config_path); | |||
} | |||
void IZ_MIDIInputInitializeConfigItems(IZ_ConfigItem config_items[]) { | |||
u8 player_index; | |||
u8 control_index; | |||
char* main_section_name; | |||
char* control_mapping_section_name; | |||
for (player_index = 0; player_index < IZ_PLAYERS; player_index += 1) { | |||
sprintf_s(control_mapping_section_name, 27, "MIDIInput.%d.ControlMapping", player_index); | |||
for (control_index = 0; control_index < CONTROLS; control_index += 1) { | |||
ini_gets( | |||
main_section_name = SDL_malloc(sizeof(char) * 64); | |||
sprintf_s(main_section_name, 64, "MIDIInput.%d", player_index); | |||
u16 base_index = (player_index * (IZ_CONTROLS + 2)); | |||
config_items[base_index] = (IZ_ConfigItem) { | |||
IZ_CONFIG_TYPE_I32, | |||
sizeof(i32), | |||
main_section_name, | |||
"DeviceID", | |||
NULL, | |||
&IZ_MIDI_INPUT_DEFAULT_STATE[player_index].config.device_id, | |||
NULL, | |||
{ | |||
.serialize = NULL, | |||
.deserialize = NULL, | |||
}, | |||
NULL, | |||
}; | |||
config_items[base_index + 1] = (IZ_ConfigItem) { | |||
IZ_CONFIG_TYPE_U8, | |||
sizeof(u8), | |||
main_section_name, | |||
"Channel", | |||
NULL, | |||
&IZ_MIDI_INPUT_DEFAULT_STATE[player_index].config.channel, | |||
IZ_MIDIInputIsValidChannel, | |||
{ | |||
.serialize = NULL, | |||
.deserialize = NULL, | |||
}, | |||
NULL, | |||
}; | |||
control_mapping_section_name = SDL_malloc(sizeof(char) * 64); | |||
sprintf_s(control_mapping_section_name, 64, "MIDIInput.%d.ControlMapping", player_index); | |||
for (control_index = 0; control_index < IZ_CONTROLS; control_index += 1) { | |||
config_items[base_index + 2 + control_index] = (IZ_ConfigItem) { | |||
IZ_CONFIG_TYPE_U8, | |||
sizeof(u8), | |||
control_mapping_section_name, | |||
ACTION_NAMES[control_index], | |||
IZ_MIDIGetNoteName(IZ_MIDI_INPUT_DEFAULT_STATE[player_index].config.control_mapping[control_index]), | |||
buffer, | |||
128, | |||
config_path | |||
); | |||
(*state)[player_index].config.control_mapping[control_index] = IZ_MIDIGetNoteFromName(buffer); | |||
IZ_ACTION_NAMES[control_index], | |||
NULL, | |||
&IZ_MIDI_INPUT_DEFAULT_STATE[player_index].config.control_mapping[control_index], | |||
NULL, | |||
{ | |||
.serialize = IZ_MIDIInputSerializeControl, | |||
.deserialize = IZ_MIDIInputDeserializeControl, | |||
}, | |||
NULL, | |||
}; | |||
} | |||
} | |||
sprintf_s(main_section_name, 12, "MIDIInput.%d", player_index); | |||
(*state)[player_index].config.channel = ini_getl(main_section_name, "Channel", player_index, config_path); | |||
(*state)[player_index].config.device_id = ini_getl(main_section_name, "DeviceID", player_index, config_path); | |||
config_items[IZ_PLAYERS * (IZ_CONTROLS + 2)] = IZ_CONFIG_ITEM_NULL; | |||
} | |||
IZ_ProcedureResult IZ_MIDIInputInitializeConfig(IZ_MIDIInputState(* state)[IZ_PLAYERS], const char* config_path, u8 argc, const char* argv[]) { | |||
IZ_MIDIInputInitializeConfigItems(midi_input_config_items); | |||
IZ_MIDIInputBindStateToConfig(state, midi_input_config_items); | |||
if (IZ_ConfigInitialize(midi_input_config_items, config_path, argc, argv) < 0) { | |||
return -1; | |||
} | |||
return 0; | |||
} | |||
IZ_ProcedureResult IZ_MIDIInputInitialize(IZ_MIDIInputState(* state)[IZ_PLAYERS], const char* config_path, u8 argc, const char* argv[]) { | |||
if (Pm_Initialize()) { | |||
return 1; | |||
return -1; | |||
} | |||
SDL_memcpy(state, &IZ_MIDI_INPUT_DEFAULT_STATE, sizeof(IZ_MIDIInputState)); | |||
IZ_MIDIInputLoadConfig(state, config_path); | |||
if (IZ_MIDIInputSaveConfig(state, config_path)) { | |||
return 2; | |||
SDL_memcpy(state, &IZ_MIDI_INPUT_DEFAULT_STATE, sizeof(IZ_MIDIInputState) * IZ_PLAYERS); | |||
if (IZ_MIDIInputInitializeConfig(state, config_path, argc, argv) < 0) { | |||
return -2; | |||
} | |||
u8 player_index; | |||
@@ -10,15 +10,16 @@ | |||
#endif | |||
#include <minIni.h> | |||
#include "IZ_action.h" | |||
#include "../../config/IZ_config.h" | |||
#include "../util/IZ_midi.h" | |||
#include "IZ_action.h" | |||
#define MIDI_EVENT_BUFFER_SIZE 1024 | |||
typedef struct { | |||
PmDeviceID device_id; | |||
u8 channel; | |||
IZ_MIDINote control_mapping[CONTROLS]; | |||
IZ_MIDINote control_mapping[IZ_CONTROLS]; | |||
} IZ_MIDIInputConfig; | |||
typedef struct { | |||
@@ -57,6 +58,7 @@ static const IZ_MIDIInputState IZ_MIDI_INPUT_DEFAULT_STATE[IZ_PLAYERS] = { | |||
.stream = NULL, | |||
.device_info = NULL, | |||
}, | |||
#if IZ_PLAYERS > 1 | |||
{ | |||
.config = { | |||
.control_mapping = { | |||
@@ -84,6 +86,7 @@ static const IZ_MIDIInputState IZ_MIDI_INPUT_DEFAULT_STATE[IZ_PLAYERS] = { | |||
.stream = NULL, | |||
.device_info = NULL, | |||
}, | |||
#endif | |||
}; | |||
IZ_ProcedureResult IZ_MIDIInputSaveConfig(IZ_MIDIInputState(*)[IZ_PLAYERS], const char*); | |||
@@ -48,7 +48,7 @@ spec("input") { | |||
} | |||
it("calls load method") { | |||
mock_set_expected_calls(ini_getl, ((CONTROLS - 4) + 2) * IZ_PLAYERS); | |||
mock_set_expected_calls(ini_getl, ((IZ_CONTROLS - 4) + 2) * IZ_PLAYERS); | |||
IZ_JoystickInitialize(&state, "config-game.ini", 0, NULL); | |||
@@ -61,7 +61,7 @@ spec("input") { | |||
} | |||
it("calls save method") { | |||
mock_set_expected_calls(ini_putl, ((CONTROLS - 4) + 2) * IZ_PLAYERS); | |||
mock_set_expected_calls(ini_putl, ((IZ_CONTROLS - 4) + 2) * IZ_PLAYERS); | |||
IZ_JoystickInitialize(&state, "config-game.ini", 0, NULL); | |||
@@ -276,7 +276,7 @@ spec("input") { | |||
} | |||
for (u8 i = 0; i < 4; i += 1) { | |||
it("handles motion for %s action", ACTION_NAMES[i]) { | |||
it("handles motion for %s action", IZ_ACTION_NAMES[i]) { | |||
e.jhat.value = (0x1u << i); | |||
action[p] = 0; | |||
@@ -287,7 +287,7 @@ spec("input") { | |||
); | |||
} | |||
it("handles motion for %s deactivation", ACTION_NAMES[i]) { | |||
it("handles motion for %s deactivation", IZ_ACTION_NAMES[i]) { | |||
e.jhat.value = 0; | |||
action[p] = ~0; | |||
@@ -301,8 +301,8 @@ spec("input") { | |||
} | |||
describe("on button events") { | |||
for (u8 i = 4; i < CONTROLS; i += 1) { | |||
it("handles %s action activation", ACTION_NAMES[i]) { | |||
for (u8 i = 4; i < IZ_CONTROLS; i += 1) { | |||
it("handles %s action activation", IZ_ACTION_NAMES[i]) { | |||
e.type = SDL_JOYBUTTONDOWN; | |||
e.jbutton.button = IZ_JOYSTICK_DEFAULT_STATE[p].config.control_mapping[i]; | |||
state[p].config.control_mapping[i] = IZ_JOYSTICK_DEFAULT_STATE[p].config.control_mapping[i]; | |||
@@ -315,7 +315,7 @@ spec("input") { | |||
); | |||
} | |||
it("handles %s action deactivation", ACTION_NAMES[i]) { | |||
it("handles %s action deactivation", IZ_ACTION_NAMES[i]) { | |||
e.type = SDL_JOYBUTTONUP; | |||
e.jbutton.button = IZ_JOYSTICK_DEFAULT_STATE[p].config.control_mapping[i]; | |||
state[p].config.control_mapping[i] = IZ_JOYSTICK_DEFAULT_STATE[p].config.control_mapping[i]; | |||
@@ -342,14 +342,14 @@ spec("input") { | |||
before_each() { | |||
for (u8 p = 0; p < IZ_PLAYERS; p += 1) { | |||
for (u8 i = 0; i < CONTROLS; i += 1) { | |||
for (u8 i = 0; i < IZ_CONTROLS; i += 1) { | |||
state[p].config.control_mapping[i] = IZ_JOYSTICK_DEFAULT_STATE[p].config.control_mapping[i]; | |||
} | |||
} | |||
} | |||
it("calls save method") { | |||
mock_set_expected_calls(ini_putl, ((CONTROLS - 4) + 2) * IZ_PLAYERS); | |||
mock_set_expected_calls(ini_putl, ((IZ_CONTROLS - 4) + 2) * IZ_PLAYERS); | |||
IZ_JoystickSaveConfig(&state, "config-game.ini"); | |||
@@ -409,7 +409,7 @@ spec("input") { | |||
before_each() { | |||
for (u8 p = 0; p < IZ_PLAYERS; p += 1) { | |||
for (u8 i = 0; i < CONTROLS; i += 1) { | |||
for (u8 i = 0; i < IZ_CONTROLS; i += 1) { | |||
state[p].config.control_mapping[i] = IZ_KEYBOARD_DEFAULT_STATE[p].config.control_mapping[i]; | |||
} | |||
} | |||
@@ -422,7 +422,7 @@ spec("input") { | |||
} | |||
it("calls load method") { | |||
mock_set_expected_calls(ini_gets, CONTROLS * IZ_PLAYERS); | |||
mock_set_expected_calls(ini_gets, IZ_CONTROLS * IZ_PLAYERS); | |||
IZ_KeyboardInitialize(&state, "config-game.ini", 0, NULL); | |||
@@ -435,7 +435,7 @@ spec("input") { | |||
} | |||
it("calls save method") { | |||
mock_set_expected_calls(ini_puts, CONTROLS * IZ_PLAYERS); | |||
mock_set_expected_calls(ini_puts, IZ_CONTROLS * IZ_PLAYERS); | |||
IZ_KeyboardInitialize(&state, "config-game.ini", 0, NULL); | |||
@@ -455,8 +455,8 @@ spec("input") { | |||
for (u8 p = 0; p < IZ_PLAYERS; p += 1) { | |||
describe("on player %u", p) { | |||
for (u8 i = 0; i < CONTROLS; i += 1) { | |||
it("handles %s action activation", ACTION_NAMES[i]) { | |||
for (u8 i = 0; i < IZ_CONTROLS; i += 1) { | |||
it("handles %s action activation", IZ_ACTION_NAMES[i]) { | |||
e.type = SDL_KEYDOWN; | |||
e.key.keysym.sym = IZ_KEYBOARD_DEFAULT_STATE[p].config.control_mapping[i]; | |||
state[p].config.control_mapping[i] = IZ_KEYBOARD_DEFAULT_STATE[p].config.control_mapping[i]; | |||
@@ -469,7 +469,7 @@ spec("input") { | |||
); | |||
} | |||
it("handles %s action deactivation", ACTION_NAMES[i]) { | |||
it("handles %s action deactivation", IZ_ACTION_NAMES[i]) { | |||
e.type = SDL_KEYUP; | |||
e.key.keysym.sym = IZ_KEYBOARD_DEFAULT_STATE[p].config.control_mapping[i]; | |||
state[p].config.control_mapping[i] = IZ_KEYBOARD_DEFAULT_STATE[p].config.control_mapping[i]; | |||
@@ -495,14 +495,14 @@ spec("input") { | |||
before_each() { | |||
for (u8 p = 0; p < IZ_PLAYERS; p += 1) { | |||
for (u8 i = 0; i < CONTROLS; i += 1) { | |||
for (u8 i = 0; i < IZ_CONTROLS; i += 1) { | |||
state[p].config.control_mapping[i] = IZ_KEYBOARD_DEFAULT_STATE[p].config.control_mapping[i]; | |||
} | |||
} | |||
} | |||
it("calls save method") { | |||
mock_set_expected_calls(ini_puts, CONTROLS * IZ_PLAYERS); | |||
mock_set_expected_calls(ini_puts, IZ_CONTROLS * IZ_PLAYERS); | |||
IZ_KeyboardSaveConfig("config-game.ini", &state); | |||
@@ -556,7 +556,7 @@ spec("input") { | |||
} | |||
it("calls load method") { | |||
mock_set_expected_calls(ini_gets, CONTROLS * IZ_PLAYERS); | |||
mock_set_expected_calls(ini_gets, IZ_CONTROLS * IZ_PLAYERS); | |||
mock_set_expected_calls(ini_getl, 2 * IZ_PLAYERS); | |||
IZ_MIDIInputInitialize(&state, "config-game.ini", 0, NULL); | |||
@@ -577,7 +577,7 @@ spec("input") { | |||
} | |||
it("calls save method") { | |||
mock_set_expected_calls(ini_puts, CONTROLS * IZ_PLAYERS); | |||
mock_set_expected_calls(ini_puts, IZ_CONTROLS * IZ_PLAYERS); | |||
mock_set_expected_calls(ini_putl, 2 * IZ_PLAYERS); | |||
IZ_MIDIInputInitialize(&state, "config-game.ini", 0, NULL); | |||
@@ -623,7 +623,7 @@ spec("input") { | |||
} | |||
it("calls save method") { | |||
mock_set_expected_calls(ini_puts, CONTROLS * IZ_PLAYERS); | |||
mock_set_expected_calls(ini_puts, IZ_CONTROLS * IZ_PLAYERS); | |||
mock_set_expected_calls(ini_putl, 2 * IZ_PLAYERS); | |||
IZ_MIDIInputSaveConfig("config-game.ini", &state); | |||
@@ -651,8 +651,8 @@ spec("input") { | |||
for (u8 p = 0; p < IZ_PLAYERS; p += 1) { | |||
describe("on player %u", p) { | |||
for (u8 i = 0; i < CONTROLS; i += 1) { | |||
it("handles %s action activation", ACTION_NAMES[i]) { | |||
for (u8 i = 0; i < IZ_CONTROLS; i += 1) { | |||
it("handles %s action activation", IZ_ACTION_NAMES[i]) { | |||
e.message = IZ_MIDI_NOTE_ON | (IZ_MIDI_INPUT_DEFAULT_STATE[p].config.control_mapping[i] << 8); | |||
state[p].config.control_mapping[i] = IZ_MIDI_INPUT_DEFAULT_STATE[p].config.control_mapping[i]; | |||
action[p] = 0; | |||
@@ -664,7 +664,7 @@ spec("input") { | |||
); | |||
} | |||
it("handles %s action deactivation", ACTION_NAMES[i]) { | |||
it("handles %s action deactivation", IZ_ACTION_NAMES[i]) { | |||
e.message = IZ_MIDI_NOTE_OFF | (IZ_MIDI_INPUT_DEFAULT_STATE[p].config.control_mapping[i] << 8); | |||
state[p].config.control_mapping[i] = IZ_MIDI_INPUT_DEFAULT_STATE[p].config.control_mapping[i]; | |||
action[p] = ~0; | |||
@@ -42,6 +42,7 @@ static IZ_ConfigItem video_config_items[] = { | |||
&IZ_VIDEO_DEFAULT_STATE.config.max_fps, | |||
IZ_VideoIsValidMaxFPS, | |||
}, | |||
IZ_CONFIG_ITEM_NULL, | |||
}; | |||
void IZ_VideoBindStateToConfig(IZ_VideoState* state, IZ_ConfigItem config_items[]) { | |||
@@ -55,10 +56,20 @@ IZ_ProcedureResult IZ_VideoSaveConfig(IZ_VideoState* state, const char* config_p | |||
return IZ_ConfigSave(video_config_items, config_path); | |||
} | |||
IZ_ProcedureResult IZ_VideoInitializeConfig(IZ_VideoState* state, const char* config_path, u8 argc, const char* argv[]) { | |||
IZ_VideoBindStateToConfig(state, video_config_items); | |||
if (IZ_ConfigInitialize(video_config_items, config_path, argc, argv) < 0) { | |||
return -1; | |||
} | |||
return 0; | |||
} | |||
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); | |||
if (IZ_VideoInitializeConfig(state, config_path, argc, argv) < 0) { | |||
return -2; | |||
} | |||
state->last_update_at = 0u; | |||
state->user_data = user_data; | |||
@@ -72,7 +83,7 @@ IZ_ProcedureResult IZ_VideoInitialize(IZ_VideoState* state, void* user_data, con | |||
); | |||
if (window == NULL) { | |||
// fprintf_s(stderr, "Window could not be created! SDL_Error: %s\n", SDL_GetError()); | |||
return 1; | |||
return -3; | |||
} | |||
state->window = window; | |||
state->renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); | |||
@@ -23,7 +23,7 @@ char* IZ_MIDIGetNoteName(u8 midi_note) { | |||
return note_name; | |||
} | |||
u8 IZ_MIDIGetNoteFromName(char* name) { | |||
u8 IZ_MIDIGetNoteFromName(const char* name) { | |||
char name_copy[8]; | |||
memcpy_s(name_copy, 8, name, 8); | |||
_strlwr_s(name_copy, 8); | |||
@@ -13,6 +13,6 @@ static const u8 IZ_MIDI_NOTE_OFF = 0x80u; | |||
char* IZ_MIDIGetNoteName(u8); | |||
u8 IZ_MIDIGetNoteFromName(char*); | |||
u8 IZ_MIDIGetNoteFromName(const char*); | |||
#endif |
@@ -12,55 +12,87 @@ bool IZ_NetClientIsValidReconnectIntervalSeconds(long reconnect_interval_secs) { | |||
return (3 <= reconnect_interval_secs && reconnect_interval_secs <= 10); | |||
} | |||
static IZ_ConfigItem net_config_items[] = { | |||
{ | |||
IZ_CONFIG_TYPE_STRING, | |||
32, | |||
"Network", | |||
"Username", | |||
NULL, | |||
&IZ_NET_CLIENT_DEFAULT_STATE.config.username, | |||
NULL | |||
}, | |||
{ | |||
static IZ_ConfigItem net_client_config_items[IZ_PLAYERS + 3]; | |||
void IZ_NetClientInitializeConfigItems(IZ_ConfigItem config_items[]) { | |||
config_items[0] = (IZ_ConfigItem) { | |||
IZ_CONFIG_TYPE_U16, | |||
sizeof(u16), | |||
"Network", | |||
"PacketIntervalMs", | |||
"-i", | |||
&IZ_NET_CLIENT_DEFAULT_STATE.config.packet_interval_ms, | |||
IZ_NetClientIsValidPacketIntervalMs, | |||
}, | |||
{ | |||
sizeof(u16), | |||
"Network", | |||
"PacketIntervalMs", | |||
"-i", | |||
&IZ_NET_CLIENT_DEFAULT_STATE.config.packet_interval_ms, | |||
IZ_NetClientIsValidPacketIntervalMs, | |||
NULL, | |||
}; | |||
config_items[1] = (IZ_ConfigItem) { | |||
IZ_CONFIG_TYPE_U8, | |||
sizeof(u8), | |||
"Network", | |||
"MaxReconnectRetries", | |||
NULL, | |||
&IZ_NET_CLIENT_DEFAULT_STATE.config.max_reconnect_retries, | |||
IZ_NetClientIsValidMaxReconnectRetries, | |||
}, | |||
{ | |||
sizeof(u8), | |||
"Network", | |||
"MaxReconnectRetries", | |||
NULL, | |||
&IZ_NET_CLIENT_DEFAULT_STATE.config.max_reconnect_retries, | |||
IZ_NetClientIsValidMaxReconnectRetries, | |||
NULL, | |||
}; | |||
config_items[2] = (IZ_ConfigItem) { | |||
IZ_CONFIG_TYPE_U8, | |||
sizeof(u8), | |||
"Network", | |||
"ReconnectIntervalSeconds", | |||
NULL, | |||
&IZ_NET_CLIENT_DEFAULT_STATE.config.reconnect_interval_secs, | |||
IZ_NetClientIsValidReconnectIntervalSeconds, | |||
}, | |||
}; | |||
sizeof(u8), | |||
"Network", | |||
"ReconnectIntervalSeconds", | |||
NULL, | |||
&IZ_NET_CLIENT_DEFAULT_STATE.config.reconnect_interval_secs, | |||
IZ_NetClientIsValidReconnectIntervalSeconds, | |||
NULL, | |||
}; | |||
u8 player_index; | |||
char* main_section_name; | |||
for (player_index = 0; player_index < IZ_PLAYERS; player_index += 1) { | |||
main_section_name = malloc(sizeof(char) * 64); | |||
sprintf_s(main_section_name, 64, "Network.%d", player_index); | |||
config_items[3 + player_index] = (IZ_ConfigItem) { | |||
IZ_CONFIG_TYPE_STRING, | |||
32, | |||
main_section_name, | |||
"Username", | |||
NULL, | |||
&IZ_NET_CLIENT_DEFAULT_STATE.config.usernames[player_index], | |||
NULL, | |||
NULL, | |||
}; | |||
} | |||
config_items[3 + IZ_PLAYERS] = IZ_CONFIG_ITEM_NULL; | |||
} | |||
void IZ_NetClientBindStateToConfig(IZ_NetClientState* 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; | |||
config_items[0].dest = &state->config.packet_interval_ms; | |||
config_items[1].dest = &state->config.max_reconnect_retries; | |||
config_items[2].dest = &state->config.reconnect_interval_secs; | |||
u8 player_index; | |||
for (player_index = 0; player_index < IZ_PLAYERS; player_index += 1) { | |||
config_items[3 + player_index].dest = &state->config.usernames[player_index]; | |||
} | |||
} | |||
IZ_ProcedureResult IZ_NetClientSaveConfig(IZ_NetClientState* state, const char* config_path) { | |||
IZ_NetClientBindStateToConfig(state, net_config_items); | |||
return IZ_ConfigSave(net_config_items, config_path); | |||
IZ_NetClientBindStateToConfig(state, net_client_config_items); | |||
return IZ_ConfigSave(net_client_config_items, config_path); | |||
} | |||
IZ_ProcedureResult IZ_NetClientInitializeConfig( | |||
IZ_NetClientState* state, | |||
const char* config_path, | |||
u8 argc, | |||
const char* argv[] | |||
) { | |||
IZ_NetClientInitializeConfigItems(net_client_config_items); | |||
IZ_NetClientBindStateToConfig(state, net_client_config_items); | |||
if (IZ_ConfigInitialize(net_client_config_items, config_path, argc, argv) < 0) { | |||
return -1; | |||
} | |||
return 0; | |||
} | |||
IZ_ProcedureResult IZ_NetClientInitialize( | |||
@@ -71,10 +103,11 @@ IZ_ProcedureResult IZ_NetClientInitialize( | |||
u8 argc, | |||
const char* argv[] | |||
) { | |||
memcpy_s(state, sizeof(IZ_NetClientState), &IZ_NET_CLIENT_DEFAULT_STATE, sizeof(IZ_NetClientState)); | |||
IZ_NetClientBindStateToConfig(state, net_config_items); | |||
IZ_ConfigInit(net_config_items, config_path, argc, argv); | |||
if (!user_data) { | |||
return -1; | |||
} | |||
memcpy_s(state, sizeof(IZ_NetClientState), &IZ_NET_CLIENT_DEFAULT_STATE, sizeof(IZ_NetClientState)); | |||
if (IZ_NetClientInitializeConfig(state, config_path, argc, argv) < 0) { | |||
return -2; | |||
} | |||
state->binding.user_data = user_data; | |||
@@ -19,7 +19,7 @@ typedef struct { | |||
u16 packet_interval_ms; | |||
u8 max_reconnect_retries; | |||
u8 reconnect_interval_secs; | |||
char username[32]; | |||
char usernames[IZ_PLAYERS][32]; | |||
} IZ_NetClientConfig; | |||
typedef struct { | |||
@@ -40,7 +40,12 @@ static IZ_NetClientState IZ_NET_CLIENT_DEFAULT_STATE = { | |||
.packet_interval_ms = 200, | |||
.max_reconnect_retries = 3, | |||
.reconnect_interval_secs = 3, | |||
.username = "Player", | |||
.usernames = { | |||
"Player 1", | |||
#if IZ_PLAYERS > 1 | |||
"Player 2" | |||
#endif | |||
}, | |||
}, | |||
.binding = { | |||
.interrupted = false, | |||
@@ -1,54 +1,79 @@ | |||
#include "IZ_net_server.h" | |||
void IZ_NetLoadConfig(IZ_NetServerState* state, const char* config_path) { | |||
char buffer[128]; | |||
ini_gets("Network", "Name", IZ_NET_SERVER_DEFAULT_STATE.config.name, buffer, 128, config_path); | |||
memcpy_s(state->config.name, 64, buffer, 64); | |||
bool IZ_NetServerIsValidPort(u16 port) { | |||
return (1000 <= port && port <= 59999); | |||
} | |||
ini_gets("Network", "Motd", IZ_NET_SERVER_DEFAULT_STATE.config.motd, buffer, 128, config_path); | |||
memcpy_s(state->config.motd, 128, buffer, 128); | |||
static IZ_ConfigItem net_server_config_items[] = { | |||
{ | |||
IZ_CONFIG_TYPE_STRING, | |||
sizeof(char) * 64, | |||
"Network", | |||
"Name", | |||
"-n", | |||
&IZ_NET_SERVER_DEFAULT_STATE.config.name, | |||
NULL, | |||
{ | |||
.serialize = NULL, | |||
.deserialize = NULL, | |||
}, | |||
NULL, | |||
}, | |||
{ | |||
IZ_CONFIG_TYPE_STRING, | |||
sizeof(char) * 128, | |||
"Network", | |||
"Motd", | |||
"-m", | |||
&IZ_NET_SERVER_DEFAULT_STATE.config.motd, | |||
NULL, | |||
{ | |||
.serialize = NULL, | |||
.deserialize = NULL, | |||
}, | |||
NULL, | |||
}, | |||
{ | |||
IZ_CONFIG_TYPE_U16, | |||
sizeof(u16), | |||
"Network", | |||
"Port", | |||
"-p", | |||
&IZ_NET_SERVER_DEFAULT_STATE.config.port, | |||
IZ_NetServerIsValidPort, | |||
{ | |||
.serialize = NULL, | |||
.deserialize = NULL, | |||
}, | |||
NULL, | |||
} | |||
}; | |||
state->config.port = ini_getl("Network", "Port", IZ_NET_SERVER_DEFAULT_STATE.config.port, config_path); | |||
void IZ_NetServerBindStateToConfig(IZ_NetServerState* state, IZ_ConfigItem config_items[]) { | |||
config_items[0].dest = &state->config.name; | |||
config_items[1].dest = &state->config.motd; | |||
config_items[2].dest = &state->config.port; | |||
} | |||
IZ_ProcedureResult IZ_NetSaveConfig(IZ_NetServerState* state, const char* config_path) { | |||
if (!ini_puts("Network", "Name", state->config.name, config_path)) { | |||
return -1; | |||
} | |||
if (!ini_puts("Network", "Motd", state->config.motd, config_path)) { | |||
return -1; | |||
} | |||
IZ_NetServerBindStateToConfig(state, net_server_config_items); | |||
return IZ_ConfigSave(net_server_config_items, config_path); | |||
} | |||
if (!ini_putl("Network", "Port", state->config.port, config_path)) { | |||
IZ_ProcedureResult IZ_NetServerInitializeConfig( | |||
IZ_NetServerState* state, | |||
const char* config_path, | |||
u8 argc, | |||
const char* argv[] | |||
) { | |||
IZ_NetServerBindStateToConfig(state, net_server_config_items); | |||
if (IZ_ConfigInitialize(net_server_config_items, config_path, argc, argv) < 0) { | |||
return -1; | |||
} | |||
return 0; | |||
} | |||
void IZ_NetOverrideConfig(IZ_NetServerState* state, u8 argc, const char* argv[]) { | |||
const char* cmdline_buffer; | |||
char* rest_of_string; | |||
u16 port; | |||
if ((cmdline_buffer = IZ_ConfigGetCommandlineOption(argc, argv, "-p"))) { | |||
port = strtol(cmdline_buffer, &rest_of_string, 10); | |||
if (strcmp(cmdline_buffer, rest_of_string) != 0) { | |||
state->config.port = port; | |||
} | |||
} | |||
if ((cmdline_buffer = IZ_ConfigGetCommandlineOption(argc, argv, "-n"))) { | |||
memcpy_s(state->config.name, 64, cmdline_buffer, 64); | |||
} | |||
if ((cmdline_buffer = IZ_ConfigGetCommandlineOption(argc, argv, "-m"))) { | |||
memcpy_s(state->config.motd, 128, cmdline_buffer, 128); | |||
} | |||
} | |||
IZ_ProcedureResult IZ_NetInitialize( | |||
IZ_ProcedureResult IZ_NetServerInitialize( | |||
IZ_NetServerState* state, | |||
void* user_data, | |||
const char* config_path, | |||
@@ -59,15 +84,13 @@ IZ_ProcedureResult IZ_NetInitialize( | |||
return -1; | |||
} | |||
memcpy_s(state, sizeof(IZ_NetServerState), &IZ_NET_SERVER_DEFAULT_STATE, sizeof(IZ_NetServerState)); | |||
IZ_NetLoadConfig(state, config_path); | |||
if (IZ_NetSaveConfig(state, config_path) < 0) { | |||
if (IZ_NetServerInitializeConfig(state, config_path, argc, argv) < 0) { | |||
return -2; | |||
} | |||
IZ_NetOverrideConfig(state, argc, argv); | |||
state->ws.user_data = user_data; | |||
state->binding.user_data = user_data; | |||
return 0; | |||
} | |||
void IZ_NetServerCancelService(IZ_NetServerState* state) { | |||
IZ_WSServerCancelService(&state->ws); | |||
IZ_WSServerCancelService(&state->binding); | |||
} |
@@ -17,7 +17,7 @@ typedef struct { | |||
typedef struct { | |||
IZ_NetServerConfig config; | |||
IZ_NetBinding ws; | |||
IZ_NetBinding binding; | |||
} IZ_NetServerState; | |||
static IZ_NetServerState IZ_NET_SERVER_DEFAULT_STATE = { | |||
@@ -26,7 +26,7 @@ static IZ_NetServerState IZ_NET_SERVER_DEFAULT_STATE = { | |||
.name = IZ_APP_NAME " Server", | |||
.motd = IZ_DEFAULT_MOTD, | |||
}, | |||
.ws = { | |||
.binding = { | |||
.interrupted = false, | |||
.context = NULL, | |||
.connection = NULL, | |||
@@ -34,7 +34,7 @@ static IZ_NetServerState IZ_NET_SERVER_DEFAULT_STATE = { | |||
}, | |||
}; | |||
IZ_ProcedureResult IZ_NetInitialize(IZ_NetServerState*, void*, const char*, u8, const char*[]); | |||
IZ_ProcedureResult IZ_NetServerInitialize(IZ_NetServerState *state, void *user_data, const char *config_path, u8 argc, const char **argv); | |||
IZ_ProcedureResult IZ_NetSaveConfig(IZ_NetServerState*, const char*); | |||
@@ -3,7 +3,7 @@ | |||
static IZ_App* global_app; | |||
void IZ_AppHandleSignal(i32 _signal) { | |||
global_app->net_state.ws.interrupted = true; | |||
global_app->net_state.binding.interrupted = true; | |||
IZ_NetServerCancelService(&global_app->net_state); | |||
} | |||
@@ -24,7 +24,7 @@ IZ_ProcedureResult IZ_AppInitialize(IZ_App *app, u8 argc, const char **argv) { | |||
IZ_ConfigGetDefaultPath(config_path, 128); | |||
} | |||
if (IZ_NetInitialize(&app->net_state, app, config_path, argc, argv)) { | |||
if (IZ_NetServerInitialize(&app->net_state, app, config_path, argc, argv)) { | |||
return -1; | |||
} | |||
@@ -37,7 +37,7 @@ IZ_ProcedureResult IZ_AppInitialize(IZ_App *app, u8 argc, const char **argv) { | |||
void IZ_AppTeardown(IZ_App* app) { | |||
IZ_RepoTeardown(&app->repo_state); | |||
IZ_WSServerTeardown(&app->net_state.ws); | |||
IZ_WSServerTeardown(&app->net_state.binding); | |||
lwsl_user("Server closed. Bye!\n"); | |||
} | |||
@@ -87,7 +87,7 @@ IZ_ProcedureResult IZ_AppRun(IZ_App *app, u8 argc, const char **argv) { | |||
return -1; | |||
} | |||
if (IZ_WSServerInitialize(&app->net_state.ws, (IZ_WSServerInitializeParams) { | |||
if (IZ_WSServerInitialize(&app->net_state.binding, (IZ_WSServerInitializeParams) { | |||
.port = app->net_state.config.port, | |||
})) { | |||
return -1; | |||
@@ -95,12 +95,12 @@ IZ_ProcedureResult IZ_AppRun(IZ_App *app, u8 argc, const char **argv) { | |||
i32 result = 0; | |||
while (true) { | |||
if (IZ_WSServerHandle(&app->net_state.ws)) { | |||
if (IZ_WSServerHandle(&app->net_state.binding)) { | |||
result = -1; | |||
break; | |||
} | |||
if (app->net_state.ws.interrupted) { | |||
if (app->net_state.binding.interrupted) { | |||
break; | |||
} | |||
} | |||
@@ -78,7 +78,7 @@ | |||
type="url" | |||
name="serverUrl" | |||
autocomplete="off" | |||
value="ws://localhost:42069" | |||
value="binding://localhost:42069" | |||
required | |||
> | |||
</label> | |||
@@ -92,7 +92,7 @@ | |||
<span>Username</span> | |||
<input | |||
type="text" | |||
name="username" | |||
name="usernames" | |||
autocomplete="off" | |||
value="Web" | |||
required | |||