"explosions" demo

I’ve been playing a lot of Twisted Metal: Black lately, and have been
enjoying the cool fireworks/sparkle-like effect for some explosions.

So, I was bored last night (my girlfriend was playing TM :slight_smile: ) and decided
to try and whip something up.

It started out as plain 2D at first, but I yanked some cruddy trig. and 3D
code out of my old “ICBM3D” vector-based Xlib game and came up with
something semi-entertaining.

Best of all, I’ve totally commented the code (more so than usual :slight_smile: )
so some of you might find it useful, even! :wink:

ftp://ftp.sonic.net/pub/users/nbs/unix/x/explosions/

Included is a .tar.gz (of the source, makefile, documentation
and PNG sprite files) as well as a GIF screenshot of the thing running.

It uses a lot of alpha-blending, and the 3D objects are sorted using
a cough bubble-sort, so it might be slow on some older machines.

It requires libSDL and SDL_image.

Enjoy!!!

-bill!

Best of all, I’ve totally commented the code (more so than usual :slight_smile: )
so some of you might find it useful, even! :wink:

ftp://ftp.sonic.net/pub/users/nbs/unix/x/explosions/

This is actually very kewl. :wink:

I’ve often thought that there should be a documented collection of some of
the great SDL demos out there for newbies and newbie sympathizers. Things
like this, that awesome parallax scrolling series by David Olofson, Randi J.
Relander, Nghia, et al. I know there is a demo page on libsdl.org, but what I
am actually thinking of would be more like a HOWTO.

I’ve been playing a lot of Twisted Metal: Black lately, and have been
enjoying the cool fireworks/sparkle-like effect for some explosions.

So, I was bored last night (my girlfriend was playing TM :slight_smile: ) and decided
to try and whip something up.

BTW, that’s one awesome game ;-)On Tuesday 31 July 2001 11:30pm, William Kendrick wrote:


Sam “Criswell” Hart <@Sam_Hart> AIM, Yahoo!:
Homepage: < http://www.geekcomix.com/snh/ >
PGP Info: < http://www.geekcomix.com/snh/contact/ >
Advogato: < http://advogato.org/person/criswell/ >

Thanks! I have a question about SDL, though…

Can someone give me a REAL simple, portable example piece of code to
read pixels (into RGB) and write pixels (as RGB) to and from a surface?

Everything I’ve tried either seems to push out two pixels at a time
(I’m using 16bit depth surface on a 16bbp X server) or segfault. :wink:

My current lame way of doing it is reading pixels off the surface
using SDL_BlitSurface() (with a 1x1 rectangle… once for each pixel… UGH!)
and then grabbing their RGB value by examining the “surface->pixels” RAM
in the surface I just blitted into (ie, to get the (0,0) position pixel)

To write into the surface (after altering the RGBs I just read), I use
SDL_FillRect() (with a 1x1 rectangle… once for each pixel… DOUBLE-UGH!)

Anyone got something simple you can show me? Esp. with lots of comments
(since I’m sure in involves pointer hell :frowning: )

Thanks!

-bill!
(working on frame bluring :slight_smile: )On Wed, Aug 01, 2001 at 11:53:32AM +0000, Samuel Hart wrote:

On Tuesday 31 July 2001 11:30pm, William Kendrick wrote:

Best of all, I’ve totally commented the code (more so than usual :slight_smile: )
so some of you might find it useful, even! :wink:

ftp://ftp.sonic.net/pub/users/nbs/unix/x/explosions/

This is actually very kewl. :wink:

I’m not a whole heck of a lot of help since I don’t know SDL too well, but
I know I saw examples of getpixel and putpixel routines in the doc project
pages, specifically at
http://sdldoc.csn.ul.ie/guidevideo.php#AEN90

If this isn’t what you’re looking for, then ignore me!

Ryan Szypowski

Hi,

Can someone give me a REAL simple, portable example piece of code to
read pixels (into RGB) and write pixels (as RGB) to and from a surface?

Why don’t you use the examples given on the SDL webpages - use the functions
they have, getpixel() and putpixel() ?

