Plasma program for X11
Mark Costlow
cheeks at arsenic..eds.com
Sun May 26 12:36:40 AEST 1991
This is a program for generating/displaying plasma cloud images for X11.
Here's part of the README:
This is plasma. It implements "plasma clouds" with X11. It's not very
sophisticated ... I just saw jjensen at dsg4.dse.beckman.com (John Jensen)'s
post in alt.fractals and coded up his ideas (and used some of his code) with
my Xlib skeleton which I use for prototyping graphics ideas. It does
colormap cycling, and it lets you mess with a few of the parameters.
Enjoy ...
Mark
cheeks at edsr.eds.com or ...uunet!edsr!cheeks
#---------------------------------- cut here ----------------------------------
# This is a shell archive. Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by Mark Costlow <cheeks at argon> on Sat May 25 20:30:25 1991
#
# This archive contains:
# README Makefile plasma.c
#
# Existing files will not be overwritten.
# Error checking via wc(1) will be performed.
LANG=""; export LANG
PATH=/bin:/usr/bin:$PATH; export PATH
if test -f README
then
echo Ok to overwrite existing file README\?
read answer
case "$answer" in
[yY]*) echo Proceeding;;
*) echo Aborting; exit 1;;
esac
rm -f README
if test -f README
then
echo Error: could not remove README, aborting
exit 1
fi
fi
echo x - README
cat >README <<'@EOF'
This is plasma. It implements "plasma clouds" with X11. It's not very
sophisticated ... I just saw jjensen at dsg4.dse.beckman.com (John Jensen)'s
post in alt.fractals and coded up his ideas (and used some of his code) with
my Xlib skeleton which I use for prototyping graphics ideas. It does
colormap cycling, and it lets you mess with a few of the parameters.
It definitely works with sparcs under SunOS 4.1.x and 8 bit displays. My
skeleton runs on HPs under hpux as well, even with those gnarly 6-bit
displays, but I haven't tested it with this program.
I don't really have time to "maintain" this thing ... I'm just throwing it
out since it's kinda cute. I'll fix bugs as time permits though, and I
would like to hear about changes or improvements (like getting it to use
the default color map and running on the root window, etc). It is hereby
placed in the public domain ... give it away, sell it, whatever. I'd
appreciate it if my name was left on it though.
Mark Costlow
cheeks at edsr.eds.com or ...uunet!edsr!cheeks
@EOF
set `wc -lwc <README`
if test $1$2$3 != 191781038
then
echo ERROR: wc results of README are $* should be 19 178 1038
fi
chmod 664 README
if test -f Makefile
then
echo Ok to overwrite existing file Makefile\?
read answer
case "$answer" in
[yY]*) echo Proceeding;;
*) echo Aborting; exit 1;;
esac
rm -f Makefile
if test -f Makefile
then
echo Error: could not remove Makefile, aborting
exit 1
fi
fi
echo x - Makefile
cat >Makefile <<'@EOF'
CC = gcc
CFLAGS = -g
.c.o:
$(CC) $(CFLAGS) -c $<
PROGS = plasma
all: $(PROGS)
plasma: plasma.o
$(CC) $(CFLAGS) -o plasma plasma.o -lX11 -lm
clean:
rm -f core *.o $(PROGS)
@EOF
set `wc -lwc <Makefile`
if test $1$2$3 != 1531180
then
echo ERROR: wc results of Makefile are $* should be 15 31 180
fi
chmod 664 Makefile
if test -f plasma.c
then
echo Ok to overwrite existing file plasma.c\?
read answer
case "$answer" in
[yY]*) echo Proceeding;;
*) echo Aborting; exit 1;;
esac
rm -f plasma.c
if test -f plasma.c
then
echo Error: could not remove plasma.c, aborting
exit 1
fi
fi
echo x - plasma.c
cat >plasma.c <<'@EOF'
/*
* plasma.c -- generate/display plasma clouds with X11. It was written in
* about an hour ... and the code shows it :-).
*
* Mark Costlow
* cheeks at edsr.eds.com
* May 25, 1991
*/
#include <stdio.h>
#include <math.h>
#include <ctype.h>
/* X-windows includes */
#include <X11/Xos.h>
#include <X11/Xatom.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/cursorfont.h>
typedef unsigned char byte;
double drand48();
Display *display;
char win_name[64];
Visual *visual = NULL;
Status status;
unsigned long wp, bp; /* pixel values for black & white */
int screen, nplanes, ncolors;
XEvent event;
XExposeEvent *expose;
XSetWindowAttributes attrib;
GC gc;
XGCValues gc_val;
XSizeHints sizehints;
Window imagewin; /* window ID for image */
XImage *image = NULL;
Colormap *cmaps;
double Futz = 2.0; /* Global scale of random perturbations. */
int usedist = 1; /* Use distance to scale perturbations. */
int sleep_delay = 50000; /* speed of colormap cyling. */
int global_x, global_y;
byte *buf;
#define BUF(a,b) buf[(global_y * b) + a]
#define NUMCOLORS 255
void MakeColormaps(int nplanes)
{
XColor colors[256];
int i, j, mask, tempcolor;
Colormap cmap;
double step, f;
fprintf(stderr, "Building color maps . . . ");
fflush(stderr);
ncolors = 1 << nplanes;
cmaps = (Colormap *) malloc(ncolors * sizeof(Colormap));
step = (double) ( (M_PI_4 * (double)nplanes) / (double) ncolors);
f = M_PI; /* + M_PI_2; */
#define MAXI 65535
for (i = 0; i < ncolors; i++)
{
double wank = MAXI / 2.0;
double sin(double);
#define PLAIN
colors[i].pixel = i;
colors[i].flags = DoRed | DoGreen | DoBlue;
#ifdef PLAIN
colors[i].red = (int)((wank * sin(f)) + wank);
colors[i].green = (int)((wank * sin(f + M_PI)) + wank);
colors[i].blue = (int)((wank * sin(f + M_PI + M_PI_2)) + wank);
#else
colors[i].red = (int)((wank * sin(f)) + wank);
colors[i].green = (int)((wank * sin(f + M_PI_4)) + wank);
colors[i].blue = (int)((wank * sin(f + M_PI_2)) + wank);
#endif
f += step;
}
for (j = 0; j < ncolors; j++)
{
tempcolor = colors[0].pixel;
for (i = 0; i < ncolors - 1; i++)
colors[i].pixel = colors[i+1].pixel;
colors[ncolors-1].pixel = tempcolor;
cmaps[j] = XCreateColormap(display, RootWindow(display, screen), visual,
AllocAll);
XStoreColors(display, cmaps[j], colors, ncolors);
}
fprintf(stderr, "Done\n");
fflush(stderr);
}
void CycleColormap()
{
static int current_map = 0;
XSetWindowColormap(display, imagewin, cmaps[current_map++]);
current_map = (current_map % ncolors);
XSync(display, False);
}
void InitX(char *disp, int x, int y)
{
int i, j;
strcpy(win_name, "Plasma");
/*
* Open the connection to the X11 server and set defaults
*/
if ((display = XOpenDisplay(disp)) == NULL)
{
fprintf(stderr,"Could not open display.\n");
exit(1);
}
screen = XDefaultScreen(display);
visual = XDefaultVisual(display, screen);
nplanes = XDisplayPlanes(display, screen);
bp = BlackPixel(display, screen);
wp = WhitePixel(display, screen);
/*
* Set window manager hints
*/
sizehints.flags = PPosition | PSize | PMinSize | PMaxSize;
sizehints.width = sizehints.min_width = x;
sizehints.max_width = x;
sizehints.height = sizehints.min_height = y;
sizehints.max_height = x;
sizehints.x = 0;
sizehints.y = 0;
MakeColormaps(nplanes);
attrib.background_pixel = wp;
attrib.border_pixel = bp;
attrib.event_mask = (ExposureMask | LeaveWindowMask |
ButtonPressMask | ButtonReleaseMask |
ColormapChangeMask | Button1MotionMask |
EnterWindowMask);
attrib.cursor = XCreateFontCursor(display, XC_top_left_arrow);
/*
* Create the window.
*/
imagewin = XCreateWindow(display, RootWindow(display, screen), 0, 0,
x, y, 5, XDefaultDepth(display, screen),
InputOutput, visual,
(CWBackPixel|CWEventMask|CWCursor|CWBorderPixel),
&attrib);
/*
* Install properties for the window.
*/
XSetStandardProperties(display, imagewin, win_name, win_name, NULL,
NULL, NULL, &sizehints);
XSetIconName(display, imagewin, "Plasma");
/*
* Install the colormap
*/
XSetWindowColormap(display, imagewin, cmaps[0]);
/* #define DEBUG */
#ifdef DEBUG
/*
* See what's in the colormap
*/
for (j = 0; j < (1<<nplanes); j++)
{
for (i=0; i < (1 << nplanes); i++)
{
XColor qcolor;
qcolor.pixel = (u_long)i;
XQueryColor(display, cmaps[j], &qcolor);
fprintf(stderr,"color[%2d]: pix %3u r= %5u g= %5u b= %5u\n",i,
qcolor.pixel, qcolor.red, qcolor.green, qcolor.blue);
}
}
fprintf(stderr, "\n\n");
#endif
/*
* Now finally map the window ...
*/
XMapWindow(display, imagewin);
/*
* Create a Graphics Context.
*/
gc_val.foreground = bp;
gc_val.background = wp;
gc = XCreateGC(display, imagewin, GCForeground | GCBackground , &gc_val);
/*
* select which input events to honor
*/
XSelectInput(display, imagewin, (ExposureMask | KeyPressMask));
/*
* Wait for first expose event
*/
XNextEvent(display, &event);
while (event.type != Expose)
{
XNextEvent(display, &event);
}
}
show_pic(byte *buf, int x, int y)
{
char ch, tmp[80];
static int ngen = 0;
image = XCreateImage(display, visual, nplanes, ZPixmap, 0, (char *)buf,
x, y, 8, 0);
XPutImage(display, imagewin, gc, image, 0, 0, 0, 0, x, y);
XSync(display, False);
}
/*
* Enter infinite loop to sevice events.
*/
void manage_window()
{
int Finished;
XKeyEvent *keypress;
KeySym keysym;
char keybuf[64];
XComposeStatus cstat;
Finished = 0;
expose = (XExposeEvent *)&event;
keypress = (XKeyEvent *)&event;
while (!Finished)
{
if (XPending(display))
{
XNextEvent(display, &event);
switch ((int)event.type)
{
case Expose:
if (expose->x % 4 != 0)
{
expose->x -= (expose->x % 4);
expose->width += (expose->x % 4);
}
if (expose->width % 4 != 0)
expose->width += 4 - (expose->width % 4);
XPutImage(display, imagewin, gc, image, expose->x, expose->y,
expose->x, expose->y, expose->width, expose->height);
break;
case ButtonPress:
Finished = 1;
break;
case KeyPress:
XLookupString(keypress, keybuf, sizeof(keybuf), &keysym, &cstat);
if(*keybuf == 'q' || *keybuf == 'Q')
Finished = 1;
break;
default:
break;
}
}
usleep(sleep_delay);
CycleColormap();
}
}
adjust(int xa, int ya, int x, int y, int xb, int yb)
{
int d;
double v;
if (usedist)
d = abs(xa - xb) + abs(ya - yb);
else
d = 1.0;
v = (BUF(xa, ya) + BUF(xb, yb)) / 2 + (drand48() - 0.5) * d * Futz;
if (v < 1.0)
v = 1.0;
else if (v > (double)NUMCOLORS)
v = (double)NUMCOLORS;
BUF(x, y) = (int)v;
}
subdivide(int x1, int y1, int x2, int y2)
{
int x, y, v;
if ((x2 - x1 > 1) || (y2 - y1 > 1))
{
x = (x1 + x2) / 2;
y = (y1 + y2) / 2;
if (!BUF(x,y1))
adjust(x1, y1, x, y1, x2, y1);
if (!BUF(x2,y))
adjust(x2, y1, x2, y, x2, y2);
if (!BUF(x,y2))
adjust(x1, y2, x, y2, x2, y2);
if (!BUF(x1,y))
adjust(x1, y1, x1, y, x1, y2);
if (!BUF(x, y))
{
v = (BUF(x1, y1) + BUF(x2, y1) + BUF(x2, y2) + BUF(x1, y2)) / 4;
if (v < 1)
v = 1;
else if (v > NUMCOLORS)
v = NUMCOLORS;
BUF(x, y) = v;
}
subdivide(x1, y1, x, y);
subdivide(x, y1, x2, y);
subdivide(x, y, x2, y2);
subdivide(x1, y, x, y2);
/* show_pic(buf, global_x, global_y); */
}
}
void Usage(char *prog, char *opt)
{
fprintf(stderr, "%s: bad option \"%s\"\n\n", prog, opt);
fprintf(stderr, "Usage: %s [options]\n\nWhere options include:\n", prog);
fprintf(stderr," -f <num>\t\t Set global futz factor (default = 2.0)\n");
fprintf(stderr," -dist\t\t Don't make perturbations dependent on dist.\n");
fprintf(stderr," -delay <num>\t Delay in colormap rotation. (default = 1.0).\n");
fprintf(stderr," -display <host:#>\t Specify alternate X server\n");
fprintf(stderr," -s <size>\t\t Use a <size>-square area\n\n");
exit(1);
}
main (int argc, char **argv)
{
char *display = NULL;
int x, y, X, Y, i, j;
int size = 0, testcolor = 0, matrix_size = 4;
int xsize = 100, ysize = 100;
/* Initialize the random number generator */
srand48(getpid());
i = 0;
for(i = 1; i < argc; i++)
{
if (! strncmp("-s", argv[i], 2) && i+1 < argc)
size = atoi(argv[++i]);
else if (! strncmp("-x", argv[i], 2) && i+1 < argc)
xsize = atoi(argv[++i]);
else if (! strncmp("-y", argv[i], 2) && i+1 < argc)
ysize = atoi(argv[++i]);
else if (! strncmp("-f", argv[i], 2) && i+1 < argc)
Futz = atof(argv[++i]);
else if (! strncmp("-display", argv[i], 8) && i+1 < argc)
display = argv[++i];
else if (! strncmp("-delay", argv[i], 6) && i+1 < argc)
sleep_delay = (int) ((double)sleep_delay * atof(argv[++i]));
else if (! strncmp("-dist", argv[i], 5))
usedist = 0;
else
Usage(argv[0], argv[i]);
}
if (size)
global_x = global_y = x = y = size;
else
{
global_x = x = xsize;
global_y = y = ysize;
}
buf = (byte *)malloc(x * y);
if (!buf)
{
fprintf(stderr, "%s: malloc failure.\n", argv[0]);
exit(1);
}
memset(buf, 0, x * y);
/*
* Prime the 4 corners with random colors.
*/
BUF(0,0) = (int)( (drand48() * NUMCOLORS) + 1.0 );
BUF(x-1,0) = (int)( (drand48() * NUMCOLORS) + 1.0 );
BUF(x-1,y-1) = (int)( (drand48() * NUMCOLORS) + 1.0 );
BUF(0,y-1) = (int)( (drand48() * NUMCOLORS) + 1.0 );
fprintf(stderr, "Subdividing ..."); fflush(stderr);
subdivide(0, 0, x-1, y-1);
fprintf(stderr, " done\n"); fflush(stderr);
InitX(display, x, y);
show_pic(buf, x, y);
manage_window();
exit(0);
}
@EOF
set `wc -lwc <plasma.c`
if test $1$2$3 != 418135110205
then
echo ERROR: wc results of plasma.c are $* should be 418 1351 10205
fi
chmod 664 plasma.c
exit 0
--
cheeks at edsr.eds.com or ...uunet!edsr!cheeks
More information about the Alt.sources
mailing list