186 lines
3.0 KiB
C
186 lines
3.0 KiB
C
|
|
|
|
# include <stdlib.h>
|
|
# include <string.h>
|
|
# include <time.h>
|
|
|
|
|
|
/*
|
|
|
|
Ripped from an Allegro example (exflame.c). :)
|
|
|
|
Should be fire, but looks more like smoke in ZSNES.
|
|
|
|
*/
|
|
|
|
|
|
#define MIN(x, y) \
|
|
(((x) < (y)) ? (x) : (y))
|
|
|
|
#define ABS(x) \
|
|
(((x) >= 0) ? (x) : ( - (x)))
|
|
|
|
|
|
#define FIRE_HOTSPOTS 80
|
|
|
|
static int fire_hotspot [FIRE_HOTSPOTS];
|
|
|
|
|
|
extern char * vidbuffer;
|
|
|
|
|
|
#define SCRW 288
|
|
|
|
#define SCRH 224
|
|
|
|
|
|
static unsigned char fire_line [SCRW];
|
|
|
|
static unsigned char fire_buffer [SCRW * SCRH];
|
|
|
|
|
|
static int fire_init_flag;
|
|
|
|
|
|
static void draw_bottom_line_of_fire (void)
|
|
{
|
|
int count, count2;
|
|
|
|
|
|
memset ((& fire_line), 0, SCRW);
|
|
|
|
|
|
for (count = 0; count < FIRE_HOTSPOTS; count ++)
|
|
{
|
|
for (count2 = (fire_hotspot [count] - 20);
|
|
count2 < (fire_hotspot [count] + 20); count2 ++)
|
|
{
|
|
if ((count2 >= 0) && (count2 < SCRW))
|
|
{
|
|
fire_line [count2] =
|
|
MIN ((fire_line [count2] + 20) -
|
|
ABS (fire_hotspot [count] - count2), 256);
|
|
}
|
|
}
|
|
|
|
|
|
fire_hotspot [count] += ((rand () & 7) - 3);
|
|
|
|
|
|
if (fire_hotspot [count] < 0)
|
|
{
|
|
fire_hotspot [count] += SCRW;
|
|
}
|
|
else if (fire_hotspot [count] >= SCRW)
|
|
{
|
|
fire_hotspot [count] -= SCRW;
|
|
}
|
|
}
|
|
|
|
|
|
for (count = 0; count < SCRW; count ++)
|
|
{
|
|
fire_buffer [((SCRH - 1) *
|
|
(SCRW)) + count] = fire_line [count];
|
|
}
|
|
}
|
|
|
|
|
|
static void init_fire (void)
|
|
{
|
|
int x, y, pixel, count;
|
|
|
|
|
|
srand (time (0));
|
|
|
|
|
|
for (count = 0; count < FIRE_HOTSPOTS; count ++)
|
|
{
|
|
fire_hotspot [count] = (rand () % SCRW);
|
|
}
|
|
|
|
|
|
for (count = 0; count < SCRH; count ++)
|
|
{
|
|
draw_bottom_line_of_fire ();
|
|
|
|
|
|
for (y = 0; y < (SCRH - 1); y ++)
|
|
{
|
|
for (x = 0; x < SCRW; x ++)
|
|
{
|
|
pixel = fire_buffer [((y + 1) * SCRW) + x];
|
|
|
|
|
|
if (pixel > 0)
|
|
{
|
|
pixel --;
|
|
}
|
|
|
|
|
|
fire_buffer [(y * SCRW) + x] = pixel;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
fire_init_flag = 1;
|
|
}
|
|
|
|
|
|
/* void DrawFire (void) */
|
|
|
|
void DrawSmoke (void)
|
|
{
|
|
int x, y, pixel, pixel2;
|
|
|
|
|
|
if (! fire_init_flag)
|
|
{
|
|
init_fire ();
|
|
}
|
|
|
|
|
|
draw_bottom_line_of_fire ();
|
|
|
|
|
|
for (y = 0; y < (SCRH - 1); y ++)
|
|
{
|
|
for (x = 0; x < SCRW; x ++)
|
|
{
|
|
pixel = fire_buffer [((y + 1) * SCRW) + x];
|
|
|
|
|
|
if (pixel > 0)
|
|
{
|
|
pixel --;
|
|
}
|
|
|
|
|
|
fire_buffer [(y * SCRW) + x] = pixel;
|
|
}
|
|
}
|
|
|
|
|
|
for (y = 0; y < SCRH; y ++)
|
|
{
|
|
for (x = 0; x < SCRW; x ++)
|
|
{
|
|
pixel = vidbuffer [(y * SCRW) + x];
|
|
|
|
pixel2 = (fire_buffer [(y * SCRW) + x] / 8);
|
|
|
|
|
|
if (pixel2 > pixel)
|
|
{
|
|
vidbuffer [(y * SCRW) + x] = pixel2;
|
|
}
|
|
else
|
|
{
|
|
vidbuffer [(y * SCRW) + x] =
|
|
(((pixel + pixel2) / 2) + 1);
|
|
}
|
|
}
|
|
}
|
|
}
|