/*-
* Cells growing on your screen
*
- * Copyright (c) 2006 by Matthias Toussaint
+ * Copyright (c) 2007 by Matthias Toussaint
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose and without fee is hereby granted,
* event will the author be liable for any lost revenue or profits or
* other special, indirect and consequential damages.
*
- * 2006: Written by Matthias Toussaint
+ * 2007: Written by Matthias Toussaint
+ * 0.1 Initial version
+ * 0.2 Bugfixes (threading) and code cleanup by Jamie Zawinski
+ * Window scaling bug + performance bug in tick()
*/
#include <sys/time.h> /* gettimeofday */
#define DEF_MINFOOD "5"
#define DEF_MAXFOOD "20"
#define DEF_DIVIDEAGE "20"
-#define DEF_MINDIST "1.40"
+#define DEF_MINDIST "1.4"
#define DEF_PAUSE "50"
#define DEFAULTS "*delay: 30000 \n" \
#undef countof
#define countof(x) (sizeof((x))/sizeof((*x)))
-#define USE_VERTEX_ARRAY
+#ifndef HAVE_JWZGLES /* glDrawElements unimplemented... */
+# define USE_VERTEX_ARRAY
+#endif
#define TEX_SIZE 64
{
GLXContext *glx_context;
int width, height; /* current size of viewport */
+ double screen_scale; /* we scale content with window size */
int num_cells; /* current number of cell in list */
Cell *cell; /* array of cells */
int cell_polys;
GLfloat color[4]; /* current cell color */
- int radius; /* cell radius */
+ double radius; /* cell radius */
int move_dist; /* min distance from neighbours for forking */
int max_cells; /* maximum number of cells */
int num_seeds; /* number of initial seeds */
{&s_maxfood, "maxfood", "Max Food", DEF_MAXFOOD, t_Int},
{&s_pause, "pause", "Pause at end", DEF_PAUSE, t_Int},
{&s_divideage, "divideage", "Age for duplication (Ticks)", DEF_DIVIDEAGE, t_Int},
- {&s_min_dist, "mindist", "Minimum prefered distance to other cells", DEF_MINDIST, t_Float},
+ {&s_min_dist, "mindist", "Minimum preferred distance to other cells", DEF_MINDIST, t_Float},
{&s_keepold, "keepold", "Keep old cells", DEF_KEEPOLD, t_Bool}
};
static Object *clone_Object( Object * );
/* return 1 if cell is capable to divide */
static int can_divide( State *st, Cell *cell );
+#ifdef USE_VERTEX_ARRAY
static VertexArray *array_from_ObjectSmooth( ObjectSmooth * );
+#endif
static void create_nucleus_texture( State *st );
ENTRYPOINT ModeSpecOpt glcells_opts = { countof(opts), opts, countof(vars), vars,
*/
static inline int random_interval( int min, int max )
{
- return min+(random()%(max-min));
+ int n = max - min;
+ if (n == 0) n = 1;
+ return min+(random()%n);
}
static inline int random_max( int max )
return ret;
}
+#ifdef USE_VERTEX_ARRAY
static VertexArray *array_from_ObjectSmooth( ObjectSmooth *obj )
{
int i, j;
return array;
}
+#endif /* USE_VERTEX_ARRAY */
+
/* create a smoothed version of the given Object
by computing average normal vectors for the vertexes
fprintf( stderr, "tick %d\n", usec );
gettimeofday( &tv1, NULL );
#endif
- glClearColor( 0, 0, 0, 0 );
-
+
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_TEST);
ObjectSmooth *smooth;
#ifdef USE_VERTEX_ARRAY
VertexArray *vertex_array;
+#else
+ int t, i;
#endif
int list = glGenLists(1);
static void create_cells( State *st )
{
+ int border = (int)(200.0 * st->screen_scale);
int i, foodcnt;
- int w = st->width-400;
- int h = st->height-400;
+ int w = st->width-2*border;
+ int h = st->height-2*border;
st->color[0] = 0.5 + random_max( 1000 ) * 0.0005;
st->color[1] = 0.5 + random_max( 1000 ) * 0.0005;
st->num_cells = st->num_seeds;
for (i=0; i<st->num_cells; ++i) {
- st->cell[i].x = 200 + random_max( w );
- st->cell[i].y = 200 + random_max( h );
+ st->cell[i].x = border + random_max( w );
+ st->cell[i].y = border + random_max( h );
st->cell[i].vx = 0.0;
st->cell[i].vy = 0.0;
st->cell[i].age = random_max( 0x0f );
int num_living = 0;
const double check_dist = 0.75*st->move_dist;
const double grow_dist = 0.75*st->radius;
+ const double adult_radius = st->radius;
/* find number of cells capable of division
and count living cells
const double dy = st->cell[b].y - st->cell[j].y;
if (fabs(dx) < check_dist || fabs(dy) < check_dist) {
- const double dist = sqrt( dx*dx+dy*dy );
+ const double dist = dx*dx+dy*dy;
+ /*const double dist = sqrt( dx*dx+dy*dy );*/
if (dist<min_dist) {
min_dist = dist;
min_index = j;
}
st->cell[b].min_dist = len;
/* if not adult (radius too small) */
- if (st->cell[b].radius < st->radius) {
+ if (st->cell[b].radius < adult_radius) {
/* if too small 60% stop shrinking */
- if (st->cell[b].radius < st->radius * 0.6) {
+ if (st->cell[b].radius < adult_radius * 0.6) {
st->cell[b].growth = 1.0;
}
/* at safe distance we start growing again */
State *st = &sstate[MI_SCREEN(mi)];
st->height = height;
st->width = width;
+ st->screen_scale = (double)width / 1600.0;
+ st->radius = s_radius;
+ if (st->radius < 5) st->radius = 5;
+ if (st->radius > 200) st->radius = 200;
+ st->radius *= st->screen_scale;
+
+ st->move_dist = s_min_dist;
+ if (st->move_dist < 1.0) st->move_dist = 1.0;
+ if (st->move_dist > 3.0) st->move_dist = 3.0;
+ st->move_dist *= st->radius;
+
glViewport (0, 0, (GLint) width, (GLint) height);
glMatrixMode(GL_PROJECTION);
if (st->food) free( st->food );
st->food = (int *)malloc( ((width*height)/16)*sizeof(int) );
-
- create_cells( st );
+ /* create_cells( st );*/
}
ENTRYPOINT void
st->num_cells = 0;
st->wire = MI_IS_WIREFRAME(mi);
+# ifdef HAVE_JWZGLES /* #### glPolygonMode other than GL_FILL unimplemented */
+ st->wire = 0;
+# endif
+
/* get settings */
st->max_cells = s_maxcells;;
if (st->max_cells < 50) st->max_cells = 50;