My current lame way of doing it is reading pixels off the surface
using SDL_BlitSurface() (with a 1x1 rectangle… once for each pixel…
UGH!)
and then grabbing their RGB value by examining the “surface->pixels” RAM
in the surface I just blitted into (ie, to get the (0,0) position pixel)

To write into the surface (after altering the RGBs I just read), I use
SDL_FillRect() (with a 1x1 rectangle… once for each pixel…
DOUBLE-UGH!)

You’re right. That’s nasty!

Anyone got something simple you can show me? Esp. with lots of comments
(since I’m sure in involves pointer hell :frowning: )

It does. Here’s the code you need:

/*

  • Return the pixel value at (x, y)

  • NOTE: The surface must be locked before calling this!
    */
    Uint32 getpixel(SDL_Surface surface, int x, int y)
    {
    int bpp = surface->format->BytesPerPixel;
    /
    Here p is the address to the pixel we want to retrieve */
    Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;

    switch(bpp) {
    case 1:
    return *p;

    case 2:
    return *(Uint16 *)p;

    case 3:
    if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
    return p[0] << 16 | p[1] << 8 | p[2];
    else
    return p[0] | p[1] << 8 | p[2] << 16;

    case 4:
    return *(Uint32 *)p;

    default:
    return 0; /* shouldn’t happen, but avoids warnings */
    }
    }

/*

  • Set the pixel at (x, y) to the given value

  • NOTE: The surface must be locked before calling this!
    */
    void putpixel(SDL_Surface surface, int x, int y, Uint32 pixel)
    {
    int bpp = surface->format->BytesPerPixel;
    /
    Here p is the address to the pixel we want to set */
    Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;

    switch(bpp) {
    case 1:
    *p = pixel;
    break;

    case 2:
    *(Uint16 *)p = pixel;
    break;

    case 3:
    if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
    p[0] = (pixel >> 16) & 0xff;
    p[1] = (pixel >> 8) & 0xff;
    p[2] = pixel & 0xff;
    } else {
    p[0] = pixel & 0xff;
    p[1] = (pixel >> 8) & 0xff;
    p[2] = (pixel >> 16) & 0xff;
    }
    break;

    case 4:
    *(Uint32 *)p = pixel;
    break;
    }
    }

void TestPixel(void)
{
/* Code to set a yellow pixel at the center of the screen */

int x, y;
Uint32 yellow;

/* Map the color yellow to this display (R=0xff, G=0xFF, B=0x00)
   Note:  If the display is palettized, you must set the palette first.
*/
yellow = SDL_MapRGB(screen->format, 0xff, 0xff, 0x00);

x = screen->w / 2;
y = screen->h / 2;

/* Lock the screen for direct access to the pixels */
if ( SDL_MUSTLOCK(screen) )

{
if ( SDL_LockSurface(screen) < 0 ) {
fprintf(stderr, “Can’t lock screen: %s\n”, SDL_GetError());
return;
}
}

putpixel(screen, x, y, yellow);

if ( SDL_MUSTLOCK(screen) )

{
SDL_UnlockSurface(screen);
}
/* Update just the part of the display that we’ve changed */
SDL_UpdateRect(screen, x, y, 1, 1);

return;

}

That code is straight off the SDL webpages, so if it doesn’t work, blame
them! :wink:

Neil.

Hey Bill!

There’s an example in the SDL documentation project on getting and putting
pixels in all supported modes:

http://sdldoc.csn.ul.ie/guidevideo.php#AEN90
http://sdldoc.csn.ul.ie/guidevideo.php#AEN93

BTW, how’d you make a public directory on sonic?

-Mark (also a sonic isp subscriber, thanks to bill)On Wed, 1 Aug 2001, William Kendrick wrote:

On Wed, Aug 01, 2001 at 11:53:32AM +0000, Samuel Hart wrote:

On Tuesday 31 July 2001 11:30pm, William Kendrick wrote:

Best of all, I’ve totally commented the code (more so than usual :slight_smile: )
so some of you might find it useful, even! :wink:

ftp://ftp.sonic.net/pub/users/nbs/unix/x/explosions/

