NESe (pronounced "Nessie") is a NES emulator based on the e6502 emulator, also written in C with a focus on speed and portability for use on embedded platforms, especially ARM.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

219 lignes
7.2KB

  1. #include <SDL2/SDL.h>
  2. #include "input.h"
  3. static SDL_GameController* sdl_find_gamepad() {
  4. int i = SDL_NumJoysticks() - 1;
  5. printf("Found %d joysticks\n", i + 1);
  6. for ( ; i >= 0 && !SDL_IsGameController(i); --i);
  7. if (i >= 0) printf("Joystick %d is a gamepad\n", i);
  8. return (i < 0 ? NULL : SDL_GameControllerOpen(i));
  9. }
  10. static void sdl_lose_gamepad(void* data) {
  11. SDL_GameController* gamepad = (SDL_GameController*)data;
  12. if (NULL != gamepad) SDL_GameControllerClose(gamepad);
  13. }
  14. static int sdl_match_gamepad(SDL_JoystickID id, void* data) {
  15. SDL_GameController* gamepad = (SDL_GameController*)data;
  16. return ( SDL_JoystickInstanceID(
  17. SDL_GameControllerGetJoystick(gamepad))
  18. == id);
  19. }
  20. /*
  21. static int sdl_event_filter(void*, SDL_Event* event) {
  22. return ( SDL_QUIT == event->type ||
  23. SDL_KEYDOWN == event->type ||
  24. SDL_KEYUP == event->type ||
  25. SDL_CONTROLLERBUTTONDOWN == event->type ||
  26. SDL_CONTROLLERBUTTONUP == event->type ||
  27. SDL_CONTROLLERDEVICEADDED == event->type ||
  28. SDL_CONTROLLERDEVICEREMOVED == event->type
  29. );
  30. }
  31. */
  32. static int sdl_input_init(nes_Input_Reader* reader) {
  33. int status = SDL_Init(SDL_INIT_EVENTS |
  34. SDL_INIT_GAMECONTROLLER);
  35. if (status == 0) {
  36. reader->data = sdl_find_gamepad();
  37. // SDL_SetEventFilter(sdl_event_filter, NULL);
  38. if (NULL != reader->data) {
  39. printf("Gamepad found\n");
  40. }
  41. }
  42. return status;
  43. }
  44. static void sdl_input_done(nes_Input_Reader* input) {
  45. sdl_lose_gamepad(input->data);
  46. }
  47. static const int sdl_reset_key = SDLK_ESCAPE;
  48. static const int sdl_save_key = SDLK_F1;
  49. static const int sdl_load_key = SDLK_F2;
  50. static const int sdl_keycodes[nes_controller_num_buttons] = {
  51. SDLK_a,
  52. SDLK_s,
  53. SDLK_q,
  54. SDLK_w,
  55. SDLK_UP,
  56. SDLK_DOWN,
  57. SDLK_LEFT,
  58. SDLK_RIGHT,
  59. };
  60. static const int sdl_save_button = SDL_CONTROLLER_BUTTON_LEFTSHOULDER;
  61. static const int sdl_load_button = SDL_CONTROLLER_BUTTON_RIGHTSHOULDER;
  62. static const int sdl_buttons[nes_controller_num_buttons] = {
  63. SDL_CONTROLLER_BUTTON_A,
  64. SDL_CONTROLLER_BUTTON_B,
  65. SDL_CONTROLLER_BUTTON_BACK,
  66. SDL_CONTROLLER_BUTTON_START,
  67. SDL_CONTROLLER_BUTTON_DPAD_UP,
  68. SDL_CONTROLLER_BUTTON_DPAD_DOWN,
  69. SDL_CONTROLLER_BUTTON_DPAD_LEFT,
  70. SDL_CONTROLLER_BUTTON_DPAD_RIGHT,
  71. };
  72. static int button_index(int keycode, const int* codes) {
  73. int index = nes_controller_num_buttons - 1;
  74. for ( ; index >= 0 && keycode != codes[index]; --index);
  75. return index;
  76. }
  77. static int sdl_input_update(nes_Input_Reader* reader,
  78. nes_input* input) {
  79. int status = input_Result_OK;
  80. SDL_Event event = {0};
  81. while (0 == status && 0 != SDL_PollEvent(&event)) {
  82. if (SDL_QUIT == event.type) {
  83. status = input_Result_Quit;
  84. } else if ( ( SDL_KEYDOWN == event.type ||
  85. SDL_KEYUP == event.type) &&
  86. 0 == event.key.repeat
  87. ) {
  88. int index = button_index(event.key.keysym.sym,
  89. sdl_keycodes);
  90. if (index >= 0) {
  91. uint8_t mask = (1 << index);
  92. if (SDL_KEYDOWN == event.type) {
  93. input->controllers[0].buttons |= mask;
  94. } else {
  95. input->controllers[0].buttons &= ~mask;
  96. }
  97. } else if ( sdl_reset_key == event.key.keysym.sym &&
  98. SDL_KEYDOWN == event.type) {
  99. status = input_Result_Reset;
  100. } else if (sdl_save_key == event.key.keysym.sym) {
  101. if (SDL_KEYDOWN == event.type) {
  102. status = input_Result_Save;
  103. } else {
  104. status = input_Result_Cancel;
  105. }
  106. } else if (sdl_load_key == event.key.keysym.sym) {
  107. if (SDL_KEYDOWN == event.type) {
  108. status = input_Result_Load;
  109. } else {
  110. status = input_Result_Cancel;
  111. }
  112. }
  113. } else if ( SDL_CONTROLLERBUTTONDOWN == event.type ||
  114. SDL_CONTROLLERBUTTONUP == event.type) {
  115. int index = button_index(event.cbutton.button,
  116. sdl_buttons);
  117. if (index >= 0) {
  118. uint8_t mask = (1 << index);
  119. if (SDL_CONTROLLERBUTTONDOWN == event.type) {
  120. input->controllers[0].buttons |= mask;
  121. } else {
  122. input->controllers[0].buttons &= ~mask;
  123. }
  124. } else if (sdl_save_button == event.cbutton.button) {
  125. if (SDL_CONTROLLERBUTTONDOWN == event.type) {
  126. status = input_Result_Save;
  127. } else {
  128. status = input_Result_Cancel;
  129. }
  130. } else if (sdl_load_button == event.cbutton.button) {
  131. if (SDL_CONTROLLERBUTTONDOWN == event.type) {
  132. status = input_Result_Load;
  133. } else {
  134. status = input_Result_Cancel;
  135. }
  136. }
  137. } else if (SDL_CONTROLLERAXISMOTION == event.type) {
  138. const uint8_t axis = event.caxis.axis;
  139. const int16_t value = event.caxis.value;
  140. uint8_t mask_set = 0;
  141. uint8_t mask_clear = 0;
  142. if (SDL_CONTROLLER_AXIS_LEFTX == axis) {
  143. mask_clear = (1 << Button_Left) |
  144. (1 << Button_Right);
  145. if (value <= -8192) {
  146. mask_set = (1 << Button_Left);
  147. } else if (value >= 8192) {
  148. mask_set = (1 << Button_Right);
  149. }
  150. } else if (SDL_CONTROLLER_AXIS_LEFTY == axis) {
  151. mask_clear = (1 << Button_Down) |
  152. (1 << Button_Up);
  153. if (value <= -8192) {
  154. mask_set = (1 << Button_Up);
  155. } else if (value >= 8192) {
  156. mask_set = (1 << Button_Down);
  157. }
  158. }
  159. input->controllers[0].buttons &= ~mask_clear;
  160. input->controllers[0].buttons |= mask_set;
  161. } else if (SDL_CONTROLLERDEVICEADDED == event.type) {
  162. if (NULL == reader->data) {
  163. printf("New gamepad connected\n");
  164. reader->data = sdl_find_gamepad();
  165. if (reader->data) printf("Using new gamepad\n");
  166. } else {
  167. printf("Redundant gamepad connected\n");
  168. }
  169. } else if (SDL_CONTROLLERDEVICEREMOVED == event.type) {
  170. if (sdl_match_gamepad(event.cdevice.which,
  171. reader->data)) {
  172. printf("Gamepad disconnected\n");
  173. sdl_lose_gamepad(reader->data);
  174. reader->data = sdl_find_gamepad();
  175. if (reader->data) printf("Using another gamepad\n");
  176. } else {
  177. printf("Redundant gamepad disconnected\n");
  178. }
  179. }
  180. }
  181. return status;
  182. }
  183. nes_Input_Reader sdl_input = {
  184. .init = sdl_input_init,
  185. .done = sdl_input_done,
  186. .update = sdl_input_update,
  187. };