ftp://ftp.linux.ncsu.edu/mirror/ftp.redhat.com/pub/redhat/linux/enterprise/4/en/os...
[xscreensaver] / hacks / glx / moebius.c
index 39229944e0bf3bc92642e4b6dd61ad1c3243b6ed..9052f4bcc6c3e83ff08af3e20484ae960bd5ad5e 100644 (file)
@@ -1,9 +1,8 @@
 /* -*- Mode: C; tab-width: 4 -*- */
 /* moebius --- Moebius Strip II, an Escher-like GL scene with ants. */
 
-#if !defined( lint ) && !defined( SABER )
+#if 0
 static const char sccsid[] = "@(#)moebius.c    5.01 2001/03/01 xlockmore";
-
 #endif
 
 /*-
@@ -88,6 +87,8 @@ static const char sccsid[] = "@(#)moebius.c   5.01 2001/03/01 xlockmore";
 # define HACK_INIT                     init_moebius
 # define HACK_DRAW                     draw_moebius
 # define HACK_RESHAPE          reshape_moebius
+# define HACK_HANDLE_EVENT     moebius_handle_event
+# define EVENT_MASK                    PointerMotionMask
 # define moebius_opts          xlockmore_opts
 # define DEFAULTS                      "*delay:                20000   \n"                     \
                                                        "*showFPS:      False   \n"                     \
@@ -103,6 +104,8 @@ static const char sccsid[] = "@(#)moebius.c 5.01 2001/03/01 xlockmore";
 
 #include <GL/glu.h>
 #include "e_textures.h"
+#include "rotator.h"
+#include "gltrackball.h"
 
 #define DEF_SOLIDMOEBIUS  "False"
 #define DEF_NOANTS  "False"
@@ -112,21 +115,21 @@ static int  noants;
 
 static XrmOptionDescRec opts[] =
 {
-  {(char *) "-solidmoebius", (char *) ".moebius.solidmoebius", XrmoptionNoArg, (caddr_t) "on"},
-  {(char *) "+solidmoebius", (char *) ".moebius.solidmoebius", XrmoptionNoArg, (caddr_t) "off"},
-  {(char *) "-noants", (char *) ".moebius.noants", XrmoptionNoArg, (caddr_t) "on"},
-  {(char *) "+noants", (char *) ".moebius.noants", XrmoptionNoArg, (caddr_t) "off"}
+  {"-solidmoebius", ".moebius.solidmoebius", XrmoptionNoArg, "on"},
+  {"+solidmoebius", ".moebius.solidmoebius", XrmoptionNoArg, "off"},
+  {"-noants", ".moebius.noants", XrmoptionNoArg, "on"},
+  {"+noants", ".moebius.noants", XrmoptionNoArg, "off"}
 };
 static argtype vars[] =
 {
-  {(caddr_t *) & solidmoebius, (char *) "solidmoebius", (char *) "Solidmoebius", (char *) DEF_SOLIDMOEBIUS, t_Bool},
-  {(caddr_t *) & noants, (char *) "noants", (char *) "Noants", (char *) DEF_NOANTS, t_Bool}
+  {&solidmoebius, "solidmoebius", "Solidmoebius", DEF_SOLIDMOEBIUS, t_Bool},
+  {&noants, "noants", "Noants", DEF_NOANTS, t_Bool}
 
 };
 static OptionStruct desc[] =
 {
-       {(char *) "-/+solidmoebius", (char *) "select between a SOLID or a NET Moebius Strip"},
-       {(char *) "-/+noants", (char *) "turn on/off walking ants"}
+       {"-/+solidmoebius", "select between a SOLID or a NET Moebius Strip"},
+       {"-/+noants", "turn on/off walking ants"}
 };
 
 ModeSpecOpt moebius_opts =
@@ -161,12 +164,9 @@ typedef struct {
        GLfloat     step;
        GLfloat     ant_position;
        GLXContext *glx_context;
-
-  GLfloat rotx, roty, rotz;       /* current object rotation */
-  GLfloat dx, dy, dz;             /* current rotational velocity */
-  GLfloat ddx, ddy, ddz;          /* current rotational acceleration */
-  GLfloat d_max;                          /* max velocity */
-
+    rotator    *rot;
+    trackball_state *trackball;
+    Bool        button_down_p;
 } moebiusstruct;
 
 static float front_shininess[] =