This is actually very kewl. :wink:

Thanks! I have a question about SDL, though…

Can someone give me a REAL simple, portable example piece of code to
read pixels (into RGB) and write pixels (as RGB) to and from a surface?

Everything I’ve tried either seems to push out two pixels at a time
(I’m using 16bit depth surface on a 16bbp X server) or segfault. :wink:

My current lame way of doing it is reading pixels off the surface
using SDL_BlitSurface() (with a 1x1 rectangle… once for each pixel… UGH!)
and then grabbing their RGB value by examining the “surface->pixels” RAM
in the surface I just blitted into (ie, to get the (0,0) position pixel)

To write into the surface (after altering the RGBs I just read), I use
SDL_FillRect() (with a 1x1 rectangle… once for each pixel… DOUBLE-UGH!)

Anyone got something simple you can show me? Esp. with lots of comments
(since I’m sure in involves pointer hell :frowning: )

Thanks!

-bill!
(working on frame bluring :slight_smile: )


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl


Mark K. Kim
http://www.cbreak.org/mark/
PGP key available upon request.

Ah, excellent! I totally forgot about the SDL doc stuff (it was in its
infancy the last time I was doing much SDL coding :wink: I got a full-time job
almost exactly 1 yr ago :slight_smile: )

Thanks all!

-bill!On Wed, Aug 01, 2001 at 08:11:04PM -0500, ryan szypowski wrote:

I’m not a whole heck of a lot of help since I don’t know SDL too well, but
I know I saw examples of getpixel and putpixel routines in the doc project
pages, specifically at
http://sdldoc.csn.ul.ie/guidevideo.php#AEN90

William,

… Pixels …
Anyone got something simple you can show me?

There is some code here that handles RGBA pixels.

http://www.ferzkopp.net/Software/SDL_gfxPrimitives/index.html

Ciao
Andreas

Ah, excellent! I totally forgot about the SDL doc stuff (it was in its
infancy the last time I was doing much SDL coding :wink: I got a full-time job
almost exactly 1 yr ago :slight_smile: )

A full time job is no excuse, Bill. grin

See ya,
-Sam Lantinga, (full time) Software Engineer, Blizzard Entertainment

A full time job is no excuse, Bill. grin

Growl

See ya,
-Sam Lantinga, (full time) Software Engineer, Blizzard Entertainment

What’s this? Blizzard? As in, not Loki any more? Or as WELL as Loki?
Man, I’m out of the loop.

-bill!On Thu, Aug 02, 2001 at 11:37:42PM -0700, Sam Lantinga wrote:

  • William Kendrick on Fri, Aug 03, 2001:

See ya,
-Sam Lantinga, (full time) Software Engineer, Blizzard Entertainment

What’s this? Blizzard? As in, not Loki any more? Or as WELL as Loki?
Man, I’m out of the loop.

Yeah, I was dazed and confused when I saw that too :).

M. R.

William Kendrick wrote:

I’ve been playing a lot of Twisted Metal: Black lately, and have been
enjoying the cool fireworks/sparkle-like effect for some explosions.

So, I was bored last night (my girlfriend was playing TM :slight_smile: ) and decided
to try and whip something up.

It started out as plain 2D at first, but I yanked some cruddy trig. and 3D
code out of my old “ICBM3D” vector-based Xlib game and came up with
something semi-entertaining.

Best of all, I’ve totally commented the code (more so than usual :slight_smile: )
so some of you might find it useful, even! :wink:

ftp://ftp.sonic.net/pub/users/nbs/unix/x/explosions/

Included is a .tar.gz (of the source, makefile, documentation
and PNG sprite files) as well as a GIF screenshot of the thing running.

It uses a lot of alpha-blending, and the 3D objects are sorted using
a cough bubble-sort, so it might be slow on some older machines.

It requires libSDL and SDL_image.

Enjoy!!!

-bill!

hm… as the screenshots really looked great, of course i wanted to
run the programm, but after having compiled it (“make”), it just
gives me the parachute :frowning:

—CLI_output::begin—

./explosions
Fatal signal: Segmentation Fault (SDL Parachute Deployed)

