- /*
- * Make with:
- *
- * gcc -Wall -o sdl-fire sdl-fire.c -lSDL
- *
- */
- #include <math.h>
- #include <stdint.h>
- #include <stdlib.h>
- #include <unistd.h>
- #if defined(_MSC_VER)
- #include "SDL.h"
- #else
- #include "SDL/SDL.h"
- #endif
- #include "palette.h"
- #define WIDTH 320
- //#define HEIGHT 150
- #define HEIGHT 100
- #define RADIUS 50
- SDL_Surface *screen;
- int flamebuf[WIDTH][HEIGHT];
- void do_fire(int buf[WIDTH][HEIGHT]) {
- int x, y;
- /*
- * Set a random bottom row.
- */
- for (x = 0; x < WIDTH; x++) {
- buf[x][0] =
- (random() % 256);
- }
- for (y = HEIGHT - 1; y > 0; y--) {
- for (x = 0; x < WIDTH; x++) {
- buf[x][y] =
- (buf[(x + WIDTH) % WIDTH][(y - 2) % HEIGHT] +
- buf[(x + WIDTH) % WIDTH][y - 1] +
- buf[(x - 1 + WIDTH) % WIDTH][y - 1] +
- buf[(x + 1 + WIDTH) % WIDTH][y - 1]) * 32 / 129;
- }
- }
- }
- void setpix(long x, long y, long newval)
- {
- long yofs = screen->pitch/4;
- uint32_t *pixadr = ((uint32_t *)screen->pixels) + x + y*yofs ;
- *pixadr = newval;
- }
- void blendpix(long x, long y, long inval)
- {
- long yofs = screen->pitch/4;
- uint32_t *pixadr = ((uint32_t *)screen->pixels) + x + y*yofs ;
- uint8_t srcval[4],dstval[4],newval[4];
- int i;
- /* Yes, I know, so shoot me. */
- *(uint32_t *)srcval = inval; /* incoming RGBA */
- *(uint32_t *)dstval = *pixadr; /* current RGBA */
- for (i=0;i<4;i++) {
- newval[i] = srcval[i]/2 + dstval[i]/2;
- }
- *pixadr = *( (uint32_t *)&newval);
- }
- void dopix(long x, long y, long newval)
- {
- setpix(x,y,newval);
- blendpix(x+1,y+1,newval);
- blendpix(x-1,y+1,newval);
- blendpix(x+1,y-1,newval);
- blendpix(x-1,y-1,newval);
- }
- void mappoint(long cx, long cy, long x, long y, long radius)
- {
- uint32_t newval = palette[flamebuf[x % WIDTH][radius]];
- if (x == 0) {
- dopix(cx, cy+y ,newval);
- dopix(cx, cy-y ,newval);
- dopix(cx+y, cy ,newval);
- dopix(cx-y, cy ,newval);
- } else if (x == y) {
- dopix(cx+x, cy+y, newval);
- dopix(cx-x, cy+y, newval);
- dopix(cx+x, cy-y, newval);
- dopix(cx-x, cy-y, newval);
- } else if (x < y) {
- dopix(cx+x, cy+y, newval);
- dopix(cx-x, cy+y, newval);
- dopix(cx+x, cy-y, newval);
- dopix(cx-x, cy-y, newval);
- dopix(cx+y, cy+x, newval);
- dopix(cx-y, cy+x, newval);
- dopix(cx+y, cy-x, newval);
- dopix(cx-y, cy-x, newval);
- }
- }
- void firetocircle(long xcenter, long ycenter, long radius)
- {
- long x = 0;
- long y = radius;
- long p = (5 - radius * 4) / 4;
- mappoint(xcenter, ycenter, x, y, radius - RADIUS);
- while (x < y) {
- x++;
- if (p < 0) {
- p += 2 * x + 1;
- } else {
- y--;
- p += 2 * (x - y) + 1;
- }
- mappoint(xcenter, ycenter, x, y, radius - RADIUS);
- }
- }
- void render()
- {
- /*
- * Lock surface if needed.
- */
- if (SDL_MUSTLOCK(screen))
- if (SDL_LockSurface(screen) < 0)
- return;
- int i;
- for (i = RADIUS; i < (HEIGHT + RADIUS); i++) {
- firetocircle(screen->w / 2, screen->h / 2, i);
- }
- /*
- * Unlock if needed.
- */
- if (SDL_MUSTLOCK(screen))
- SDL_UnlockSurface(screen);
- /*
- * Tell SDL to update the whole screen.
- */
- SDL_UpdateRect(screen, 0, 0, screen->w, screen->h);
- }
- // Entry point
- int main(int argc, char *argv[])
- {
- // Initialize SDL's subsystems - in this case, only video.
- if (SDL_Init(SDL_INIT_VIDEO) < 0) {
- fprintf(stderr, "Unable to init SDL: %s\n",
- SDL_GetError());
- exit(1);
- }
- // Register SDL_Quit to be called at exit; makes sure things are
- // cleaned up when we quit.
- atexit(SDL_Quit);
- // Attempt to create a WIDTHxHEIGHT window with 32bit pixels.
- // screen = SDL_SetVideoMode(WIDTH, HEIGHT, 32, SDL_SWSURFACE);
- screen = SDL_SetVideoMode(1024,768, 32, SDL_SWSURFACE);
- // If we fail, return error.
- if (screen == NULL) {
- fprintf(stderr, "Unable to set 640x480 video: %s\n",
- SDL_GetError());
- exit(1);
- }
- // Main loop: loop forever.
- while (1) {
- // Update our fire.
- do_fire(flamebuf);
- // Render stuff
- render();
- // Poll for events, and handle the ones we care about.
- SDL_Event event;
- while (SDL_PollEvent(&event)) {
- switch (event.type) {
- case SDL_KEYDOWN:
- break;
- case SDL_KEYUP:
- // If escape is pressed, return (and thus, quit)
- if (event.key.keysym.sym == SDLK_ESCAPE)
- return 0;
- break;
- case SDL_QUIT:
- return (0);
- }
- }
- usleep(50000);
- }
- return 0;
- }
Raw Paste