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.

180 lines
4.1 KiB

  1. #include <SDL.h>
  2. #include <stdbool.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <minIni.h>
  6. const char* APP_NAME = "SDL2";
  7. static const unsigned char CONTROLS = 16;
  8. static const unsigned char PLAYERS = 1;
  9. static const SDL_KeyCode KEYBOARD_CONTROLS[CONTROLS] = {
  10. SDLK_RIGHT,
  11. SDLK_DOWN,
  12. SDLK_LEFT,
  13. SDLK_UP,
  14. SDLK_RETURN, // yes
  15. SDLK_BACKSPACE, // no
  16. SDLK_a, // action0
  17. SDLK_s, // action1
  18. SDLK_d, // action2
  19. SDLK_f, // action3
  20. SDLK_z, // action4
  21. SDLK_x, // action5
  22. SDLK_c, // action6
  23. SDLK_v, // action7
  24. SDLK_w, // action8
  25. SDLK_e, // action9
  26. };
  27. static const char* ACTION_NAMES[CONTROLS] = {
  28. "Right",
  29. "Down",
  30. "Left",
  31. "Up",
  32. "Affirm",
  33. "Negate",
  34. "Action0",
  35. "Action1",
  36. "Action2",
  37. "Action3",
  38. "Action4",
  39. "Action5",
  40. "Action6",
  41. "Action7",
  42. "Action8",
  43. "Action9",
  44. };
  45. typedef struct {
  46. unsigned int width;
  47. unsigned int height;
  48. } IZ_VideoConfig;
  49. typedef SDL_KeyCode IZ_KeyCode;
  50. typedef int IZ_PadButton;
  51. typedef struct {
  52. IZ_KeyCode keyboard[CONTROLS];
  53. IZ_PadButton gamepad[CONTROLS];
  54. } IZ_ControlsConfig;
  55. typedef struct {
  56. IZ_VideoConfig video;
  57. IZ_ControlsConfig controls[PLAYERS];
  58. } IZ_Config;
  59. static void IZ_GetConfigPath(char* config_path) {
  60. //const char* config_path_dir = SDL_GetPrefPath("Modal Studios", APP_NAME);
  61. const char* config_path_dir = SDL_GetBasePath();
  62. memcpy_s(config_path, 128, config_path_dir, 128);
  63. strcat_s(config_path, 128, "config.ini");
  64. }
  65. static void IZ_LoadConfig(IZ_Config* config) {
  66. static char config_path[128];
  67. IZ_GetConfigPath(config_path);
  68. // TODO check if file exists first
  69. config->video.width = ini_getl("Video", "Width", 640l, config_path);
  70. config->video.height = ini_getl("Video", "Height", 480l, config_path);
  71. char buffer[128];
  72. for (int i = 0; i < CONTROLS; i += 1) {
  73. ini_gets("Controls.0.Keyboard", ACTION_NAMES[i], SDL_GetKeyName(KEYBOARD_CONTROLS[i]), buffer, 128, config_path);
  74. config->controls[0].keyboard[i] = SDL_GetKeyFromName(buffer);
  75. }
  76. }
  77. int main(int argc, char* args[]) {
  78. SDL_Window* window = NULL;
  79. SDL_Surface* screen_surface = NULL;
  80. IZ_Config config;
  81. IZ_LoadConfig(&config);
  82. if (SDL_Init(
  83. SDL_INIT_VIDEO
  84. | SDL_INIT_GAMECONTROLLER
  85. | SDL_INIT_EVENTS
  86. ) < 0) {
  87. printf("SDL could not initialize! SDL_Error: %s\n", SDL_GetError());
  88. return -1;
  89. }
  90. window = SDL_CreateWindow(
  91. APP_NAME,
  92. SDL_WINDOWPOS_CENTERED,
  93. SDL_WINDOWPOS_CENTERED,
  94. config.video.width,
  95. config.video.height,
  96. SDL_WINDOW_SHOWN
  97. );
  98. if (window == NULL) {
  99. printf("Window could not be created! SDL_Error: %s\n", SDL_GetError());
  100. return -2;
  101. }
  102. bool quit = false;
  103. SDL_Event e;
  104. screen_surface = SDL_GetWindowSurface(window);
  105. unsigned short action = 0;
  106. while (!quit) {
  107. SDL_FillRect(screen_surface, NULL, SDL_MapRGB(screen_surface->format, 0x00, 0x00, 0x00));
  108. uint64_t ticks = SDL_GetTicks64();
  109. for (unsigned char i = 0; i < 64; i += 1) {
  110. const unsigned char column = (64 - i) % 32;
  111. const unsigned char row = i / 32;
  112. const uint64_t bitflag = (0x1lu << i);
  113. const unsigned char size = 4;
  114. if (ticks & bitflag) {
  115. SDL_FillRect(screen_surface, &(SDL_Rect) {
  116. column * size,
  117. config.video.height - ((row + 1) * size),
  118. size,
  119. size
  120. }, SDL_MapRGB(screen_surface->format, 0x00, 0xff, 0xff));
  121. }
  122. }
  123. while (SDL_PollEvent(&e) != 0) {
  124. if (e.type == SDL_QUIT) {
  125. quit = true;
  126. }
  127. for (unsigned char i = 0; i < CONTROLS; i += 1) {
  128. // TODO do same for gamepad
  129. if (e.key.keysym.sym == config.controls[0].keyboard[i]) {
  130. const unsigned short bitflag = (0x1 << i);
  131. if (e.type == SDL_KEYDOWN) {
  132. action |= bitflag;
  133. } else if (e.type == SDL_KEYUP) {
  134. action &= ~bitflag;
  135. }
  136. }
  137. }
  138. for (unsigned char i = 0; i < CONTROLS; i += 1) {
  139. const unsigned char column = i % 4;
  140. const unsigned char row = i / 4;
  141. const unsigned short bitflag = (0x1 << i);
  142. const unsigned char size = 4;
  143. if (action & bitflag) {
  144. SDL_FillRect(screen_surface, &(SDL_Rect) {
  145. column * size,
  146. row * size,
  147. size,
  148. size
  149. }, SDL_MapRGB(screen_surface->format, 0xff, 0xff, 0x00));
  150. }
  151. }
  152. SDL_UpdateWindowSurface(window);
  153. }
  154. }
  155. SDL_DestroyWindow(window);
  156. SDL_Quit();
  157. return 0;
  158. }