Das Programmierspiel von der Gulasch-Programmier-Nacht 11

(Latest mirror + merged latest fork by qr4 on Lua 5.3)

Entropia info page https://entropia.de/GPN11:Programmierspiel (dead links)
Origin Gitlab
https://code.nerd2nerd.org/n2n/WeltraumProgrammierNacht

screen.c 6.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. #include <stdio.h>
  2. #include <sys/time.h>
  3. #include <SDL/SDL.h>
  4. #include <SDL/SDL_gfxPrimitives.h>
  5. #include <errno.h>
  6. #include "globals.h"
  7. #include "screen.h"
  8. #include "route.h"
  9. /* TODO:
  10. *
  11. * a global scene for easy rerender
  12. * fast image switch
  13. */
  14. SDL_Surface *screen;
  15. int safety_radius;
  16. void sdl_setup() {
  17. const SDL_VideoInfo *info;
  18. if (SDL_Init(SDL_INIT_VIDEO) == -1) {
  19. ERROR("SDL_Init() failed: %s\n", SDL_GetError());
  20. exit(1);
  21. }
  22. info = SDL_GetVideoInfo();
  23. GLOBALS.DISPLAY_WIDTH = info->current_w;
  24. GLOBALS.DISPLAY_HEIGHT = info->current_h;
  25. atexit(SDL_Quit);
  26. }
  27. void sdl_screen_init() {
  28. if (GLOBALS.FULLSCREEN) {
  29. screen = SDL_SetVideoMode(GLOBALS.DISPLAY_WIDTH, GLOBALS.DISPLAY_HEIGHT, 0, SDL_FULLSCREEN);
  30. } else {
  31. screen = SDL_SetVideoMode(GLOBALS.WIDTH, GLOBALS.HEIGHT, 0, 0);
  32. }
  33. }
  34. void sdl_init() {
  35. sdl_setup();
  36. sdl_screen_init();
  37. if (screen == NULL) {
  38. ERROR("SDL_SetVideoMode() failed: %s\n", SDL_GetError());
  39. exit(1);
  40. }
  41. }
  42. void draw_line(pixel_t *p1, pixel_t *p2) {
  43. aalineRGBA(screen, p1->x, p1->y, p2->x, p2->y, 255, 255, 255, 255);
  44. }
  45. void draw_blob(pixel_t *p1) {
  46. aacircleRGBA(screen, p1->x, p1->y, 2, 255, 255, 255, 255);
  47. aacircleRGBA(screen, p1->x, p1->y, safety_radius, 64, 64, 64, 255);
  48. }
  49. void draw_points(pixel_t *points, int n) {
  50. int x, y;
  51. for (y = 0; y < n; y++) {
  52. for (x = 0; x < n; x++) {
  53. draw_blob(&points[y*n + x]);
  54. }
  55. }
  56. }
  57. void draw_grid(pixel_t *points, int n) {
  58. int x, y;
  59. for (y = 0; y < n - 1; y++) {
  60. for (x = 0; x < n - 1; x++) {
  61. draw_line(&points[y*n + x], &points[y*n + x + 1]);
  62. draw_line(&points[y*n + x], &points[(y + 1)*n + x]);
  63. }
  64. draw_line(&points[y*n + x], &points[(y + 1)*n + x]);
  65. }
  66. for (x = 0; x < n - 1; x++) {
  67. draw_line(&points[y*n + x], &points[y*n + x + 1]);
  68. }
  69. }
  70. void draw_route(waypoint_t* route, int r, int g, int b) {
  71. waypoint_t* t = route;
  72. while (t->next != NULL) {
  73. aacircleRGBA(screen, t->point.x, t->point.y, 2, r, g, b, 255);
  74. aalineRGBA(screen, t->point.x, t->point.y, t->next->point.x, t->next->point.y, r, g, b, 64);
  75. t = t->next;
  76. }
  77. aacircleRGBA(screen, t->point.x, t->point.y, 2, r, g, g, 255);
  78. }
  79. void randomize(pixel_t *points, int n, float fac) {
  80. int i;
  81. for (i = 0; i < n * n; i++) {
  82. points[i].x += (((float) rand() / RAND_MAX) - 0.5) * 2 * fac;
  83. points[i].y += (((float) rand() / RAND_MAX) - 0.5) * 2 * fac;
  84. }
  85. }
  86. void set(pixel_t *points, int n) {
  87. int x, y;
  88. for (y = 0; y < n; y++) {
  89. for (x = 0; x < n; x++) {
  90. points[y*n + x].x = GLOBALS.WIDTH * (x + 1) / (n + 1);
  91. points[y*n + x].y = GLOBALS.HEIGHT * (y + 1) / (n + 1);
  92. }
  93. }
  94. }
  95. int main_loop() {
  96. int quit = 0;
  97. int n = 16;
  98. int view_grid = 0;
  99. int view_points = 1;
  100. float fac = GLOBALS.WIDTH / (n + 1) * 0.3;
  101. SDL_Event e;
  102. pixel_t *points;
  103. pixel_t start = {0, 0};
  104. pixel_t stop = {0, 0};
  105. waypoint_t* route1 = NULL;
  106. waypoint_t* route1s = NULL;
  107. waypoint_t* route2 = NULL;
  108. waypoint_t* route2s = NULL;
  109. struct timeval t1, t2;
  110. double elapsedTime;
  111. points = (pixel_t *) malloc (sizeof(pixel_t) * n * n);
  112. set(points, n);
  113. while (!quit) {
  114. safety_radius = GLOBALS.HEIGHT / (n + 1) / 5 ;
  115. SDL_FillRect( SDL_GetVideoSurface(), NULL, 0 );
  116. if (view_grid) {
  117. draw_grid(points, n);
  118. }
  119. if (view_points) {
  120. draw_points(points, n);
  121. }
  122. if (route1s != NULL) {
  123. draw_route(route1s, 0, 0, 255);
  124. }
  125. if (route2s != NULL) {
  126. draw_route(route2s, 255, 255, 0);
  127. }
  128. if (start.x != 0 && start.y != 0) {
  129. aacircleRGBA(screen, start.x, start.y, 2, 0, 255, 0, 255);
  130. }
  131. if (stop.x != 0 && stop.y != 0) {
  132. aacircleRGBA(screen, stop.x, stop.y, 2, 255, 0, 0, 255);
  133. }
  134. SDL_Flip(screen);
  135. SDL_WaitEvent(&e);
  136. switch (e.type) {
  137. case SDL_QUIT :
  138. quit = 1;
  139. break;
  140. case SDL_MOUSEBUTTONDOWN :
  141. switch (e.button.button) {
  142. case SDL_BUTTON_LEFT:
  143. start.x = e.button.x;
  144. start.y = e.button.y;
  145. break;
  146. case SDL_BUTTON_RIGHT:
  147. stop.x = e.button.x;
  148. stop.y = e.button.y;
  149. break;
  150. }
  151. if (start.x != 0 && start.y != 0 && stop.x != 0 && stop.y != 0) {
  152. printf("\n\nRoute from (%f,%f) to (%f,%f)\n", start.x, start.y, stop.x, stop.y);
  153. gettimeofday(&t1, NULL);
  154. route1 = plotCourse(&start, &stop, points, n);
  155. gettimeofday(&t2, NULL);
  156. elapsedTime = (t2.tv_sec - t1.tv_sec) * 1000.0;
  157. elapsedTime += (t2.tv_usec - t1.tv_usec) / 1000.0;
  158. printf("plotCourse scanline based took %f ms\n", elapsedTime);
  159. gettimeofday(&t1, NULL);
  160. route1s = smooth(route1, 5);
  161. gettimeofday(&t2, NULL);
  162. elapsedTime = (t2.tv_sec - t1.tv_sec) * 1000.0;
  163. elapsedTime += (t2.tv_usec - t1.tv_usec) / 1000.0;
  164. printf("smoth scanline based route took %f ms\n", elapsedTime);
  165. gettimeofday(&t1, NULL);
  166. route2 = plotCourse_gridbased(&start, &stop, points, n);
  167. gettimeofday(&t2, NULL);
  168. elapsedTime = (t2.tv_sec - t1.tv_sec) * 1000.0;
  169. elapsedTime += (t2.tv_usec - t1.tv_usec) / 1000.0;
  170. printf("plotCourse gridline based took %f ms\n", elapsedTime);
  171. gettimeofday(&t1, NULL);
  172. route2s = smooth(route2, 5);
  173. gettimeofday(&t2, NULL);
  174. elapsedTime = (t2.tv_sec - t1.tv_sec) * 1000.0;
  175. elapsedTime += (t2.tv_usec - t1.tv_usec) / 1000.0;
  176. printf("smooth gridline based route took %f ms\n", elapsedTime);
  177. /*
  178. waypoint_t* r = route;
  179. while (r != NULL) {
  180. printf("Waypoint (%f,%f)\n", r->point.x, r->point.y);
  181. r = r->next;
  182. }
  183. */
  184. }
  185. break;
  186. case SDL_KEYDOWN :
  187. switch (e.key.keysym.sym) {
  188. case SDLK_p:
  189. view_points = !view_points;
  190. break;
  191. case SDLK_g:
  192. case SDLK_l:
  193. view_grid = !view_grid;
  194. break;
  195. case SDLK_r:
  196. randomize(points, n, fac);
  197. break;
  198. case SDLK_s:
  199. set(points, n);
  200. break;
  201. case SDLK_q:
  202. quit = 1;
  203. break;
  204. case SDLK_UP:
  205. n++;
  206. points = (pixel_t *) realloc (points, sizeof(pixel_t) * n * n);
  207. fac = GLOBALS.WIDTH / (n + 1) * 0.3;
  208. set(points, n);
  209. break;
  210. case SDLK_DOWN:
  211. n--;
  212. points = (pixel_t *) realloc (points, sizeof(pixel_t) * n * n);
  213. fac = GLOBALS.WIDTH / (n + 1) * 0.3;
  214. set(points, n);
  215. break;
  216. case SDLK_PLUS:
  217. case SDLK_KP_PLUS:
  218. fac *= 1.1;
  219. printf("fac: %f\n", fac);
  220. set(points, n);
  221. randomize(points, n, fac);
  222. break;
  223. case SDLK_MINUS:
  224. case SDLK_KP_MINUS:
  225. fac /= 1.1;
  226. printf("fac: %f\n", fac);
  227. set(points, n);
  228. randomize(points, n, fac);
  229. break;
  230. default:
  231. break;
  232. }
  233. break;
  234. case SDL_VIDEORESIZE:
  235. GLOBALS.WIDTH = e.resize.w;
  236. GLOBALS.HEIGHT = e.resize.h;
  237. sdl_screen_init();
  238. break;
  239. default :
  240. break;
  241. }
  242. }
  243. free(points);
  244. return 0;
  245. }