/* -*- Mode: C; tab-width: 4 -*- */
-/* glhanoi, Copyright (c) 2005 Dave Atkinson <dave.atkinson@uwe.ac.uk>
+/* glhanoi, Copyright (c) 2005, 2009 Dave Atkinson <da@davea.org.uk>
* except noise function code Copyright (c) 2002 Ken Perlin
*
* Permission to use, copy, modify, distribute, and sell this software and its
int drag_x;
int drag_y;
int noise_initted;
-
- int p[512];
+ int p[512];
} glhcfg;
int dst = glhanoi->dst;
GLfloat theta;
GLfloat sintheta, costheta;
+ double absx;
- if(glhanoi->state != FINISHED && random() % 6 == 0) {
- disk->rotAngle =
- -180.0 * (2 - 2 * random() % 2) * (random() % 3 + 1);
+ if(glhanoi->state != FINISHED) {
+ double xxx = -180.0 * (dst - src >= 0 ? 1.0 : -1.0);
+ if(random() % 6 == 0) {
+ disk->rotAngle = xxx * (2 - 2 * random() % 2) * (random() % 3 + 1);
+ } else {
+ disk->rotAngle = xxx;
+ }
+ if(random() % 4 == 0) {
+ disk->rotAngle = -disk->rotAngle;
+ }
} else {
disk->rotAngle = -180.0;
}
disk->xmin = glhanoi->poleOffset * (src - 1);
disk->xmax = glhanoi->poleOffset * (dst - 1);
disk->ymin = glhanoi->poleHeight;
- ymax =
- glhanoi->poleHeight + fabs(disk->xmax -
- disk->xmin) * (glhanoi->state ==
- FINISHED ? 1.0 +
- (double)(glhanoi->
- numberOfDisks -
- disk->id) /
- (double)glhanoi->
- numberOfDisks : 1.0);
+ absx = fabs(disk->xmax - disk->xmin);
+ ymax = glhanoi->poleHeight + absx;
+ if(glhanoi->state == FINISHED) {
+ ymax += absx * (double)(glhanoi->numberOfDisks - disk->id);
+ }
h = ymax - disk->ymin;
theta = atan((disk->xmin - disk->xmax) * A(disk->xmin, disk->xmax, h));
if(theta < 0.0)
d->position[1] = d->ymin + (d->usintheta - 0.5 * g * t) * t;
d->rotation[1] =
- d->rotAngle * (d->position[0] - d->xmin) / (d->xmax - d->xmin);
+ d->rotAngle * (d->position[0] - d->xmin) / (d->xmax - d->xmin);
}
static void downfunc(GLdouble t, Disk * d)
x -= floor(x); /* FIND RELATIVE X,Y,Z */
y -= floor(y); /* OF POINT IN CUBE. */
z -= floor(z);
- u = fade(x), /* COMPUTE FADE CURVES */
- v = fade(y), /* FOR EACH OF X,Y,Z. */
- w = fade(z);
- A = glhanoi->p[X] + Y, AA = glhanoi->p[A] + Z, AB = glhanoi->p[A + 1] + Z, /* HASH COORDINATES OF */
- B = glhanoi->p[X + 1] + Y, BA = glhanoi->p[B] + Z, BB = glhanoi->p[B + 1] + Z; /* THE 8 CUBE CORNERS, */
- return lerp(w, lerp(v, lerp(u, grad(glhanoi->p[AA], x, y, z), /* AND ADD */
- grad(glhanoi->p[BA], x - 1, y, z)), /* BLENDED */
- lerp(u, grad(glhanoi->p[AB], x, y - 1, z), /* RESULTS */
- grad(glhanoi->p[BB], x - 1, y - 1, z))), /* FROM 8 CORNERS */
+ u = fade(x), /* COMPUTE FADE CURVES */
+ v = fade(y), /* FOR EACH OF X,Y,Z. */
+ w = fade(z);
+ A = glhanoi->p[X] + Y;
+ AA = glhanoi->p[A] + Z;
+ AB = glhanoi->p[A + 1] + Z, /* HASH COORDINATES OF */
+ B = glhanoi->p[X + 1] + Y;
+ BA = glhanoi->p[B] + Z;
+ BB = glhanoi->p[B + 1] + Z; /* THE 8 CUBE CORNERS, */
+ return lerp(w, lerp(v, lerp(u, grad(glhanoi->p[AA], x, y, z),/* AND ADD */
+ grad(glhanoi->p[BA], x - 1, y, z)),/* BLENDED */
+ lerp(u, grad(glhanoi->p[AB], x, y - 1, z),/* RESULTS */
+ grad(glhanoi->p[BB], x - 1, y - 1, z))),/* FROM 8 CORNERS */
lerp(v, lerp(u, grad(glhanoi->p[AA + 1], x, y, z - 1), grad(glhanoi->p[BA + 1], x - 1, y, z - 1)), /* OF CUBE */
lerp(u, grad(glhanoi->p[AB + 1], x, y - 1, z - 1),
grad(glhanoi->p[BB + 1], x - 1, y - 1, z - 1))));
return textureData;
}
-static tex_col_t makeMarbleColours(void)
+static void freeTexCols(tex_col_t*p)
+{
+ free(p->colours);
+ free(p);
+}
+
+static tex_col_t *makeMarbleColours(void)
{
- tex_col_t marbleColours;
+ tex_col_t *marbleColours;
int ncols = 2;
- marbleColours.colours = calloc(sizeof(GLuint), ncols);
- marbleColours.ncols = ncols;
+ marbleColours = malloc(sizeof(tex_col_t));
+ if(marbleColours == NULL) return NULL;
+ marbleColours->colours = calloc(sizeof(GLuint), ncols);
+ if(marbleColours->colours == NULL) return NULL;
+ marbleColours->ncols = ncols;
- marbleColours.colours[0] = 0x3f3f3f3f;
- marbleColours.colours[1] = 0xffffffff;
+ marbleColours->colours[0] = 0x3f3f3f3f;
+ marbleColours->colours[1] = 0xffffffff;
return marbleColours;
}
static int makeTextures(glhcfg *glhanoi)
{
GLubyte *marbleTexture;
- tex_col_t marbleColours;
+ tex_col_t *marbleColours;
glGenTextures(N_TEXTURES, glhanoi->textureNames);
- marbleColours = makeMarbleColours();
+ if((marbleColours = makeMarbleColours()) == NULL) {
+ return 1;
+ }
if((marbleTexture =
makeTexture(glhanoi, MARBLE_TEXTURE_SIZE, MARBLE_TEXTURE_SIZE, 1,
- makeMarbleTexture, &marbleColours)) == NULL) {
+ makeMarbleTexture, marbleColours)) == NULL) {
return 1;
}
MARBLE_TEXTURE_SIZE, MARBLE_TEXTURE_SIZE, 0,
GL_RGBA, GL_UNSIGNED_BYTE, marbleTexture);
free(marbleTexture);
+ freeTexCols(marbleColours);
return 0;
}
glhanoi->baseHeight);
glEndList();
-
if((glhanoi->poleList = glGenLists(1)) == 0) {
fprintf(stderr, "can't allocate memory for towers display list\n");
exit(EXIT_FAILURE);
if (glhanoi->numberOfDisks <= 1)
glhanoi->numberOfDisks = 3 + (int) BELLRAND(9);
- /* magicnumber is a bitfield, so we can't have more than 31 discs
- on a system with 4-byte ints. */
- if (glhanoi->numberOfDisks >= 8 * sizeof(int))
- glhanoi->numberOfDisks = (8 * sizeof(int)) - 1;
+ /* magicnumber is a bitfield, so we can't have more than 31 discs
+ on a system with 4-byte ints. */
+ if (glhanoi->numberOfDisks >= 8 * sizeof(int))
+ glhanoi->numberOfDisks = (8 * sizeof(int)) - 1;
glhanoi->maxDiskIdx = glhanoi->numberOfDisks - 1;
glhanoi->wire = MI_IS_WIREFRAME(mi);
ENTRYPOINT void draw_glhanoi(ModeInfo * mi)
{
- glhcfg *glhanoi = &glhanoi_cfg[MI_SCREEN(mi)];
+ glhcfg *glhanoi = &glhanoi_cfg[MI_SCREEN(mi)];
Display *dpy = MI_DISPLAY(mi);
Window window = MI_WINDOW(mi);