9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
* [9fans] Galaxy screensaver updated
@ 2002-06-23 22:44 Sam
  2002-06-24  6:04 ` Micah Stetson
  2002-06-24 13:04 ` andrey mirtchovski
  0 siblings, 2 replies; 4+ messages in thread
From: Sam @ 2002-06-23 22:44 UTC (permalink / raw)
  To: 9fans

[-- Attachment #1: Type: TEXT/PLAIN, Size: 446 bytes --]

Attached is the new and improved galaxy screensaver.  I've put
suggestions as to what to do next, if anyone wants to pick
up the ball.  I've wasted enough time on this. ;)

The middle mouse button picks different colors, as well
as some options.  See the end of the list.  My favourite
is definitely 'Random.'

If you want to see some really neat effects, see line 351.

Thanks Andrey, I had a super blast with this!

Cheers,

Sam

[-- Attachment #2: Type: TEXT/PLAIN, Size: 10260 bytes --]

/* Touched by:
  *  sah@coraid.com, 06/02
  *
  * To do:
  * Decrease the mass of the galaxy as the stars leave.
  * Add fullscreen option on right button menu.
  * Give stars tiny mass and make them react to each other.
  * Give stars size based on their mass.
  */
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <event.h>

#define MIN_GALS			2
#define MAX_GALS			4
#define MAX_STARS			500
#define MAX_IDELTAT		50
#define MIN_GALSZ			1e-1
#define MAX_GALSZ			1.5e-1
#define COLORBASE			16

#define EPSILON 			1e-8
#define SQRT_EPSILON 		1e-4
#define DELTAT 			(MAX_IDELTAT * SQRT_EPSILON)
#define QCONS				1e-3
#define EPS				1/(EPSILON * SQRT_EPSILON * DELTAT * DELTAT * QCONS);
#define M_PI				3.141592653589793238462643383 

typedef struct Star Star;
struct Star {
	double pos[3], vel[3];
};

typedef struct Galaxy Galaxy;
struct Galaxy {
	int mass, nstars, galcol, swappoints, col;
	double pos[3], vel[3], opos[3], ovel[3];
	Star stars[MAX_STARS];
	Point oldpoints[MAX_STARS], newpoints[MAX_STARS];
};

typedef struct Uni Uni;
struct Uni {
	int midx, midy, ngals, f_hititerations, step;
	double mat[3][3], scale, diff[3], rot_x, rot_y;
	Galaxy gals[MAX_GALS];
};

enum {	WHITE, PALEGREYGREEN, PALEGREYBLUE, GREYGREEN, GREYBLUE, 
		RED, GREEN, BLUE, CYAN, MAGENTA, YELLOW, PALEYELLOW, DARKYELLOW, 
		DARKGREEN, PALEGREEN, MEDGREEN, DARKBLUE, PALEBLUEGREEN, PALEBLUE,
		BLUEGREEN, YELLOWGREEN, MEDBLUE, PURPLEBLUE, RANDY, 
		TWINKLE, SPARKLE, FWORKS, NCOLORS,
};

int colors[NCOLORS] = {
[WHITE] 			DWhite,
[RED]			DRed,
[GREEN]			DGreen,
[BLUE]			DBlue,
[CYAN]			DCyan,
[MAGENTA]		DMagenta,
[YELLOW]			DYellow,
[PALEYELLOW]		DPaleyellow,
[DARKYELLOW]		DDarkyellow,
[DARKGREEN]		DDarkgreen,
[PALEGREEN]		DPalegreen,
[MEDGREEN]		DMedgreen,
[DARKBLUE]		DDarkblue,
[PALEBLUEGREEN]	DPalebluegreen,
[PALEBLUE]		DPaleblue,
[BLUEGREEN]		DBluegreen,
[GREYGREEN]		DGreygreen,
[PALEGREYGREEN]	DPalegreygreen,
[YELLOWGREEN]	DYellowgreen,
[MEDBLUE]		DMedblue,
[GREYBLUE]		DGreyblue,
[PALEGREYBLUE]	DPalegreyblue,
[PURPLEBLUE]		DPurpleblue
};

char *mbtns[] = {
[WHITE] 			"White",
[RED]			"Red",
[GREEN]			"Green",
[BLUE]			"Blue",
[CYAN]			"Cyan",
[MAGENTA]		"Magenta",
[YELLOW]			"Yellow",
[PALEYELLOW]		"Paleyellow",
[DARKYELLOW]		"Darkyellow",
[DARKGREEN]		"Darkgreen",
[PALEGREEN]		"Palegreen",
[MEDGREEN]		"Medgreen",
[DARKBLUE]		"Darkblue",
[PALEBLUEGREEN]	"Palebluegreen",
[PALEBLUE]		"Paleblue",
[BLUEGREEN]		"Bluegreen",
[GREYGREEN]		"Greygreen",
[PALEGREYGREEN]	"Palegreygreen",
[YELLOWGREEN]	"Yellowgreen",
[MEDBLUE]		"Medblue",
[GREYBLUE]		"Greyblue",
[PALEGREYBLUE]	"Palegreyblue",
[PURPLEBLUE]		"PurpleBlue",
[RANDY]			"Random",
[FWORKS]			"Fireworks",
[SPARKLE]			"Sparkle",
[TWINKLE]		"Twinkle",
[NCOLORS]		0
};

char *rbtns[] = { "exit", 0 };

Image *images[NCOLORS];
Uni univ;
uint color;

int
alloc_colors(void)
{
	int i;

	for(i=0; i<NCOLORS; i++)
		images[i] = allocimage(display, Rect(0,0,2,2), display->chan, 0, colors[i]);
	return 1;
}

void
free_colors(void)
{
	int i;

	for(i=0; i<NCOLORS; i++)
		freeimage(images[i]);
}

/* mat? */
void
init_mat(void)
{
	double w1, w2, sinw1, sinw2, cosw1, cosw2;

	w1 = w2 = 2.0 * M_PI * frand();

	sinw1 = sin(w1);
	sinw2 = sin(w2);
	cosw1 = cos(w1);
	cosw2 = cos(w2);

	univ.mat[0][0] = cosw2;
	univ.mat[0][1] = -sinw1 * sinw2;
	univ.mat[0][2] = cosw1 * sinw2;
	univ.mat[1][0] = 0.0;
	univ.mat[1][1] = cosw1;
	univ.mat[1][2] = sinw1;
	univ.mat[2][0] = -sinw2;
	univ.mat[2][1] = -sinw1 * cosw2;
	univ.mat[2][2] = cosw1 * cosw2;
}

void
init_gal(Galaxy *g)
{
	g->vel[0] = g->vel[1] = g->vel[2] = frand() * 2.0 - 1.0;
	g->ovel[0] = g->ovel[1] = g->ovel[2] = g->vel[0];
	g->pos[0] = g->opos[0] = -g->vel[0] * DELTAT * univ.f_hititerations + frand() - 0.5;
	g->pos[1] = g->opos[0] = -g->vel[1] * DELTAT * univ.f_hititerations + frand() - 0.5;
	g->pos[2] = g->opos[0] = -g->vel[2] * DELTAT * univ.f_hititerations + frand() - 0.5;
	g->mass = (int) (frand() * 1000.0) + 1;
	g->nstars = nrand(MAX_STARS / 2) + MAX_STARS / 2;

	if(color == RANDY)
		g->col = rand()%RANDY;
}

void
init_stars(Galaxy *g)
{
	int i;
	double galsz, sinw, cosw, d, h, v;
	Star *st;
	Point *oldp, *newp;

	galsz = MAX_GALSZ*frand() + MIN_GALSZ;
	st = g->stars;
	oldp = g->oldpoints;
	newp = g->newpoints;

	for (i=0; i < g->nstars; i++, st++, oldp++, newp++) {
		d = 2.0 * M_PI * frand();
		sinw = sin(d);
		cosw = cos(d);
		d = frand() * galsz;
		h = frand() * exp(-2.0 * (d / galsz)) / 5.0 * galsz;

		if(frand() < 0.5)
			h = -h;
		st->pos[0] = univ.mat[0][0] * d * cosw + univ.mat[1][0] * d * sinw + univ.mat[2][0] *
				 	h + g->pos[0];
		st->pos[1] = univ.mat[0][1] * d * cosw + univ.mat[1][1] * d * sinw + univ.mat[2][1] *
				 	h + g->pos[1];
		st->pos[2] = univ.mat[0][2] * d * cosw + univ.mat[1][2] * d * sinw + univ.mat[2][2] *
				 	h + g->pos[2];

		v = sqrt(g->mass * QCONS / sqrt(d * d + h * h));
		st->vel[0] = -univ.mat[0][0] * v * sinw + univ.mat[1][0] * v * cosw + g->vel[0];
		st->vel[1] = -univ.mat[0][1] * v * sinw + univ.mat[1][1] * v * cosw + g->vel[1];
		st->vel[2] = -univ.mat[0][2] * v * sinw + univ.mat[1][2] * v * cosw + g->vel[2];

		st->vel[0] *= DELTAT;
		st->vel[1] *= DELTAT;
		st->vel[2] *= DELTAT;
	
		*oldp = Pt(0, 0);
		*newp = Pt(0, 0);;
	}
 }

static void
startover(void)
{
	int i;
	Galaxy *g;

	univ.step = 0;
	univ.rot_y = 0;
	univ.rot_x = 0;
	univ.ngals = MIN_GALS + (frand()*(MAX_GALS-MIN_GALS+1));
	for(i=0, g=univ.gals; i < univ.ngals; i++, g++) {
		init_mat();
		init_gal(g);
		init_stars(g);
	}
	draw(screen, screen->r, display->black, nil, ZP);
}

void
init(void)
{
	srand(time(0));

	if(initdraw(nil, nil, "bez") < 0)
		sysfatal("initdraw failed: %r");
	if(!alloc_colors())
		sysfatal("failed to init colors\n");
	univ.f_hititerations = 100;
	univ.scale = (double) (Dx(screen->r) + Dy(screen->r)) / 8.0;
	univ.midx =  screen->r.min.x + Dx(screen->r)  / 2;
	univ.midy =  screen->r.min.y +Dy(screen->r) / 2;
}

/* calculate star pos,vel relative to the gravity of the other galaxies */
void
calc_star_rel_gal(Galaxy *g, Star *s)
{
	double d, d0, d1, d2, v0, v1, v2;

	v0 = s->vel[0], v1 = s->vel[1], v2 = s->vel[2];
	d0 = g->pos[0] - s->pos[0];
	d1 = g->pos[1] - s->pos[1];
	d2 = g->pos[2] - s->pos[2];
	d = d0 * d0 + d1 * d1 + d2 * d2;

	if (d > EPSILON)
		d = g->mass / (d * sqrt(d)) * DELTAT * DELTAT * QCONS;
	else
		d = g->mass * EPS;
	v0 += d0 * d;
	v1 += d1 * d;
	v2 += d2 * d;
	s->vel[0] = v0, s->vel[1] = v1, s->vel[2] = v2;
	s->pos[0] += v0, s->pos[1] += v1, s->pos[2] += v2;
}

/* calculate galaxy pos/vel relative to other galaxies */
void
calc_gal_rel_gals(Galaxy *thisg)
{
	double d, d0, d1, d2;
	int i;
	Galaxy *g;

	for (i=0, g=univ.gals; i < univ.ngals; i++, g++) {
		if(g == thisg)
			continue;
		d0 = g->opos[0] - thisg->pos[0];
		d1 = g->opos[1] - thisg->pos[1];
		d2 = g->opos[2] - thisg->pos[2];
		d = d0 * d0 + d1 * d1 + d2 * d2;

		if(d > EPSILON)
			d = thisg->mass * thisg->mass / (d * sqrt(d));
		else
			d = thisg->mass * thisg->mass / (EPSILON * SQRT_EPSILON);
		d *= DELTAT * QCONS;
		d0 *= d;
		d1 *= d;
		d2 *= d;
		thisg->vel[0] += d0 / thisg->mass;
		thisg->vel[1] += d1 / thisg->mass;
		thisg->vel[2] += d2 / thisg->mass;
		g->vel[0] -= d0 / g->mass;
		g->vel[1] -= d1 / g->mass;
		g->vel[2] -= d2 / g->mass;
	}
	thisg->pos[0] += thisg->vel[0] * DELTAT;
	thisg->pos[1] += thisg->vel[1] * DELTAT;
	thisg->pos[2] += thisg->vel[2] * DELTAT;
}

void
redraw_stars(Galaxy *g)
{
	uint i;
	Rectangle r;
	Point *oldp, *newp;

	if((g->swappoints ^= 1)) {
		oldp = g->newpoints;
		newp = g->oldpoints;
	} else {
		oldp=g->oldpoints;
		newp=g->newpoints;
	}
	if(color == FWORKS)
		g->col = rand()%RANDY;
	for(i=0; i < g->nstars; i++, oldp++, newp++) {
		if(color == SPARKLE)
			g->col = rand()%RANDY;
		else if(color == TWINKLE)
			g->col = rand()%PALEGREYBLUE;
		r = Rpt(*oldp, addpt(*oldp, Pt(2, 2)));
		draw(screen, r, display->black, nil, ZP);
		r = Rpt(*newp, addpt(*newp, Pt(2, 2)));
		draw(screen, r, images[g->col], nil, ZP);

	}
 }

void
redraw_gal(Galaxy *g)
{
	int i;
	Point *p;
	Star *s;

	s=g->stars;

//	try one of these instead for nifty effects ;)
//	p = g->newpoints;
//	p = g->swappoints ? g->oldpoints : g->newpoints;
	p = g->swappoints ? g->newpoints : g->oldpoints;

	for(i=0; i < g->nstars; i++, s++, p++) {
		calc_star_rel_gal(g, s);
		p->x = (((s->pos[0]) - (s->pos[2])) * univ.scale) + univ.midx;
		p->y = (((s->pos[1]) - (((s->pos[0]) + (s->pos[2])))) * univ.scale) + univ.midy;
	}
	calc_gal_rel_gals(g);
	redraw_stars(g);
}

void
redraw_univ(void)
{
	int i; 
	Galaxy *g;

	univ.rot_y += 0.01;
	univ.rot_x += 0.004;

	for(i=0, g=univ.gals; i < univ.ngals; i++, g++)
		redraw_gal(g);
	for(i=0, g=univ.gals; i < univ.ngals; i++, g++) {
		g->ovel[0] = g->vel[0];
		g->ovel[1] = g->vel[1];
		g->ovel[2] = g->vel[2];
		g->opos[0] = g->pos[0];
		g->opos[1] = g->pos[1];
		g->opos[2] = g->pos[2];
	}
	if(++univ.step > univ.f_hititerations * 4)
		startover();
}

void
eresized(int new)
{
	if(new && getwindow(display, Refnone) < 0)
		sysfatal("can't reattach to window");
	draw(screen, screen->r, display->black, nil, ZP);
}

void
set_galcolor(int col)
{
	int i;
	Galaxy *g;

	if(col < RANDY)
		for(i=0, g=univ.gals; i < univ.ngals; i++, g++)
			g->col = col;
	else if(col == RANDY)
		for(i=0, g=univ.gals; i < univ.ngals; i++, g++)
			g->col = rand()%RANDY;
		
}

Menu rmenu = { rbtns }, mmenu = { mbtns };
Mouse m;

void 
main(void)
{
	vlong tbegin, tend;
	ulong frames=0;
	void init(void);
	int col;

	init();
	einit(Emouse);
	eresized(0);
	tbegin = nsec();

	for(;;) {
		if(ecanmouse()) {
			m = emouse();
			if(m.buttons&4)
			if(!emenuhit(3, &m, &rmenu)) {
				tend = nsec();
				print("fps: %uf\n", frames/((tend - tbegin)/1000000000.0));
				exits(0);
			}
			if(m.buttons&2)
			if((col=emenuhit(2, &m, &mmenu)) >= 0)
				set_galcolor(color=col);
		}
		redraw_univ();
		frames++;
	}
}

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [9fans] Galaxy screensaver updated
  2002-06-23 22:44 [9fans] Galaxy screensaver updated Sam
@ 2002-06-24  6:04 ` Micah Stetson
  2002-06-24 13:04 ` andrey mirtchovski
  1 sibling, 0 replies; 4+ messages in thread
From: Micah Stetson @ 2002-06-24  6:04 UTC (permalink / raw)
  To: 9fans

On Sun, Jun 23, 2002 at 06:44:25PM -0400, Sam wrote:
> images[i] = allocimage(display, Rect(0,0,2,2), display->chan, 0, colors[i]);

Had to s/display->chan/screen->chan/ in 4th Ed.  I guess it
was decided that having both was redundant, but graphics(2)
still says there's a chan member in the Display struct.  I
suppose it was missed?

Micah



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [9fans] Galaxy screensaver updated
  2002-06-24 13:04 ` andrey mirtchovski
@ 2002-06-24 12:20   ` Sam
  0 siblings, 0 replies; 4+ messages in thread
From: Sam @ 2002-06-24 12:20 UTC (permalink / raw)
  To: 9fans

I don't know, but it hasn't occurred again.  I took out all the
nasty, unnecessary dynamic memory allocation and it went away.

The only problem I'm seeing now is that it crashes when the screen
blacks out due to lack of user input.  I don't really consider this
a show-stopper. ;)

Cheers,

Sam

On Mon, 24 Jun 2002, andrey mirtchovski wrote:

> i have translated five or six more xscreensaver hacks (long delay
> between flights :). i'm not able to send them to the list now,
> but will do so as soon as possible..
>
> some of the (tom duff's spheres for example) now have colors :)
>
> one thought -- could it be possible that the program crashes because
> there is some sort of a race condition with eresized()?
>
> does it get called the same way notes handlers are? i don't know,
> just speculating -- i had only one crash during a resize for the last
> few days and the rarity of it is puzzling me...
>
> anyway, i'm planning a web page for ports and fixes to the
> xscreensaver hacks -- i'll put your new galaxy code in...
>
> andrey
>
> On Sun, 23 Jun 2002, Sam wrote:
>
> > Attached is the new and improved galaxy screensaver.  I've put
> > suggestions as to what to do next, if anyone wants to pick
> > up the ball.  I've wasted enough time on this. ;)
> >
> > The middle mouse button picks different colors, as well
> > as some options.  See the end of the list.  My favourite
> > is definitely 'Random.'
> >
> > If you want to see some really neat effects, see line 351.
> >
> > Thanks Andrey, I had a super blast with this!
> >
> > Cheers,
> >
> > Sam
> >
>



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [9fans] Galaxy screensaver updated
  2002-06-23 22:44 [9fans] Galaxy screensaver updated Sam
  2002-06-24  6:04 ` Micah Stetson
@ 2002-06-24 13:04 ` andrey mirtchovski
  2002-06-24 12:20   ` Sam
  1 sibling, 1 reply; 4+ messages in thread
From: andrey mirtchovski @ 2002-06-24 13:04 UTC (permalink / raw)
  To: 9fans

i have translated five or six more xscreensaver hacks (long delay
between flights :). i'm not able to send them to the list now,
but will do so as soon as possible..

some of the (tom duff's spheres for example) now have colors :)

one thought -- could it be possible that the program crashes because
there is some sort of a race condition with eresized()?

does it get called the same way notes handlers are? i don't know,
just speculating -- i had only one crash during a resize for the last
few days and the rarity of it is puzzling me...

anyway, i'm planning a web page for ports and fixes to the
xscreensaver hacks -- i'll put your new galaxy code in...

andrey

On Sun, 23 Jun 2002, Sam wrote:

> Attached is the new and improved galaxy screensaver.  I've put
> suggestions as to what to do next, if anyone wants to pick
> up the ball.  I've wasted enough time on this. ;)
>
> The middle mouse button picks different colors, as well
> as some options.  See the end of the list.  My favourite
> is definitely 'Random.'
>
> If you want to see some really neat effects, see line 351.
>
> Thanks Andrey, I had a super blast with this!
>
> Cheers,
>
> Sam
>



^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2002-06-24 13:04 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-06-23 22:44 [9fans] Galaxy screensaver updated Sam
2002-06-24  6:04 ` Micah Stetson
2002-06-24 13:04 ` andrey mirtchovski
2002-06-24 12:20   ` Sam

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).