http://www.tienza.es/crux/src/www.jwz.org/xscreensaver/xscreensaver-5.05.tar.gz
[xscreensaver] / hacks / glx / glplanet.c
index 5352a5db53d5dde5148037c0a3239080f2339579..c0e0a573e872afbba7885512c91d7f317d70d6c2 100644 (file)
  */
 
 
-/*-
- * due to a Bug/feature in VMS X11/Intrinsic.h has to be placed before xlock.
- * otherwise caddr_t is not defined correctly
- */
-
-#include <X11/Intrinsic.h>
-
 #ifdef STANDALONE
-# define PROGCLASS                                             "Planet"
-# define HACK_INIT                                             init_planet
-# define HACK_DRAW                                             draw_planet
-# define HACK_RESHAPE                                  reshape_planet
-# define HACK_HANDLE_EVENT                             planet_handle_event
-# define EVENT_MASK                                            PointerMotionMask
-# define planet_opts                                   xlockmore_opts
-#define DEFAULTS       "*delay:                        15000   \n"     \
+#define DEFAULTS       "*delay:                        20000   \n"     \
                                        "*showFPS:                      False   \n" \
-                    "*rotate:           True    \n" \
-                    "*roll:             True    \n" \
-                    "*wander:           True    \n" \
                                        "*wireframe:            False   \n"     \
-                                       "*light:                        True    \n"     \
-                                       "*texture:                      True    \n" \
-                                       "*stars:                        True    \n" \
-                                       "*image:                        BUILTIN \n" \
                                        "*imageForeground:      Green   \n" \
                                        "*imageBackground:      Blue    \n"
-
+# define refresh_planet 0
 # include "xlockmore.h"                                /* from the xscreensaver distribution */
 #else  /* !STANDALONE */
 # include "xlock.h"                                    /* from the xlockmore distribution */
 # endif /* VMS */
 #endif
 
-
-#include <GL/glu.h>
-
 #define DEF_ROTATE  "True"
 #define DEF_ROLL    "True"
 #define DEF_WANDER  "True"
 #define DEF_TEXTURE "True"
 #define DEF_STARS   "True"
 #define DEF_LIGHT   "True"
-#define DEF_RESOLUTION "64"
+#define DEF_RESOLUTION "128"
 #define DEF_IMAGE   "BUILTIN"
 
 #undef countof
