http://ftp.x.org/contrib/applications/xscreensaver-2.34.tar.gz
[xscreensaver] / hacks / glx / rubik.c
index 104fbe0040e4e06c17f0c00199a9e160540c8c26..69ea19583722f90573ae7d2b1dfc6ed2d1d1295e 100644 (file)
@@ -22,7 +22,7 @@ static const char sccsid[] = "@(#)rubik.c     4.07 97/11/24 xlockmore";
  * event will the author be liable for any lost revenue or profits or
  * other special, indirect and consequential damages.
  *
- * This mode shows a auto-solving rubik's cube "puzzle". If somebody
+ * This mode shows an auto-solving rubik's cube "puzzle". If somebody
  * intends to make a game or something based on this code, please let me
  * know first, my e-mail address is provided in this comment. Marcelo.
  *
@@ -40,6 +40,9 @@ static const char sccsid[] = "@(#)rubik.c     4.07 97/11/24 xlockmore";
  * Marcelo F. Vianna (Jul-31-1997)
  *
  * Revision History:
+ * 26-Sep-98: Added some more movement (the cube do not stays in the screen
+ *            center anymore. Also fixed the scale problem imediatelly after
+ *            shuffling when the puzzle is solved.
  * 08-Aug-97: Now has some internals from xrubik by David Bagley
  *            This should make it easier to add features.
  * 02-Aug-97: Now behaves more like puzzle.c: first show the cube being
@@ -133,6 +136,7 @@ static const char sccsid[] = "@(#)rubik.c   4.07 97/11/24 xlockmore";
 # include "xlockmore.h"                                /* from the xscreensaver distribution */
 #else /* !STANDALONE */
 # include "xlock.h"                                    /* from the xlockmore distribution */
+# include "vis.h"
 #endif /* !STANDALONE */
 
 #ifdef USE_GL
@@ -164,7 +168,7 @@ ModeSpecOpt rubik_opts =
 ModStruct   rubik_description =
 {"rubik", "init_rubik", "draw_rubik", "release_rubik",
  "draw_rubik", "change_rubik", NULL, &rubik_opts,
- 1000, -30, 5, -6, 4, 1.0, "",
+ 10000, -30, 5, -6, 4, 1.0, "",
  "Shows an auto-solving Rubik's Cube", 0, NULL};
 
 #endif
@@ -381,6 +385,7 @@ typedef struct {
        RubikLoc   *rowLoc[MAXORIENT];
        RubikMove   movement;
        GLfloat     rotatestep;
+       GLfloat     PX, PY, VX, VY;
        GLXContext *glx_context;
        int         AreObjectsDefined[1];
 } rubikstruct;
@@ -1608,6 +1613,12 @@ shuffle(ModeInfo * mi)
                        evalmovement(mi, move);
                rp->moves[i] = move;
        }
+       rp->VX = 0.05;
+       if (NRAND(100) < 50)
+               rp->VX *= -1;
+       rp->VY = 0.05;
+       if (NRAND(100) < 50)
+               rp->VY *= -1;
        rp->movement.face = NO_FACE;
        rp->rotatestep = 0;
        rp->action = hideshuffling ? ACTION_SOLVE : ACTION_SHUFFLE;
@@ -1672,6 +1683,9 @@ init_rubik(ModeInfo * mi)
        rp = &rubik[screen];
        rp->step = NRAND(90);
 
+       rp->PX = ((float) LRAND() / (float) RAND_MAX) * 2 - 1;
+       rp->PY = ((float) LRAND() / (float) RAND_MAX) * 2 - 1;
+
        if ((rp->glx_context = init_GL(mi)) != NULL) {
 
                reshape(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
@@ -1685,10 +1699,14 @@ init_rubik(ModeInfo * mi)
 void
 draw_rubik(ModeInfo * mi)
 {
+       int         bounced = 0;
+
        rubikstruct *rp = &rubik[MI_SCREEN(mi)];
        Display    *display = MI_DISPLAY(mi);
        Window      window = MI_WINDOW(mi);
 
+       MI_IS_DRAWN(mi) = True;
+
        if (!rp->glx_context)
                return;
 
@@ -1701,7 +1719,43 @@ draw_rubik(ModeInfo * mi)
 
        glTranslatef(0.0, 0.0, -10.0);
 
+       rp->PX += rp->VX;
+       rp->PY += rp->VY;
+
+       if (rp->PY < -1) {
+               rp->PY += (-1) - (rp->PY);
+               rp->VY = -rp->VY;
+               bounced = 1;
+       }
+       if (rp->PY > 1) {
+               rp->PY -= (rp->PY) - 1;
+               rp->VY = -rp->VY;
+               bounced = 1;
+       }
+       if (rp->PX < -1) {
+               rp->PX += (-1) - (rp->PX);
+               rp->VX = -rp->VX;
+               bounced = 1;
+       }
+       if (rp->PX > 1) {
+               rp->PX -= (rp->PX) - 1;
+               rp->VX = -rp->VX;
+               bounced = 1;
+       }
+       if (bounced) {
+               rp->VX += ((float) LRAND() / (float) RAND_MAX) * 0.02 - 0.01;
+               rp->VX += ((float) LRAND() / (float) RAND_MAX) * 0.02 - 0.01;
+               if (rp->VX > 0.06)
+                       rp->VX = 0.06;
+               if (rp->VY > 0.06)
+                       rp->VY = 0.06;
+               if (rp->VX < -0.06)
+                       rp->VX = -0.06;
+               if (rp->VY < -0.06)
+                       rp->VY = -0.06;
+       }
        if (!MI_IS_ICONIC(mi)) {
+               glTranslatef(rp->PX, rp->PY, 0);
                glScalef(Scale4Window * rp->WindH / rp->WindW, Scale4Window, Scale4Window);
        } else {
                glScalef(Scale4Iconic * rp->WindH / rp->WindW, Scale4Iconic, Scale4Iconic);
@@ -1711,6 +1765,9 @@ draw_rubik(ModeInfo * mi)
        glRotatef(rp->step * 95, 0, 1, 0);
        glRotatef(rp->step * 90, 0, 0, 1);
 
+       draw_cube(mi);
+       glXSwapBuffers(display, window);
+
        if (rp->action == ACTION_SHUFFLE) {
                if (rp->done) {
                        if (++rp->rotatestep > DELAY_AFTER_SHUFFLING) {
@@ -1763,14 +1820,10 @@ draw_rubik(ModeInfo * mi)
                }
        }
 
-       draw_cube(mi);
-
        glPopMatrix();
 
        glFlush();
 
-       glXSwapBuffers(display, window);
-
        rp->step += 0.05;
 }