1 /* -*- Mode: C; tab-width: 4 -*- */
2 /* rubik --- Shows a self-solving Rubik's cube */
4 #if !defined( lint ) && !defined( SABER )
5 static const char sccsid[] = "@(#)rubik.c 4.04 97/07/28 xlockmore";
12 * Permission to use, copy, modify, and distribute this software and its
13 * documentation for any purpose and without fee is hereby granted,
14 * provided that the above copyright notice appear in all copies and that
15 * both that copyright notice and this permission notice appear in
16 * supporting documentation.
18 * This file is provided AS IS with no warranties of any kind. The author
19 * shall have no liability with respect to the infringement of copyrights,
20 * trade secrets or any patents by this file or any part thereof. In no
21 * event will the author be liable for any lost revenue or profits or
22 * other special, indirect and consequential damages.
24 * This mode shows a self solving rubik's cube "puzzle". If somebody
25 * intends to make a game or something based on this code, please let me
26 * know first, my e-mail address is provided in this comment. Marcelo.
28 * Thanks goes also to Brian Paul for making it possible and inexpensive
29 * to use OpenGL at home.
31 * Since I'm not a native english speaker, my apologies for any gramatical
34 * My e-mail addresses are
37 * marcelo@venus.rdc.puc-rio.br
39 * Marcelo F. Vianna (Jul-31-1997)
42 * 02-Aug-97: Now behaves more like puzzle.c: first show the cube being
43 * shuffled and then being solved. A mode specific option was added:
44 * "+/-hideshuffling" to provide the original behavior (in which
45 * only the solution is shown).
46 * The color labels corners are now rounded.
47 * Optimized the cubit() routine using glLists.
48 * 01-Aug-97: Shuffling now avoids movements that undoes the previous movement
49 * and three consecutive identical moves (which is pretty stupid).
50 * improved the "cycles" option in replacement of David's hack,
51 * now rp->anglestep is a GLfloat, so this option selects the
52 * "exact" number of frames that a rotation (movement) takes to
54 * 30-Jul-97: Initial release, there is no algorithm to solve the puzzle,
55 * instead, it randomly shuffle the cube and then make the
56 * movements in the reverse order.
57 * The mode was written in 1 day (I got sick and had a license
58 * at work...) There was not much to do since I could not exit
64 * Color labels mapping:
65 * =====================
75 * +-----------+------------+-----------+
79 * | LEFT(1) | FRONT(2) | RIGHT(3) |
82 * |00--> |00--> |00--> |
83 * +-----------+------------+-----------+
87 * | BOTTOM(4) | rp->faces[N][X][Y]=
90 * |00--> | +---+---+---+
91 * +------------+ | | |XY |
95 * | BACK(5) | |01 |11 |21 |
98 * |00--> | |00 |10 |20 |
99 * +------------+ +---+---+---+
111 * PURIFY 3.0a on SunOS4 reports an unitialized memory read on each of
112 * the glCallList() functions below when using MesaGL 2.1. This has
113 * been fixed in MesaGL 2.2 and later releases.
117 * due to a Bug/feature in VMS X11/Intrinsic.h has to be placed before xlock.
118 * otherwise caddr_t is not defined correctly
120 #include <X11/Intrinsic.h>
124 # define PROGCLASS "Rubik"
125 # define HACK_INIT init_rubik
126 # define HACK_DRAW draw_rubik
127 # define rubik_opts xlockmore_opts
128 # define DEFAULTS "*delay: 50000 \n" \
131 # include "xlockmore.h" /* from the xscreensaver distribution */
132 #else /* !STANDALONE */
133 # include "xlock.h" /* from the xlockmore distribution */
134 #endif /* !STANDALONE */
138 #define DEF_HIDESHUFFLING "False"
140 static Bool hideshuffling;
142 static XrmOptionDescRec opts[] =
144 {"-hideshuffling", ".rubik.hideshuffling", XrmoptionNoArg, (caddr_t) "on"},
145 {"+hideshuffling", ".rubik.hideshuffling", XrmoptionNoArg, (caddr_t) "off"}
148 static argtype vars[] =
150 {(caddr_t *) & hideshuffling, "hideshuffling", "Hideshuffling", DEF_HIDESHUFFLING, t_Bool}
153 static OptionStruct desc[] =
155 {"-/+hideshuffling", "turn on/off hidden shuffle phase"}
158 ModeSpecOpt rubik_opts =
159 {2, opts, 1, vars, desc};
161 #define Scale4Window 0.3
162 #define Scale4Iconic 0.7
164 #define VectMul(X1,Y1,Z1,X2,Y2,Z2) (Y1)*(Z2)-(Z1)*(Y2),(Z1)*(X2)-(X1)*(Z2),(X1)*(Y2)-(Y1)*(X2)
165 #define sqr(A) ((A)*(A))
171 #define NO_ROTATION -1
172 #define TOP_ROTATION 0
173 #define LEFT_ROTATION 1
174 #define FRONT_ROTATION 2
175 #define RIGHT_ROTATION 3
176 #define BOTTOM_ROTATION 4
177 #define BACK_ROTATION 5
180 #define C_CLOCK_WISE 1
182 #define ACTION_SOLVE 1
183 #define ACTION_SHUFFLE 0
185 #define DELAY_AFTER_SHUFFLING 5
186 #define DELAY_AFTER_SOLVING 20
190 /*************************************************************************/
193 * Ignore trivial case, since it adds needless complications.
194 * MAXSIZE must be 2 or greater.
200 #define MAXSIZE (MAX(MAX(MAXSIZEX,MAXSIZEY),MAXSIZEZ))
201 #define MAXSIZEXY (MAXSIZEX*MAXSIZEY)
202 #define MAXSIZEZY (MAXSIZEZ*MAXSIZEY)
203 #define MAXSIZEXZ (MAXSIZEX*MAXSIZEZ)
204 #define MAXSIZESQ (MAX(MAX(MAXSIZEXY,MAXSIZEZY),MAXSIZEXZ))
205 #define LAST (MAXSIZE-1)
206 #define LASTX (MAXSIZEX-1)
207 #define LASTY (MAXSIZEY-1)
208 #define LASTZ (MAXSIZEZ-1)
220 char faces[6][MAXSIZE][MAXSIZE];
224 GLXContext glx_context;
225 int AreObjectsDefined[1];
228 static float front_shininess[] =
230 static float front_specular[] =
231 {0.7, 0.7, 0.7, 1.0};
232 static float ambient[] =
233 {0.0, 0.0, 0.0, 1.0};
234 static float diffuse[] =
235 {1.0, 1.0, 1.0, 1.0};
236 static float position0[] =
237 {1.0, 1.0, 1.0, 0.0};
238 static float position1[] =
239 {-1.0, -1.0, 1.0, 0.0};
240 static float lmodel_ambient[] =
241 {0.5, 0.5, 0.5, 1.0};
242 static float lmodel_twoside[] =
245 static float MaterialRed[] =
246 {0.5, 0.0, 0.0, 1.0};
247 static float MaterialGreen[] =
248 {0.0, 0.5, 0.0, 1.0};
249 static float MaterialBlue[] =
250 {0.0, 0.0, 0.5, 1.0};
251 static float MaterialYellow[] =
252 {0.7, 0.7, 0.0, 1.0};
253 static float MaterialOrange[] =
254 {1.0, 0.5, 0.4, 1.0};
257 static float MaterialMagenta[] =
258 {0.7, 0.0, 0.7, 1.0};
259 static float MaterialCyan[] =
260 {0.0, 0.7, 0.7, 1.0};
263 static float MaterialWhite[] =
264 {0.8, 0.8, 0.8, 1.0};
265 static float MaterialGray[] =
266 {0.2, 0.2, 0.2, 1.0};
268 static rubikstruct *rubik = NULL;
269 static GLuint objects;
278 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialRed);
281 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialGreen);
284 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialBlue);
287 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialYellow);
291 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialCyan);
294 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialMagenta);
298 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialOrange);
301 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialWhite);
308 draw_cubit(ModeInfo * mi, char BACK, char FRONT, char LEFT, char RIGHT, char BOTTOM, char TOP)
310 rubikstruct *rp = &rubik[MI_SCREEN(mi)];
312 if (!rp->AreObjectsDefined[ObjCubit]) {
313 glNewList(objects + ObjCubit, GL_COMPILE_AND_EXECUTE);
315 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialGray);
316 glNormal3f(0.00, 0.00, 1.00);
317 glVertex3f(-0.45, -0.45, 0.50);
318 glVertex3f(0.45, -0.45, 0.50);
319 glVertex3f(0.45, 0.45, 0.50);
320 glVertex3f(-0.45, 0.45, 0.50);
321 glNormal3f(0.00, 0.00, -1.00);
322 glVertex3f(-0.45, 0.45, -0.50);
323 glVertex3f(0.45, 0.45, -0.50);
324 glVertex3f(0.45, -0.45, -0.50);
325 glVertex3f(-0.45, -0.45, -0.50);
326 glNormal3f(-1.00, 0.00, 0.00);
327 glVertex3f(-0.50, -0.45, 0.45);
328 glVertex3f(-0.50, 0.45, 0.45);
329 glVertex3f(-0.50, 0.45, -0.45);
330 glVertex3f(-0.50, -0.45, -0.45);
331 glNormal3f(1.00, 0.00, 0.00);
332 glVertex3f(0.50, -0.45, -0.45);
333 glVertex3f(0.50, 0.45, -0.45);
334 glVertex3f(0.50, 0.45, 0.45);
335 glVertex3f(0.50, -0.45, 0.45);
336 glNormal3f(0.00, -1.00, 0.00);
337 glVertex3f(0.45, -0.50, -0.45);
338 glVertex3f(0.45, -0.50, 0.45);
339 glVertex3f(-0.45, -0.50, 0.45);
340 glVertex3f(-0.45, -0.50, -0.45);
341 glNormal3f(0.00, 1.00, 0.00);
342 glVertex3f(-0.45, 0.50, -0.45);
343 glVertex3f(-0.45, 0.50, 0.45);
344 glVertex3f(0.45, 0.50, 0.45);
345 glVertex3f(0.45, 0.50, -0.45);
346 glNormal3f(-1.00, -1.00, 0.00);
347 glVertex3f(-0.45, -0.50, -0.45);
348 glVertex3f(-0.45, -0.50, 0.45);
349 glVertex3f(-0.50, -0.45, 0.45);
350 glVertex3f(-0.50, -0.45, -0.45);
351 glNormal3f(1.00, 1.00, 0.00);
352 glVertex3f(0.45, 0.50, -0.45);
353 glVertex3f(0.45, 0.50, 0.45);
354 glVertex3f(0.50, 0.45, 0.45);
355 glVertex3f(0.50, 0.45, -0.45);
356 glNormal3f(-1.00, 1.00, 0.00);
357 glVertex3f(-0.50, 0.45, -0.45);
358 glVertex3f(-0.50, 0.45, 0.45);
359 glVertex3f(-0.45, 0.50, 0.45);
360 glVertex3f(-0.45, 0.50, -0.45);
361 glNormal3f(1.00, -1.00, 0.00);
362 glVertex3f(0.50, -0.45, -0.45);
363 glVertex3f(0.50, -0.45, 0.45);
364 glVertex3f(0.45, -0.50, 0.45);
365 glVertex3f(0.45, -0.50, -0.45);
366 glNormal3f(0.00, -1.00, -1.00);
367 glVertex3f(-0.45, -0.45, -0.50);
368 glVertex3f(0.45, -0.45, -0.50);
369 glVertex3f(0.45, -0.50, -0.45);
370 glVertex3f(-0.45, -0.50, -0.45);
371 glNormal3f(0.00, 1.00, 1.00);
372 glVertex3f(-0.45, 0.45, 0.50);
373 glVertex3f(0.45, 0.45, 0.50);
374 glVertex3f(0.45, 0.50, 0.45);
375 glVertex3f(-0.45, 0.50, 0.45);
376 glNormal3f(0.00, -1.00, 1.00);
377 glVertex3f(-0.45, -0.50, 0.45);
378 glVertex3f(0.45, -0.50, 0.45);
379 glVertex3f(0.45, -0.45, 0.50);
380 glVertex3f(-0.45, -0.45, 0.50);
381 glNormal3f(0.00, 1.00, -1.00);
382 glVertex3f(-0.45, 0.50, -0.45);
383 glVertex3f(0.45, 0.50, -0.45);
384 glVertex3f(0.45, 0.45, -0.50);
385 glVertex3f(-0.45, 0.45, -0.50);
386 glNormal3f(-1.00, 0.00, -1.00);
387 glVertex3f(-0.50, -0.45, -0.45);
388 glVertex3f(-0.50, 0.45, -0.45);
389 glVertex3f(-0.45, 0.45, -0.50);
390 glVertex3f(-0.45, -0.45, -0.50);
391 glNormal3f(1.00, 0.00, 1.00);
392 glVertex3f(0.50, -0.45, 0.45);
393 glVertex3f(0.50, 0.45, 0.45);
394 glVertex3f(0.45, 0.45, 0.50);
395 glVertex3f(0.45, -0.45, 0.50);
396 glNormal3f(1.00, 0.00, -1.00);
397 glVertex3f(0.45, -0.45, -0.50);
398 glVertex3f(0.45, 0.45, -0.50);
399 glVertex3f(0.50, 0.45, -0.45);
400 glVertex3f(0.50, -0.45, -0.45);
401 glNormal3f(-1.00, 0.00, 1.00);
402 glVertex3f(-0.45, -0.45, 0.50);
403 glVertex3f(-0.45, 0.45, 0.50);
404 glVertex3f(-0.50, 0.45, 0.45);
405 glVertex3f(-0.50, -0.45, 0.45);
407 glBegin(GL_TRIANGLES);
408 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialGray);
409 glNormal3f(1.00, 1.00, 1.00);
410 glVertex3f(0.45, 0.45, 0.50);
411 glVertex3f(0.50, 0.45, 0.45);
412 glVertex3f(0.45, 0.50, 0.45);
413 glNormal3f(-1.00, -1.00, -1.00);
414 glVertex3f(-0.45, -0.50, -0.45);
415 glVertex3f(-0.50, -0.45, -0.45);
416 glVertex3f(-0.45, -0.45, -0.50);
417 glNormal3f(-1.00, 1.00, 1.00);
418 glVertex3f(-0.45, 0.45, 0.50);
419 glVertex3f(-0.45, 0.50, 0.45);
420 glVertex3f(-0.50, 0.45, 0.45);
421 glNormal3f(1.00, -1.00, -1.00);
422 glVertex3f(0.50, -0.45, -0.45);
423 glVertex3f(0.45, -0.50, -0.45);
424 glVertex3f(0.45, -0.45, -0.50);
425 glNormal3f(1.00, -1.00, 1.00);
426 glVertex3f(0.45, -0.45, 0.50);
427 glVertex3f(0.45, -0.50, 0.45);
428 glVertex3f(0.50, -0.45, 0.45);
429 glNormal3f(-1.00, 1.00, -1.00);
430 glVertex3f(-0.50, 0.45, -0.45);
431 glVertex3f(-0.45, 0.50, -0.45);
432 glVertex3f(-0.45, 0.45, -0.50);
433 glNormal3f(-1.00, -1.00, 1.00);
434 glVertex3f(-0.45, -0.45, 0.50);
435 glVertex3f(-0.50, -0.45, 0.45);
436 glVertex3f(-0.45, -0.50, 0.45);
437 glNormal3f(1.00, 1.00, -1.00);
438 glVertex3f(0.50, 0.45, -0.45);
439 glVertex3f(0.45, 0.45, -0.50);
440 glVertex3f(0.45, 0.50, -0.45);
443 rp->AreObjectsDefined[ObjCubit] = 1;
445 (void) printf("Cubit drawn SLOWLY\n");
448 glCallList(objects + ObjCubit);
450 (void) printf("Cubit drawn quickly\n");
457 glNormal3f(0.00, 0.00, -1.00);
458 glVertex3f(-0.35, 0.40, -0.51);
459 glVertex3f(0.35, 0.40, -0.51);
460 glVertex3f(0.40, 0.35, -0.51);
461 glVertex3f(0.40, -0.35, -0.51);
462 glVertex3f(0.35, -0.40, -0.51);
463 glVertex3f(-0.35, -0.40, -0.51);
464 glVertex3f(-0.40, -0.35, -0.51);
465 glVertex3f(-0.40, 0.35, -0.51);
471 glNormal3f(0.00, 0.00, 1.00);
472 glVertex3f(-0.35, -0.40, 0.51);
473 glVertex3f(0.35, -0.40, 0.51);
474 glVertex3f(0.40, -0.35, 0.51);
475 glVertex3f(0.40, 0.35, 0.51);
476 glVertex3f(0.35, 0.40, 0.51);
477 glVertex3f(-0.35, 0.40, 0.51);
478 glVertex3f(-0.40, 0.35, 0.51);
479 glVertex3f(-0.40, -0.35, 0.51);
485 glNormal3f(-1.00, 0.00, 0.00);
486 glVertex3f(-0.51, -0.35, 0.40);
487 glVertex3f(-0.51, 0.35, 0.40);
488 glVertex3f(-0.51, 0.40, 0.35);
489 glVertex3f(-0.51, 0.40, -0.35);
490 glVertex3f(-0.51, 0.35, -0.40);
491 glVertex3f(-0.51, -0.35, -0.40);
492 glVertex3f(-0.51, -0.40, -0.35);
493 glVertex3f(-0.51, -0.40, 0.35);
499 glNormal3f(1.00, 0.00, 0.00);
500 glVertex3f(0.51, -0.35, -0.40);
501 glVertex3f(0.51, 0.35, -0.40);
502 glVertex3f(0.51, 0.40, -0.35);
503 glVertex3f(0.51, 0.40, 0.35);
504 glVertex3f(0.51, 0.35, 0.40);
505 glVertex3f(0.51, -0.35, 0.40);
506 glVertex3f(0.51, -0.40, 0.35);
507 glVertex3f(0.51, -0.40, -0.35);
513 glNormal3f(0.00, -1.00, 0.00);
514 glVertex3f(0.40, -0.51, -0.35);
515 glVertex3f(0.40, -0.51, 0.35);
516 glVertex3f(0.35, -0.51, 0.40);
517 glVertex3f(-0.35, -0.51, 0.40);
518 glVertex3f(-0.40, -0.51, 0.35);
519 glVertex3f(-0.40, -0.51, -0.35);
520 glVertex3f(-0.35, -0.51, -0.40);
521 glVertex3f(0.35, -0.51, -0.40);
527 glNormal3f(0.00, 1.00, 0.00);
528 glVertex3f(-0.40, 0.51, -0.35);
529 glVertex3f(-0.40, 0.51, 0.35);
530 glVertex3f(-0.35, 0.51, 0.40);
531 glVertex3f(0.35, 0.51, 0.40);
532 glVertex3f(0.40, 0.51, 0.35);
533 glVertex3f(0.40, 0.51, -0.35);
534 glVertex3f(0.35, 0.51, -0.40);
535 glVertex3f(-0.35, 0.51, -0.40);
542 draw_cube(ModeInfo * mi)
546 rubikstruct *rp = &rubik[MI_SCREEN(mi)];
548 switch (rp->movement) {
553 if (rp->movement == BACK_ROTATION)
554 glRotatef(-rp->rotatestep, 0, 0, 1);
555 glTranslatef(-S1, -S1, -S1);
556 draw_cubit(mi, F_[BACK_ROTATION][0][LAST], ' ',
557 F_[LEFT_ROTATION][0][0], ' ',
558 F_[BOTTOM_ROTATION][0][0], ' ');
559 glTranslatef(S1, 0, 0);
560 draw_cubit(mi, F_[BACK_ROTATION][1][LAST], ' ',
562 F_[BOTTOM_ROTATION][1][0], ' ');
563 glTranslatef(S1, 0, 0);
564 draw_cubit(mi, F_[BACK_ROTATION][LAST][LAST], ' ',
565 ' ', F_[RIGHT_ROTATION][LAST][0],
566 F_[BOTTOM_ROTATION][LAST][0], ' ');
567 glTranslatef(-S2, S1, 0);
568 draw_cubit(mi, F_[BACK_ROTATION][0][1], ' ',
569 F_[LEFT_ROTATION][0][1], ' ',
571 glTranslatef(S1, 0, 0);
572 draw_cubit(mi, F_[BACK_ROTATION][1][1], ' ',
575 glTranslatef(S1, 0, 0);
576 draw_cubit(mi, F_[BACK_ROTATION][LAST][1], ' ',
577 ' ', F_[RIGHT_ROTATION][LAST][1],
579 glTranslatef(-S2, S1, 0);
580 draw_cubit(mi, F_[BACK_ROTATION][0][0], ' ',
581 F_[LEFT_ROTATION][0][LAST], ' ',
582 ' ', F_[TOP_ROTATION][0][LAST]);
583 glTranslatef(S1, 0, 0);
584 draw_cubit(mi, F_[BACK_ROTATION][1][0], ' ',
586 ' ', F_[TOP_ROTATION][1][LAST]);
587 glTranslatef(S1, 0, 0);
588 draw_cubit(mi, F_[BACK_ROTATION][LAST][0], ' ',
589 ' ', F_[RIGHT_ROTATION][LAST][LAST],
590 ' ', F_[TOP_ROTATION][LAST][LAST]);
593 glTranslatef(-S1, -S1, 0);
594 draw_cubit(mi, ' ', ' ',
595 F_[LEFT_ROTATION][1][0], ' ',
596 F_[BOTTOM_ROTATION][0][1], ' ');
597 glTranslatef(S1, 0, 0);
598 draw_cubit(mi, ' ', ' ',
600 F_[BOTTOM_ROTATION][1][1], ' ');
601 glTranslatef(S1, 0, 0);
602 draw_cubit(mi, ' ', ' ',
603 ' ', F_[RIGHT_ROTATION][1][0],
604 F_[BOTTOM_ROTATION][LAST][1], ' ');
605 glTranslatef(-S2, S1, 0);
606 draw_cubit(mi, ' ', ' ',
607 F_[LEFT_ROTATION][1][1], ' ',
609 glTranslatef(2, 0, 0);
610 draw_cubit(mi, ' ', ' ',
611 ' ', F_[RIGHT_ROTATION][1][1],
613 glTranslatef(-S2, S1, 0);
614 draw_cubit(mi, ' ', ' ',
615 F_[LEFT_ROTATION][1][LAST], ' ',
616 ' ', F_[TOP_ROTATION][0][1]);
617 glTranslatef(S1, 0, 0);
618 draw_cubit(mi, ' ', ' ',
620 ' ', F_[TOP_ROTATION][1][1]);
621 glTranslatef(S1, 0, 0);
622 draw_cubit(mi, ' ', ' ',
623 ' ', F_[RIGHT_ROTATION][1][LAST],
624 ' ', F_[TOP_ROTATION][LAST][1]);
626 if (rp->movement == FRONT_ROTATION)
627 glRotatef(rp->rotatestep, 0, 0, 1);
628 glTranslatef(-S1, -S1, S1);
629 draw_cubit(mi, ' ', F_[FRONT_ROTATION][0][0],
630 F_[LEFT_ROTATION][LAST][0], ' ',
631 F_[BOTTOM_ROTATION][0][LAST], ' ');
632 glTranslatef(S1, 0, 0);
633 draw_cubit(mi, ' ', F_[FRONT_ROTATION][1][0],
635 F_[BOTTOM_ROTATION][1][LAST], ' ');
636 glTranslatef(S1, 0, 0);
637 draw_cubit(mi, ' ', F_[FRONT_ROTATION][LASTX][0],
638 ' ', F_[RIGHT_ROTATION][0][0],
639 F_[BOTTOM_ROTATION][LAST][LAST], ' ');
640 glTranslatef(-S2, S1, 0);
641 draw_cubit(mi, ' ', F_[FRONT_ROTATION][0][1],
642 F_[LEFT_ROTATION][LAST][1], ' ',
644 glTranslatef(S1, 0, 0);
645 draw_cubit(mi, ' ', F_[FRONT_ROTATION][1][1],
648 glTranslatef(S1, 0, 0);
649 draw_cubit(mi, ' ', F_[FRONT_ROTATION][LASTX][1],
650 ' ', F_[RIGHT_ROTATION][0][1],
652 glTranslatef(-S2, S1, 0);
653 draw_cubit(mi, ' ', F_[FRONT_ROTATION][0][LASTY],
654 F_[LEFT_ROTATION][LAST][LAST], ' ',
655 ' ', F_[TOP_ROTATION][0][0]);
656 glTranslatef(S1, 0, 0);
657 draw_cubit(mi, ' ', F_[FRONT_ROTATION][1][LASTY],
659 ' ', F_[TOP_ROTATION][1][0]);
660 glTranslatef(S1, 0, 0);
661 draw_cubit(mi, ' ', F_[FRONT_ROTATION][LASTX][LASTY],
662 ' ', F_[RIGHT_ROTATION][0][LAST],
663 ' ', F_[TOP_ROTATION][LAST][0]);
668 if (rp->movement == LEFT_ROTATION)
669 glRotatef(-rp->rotatestep, 1, 0, 0);
670 glTranslatef(-S1, -S1, -S1);
671 draw_cubit(mi, F_[BACK_ROTATION][0][LAST], ' ',
672 F_[LEFT_ROTATION][0][0], ' ',
673 F_[BOTTOM_ROTATION][0][0], ' ');
674 glTranslatef(0, S1, 0);
675 draw_cubit(mi, F_[BACK_ROTATION][0][1], ' ',
676 F_[LEFT_ROTATION][0][1], ' ',
678 glTranslatef(0, S1, 0);
679 draw_cubit(mi, F_[BACK_ROTATION][0][0], ' ',
680 F_[LEFT_ROTATION][0][LAST], ' ',
681 ' ', F_[TOP_ROTATION][0][LAST]);
682 glTranslatef(0, -S2, S1);
683 draw_cubit(mi, ' ', ' ',
684 F_[LEFT_ROTATION][1][0], ' ',
685 F_[BOTTOM_ROTATION][0][1], ' ');
686 glTranslatef(0, S1, 0);
687 draw_cubit(mi, ' ', ' ',
688 F_[LEFT_ROTATION][1][1], ' ',
690 glTranslatef(0, S1, 0);
691 draw_cubit(mi, ' ', ' ',
692 F_[LEFT_ROTATION][1][LAST], ' ',
693 ' ', F_[TOP_ROTATION][0][1]);
694 glTranslatef(0, -S2, S1);
695 draw_cubit(mi, ' ', F_[FRONT_ROTATION][0][0],
696 F_[LEFT_ROTATION][LAST][0], ' ',
697 F_[BOTTOM_ROTATION][0][LAST], ' ');
698 glTranslatef(0, S1, 0);
699 draw_cubit(mi, ' ', F_[FRONT_ROTATION][0][1],
700 F_[LEFT_ROTATION][LAST][1], ' ',
702 glTranslatef(0, S1, 0);
703 draw_cubit(mi, ' ', F_[FRONT_ROTATION][0][LASTY],
704 F_[LEFT_ROTATION][LAST][LAST], ' ',
705 ' ', F_[TOP_ROTATION][0][0]);
708 glTranslatef(0, -S1, -S1);
709 draw_cubit(mi, F_[BACK_ROTATION][1][LAST], ' ',
711 F_[BOTTOM_ROTATION][1][0], ' ');
712 glTranslatef(0, S1, 0);
713 draw_cubit(mi, F_[BACK_ROTATION][1][1], ' ',
716 glTranslatef(0, S1, 0);
717 draw_cubit(mi, F_[BACK_ROTATION][1][0], ' ',
719 ' ', F_[TOP_ROTATION][1][LAST]);
720 glTranslatef(0, -S2, S1);
721 draw_cubit(mi, ' ', ' ',
723 F_[BOTTOM_ROTATION][1][1], ' ');
724 glTranslatef(0, S2, 0);
725 draw_cubit(mi, ' ', ' ',
727 ' ', F_[TOP_ROTATION][1][1]);
728 glTranslatef(0, -S2, S1);
729 draw_cubit(mi, ' ', F_[FRONT_ROTATION][1][0],
731 F_[BOTTOM_ROTATION][1][LAST], ' ');
732 glTranslatef(0, S1, 0);
733 draw_cubit(mi, ' ', F_[FRONT_ROTATION][1][1],
736 glTranslatef(0, S1, 0);
737 draw_cubit(mi, ' ', F_[FRONT_ROTATION][1][LASTY],
739 ' ', F_[TOP_ROTATION][1][0]);
741 if (rp->movement == RIGHT_ROTATION)
742 glRotatef(rp->rotatestep, 1, 0, 0);
743 glTranslatef(S1, -S1, -S1);
744 draw_cubit(mi, F_[BACK_ROTATION][LAST][LAST], ' ',
745 ' ', F_[RIGHT_ROTATION][LAST][0],
746 F_[BOTTOM_ROTATION][LAST][0], ' ');
747 glTranslatef(0, S1, 0);
748 draw_cubit(mi, F_[BACK_ROTATION][LAST][1], ' ',
749 ' ', F_[RIGHT_ROTATION][LAST][1],
751 glTranslatef(0, S1, 0);
752 draw_cubit(mi, F_[BACK_ROTATION][LAST][0], ' ',
753 ' ', F_[RIGHT_ROTATION][LAST][LAST],
754 ' ', F_[TOP_ROTATION][LAST][LAST]);
755 glTranslatef(0, -S2, S1);
756 draw_cubit(mi, ' ', ' ',
757 ' ', F_[RIGHT_ROTATION][1][0],
758 F_[BOTTOM_ROTATION][LAST][1], ' ');
759 glTranslatef(0, S1, 0);
760 draw_cubit(mi, ' ', ' ',
761 ' ', F_[RIGHT_ROTATION][1][1],
763 glTranslatef(0, S1, 0);
764 draw_cubit(mi, ' ', ' ',
765 ' ', F_[RIGHT_ROTATION][1][LAST],
766 ' ', F_[TOP_ROTATION][LAST][1]);
767 glTranslatef(0, -S2, S1);
768 draw_cubit(mi, ' ', F_[FRONT_ROTATION][LASTX][0],
769 ' ', F_[RIGHT_ROTATION][0][0],
770 F_[BOTTOM_ROTATION][LAST][LAST], ' ');
771 glTranslatef(0, S1, 0);
772 draw_cubit(mi, ' ', F_[FRONT_ROTATION][LASTX][1],
773 ' ', F_[RIGHT_ROTATION][0][1],
775 glTranslatef(0, S1, 0);
776 draw_cubit(mi, ' ', F_[FRONT_ROTATION][LASTX][LASTY],
777 ' ', F_[RIGHT_ROTATION][0][LAST],
778 ' ', F_[TOP_ROTATION][LAST][0]);
780 case BOTTOM_ROTATION:
783 if (rp->movement == BOTTOM_ROTATION)
784 glRotatef(-rp->rotatestep, 0, 1, 0);
785 glTranslatef(-S1, -S1, -S1);
786 draw_cubit(mi, F_[BACK_ROTATION][0][LAST], ' ',
787 F_[LEFT_ROTATION][0][0], ' ',
788 F_[BOTTOM_ROTATION][0][0], ' ');
789 glTranslatef(0, 0, S1);
790 draw_cubit(mi, ' ', ' ',
791 F_[LEFT_ROTATION][1][0], ' ',
792 F_[BOTTOM_ROTATION][0][1], ' ');
793 glTranslatef(0, 0, S1);
794 draw_cubit(mi, ' ', F_[FRONT_ROTATION][0][0],
795 F_[LEFT_ROTATION][LAST][0], ' ',
796 F_[BOTTOM_ROTATION][0][LAST], ' ');
797 glTranslatef(S1, 0, -S2);
798 draw_cubit(mi, F_[BACK_ROTATION][1][LAST], ' ',
800 F_[BOTTOM_ROTATION][1][0], ' ');
801 glTranslatef(0, 0, S1);
802 draw_cubit(mi, ' ', ' ',
804 F_[BOTTOM_ROTATION][1][1], ' ');
805 glTranslatef(0, 0, S1);
806 draw_cubit(mi, ' ', F_[FRONT_ROTATION][1][0],
808 F_[BOTTOM_ROTATION][1][LAST], ' ');
809 glTranslatef(1, 0, -S2);
810 draw_cubit(mi, F_[BACK_ROTATION][LAST][LAST], ' ',
811 ' ', F_[RIGHT_ROTATION][LAST][0],
812 F_[BOTTOM_ROTATION][LAST][0], ' ');
813 glTranslatef(0, 0, S1);
814 draw_cubit(mi, ' ', ' ',
815 ' ', F_[RIGHT_ROTATION][1][0],
816 F_[BOTTOM_ROTATION][LAST][1], ' ');
817 glTranslatef(0, 0, S1);
818 draw_cubit(mi, ' ', F_[FRONT_ROTATION][LASTX][0],
819 ' ', F_[RIGHT_ROTATION][0][0],
820 F_[BOTTOM_ROTATION][LAST][LAST], ' ');
823 glTranslatef(-S1, 0, -S1);
824 draw_cubit(mi, F_[BACK_ROTATION][0][1], ' ',
825 F_[LEFT_ROTATION][0][1], ' ',
827 glTranslatef(0, 0, S1);
828 draw_cubit(mi, ' ', ' ',
829 F_[LEFT_ROTATION][1][1], ' ',
831 glTranslatef(0, 0, S1);
832 draw_cubit(mi, ' ', F_[FRONT_ROTATION][0][1],
833 F_[LEFT_ROTATION][LAST][1], ' ',
835 glTranslatef(1, 0, -S2);
836 draw_cubit(mi, F_[BACK_ROTATION][1][1], ' ',
839 glTranslatef(0, 0, S2);
840 draw_cubit(mi, ' ', F_[FRONT_ROTATION][1][1],
843 glTranslatef(S1, 0, -S2);
844 draw_cubit(mi, F_[BACK_ROTATION][LAST][1], ' ',
845 ' ', F_[RIGHT_ROTATION][LAST][1],
847 glTranslatef(0, 0, S1);
848 draw_cubit(mi, ' ', ' ',
849 ' ', F_[RIGHT_ROTATION][1][1],
851 glTranslatef(0, 0, S1);
852 draw_cubit(mi, ' ', F_[FRONT_ROTATION][LASTX][1],
853 ' ', F_[RIGHT_ROTATION][0][1],
856 if (rp->movement == TOP_ROTATION)
857 glRotatef(rp->rotatestep, 0, 1, 0);
858 glTranslatef(-S1, S1, -S1);
859 draw_cubit(mi, F_[BACK_ROTATION][0][0], ' ',
860 F_[LEFT_ROTATION][0][LAST], ' ',
861 ' ', F_[TOP_ROTATION][0][LAST]);
862 glTranslatef(0, 0, S1);
863 draw_cubit(mi, ' ', ' ',
864 F_[LEFT_ROTATION][1][LAST], ' ',
865 ' ', F_[TOP_ROTATION][0][1]);
866 glTranslatef(0, 0, S1);
867 draw_cubit(mi, ' ', F_[FRONT_ROTATION][0][LASTY],
868 F_[LEFT_ROTATION][LAST][LAST], ' ',
869 ' ', F_[TOP_ROTATION][0][0]);
870 glTranslatef(S1, 0, -S2);
871 draw_cubit(mi, F_[BACK_ROTATION][1][0], ' ',
873 ' ', F_[TOP_ROTATION][1][LAST]);
874 glTranslatef(0, 0, S1);
875 draw_cubit(mi, ' ', ' ',
877 ' ', F_[TOP_ROTATION][1][1]);
878 glTranslatef(0, 0, S1);
879 draw_cubit(mi, ' ', F_[FRONT_ROTATION][1][LASTY],
881 ' ', F_[TOP_ROTATION][1][0]);
882 glTranslatef(S1, 0, -S2);
883 draw_cubit(mi, F_[BACK_ROTATION][LAST][0], ' ',
884 ' ', F_[RIGHT_ROTATION][LAST][LAST],
885 ' ', F_[TOP_ROTATION][LAST][LAST]);
886 glTranslatef(0, 0, S1);
887 draw_cubit(mi, ' ', ' ',
888 ' ', F_[RIGHT_ROTATION][1][LAST],
889 ' ', F_[TOP_ROTATION][LAST][1]);
890 glTranslatef(0, 0, S1);
891 draw_cubit(mi, ' ', F_[FRONT_ROTATION][LASTX][LASTY],
892 ' ', F_[RIGHT_ROTATION][0][LAST],
893 ' ', F_[TOP_ROTATION][LAST][0]);
901 evalmovement(ModeInfo * mi, int face, char orient)
903 rubikstruct *rp = &rubik[MI_SCREEN(mi)];
906 if (face < 0 || face > 5)
909 if (orient == CLOCK_WISE) {
910 T1 = F_[face][0][LAST];
911 T2 = F_[face][1][LAST];
912 F_[face][0][LAST] = F_[face][0][0];
913 F_[face][1][LAST] = F_[face][0][1];
914 F_[face][0][0] = F_[face][LAST][0];
915 F_[face][0][1] = F_[face][1][0];
916 F_[face][1][0] = F_[face][LAST][1];
917 F_[face][LAST][0] = F_[face][LAST][LAST];
918 F_[face][LAST][LAST] = T1; /* F_[face][0][LAST]; */
919 F_[face][LAST][1] = T2; /* F_[face][1][LAST]; */
923 F_[face][0][0] = F_[face][0][LAST];
924 F_[face][0][1] = F_[face][1][LAST];
925 F_[face][0][LAST] = F_[face][LAST][LAST];
926 F_[face][1][LAST] = F_[face][LAST][1];
927 F_[face][LAST][1] = F_[face][1][0];
928 F_[face][LAST][LAST] = F_[face][LAST][0];
929 F_[face][1][0] = T2; /* F_[face][0][1]; */
930 F_[face][LAST][0] = T1; /* F_[face][0][0]; */
935 if (orient == CLOCK_WISE) {
936 T1 = F_[BOTTOM_ROTATION][0][0];
937 T2 = F_[BOTTOM_ROTATION][1][0];
938 T3 = F_[BOTTOM_ROTATION][LAST][0];
939 F_[BOTTOM_ROTATION][0][0] = F_[LEFT_ROTATION][0][LAST];
940 F_[BOTTOM_ROTATION][1][0] = F_[LEFT_ROTATION][0][1];
941 F_[BOTTOM_ROTATION][LAST][0] = F_[LEFT_ROTATION][0][0];
942 F_[LEFT_ROTATION][0][0] = F_[TOP_ROTATION][0][LAST];
943 F_[LEFT_ROTATION][0][1] = F_[TOP_ROTATION][1][LAST];
944 F_[LEFT_ROTATION][0][LAST] = F_[TOP_ROTATION][LAST][LAST];
945 F_[TOP_ROTATION][0][LAST] = F_[RIGHT_ROTATION][LAST][LAST];
946 F_[TOP_ROTATION][1][LAST] = F_[RIGHT_ROTATION][LAST][1];
947 F_[TOP_ROTATION][LAST][LAST] = F_[RIGHT_ROTATION][LAST][0];
948 F_[RIGHT_ROTATION][LAST][0] = T1; /* F_[BOTTOM_ROTATION][0][0]; */
949 F_[RIGHT_ROTATION][LAST][1] = T2; /* F_[BOTTOM_ROTATION][1][0]; */
950 F_[RIGHT_ROTATION][LAST][LAST] = T3; /* F_[BOTTOM_ROTATION][LAST][0]; */
952 T1 = F_[LEFT_ROTATION][0][LAST];
953 T2 = F_[LEFT_ROTATION][0][1];
954 T3 = F_[LEFT_ROTATION][0][0];
955 F_[LEFT_ROTATION][0][LAST] = F_[BOTTOM_ROTATION][0][0];
956 F_[LEFT_ROTATION][0][1] = F_[BOTTOM_ROTATION][1][0];
957 F_[LEFT_ROTATION][0][0] = F_[BOTTOM_ROTATION][LAST][0];
958 F_[BOTTOM_ROTATION][0][0] = F_[RIGHT_ROTATION][LAST][0];
959 F_[BOTTOM_ROTATION][1][0] = F_[RIGHT_ROTATION][LAST][1];
960 F_[BOTTOM_ROTATION][LAST][0] = F_[RIGHT_ROTATION][LAST][LAST];
961 F_[RIGHT_ROTATION][LAST][LAST] = F_[TOP_ROTATION][0][LAST];
962 F_[RIGHT_ROTATION][LAST][1] = F_[TOP_ROTATION][1][LAST];
963 F_[RIGHT_ROTATION][LAST][0] = F_[TOP_ROTATION][LAST][LAST];
964 F_[TOP_ROTATION][0][LAST] = T3; /* F_[LEFT_ROTATION][0][0]; */
965 F_[TOP_ROTATION][1][LAST] = T2; /* F_[LEFT_ROTATION][0][1]; */
966 F_[TOP_ROTATION][LAST][LAST] = T1; /* F_[LEFT_ROTATION][0][LAST]; */
970 if (orient == CLOCK_WISE) {
971 T1 = F_[RIGHT_ROTATION][0][LAST];
972 T2 = F_[RIGHT_ROTATION][0][1];
973 T3 = F_[RIGHT_ROTATION][0][0];
974 F_[RIGHT_ROTATION][0][LAST] = F_[TOP_ROTATION][0][0];
975 F_[RIGHT_ROTATION][0][1] = F_[TOP_ROTATION][1][0];
976 F_[RIGHT_ROTATION][0][0] = F_[TOP_ROTATION][LAST][0];
977 F_[TOP_ROTATION][0][0] = F_[LEFT_ROTATION][LAST][0];
978 F_[TOP_ROTATION][1][0] = F_[LEFT_ROTATION][LAST][1];
979 F_[TOP_ROTATION][LAST][0] = F_[LEFT_ROTATION][LAST][LAST];
980 F_[LEFT_ROTATION][LAST][LAST] = F_[BOTTOM_ROTATION][0][LAST];
981 F_[LEFT_ROTATION][LAST][1] = F_[BOTTOM_ROTATION][1][LAST];
982 F_[LEFT_ROTATION][LAST][0] = F_[BOTTOM_ROTATION][LAST][LAST];
983 F_[BOTTOM_ROTATION][0][LAST] = T3; /* F_[RIGHT_ROTATION][0][0]; */
984 F_[BOTTOM_ROTATION][1][LAST] = T2; /* F_[RIGHT_ROTATION][0][1]; */
985 F_[BOTTOM_ROTATION][LAST][LAST] = T1; /* F_[RIGHT_ROTATION][0][LAST]; */
987 T1 = F_[TOP_ROTATION][0][0];
988 T2 = F_[TOP_ROTATION][1][0];
989 T3 = F_[TOP_ROTATION][LAST][0];
990 F_[TOP_ROTATION][0][0] = F_[RIGHT_ROTATION][0][LAST];
991 F_[TOP_ROTATION][1][0] = F_[RIGHT_ROTATION][0][1];
992 F_[TOP_ROTATION][LAST][0] = F_[RIGHT_ROTATION][0][0];
993 F_[RIGHT_ROTATION][0][0] = F_[BOTTOM_ROTATION][0][LAST];
994 F_[RIGHT_ROTATION][0][1] = F_[BOTTOM_ROTATION][1][LAST];
995 F_[RIGHT_ROTATION][0][LAST] = F_[BOTTOM_ROTATION][LAST][LAST];
996 F_[BOTTOM_ROTATION][0][LAST] = F_[LEFT_ROTATION][LAST][LAST];
997 F_[BOTTOM_ROTATION][1][LAST] = F_[LEFT_ROTATION][LAST][1];
998 F_[BOTTOM_ROTATION][LAST][LAST] = F_[LEFT_ROTATION][LAST][0];
999 F_[LEFT_ROTATION][LAST][0] = T1; /* F_[TOP_ROTATION][0][0]; */
1000 F_[LEFT_ROTATION][LAST][1] = T2; /* F_[TOP_ROTATION][1][0]; */
1001 F_[LEFT_ROTATION][LAST][LAST] = T3; /* F_[TOP_ROTATION][LAST][0]; */
1005 if (orient == CLOCK_WISE) {
1006 T1 = F_[TOP_ROTATION][0][0];
1007 T2 = F_[TOP_ROTATION][0][1];
1008 T3 = F_[TOP_ROTATION][0][LAST];
1009 F_[TOP_ROTATION][0][0] = F_[BACK_ROTATION][0][0];
1010 F_[TOP_ROTATION][0][1] = F_[BACK_ROTATION][0][1];
1011 F_[TOP_ROTATION][0][LAST] = F_[BACK_ROTATION][0][LAST];
1012 F_[BACK_ROTATION][0][0] = F_[BOTTOM_ROTATION][0][0];
1013 F_[BACK_ROTATION][0][1] = F_[BOTTOM_ROTATION][0][1];
1014 F_[BACK_ROTATION][0][LAST] = F_[BOTTOM_ROTATION][0][LAST];
1015 F_[BOTTOM_ROTATION][0][0] = F_[FRONT_ROTATION][0][0];
1016 F_[BOTTOM_ROTATION][0][1] = F_[FRONT_ROTATION][0][1];
1017 F_[BOTTOM_ROTATION][0][LAST] = F_[FRONT_ROTATION][0][LASTY];
1018 F_[FRONT_ROTATION][0][0] = T1; /* F_[TOP_ROTATION][0][0]; */
1019 F_[FRONT_ROTATION][0][1] = T2; /* F_[TOP_ROTATION][0][1]; */
1020 F_[FRONT_ROTATION][0][LASTY] = T3; /* F_[TOP_ROTATION][0][LAST]; */
1022 T1 = F_[BACK_ROTATION][0][0];
1023 T2 = F_[BACK_ROTATION][0][1];
1024 T3 = F_[BACK_ROTATION][0][LAST];
1025 F_[BACK_ROTATION][0][0] = F_[TOP_ROTATION][0][0];
1026 F_[BACK_ROTATION][0][1] = F_[TOP_ROTATION][0][1];
1027 F_[BACK_ROTATION][0][LAST] = F_[TOP_ROTATION][0][LAST];
1028 F_[TOP_ROTATION][0][0] = F_[FRONT_ROTATION][0][0];
1029 F_[TOP_ROTATION][0][1] = F_[FRONT_ROTATION][0][1];
1030 F_[TOP_ROTATION][0][LAST] = F_[FRONT_ROTATION][0][LASTY];
1031 F_[FRONT_ROTATION][0][0] = F_[BOTTOM_ROTATION][0][0];
1032 F_[FRONT_ROTATION][0][1] = F_[BOTTOM_ROTATION][0][1];
1033 F_[FRONT_ROTATION][0][LASTY] = F_[BOTTOM_ROTATION][0][LAST];
1034 F_[BOTTOM_ROTATION][0][0] = T1; /* F_[BACK_ROTATION][0][0]; */
1035 F_[BOTTOM_ROTATION][0][1] = T2; /* F_[BACK_ROTATION][0][1]; */
1036 F_[BOTTOM_ROTATION][0][LAST] = T3; /* F_[BACK_ROTATION][0][LAST]; */
1039 case RIGHT_ROTATION:
1040 if (orient == CLOCK_WISE) {
1041 T1 = F_[TOP_ROTATION][LAST][0];
1042 T2 = F_[TOP_ROTATION][LAST][1];
1043 T3 = F_[TOP_ROTATION][LAST][LAST];
1044 F_[TOP_ROTATION][LAST][0] = F_[FRONT_ROTATION][LASTX][0];
1045 F_[TOP_ROTATION][LAST][1] = F_[FRONT_ROTATION][LASTX][1];
1046 F_[TOP_ROTATION][LAST][LAST] = F_[FRONT_ROTATION][LASTX][LASTY];
1047 F_[FRONT_ROTATION][LASTX][0] = F_[BOTTOM_ROTATION][LAST][0];
1048 F_[FRONT_ROTATION][LASTX][1] = F_[BOTTOM_ROTATION][LAST][1];
1049 F_[FRONT_ROTATION][LASTX][LASTY] = F_[BOTTOM_ROTATION][LAST][LAST];
1050 F_[BOTTOM_ROTATION][LAST][0] = F_[BACK_ROTATION][LAST][0];
1051 F_[BOTTOM_ROTATION][LAST][1] = F_[BACK_ROTATION][LAST][1];
1052 F_[BOTTOM_ROTATION][LAST][LAST] = F_[BACK_ROTATION][LAST][LAST];
1053 F_[BACK_ROTATION][LAST][0] = T1; /* F_[TOP_ROTATION][LAST][0]; */
1054 F_[BACK_ROTATION][LAST][1] = T2; /* F_[TOP_ROTATION][LAST][1]; */
1055 F_[BACK_ROTATION][LAST][LAST] = T3; /* F_[TOP_ROTATION][LAST][LAST]; */
1057 T1 = F_[FRONT_ROTATION][LASTX][0];
1058 T2 = F_[FRONT_ROTATION][LASTX][1];
1059 T3 = F_[FRONT_ROTATION][LASTX][LASTY];
1060 F_[FRONT_ROTATION][LASTX][0] = F_[TOP_ROTATION][LAST][0];
1061 F_[FRONT_ROTATION][LASTX][1] = F_[TOP_ROTATION][LAST][1];
1062 F_[FRONT_ROTATION][LASTX][LASTY] = F_[TOP_ROTATION][LAST][LAST];
1063 F_[TOP_ROTATION][LAST][0] = F_[BACK_ROTATION][LAST][0];
1064 F_[TOP_ROTATION][LAST][1] = F_[BACK_ROTATION][LAST][1];
1065 F_[TOP_ROTATION][LAST][LAST] = F_[BACK_ROTATION][LAST][LAST];
1066 F_[BACK_ROTATION][LAST][0] = F_[BOTTOM_ROTATION][LAST][0];
1067 F_[BACK_ROTATION][LAST][1] = F_[BOTTOM_ROTATION][LAST][1];
1068 F_[BACK_ROTATION][LAST][LAST] = F_[BOTTOM_ROTATION][LAST][LAST];
1069 F_[BOTTOM_ROTATION][LAST][0] = T1; /* F_[FRONT_ROTATION][LASTX][0]; */
1070 F_[BOTTOM_ROTATION][LAST][1] = T2; /* F_[FRONT_ROTATION][LASTX][1]; */
1071 F_[BOTTOM_ROTATION][LAST][LAST] = T3; /* F_[FRONT_ROTATION][LASTX][LASTY]; */
1074 case BOTTOM_ROTATION:
1075 if (orient == CLOCK_WISE) {
1076 T1 = F_[FRONT_ROTATION][0][0];
1077 T2 = F_[FRONT_ROTATION][1][0];
1078 T3 = F_[FRONT_ROTATION][LASTX][0];
1079 F_[FRONT_ROTATION][0][0] = F_[LEFT_ROTATION][0][0];
1080 F_[FRONT_ROTATION][1][0] = F_[LEFT_ROTATION][1][0];
1081 F_[FRONT_ROTATION][LASTX][0] = F_[LEFT_ROTATION][LAST][0];
1082 F_[LEFT_ROTATION][0][0] = F_[BACK_ROTATION][LAST][LAST];
1083 F_[LEFT_ROTATION][1][0] = F_[BACK_ROTATION][1][LAST];
1084 F_[LEFT_ROTATION][LAST][0] = F_[BACK_ROTATION][0][LAST];
1085 F_[BACK_ROTATION][LAST][LAST] = F_[RIGHT_ROTATION][0][0];
1086 F_[BACK_ROTATION][1][LAST] = F_[RIGHT_ROTATION][1][0];
1087 F_[BACK_ROTATION][0][LAST] = F_[RIGHT_ROTATION][LAST][0];
1088 F_[RIGHT_ROTATION][0][0] = T1; /* F_[FRONT_ROTATION][0][0]; */
1089 F_[RIGHT_ROTATION][1][0] = T2; /* F_[FRONT_ROTATION][1][0]; */
1090 F_[RIGHT_ROTATION][LAST][0] = T3; /* F_[FRONT_ROTATION][LASTX][0]; */
1092 T1 = F_[BACK_ROTATION][LAST][LAST];
1093 T2 = F_[BACK_ROTATION][1][LAST];
1094 T3 = F_[BACK_ROTATION][0][LAST];
1095 F_[BACK_ROTATION][LAST][LAST] = F_[LEFT_ROTATION][0][0];
1096 F_[BACK_ROTATION][1][LAST] = F_[LEFT_ROTATION][1][0];
1097 F_[BACK_ROTATION][0][LAST] = F_[LEFT_ROTATION][LAST][0];
1098 F_[LEFT_ROTATION][0][0] = F_[FRONT_ROTATION][0][0];
1099 F_[LEFT_ROTATION][1][0] = F_[FRONT_ROTATION][1][0];
1100 F_[LEFT_ROTATION][LAST][0] = F_[FRONT_ROTATION][LASTX][0];
1101 F_[FRONT_ROTATION][0][0] = F_[RIGHT_ROTATION][0][0];
1102 F_[FRONT_ROTATION][1][0] = F_[RIGHT_ROTATION][1][0];
1103 F_[FRONT_ROTATION][LASTX][0] = F_[RIGHT_ROTATION][LAST][0];
1104 F_[RIGHT_ROTATION][0][0] = T1; /* F_[BACK_ROTATION][LAST][LAST]; */
1105 F_[RIGHT_ROTATION][1][0] = T2; /* F_[BACK_ROTATION][1][LAST]; */
1106 F_[RIGHT_ROTATION][LAST][0] = T3; /* F_[BACK_ROTATION][0][LAST]; */
1110 if (orient == CLOCK_WISE) {
1111 T1 = F_[BACK_ROTATION][0][0];
1112 T2 = F_[BACK_ROTATION][1][0];
1113 T3 = F_[BACK_ROTATION][LAST][0];
1114 F_[BACK_ROTATION][0][0] = F_[LEFT_ROTATION][LAST][LAST];
1115 F_[BACK_ROTATION][1][0] = F_[LEFT_ROTATION][1][LAST];
1116 F_[BACK_ROTATION][LAST][0] = F_[LEFT_ROTATION][0][LAST];
1117 F_[LEFT_ROTATION][LAST][LAST] = F_[FRONT_ROTATION][LASTX][LASTY];
1118 F_[LEFT_ROTATION][1][LAST] = F_[FRONT_ROTATION][1][LASTY];
1119 F_[LEFT_ROTATION][0][LAST] = F_[FRONT_ROTATION][0][LASTY];
1120 F_[FRONT_ROTATION][LASTX][LASTY] = F_[RIGHT_ROTATION][LAST][LAST];
1121 F_[FRONT_ROTATION][1][LASTY] = F_[RIGHT_ROTATION][1][LAST];
1122 F_[FRONT_ROTATION][0][LASTY] = F_[RIGHT_ROTATION][0][LAST];
1123 F_[RIGHT_ROTATION][LAST][LAST] = T1; /* F_[BACK_ROTATION][0][0]; */
1124 F_[RIGHT_ROTATION][1][LAST] = T2; /* F_[BACK_ROTATION][1][0]; */
1125 F_[RIGHT_ROTATION][0][LAST] = T3; /* F_[BACK_ROTATION][LAST][0]; */
1127 T1 = F_[RIGHT_ROTATION][LAST][LAST];
1128 T2 = F_[RIGHT_ROTATION][1][LAST];
1129 T3 = F_[RIGHT_ROTATION][0][LAST];
1130 F_[RIGHT_ROTATION][LAST][LAST] = F_[FRONT_ROTATION][LASTX][LASTY];
1131 F_[RIGHT_ROTATION][1][LAST] = F_[FRONT_ROTATION][1][LASTY];
1132 F_[RIGHT_ROTATION][0][LAST] = F_[FRONT_ROTATION][0][LASTY];
1133 F_[FRONT_ROTATION][LASTX][LASTY] = F_[LEFT_ROTATION][LAST][LAST];
1134 F_[FRONT_ROTATION][1][LASTY] = F_[LEFT_ROTATION][1][LAST];
1135 F_[FRONT_ROTATION][0][LASTY] = F_[LEFT_ROTATION][0][LAST];
1136 F_[LEFT_ROTATION][LAST][LAST] = F_[BACK_ROTATION][0][0];
1137 F_[LEFT_ROTATION][1][LAST] = F_[BACK_ROTATION][1][0];
1138 F_[LEFT_ROTATION][0][LAST] = F_[BACK_ROTATION][LAST][0];
1139 F_[BACK_ROTATION][0][0] = T1; /* F_[RIGHT_ROTATION][LAST][LAST]; */
1140 F_[BACK_ROTATION][1][0] = T2; /* F_[RIGHT_ROTATION][1][LAST]; */
1141 F_[BACK_ROTATION][LAST][0] = T3; /* F_[RIGHT_ROTATION][0][LAST]; */
1148 shuffle(ModeInfo * mi)
1150 rubikstruct *rp = &rubik[MI_SCREEN(mi)];
1153 memset(F_[TOP_ROTATION], 'R', MAXSIZEXZ);
1154 memset(F_[LEFT_ROTATION], 'Y', MAXSIZEZY);
1155 memset(F_[FRONT_ROTATION], 'W', MAXSIZEXY);
1156 memset(F_[RIGHT_ROTATION], 'G', MAXSIZEZY);
1157 memset(F_[BOTTOM_ROTATION], 'O', MAXSIZEXZ);
1158 memset(F_[BACK_ROTATION], 'B', MAXSIZEXY);
1160 rp->storedmoves = MI_BATCHCOUNT(mi);
1161 if (rp->storedmoves < 0) {
1162 if (rp->movedfaces != NULL)
1163 (void) free((void *) rp->movedfaces);
1164 if (rp->movedorient != NULL)
1165 (void) free((void *) rp->movedorient);
1166 rp->movedfaces = NULL;
1167 rp->movedorient = NULL;
1168 rp->storedmoves = NRAND(-rp->storedmoves) + 1;
1170 if ((rp->storedmoves) && (rp->movedfaces == NULL))
1171 if ((rp->movedfaces =
1172 (char *) calloc(rp->storedmoves + 1, sizeof (char))) == NULL)
1173 (void) fprintf(stderr,
1174 "Could not allocate memory for rubik move buffer\n");
1176 if ((rp->storedmoves) && (rp->movedorient == NULL))
1177 if ((rp->movedorient =
1178 (char *) calloc(rp->storedmoves + 1, sizeof (char))) == NULL)
1179 (void) fprintf(stderr,
1180 "Could not allocate memory for rubik orient buffer\n");
1182 if (MI_CYCLES(mi) <= 1) {
1183 rp->anglestep = 90.0;
1185 rp->anglestep = 90.0 / (GLfloat) (MI_CYCLES(mi));
1188 for (i = 0; i < rp->storedmoves; i++) {
1195 if (i > 0) /* avoid immediate undoing moves */
1196 if (mov == rp->movedfaces[i - 1] &&
1197 ori == rp->movedorient[i - 1])
1199 if (i > 1) /* avoid 3 consecutive identical moves */
1200 if (mov == rp->movedfaces[i - 1] &&
1201 ori != rp->movedorient[i - 1] &&
1202 rp->movedfaces[i - 1] == rp->movedfaces[i - 2] &&
1203 rp->movedorient[i - 1] == rp->movedorient[i - 2])
1205 } while (!condition);
1207 evalmovement(mi, mov, ori);
1208 rp->movedfaces[i] = mov;
1209 rp->movedorient[i] = (ori == CLOCK_WISE) ? C_CLOCK_WISE : CLOCK_WISE;
1211 rp->movement = NO_ROTATION;
1213 rp->action = hideshuffling ? ACTION_SOLVE : ACTION_SHUFFLE;
1214 rp->shufflingmoves = 0;
1219 draw_rubik(ModeInfo * mi)
1221 rubikstruct *rp = &rubik[MI_SCREEN(mi)];
1223 Display *display = MI_DISPLAY(mi);
1224 Window window = MI_WINDOW(mi);
1226 glDrawBuffer(GL_BACK);
1227 glXMakeCurrent(display, window, rp->glx_context);
1229 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1233 glTranslatef(0.0, 0.0, -10.0);
1235 if (!MI_WIN_IS_ICONIC(mi)) {
1236 glScalef(Scale4Window * rp->WindH / rp->WindW, Scale4Window, Scale4Window);
1238 glScalef(Scale4Iconic * rp->WindH / rp->WindW, Scale4Iconic, Scale4Iconic);
1241 glRotatef(rp->step * 100, 1, 0, 0);
1242 glRotatef(rp->step * 95, 0, 1, 0);
1243 glRotatef(rp->step * 90, 0, 0, 1);
1245 if (rp->action == ACTION_SHUFFLE) {
1247 if (++rp->rotatestep > DELAY_AFTER_SHUFFLING) {
1248 rp->movement = NO_ROTATION;
1250 rp->action = ACTION_SOLVE;
1254 if (rp->movement == NO_ROTATION) {
1255 if (rp->shufflingmoves < rp->storedmoves) {
1257 rp->movement = rp->movedfaces[rp->shufflingmoves];
1259 (rp->movedorient[rp->shufflingmoves] == CLOCK_WISE) ?
1260 C_CLOCK_WISE : CLOCK_WISE;
1266 rp->rotatestep += (rp->orientation == CLOCK_WISE) ?
1267 -rp->anglestep : rp->anglestep;
1268 if (rp->rotatestep > 90 || rp->rotatestep < -90) {
1269 evalmovement(mi, rp->movement, rp->orientation);
1270 rp->shufflingmoves++;
1271 rp->movement = NO_ROTATION;
1277 if (++rp->rotatestep > DELAY_AFTER_SOLVING)
1280 if (rp->movement == NO_ROTATION) {
1281 if (rp->storedmoves > 0) {
1283 rp->movement = rp->movedfaces[rp->storedmoves - 1];
1284 rp->orientation = rp->movedorient[rp->storedmoves - 1];
1290 rp->rotatestep += (rp->orientation == CLOCK_WISE) ?
1291 -rp->anglestep : rp->anglestep;
1292 if (rp->rotatestep > 90 || rp->rotatestep < -90) {
1293 evalmovement(mi, rp->movement, rp->orientation);
1295 rp->movement = NO_ROTATION;
1307 glXSwapBuffers(display, window);
1313 reshape(ModeInfo * mi, int width, int height)
1315 rubikstruct *rp = &rubik[MI_SCREEN(mi)];
1317 glViewport(0, 0, rp->WindW = (GLint) width, rp->WindH = (GLint) height);
1318 glMatrixMode(GL_PROJECTION);
1320 glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 15.0);
1321 glMatrixMode(GL_MODELVIEW);
1323 rp->AreObjectsDefined[ObjCubit] = 0;
1327 pinit(ModeInfo * mi)
1330 glClearColor(0.0, 0.0, 0.0, 1.0);
1331 glColor3f(1.0, 1.0, 1.0);
1333 glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
1334 glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
1335 glLightfv(GL_LIGHT0, GL_POSITION, position0);
1336 glLightfv(GL_LIGHT1, GL_AMBIENT, ambient);
1337 glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);
1338 glLightfv(GL_LIGHT1, GL_POSITION, position1);
1339 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
1340 glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
1341 glEnable(GL_LIGHTING);
1342 glEnable(GL_LIGHT0);
1343 glEnable(GL_LIGHT1);
1344 glEnable(GL_DEPTH_TEST);
1345 glEnable(GL_NORMALIZE);
1346 glEnable(GL_CULL_FACE);
1348 glShadeModel(GL_FLAT);
1349 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, front_shininess);
1350 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, front_specular);
1356 init_rubik(ModeInfo * mi)
1358 int screen = MI_SCREEN(mi);
1361 if (rubik == NULL) {
1362 if ((rubik = (rubikstruct *) calloc(MI_NUM_SCREENS(mi),
1363 sizeof (rubikstruct))) == NULL)
1366 rp = &rubik[screen];
1367 rp->step = NRAND(90);
1369 rp->glx_context = init_GL(mi);
1371 reshape(mi, MI_WIN_WIDTH(mi), MI_WIN_HEIGHT(mi));
1372 objects = glGenLists(1);
1377 change_rubik(ModeInfo * mi)
1383 release_rubik(ModeInfo * mi)
1385 if (rubik != NULL) {
1388 for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) {
1389 rubikstruct *rp = &rubik[screen];
1391 if (rp->movedfaces != NULL)
1392 (void) free((void *) rp->movedfaces);
1393 if (rp->movedorient != NULL)
1394 (void) free((void *) rp->movedorient);
1396 (void) free((void *) rubik);