happy.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /*
  2. * happy.c
  3. * written by Holmes Futrell
  4. * use however you want
  5. */
  6. #include <SDL3/SDL.h>
  7. #include <SDL3/SDL_main.h>
  8. #include "common.h"
  9. #define NUM_HAPPY_FACES 100 /* number of faces to draw */
  10. #define HAPPY_FACE_SIZE 32 /* width and height of happyface */
  11. static SDL_Texture *texture = 0; /* reference to texture holding happyface */
  12. static struct
  13. {
  14. float x, y; /* position of happyface */
  15. float xvel, yvel; /* velocity of happyface */
  16. } faces[NUM_HAPPY_FACES];
  17. /*
  18. Sets initial positions and velocities of happyfaces
  19. units of velocity are pixels per millesecond
  20. */
  21. void
  22. initializeHappyFaces(SDL_Renderer *renderer)
  23. {
  24. int i;
  25. int w;
  26. int h;
  27. SDL_GetRenderLogicalSize(renderer, &w, &h);
  28. for (i = 0; i < NUM_HAPPY_FACES; i++) {
  29. faces[i].x = randomFloat(0.0f, w - HAPPY_FACE_SIZE);
  30. faces[i].y = randomFloat(0.0f, h - HAPPY_FACE_SIZE);
  31. faces[i].xvel = randomFloat(-60.0f, 60.0f);
  32. faces[i].yvel = randomFloat(-60.0f, 60.0f);
  33. }
  34. }
  35. void
  36. render(SDL_Renderer *renderer, double deltaTime)
  37. {
  38. int i;
  39. SDL_Rect srcRect;
  40. SDL_Rect dstRect;
  41. int w;
  42. int h;
  43. SDL_GetRenderLogicalSize(renderer, &w, &h);
  44. /* setup boundaries for happyface bouncing */
  45. int maxx = w - HAPPY_FACE_SIZE;
  46. int maxy = h - HAPPY_FACE_SIZE;
  47. int minx = 0;
  48. int miny = 0;
  49. /* setup rects for drawing */
  50. srcRect.x = 0;
  51. srcRect.y = 0;
  52. srcRect.w = HAPPY_FACE_SIZE;
  53. srcRect.h = HAPPY_FACE_SIZE;
  54. dstRect.w = HAPPY_FACE_SIZE;
  55. dstRect.h = HAPPY_FACE_SIZE;
  56. /* fill background in with black */
  57. SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
  58. SDL_RenderClear(renderer);
  59. /*
  60. loop through all the happy faces:
  61. - update position
  62. - update velocity (if boundary is hit)
  63. - draw
  64. */
  65. for (i = 0; i < NUM_HAPPY_FACES; i++) {
  66. faces[i].x += faces[i].xvel * deltaTime;
  67. faces[i].y += faces[i].yvel * deltaTime;
  68. if (faces[i].x > maxx) {
  69. faces[i].x = maxx;
  70. faces[i].xvel = -faces[i].xvel;
  71. } else if (faces[i].y > maxy) {
  72. faces[i].y = maxy;
  73. faces[i].yvel = -faces[i].yvel;
  74. }
  75. if (faces[i].x < minx) {
  76. faces[i].x = minx;
  77. faces[i].xvel = -faces[i].xvel;
  78. } else if (faces[i].y < miny) {
  79. faces[i].y = miny;
  80. faces[i].yvel = -faces[i].yvel;
  81. }
  82. dstRect.x = faces[i].x;
  83. dstRect.y = faces[i].y;
  84. SDL_RenderTexture(renderer, texture, &srcRect, &dstRect);
  85. }
  86. /* update screen */
  87. SDL_RenderPresent(renderer);
  88. }
  89. /*
  90. loads the happyface graphic into a texture
  91. */
  92. void
  93. initializeTexture(SDL_Renderer *renderer)
  94. {
  95. SDL_Surface *bmp_surface;
  96. /* load the bmp */
  97. bmp_surface = SDL_LoadBMP("icon.bmp");
  98. if (bmp_surface == NULL) {
  99. fatalError("could not load bmp");
  100. }
  101. /* set white to transparent on the happyface */
  102. SDL_SetSurfaceColorKey(bmp_surface, 1,
  103. SDL_MapRGB(bmp_surface->format, 255, 255, 255));
  104. /* convert RGBA surface to texture */
  105. texture = SDL_CreateTextureFromSurface(renderer, bmp_surface);
  106. if (texture == NULL) {
  107. fatalError("could not create texture");
  108. }
  109. SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
  110. /* free up allocated memory */
  111. SDL_DestroySurface(bmp_surface);
  112. }
  113. int
  114. main(int argc, char *argv[])
  115. {
  116. SDL_Window *window;
  117. SDL_Renderer *renderer;
  118. int done;
  119. int width;
  120. int height;
  121. /* initialize SDL */
  122. if (SDL_Init(SDL_INIT_VIDEO) < 0) {
  123. fatalError("Could not initialize SDL");
  124. }
  125. /* The specified window size doesn't matter - except for its aspect ratio,
  126. * which determines whether the window is in portrait or landscape on iOS
  127. * (if SDL_WINDOW_RESIZABLE isn't specified). */
  128. window = SDL_CreateWindow(NULL, 0, 0, 320, 480, SDL_WINDOW_FULLSCREEN | SDL_WINDOW_ALLOW_HIGHDPI);
  129. renderer = SDL_CreateRenderer(window, NULL, 0);
  130. SDL_GetWindowSize(window, &width, &height);
  131. SDL_SetRenderLogicalSize(renderer, width, height);
  132. initializeTexture(renderer);
  133. initializeHappyFaces(renderer);
  134. /* main loop */
  135. done = 0;
  136. while (!done) {
  137. SDL_Event event;
  138. double deltaTime = updateDeltaTime();
  139. while (SDL_PollEvent(&event)) {
  140. if (event.type == SDL_QUIT) {
  141. done = 1;
  142. }
  143. }
  144. render(renderer, deltaTime);
  145. SDL_Delay(1);
  146. }
  147. /* cleanup */
  148. SDL_DestroyTexture(texture);
  149. /* shutdown SDL */
  150. SDL_Quit();
  151. return 0;
  152. }