diff --git a/CMakeLists.txt b/CMakeLists.txt index 5d28def..a018b4f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -69,7 +69,7 @@ include_directories( "${CMAKE_HOME_DIRECTORY}/dependencies/SDL2_image/include" "${CMAKE_HOME_DIRECTORY}/dependencies/SDL2_ttf/include" "${CMAKE_HOME_DIRECTORY}/subprojects/ini-config/subprojects/minIni/dev" - "${CMAKE_HOME_DIRECTORY}/subprojects/ini-config" + "${CMAKE_HOME_DIRECTORY}/subprojects/ini-config/source" "${CMAKE_HOME_DIRECTORY}/subprojects/bdd-for-c" "${CMAKE_HOME_DIRECTORY}/subprojects/bdd-for-c-mocks" "${CMAKE_HOME_DIRECTORY}/subprojects/midi-utils" @@ -142,12 +142,12 @@ add_executable( ${IZ_EXECUTABLE_TYPE} subprojects/ini-config/subprojects/minIni/dev/minIni.h subprojects/ini-config/subprojects/minIni/dev/minIni.c - subprojects/ini-config/ini-config.h - subprojects/ini-config/ini-config.c - subprojects/ini-config/types/int.h - subprojects/ini-config/types/int.c - subprojects/ini-config/types/string.h - subprojects/ini-config/types/string.c + subprojects/ini-config/source/ini-config.h + subprojects/ini-config/source/ini-config.c + subprojects/ini-config/source/types/int.h + subprojects/ini-config/source/types/int.c + subprojects/ini-config/source/types/string.h + subprojects/ini-config/source/types/string.c subprojects/midi-utils/midi-utils.h subprojects/midi-utils/midi-utils.c ${IZ_GETOPT_DEPENDENCIES} @@ -158,8 +158,8 @@ add_executable( src/packages/game/IZ_app.h src/packages/game/IZ_app.c src/packages/game/main.c - src/packages/game/input/IZ_joystick.c - src/packages/game/input/IZ_joystick.h + src/packages/game/input/IZ_gamecontroller.c + src/packages/game/input/IZ_gamecontroller.h src/packages/game/input/IZ_keyboard.c src/packages/game/input/IZ_keyboard.h src/packages/game/geometry/IZ_vector2d.c @@ -242,23 +242,26 @@ add_executable( subprojects/bdd-for-c/bdd-for-c.h subprojects/bdd-for-c-mocks/bdd-for-c-mocks.h - subprojects/ini-config/ini-config.h - __mocks__/subprojects/ini-config/ini-config.mock.h + subprojects/ini-config/source/ini-config.h + __mocks__/subprojects/ini-config/source/ini-config.mock.h __mocks__/subprojects/SDL/SDL_keyboard.mock.h __mocks__/subprojects/SDL/SDL_events.mock.h - __mocks__/subprojects/SDL/SDL_joystick.mock.h + __mocks__/subprojects/SDL/SDL_gamecontroller.mock.h __mocks__/subprojects/SDL/SDL_stdinc.mock.h __mocks__/subprojects/portmidi/portmidi.mock.h + src/packages/log/IZ_log.h + __mocks__/src/packages/log/IZ_log.mock.h + src/packages/config/IZ_config_guid.h src/packages/config/IZ_config_guid.c src/packages/game/input/IZ_keyboard.h src/packages/game/input/IZ_keyboard.c - src/packages/game/input/IZ_joystick.h - src/packages/game/input/IZ_joystick.c + src/packages/game/input/IZ_gamecontroller.h + src/packages/game/input/IZ_gamecontroller.c src/packages/game/input/IZ_midi.h src/packages/game/input/IZ_midi.c @@ -350,12 +353,12 @@ add_executable( dependencies/sqlite/sqlite3.c subprojects/ini-config/subprojects/minIni/dev/minIni.h subprojects/ini-config/subprojects/minIni/dev/minIni.c - subprojects/ini-config/ini-config.h - subprojects/ini-config/ini-config.c - subprojects/ini-config/types/int.h - subprojects/ini-config/types/int.c - subprojects/ini-config/types/string.h - subprojects/ini-config/types/string.c + subprojects/ini-config/source/ini-config.h + subprojects/ini-config/source/ini-config.c + subprojects/ini-config/source/types/int.h + subprojects/ini-config/source/types/int.c + subprojects/ini-config/source/types/string.h + subprojects/ini-config/source/types/string.c src/packages/log/IZ_intercept.h src/packages/log/IZ_intercept.c src/packages/server/main.c @@ -394,12 +397,12 @@ add_executable( asset-inv subprojects/ini-config/subprojects/minIni/dev/minIni.h subprojects/ini-config/subprojects/minIni/dev/minIni.c - subprojects/ini-config/ini-config.h - subprojects/ini-config/ini-config.c - subprojects/ini-config/types/int.h - subprojects/ini-config/types/int.c - subprojects/ini-config/types/string.h - subprojects/ini-config/types/string.c + subprojects/ini-config/source/ini-config.h + subprojects/ini-config/source/ini-config.c + subprojects/ini-config/source/types/int.h + subprojects/ini-config/source/types/int.c + subprojects/ini-config/source/types/string.h + subprojects/ini-config/source/types/string.c src/packages/common/IZ_common.h src/packages/asset-inv/main.c ) diff --git a/__mocks__/src/packages/log/IZ_log.mock.h b/__mocks__/src/packages/log/IZ_log.mock.h index d137f67..f74fbf6 100644 --- a/__mocks__/src/packages/log/IZ_log.mock.h +++ b/__mocks__/src/packages/log/IZ_log.mock.h @@ -9,6 +9,10 @@ mock_modes(IZ_LogInfo) { IZ_LOG_INFO_LOG, }; +mock(IZ_LOG_DATE_FUNCTION) char* IZ_LOG_DATE_FUNCTION(void) { + mock_return(IZ_LOG_DATE_FUNCTION) ""; +} + mock(IZ_LogInfo) void IZ_LogInfo(IZ_LogCategory category, const char* context, const char* fmt, ...) { mock_mode_if(IZ_LogInfo, IZ_LOG_INFO_SUPPRESS) { mock_return(IZ_LogInfo); diff --git a/__mocks__/subprojects/SDL/SDL_gamecontroller.mock.h b/__mocks__/subprojects/SDL/SDL_gamecontroller.mock.h new file mode 100644 index 0000000..93c3bc9 --- /dev/null +++ b/__mocks__/subprojects/SDL/SDL_gamecontroller.mock.h @@ -0,0 +1,48 @@ +#ifndef SDL_GAMECONTROLLER_MOCK_H +#define SDL_GAMECONTROLLER_MOCK_H + +#include +#include +#include +#include "../../../src/packages/common/IZ_common.h" + +#define MOCK_OPEN_JOYSTICKS 1 + +mock(SDL_GameControllerOpen) SDL_GameController* SDL_GameControllerOpen(i32 device_index) { + static void* joystick = (void*) 1; + mock_return(SDL_GameControllerOpen) (SDL_GameController*) &joystick; +} + +mock(SDL_NumJoysticks) i32 SDL_NumJoysticks(void) { + mock_return(SDL_NumJoysticks) MOCK_OPEN_JOYSTICKS; +} + +mock(SDL_JoystickInstanceID) i32 SDL_JoystickInstanceID(SDL_Joystick* joystick) { + mock_return(SDL_JoystickInstanceID) 0; +} + +mock(SDL_GameControllerClose) void SDL_GameControllerClose(SDL_GameController* _joystick) { + mock_return(SDL_GameControllerClose); +} + +mock(SDL_JoystickGetGUID) SDL_JoystickGUID SDL_JoystickGetGUID(SDL_Joystick* joystick) { + mock_return(SDL_JoystickGetGUID) (SDL_JoystickGUID) { + .data = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, } + }; +} + +mock(SDL_GameControllerAddMappingsFromRW) int SDL_GameControllerAddMappingsFromRW(SDL_RWops *rw, int freerw) { + mock_return(SDL_GameControllerAddMappingsFromRW) 1; +} + +mock(SDL_GameControllerFromInstanceID) SDL_GameController* SDL_GameControllerFromInstanceID(SDL_JoystickID instance_id) { + static void* joystick = (void*) 1; + mock_return(SDL_GameControllerFromInstanceID) (SDL_GameController*) &joystick; +} + +mock(SDL_GameControllerGetJoystick) SDL_Joystick* SDL_GameControllerGetJoystick(SDL_GameController* gamecontroller) { + static void* joystick = (void*) 1; + mock_return(SDL_GameControllerGetJoystick) (SDL_Joystick*) &joystick; +} + +#endif diff --git a/__mocks__/subprojects/SDL/SDL_joystick.mock.h b/__mocks__/subprojects/SDL/SDL_joystick.mock.h deleted file mode 100644 index f013711..0000000 --- a/__mocks__/subprojects/SDL/SDL_joystick.mock.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef SDL_JOYSTICK_MOCK_H -#define SDL_JOYSTICK_MOCK_H - -#include -#include -#include -#include "../../../src/packages/common/IZ_common.h" - -#define MOCK_OPEN_JOYSTICKS 1 - -mock(SDL_JoystickOpen) SDL_Joystick* SDL_JoystickOpen(i32 device_index) { - static void* joystick = (void*) 1; - mock_return(SDL_JoystickOpen) (SDL_Joystick*) &joystick; -} - -mock(SDL_NumJoysticks) i32 SDL_NumJoysticks(void) { - mock_return(SDL_NumJoysticks) MOCK_OPEN_JOYSTICKS; -} - -mock(SDL_JoystickInstanceID) i32 SDL_JoystickInstanceID(SDL_Joystick* joystick) { - mock_return(SDL_JoystickInstanceID) 0; -} - -mock(SDL_JoystickClose) void SDL_JoystickClose(SDL_Joystick* _joystick) { - mock_return(SDL_JoystickClose); -} - -mock(SDL_JoystickGetGUID) SDL_JoystickGUID SDL_JoystickGetGUID(SDL_Joystick* joystick) { - mock_return(SDL_JoystickGetGUID) (SDL_JoystickGUID) { - .data = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, } - }; -} - -mock(SDL_GameControllerAddMappingsFromRW) int SDL_GameControllerAddMappingsFromRW(SDL_RWops *rw, int freerw) { - mock_return(SDL_GameControllerAddMappingsFromRW) 0; -} - -mock(SDL_JoystickFromInstanceID) SDL_Joystick* SDL_JoystickFromInstanceID(SDL_JoystickID instance_id) { - static void* joystick = (void*) 1; - mock_return(SDL_JoystickFromInstanceID) (SDL_Joystick*) &joystick; -} - -#endif diff --git a/__mocks__/subprojects/ini-config/ini-config.mock.h b/__mocks__/subprojects/ini-config/source/ini-config.mock.h similarity index 79% rename from __mocks__/subprojects/ini-config/ini-config.mock.h rename to __mocks__/subprojects/ini-config/source/ini-config.mock.h index 73d64b5..07345f3 100644 --- a/__mocks__/subprojects/ini-config/ini-config.mock.h +++ b/__mocks__/subprojects/ini-config/source/ini-config.mock.h @@ -16,59 +16,59 @@ mock(INI_ConfigGetCommandlineOption) const char* INI_ConfigGetCommandlineOption( mock_return(INI_ConfigGetCommandlineOption) ""; } -mock(INI_ConfigLoadU8) void INI_ConfigLoadU8(INI_ConfigItem* _item, const char* _config_path) { +mock(INI_ConfigLoadU8) void INI_ConfigLoadU8(INI_ConfigItem* _item, const char* _config_path, void* _item_array) { mock_return(INI_ConfigLoadU8); } -mock(INI_ConfigLoadU16) void INI_ConfigLoadU16(INI_ConfigItem* _item, const char* _config_path) { +mock(INI_ConfigLoadU16) void INI_ConfigLoadU16(INI_ConfigItem* _item, const char* _config_path, void* _item_array) { mock_return(INI_ConfigLoadU16); } -mock(INI_ConfigLoadU32) void INI_ConfigLoadU32(INI_ConfigItem* _item, const char* _config_path) { +mock(INI_ConfigLoadU32) void INI_ConfigLoadU32(INI_ConfigItem* _item, const char* _config_path, void* _item_array) { mock_return(INI_ConfigLoadU32); } -mock(INI_ConfigLoadI8) void INI_ConfigLoadI8(INI_ConfigItem* _item, const char* _config_path) { +mock(INI_ConfigLoadI8) void INI_ConfigLoadI8(INI_ConfigItem* _item, const char* _config_path, void* _item_array) { mock_return(INI_ConfigLoadI8); } -mock(INI_ConfigLoadI16) void INI_ConfigLoadI16(INI_ConfigItem* _item, const char* _config_path) { +mock(INI_ConfigLoadI16) void INI_ConfigLoadI16(INI_ConfigItem* _item, const char* _config_path, void* _item_array) { mock_return(INI_ConfigLoadI16); } -mock(INI_ConfigLoadI32) void INI_ConfigLoadI32(INI_ConfigItem* _item, const char* _config_path) { +mock(INI_ConfigLoadI32) void INI_ConfigLoadI32(INI_ConfigItem* _item, const char* _config_path, void* _item_array) { mock_return(INI_ConfigLoadI32); } -mock(INI_ConfigLoadString) void INI_ConfigLoadString(INI_ConfigItem* _item, const char* _config_path) { +mock(INI_ConfigLoadString) void INI_ConfigLoadString(INI_ConfigItem* _item, const char* _config_path, void* _item_array) { mock_return(INI_ConfigLoadString); } -mock(INI_ConfigSaveU8) INI_ConfigSaveItemResult INI_ConfigSaveU8(INI_ConfigItem* _item, const char* _config_path) { +mock(INI_ConfigSaveU8) INI_ConfigSaveItemResult INI_ConfigSaveU8(INI_ConfigItem* _item, const char* _config_path, void* _item_array) { mock_return(INI_ConfigSaveU8) INI_CONFIG_SAVE_ITEM_OK; } -mock(INI_ConfigSaveU16) INI_ConfigSaveItemResult INI_ConfigSaveU16(INI_ConfigItem* _item, const char* _config_path) { +mock(INI_ConfigSaveU16) INI_ConfigSaveItemResult INI_ConfigSaveU16(INI_ConfigItem* _item, const char* _config_path, void* _item_array) { mock_return(INI_ConfigSaveU16) INI_CONFIG_SAVE_ITEM_OK; } -mock(INI_ConfigSaveU32) INI_ConfigSaveItemResult INI_ConfigSaveU32(INI_ConfigItem* _item, const char* _config_path) { +mock(INI_ConfigSaveU32) INI_ConfigSaveItemResult INI_ConfigSaveU32(INI_ConfigItem* _item, const char* _config_path, void* _item_array) { mock_return(INI_ConfigSaveU32) INI_CONFIG_SAVE_ITEM_OK; } -mock(INI_ConfigSaveI8) INI_ConfigSaveItemResult INI_ConfigSaveI8(INI_ConfigItem* _item, const char* _config_path) { +mock(INI_ConfigSaveI8) INI_ConfigSaveItemResult INI_ConfigSaveI8(INI_ConfigItem* _item, const char* _config_path, void* _item_array) { mock_return(INI_ConfigSaveI8) INI_CONFIG_SAVE_ITEM_OK; } -mock(INI_ConfigSaveI16) INI_ConfigSaveItemResult INI_ConfigSaveI16(INI_ConfigItem* _item, const char* _config_path) { +mock(INI_ConfigSaveI16) INI_ConfigSaveItemResult INI_ConfigSaveI16(INI_ConfigItem* _item, const char* _config_path, void* _item_array) { mock_return(INI_ConfigSaveI16) INI_CONFIG_SAVE_ITEM_OK; } -mock(INI_ConfigSaveI32) INI_ConfigSaveItemResult INI_ConfigSaveI32(INI_ConfigItem* _item, const char* _config_path) { +mock(INI_ConfigSaveI32) INI_ConfigSaveItemResult INI_ConfigSaveI32(INI_ConfigItem* _item, const char* _config_path, void* _item_array) { mock_return(INI_ConfigSaveI32) INI_CONFIG_SAVE_ITEM_OK; } -mock(INI_ConfigSaveString) INI_ConfigSaveItemResult INI_ConfigSaveString(INI_ConfigItem* _item, const char* _config_path) { +mock(INI_ConfigSaveString) INI_ConfigSaveItemResult INI_ConfigSaveString(INI_ConfigItem* _item, const char* _config_path, void* _item_array) { mock_return(INI_ConfigSaveString) INI_CONFIG_SAVE_ITEM_OK; } diff --git a/__tests__/src/packages/game/input.test.c b/__tests__/src/packages/game/input.test.c index a856a6f..900126c 100644 --- a/__tests__/src/packages/game/input.test.c +++ b/__tests__/src/packages/game/input.test.c @@ -3,29 +3,22 @@ #endif #include #include -#include +#include #include #include #include #include #include -#include +#include +#include #include -#include +#include #include -i16 GenerateAxisValueWithinThreshold(u16 threshold) { - return rand() % threshold; -} - -i16 GenerateAxisValueOutsideThreshold(u16 threshold) { - return threshold + (rand() % (RAND_MAX - threshold - 1)) + 1; -} - spec("input") { - describe("joystick") { + describe("gamecontroller") { describe("Initialize") { - static IZ_JoystickState state[IZ_PLAYERS]; + static IZ_GameControllerState state[IZ_PLAYERS]; after_each() { mock_reset(IZ_memcpy); @@ -36,7 +29,7 @@ spec("input") { } after_each() { - mock_reset(SDL_JoystickOpen); + mock_reset(SDL_GameControllerOpen); } after_each() { @@ -48,41 +41,41 @@ spec("input") { } it("sets initial state") { - IZ_JoystickInitialize(&state, IZ_CONFIG_GAME_PATH, 0, NULL); + IZ_GameControllerInitialize(&state, IZ_CONFIG_GAME_PATH, 0, NULL); check(mock_is_called(IZ_memcpy), "Initial state not loaded."); check(mock_is_called(SDL_NumJoysticks), "Connected joysticks not checked."); } it("calls load method") { - IZ_JoystickInitialize(&state, IZ_CONFIG_GAME_PATH, 0, NULL); + IZ_GameControllerInitialize(&state, IZ_CONFIG_GAME_PATH, 0, NULL); check(mock_is_called(INI_ConfigInitialize), "Config load function not called."); } it("calls save method") { - IZ_JoystickInitialize(&state, IZ_CONFIG_GAME_PATH, 0, NULL); + IZ_GameControllerInitialize(&state, IZ_CONFIG_GAME_PATH, 0, NULL); check(mock_is_called(INI_ConfigSave), "Config save function not called."); } it("opens device handles") { - mock_set_expected_calls(SDL_JoystickOpen, MOCK_OPEN_JOYSTICKS); + mock_set_expected_calls(SDL_GameControllerOpen, MOCK_OPEN_JOYSTICKS); - IZ_JoystickInitialize(&state, IZ_CONFIG_GAME_PATH, 0, NULL); + IZ_GameControllerInitialize(&state, IZ_CONFIG_GAME_PATH, 0, NULL); check( - mock_get_expected_calls(SDL_JoystickOpen) == mock_get_actual_calls(SDL_JoystickOpen), - "Call count mismatch for SDL_JoystickOpen() (expected %u, received %u).", - mock_get_expected_calls(SDL_JoystickOpen), - mock_get_actual_calls(SDL_JoystickOpen) + mock_get_expected_calls(SDL_GameControllerOpen) == mock_get_actual_calls(SDL_GameControllerOpen), + "Call count mismatch for SDL_GameControllerOpen() (expected %u, received %u).", + mock_get_expected_calls(SDL_GameControllerOpen), + mock_get_actual_calls(SDL_GameControllerOpen) ); } } describe("HandleEvents") { static SDL_Event e; - static IZ_JoystickState state[IZ_PLAYERS] = {}; + static IZ_GameControllerState state[IZ_PLAYERS] = {}; static IZ_Action action[IZ_PLAYERS] = {}; u8 p; @@ -90,267 +83,75 @@ spec("input") { describe("on player %u", p) { describe("on axis motion events") { before_each() { - e.type = SDL_JOYAXISMOTION; - state[p].config.axis_threshold = 8000u; + state[p].config.axis_threshold = IZ_GAME_CONTROLLER_AXIS_THRESHOLD; } - describe("on primary horizontal direction") { - before_each() { - e.jaxis.axis = IZ_JOY_AXIS_DIRECTION_HORIZONTAL1; - } - - it("handles positive motion") { - e.jaxis.value = GenerateAxisValueOutsideThreshold(state[p].config.axis_threshold); - if (e.jaxis.value < 0) { - e.jaxis.value = -e.jaxis.value; - } - action[p] = 0; - - printf("(axis value: %d) ", e.jaxis.value); - IZ_JoystickHandleEvents(&state, &action, e); - check( - action[p] == (0x1 << IZ_ACTION_INDEX_RIGHT), - "Action not set." - ); - } + for (u8 i = 0; i < SDL_CONTROLLER_AXIS_MAX; i += 1) { + static const char* axis_name; + axis_name = SDL_GameControllerGetStringForAxis(i); - it("handles negative motion") { - e.jaxis.value = -GenerateAxisValueOutsideThreshold(state[p].config.axis_threshold); - if (e.jaxis.value > 0) { - e.jaxis.value = -e.jaxis.value; - } + it("handles %s positive motion activation", axis_name) { + e.type = SDL_CONTROLLERAXISMOTION; + e.caxis.axis = i; + e.caxis.value = IZ_GAME_CONTROLLER_AXIS_THRESHOLD + 1; + sprintf(state[p].config.control_mapping[0], "axis:+%s", axis_name); action[p] = 0; - - printf("(axis value: %d) ", e.jaxis.value); - IZ_JoystickHandleEvents(&state, &action, e); - check( - action[p] == (0x1 << IZ_ACTION_INDEX_LEFT), - "Action not set." - ); - } - - it("handles neutral motion") { - e.jaxis.value = GenerateAxisValueWithinThreshold(state[p].config.axis_threshold); - action[p] = 0; - - printf("(axis value: %d) ", e.jaxis.value); - IZ_JoystickHandleEvents(&state, &action, e); - check( - action[p] == 0, - "Action not set." - ); - } - } - - describe("on secondary horizontal direction") { - before_each() { - e.jaxis.axis = IZ_JOY_AXIS_DIRECTION_HORIZONTAL2; + IZ_GameControllerHandleEvents(&state, &action, e); + check(action[p] != 0, "Action not set."); } - it("handles positive motion") { - e.jaxis.value = GenerateAxisValueOutsideThreshold(state[p].config.axis_threshold); - if (e.jaxis.value < 0) { - e.jaxis.value = -e.jaxis.value; - } + it("handles %s negative motion activation", axis_name) { + e.type = SDL_CONTROLLERAXISMOTION; + e.caxis.axis = i; + e.caxis.value = -(IZ_GAME_CONTROLLER_AXIS_THRESHOLD + 1); + sprintf(state[p].config.control_mapping[0], "axis:-%s", axis_name); action[p] = 0; - - printf("(axis value: %d) ", e.jaxis.value); - IZ_JoystickHandleEvents(&state, &action, e); - check( - action[p] == (0x1 << IZ_ACTION_INDEX_RIGHT), - "Action not set." - ); + IZ_GameControllerHandleEvents(&state, &action, e); + check(action[p] != 0, "Action not set."); } - it("handles negative motion") { - e.jaxis.value = -GenerateAxisValueOutsideThreshold(state[p].config.axis_threshold); - if (e.jaxis.value > 0) { - e.jaxis.value = -e.jaxis.value; - } - action[p] = 0; - - printf("(axis value: %d) ", e.jaxis.value); - IZ_JoystickHandleEvents(&state, &action, e); - check( - action[p] == (0x1 << IZ_ACTION_INDEX_LEFT), - "Action not set." - ); + it("handles %s positive motion deactivation", axis_name) { + e.type = SDL_CONTROLLERAXISMOTION; + e.caxis.axis = i; + e.caxis.value = IZ_GAME_CONTROLLER_AXIS_THRESHOLD - 1; + sprintf(state[p].config.control_mapping[0], "axis:+%s", axis_name); + action[p] = 1; + IZ_GameControllerHandleEvents(&state, &action, e); + check(action[p] != 1, "Action not unset. %d", action[p]); } - it("handles neutral motion") { - e.jaxis.value = GenerateAxisValueWithinThreshold(state[p].config.axis_threshold);; - action[p] = 0; - - printf("(axis value: %d) ", e.jaxis.value); - IZ_JoystickHandleEvents(&state, &action, e); - check( - action[p] == 0, - "Action not set." - ); - } - } - - describe("on primary vertical direction") { - before_each() { - e.jaxis.axis = IZ_JOY_AXIS_DIRECTION_VERTICAL1; - } - - it("handles positive motion") { - e.jaxis.value = GenerateAxisValueOutsideThreshold(state[p].config.axis_threshold); - if (e.jaxis.value < 0) { - e.jaxis.value = -e.jaxis.value; - } - action[p] = 0; - - printf("(axis value: %d) ", e.jaxis.value); - IZ_JoystickHandleEvents(&state, &action, e); - check( - action[p] == (0x1 << IZ_ACTION_INDEX_DOWN), - "Action not set." - ); - } - - it("handles negative motion") { - e.jaxis.value = -GenerateAxisValueOutsideThreshold(state[p].config.axis_threshold); - if (e.jaxis.value > 0) { - e.jaxis.value = -e.jaxis.value; - } - action[p] = 0; - - printf("(axis value: %d) ", e.jaxis.value); - IZ_JoystickHandleEvents(&state, &action, e); - check( - action[p] == (0x1 << IZ_ACTION_INDEX_UP), - "Action not set." - ); - } - - it("handles neutral motion") { - e.jaxis.value = GenerateAxisValueWithinThreshold(state[p].config.axis_threshold);; - action[p] = 0; - - printf("(axis value: %d) ", e.jaxis.value); - IZ_JoystickHandleEvents(&state, &action, e); - check( - action[p] == 0, - "Action not set." - ); - } - } - - describe("on secondary vertical direction") { - before_each() { - e.jaxis.axis = IZ_JOY_AXIS_DIRECTION_VERTICAL2; - } - - it("handles positive motion") { - e.jaxis.value = GenerateAxisValueOutsideThreshold(state[p].config.axis_threshold); - if (e.jaxis.value < 0) { - e.jaxis.value = -e.jaxis.value; - } - action[p] = 0; - - printf("(axis value: %d) ", e.jaxis.value); - IZ_JoystickHandleEvents(&state, &action, e); - check( - action[p] == (0x1 << IZ_ACTION_INDEX_DOWN), - "Action not set." - ); - } - - it("handles negative motion") { - e.jaxis.value = -GenerateAxisValueOutsideThreshold(state[p].config.axis_threshold); - if (e.jaxis.value > 0) { - e.jaxis.value = -e.jaxis.value; - } - action[p] = 0; - - printf("(axis value: %d) ", e.jaxis.value); - IZ_JoystickHandleEvents(&state, &action, e); - check( - action[p] == (0x1 << IZ_ACTION_INDEX_UP), - "Action not set." - ); - } - - it("handles neutral motion") { - e.jaxis.value = GenerateAxisValueWithinThreshold(state[p].config.axis_threshold);; - action[p] = 0; - - printf("(axis value: %d) ", e.jaxis.value); - IZ_JoystickHandleEvents(&state, &action, e); - check( - action[p] == 0, - "Action not set." - ); - } - } - } - - describe("on hat motion events") { - before_each() { - e.type = SDL_JOYHATMOTION; - } - - for (u8 i = 0; i < 4; i += 1) { - it("handles motion for %s action", IZ_ACTION_NAMES[i]) { - e.jhat.value = (0x1u << i); - action[p] = 0; - - IZ_JoystickHandleEvents(&state, &action, e); - check( - action[p] == (0x1u << i), - "Action not set." - ); - } - - it("handles motion for %s deactivation", IZ_ACTION_NAMES[i]) { - e.jhat.value = 0; - action[p] = ~0; - - IZ_JoystickHandleEvents(&state, &action, e); - check( - !(action[p] & (0x1 << i)), - "Action not unset." - ); + it("handles %s negative motion deactivation", axis_name) { + e.type = SDL_CONTROLLERAXISMOTION; + e.caxis.axis = i; + e.caxis.value = -(IZ_GAME_CONTROLLER_AXIS_THRESHOLD - 1); + sprintf(state[p].config.control_mapping[0], "axis:-%s", axis_name); + action[p] = 1; + IZ_GameControllerHandleEvents(&state, &action, e); + check(action[p] != 1, "Action not unset. %d", action[p]); } } } describe("on button events") { - 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]; + for (u8 i = 0; i < SDL_CONTROLLER_BUTTON_MAX; i += 1) { + static const char* button_name; + button_name = SDL_GameControllerGetStringForButton(i); + it("handles %s action activation", button_name) { + e.type = SDL_CONTROLLERBUTTONDOWN; + e.cbutton.button = i; + sprintf(state[p].config.control_mapping[0], "button:%s", button_name); action[p] = 0; - - if (i == IZ_ACTION_INDEX_ACTION2) { - ; - } - - if (i == IZ_ACTION_INDEX_ACTION4) { - ; - } - - IZ_JoystickHandleEvents(&state, &action, e); - check( - action[p] == (0x1u << i), - "Action not set." - ); + IZ_GameControllerHandleEvents(&state, &action, e); + check(action[p] != 0, "Action not set."); } - 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]; - action[p] = ~0; - - IZ_JoystickHandleEvents(&state, &action, e); - check( - !(action[p] & (0x1 << i)), - "Action not unset." - ); + it("handles %s action deactivation", button_name) { + e.type = SDL_CONTROLLERBUTTONUP; + e.cbutton.button = i; + sprintf(state[p].config.control_mapping[0], "button:%s", button_name); + action[p] = 1; + IZ_GameControllerHandleEvents(&state, &action, e); + check(action[p] != 1, "Action not unset."); } } } @@ -359,7 +160,7 @@ spec("input") { } describe("SaveConfig") { - static IZ_JoystickState state[IZ_PLAYERS]; + static IZ_GameControllerState state[IZ_PLAYERS]; after_each() { mock_reset(INI_ConfigSave); @@ -368,13 +169,18 @@ spec("input") { before_each() { for (u8 p = 0; p < IZ_PLAYERS; p += 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]; + IZ_memcpy( + state[p].config.control_mapping[i], + IZ_GAME_CONTROLLER_MAX_CONTROL_NAME_LENGTH, + IZ_GAME_CONTROLLER_DEFAULT_STATE[p].config.control_mapping[i], + IZ_GAME_CONTROLLER_MAX_CONTROL_NAME_LENGTH + ); } } } it("calls save method") { - IZ_JoystickSaveConfig(&state, IZ_CONFIG_GAME_PATH); + IZ_GameControllerSaveConfig(&state, IZ_CONFIG_GAME_PATH); check(mock_is_called(INI_ConfigSave), "Config save function not called."); } @@ -382,7 +188,7 @@ spec("input") { describe("Teardown") { static void* device = (void*) 1; - static IZ_JoystickState state[IZ_PLAYERS] = {}; + static IZ_GameControllerState state[IZ_PLAYERS] = {}; before_each() { for (u8 p = 0; p < IZ_PLAYERS; p += 1) { @@ -391,19 +197,19 @@ spec("input") { } after_each() { - mock_reset(SDL_JoystickClose); + mock_reset(SDL_GameControllerClose); } it("closes opened devices") { - mock_set_expected_calls(SDL_JoystickClose, IZ_PLAYERS); + mock_set_expected_calls(SDL_GameControllerClose, IZ_PLAYERS); - IZ_JoystickTeardown(&state); + IZ_GameControllerTeardown(&state); check( - mock_get_expected_calls(SDL_JoystickClose) == mock_get_actual_calls(SDL_JoystickClose), - "Call count mismatch for SDL_JoystickClose() (expected %u, received %u).", - mock_get_expected_calls(SDL_JoystickClose), - mock_get_actual_calls(SDL_JoystickClose) + mock_get_expected_calls(SDL_GameControllerClose) == mock_get_actual_calls(SDL_GameControllerClose), + "Call count mismatch for SDL_GameControllerClose() (expected %u, received %u).", + mock_get_expected_calls(SDL_GameControllerClose), + mock_get_actual_calls(SDL_GameControllerClose) ); } } diff --git a/assets_src/gfx/weapons-rigged.cdr b/assets_src/gfx/weapons-rigged.cdr index 547d51b..c89e5ee 100644 Binary files a/assets_src/gfx/weapons-rigged.cdr and b/assets_src/gfx/weapons-rigged.cdr differ diff --git a/docs/controls.md b/docs/controls.md index a1929d7..214746d 100644 --- a/docs/controls.md +++ b/docs/controls.md @@ -1,20 +1,45 @@ # Controls -| Action | XInput | PS4 | Effect | Remarks | -|---------|---------:|---------:|-----------------------------------|--------------------------------------------------------------------------------------------------------| -| Up | A1+, A3+ | A1+, A4+ | Select Menu Item Up/Look Up | | -| Right | A0+, A2+ | A0+, A2+ | Select Menu Item Right/Move Right | | -| Down | A1-, A3- | A1-, A4- | Select Menu Item Down/Crouch | | -| Left | A0-, A2- | A0-, A2- | Select Menu Item Left/Move Left | | -| Affirm | B11 | | Confirm Selected Option | | -| Negate | B10 | | Go Back | | -| Action0 | B1 | B2 | Jump | When crouched, player will go down a solid-on-top ground. | -| Action1 | B0 | B1 | Primary Fire | Each weapon has firing characteristics, see below. | -| Action2 | B4 | | Secondary Fire | Each weapon has firing characteristics, see below. | -| Action3 | B3 | | Reload | Reload always drops current clip regardless if there are rounds left. | -| Action4 | B6 | | Switch Weapon Mode | Press to select next weapon mode (cycle), hold then press Left/Right to set previous/next weapon mode. | -| Action5 | B7 | | Switch Weapon | Press to select next weapon (cycle), hold then press Left/Right to set previous/next weapon. | -| Action6 | B8 | | Item/Inventory | Hold to open inventory, double press to use current item. | -| Action7 | B9 | | Switch Item | Press to select next item (cycle), hold then press Left/Right to set previous/next item. | -| Action8 | B13 | | Take Cover | Enter doors, go between objects to hide from enemies. | -| Action9 | B14 | | Sneak | Hold then press Left/Right to sneak. (do we need this control, or crouch is enough?) | +| Action | Default Control | Effect | Remarks | +|---------|------------------------|-----------------------------------|--------------------------------------------------------------------------------------------------------| +| Up | DPad Up/Stick Up | Select Menu Item Up/Look Up | | +| Right | DPad Right/Stick Right | Select Menu Item Right/Move Right | | +| Down | DPad Down/Stick Down | Select Menu Item Down/Crouch | | +| Left | DPad Left/Stick Left | Select Menu Item Left/Move Left | | +| Affirm | Start | Confirm Selected Option | | +| Negate | Select (Back) | Go Back | | +| Action0 | Button X | Jump | When crouched, player will go down a solid-on-top ground. | +| Action1 | Right Trigger | Primary Fire | Each weapon has firing characteristics, see below. | +| Action2 | Left Trigger | Secondary Fire | Each weapon has firing characteristics, see below. | +| Action3 | Button A | Reload | Reload always drops current clip regardless if there are rounds left. | +| Action4 | Button Y | Switch Weapon Mode | Press to select next weapon mode (cycle), hold then press Left/Right to set previous/next weapon mode. | +| Action5 | Right Bumper/Shoulder | Switch Weapon | Press to select next weapon (cycle), hold then press Left/Right to set previous/next weapon. | +| Action6 | Left Stick Button | Item/Inventory | Hold to open inventory, double press to use current item. | +| Action7 | Right Stick Button | Switch Item | Press to select next item (cycle), hold then press Left/Right to set previous/next item. | +| Action8 | Left Bumper/Shoulder | Take Cover | Enter doors, go between objects to hide from enemies. | +| Action9 | Button B | Sneak | Hold then press Left/Right to sneak. (do we need this control, or crouch is enough?) | + +# Control Internals + +| Control | Config Key | +|-----------------------|------------------------| +| DPad Up | `button:dpup` | +| DPad Right | `button:dpright` | +| DPad Down | `button:dpdown` | +| DPad Left | `button:dpleft` | +| Start | `button:start` | +| Select (Back) | `button:back` | +| Button A | `button:a` | +| Button B | `button:b` | +| Button X | `button:x` | +| Button Y | `button:y` | +| Right Bumper/Shoulder | `button:rightshoulder` | +| Right Trigger | `axis:+righttrigger` | +| Left Stick Button | `button:leftstick` | +| Right Stick Button | `button:rightstick` | +| Left Bumper/Shoulder | `button:leftshoulder` | +| Left Trigger | `axis:lefttrigger` | + +> **Note:** The config keys are based from SDL internal names, only we have added the `button:` and `axis:` bind +> prefixes to be flexible on setting up controls on the gamepad. The reason is because gamepad controls use different +> types of binds. diff --git a/src/packages/config/IZ_config_guid.c b/src/packages/config/IZ_config_guid.c index 782d17a..9573360 100644 --- a/src/packages/config/IZ_config_guid.c +++ b/src/packages/config/IZ_config_guid.c @@ -26,7 +26,7 @@ void INI_ConfigEnsureValidGuid(INI_ConfigItem* item, SDL_GUID raw_value, SDL_GUI *dest = raw_value; } -void INI_ConfigLoadGuid(INI_ConfigItem* item, const char* config_path) { +void INI_ConfigLoadGuid(INI_ConfigItem* item, const char* config_path, void* item_array) { static SDL_GUID raw_value; static SDL_GUID default_value = { .data = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, @@ -53,7 +53,7 @@ void INI_ConfigLoadGuid(INI_ConfigItem* item, const char* config_path) { INI_ConfigEnsureValidGuid(item, raw_value, default_value); } -INI_ConfigSaveItemResult INI_ConfigSaveGuid(INI_ConfigItem* item, const char* config_path) { +INI_ConfigSaveItemResult INI_ConfigSaveGuid(INI_ConfigItem* item, const char* config_path, void* item_array) { SDL_GUID dest = *((SDL_GUID*) item->dest); if (item->validator) { INI_ConfigLoadParamsGuidValidator* validate = item->validator; diff --git a/src/packages/game/input/IZ_gamecontroller.c b/src/packages/game/input/IZ_gamecontroller.c new file mode 100644 index 0000000..33fb81f --- /dev/null +++ b/src/packages/game/input/IZ_gamecontroller.c @@ -0,0 +1,272 @@ +#include "IZ_gamecontroller.h" + +static INI_ConfigItem game_controller_config_items[IZ_PLAYERS * (IZ_CONTROLS + IZ_GAME_CONTROLLER_DEFAULT_CONFIGS) + 1]; + +bool IZ_GameControllerIsValidAxisThreshold(u16 value) { + return (IZ_GAME_CONTROLLER_MIN_AXIS_THRESHOLD <= value && value <= IZ_GAME_CONTROLLER_MAX_AXIS_THRESHOLD); +} + +void IZ_GameControllerHandleDeviceEvents(IZ_GameControllerState* state, SDL_Event e) { + if (e.type == SDL_CONTROLLERDEVICEADDED) { + u8 game_controllers_count = SDL_NumJoysticks(); + if (game_controllers_count <= IZ_PLAYERS && !state->device) { + state->device = SDL_GameControllerOpen(e.cdevice.which); + } + return; + } + + if (e.type == SDL_CONTROLLERDEVICEREMOVED) { + if ( + state->device + && SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(state->device)) == e.cdevice.which + ) { + state->device = NULL; + } + } +} + +void IZ_GameControllerHandleAxisEvents(IZ_GameControllerState* state, IZ_Action* action, SDL_Event e) { + if (e.type != SDL_CONTROLLERAXISMOTION) { + return; + } + + u8 control_index; + + for (control_index = 0; control_index < IZ_CONTROLS; control_index += 1) { + const char* current_axis_name = SDL_GameControllerGetStringForAxis(e.caxis.axis); + if (!current_axis_name) { + continue; + } + + char current_positive_axis_full_name[IZ_GAME_CONTROLLER_MAX_CONTROL_NAME_LENGTH]; + sprintf( + current_positive_axis_full_name, + "axis:+%s", + current_axis_name + ); + + char current_negative_axis_full_name[IZ_GAME_CONTROLLER_MAX_CONTROL_NAME_LENGTH]; + sprintf( + current_negative_axis_full_name, + "axis:-%s", + current_axis_name + ); + + bool is_capture = false; + const u16 bitflag = (0x1 << control_index); + if ( + strstr(state->config.control_mapping[control_index], current_positive_axis_full_name) + || strstr(state->config.control_mapping[control_index], current_negative_axis_full_name) + ) { + *action &= ~bitflag; + // should we implement actions that do not cancel out across input controllers? + // add extra byte for source of action: + // 0x1 - keyboard + // 0x2 - game controller dpad + // 0x4 - game controller left stick + // 0x8 - game controller right stick + // 0x10 - other device + } + + char current_axis_full_name[IZ_GAME_CONTROLLER_MAX_CONTROL_NAME_LENGTH]; + if (e.caxis.value > 0) { + IZ_memcpy( + current_axis_full_name, + IZ_GAME_CONTROLLER_MAX_CONTROL_NAME_LENGTH, + current_positive_axis_full_name, + IZ_GAME_CONTROLLER_MAX_CONTROL_NAME_LENGTH + ); + is_capture = e.caxis.value > state->config.axis_threshold; + } + if (e.caxis.value < 0) { + IZ_memcpy( + current_axis_full_name, + IZ_GAME_CONTROLLER_MAX_CONTROL_NAME_LENGTH, + current_negative_axis_full_name, + IZ_GAME_CONTROLLER_MAX_CONTROL_NAME_LENGTH + ); + is_capture = e.jaxis.value <= -state->config.axis_threshold; + } + + if (!strstr(state->config.control_mapping[control_index], current_axis_full_name)) { + continue; + } + + if (!is_capture) { + continue; + } + + *action |= bitflag; + } +} + +void IZ_GameControllerHandleButtonEvents(IZ_GameControllerState* state, IZ_Action* action, SDL_Event e) { + u8 control_index; + for (control_index = 0; control_index < IZ_CONTROLS; control_index += 1) { + const char* current_button_name = SDL_GameControllerGetStringForButton(e.cbutton.button); + if (!current_button_name) { + continue; + } + + char current_button_full_name[IZ_GAME_CONTROLLER_MAX_CONTROL_NAME_LENGTH]; + sprintf( + current_button_full_name, + "button:%s", + current_button_name + ); + + if (!strstr(state->config.control_mapping[control_index], current_button_full_name)) { + continue; + } + + const u16 bitflag = (0x1 << control_index); + if (e.type == SDL_CONTROLLERBUTTONDOWN) { + *action |= bitflag; + return; + } + + if (e.type == SDL_CONTROLLERBUTTONUP) { + *action &= ~bitflag; + return; + } + } +} + +void IZ_GameControllerHandleEvents(IZ_GameControllerState(* state)[IZ_PLAYERS], IZ_Action(* action)[IZ_PLAYERS], SDL_Event e) { + u8 player_index; + for (player_index = 0; player_index < IZ_PLAYERS; player_index += 1) { + IZ_GameControllerHandleDeviceEvents(&(*state)[player_index], e); + IZ_GameControllerHandleAxisEvents(&(*state)[player_index], &(*action)[player_index], e); + IZ_GameControllerHandleButtonEvents(&(*state)[player_index], &(*action)[player_index], e); + } +} + +void IZ_GameControllerBindStateToConfig(IZ_GameControllerState(* state)[IZ_PLAYERS], INI_ConfigItem config_items[]) { + u8 player_index; + u8 control_index; + for (player_index = 0; player_index < IZ_PLAYERS; player_index += 1) { + // The `+ 3` corresponds to the first three config items. Add as appropriate. + u8 base_index = (player_index * (IZ_CONTROLS + IZ_GAME_CONTROLLER_DEFAULT_CONFIGS)); + config_items[base_index + 0].dest = &((*state)[player_index].config.axis_threshold); + config_items[base_index + 1].dest = &((*state)[player_index].config.guid); + for (control_index = 0; control_index < IZ_CONTROLS; control_index += 1) { + config_items[base_index + IZ_GAME_CONTROLLER_DEFAULT_CONFIGS + control_index].dest = &((*state)[player_index].config.control_mapping[control_index]); + } + } +} + +IZ_ProcedureResult IZ_GameControllerSaveConfig(IZ_GameControllerState(* state)[IZ_PLAYERS], const char* config_path) { + IZ_GameControllerBindStateToConfig(state, game_controller_config_items); + return INI_ConfigSave(game_controller_config_items, config_path); +} + +void IZ_GameControllerInitializeConfigItems(INI_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) { + main_section_name = IZ_calloc(64, sizeof(char)); + sprintf(main_section_name, "GameController.%d", player_index); + // The `+ 3` corresponds to the first three config items. Add as appropriate. + u8 base_index = (player_index * (IZ_CONTROLS + IZ_GAME_CONTROLLER_DEFAULT_CONFIGS)); + config_items[base_index + 0] = (INI_ConfigItem) { + INI_CONFIG_TYPE_U16, + main_section_name, + "AxisThreshold", + NULL, + &IZ_GAME_CONTROLLER_DEFAULT_STATE[player_index].config.axis_threshold, + IZ_GameControllerIsValidAxisThreshold, + INI_CONFIG_TRANSFORMER_NONE, + NULL, + }; + + config_items[base_index + 1] = (INI_ConfigItem) { + INI_CONFIG_TYPE_GUID, + main_section_name, + "GUID", + NULL, + &IZ_GAME_CONTROLLER_DEFAULT_STATE[player_index].config.guid, + NULL, + INI_CONFIG_TRANSFORMER_NONE, + NULL, + }; + + control_mapping_section_name = IZ_calloc(64, sizeof(char)); + sprintf(control_mapping_section_name, "GameController.%d.ControlMapping", player_index); + for (control_index = 0; control_index < IZ_CONTROLS; control_index += 1) { + config_items[base_index + IZ_GAME_CONTROLLER_DEFAULT_CONFIGS + control_index] = (INI_ConfigItem) { + INI_CONFIG_TYPE_STRING(IZ_GAME_CONTROLLER_MAX_CONTROL_NAME_LENGTH), + control_mapping_section_name, + IZ_ACTION_NAMES[control_index], + NULL, + &IZ_GAME_CONTROLLER_DEFAULT_STATE[player_index].config.control_mapping[control_index], + NULL, + INI_CONFIG_TRANSFORMER_NONE, + NULL, + }; + } + } + + config_items[IZ_PLAYERS * (IZ_CONTROLS + IZ_GAME_CONTROLLER_DEFAULT_CONFIGS)] = INI_CONFIG_ITEM_NULL; +} + +IZ_ProcedureResult IZ_GameControllerInitializeConfig(IZ_GameControllerState(* state)[IZ_PLAYERS], const char* config_path, u8 argc, const char* argv[]) { + IZ_GameControllerInitializeConfigItems(game_controller_config_items); + IZ_GameControllerBindStateToConfig(state, game_controller_config_items); + if (INI_ConfigInitialize(game_controller_config_items, config_path, argc, argv) < 0) { + return -1; + } + return 0; +} + +IZ_ProcedureResult IZ_GameControllerInitialize(IZ_GameControllerState(* state)[IZ_PLAYERS], const char* config_path, u8 argc, const char* argv[]) { + IZ_memcpy(state, sizeof(IZ_GameControllerState) * IZ_PLAYERS, &IZ_GAME_CONTROLLER_DEFAULT_STATE, sizeof(IZ_GameControllerState) * IZ_PLAYERS); + + // TODO query this file from the internet? + IZ_LogInfo(IZ_LOG_CATEGORY_GENERIC, "input", "Loading game controller mappings file: %s", "assets/gamecontrollerdb.txt"); + const i16 loaded_mappings = SDL_GameControllerAddMappingsFromFile("assets/gamecontrollerdb.txt"); + if (loaded_mappings <= 0) { + return -1; + } + IZ_LogInfo(IZ_LOG_CATEGORY_GENERIC, "input", "Mappings loaded: %d", loaded_mappings); + u8 player_index; + + if (IZ_GameControllerInitializeConfig(state, config_path, argc, argv) < 0) { + return -2; + } + + u8 game_controllers_count = SDL_NumJoysticks(); + for (player_index = 0; player_index < game_controllers_count; player_index += 1) { + if (player_index >= IZ_PLAYERS) { + break; + } + + (*state)[player_index].device = SDL_GameControllerOpen(state[player_index]->config.device_id); + if (!(*state)[player_index].device) { + break; + } + (*state)[player_index].config.device_id = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick((*state)[player_index].device)); + SDL_GUID game_controller_guid = SDL_JoystickGetGUID(SDL_GameControllerGetJoystick((*state)[player_index].device)); + IZ_memcpy(&(*state)[player_index].config.guid, sizeof(SDL_GUID), &game_controller_guid, sizeof(SDL_GUID)); + } + + // Post config (after game_controller GUIDs have been queried), this is unique to game_controllers since they can be plugged in any + // time. + INI_ConfigSaveResult post_config_save_result = IZ_GameControllerSaveConfig(state, config_path); + if (post_config_save_result < 0) { + return -3; + } + + return 0; +} + +void IZ_GameControllerTeardown(IZ_GameControllerState(* state)[IZ_PLAYERS]) { + u8 player_index; + for (player_index = 0; player_index < IZ_PLAYERS; player_index += 1) { + if (!(*state)[player_index].device) { + continue; + } + SDL_GameControllerClose((*state)[player_index].device); + } +} diff --git a/src/packages/game/input/IZ_gamecontroller.h b/src/packages/game/input/IZ_gamecontroller.h new file mode 100644 index 0000000..fbfbe3f --- /dev/null +++ b/src/packages/game/input/IZ_gamecontroller.h @@ -0,0 +1,104 @@ +#ifndef IZ_GAMECONTROLLER_H +#define IZ_GAMECONTROLLER_H + +#include +#include +#include +#include +#include +#include "../../config/IZ_config_guid.h" +#include "../../common/IZ_common.h" +#include "../../stdinc/IZ_string.h" +#include "../../stdinc/IZ_stdlib.h" +#include "../../log/IZ_log.h" +#include "IZ_action.h" + +#define IZ_GAME_CONTROLLER_AXIS_THRESHOLD ((u16) 8000) + +#define IZ_GAME_CONTROLLER_MIN_AXIS_THRESHOLD ((u16) 4000) +#define IZ_GAME_CONTROLLER_MAX_AXIS_THRESHOLD ((u16) 12000) + +#define IZ_GAME_CONTROLLER_DEFAULT_CONFIGS 2 + +#define IZ_GAME_CONTROLLER_MAX_CONTROL_NAME_LENGTH 64 + +typedef struct { + u16 axis_threshold; + SDL_JoystickID device_id; + SDL_GUID guid; + const char control_mapping[IZ_CONTROLS][IZ_GAME_CONTROLLER_MAX_CONTROL_NAME_LENGTH]; +} IZ_GameControllerConfig; + +typedef struct { + SDL_GameController* device; + IZ_GameControllerConfig config; +} IZ_GameControllerState; + +static const IZ_GameControllerState IZ_GAME_CONTROLLER_DEFAULT_STATE[IZ_PLAYERS] = { + { + .config = { + .control_mapping = { + "button:dpup axis:+lefty axis:+righty", + "button:dpright axis:+leftx axis:+rightx", + "button:dpdown axis:-lefty axis:-righty", + "button:dpleft axis:-leftx axis:-rightx", + "button:start", + "button:back", + "button:x", + "axis:+righttrigger", + "axis:+lefttrigger", + "button:a", + "button:y", + "button:rightshoulder", + "button:leftstick", + "button:rightstick", + "button:leftshoulder", + "button:b", + }, + .axis_threshold = IZ_GAME_CONTROLLER_AXIS_THRESHOLD, + .guid = { + .data = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + }, + .device = NULL, + }, +#if IZ_PLAYERS > 1 + { + .config = { + .control_mapping = { + "button:dpadup", + "button:dpadright", + "button:dpaddown", + "button:dpadleft", + "button:start", + "button:back", + "button:x", + "button:y", + "button:a", + "button:b", + "button:rightshoulder", + "axis:righttrigger", + "button:leftstick", + "button:rightstick", + "button:leftshoulder", + "axis:lefttrigger", + }, + .axis_threshold = 8000u, + .guid = { + .data = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }, + }, + .device = NULL, + }, +#endif +}; + +IZ_ProcedureResult IZ_GameControllerSaveConfig(IZ_GameControllerState(*)[IZ_PLAYERS], const char*); + +void IZ_GameControllerHandleEvents(IZ_GameControllerState(*)[IZ_PLAYERS], IZ_Action(*)[IZ_PLAYERS], SDL_Event); + +IZ_ProcedureResult IZ_GameControllerInitialize(IZ_GameControllerState(*)[IZ_PLAYERS], const char*, u8, const char*[]); + +void IZ_GameControllerTeardown(IZ_GameControllerState(*)[IZ_PLAYERS]); + +#endif diff --git a/src/packages/game/input/IZ_input.c b/src/packages/game/input/IZ_input.c index e36d125..fdaafe9 100644 --- a/src/packages/game/input/IZ_input.c +++ b/src/packages/game/input/IZ_input.c @@ -1,7 +1,7 @@ #include "IZ_input.h" void IZ_InputHandleSDLEvents(IZ_InputState* state, SDL_Event e) { - IZ_JoystickHandleEvents(&state->joystick_state, &state->action, e); + IZ_GameControllerHandleEvents(&state->game_controller_state, &state->action, e); IZ_KeyboardHandleEvents(&state->keyboard_state, &state->action, e); } @@ -14,14 +14,14 @@ IZ_ProcedureResult IZ_InputInitialize(IZ_InputState* state, const char* config_p *state = (IZ_InputState) { .action = {}, - .joystick_state = {}, + .game_controller_state = {}, .midi_input_state = {}, .keyboard_state = {}, }; IZ_ProcedureResult result = 0; - if (IZ_JoystickInitialize(&state->joystick_state, config_path, argc, argv) < 0) { + if (IZ_GameControllerInitialize(&state->game_controller_state, config_path, argc, argv) < 0) { result |= 1; } @@ -47,6 +47,6 @@ IZ_ProcedureResult IZ_InputInitialize(IZ_InputState* state, const char* config_p void IZ_InputTeardown(IZ_InputState* state) { IZ_LogInfo(IZ_LOG_CATEGORY_GLOBAL, "input", "Shutting down..."); - IZ_JoystickTeardown(&state->joystick_state); + IZ_GameControllerTeardown(&state->game_controller_state); IZ_MIDIInputTeardown(&state->midi_input_state); } diff --git a/src/packages/game/input/IZ_input.h b/src/packages/game/input/IZ_input.h index b567a30..ad8a6e6 100644 --- a/src/packages/game/input/IZ_input.h +++ b/src/packages/game/input/IZ_input.h @@ -3,14 +3,14 @@ #include "IZ_action.h" #include "IZ_keyboard.h" -#include "IZ_joystick.h" +#include "IZ_gamecontroller.h" #include "IZ_midi.h" #include "../../log/IZ_log.h" typedef struct { IZ_Action action[IZ_PLAYERS]; IZ_KeyboardState keyboard_state[IZ_PLAYERS]; - IZ_JoystickState joystick_state[IZ_PLAYERS]; + IZ_GameControllerState game_controller_state[IZ_PLAYERS]; IZ_MIDIInputState midi_input_state[IZ_PLAYERS]; } IZ_InputState; diff --git a/src/packages/game/input/IZ_joystick.c b/src/packages/game/input/IZ_joystick.c deleted file mode 100644 index 6e240f4..0000000 --- a/src/packages/game/input/IZ_joystick.c +++ /dev/null @@ -1,324 +0,0 @@ -#include "IZ_joystick.h" - -static INI_ConfigItem joystick_config_items[IZ_PLAYERS * (IZ_CONTROLS - 4 + 3) + 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) { - u8 joysticks_count = SDL_NumJoysticks(); - if (joysticks_count <= IZ_PLAYERS && !state->device) { - state->device = SDL_JoystickOpen(e.jdevice.which); - } - return; - } - - if (e.type == SDL_JOYDEVICEREMOVED) { - if ( - state->device - && SDL_JoystickInstanceID(state->device) == e.jdevice.which - ) { - state->device = NULL; - } - } -} - -void IZ_JoystickHandleAxisEvents(IZ_JoystickState* state, IZ_Action* action, SDL_Event e) { - if (e.type == SDL_JOYAXISMOTION) { - // XInput handling - u8 control_index; - for (control_index = 4; control_index < IZ_CONTROLS; control_index += 1) { - if (e.jaxis.axis == IZ_JOY_AXIS_DIRECTION_LEFT_SHOULDER && state->config.control_mapping[control_index] == 10) { - const u16 bitflag = (0x1 << control_index); - - if (e.jaxis.value > state->config.axis_threshold) { - *action |= bitflag; - return; - } - - if (e.jaxis.value <= state->config.axis_threshold) { - *action &= ~bitflag; - return; - } - } - - if (e.jaxis.axis == IZ_JOY_AXIS_DIRECTION_RIGHT_SHOULDER && state->config.control_mapping[control_index] == 11) { - const u16 bitflag = (0x1 << control_index); - - if (e.jaxis.value > state->config.axis_threshold) { - *action |= bitflag; - return; - } - - if (e.jaxis.value <= state->config.axis_threshold) { - *action &= ~bitflag; - return; - } - } - } - - if ( - e.jaxis.axis == IZ_JOY_AXIS_DIRECTION_HORIZONTAL1 - || e.jaxis.axis == IZ_JOY_AXIS_DIRECTION_HORIZONTAL2 - ) { - *action &= ~(0x1 << IZ_ACTION_INDEX_RIGHT); - *action &= ~(0x1 << IZ_ACTION_INDEX_LEFT); - if (e.jaxis.value > state->config.axis_threshold) { - *action |= (0x1 << IZ_ACTION_INDEX_RIGHT); - return; - } - if (e.jaxis.value <= -state->config.axis_threshold) { - *action |= (0x1 << IZ_ACTION_INDEX_LEFT); - } - return; - } - if ( - e.jaxis.axis == IZ_JOY_AXIS_DIRECTION_VERTICAL1 - || e.jaxis.axis == IZ_JOY_AXIS_DIRECTION_VERTICAL2 - ) { - *action &= ~(0x1 << IZ_ACTION_INDEX_UP); - *action &= ~(0x1 << IZ_ACTION_INDEX_DOWN); - if (e.jaxis.value > state->config.axis_threshold) { - *action |= (0x1 << IZ_ACTION_INDEX_DOWN); - return; - } - if (e.jaxis.value <= -state->config.axis_threshold) { - *action |= (0x1 << IZ_ACTION_INDEX_UP); - } - } - } -} - -void IZ_JoystickHandleHatEvents(IZ_Action* action, SDL_Event e) { - if (e.type == SDL_JOYHATMOTION) { - *action &= ~(0x1 << IZ_ACTION_INDEX_UP); - *action &= ~(0x1 << IZ_ACTION_INDEX_RIGHT); - *action &= ~(0x1 << IZ_ACTION_INDEX_DOWN); - *action &= ~(0x1 << IZ_ACTION_INDEX_LEFT); - if (e.jhat.value != 0) { - *action |= e.jhat.value; - } - } -} - -void IZ_JoystickHandleButtonEvents(IZ_JoystickState* state, IZ_Action* action, SDL_Event e) { - u8 control_index; - - SDL_JoystickGUID joystick_guid = SDL_JoystickGetGUID(SDL_JoystickFromInstanceID(e.jbutton.which)); - bool is_valid_event = false; - for (u8 zz = 0; zz < 16; zz += 1) { - is_valid_event |= joystick_guid.data[zz] != 0; - } - if (!is_valid_event) { - return; - } - -// printf("button event from guid: "); -// for (u8 zz = 0; zz < 16; zz += 1) { -// printf("%02x", joystick_guid.data[zz]); -// } -// printf("\n"); - - for (control_index = 4; control_index < IZ_CONTROLS; control_index += 1) { - u8 normalized_button = e.jbutton.button; - - /* - * ZL ZR - * L R - * - * U SLCT STRT 3 - * L R 2 0 - * D 1 - * - * - * - */ - - // TODO test with XInput, make compatible with Apple - - // TODO honor mapping with controller - -#ifdef IZ_MACOS - //printf("%d\n", e.jbutton.button); -// if (e.jbutton.button == 2) { -// normalized_button = 4; -// } else if (e.jbutton.button == 6) { -// normalized_button = 11; -// } else if (e.jbutton.button == 4) { -// normalized_button = 10; -// } -#endif - - if (normalized_button == state->config.control_mapping[control_index]) { - const u16 bitflag = (0x1 << control_index); - - if (e.type == SDL_JOYBUTTONDOWN) { - *action |= bitflag; - return; - } - - if (e.type == SDL_JOYBUTTONUP) { - *action &= ~bitflag; - return; - } - } - } -} - -void IZ_JoystickHandleEvents(IZ_JoystickState(* state)[IZ_PLAYERS], IZ_Action(* action)[IZ_PLAYERS], SDL_Event e) { - u8 player_index; - for (player_index = 0; player_index < IZ_PLAYERS; player_index += 1) { - IZ_JoystickHandleDeviceEvents(&(*state)[player_index], e); - IZ_JoystickHandleAxisEvents(&(*state)[player_index], &(*action)[player_index], e); - IZ_JoystickHandleHatEvents(&(*action)[player_index], e); - IZ_JoystickHandleButtonEvents(&(*state)[player_index], &(*action)[player_index], e); - } -} - -void IZ_JoystickBindStateToConfig(IZ_JoystickState(* state)[IZ_PLAYERS], INI_ConfigItem config_items[]) { - u8 player_index; - u8 control_index; - for (player_index = 0; player_index < IZ_PLAYERS; player_index += 1) { - 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); - config_items[base_index + 2].dest = &((*state)[player_index].config.guid); - for (control_index = 4; control_index < IZ_CONTROLS; control_index += 1) { - config_items[base_index + 3 + (control_index - 4)].dest = &((*state)[player_index].config.control_mapping[control_index]); - } - } -} - -IZ_ProcedureResult IZ_JoystickSaveConfig(IZ_JoystickState(* state)[IZ_PLAYERS], const char* config_path) { - IZ_JoystickBindStateToConfig(state, joystick_config_items); - return INI_ConfigSave(joystick_config_items, config_path); -} - -void IZ_JoystickInitializeConfigItems(INI_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) { - main_section_name = IZ_calloc(64, sizeof(char)); - sprintf(main_section_name, "Joystick.%d", player_index); - // The `+ 3` corresponds to the first three config items. Add as appropriate. - u8 base_index = (player_index * (IZ_CONTROLS - 4 + 3)); - config_items[base_index] = (INI_ConfigItem) { - INI_CONFIG_TYPE_I32, - main_section_name, - "DeviceID", - NULL, - &IZ_JOYSTICK_DEFAULT_STATE[player_index].config.device_id, - NULL, - INI_CONFIG_TRANSFORMER_NONE, - NULL, - }; - - config_items[base_index + 1] = (INI_ConfigItem) { - INI_CONFIG_TYPE_U16, - main_section_name, - "AxisThreshold", - NULL, - &IZ_JOYSTICK_DEFAULT_STATE[player_index].config.axis_threshold, - IZ_JoystickIsValidAxisThreshold, - INI_CONFIG_TRANSFORMER_NONE, - NULL, - }; - - config_items[base_index + 2] = (INI_ConfigItem) { - INI_CONFIG_TYPE_GUID, - main_section_name, - "GUID", - NULL, - &IZ_JOYSTICK_DEFAULT_STATE[player_index].config.guid, - NULL, - INI_CONFIG_TRANSFORMER_NONE, - NULL, - }; - - // todo add game controller GUID for determining mappings - - control_mapping_section_name = IZ_calloc(64, sizeof(char)); - sprintf(control_mapping_section_name, "Joystick.%d.ControlMapping", player_index); - for (control_index = 4; control_index < IZ_CONTROLS; control_index += 1) { - config_items[base_index + 3 + (control_index - 4)] = (INI_ConfigItem) { - INI_CONFIG_TYPE_U8, - control_mapping_section_name, - IZ_ACTION_NAMES[control_index], - NULL, - &IZ_JOYSTICK_DEFAULT_STATE[player_index].config.control_mapping[control_index], - NULL, - INI_CONFIG_TRANSFORMER_NONE, - NULL, - }; - } - } - - config_items[IZ_PLAYERS * (IZ_CONTROLS - 4 + 3)] = INI_CONFIG_ITEM_NULL; -} - -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 (INI_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[]) { - IZ_memcpy(state, sizeof(IZ_JoystickState) * IZ_PLAYERS, &IZ_JOYSTICK_DEFAULT_STATE, sizeof(IZ_JoystickState) * IZ_PLAYERS); - - // TODO query this file from the internet? - SDL_GameControllerAddMappingsFromFile("assets/gamecontrollerdb.txt"); - u8 player_index; - - if (IZ_JoystickInitializeConfig(state, config_path, argc, argv) < 0) { - return -2; - } - - u8 joysticks_count = SDL_NumJoysticks(); - for (player_index = 0; player_index < joysticks_count; player_index += 1) { - if (player_index >= IZ_PLAYERS) { - break; - } - - (*state)[player_index].device = SDL_JoystickOpen(state[player_index]->config.device_id); - if (!(*state)[player_index].device) { - break; - } - - (*state)[player_index].config.device_id = SDL_JoystickInstanceID((*state)[player_index].device); - SDL_GUID joystick_guid = SDL_JoystickGetGUID((*state)[player_index].device); - IZ_memcpy(&(*state)[player_index].config.guid, sizeof(SDL_GUID), &joystick_guid, sizeof(SDL_GUID)); - //(*state)[player_index].config.guid = joystick_guid; - -// printf("[INPUT:JOYSTICK] Initialize event from GUID: "); -// for (u8 zz = 0; zz < 16; zz += 1) { -// printf("%02x", (*state)[player_index].config.guid.data[zz]); -// } -// printf("\n"); - } - - // Post config (after joystick GUIDs have been queried), this is unique to joysticks since they can be plugged in any - // time. - INI_ConfigSaveResult post_config_save_result = IZ_JoystickSaveConfig(state, config_path); - if (post_config_save_result < 0) { - return -3; - } - - return 0; -} - -void IZ_JoystickTeardown(IZ_JoystickState(* state)[IZ_PLAYERS]) { - u8 player_index; - for (player_index = 0; player_index < IZ_PLAYERS; player_index += 1) { - if (!(*state)[player_index].device) { - continue; - } - SDL_JoystickClose((*state)[player_index].device); - } -} diff --git a/src/packages/game/input/IZ_joystick.h b/src/packages/game/input/IZ_joystick.h deleted file mode 100644 index e159ca7..0000000 --- a/src/packages/game/input/IZ_joystick.h +++ /dev/null @@ -1,106 +0,0 @@ -#ifndef IZ_JOYSTICK_H -#define IZ_JOYSTICK_H - -#include -#include -#include -#include -#include -#include "../../config/IZ_config_guid.h" -#include "../../common/IZ_common.h" -#include "../../stdinc/IZ_string.h" -#include "../../stdinc/IZ_stdlib.h" -#include "IZ_action.h" - -typedef u8 IZ_PadButton; - -#define IZ_DEFAULT_AXIS_THRESHOLD ((u16) 8000) - -typedef enum { - IZ_JOY_AXIS_DIRECTION_HORIZONTAL1 = 0, - IZ_JOY_AXIS_DIRECTION_VERTICAL1 = 1, - IZ_JOY_AXIS_DIRECTION_HORIZONTAL2 = 2, - IZ_JOY_AXIS_DIRECTION_VERTICAL2 = 3, - IZ_JOY_AXIS_DIRECTION_LEFT_SHOULDER = 4, - IZ_JOY_AXIS_DIRECTION_RIGHT_SHOULDER = 5, -} IZ_JoyAxisDirection; - -typedef struct { - u16 axis_threshold; - SDL_JoystickID device_id; - SDL_GUID guid; - IZ_PadButton control_mapping[IZ_CONTROLS]; -} IZ_JoystickConfig; - -typedef struct { - SDL_Joystick* device; - IZ_JoystickConfig config; -} IZ_JoystickState; - -static const IZ_JoystickState IZ_JOYSTICK_DEFAULT_STATE[IZ_PLAYERS] = { - { - .config = { - .control_mapping = { - 255, - 255, - 255, - 255, - 11, - 10, - 1, - 0, - 4, - 3, - 6, - 7, - 8, - 9, - 13, - 14, - }, - .axis_threshold = IZ_DEFAULT_AXIS_THRESHOLD, - .device_id = 0, - .guid = { - .data = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } - } - }, - .device = NULL, - }, -#if IZ_PLAYERS > 1 - { - .config = { - .control_mapping = { - 255, - 255, - 255, - 255, - 11, - 10, - 1, - 0, - 4, - 3, - 6, - 7, - 8, - 9, - 13, - 14, - }, - .axis_threshold = 8000u, - .device_id = 1, - }, - .device = NULL, - }, -#endif -}; - -IZ_ProcedureResult IZ_JoystickSaveConfig(IZ_JoystickState(*)[IZ_PLAYERS], const char*); - -void IZ_JoystickHandleEvents(IZ_JoystickState(*)[IZ_PLAYERS], IZ_Action(*)[IZ_PLAYERS], SDL_Event); - -IZ_ProcedureResult IZ_JoystickInitialize(IZ_JoystickState(*)[IZ_PLAYERS], const char*, u8, const char*[]); - -void IZ_JoystickTeardown(IZ_JoystickState(*)[IZ_PLAYERS]); - -#endif diff --git a/src/packages/game/input/IZ_keyboard.c b/src/packages/game/input/IZ_keyboard.c index e364706..3f3a5f9 100644 --- a/src/packages/game/input/IZ_keyboard.c +++ b/src/packages/game/input/IZ_keyboard.c @@ -2,12 +2,12 @@ static INI_ConfigItem keyboard_config_items[IZ_PLAYERS * IZ_CONTROLS + 1]; -void IZ_KeyboardSerializeControl(i32 value, char control[128]) { +void IZ_KeyboardSerializeControl(i32 value, char control[128], void* _unused) { const char* serialized = SDL_GetKeyName(value); IZ_memcpy(control, 128, serialized, 128); } -i32 IZ_KeyboardDeserializeControl(const char* control) { +i32 IZ_KeyboardDeserializeControl(const char* control, void* _unused) { return SDL_GetKeyFromName(control); } diff --git a/src/packages/game/input/IZ_keyboard.h b/src/packages/game/input/IZ_keyboard.h index 718f37a..92abf3c 100644 --- a/src/packages/game/input/IZ_keyboard.h +++ b/src/packages/game/input/IZ_keyboard.h @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include "../../stdinc/IZ_string.h" #include "../../stdinc/IZ_stdlib.h" #include "IZ_action.h" diff --git a/src/packages/game/input/IZ_midi.h b/src/packages/game/input/IZ_midi.h index 536058f..ac06a58 100644 --- a/src/packages/game/input/IZ_midi.h +++ b/src/packages/game/input/IZ_midi.h @@ -6,7 +6,7 @@ #include #include -#include +#include #include "../../stdinc/IZ_string.h" #include "../../stdinc/IZ_stdlib.h" #include "IZ_action.h" diff --git a/src/packages/net/IZ_net_client.h b/src/packages/net/IZ_net_client.h index 03df062..714fa0b 100644 --- a/src/packages/net/IZ_net_client.h +++ b/src/packages/net/IZ_net_client.h @@ -3,8 +3,8 @@ #include #include -#include -#include +#include +#include #include "../common/IZ_common.h" #include "../game/input/IZ_action.h" diff --git a/subprojects/ini-config b/subprojects/ini-config index b5007a8..f3eb15d 160000 --- a/subprojects/ini-config +++ b/subprojects/ini-config @@ -1 +1 @@ -Subproject commit b5007a86c4c9db88427362a9cda53ce8315cbfbd +Subproject commit f3eb15d59ce81fb92a16375189f1d4755e2b7574