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.
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

231 linhas
7.7KB

  1. #include <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_menu_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_menu_button = SDL_CONTROLLER_BUTTON_X;
  61. static const int sdl_save_button = SDL_CONTROLLER_BUTTON_LEFTSHOULDER;
  62. static const int sdl_load_button = SDL_CONTROLLER_BUTTON_RIGHTSHOULDER;
  63. static const int sdl_buttons[nes_controller_num_buttons] = {
  64. SDL_CONTROLLER_BUTTON_A,
  65. SDL_CONTROLLER_BUTTON_B,
  66. SDL_CONTROLLER_BUTTON_BACK,
  67. SDL_CONTROLLER_BUTTON_START,
  68. SDL_CONTROLLER_BUTTON_DPAD_UP,
  69. SDL_CONTROLLER_BUTTON_DPAD_DOWN,
  70. SDL_CONTROLLER_BUTTON_DPAD_LEFT,
  71. SDL_CONTROLLER_BUTTON_DPAD_RIGHT,
  72. };
  73. static int button_index(int keycode, const int* codes) {
  74. int index = nes_controller_num_buttons - 1;
  75. for ( ; index >= 0 && keycode != codes[index]; --index);
  76. return index;
  77. }
  78. static int sdl_input_update(nes_Input_Reader* reader,
  79. nes_input* input) {
  80. int status = input_Result_OK;
  81. SDL_Event event = {0};
  82. while (0 == status && 0 != SDL_PollEvent(&event)) {
  83. if (SDL_QUIT == event.type) {
  84. status = input_Result_Quit;
  85. } else if (SDL_WINDOWEVENT == event.type) {
  86. if ( SDL_WINDOWEVENT_EXPOSED ==
  87. event.window.event) {
  88. status = input_Result_Refresh;
  89. }
  90. } else if ( ( SDL_KEYDOWN == event.type ||
  91. SDL_KEYUP == event.type) &&
  92. 0 == event.key.repeat
  93. ) {
  94. int index = button_index(event.key.keysym.sym,
  95. sdl_keycodes);
  96. if (index >= 0) {
  97. uint8_t mask = (1 << index);
  98. if (SDL_KEYDOWN == event.type) {
  99. input->controllers[0].buttons |= mask;
  100. } else {
  101. input->controllers[0].buttons &= ~mask;
  102. }
  103. } else if ( sdl_menu_key == event.key.keysym.sym &&
  104. SDL_KEYDOWN == event.type) {
  105. status = input_Result_Menu;
  106. } else if (sdl_save_key == event.key.keysym.sym) {
  107. if (SDL_KEYDOWN == event.type) {
  108. status = input_Result_Save;
  109. } else {
  110. status = input_Result_Cancel;
  111. }
  112. } else if (sdl_load_key == event.key.keysym.sym) {
  113. if (SDL_KEYDOWN == event.type) {
  114. status = input_Result_Load;
  115. } else {
  116. status = input_Result_Cancel;
  117. }
  118. }
  119. } else if ( SDL_CONTROLLERBUTTONDOWN == event.type ||
  120. SDL_CONTROLLERBUTTONUP == event.type) {
  121. int index = button_index(event.cbutton.button,
  122. sdl_buttons);
  123. if (index >= 0) {
  124. uint8_t mask = (1 << index);
  125. if (SDL_CONTROLLERBUTTONDOWN == event.type) {
  126. input->controllers[0].buttons |= mask;
  127. } else {
  128. input->controllers[0].buttons &= ~mask;
  129. }
  130. } else if (sdl_menu_button == event.cbutton.button) {
  131. if (SDL_CONTROLLERBUTTONDOWN == event.type) {
  132. status = input_Result_Menu;
  133. }
  134. } else if (sdl_save_button == event.cbutton.button) {
  135. if (SDL_CONTROLLERBUTTONDOWN == event.type) {
  136. status = input_Result_Save;
  137. } else {
  138. status = input_Result_Cancel;
  139. }
  140. } else if (sdl_load_button == event.cbutton.button) {
  141. if (SDL_CONTROLLERBUTTONDOWN == event.type) {
  142. status = input_Result_Load;
  143. } else {
  144. status = input_Result_Cancel;
  145. }
  146. }
  147. } else if (SDL_CONTROLLERAXISMOTION == event.type) {
  148. const uint8_t axis = event.caxis.axis;
  149. const int16_t value = event.caxis.value;
  150. uint8_t mask_set = 0;
  151. uint8_t mask_clear = 0;
  152. if (SDL_CONTROLLER_AXIS_LEFTX == axis) {
  153. mask_clear = (1 << Button_Left) |
  154. (1 << Button_Right);
  155. if (value <= -8192) {
  156. mask_set = (1 << Button_Left);
  157. } else if (value >= 8192) {
  158. mask_set = (1 << Button_Right);
  159. }
  160. } else if (SDL_CONTROLLER_AXIS_LEFTY == axis) {
  161. mask_clear = (1 << Button_Down) |
  162. (1 << Button_Up);
  163. if (value <= -8192) {
  164. mask_set = (1 << Button_Up);
  165. } else if (value >= 8192) {
  166. mask_set = (1 << Button_Down);
  167. }
  168. }
  169. input->controllers[0].buttons &= ~mask_clear;
  170. input->controllers[0].buttons |= mask_set;
  171. } else if (SDL_CONTROLLERDEVICEADDED == event.type) {
  172. if (NULL == reader->data) {
  173. printf("New gamepad connected\n");
  174. reader->data = sdl_find_gamepad();
  175. if (reader->data) printf("Using new gamepad\n");
  176. } else {
  177. printf("Redundant gamepad connected\n");
  178. }
  179. } else if (SDL_CONTROLLERDEVICEREMOVED == event.type) {
  180. if (sdl_match_gamepad(event.cdevice.which,
  181. reader->data)) {
  182. printf("Gamepad disconnected\n");
  183. sdl_lose_gamepad(reader->data);
  184. reader->data = sdl_find_gamepad();
  185. if (reader->data) printf("Using another gamepad\n");
  186. } else {
  187. printf("Redundant gamepad disconnected\n");
  188. }
  189. }
  190. }
  191. return status;
  192. }
  193. nes_Input_Reader sdl_input = {
  194. .init = sdl_input_init,
  195. .done = sdl_input_done,
  196. .update = sdl_input_update,
  197. };