2D Run-and-gun shooter inspired by One Man's Doomsday, Counter-Strike, and Metal Slug.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

193 lines
5.7 KiB

  1. #include "IZ_joystick.h"
  2. void IZ_JoystickHandleDeviceEvents(IZ_JoystickState* state, SDL_Event e) {
  3. if (e.type == SDL_JOYDEVICEADDED) {
  4. if (SDL_NumJoysticks() <= IZ_PLAYERS && !state->device) {
  5. state->device = SDL_JoystickOpen(e.jdevice.which);
  6. }
  7. return;
  8. }
  9. if (e.type == SDL_JOYDEVICEREMOVED) {
  10. if (
  11. state->device
  12. && SDL_JoystickInstanceID(state->device) == e.jdevice.which
  13. ) {
  14. state->device = NULL;
  15. }
  16. }
  17. }
  18. void IZ_JoystickHandleAxisEvents(IZ_JoystickState* state, IZ_Action* action, SDL_Event e) {
  19. if (e.type == SDL_JOYAXISMOTION) {
  20. if (
  21. e.jaxis.axis == IZ_JOY_AXIS_DIRECTION_HORIZONTAL1
  22. || e.jaxis.axis == IZ_JOY_AXIS_DIRECTION_HORIZONTAL2
  23. ) {
  24. *action &= ~(0x1 << IZ_ACTION_INDEX_RIGHT);
  25. *action &= ~(0x1 << IZ_ACTION_INDEX_LEFT);
  26. if (e.jaxis.value > state->config.axis_threshold) {
  27. *action |= (0x1 << IZ_ACTION_INDEX_RIGHT);
  28. return;
  29. }
  30. if (e.jaxis.value <= -state->config.axis_threshold) {
  31. *action |= (0x1 << IZ_ACTION_INDEX_LEFT);
  32. }
  33. return;
  34. }
  35. if (
  36. e.jaxis.axis == IZ_JOY_AXIS_DIRECTION_VERTICAL1
  37. || e.jaxis.axis == IZ_JOY_AXIS_DIRECTION_VERTICAL2
  38. ) {
  39. *action &= ~(0x1 << IZ_ACTION_INDEX_UP);
  40. *action &= ~(0x1 << IZ_ACTION_INDEX_DOWN);
  41. if (e.jaxis.value > state->config.axis_threshold) {
  42. *action |= (0x1 << IZ_ACTION_INDEX_DOWN);
  43. return;
  44. }
  45. if (e.jaxis.value <= -state->config.axis_threshold) {
  46. *action |= (0x1 << IZ_ACTION_INDEX_UP);
  47. }
  48. }
  49. }
  50. }
  51. void IZ_JoystickHandleHatEvents(IZ_Action* action, SDL_Event e) {
  52. if (e.type == SDL_JOYHATMOTION) {
  53. *action &= ~(0x1 << IZ_ACTION_INDEX_UP);
  54. *action &= ~(0x1 << IZ_ACTION_INDEX_RIGHT);
  55. *action &= ~(0x1 << IZ_ACTION_INDEX_DOWN);
  56. *action &= ~(0x1 << IZ_ACTION_INDEX_LEFT);
  57. if (e.jhat.value != 0) {
  58. *action |= e.jhat.value;
  59. }
  60. }
  61. }
  62. void IZ_JoystickHandleButtonEvents(IZ_JoystickState* state, IZ_Action* action, SDL_Event e) {
  63. u8 control_index;
  64. for (control_index = 4; control_index < CONTROLS; control_index += 1) {
  65. if (e.jbutton.button == state->config.control_mapping[control_index]) {
  66. const u16 bitflag = (0x1 << control_index);
  67. if (e.type == SDL_JOYBUTTONDOWN) {
  68. *action |= bitflag;
  69. return;
  70. }
  71. if (e.type == SDL_JOYBUTTONUP) {
  72. *action &= ~bitflag;
  73. return;
  74. }
  75. }
  76. }
  77. }
  78. void IZ_JoystickHandleEvents(IZ_JoystickState(* state)[IZ_PLAYERS], IZ_Action(* action)[IZ_PLAYERS], SDL_Event e) {
  79. u8 player_index;
  80. for (player_index = 0; player_index < IZ_PLAYERS; player_index += 1) {
  81. IZ_JoystickHandleDeviceEvents(&(*state)[player_index], e);
  82. IZ_JoystickHandleAxisEvents(&(*state)[player_index], &(*action)[player_index], e);
  83. IZ_JoystickHandleHatEvents(&(*action)[player_index], e);
  84. IZ_JoystickHandleButtonEvents(&(*state)[player_index], &(*action)[player_index], e);
  85. }
  86. }
  87. void IZ_JoystickLoadConfig(IZ_JoystickState(* state)[IZ_PLAYERS], const char* config_path) {
  88. char control_mapping_section_name[26];
  89. char main_section_name[11];
  90. u8 player_index;
  91. u8 control_index;
  92. for (player_index = 0; player_index < IZ_PLAYERS; player_index += 1) {
  93. sprintf_s(control_mapping_section_name, 26, "Joystick.%d.ControlMapping", player_index);
  94. for (control_index = 4; control_index < CONTROLS; control_index += 1) {
  95. (*state)[player_index].config.control_mapping[control_index] = ini_getl(
  96. control_mapping_section_name,
  97. ACTION_NAMES[control_index],
  98. IZ_JOYSTICK_DEFAULT_STATE[player_index].config.control_mapping[control_index],
  99. config_path
  100. );
  101. }
  102. sprintf_s(main_section_name, 11, "Joystick.%d", player_index);
  103. (*state)[player_index].config.axis_threshold = ini_getl(main_section_name, "AxisThreshold", IZ_DEFAULT_AXIS_THRESHOLD, config_path);
  104. (*state)[player_index].config.device_id = ini_getl(main_section_name, "DeviceID", player_index, config_path);
  105. }
  106. }
  107. IZ_ProcedureResult IZ_JoystickSaveConfig(IZ_JoystickState(* state)[IZ_PLAYERS], const char* config_path) {
  108. u8 problem = 0;
  109. char control_mapping_section_name[26];
  110. char main_section_name[11];
  111. u8 player_index;
  112. u8 control_index;
  113. for (player_index = 0; player_index < IZ_PLAYERS; player_index += 1) {
  114. sprintf_s(control_mapping_section_name, 26, "Joystick.%d.ControlMapping", player_index);
  115. for (control_index = 4; control_index < CONTROLS; control_index += 1) {
  116. if (!ini_putl(
  117. control_mapping_section_name,
  118. ACTION_NAMES[control_index],
  119. (*state)[player_index].config.control_mapping[control_index],
  120. config_path
  121. )) {
  122. problem |= (1 << player_index);
  123. }
  124. }
  125. sprintf_s(main_section_name, 11, "Joystick.%d", player_index);
  126. if (!ini_putl(
  127. main_section_name,
  128. "DeviceID",
  129. (*state)[player_index].config.device_id,
  130. config_path
  131. )) {
  132. problem |= (1 << player_index);
  133. }
  134. if (!ini_putl(
  135. main_section_name,
  136. "AxisThreshold",
  137. (*state)[player_index].config.axis_threshold,
  138. config_path
  139. )) {
  140. problem |= (1 << player_index);
  141. }
  142. }
  143. return -problem;
  144. }
  145. IZ_ProcedureResult IZ_JoystickInitialize(IZ_JoystickState(* state)[IZ_PLAYERS], const char* config_path, u8 argc, const char* argv[]) {
  146. SDL_memcpy(state, &IZ_JOYSTICK_DEFAULT_STATE, sizeof(IZ_JoystickState));
  147. IZ_JoystickLoadConfig(state, config_path);
  148. if (IZ_JoystickSaveConfig(state, config_path) < 0) {
  149. return -1;
  150. }
  151. u8 joysticks_count = SDL_NumJoysticks();
  152. u8 player_index;
  153. for (player_index = 0; player_index < joysticks_count; player_index += 1) {
  154. if (player_index >= IZ_PLAYERS) {
  155. break;
  156. }
  157. (*state)[player_index].device = SDL_JoystickOpen(state[player_index]->config.device_id);
  158. }
  159. return 0;
  160. }
  161. void IZ_JoystickTeardown(IZ_JoystickState(* state)[IZ_PLAYERS]) {
  162. u8 player_index;
  163. for (player_index = 0; player_index < IZ_PLAYERS; player_index += 1) {
  164. if (!(*state)[player_index].device) {
  165. continue;
  166. }
  167. SDL_JoystickClose((*state)[player_index].device);
  168. }
  169. }