@@ -105,34 +81,34 @@ static char *which_image;
 static int resolution;
 
 static XrmOptionDescRec opts[] = {
-  {"-rotate",  ".glplanet.rotate",  XrmoptionNoArg, (caddr_t) "true" },
-  {"+rotate",  ".glplanet.rotate",  XrmoptionNoArg, (caddr_t) "false" },
-  {"-roll",    ".glplanet.roll",    XrmoptionNoArg, (caddr_t) "true" },
-  {"+roll",    ".glplanet.roll",    XrmoptionNoArg, (caddr_t) "false" },
-  {"-wander",  ".glplanet.wander",  XrmoptionNoArg, (caddr_t) "true" },
-  {"+wander",  ".glplanet.wander",  XrmoptionNoArg, (caddr_t) "false" },
-  {"-texture", ".glplanet.texture", XrmoptionNoArg, (caddr_t) "true" },
-  {"+texture", ".glplanet.texture", XrmoptionNoArg, (caddr_t) "false" },
-  {"-stars",   ".glplanet.stars",   XrmoptionNoArg, (caddr_t) "true" },
-  {"+stars",   ".glplanet.stars",   XrmoptionNoArg, (caddr_t) "false" },
-  {"-light",   ".glplanet.light",   XrmoptionNoArg, (caddr_t) "true" },
-  {"+light",   ".glplanet.light",   XrmoptionNoArg, (caddr_t) "false" },
-  {"-image",   ".glplanet.image",  XrmoptionSepArg, (caddr_t) 0 },
-  {"-resolution", ".glplanet.resolution", XrmoptionSepArg, (caddr_t) 0 },
+  {"-rotate",  ".glplanet.rotate",  XrmoptionNoArg, "true" },
+  {"+rotate",  ".glplanet.rotate",  XrmoptionNoArg, "false" },
+  {"-roll",    ".glplanet.roll",    XrmoptionNoArg, "true" },
+  {"+roll",    ".glplanet.roll",    XrmoptionNoArg, "false" },
+  {"-wander",  ".glplanet.wander",  XrmoptionNoArg, "true" },
+  {"+wander",  ".glplanet.wander",  XrmoptionNoArg, "false" },
+  {"-texture", ".glplanet.texture", XrmoptionNoArg, "true" },
+  {"+texture", ".glplanet.texture", XrmoptionNoArg, "false" },
+  {"-stars",   ".glplanet.stars",   XrmoptionNoArg, "true" },
+  {"+stars",   ".glplanet.stars",   XrmoptionNoArg, "false" },
+  {"-light",   ".glplanet.light",   XrmoptionNoArg, "true" },
+  {"+light",   ".glplanet.light",   XrmoptionNoArg, "false" },
+  {"-image",   ".glplanet.image",  XrmoptionSepArg, 0 },
+  {"-resolution", ".glplanet.resolution", XrmoptionSepArg, 0 },
 };
 
 static argtype vars[] = {
-  {(caddr_t *) &do_rotate,   "rotate",  "Rotate",  DEF_ROTATE,  t_Bool},
-  {(caddr_t *) &do_roll,     "roll",    "Roll",    DEF_ROLL,    t_Bool},
-  {(caddr_t *) &do_wander,   "wander",  "Wander",  DEF_WANDER,  t_Bool},
-  {(caddr_t *) &do_texture,  "texture", "Texture", DEF_TEXTURE, t_Bool},
-  {(caddr_t *) &do_stars,  "stars", "Stars", DEF_STARS, t_Bool},
-  {(caddr_t *) &do_light,    "light",   "Light",   DEF_LIGHT,   t_Bool},
-  {(caddr_t *) &which_image, "image",   "Image",   DEF_IMAGE,   t_String},
-  {(caddr_t *) &resolution,  "resolution","Resolution", DEF_RESOLUTION, t_Int},
+  {&do_rotate,   "rotate",  "Rotate",  DEF_ROTATE,  t_Bool},
+  {&do_roll,     "roll",    "Roll",    DEF_ROLL,    t_Bool},
+  {&do_wander,   "wander",  "Wander",  DEF_WANDER,  t_Bool},
+  {&do_texture,  "texture", "Texture", DEF_TEXTURE, t_Bool},
+  {&do_stars,    "stars",   "Stars",   DEF_STARS,   t_Bool},
+  {&do_light,    "light",   "Light",   DEF_LIGHT,   t_Bool},
+  {&which_image, "image",   "Image",   DEF_IMAGE,   t_String},
+  {&resolution,  "resolution","Resolution", DEF_RESOLUTION, t_Int},
 };
 
-ModeSpecOpt planet_opts = {countof(opts), opts, countof(vars), vars, NULL};
+ENTRYPOINT ModeSpecOpt planet_opts = {countof(opts), opts, countof(vars), vars, NULL};
 
 #ifdef USE_MODULES
 ModStruct   planet_description =
@@ -142,7 +118,13 @@ ModStruct   planet_description =
  "Animates texture mapped sphere (planet)", 0, NULL};
 #endif
 
+# ifdef __GNUC__
+  __extension__  /* don't warn about "string length is greater than the length
+                    ISO C89 compilers are required to support" when including
+                    the following XPM file... */
+# endif
 #include "../images/earth.xpm"
+
 #include "xpm-ximage.h"
 #include "rotator.h"
 #include "gltrackball.h"
@@ -167,6 +149,7 @@ ModStruct   planet_description =
 /* structure for holding the planet data */
 typedef struct {
   GLuint platelist;
+  GLuint latlonglist;
   GLuint starlist;
   int screen_width, screen_height;
   GLXContext *glx_context;
@@ -183,25 +166,6 @@ typedef struct {
 static planetstruct *planets = NULL;
 
 
-static inline void
-normalize(GLfloat v[3])
-{
-  GLfloat d = (GLfloat) sqrt((double) (v[0] * v[0] +
-                                       v[1] * v[1] +
-                                       v[2] * v[2]));
-  if (d != 0)
-    {
-      v[0] /= d;
-      v[1] /= d;
-      v[2] /= d;
-       }
-  else
-    {
-      v[0] = v[1] = v[2] = 0;
-       }
-}
-
-
 /* Set up and enable texturing on our object */
 static void
 setup_xpm_texture (ModeInfo *mi, char **xpm_data)
@@ -212,7 +176,10 @@ setup_xpm_texture (ModeInfo *mi, char **xpm_data)
   clear_gl_error();
   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
                image->width, image->height, 0,
-               GL_RGBA, GL_UNSIGNED_BYTE, image->data);
+               GL_RGBA,
+               /* GL_UNSIGNED_BYTE, */
+               GL_UNSIGNED_INT_8_8_8_8_REV,
+               image->data);
   sprintf (buf, "builtin texture (%dx%d)", image->width, image->height);
   check_gl_error(buf);
 