—CLI_output::end—

maybe a little strace-output might help…

—strace_output::begin—

[…]
open(“spark7.png”, O_RDONLY) = 5
fstat64(5, {st_mode=S_IFREG|0600, st_size=4176, …}) = 0
old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS,
-1, 0) = 0x40081000
_llseek(5, 0, [0], SEEK_CUR) = 0
_llseek(5, 0, [0], SEEK_SET) = 0
_llseek(5, 0, [0], SEEK_SET) = 0
read(5, “\211PNG\r\n\32\n\0\0\0\rIHDR\0\0\0c\0\0\0\23\10\6\0\0\0”…,
4096) = 4096
_llseek(5, 4096, [4096], SEEK_SET) = 0
_llseek(5, 4096, [4096], SEEK_SET) = 0
_llseek(5, 4096, [4096], SEEK_SET) = 0
_llseek(5, 4096, [4096], SEEK_SET) = 0
_llseek(5, 4096, [4096], SEEK_SET) = 0
_llseek(5, 4096, [4096], SEEK_SET) = 0
_llseek(5, 4096, [4096], SEEK_SET) = 0
_llseek(5, 4096, [4096], SEEK_SET) = 0
llseek(5, 4096, [4096], SEEK_SET) = 0
brk(0x808a000) = 0x808a000
read(5, “P\212\312\222\364\243dFt\323\367n\330z\344P\366\3770\376”…,
4096) = 80
close(5) = 0
munmap(0x40081000, 4096) = 0
gettimeofday({997774381, 491733}, NULL) = 0
gettimeofday({997774381, 492069}, NULL) = 0
write(3, “\33\0\2\0\0\0\0\0 \0\2\0\0\0\0\0+\1\1\0”, 20) = 20
read(3, “\34\0M\0\3\0\300\0010\1\0\0\243\321\374O\0\0\0\0\0\0\0”…, 32)
= 32
read(3, 0xbffff488, 32) = -1 EAGAIN (Resource
temporarily unavailable)
select(4, [3], NULL, NULL, NULL) = 1 (in [3])
read(3, “\1\1P\0\0\0\0\0\n\0@\1\0\0\0\0\0\0\0\0\0\0\0\0\370\1\217”…,
32) = 32
write(3, “\221\3\n\0\r\0\300\1\16\0\300\1\240\0\240\0\0\0\0\0\240”…,
44) = 44
read(3, 0xbffff498, 32) = -1 EAGAIN (Resource
temporarily unavailable)
select(4, [3], NULL, NULL, NULL) = 1 (in [3])
read(3, “\1\1R\0\0\0\0\0\n\0@\1\0\0\0\0\0\0\0\0\0\0\0\0\370\1\217”…,
32) = 32
write(3, “\221\3\n\0\r\0\300\1\16\0\300\1\240\0\240\0\0\0\0\0\240”…,
44) = 44
read(3, 0xbffff498, 32) = -1 EAGAIN (Resource
temporarily unavailable)
select(4, [3], NULL, NULL, NULL) = 1 (in [3])
read(3, “\1\1T\0\0\0\0\0\n\0@\1\0\0\0\0\0\0\0\0\0\0\0\0\370\1\217”…,
32) = 32
select(4, [3], NULL, NULL, {0, 0}) = 0 (Timeout)
select(4, [3], NULL, NULL, {0, 0}) = 0 (Timeout)
— SIGSEGV (Segmentation fault) —
rt_sigaction(SIGSEGV, {SIG_DFL}, {0x4009a620, [SEGV],
SA_RESTART|0x4000000}, 8)
= 0
write(2, "Fatal signal: “, 14Fatal signal: ) = 14
write(2, “Segmentation Fault”, 18Segmentation Fault) = 18
write(2, " (SDL Parachute Deployed)\n”, 26 (SDL Parachute Deployed)
) = 26
write(3, "
\3\2\0\v\0\300\1+\0\1\0", 12) = 12
read(3, 0xbffff0e8, 32) = -1 EAGAIN (Resource
temporarily unavailable)
select(4, [3], NULL, NULL, NULL) = 1 (in [3])
read(3, “\1\1V\0\0\0\0\0\n\0@\1\0\0\0\0\0\0\0\0\0\0\0\0\370\1\217”…,
32) = 32
write(4, “+\3\1\0”, 4) = 4
read(4, 0xbffff118, 32) = -1 EAGAIN (Resource
temporarily unavailable)
select(5, [4], NULL, NULL, NULL) = 1 (in [4])
read(4, “\1\1\16\0\0\0\0\0\n\0@\1\0\0\0\0\1\0\0\0\1\0\0\0X\223\213”…,
32) = 32write(3, “\221\2\2\0\17\0\300\1+\0\1\0”, 12) = 12
read(3, 0xbffff0e8, 32) = -1 EAGAIN (Resource
temporarily unavailable)
select(4, [3], NULL, NULL, NULL) = 1 (in [3])
read(3, “\1\1X\0\0\0\0\0\n\0@\1\0\0\0\0\0\0\0\0\0\0\0\0\370\1\217”…,
32) = 32
shmdt(0x4036a000) = 0
write(3, “\n\2\2\0\3\0\300\1\4\0\2\0\r\0\300\1<\0\2\0\16\0\300\1”…,
44) = 44
read(3, 0xbffff0e8, 32) = -1 EAGAIN (Resource
temporarily unavailable)
select(4, [3], NULL, NULL, NULL) = 1 (in [3])
read(3, “\22\0Y\0\3\0\300\1\3\0\300\1\0p\204\10\3\0\300\1\366\377"..., 32) = 32read(3, "\1\1^\0\0\0\0\0\n\0@\1\0\0\0\0\0\0\0\0\0\0\0\0\370\1\217"..., 32) = 32 write(4, "<\3\2\0\0\0\340\2+\0\1\0", 12) = 12 read(4, 0xbffff0fc, 32) = -1 EAGAIN (Resource temporarily unavailable) select(5, [4], NULL, NULL, NULL) = 1 (in [4]) read(4, "\1\1\20\0\0\0\0\0\n\0@\1\0\0\0\0\0\0\0\0\1\0\0\0X\223\213"..., 32) = 32shutdown(4, 2 /* send and receive */) = 0 close(4) = 0 write(3, "<\2\2\0\0\0\300\1+\0\1\0", 12) = 12 read(3, "\34\0^\0\3\0\300\1j\0\0\0002\322\374O\0\0\0\0\3\0\300\1"..., 32) = 32 read(3, "\34\366^\0\3\0\300\0013\1\0\0002\322\374O\1\0\0\0002\322"..., 32) = 32 read(3, "\226\20^\0\3\0\300\1\3\0\300\1>\317K at 0\5n\1\240\0\240\0"..., 32) = 32 read(3, "\25\0^\0\3\0\300\1\3\0\300\0017\0\0\0,\5\\\1\0\365\377"..., 32) = 32 read(3, 0xbffff0fc, 32) = -1 EAGAIN (Resource temporarily unavailable) select(4, [3], NULL, NULL, NULL) = 1 (in [3]) read(3, "\1\1\0\0\0\0\0\n\0@\1\0\0\0\0\0\0\0\0\0\0\0\0\370\1\217”…,
32) = 32
shutdown(3, 2 /* send and receive */) = 0
close(3) = 0
rt_sigaction(SIGSEGV, {SIG_DFL}, {SIG_DFL}, 8) = 0
rt_sigaction(SIGSEGV, {SIG_DFL}, {SIG_DFL}, 8) = 0
rt_sigaction(SIGBUS, {SIG_DFL}, {0x4009a620, [BUS],
SA_RESTART|0x4000000}, 8) =
0
rt_sigaction(SIGFPE, {SIG_DFL}, {0x4009a620, [FPE],
SA_RESTART|0x4000000}, 8) =
0
rt_sigaction(SIGQUIT, {SIG_DFL}, {0x4009a620, [QUIT],
SA_RESTART|0x4000000}, 8)
= 0
rt_sigaction(SIGPIPE, {SIG_DFL}, {0x4009a620, [PIPE],
SA_RESTART|0x4000000}, 8)
= 0
_exit(-11) = ?

—strace_output::end—

hm… to me both messages (CLI and strace) are not very meaningful,
or rather, they don’t give me a clue on where to start “debugging”.

any ideas ?

ah…

  • Red Hat Linux release 7.1 (Seawolf),
    Kernel 2.4.5 on an i586

  • XFree86 Version 4.0.3 / X Window System

  • SDL-1.2.1-3, SDL-devel-1.2.1-3,
    SDL_mixer-1.2.0-1, SDL_mixer-devel-1.2.0-1,
    SDL_image-1.2.0-1, SDL_image-devel-1.2.0-1

  • nvidia_drv.o (NVIDIA_GLX 1.0)

  • something i forgot?

TIA–

br,
#nos

>

hm… as the screenshots really looked great, of course i wanted to
run the programm, but after having compiled it (“make”), it just
gives me the parachute :frowning:

—CLI_output::begin—

./explosions
Fatal signal: Segmentation Fault (SDL Parachute Deployed)

—CLI_output::end—

maybe a little strace-output might help…

Holy moley! Anyone have any ideas what’s going on?

What bit depth is your system at? Admittedly, I’ve only tried it
at 16bpp, but I pretty much lifted the get/putpixel() functions
straight off the SDL doc project site.

> read(3, 0xbffff498, 32) = -1 EAGAIN (Resource > temporarily unavailable) > select(4, [3], NULL, NULL, NULL) = 1 (in [3]) > read(3, "\1\1T\0\0\0\0\0\n\0@\1\0\0\0\0\0\0\0\0\0\0\0\0\370\1\217"..., > 32) = 32 > select(4, [3], NULL, NULL, {0, 0}) = 0 (Timeout) > select(4, [3], NULL, NULL, {0, 0}) = 0 (Timeout) > --- SIGSEGV (Segmentation fault) ---

Merr… seems like it’s happening in the PNG-loading function?
Maybe not. I’m not good with strace outputs :wink:

-bill!On Tue, Aug 14, 2001 at 09:42:28AM +0200, herwig schwantzer wrote:

William Kendrick wrote:

Holy moley! Anyone have any ideas what’s going on?

What bit depth is your system at? Admittedly, I’ve only tried it
at 16bpp, but I pretty much lifted the get/putpixel() functions
straight off the SDL doc project site.

16, actually.

ok, i forgot to mention, that, when i launch ./parachute, i get a
little window, bout 150x150 (guessing - let’s put it like this:
it’s very small on my 1600x1200 screen), which disappears again
within a quarter of a second. shrug

> read(3, 0xbffff498, 32) = -1 EAGAIN (Resource > temporarily unavailable) > select(4, [3], NULL, NULL, NULL) = 1 (in [3]) > read(3, "\1\1T\0\0\0\0\0\n\0@\1\0\0\0\0\0\0\0\0\0\0\0\0\370\1\217"..., > 32) = 32 > select(4, [3], NULL, NULL, {0, 0}) = 0 (Timeout) > select(4, [3], NULL, NULL, {0, 0}) = 0 (Timeout) > --- SIGSEGV (Segmentation fault) ---

Merr… seems like it’s happening in the PNG-loading function?
Maybe not. I’m not good with strace outputs :wink:

not my guess, but at least a guess :slight_smile:

-bill!

thnx–

br,
#nos

16, actually.

ok, i forgot to mention, that, when i launch ./parachute,

You mean “./explosions” I think. :wink:

i get a little window, bout 150x150 (guessing - let’s put it like this:
it’s very small on my 1600x1200 screen), which disappears again
within a quarter of a second. shrug

Yes… the window is very small. If you combine numerous effects, the
FPS drops pretty dramatically at larger resolutions (depending on the
speed of your CPU… let’s put it like this: my overclocked-to-450Mhz Celeron
can’t keep up at 320x240 with some of the more CPU-intensive effects going
on)

-bill!On Thu, Aug 16, 2001 at 08:50:45AM +0200, herwig schwantzer wrote: