From http://www.jwz.org/xscreensaver/xscreensaver-5.37.tar.gz
[xscreensaver] / hacks / glx / glhanoi.c
index a853896e5d174693ce903e86ba129a935f9fa0d3..e390f688c0663fa4f72a1f8281fee88b2968b687 100644 (file)
@@ -29,6 +29,7 @@
                                 "*wireframe: False\n"
                                 
 # define refresh_glhanoi 0
+# define release_glhanoi 0
 
 /* polygon resolution of poles and disks */
 #define NSLICE 32
@@ -235,7 +236,7 @@ ENTRYPOINT ModeSpecOpt glhanoi_opts = { countof(opts), opts, countof(vars), vars
 #ifdef USE_MODULES
 
 ModStruct glhanoi_description = {
-       "glhanoi", "init_glhanoi", "draw_glhanoi", "release_glhanoi",
+       "glhanoi", "init_glhanoi", "draw_glhanoi", NULL,
        "draw_glhanoi", "init_glhanoi", NULL, &glhanoi_opts,
        1000, 1, 2, 1, 4, 1.0, "",
        "Towers of Hanoi", 0, NULL
@@ -345,7 +346,7 @@ static void moveSetup(glhcfg *glhanoi, Disk * disk)
        int dst = glhanoi->dst;
        GLfloat theta;
        GLfloat sintheta, costheta;
-       double absx, dh;
+       double dh;
        double dx, dz; /* total x and z distances from src to dst */
        Pole *poleSrc, *poleDst;
 
@@ -385,7 +386,7 @@ static void moveSetup(glhcfg *glhanoi, Disk * disk)
        /* horizontal distance to travel? */
        /* was: absx = sqrt(disk->xmax - disk->xmin); */
        dh = distance(poleSrc->position, poleDst->position);
-       absx = sqrt(dh);
+       /* absx = sqrt(dh); */
        ymax = glhanoi->poleHeight + dh;
        if(glhanoi->state == FINISHED) {
                ymax += dh * (double)(glhanoi->numberOfDisks - disk->id);
@@ -888,7 +889,6 @@ static int drawTube(GLdouble bottomRadius, GLdouble topRadius,
        GLint lastSlice = nSlice - 1;
        GLfloat radius;
        GLfloat innerRadius;
-       GLfloat maxRadius;
 
        if(bottomThickness > bottomRadius) {
                bottomThickness = bottomRadius;
@@ -902,11 +902,11 @@ static int drawTube(GLdouble bottomRadius, GLdouble topRadius,
        if(topThickness < 0.0) {
                topThickness = 0.0;
        }
-       if(topRadius >= bottomRadius) {
+/*     if(topRadius >= bottomRadius) {
                maxRadius = topRadius;
        } else {
                maxRadius = bottomRadius;
-       }
+       } */
 
        /* bottom */
        y = 0.0;
@@ -1846,6 +1846,9 @@ static int drawTrails(glhcfg *glhanoi) {
  */
 ENTRYPOINT void reshape_glhanoi(ModeInfo * mi, int width, int height)
 {
+       glhcfg *glhanoi = &glhanoi_cfg[MI_SCREEN(mi)];
+       glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(glhanoi->glx_context));
+
        glViewport(0, 0, (GLint) width, (GLint) height);
 
        glMatrixMode(GL_PROJECTION);
@@ -1859,14 +1862,12 @@ ENTRYPOINT void reshape_glhanoi(ModeInfo * mi, int width, int height)
        glClear(GL_COLOR_BUFFER_BIT);
 }
 
+static void free_glhanoi(ModeInfo * mi);
+
 ENTRYPOINT void init_glhanoi(ModeInfo * mi)
 {
        glhcfg *glhanoi;
-       if(!glhanoi_cfg) {
-               glhanoi_cfg =
-                       (glhcfg *) calloc(MI_NUM_SCREENS(mi), sizeof(glhcfg));
-               checkAllocAndExit(!!glhanoi_cfg, "configuration");
-       }
+       MI_INIT(mi, glhanoi_cfg, free_glhanoi);
 
        glhanoi = &glhanoi_cfg[MI_SCREEN(mi)];
        glhanoi->glx_context = init_GL(mi);
@@ -1890,6 +1891,11 @@ ENTRYPOINT void init_glhanoi(ModeInfo * mi)
                (int)((1 - sqrt(frand(1.0))) * (glhanoi->numberOfDisks - 1));
        
        glhanoi->wire = MI_IS_WIREFRAME(mi);
+
+# ifdef HAVE_JWZGLES /* #### glPolygonMode other than GL_FILL unimplemented */
+    glhanoi->wire = 0;
+# endif
+
        glhanoi->light = light;
        glhanoi->fog = fog;
        glhanoi->texture = texture;
@@ -1963,6 +1969,15 @@ ENTRYPOINT void draw_glhanoi(ModeInfo * mi)
        update_glhanoi(glhanoi);
        updateView(glhanoi);
 
+# ifdef HAVE_MOBILE    /* Keep it the same relative size when rotated. */
+    {
+      GLfloat h = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi);
+      int o = (int) current_device_rotation();
+      if (o != 0 && o != 180 && o != -180)
+        glScalef (1/h, 1/h, 1/h);
+    }
+# endif
+
        if(!glhanoi->wire && glhanoi->texture) {
                glEnable(GL_TEXTURE_2D);
        }
@@ -1989,6 +2004,8 @@ ENTRYPOINT Bool glhanoi_handle_event(ModeInfo * mi, XEvent * event)
 {
        glhcfg *glhanoi = &glhanoi_cfg[MI_SCREEN(mi)];
 
+    /* #### this is all wrong on iOS -- should be using gltrackball. */
+
        if(event->xany.type == ButtonPress && event->xbutton.button == Button1) {
                glhanoi->button_down_p = True;
                glhanoi->drag_x = event->xbutton.x;
@@ -2025,34 +2042,37 @@ ENTRYPOINT Bool glhanoi_handle_event(ModeInfo * mi, XEvent * event)
 
                return True;
        }
+#if 0 /* #### doesn't work */
+  else if (screenhack_event_helper (MI_DISPLAY(mi), MI_WINDOW(mi), event))
+    {
+      changeState(glhanoi, START);
+      return True;
+    }
+#endif
        return False;
 }
 
-ENTRYPOINT void release_glhanoi(ModeInfo * mi)
+static void free_glhanoi(ModeInfo * mi)
 {
-       if(glhanoi_cfg != NULL) {
-               int screen;
-               for(screen = 0; screen < MI_NUM_SCREENS(mi); screen++) {
-                       int i;
-                       int j;
-                       glhcfg *glh = &glhanoi_cfg[screen];
-                       glDeleteLists(glh->floorList, 1);
-                       glDeleteLists(glh->baseList, 1);
-                       glDeleteLists(glh->poleList, 1);
-                        glDeleteLists(glh->textureNames[0], 2);
-                       for(j = 0; j < glh->numberOfDisks; ++j) {
-                               glDeleteLists(glh->disk[j].displayList, 1);
-                       }
-                       free(glh->disk);
-                       for(i = 0; i < glh->numberOfPoles; i++) {
-                               if(glh->pole[i].data != NULL) {
-                                       free(glh->pole[i].data);
-                               }
+       int i;
+       int j;
+       glhcfg *glh = &glhanoi_cfg[MI_SCREEN(mi)];
+       if (glh->glx_context) {
+               glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(glh->glx_context));
+               glDeleteLists(glh->floorList, 1);
+               glDeleteLists(glh->baseList, 1);
+               glDeleteLists(glh->poleList, 1);
+                glDeleteLists(glh->textureNames[0], 2);
+               for(j = 0; j < glh->numberOfDisks; ++j) {
+                       glDeleteLists(glh->disk[j].displayList, 1);
+               }
+               free(glh->disk);
+               for(i = 0; i < glh->numberOfPoles; i++) {
+                       if(glh->pole[i].data != NULL) {
+                               free(glh->pole[i].data);
                        }
                }
        }
-       free(glhanoi_cfg);
-       glhanoi_cfg = NULL;
 }
 
 XSCREENSAVER_MODULE ("GLHanoi", glhanoi)