@@ -239,7 +206,10 @@ setup_file_texture (ModeInfo *mi, char *filename)
   clear_gl_error();
   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
                image->width, image->height, 0,
-               GL_RGBA, GL_UNSIGNED_BYTE, image->data);
+               GL_RGBA,
+               /* GL_UNSIGNED_BYTE, */
+               GL_UNSIGNED_INT_8_8_8_8_REV,
+               image->data);
   sprintf (buf, "texture: %.100s (%dx%d)",
            filename, image->width, image->height);
   check_gl_error(buf);
@@ -279,7 +249,7 @@ setup_texture(ModeInfo * mi)
 }
 
 
-void
+static void
 init_stars (ModeInfo *mi)
 {
   int i, j;
@@ -320,7 +290,7 @@ init_stars (ModeInfo *mi)
 }
 
 
-void
+static void
 draw_stars (ModeInfo * mi)
 {
   int width  = MI_WIDTH(mi);
@@ -438,32 +408,7 @@ init_sun (ModeInfo * mi)
 
 #define RANDSIGN() ((random() & 1) ? 1 : -1)
 
-static void
-pick_velocity (ModeInfo * mi)
-{
-#if 0
-  planetstruct *gp = &planets[MI_SCREEN(mi)];
-
-  gp->box_width =  15.0;
-  gp->box_height = 15.0;
-  gp->box_depth =  5.0;
-
-  gp->tx = 0.0;
-  gp->ty = 0.0;
-  gp->tz = frand(360);
-
-  gp->dtx = (frand(0.4) + frand(0.3)) * RANDSIGN();
-  gp->dty = (frand(0.4) + frand(0.3)) * RANDSIGN();
-  gp->dtz = (frand(5.0) + frand(5.0));  /* the sun sets in the west */
-
-  gp->dx = (frand(0.2) + frand(0.2)) * RANDSIGN();
-  gp->dy = (frand(0.2) + frand(0.2)) * RANDSIGN();
-  gp->dz = (frand(0.2) + frand(0.2)) * RANDSIGN();
-#endif
-}
-
-
-void
+ENTRYPOINT void
 reshape_planet (ModeInfo *mi, int width, int height)
 {
   GLfloat h = (GLfloat) height / (GLfloat) width;
@@ -480,13 +425,13 @@ reshape_planet (ModeInfo *mi, int width, int height)
 }
 
 
-Bool
+ENTRYPOINT Bool
 planet_handle_event (ModeInfo *mi, XEvent *event)
 {
   planetstruct *gp = &planets[MI_SCREEN(mi)];
 
   if (event->xany.type == ButtonPress &&
-      event->xbutton.button & Button1)
+      event->xbutton.button == Button1)
     {
       gp->button_down_p = True;
       gltrackball_start (gp->trackball,
@@ -495,11 +440,21 @@ planet_handle_event (ModeInfo *mi, XEvent *event)
       return True;
     }
   else if (event->xany.type == ButtonRelease &&
-           event->xbutton.button & Button1)
+           event->xbutton.button == Button1)
     {
       gp->button_down_p = False;
       return True;
     }
+  else if (event->xany.type == ButtonPress &&
+           (event->xbutton.button == Button4 ||
+            event->xbutton.button == Button5 ||
+            event->xbutton.button == Button6 ||
+            event->xbutton.button == Button7))
+    {
+      gltrackball_mousewheel (gp->trackball, event->xbutton.button, 10,
+                              !!event->xbutton.state);
+      return True;
+    }
   else if (event->xany.type == MotionNotify &&
            gp->button_down_p)
     {
@@ -513,7 +468,7 @@ planet_handle_event (ModeInfo *mi, XEvent *event)
 }
 
 
-void
+ENTRYPOINT void
 init_planet (ModeInfo * mi)
 {
   planetstruct *gp;
@@ -527,15 +482,13 @@ init_planet (ModeInfo * mi)
   }
   gp = &planets[screen];
 
-  pick_velocity (mi);
-
   if ((gp->glx_context = init_GL(mi)) != NULL) {
        reshape_planet(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
   }
 
   {
-       char *f = get_string_resource("imageForeground", "Foreground");
-       char *b = get_string_resource("imageBackground", "Background");
+       char *f = get_string_resource(mi->dpy, "imageForeground", "Foreground");
+       char *b = get_string_resource(mi->dpy, "imageBackground", "Background");
        char *s;
        if (!f) f = strdup("white");
        if (!b) b = strdup("black");
@@ -563,8 +516,8 @@ init_planet (ModeInfo * mi)
   }
 
   {
-    double spin_speed   = 1.0;
-    double wander_speed = 0.05;
+    double spin_speed   = 0.5;
+    double wander_speed = 0.02;
     gp->rot = make_rotator (do_roll ? spin_speed : 0,
                             do_roll ? spin_speed : 0,
                             0, 1,
@@ -594,6 +547,8 @@ init_planet (ModeInfo * mi)
   glEnable(GL_CULL_FACE);
   glCullFace(GL_BACK); 
 
+  /* construct the polygons of the planet
+   */
   gp->platelist = glGenLists(1);
   glNewList (gp->platelist, GL_COMPILE);
   glColor3f (1,1,1);
@@ -602,20 +557,32 @@ init_planet (ModeInfo * mi)
   glRotatef (90, 1, 0, 0);
   unit_sphere (resolution, resolution, wire);
   mi->polygon_count += resolution*resolution;
-#if 0
-  if (!wire)
-    {
-      glDisable(GL_LIGHTING);
-      glScalef(1.01,1.01,1.01);
-      unit_sphere (12, 24, 1);
-      glEnable(GL_LIGHTING);
-    }
-#endif
+  glPopMatrix ();
+  glEndList();
+
+  /* construct the polygons of the latitude/longitude/axis lines.
+   */
+  gp->latlonglist = glGenLists(1);
+  glNewList (gp->latlonglist, GL_COMPILE);
+  glPushMatrix ();
+  if (do_texture) glDisable (GL_TEXTURE_2D);
+  if (do_light)   glDisable (GL_LIGHTING);
+  glColor3f (0.1, 0.3, 0.1);
+  glScalef (RADIUS, RADIUS, RADIUS);
+  glScalef (1.01, 1.01, 1.01);
+  glRotatef (90, 1, 0, 0);
+  unit_sphere (12, 24, 1);
+  glBegin(GL_LINES);
+  glVertex3f(0, -2, 0);
+  glVertex3f(0,  2, 0);
+  glEnd();
+  if (do_light)   glEnable(GL_LIGHTING);
+  if (do_texture) glEnable(GL_TEXTURE_2D);
   glPopMatrix ();
   glEndList();
 }
 
-void
+ENTRYPOINT void
 draw_planet (ModeInfo * mi)
 {
   planetstruct *gp = &planets[MI_SCREEN(mi)];
@@ -657,11 +624,13 @@ draw_planet (ModeInfo * mi)
   glRotatef (gp->z * 360, 0.0, 0.0, 1.0);
   if (do_rotate && !gp->button_down_p)
     {
-      gp->z += 0.01;
-      if (gp->z > 1) gp->z -= 1;
+      gp->z -= 0.005;     /* the sun sets in the west */
+      if (gp->z < 0) gp->z += 1;
     }
 
   glCallList (gp->platelist);
+  if (gp->button_down_p)
+    glCallList (gp->latlonglist);
   glPopMatrix();
 
   if (mi->fps_p) do_fps (mi);
@@ -670,7 +639,7 @@ draw_planet (ModeInfo * mi)
 }
 
 
-void
+ENTRYPOINT void
 release_planet (ModeInfo * mi)
 {
   if (planets != NULL) {
@@ -681,7 +650,8 @@ release_planet (ModeInfo * mi)
 
          if (gp->glx_context) {
                /* Display lists MUST be freed while their glXContext is current. */
-               glXMakeCurrent(MI_DISPLAY(mi), gp->window, *(gp->glx_context));
+        /* but this gets a BadMatch error. -jwz */
+               /*glXMakeCurrent(MI_DISPLAY(mi), gp->window, *(gp->glx_context));*/
 
                if (glIsList(gp->platelist))
                  glDeleteLists(gp->platelist, 1);
@@ -696,5 +666,6 @@ release_planet (ModeInfo * mi)
 }
 
 
-#endif
+XSCREENSAVER_MODULE_2 ("GLPlanet", glplanet, planet)
 
+#endif