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_NAME="Izanagi" | ||||
-DIZ_APP_DESCRIPTION="Run and gun game" | -DIZ_APP_DESCRIPTION="Run and gun game" | ||||
-DIZ_APP_SERVER_DESCRIPTION="Dedicated server" | -DIZ_APP_SERVER_DESCRIPTION="Dedicated server" | ||||
-DIZ_PLAYERS=1 | |||||
-DIZ_PLAYERS=2 | |||||
) | ) | ||||
if (${CMAKE_BUILD_TYPE} STREQUAL "Debug") | if (${CMAKE_BUILD_TYPE} STREQUAL "Debug") | ||||
@@ -2,6 +2,9 @@ | |||||
Width=320 | Width=320 | ||||
Height=240 | Height=240 | ||||
MaxFps=30 | MaxFps=30 | ||||
[Joystick.0] | |||||
DeviceID=0 | |||||
AxisThreshold=8000 | |||||
[Joystick.0.ControlMapping] | [Joystick.0.ControlMapping] | ||||
Affirm=11 | Affirm=11 | ||||
Negate=10 | Negate=10 | ||||
@@ -15,9 +18,6 @@ Action6=8 | |||||
Action7=9 | Action7=9 | ||||
Action8=13 | Action8=13 | ||||
Action9=14 | Action9=14 | ||||
[Joystick.0] | |||||
DeviceID=0 | |||||
AxisThreshold=8000 | |||||
[Keyboard.0.ControlMapping] | [Keyboard.0.ControlMapping] | ||||
Up=Up | Up=Up | ||||
Right=Right | Right=Right | ||||
@@ -35,6 +35,9 @@ Action6=C | |||||
Action7=V | Action7=V | ||||
Action8=W | Action8=W | ||||
Action9=E | Action9=E | ||||
[MIDIInput.0] | |||||
DeviceID=0 | |||||
Channel=0 | |||||
[MIDIInput.0.ControlMapping] | [MIDIInput.0.ControlMapping] | ||||
Up="A#5" | Up="A#5" | ||||
Right=C6 | Right=C6 | ||||
@@ -52,11 +55,64 @@ Action6="F#4" | |||||
Action7=G4 | Action7=G4 | ||||
Action8="G#4" | Action8="G#4" | ||||
Action9=A4 | Action9=A4 | ||||
[MIDIInput.0] | |||||
Channel=0 | |||||
DeviceID=0 | |||||
[Network] | [Network] | ||||
Username=Player | |||||
PacketIntervalMs=200 | PacketIntervalMs=200 | ||||
MaxReconnectRetries=3 | MaxReconnectRetries=3 | ||||
ReconnectIntervalSeconds=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; | 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)) { | 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; | 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; | 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); | 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; | 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) { | 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) { | for (i = 0; item[i].type != IZ_CONFIG_TYPE_VOID; i += 1) { | ||||
switch (item[i].type) { | switch (item[i].type) { | ||||
case IZ_CONFIG_TYPE_STRING: | case IZ_CONFIG_TYPE_STRING: | ||||
IZ_ConfigLoadString(item[i], config_path); | |||||
IZ_ConfigLoadString(&item[i], config_path); | |||||
break; | break; | ||||
case IZ_CONFIG_TYPE_U8: | case IZ_CONFIG_TYPE_U8: | ||||
IZ_ConfigLoadU8(item[i], config_path); | |||||
IZ_ConfigLoadU8(&item[i], config_path); | |||||
break; | break; | ||||
case IZ_CONFIG_TYPE_U16: | case IZ_CONFIG_TYPE_U16: | ||||
IZ_ConfigLoadU16(item[i], config_path); | |||||
IZ_ConfigLoadU16(&item[i], config_path); | |||||
break; | break; | ||||
case IZ_CONFIG_TYPE_I32: | |||||
IZ_ConfigLoadI32(&item[i], config_path); | |||||
default: | default: | ||||
break; | 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) { | IZ_ProcedureResult IZ_ConfigSave(IZ_ConfigItem item[], const char* config_path) { | ||||
u8 i; | u8 i; | ||||
u16 problems = 0; | u16 problems = 0; | ||||
for (i = 0; item[i].type != IZ_CONFIG_TYPE_VOID; i += 1) { | for (i = 0; item[i].type != IZ_CONFIG_TYPE_VOID; i += 1) { | ||||
switch (item[i].type) { | switch (item[i].type) { | ||||
case IZ_CONFIG_TYPE_STRING: | case IZ_CONFIG_TYPE_STRING: | ||||
IZ_ConfigSaveString(item[i], config_path); | |||||
IZ_ConfigSaveString(&item[i], config_path); | |||||
break; | break; | ||||
case IZ_CONFIG_TYPE_U8: | case IZ_CONFIG_TYPE_U8: | ||||
IZ_ConfigSaveU8(item[i], config_path); | |||||
IZ_ConfigSaveU8(&item[i], config_path); | |||||
break; | break; | ||||
case IZ_CONFIG_TYPE_U16: | case IZ_CONFIG_TYPE_U16: | ||||
IZ_ConfigSaveU16(item[i], config_path); | |||||
IZ_ConfigSaveU16(&item[i], config_path); | |||||
break; | break; | ||||
case IZ_CONFIG_TYPE_I32: | |||||
IZ_ConfigSaveI32(&item[i], config_path); | |||||
default: | default: | ||||
break; | break; | ||||
} | } | ||||
@@ -183,66 +204,21 @@ IZ_ProcedureResult IZ_ConfigSave(IZ_ConfigItem item[], const char* config_path) | |||||
return -problems; | 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[]) { | void IZ_ConfigOverride(IZ_ConfigItem item[], u8 argc, const char* argv[]) { | ||||
u8 i; | u8 i; | ||||
for (i = 0; item[i].type != IZ_CONFIG_TYPE_VOID; i += 1) { | for (i = 0; item[i].type != IZ_CONFIG_TYPE_VOID; i += 1) { | ||||
switch (item[i].type) { | switch (item[i].type) { | ||||
case IZ_CONFIG_TYPE_STRING: | |||||
IZ_ConfigOverrideString(&item[i], argc, argv); | |||||
break; | |||||
case IZ_CONFIG_TYPE_U8: | case IZ_CONFIG_TYPE_U8: | ||||
IZ_ConfigOverrideU8(item[i], argc, argv); | |||||
IZ_ConfigOverrideU8(&item[i], argc, argv); | |||||
break; | break; | ||||
case IZ_CONFIG_TYPE_U16: | case IZ_CONFIG_TYPE_U16: | ||||
IZ_ConfigOverrideU16(item[i], argc, argv); | |||||
IZ_ConfigOverrideU16(&item[i], argc, argv); | |||||
break; | break; | ||||
case IZ_CONFIG_TYPE_STRING: | |||||
IZ_ConfigOverrideString(item[i], argc, argv); | |||||
case IZ_CONFIG_TYPE_I32: | |||||
IZ_ConfigOverrideI32(&item[i], argc, argv); | |||||
break; | break; | ||||
default: | default: | ||||
break; | 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); | 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); | IZ_ConfigOverride(item, argc, argv); | ||||
return save_result > 0 ? 1 : 0; | |||||
} | } |
@@ -10,9 +10,15 @@ typedef enum { | |||||
IZ_CONFIG_TYPE_VOID, | IZ_CONFIG_TYPE_VOID, | ||||
IZ_CONFIG_TYPE_STRING, | IZ_CONFIG_TYPE_STRING, | ||||
IZ_CONFIG_TYPE_U8, | IZ_CONFIG_TYPE_U8, | ||||
IZ_CONFIG_TYPE_U16 | |||||
IZ_CONFIG_TYPE_U16, | |||||
IZ_CONFIG_TYPE_I32, | |||||
} IZ_ConfigType; | } IZ_ConfigType; | ||||
typedef struct { | |||||
void* serialize; | |||||
void* deserialize; | |||||
} IZ_ConfigSerializerPair; | |||||
typedef struct { | typedef struct { | ||||
IZ_ConfigType type; | IZ_ConfigType type; | ||||
size_t dest_size; | size_t dest_size; | ||||
@@ -21,6 +27,7 @@ typedef struct { | |||||
const char* cmdline_option; | const char* cmdline_option; | ||||
const void* default_value; | const void* default_value; | ||||
void* validator; | void* validator; | ||||
IZ_ConfigSerializerPair transformer; | |||||
void* dest; | void* dest; | ||||
} IZ_ConfigItem; | } IZ_ConfigItem; | ||||
@@ -28,8 +35,23 @@ 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_ConfigInitialize(IZ_ConfigItem[], const char*, u8, const char*[]); | |||||
IZ_ProcedureResult IZ_ConfigSave(IZ_ConfigItem[], 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 | #endif |
@@ -35,7 +35,7 @@ void IZ_VideoUpdateForDebugInput(IZ_VideoState* video_state, IZ_InputState* inpu | |||||
u8 control_index; | u8 control_index; | ||||
for (player_index = 0; player_index < IZ_PLAYERS; player_index += 1) { | for (player_index = 0; player_index < IZ_PLAYERS; player_index += 1) { | ||||
IZ_Action the_action = input_state->action[player_index]; | 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); | column = (control_index % 4) + (player_index * 4); | ||||
row = control_index / 4; | row = control_index / 4; | ||||
@@ -87,7 +87,7 @@ void IZ_VideoUpdateForDebugNet(IZ_VideoState* video_state, IZ_NetClientState* ne | |||||
u8 control_index; | u8 control_index; | ||||
for (player_index = 0; player_index < IZ_PLAYERS; player_index += 1) { | for (player_index = 0; player_index < IZ_PLAYERS; player_index += 1) { | ||||
IZ_Action the_action = net_state->action[player_index]; | 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); | column = (control_index % 4) + (player_index * 4); | ||||
row = control_index / 4; | row = control_index / 4; | ||||
@@ -3,11 +3,11 @@ | |||||
#include "../../common/IZ_common.h" | #include "../../common/IZ_common.h" | ||||
#define CONTROLS (unsigned char) 16 | |||||
#define IZ_CONTROLS (unsigned char) 16 | |||||
typedef u16 IZ_Action; | typedef u16 IZ_Action; | ||||
static const char* ACTION_NAMES[CONTROLS] = { | |||||
static const char* IZ_ACTION_NAMES[IZ_CONTROLS] = { | |||||
"Up", | "Up", | ||||
"Right", | "Right", | ||||
"Down", | "Down", | ||||
@@ -19,15 +19,15 @@ IZ_ProcedureResult IZ_InputInitialize(IZ_InputState* state, const char* config_p | |||||
IZ_ProcedureResult result = 0; | 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; | 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; | 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; | result |= 4; | ||||
} | } | ||||
@@ -1,5 +1,11 @@ | |||||
#include "IZ_joystick.h" | #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) { | void IZ_JoystickHandleDeviceEvents(IZ_JoystickState* state, SDL_Event e) { | ||||
if (e.type == SDL_JOYDEVICEADDED) { | if (e.type == SDL_JOYDEVICEADDED) { | ||||
if (SDL_NumJoysticks() <= IZ_PLAYERS && !state->device) { | 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) { | void IZ_JoystickHandleButtonEvents(IZ_JoystickState* state, IZ_Action* action, SDL_Event e) { | ||||
u8 control_index; | 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]) { | if (e.jbutton.button == state->config.control_mapping[control_index]) { | ||||
const u16 bitflag = (0x1 << 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 player_index; | ||||
u8 control_index; | u8 control_index; | ||||
for (player_index = 0; player_index < IZ_PLAYERS; player_index += 1) { | 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) { | 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 player_index; | ||||
u8 control_index; | u8 control_index; | ||||
char* main_section_name; | |||||
char* control_mapping_section_name; | |||||
for (player_index = 0; player_index < IZ_PLAYERS; player_index += 1) { | 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, | main_section_name, | ||||
"DeviceID", | "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, | main_section_name, | ||||
"AxisThreshold", | "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 -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 player_index; | ||||
u8 joysticks_count = SDL_NumJoysticks(); | |||||
for (player_index = 0; player_index < joysticks_count; player_index += 1) { | for (player_index = 0; player_index < joysticks_count; player_index += 1) { | ||||
if (player_index >= IZ_PLAYERS) { | if (player_index >= IZ_PLAYERS) { | ||||
break; | break; | ||||
@@ -5,6 +5,7 @@ | |||||
#include <SDL_joystick.h> | #include <SDL_joystick.h> | ||||
#include <SDL_events.h> | #include <SDL_events.h> | ||||
#include <minIni.h> | #include <minIni.h> | ||||
#include "../../config/IZ_config.h" | |||||
#include "IZ_action.h" | #include "IZ_action.h" | ||||
typedef u8 IZ_PadButton; | typedef u8 IZ_PadButton; | ||||
@@ -21,7 +22,7 @@ typedef enum { | |||||
typedef struct { | typedef struct { | ||||
u16 axis_threshold; | u16 axis_threshold; | ||||
SDL_JoystickID device_id; | SDL_JoystickID device_id; | ||||
IZ_PadButton control_mapping[CONTROLS]; | |||||
IZ_PadButton control_mapping[IZ_CONTROLS]; | |||||
} IZ_JoystickConfig; | } IZ_JoystickConfig; | ||||
typedef struct { | typedef struct { | ||||
@@ -55,6 +56,7 @@ static const IZ_JoystickState IZ_JOYSTICK_DEFAULT_STATE[IZ_PLAYERS] = { | |||||
}, | }, | ||||
.device = NULL, | .device = NULL, | ||||
}, | }, | ||||
#if IZ_PLAYERS > 1 | |||||
{ | { | ||||
.config = { | .config = { | ||||
.control_mapping = { | .control_mapping = { | ||||
@@ -80,6 +82,7 @@ static const IZ_JoystickState IZ_JOYSTICK_DEFAULT_STATE[IZ_PLAYERS] = { | |||||
}, | }, | ||||
.device = NULL, | .device = NULL, | ||||
}, | }, | ||||
#endif | |||||
}; | }; | ||||
IZ_ProcedureResult IZ_JoystickSaveConfig(IZ_JoystickState(*)[IZ_PLAYERS], const char*); | IZ_ProcedureResult IZ_JoystickSaveConfig(IZ_JoystickState(*)[IZ_PLAYERS], const char*); | ||||
@@ -1,8 +1,19 @@ | |||||
#include "IZ_keyboard.h" | #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) { | void IZ_KeyboardHandleKeyUpDownEvents(IZ_KeyboardState* state, IZ_Action* action, SDL_Event e) { | ||||
u8 control_index; | 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]) { | if (e.key.keysym.sym == state->config.control_mapping[control_index]) { | ||||
const u16 bitflag = (0x1 << control_index); | const u16 bitflag = (0x1 << control_index); | ||||
if (e.type == SDL_KEYDOWN) { | 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 player_index; | ||||
u8 control_index; | u8 control_index; | ||||
for (player_index = 0; player_index < IZ_PLAYERS; player_index += 1) { | 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 player_index; | ||||
u8 control_index; | u8 control_index; | ||||
char* control_mapping_section_name; | |||||
for (player_index = 0; player_index < IZ_PLAYERS; player_index += 1) { | 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[]) { | 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_keyboard.h> | ||||
#include <SDL_events.h> | #include <SDL_events.h> | ||||
#include <minIni.h> | #include <minIni.h> | ||||
#include "../../config/IZ_config.h" | |||||
#include "IZ_action.h" | #include "IZ_action.h" | ||||
typedef struct { | typedef struct { | ||||
SDL_KeyCode control_mapping[CONTROLS]; | |||||
SDL_KeyCode control_mapping[IZ_CONTROLS]; | |||||
} IZ_KeyboardConfig; | } IZ_KeyboardConfig; | ||||
typedef struct { | typedef struct { | ||||
@@ -38,6 +39,7 @@ static const IZ_KeyboardState IZ_KEYBOARD_DEFAULT_STATE[IZ_PLAYERS] = { | |||||
}, | }, | ||||
}, | }, | ||||
}, | }, | ||||
#if IZ_PLAYERS > 1 | |||||
{ | { | ||||
.config = { | .config = { | ||||
.control_mapping = { | .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*); | IZ_ProcedureResult IZ_KeyboardSaveConfig(IZ_KeyboardState(*)[IZ_PLAYERS], const char*); | ||||
@@ -1,5 +1,20 @@ | |||||
#include "IZ_midi.h" | #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) { | void IZ_MIDIInputHandleNoteOnOffEvents(IZ_MIDIInputState* state, IZ_Action* action, PmEvent e) { | ||||
u32 message = e.message; | u32 message = e.message; | ||||
u8 status = message & 0xF0u; | u8 status = message & 0xF0u; | ||||
@@ -8,7 +23,7 @@ void IZ_MIDIInputHandleNoteOnOffEvents(IZ_MIDIInputState* state, IZ_Action* acti | |||||
// u8 data2 = (message >> 16) & 0xFFu; | // u8 data2 = (message >> 16) & 0xFFu; | ||||
u8 control_index; | 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 ( | if ( | ||||
data1 == state->config.control_mapping[control_index] | 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 player_index; | ||||
u8 control_index; | u8 control_index; | ||||
for (player_index = 0; player_index < IZ_PLAYERS; player_index += 1) { | 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 player_index; | ||||
u8 control_index; | u8 control_index; | ||||
char* main_section_name; | |||||
char* control_mapping_section_name; | |||||
for (player_index = 0; player_index < IZ_PLAYERS; player_index += 1) { | 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, | 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[]) { | IZ_ProcedureResult IZ_MIDIInputInitialize(IZ_MIDIInputState(* state)[IZ_PLAYERS], const char* config_path, u8 argc, const char* argv[]) { | ||||
if (Pm_Initialize()) { | 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; | u8 player_index; | ||||
@@ -10,15 +10,16 @@ | |||||
#endif | #endif | ||||
#include <minIni.h> | #include <minIni.h> | ||||
#include "IZ_action.h" | |||||
#include "../../config/IZ_config.h" | |||||
#include "../util/IZ_midi.h" | #include "../util/IZ_midi.h" | ||||
#include "IZ_action.h" | |||||
#define MIDI_EVENT_BUFFER_SIZE 1024 | #define MIDI_EVENT_BUFFER_SIZE 1024 | ||||
typedef struct { | typedef struct { | ||||
PmDeviceID device_id; | PmDeviceID device_id; | ||||
u8 channel; | u8 channel; | ||||
IZ_MIDINote control_mapping[CONTROLS]; | |||||
IZ_MIDINote control_mapping[IZ_CONTROLS]; | |||||
} IZ_MIDIInputConfig; | } IZ_MIDIInputConfig; | ||||
typedef struct { | typedef struct { | ||||
@@ -57,6 +58,7 @@ static const IZ_MIDIInputState IZ_MIDI_INPUT_DEFAULT_STATE[IZ_PLAYERS] = { | |||||
.stream = NULL, | .stream = NULL, | ||||
.device_info = NULL, | .device_info = NULL, | ||||
}, | }, | ||||
#if IZ_PLAYERS > 1 | |||||
{ | { | ||||
.config = { | .config = { | ||||
.control_mapping = { | .control_mapping = { | ||||
@@ -84,6 +86,7 @@ static const IZ_MIDIInputState IZ_MIDI_INPUT_DEFAULT_STATE[IZ_PLAYERS] = { | |||||
.stream = NULL, | .stream = NULL, | ||||
.device_info = NULL, | .device_info = NULL, | ||||
}, | }, | ||||
#endif | |||||
}; | }; | ||||
IZ_ProcedureResult IZ_MIDIInputSaveConfig(IZ_MIDIInputState(*)[IZ_PLAYERS], const char*); | IZ_ProcedureResult IZ_MIDIInputSaveConfig(IZ_MIDIInputState(*)[IZ_PLAYERS], const char*); | ||||
@@ -48,7 +48,7 @@ spec("input") { | |||||
} | } | ||||
it("calls load method") { | 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); | IZ_JoystickInitialize(&state, "config-game.ini", 0, NULL); | ||||
@@ -61,7 +61,7 @@ spec("input") { | |||||
} | } | ||||
it("calls save method") { | 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); | IZ_JoystickInitialize(&state, "config-game.ini", 0, NULL); | ||||
@@ -276,7 +276,7 @@ spec("input") { | |||||
} | } | ||||
for (u8 i = 0; i < 4; i += 1) { | 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); | e.jhat.value = (0x1u << i); | ||||
action[p] = 0; | 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; | e.jhat.value = 0; | ||||
action[p] = ~0; | action[p] = ~0; | ||||
@@ -301,8 +301,8 @@ spec("input") { | |||||
} | } | ||||
describe("on button events") { | 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.type = SDL_JOYBUTTONDOWN; | ||||
e.jbutton.button = IZ_JOYSTICK_DEFAULT_STATE[p].config.control_mapping[i]; | 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]; | 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.type = SDL_JOYBUTTONUP; | ||||
e.jbutton.button = IZ_JOYSTICK_DEFAULT_STATE[p].config.control_mapping[i]; | 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]; | state[p].config.control_mapping[i] = IZ_JOYSTICK_DEFAULT_STATE[p].config.control_mapping[i]; | ||||
@@ -342,14 +342,14 @@ spec("input") { | |||||
before_each() { | before_each() { | ||||
for (u8 p = 0; p < IZ_PLAYERS; p += 1) { | 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]; | state[p].config.control_mapping[i] = IZ_JOYSTICK_DEFAULT_STATE[p].config.control_mapping[i]; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
it("calls save method") { | 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"); | IZ_JoystickSaveConfig(&state, "config-game.ini"); | ||||
@@ -409,7 +409,7 @@ spec("input") { | |||||
before_each() { | before_each() { | ||||
for (u8 p = 0; p < IZ_PLAYERS; p += 1) { | 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]; | 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") { | 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); | IZ_KeyboardInitialize(&state, "config-game.ini", 0, NULL); | ||||
@@ -435,7 +435,7 @@ spec("input") { | |||||
} | } | ||||
it("calls save method") { | 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); | IZ_KeyboardInitialize(&state, "config-game.ini", 0, NULL); | ||||
@@ -455,8 +455,8 @@ spec("input") { | |||||
for (u8 p = 0; p < IZ_PLAYERS; p += 1) { | for (u8 p = 0; p < IZ_PLAYERS; p += 1) { | ||||
describe("on player %u", p) { | 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.type = SDL_KEYDOWN; | ||||
e.key.keysym.sym = IZ_KEYBOARD_DEFAULT_STATE[p].config.control_mapping[i]; | 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]; | 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.type = SDL_KEYUP; | ||||
e.key.keysym.sym = IZ_KEYBOARD_DEFAULT_STATE[p].config.control_mapping[i]; | 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]; | state[p].config.control_mapping[i] = IZ_KEYBOARD_DEFAULT_STATE[p].config.control_mapping[i]; | ||||
@@ -495,14 +495,14 @@ spec("input") { | |||||
before_each() { | before_each() { | ||||
for (u8 p = 0; p < IZ_PLAYERS; p += 1) { | 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]; | state[p].config.control_mapping[i] = IZ_KEYBOARD_DEFAULT_STATE[p].config.control_mapping[i]; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
it("calls save method") { | 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); | IZ_KeyboardSaveConfig("config-game.ini", &state); | ||||
@@ -556,7 +556,7 @@ spec("input") { | |||||
} | } | ||||
it("calls load method") { | 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); | mock_set_expected_calls(ini_getl, 2 * IZ_PLAYERS); | ||||
IZ_MIDIInputInitialize(&state, "config-game.ini", 0, NULL); | IZ_MIDIInputInitialize(&state, "config-game.ini", 0, NULL); | ||||
@@ -577,7 +577,7 @@ spec("input") { | |||||
} | } | ||||
it("calls save method") { | 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); | mock_set_expected_calls(ini_putl, 2 * IZ_PLAYERS); | ||||
IZ_MIDIInputInitialize(&state, "config-game.ini", 0, NULL); | IZ_MIDIInputInitialize(&state, "config-game.ini", 0, NULL); | ||||
@@ -623,7 +623,7 @@ spec("input") { | |||||
} | } | ||||
it("calls save method") { | 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); | mock_set_expected_calls(ini_putl, 2 * IZ_PLAYERS); | ||||
IZ_MIDIInputSaveConfig("config-game.ini", &state); | IZ_MIDIInputSaveConfig("config-game.ini", &state); | ||||
@@ -651,8 +651,8 @@ spec("input") { | |||||
for (u8 p = 0; p < IZ_PLAYERS; p += 1) { | for (u8 p = 0; p < IZ_PLAYERS; p += 1) { | ||||
describe("on player %u", p) { | 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); | 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]; | state[p].config.control_mapping[i] = IZ_MIDI_INPUT_DEFAULT_STATE[p].config.control_mapping[i]; | ||||
action[p] = 0; | 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); | 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]; | state[p].config.control_mapping[i] = IZ_MIDI_INPUT_DEFAULT_STATE[p].config.control_mapping[i]; | ||||
action[p] = ~0; | action[p] = ~0; | ||||
@@ -42,6 +42,7 @@ static IZ_ConfigItem video_config_items[] = { | |||||
&IZ_VIDEO_DEFAULT_STATE.config.max_fps, | &IZ_VIDEO_DEFAULT_STATE.config.max_fps, | ||||
IZ_VideoIsValidMaxFPS, | IZ_VideoIsValidMaxFPS, | ||||
}, | }, | ||||
IZ_CONFIG_ITEM_NULL, | |||||
}; | }; | ||||
void IZ_VideoBindStateToConfig(IZ_VideoState* state, IZ_ConfigItem config_items[]) { | 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); | 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[]) { | 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)); | 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->last_update_at = 0u; | ||||
state->user_data = user_data; | state->user_data = user_data; | ||||
@@ -72,7 +83,7 @@ IZ_ProcedureResult IZ_VideoInitialize(IZ_VideoState* state, void* user_data, con | |||||
); | ); | ||||
if (window == NULL) { | if (window == NULL) { | ||||
// fprintf_s(stderr, "Window could not be created! SDL_Error: %s\n", SDL_GetError()); | // fprintf_s(stderr, "Window could not be created! SDL_Error: %s\n", SDL_GetError()); | ||||
return 1; | |||||
return -3; | |||||
} | } | ||||
state->window = window; | state->window = window; | ||||
state->renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); | state->renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); | ||||
@@ -23,7 +23,7 @@ char* IZ_MIDIGetNoteName(u8 midi_note) { | |||||
return note_name; | return note_name; | ||||
} | } | ||||
u8 IZ_MIDIGetNoteFromName(char* name) { | |||||
u8 IZ_MIDIGetNoteFromName(const char* name) { | |||||
char name_copy[8]; | char name_copy[8]; | ||||
memcpy_s(name_copy, 8, name, 8); | memcpy_s(name_copy, 8, name, 8); | ||||
_strlwr_s(name_copy, 8); | _strlwr_s(name_copy, 8); | ||||
@@ -13,6 +13,6 @@ static const u8 IZ_MIDI_NOTE_OFF = 0x80u; | |||||
char* IZ_MIDIGetNoteName(u8); | char* IZ_MIDIGetNoteName(u8); | ||||
u8 IZ_MIDIGetNoteFromName(char*); | |||||
u8 IZ_MIDIGetNoteFromName(const char*); | |||||
#endif | #endif |
@@ -12,55 +12,87 @@ bool IZ_NetClientIsValidReconnectIntervalSeconds(long reconnect_interval_secs) { | |||||
return (3 <= reconnect_interval_secs && reconnect_interval_secs <= 10); | 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, | 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, | 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, | 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[]) { | 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_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( | IZ_ProcedureResult IZ_NetClientInitialize( | ||||
@@ -71,10 +103,11 @@ IZ_ProcedureResult IZ_NetClientInitialize( | |||||
u8 argc, | u8 argc, | ||||
const char* argv[] | 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) { | 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; | return -2; | ||||
} | } | ||||
state->binding.user_data = user_data; | state->binding.user_data = user_data; | ||||
@@ -19,7 +19,7 @@ typedef struct { | |||||
u16 packet_interval_ms; | u16 packet_interval_ms; | ||||
u8 max_reconnect_retries; | u8 max_reconnect_retries; | ||||
u8 reconnect_interval_secs; | u8 reconnect_interval_secs; | ||||
char username[32]; | |||||
char usernames[IZ_PLAYERS][32]; | |||||
} IZ_NetClientConfig; | } IZ_NetClientConfig; | ||||
typedef struct { | typedef struct { | ||||
@@ -40,7 +40,12 @@ static IZ_NetClientState IZ_NET_CLIENT_DEFAULT_STATE = { | |||||
.packet_interval_ms = 200, | .packet_interval_ms = 200, | ||||
.max_reconnect_retries = 3, | .max_reconnect_retries = 3, | ||||
.reconnect_interval_secs = 3, | .reconnect_interval_secs = 3, | ||||
.username = "Player", | |||||
.usernames = { | |||||
"Player 1", | |||||
#if IZ_PLAYERS > 1 | |||||
"Player 2" | |||||
#endif | |||||
}, | |||||
}, | }, | ||||
.binding = { | .binding = { | ||||
.interrupted = false, | .interrupted = false, | ||||
@@ -1,54 +1,79 @@ | |||||
#include "IZ_net_server.h" | #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) { | 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 -1; | ||||
} | } | ||||
return 0; | 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, | IZ_NetServerState* state, | ||||
void* user_data, | void* user_data, | ||||
const char* config_path, | const char* config_path, | ||||
@@ -59,15 +84,13 @@ IZ_ProcedureResult IZ_NetInitialize( | |||||
return -1; | return -1; | ||||
} | } | ||||
memcpy_s(state, sizeof(IZ_NetServerState), &IZ_NET_SERVER_DEFAULT_STATE, sizeof(IZ_NetServerState)); | 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; | return -2; | ||||
} | } | ||||
IZ_NetOverrideConfig(state, argc, argv); | |||||
state->ws.user_data = user_data; | |||||
state->binding.user_data = user_data; | |||||
return 0; | return 0; | ||||
} | } | ||||
void IZ_NetServerCancelService(IZ_NetServerState* state) { | void IZ_NetServerCancelService(IZ_NetServerState* state) { | ||||
IZ_WSServerCancelService(&state->ws); | |||||
IZ_WSServerCancelService(&state->binding); | |||||
} | } |
@@ -17,7 +17,7 @@ typedef struct { | |||||
typedef struct { | typedef struct { | ||||
IZ_NetServerConfig config; | IZ_NetServerConfig config; | ||||
IZ_NetBinding ws; | |||||
IZ_NetBinding binding; | |||||
} IZ_NetServerState; | } IZ_NetServerState; | ||||
static IZ_NetServerState IZ_NET_SERVER_DEFAULT_STATE = { | 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", | .name = IZ_APP_NAME " Server", | ||||
.motd = IZ_DEFAULT_MOTD, | .motd = IZ_DEFAULT_MOTD, | ||||
}, | }, | ||||
.ws = { | |||||
.binding = { | |||||
.interrupted = false, | .interrupted = false, | ||||
.context = NULL, | .context = NULL, | ||||
.connection = 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*); | IZ_ProcedureResult IZ_NetSaveConfig(IZ_NetServerState*, const char*); | ||||
@@ -3,7 +3,7 @@ | |||||
static IZ_App* global_app; | static IZ_App* global_app; | ||||
void IZ_AppHandleSignal(i32 _signal) { | 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); | 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); | 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; | return -1; | ||||
} | } | ||||
@@ -37,7 +37,7 @@ IZ_ProcedureResult IZ_AppInitialize(IZ_App *app, u8 argc, const char **argv) { | |||||
void IZ_AppTeardown(IZ_App* app) { | void IZ_AppTeardown(IZ_App* app) { | ||||
IZ_RepoTeardown(&app->repo_state); | IZ_RepoTeardown(&app->repo_state); | ||||
IZ_WSServerTeardown(&app->net_state.ws); | |||||
IZ_WSServerTeardown(&app->net_state.binding); | |||||
lwsl_user("Server closed. Bye!\n"); | lwsl_user("Server closed. Bye!\n"); | ||||
} | } | ||||
@@ -87,7 +87,7 @@ IZ_ProcedureResult IZ_AppRun(IZ_App *app, u8 argc, const char **argv) { | |||||
return -1; | 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, | .port = app->net_state.config.port, | ||||
})) { | })) { | ||||
return -1; | return -1; | ||||
@@ -95,12 +95,12 @@ IZ_ProcedureResult IZ_AppRun(IZ_App *app, u8 argc, const char **argv) { | |||||
i32 result = 0; | i32 result = 0; | ||||
while (true) { | while (true) { | ||||
if (IZ_WSServerHandle(&app->net_state.ws)) { | |||||
if (IZ_WSServerHandle(&app->net_state.binding)) { | |||||
result = -1; | result = -1; | ||||
break; | break; | ||||
} | } | ||||
if (app->net_state.ws.interrupted) { | |||||
if (app->net_state.binding.interrupted) { | |||||
break; | break; | ||||
} | } | ||||
} | } | ||||
@@ -78,7 +78,7 @@ | |||||
type="url" | type="url" | ||||
name="serverUrl" | name="serverUrl" | ||||
autocomplete="off" | autocomplete="off" | ||||
value="ws://localhost:42069" | |||||
value="binding://localhost:42069" | |||||
required | required | ||||
> | > | ||||
</label> | </label> | ||||
@@ -92,7 +92,7 @@ | |||||
<span>Username</span> | <span>Username</span> | ||||
<input | <input | ||||
type="text" | type="text" | ||||
name="username" | |||||
name="usernames" | |||||
autocomplete="off" | autocomplete="off" | ||||
value="Web" | value="Web" | ||||
required | required | ||||