Starter project for SDL2.
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.

176 lines
5.0 KiB

  1. #include <SDL.h>
  2. #include <stdbool.h>
  3. #include <stdio.h>
  4. #include "IZ_action.h"
  5. #include "IZ_app.h"
  6. int main(int argc, char* args[]) {
  7. SDL_Window* window = NULL;
  8. SDL_Surface* screen_surface = NULL;
  9. IZ_App app;
  10. IZ_InitializeApp(&app);
  11. if (SDL_Init(
  12. SDL_INIT_VIDEO
  13. | SDL_INIT_GAMECONTROLLER
  14. | SDL_INIT_EVENTS
  15. ) < 0) {
  16. printf("SDL could not initialize! SDL_Error: %s\n", SDL_GetError());
  17. return -1;
  18. }
  19. window = SDL_CreateWindow(
  20. APP_NAME,
  21. SDL_WINDOWPOS_CENTERED,
  22. SDL_WINDOWPOS_CENTERED,
  23. app.config.video.width,
  24. app.config.video.height,
  25. SDL_WINDOW_SHOWN
  26. );
  27. if (window == NULL) {
  28. printf("Window could not be created! SDL_Error: %s\n", SDL_GetError());
  29. return -2;
  30. }
  31. screen_surface = SDL_GetWindowSurface(window);
  32. bool quit = false;
  33. SDL_Event e;
  34. while (true) {
  35. uint64_t ticks = SDL_GetTicks64();
  36. while (SDL_PollEvent(&e) != 0) {
  37. if (e.type == SDL_QUIT) {
  38. quit = true;
  39. break;
  40. }
  41. // Handle joystick events
  42. for (uint8_t current_player = 0; current_player < PLAYERS; current_player += 1) {
  43. if (e.type == SDL_JOYDEVICEADDED) {
  44. if (SDL_NumJoysticks() <= PLAYERS && !app.assigned_joysticks[current_player]) {
  45. app.assigned_joysticks[current_player] = SDL_JoystickOpen(e.jdevice.which);
  46. }
  47. }
  48. if (e.type == SDL_JOYDEVICEREMOVED) {
  49. if (
  50. app.assigned_joysticks[current_player]
  51. && SDL_JoystickInstanceID(app.assigned_joysticks[current_player]) == e.jdevice.which
  52. ) {
  53. app.assigned_joysticks[current_player] = NULL;
  54. }
  55. }
  56. if (e.type == SDL_JOYAXISMOTION) {
  57. if (e.jaxis.axis == 0 || e.jaxis.axis == 3) {
  58. app.actions[current_player] &= ~(0x1 << IZ_ACTION_INDEX_RIGHT);
  59. app.actions[current_player] &= ~(0x1 << IZ_ACTION_INDEX_LEFT);
  60. if (e.jaxis.value > app.config.input.gamepad_axis_threshold) {
  61. app.actions[current_player] |= (0x1 << IZ_ACTION_INDEX_RIGHT);
  62. } else if (e.jaxis.value <= -app.config.input.gamepad_axis_threshold) {
  63. app.actions[current_player] |= (0x1 << IZ_ACTION_INDEX_LEFT);
  64. }
  65. }
  66. if (e.jaxis.axis == 1 || e.jaxis.axis == 4) {
  67. app.actions[current_player] &= ~(0x1 << IZ_ACTION_INDEX_UP);
  68. app.actions[current_player] &= ~(0x1 << IZ_ACTION_INDEX_DOWN);
  69. if (e.jaxis.value > app.config.input.gamepad_axis_threshold) {
  70. app.actions[current_player] |= (0x1 << IZ_ACTION_INDEX_DOWN);
  71. } else if (e.jaxis.value <= -app.config.input.gamepad_axis_threshold) {
  72. app.actions[current_player] |= (0x1 << IZ_ACTION_INDEX_UP);
  73. }
  74. }
  75. }
  76. if (e.type == SDL_JOYHATMOTION) {
  77. app.actions[current_player] &= ~(0x1 << IZ_ACTION_INDEX_UP);
  78. app.actions[current_player] &= ~(0x1 << IZ_ACTION_INDEX_RIGHT);
  79. app.actions[current_player] &= ~(0x1 << IZ_ACTION_INDEX_DOWN);
  80. app.actions[current_player] &= ~(0x1 << IZ_ACTION_INDEX_LEFT);
  81. if (e.jhat.value != 0) {
  82. app.actions[current_player] |= e.jhat.value;
  83. }
  84. }
  85. }
  86. // Handle keyboard events
  87. for (uint8_t current_player = 0; current_player < PLAYERS; current_player += 1) {
  88. for (uint8_t i = 0; i < CONTROLS; i += 1) {
  89. if (e.key.keysym.sym == app.config.controls[current_player].keyboard[i]) {
  90. const uint16_t bitflag = (0x1 << i);
  91. if (e.type == SDL_KEYDOWN) {
  92. app.actions[current_player] |= bitflag;
  93. } else if (e.type == SDL_KEYUP) {
  94. app.actions[current_player] &= ~bitflag;
  95. }
  96. }
  97. if (i >= 4) {
  98. if (e.jbutton.button == app.config.controls[current_player].gamepad[i]) {
  99. const uint16_t bitflag = (0x1 << i);
  100. if (e.type == SDL_JOYBUTTONDOWN) {
  101. app.actions[current_player] |= bitflag;
  102. } else if (e.type == SDL_JOYBUTTONUP) {
  103. app.actions[current_player] &= ~bitflag;
  104. }
  105. }
  106. }
  107. }
  108. }
  109. }
  110. if (quit) {
  111. break;
  112. }
  113. if (ticks - app.video_update_at > 1000 / app.config.video.max_fps) {
  114. // Update window
  115. SDL_FillRect(screen_surface, NULL, SDL_MapRGB(screen_surface->format, 0x00, 0x00, 0x00));
  116. for (uint8_t i = 0; i < 64; i += 1) {
  117. const uint8_t column = (64 - i) % 32;
  118. const uint8_t row = i / 32;
  119. const uint64_t bitflag = (0x1lu << i);
  120. const uint8_t size = 4;
  121. if (ticks & bitflag) {
  122. SDL_FillRect(screen_surface, &(SDL_Rect) {
  123. column * size,
  124. app.config.video.height - ((row + 1) * size),
  125. size,
  126. size
  127. }, SDL_MapRGB(screen_surface->format, 0x00, 0xff, 0xff));
  128. }
  129. }
  130. for (uint8_t current_player = 0; current_player < PLAYERS; current_player += 1) {
  131. for (uint8_t i = 0; i < CONTROLS; i += 1) {
  132. const uint8_t column = i % 4;
  133. const uint8_t row = i / 4;
  134. const IZ_Action bitflag = (0x1 << i);
  135. const uint8_t size = 4;
  136. if (app.actions[current_player] & bitflag) {
  137. SDL_FillRect(screen_surface, &(SDL_Rect) {
  138. column * size,
  139. row * size,
  140. size,
  141. size
  142. }, SDL_MapRGB(screen_surface->format, 0xff, 0xff, 0x00));
  143. }
  144. }
  145. }
  146. SDL_UpdateWindowSurface(window);
  147. app.video_update_at = ticks;
  148. }
  149. }
  150. SDL_DestroyWindow(window);
  151. SDL_Quit();
  152. return 0;
  153. }