C   108
sdl fire blur
Guest on 10th June 2022 01:29:06 PM


  1. /*
  2.  * Make with:
  3.  *
  4.  * gcc -Wall -o sdl-fire sdl-fire.c -lSDL
  5.  *
  6.  */
  7. #include <math.h>
  8. #include <stdint.h>
  9. #include <stdlib.h>
  10. #include <unistd.h>
  11. #if defined(_MSC_VER)
  12. #include "SDL.h"
  13. #else
  14. #include "SDL/SDL.h"
  15. #endif
  16.  
  17. #include "palette.h"
  18.  
  19. #define WIDTH           320
  20. //#define HEIGHT                150
  21. #define HEIGHT          100
  22. #define RADIUS          50
  23.  
  24. SDL_Surface *screen;
  25. int flamebuf[WIDTH][HEIGHT];
  26.  
  27. void do_fire(int buf[WIDTH][HEIGHT]) {
  28.         int x, y;
  29.  
  30.         /*
  31.          * Set a random bottom row.
  32.          */
  33.         for (x = 0; x < WIDTH; x++) {
  34.                 buf[x][0] =
  35.                         (random() % 256);
  36.         }
  37.  
  38.         for (y = HEIGHT - 1; y > 0; y--) {
  39.                 for (x = 0; x < WIDTH; x++) {
  40.                         buf[x][y] =
  41.                         (buf[(x + WIDTH) % WIDTH][(y - 2) % HEIGHT] +
  42.                          buf[(x + WIDTH) % WIDTH][y - 1] +
  43.                          buf[(x - 1 + WIDTH) % WIDTH][y - 1] +
  44.                          buf[(x + 1 + WIDTH) % WIDTH][y - 1]) * 32 / 129;
  45.                 }
  46.         }
  47. }
  48.  
  49. void setpix(long x, long y, long newval)
  50. {
  51.         long yofs = screen->pitch/4;
  52.         uint32_t *pixadr = ((uint32_t *)screen->pixels) + x + y*yofs ;
  53.  
  54.         *pixadr = newval;
  55. }
  56.  
  57. void blendpix(long x, long y, long inval)
  58. {
  59.         long yofs = screen->pitch/4;
  60.         uint32_t *pixadr = ((uint32_t *)screen->pixels) + x + y*yofs ;
  61.         uint8_t srcval[4],dstval[4],newval[4];
  62.         int i;
  63.  
  64.         /* Yes, I know, so shoot me. */
  65.  
  66.         *(uint32_t *)srcval = inval;   /* incoming RGBA */
  67.         *(uint32_t *)dstval = *pixadr; /* current  RGBA */
  68.  
  69.         for (i=0;i<4;i++) {
  70.                 newval[i] = srcval[i]/2 + dstval[i]/2;
  71.         }
  72.  
  73.         *pixadr = *( (uint32_t *)&newval);
  74. }
  75.  
  76. void dopix(long x, long y, long newval)
  77. {
  78.         setpix(x,y,newval);
  79.         blendpix(x+1,y+1,newval);
  80.         blendpix(x-1,y+1,newval);
  81.         blendpix(x+1,y-1,newval);
  82.         blendpix(x-1,y-1,newval);
  83. }
  84.  
  85. void mappoint(long cx, long cy, long x, long y, long radius)
  86. {
  87.         uint32_t newval = palette[flamebuf[x % WIDTH][radius]];
  88.         if (x == 0) {
  89.                 dopix(cx,   cy+y ,newval);
  90.                 dopix(cx,   cy-y ,newval);
  91.                 dopix(cx+y, cy   ,newval);
  92.                 dopix(cx-y, cy   ,newval);
  93.  
  94.         } else if (x == y) {
  95.  
  96.                 dopix(cx+x, cy+y, newval);
  97.                 dopix(cx-x, cy+y, newval);
  98.                 dopix(cx+x, cy-y, newval);
  99.                 dopix(cx-x, cy-y, newval);
  100.  
  101.         } else if (x < y) {
  102.  
  103.                 dopix(cx+x, cy+y, newval);
  104.                 dopix(cx-x, cy+y, newval);
  105.                 dopix(cx+x, cy-y, newval);
  106.                 dopix(cx-x, cy-y, newval);
  107.  
  108.                 dopix(cx+y, cy+x, newval);
  109.                 dopix(cx-y, cy+x, newval);
  110.                 dopix(cx+y, cy-x, newval);
  111.                 dopix(cx-y, cy-x, newval);
  112.  
  113.         }
  114. }
  115.  
  116. void firetocircle(long xcenter, long ycenter, long radius)
  117. {
  118.         long x = 0;
  119.         long y = radius;
  120.         long p = (5 - radius * 4) / 4;
  121.  
  122.         mappoint(xcenter, ycenter, x, y, radius - RADIUS);
  123.         while (x < y) {
  124.                 x++;
  125.                 if (p < 0) {
  126.                         p += 2 * x + 1;
  127.                 } else {
  128.                         y--;
  129.                         p += 2 * (x - y) + 1;
  130.                 }
  131.                 mappoint(xcenter, ycenter, x, y, radius - RADIUS);
  132.         }
  133. }
  134.  
  135. void render()
  136. {
  137.         /*
  138.          * Lock surface if needed.
  139.          */
  140.         if (SDL_MUSTLOCK(screen))
  141.                 if (SDL_LockSurface(screen) < 0)
  142.                         return;
  143.  
  144.         int i;
  145.         for (i = RADIUS; i < (HEIGHT + RADIUS); i++) {
  146.                 firetocircle(screen->w / 2, screen->h / 2, i);
  147.         }
  148.  
  149.         /*
  150.          * Unlock if needed.
  151.          */
  152.         if (SDL_MUSTLOCK(screen))
  153.                 SDL_UnlockSurface(screen);
  154.  
  155.         /*
  156.          * Tell SDL to update the whole screen.
  157.          */
  158.         SDL_UpdateRect(screen, 0, 0, screen->w, screen->h);
  159. }
  160.  
  161.  
  162. // Entry point
  163. int main(int argc, char *argv[])
  164. {
  165.         // Initialize SDL's subsystems - in this case, only video.
  166.         if (SDL_Init(SDL_INIT_VIDEO) < 0) {
  167.                 fprintf(stderr, "Unable to init SDL: %s\n",
  168.                         SDL_GetError());
  169.                 exit(1);
  170.         }
  171.         // Register SDL_Quit to be called at exit; makes sure things are
  172.         // cleaned up when we quit.
  173.         atexit(SDL_Quit);
  174.  
  175.         // Attempt to create a WIDTHxHEIGHT window with 32bit pixels.
  176. //      screen = SDL_SetVideoMode(WIDTH, HEIGHT, 32, SDL_SWSURFACE);
  177.         screen = SDL_SetVideoMode(1024,768, 32, SDL_SWSURFACE);
  178.  
  179.         // If we fail, return error.
  180.         if (screen == NULL) {
  181.                 fprintf(stderr, "Unable to set 640x480 video: %s\n",
  182.                         SDL_GetError());
  183.                 exit(1);
  184.         }
  185.  
  186.         // Main loop: loop forever.
  187.         while (1) {
  188.                 // Update our fire.
  189.                 do_fire(flamebuf);
  190.                 // Render stuff
  191.                 render();
  192.  
  193.                 // Poll for events, and handle the ones we care about.
  194.                 SDL_Event event;
  195.                 while (SDL_PollEvent(&event)) {
  196.                         switch (event.type) {
  197.                         case SDL_KEYDOWN:
  198.                                 break;
  199.                         case SDL_KEYUP:
  200.                                 // If escape is pressed, return (and thus, quit)
  201.                                 if (event.key.keysym.sym == SDLK_ESCAPE)
  202.                                         return 0;
  203.                                 break;
  204.                         case SDL_QUIT:
  205.                                 return (0);
  206.                         }
  207.                 }
  208.                 usleep(50000);
  209.         }
  210.         return 0;
  211. }

Raw Paste

Login or Register to edit or fork this paste. It's free.