@@ -607,7 +607,7 @@ pinit(void)
                                GL_RGB, GL_UNSIGNED_BYTE, WoodTextureData);
     if (status)
       {
-        const char *s = gluErrorString (status);
+        const char *s = (char *) gluErrorString (status);
         fprintf (stderr, "%s: error mipmapping %dx%d texture: %s\n",
                  progname, WoodTextureWidth, WoodTextureHeight,
                  (s ? s : "(unknown)"));
@@ -627,92 +627,49 @@ pinit(void)
 
 
 
-/* lifted from lament.c */
-#define RANDSIGN() ((LRAND() & 1) ? 1 : -1)
-#define FLOATRAND(a) (((double)LRAND() / (double)MAXRAND) * a)
-
-static void
-rotate(GLfloat *pos, GLfloat *v, GLfloat *dv, GLfloat max_v, Bool verbose)
+void
+release_moebius(ModeInfo * mi)
 {
-  double ppos = *pos;
-
-  /* tick position */
-  if (ppos < 0)
-    ppos = -(ppos + *v);
-  else
-    ppos += *v;
-
-  if (ppos > 1.0)
-    ppos -= 1.0;
-  else if (ppos < 0)
-    ppos += 1.0;
-
-  if ((ppos < 0.0) || (ppos > 1.0)) {
-    if (verbose) {
-      (void) fprintf(stderr, "Weirdness in rotate()\n");
-      (void) fprintf(stderr, "ppos = %g\n", ppos);
-    }
-    return;
-  }
-
-  *pos = (*pos > 0 ? ppos : -ppos);
+       if (moebius != NULL) {
+               (void) free((void *) moebius);
+               moebius = (moebiusstruct *) NULL;
+       }
+       FreeAllGL(mi);
+}
 
-  /* accelerate */
-  *v += *dv;
+Bool
+moebius_handle_event (ModeInfo *mi, XEvent *event)
+{
+  moebiusstruct *mp = &moebius[MI_SCREEN(mi)];
 
-  /* clamp velocity */
-  if (*v > max_v || *v < -max_v)
+  if (event->xany.type == ButtonPress &&
+      event->xbutton.button & Button1)
     {
-      *dv = -*dv;
+      mp->button_down_p = True;
+      gltrackball_start (mp->trackball,
+                         event->xbutton.x, event->xbutton.y,
+                         MI_WIDTH (mi), MI_HEIGHT (mi));
+      return True;
     }
-  /* If it stops, start it going in the other direction. */
-  else if (*v < 0)
+  else if (event->xany.type == ButtonRelease &&
+           event->xbutton.button & Button1)
     {
-      if (random() % 4)
-       {
-         *v = 0;
-
-         /* keep going in the same direction */
-         if (random() % 2)
-           *dv = 0;
-         else if (*dv < 0)
-           *dv = -*dv;
-       }
-      else
-       {
-         /* reverse gears */
-         *v = -*v;
-         *dv = -*dv;
-         *pos = -*pos;
-       }
+      mp->button_down_p = False;
+      return True;
     }
-
-  /* Alter direction of rotational acceleration randomly. */
-  if (! (random() % 120))
-    *dv = -*dv;
-
-  /* Change acceleration very occasionally. */
-  if (! (random() % 200))
+  else if (event->xany.type == MotionNotify &&
+           mp->button_down_p)
     {
-      if (*dv == 0)
-       *dv = 0.00001;
-      else if (random() & 1)
-       *dv *= 1.2;
-      else
-       *dv *= 0.8;
+      gltrackball_track (mp->trackball,
+                         event->xmotion.x, event->xmotion.y,
+                         MI_WIDTH (mi), MI_HEIGHT (mi));
+      return True;
     }
-}
 
-void
-release_moebius(ModeInfo * mi)
-{
-       if (moebius != NULL) {
-               (void) free((void *) moebius);
-               moebius = (moebiusstruct *) NULL;
-       }
-       FreeAllGL(mi);
+  return False;
 }
 
+
 void
 init_moebius(ModeInfo * mi)
 {
@@ -727,24 +684,11 @@ init_moebius(ModeInfo * mi)
        mp->step = NRAND(90);
        mp->ant_position = NRAND(90);
 
-    mp->rotx = FLOATRAND(1.0) * RANDSIGN();
-    mp->roty = FLOATRAND(1.0) * RANDSIGN();
-    mp->rotz = FLOATRAND(1.0) * RANDSIGN();
-
-    /* bell curve from 0-1.5 degrees, avg 0.75 */
-    mp->dx = (FLOATRAND(1) + FLOATRAND(1) + FLOATRAND(1)) / (360*2);
-    mp->dy = (FLOATRAND(1) + FLOATRAND(1) + FLOATRAND(1)) / (360*2);
-    mp->dz = (FLOATRAND(1) + FLOATRAND(1) + FLOATRAND(1)) / (360*2);
-
-    mp->d_max = mp->dx * 2;
-
-    mp->ddx = 0.00006 + FLOATRAND(0.00003);
-    mp->ddy = 0.00006 + FLOATRAND(0.00003);
-    mp->ddz = 0.00006 + FLOATRAND(0.00003);
-
-    mp->ddx = 0.00001;
-    mp->ddy = 0.00001;
-    mp->ddz = 0.00001;
+    {
+      double rot_speed = 0.3;
+      mp->rot = make_rotator (rot_speed, rot_speed, rot_speed, 1, 0, True);
+      mp->trackball = gltrackball_init ();
+    }
 
        if ((mp->glx_context = init_GL(mi)) != NULL) {
 
@@ -781,6 +725,8 @@ draw_moebius(ModeInfo * mi)
 
        glTranslatef(0.0, 0.0, -10.0);
 
+    gltrackball_rotate (mp->trackball);
+
        if (!MI_IS_ICONIC(mi)) {
                glScalef(Scale4Window * mp->WindH / mp->WindW, Scale4Window, Scale4Window);
        } else {
@@ -788,15 +734,11 @@ draw_moebius(ModeInfo * mi)
        }
 
     {
-      GLfloat x = mp->rotx;
-      GLfloat y = mp->roty;
-      GLfloat z = mp->rotz;
-      if (x < 0) x = 1 - (x + 1);
-      if (y < 0) y = 1 - (y + 1);
-      if (z < 0) z = 1 - (z + 1);
-      glRotatef(x * 360, 1.0, 0.0, 0.0);
-      glRotatef(y * 360, 0.0, 1.0, 0.0);
-      glRotatef(z * 360, 0.0, 0.0, 1.0);
+      double x, y, z;
+      get_rotation (mp->rot, &x, &y, &z, !mp->button_down_p);
+      glRotatef (x * 360, 1.0, 0.0, 0.0);
+      glRotatef (y * 360, 0.0, 1.0, 0.0);
+      glRotatef (z * 360, 0.0, 0.0, 1.0);
     }
 
        /* moebius */
@@ -807,10 +749,6 @@ draw_moebius(ModeInfo * mi)
 
        glPopMatrix();
 
-    rotate(&mp->rotx, &mp->dx, &mp->ddx, mp->d_max, MI_IS_VERBOSE(mi));
-    rotate(&mp->roty, &mp->dy, &mp->ddy, mp->d_max, MI_IS_VERBOSE(mi));
-    rotate(&mp->rotz, &mp->dz, &mp->ddz, mp->d_max, MI_IS_VERBOSE(mi));
-
     if (MI_IS_FPS(mi)) do_fps (mi);
        glFlush();