1 /* glsnake.c - OpenGL imitation of Rubik's Snake
3 * (c) 2001-2003 Jamie Wilkinson <jaq@spacepants.org>
4 * (c) 2001-2003 Andrew Bennetts <andrew@puzzling.org>
5 * (c) 2001-2003 Peter Aylett <peter@ylett.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 /* HAVE_GLUT defined if we're building a standalone glsnake,
27 * and not defined if we're building as an xscreensaver hack */
46 #ifdef HAVE_GETTIMEOFDAY
47 #ifdef GETTIMEOFDAY_TWO_ARGS
48 # include <sys/time.h>
50 typedef struct timeval snaketime;
51 # define GETSECS(t) ((t).tv_sec)
52 # define GETMSECS(t) ((t).tv_usec/1000)
53 #else /* GETTIMEOFDAY_TWO_ARGS */
54 # include <sys/time.h>
56 typedef struct timeval snaketime;
57 # define GETSECS(t) ((t).tv_sec)
58 # define GETMSECS(t) ((t).tv_usec/1000)
60 #else /* HAVE_GETTIMEOFDAY */
62 # include <sys/timeb.h>
63 typedef struct timeb snaketime;
64 # define GETSECS(t) ((long)(t).time)
65 # define GETMSECS(t) ((t).millitm/1000)
66 #endif /* HAVE_FTIME */
67 #endif /* HAVE_GETTIMEOFDAY */
71 #ifndef M_SQRT1_2 /* Win32 doesn't have this constant */
72 #define M_SQRT1_2 0.70710678118654752440084436210485
78 #define DEF_YANGVEL 0.10
79 #define DEF_ZANGVEL 0.14
80 #define DEF_EXPLODE 0.03
81 #define DEF_ANGVEL 1.0
83 #define DEF_STATICTIME 5000
84 #define DEF_ALTCOLOUR 0
86 #define DEF_INTERACTIVE 0
88 #define DEF_WIREFRAME 0
90 /* xscreensaver options doobies prefer strings */
91 #define DEF_YANGVEL "0.10"
92 #define DEF_ZANGVEL "0.14"
93 #define DEF_EXPLODE "0.03"
94 #define DEF_ANGVEL "1.0"
95 #define DEF_ACCEL "0.1"
96 #define DEF_STATICTIME "5000"
97 #define DEF_ALTCOLOUR "False"
98 #define DEF_TITLES "True"
99 #define DEF_INTERACTIVE "False"
100 #define DEF_ZOOM "25.0"
101 #define DEF_WIREFRAME "False"
104 /* static variables */
106 # include <X11/Intrinsic.h>
108 /* xscreensaver boolean type */
112 static GLfloat explode;
113 static GLfloat accel;
114 static long statictime;
115 static GLfloat yspin = 0;
116 static GLfloat zspin = 0;
117 static GLfloat yangvel;
118 static GLfloat zangvel;
119 static Bool altcolour;
121 static Bool interactive;
122 static Bool wireframe;
124 static GLfloat angvel;
127 /* xscreensaver setup */
128 extern XtAppContext app;
130 #define PROGCLASS "glsnake"
131 #define HACK_INIT glsnake_init
132 #define HACK_DRAW glsnake_display
133 #define HACK_RESHAPE glsnake_reshape
134 #define sws_opts xlockmore_opts
137 /* xscreensaver defaults */
138 #define DEFAULTS "*delay: 30000 \n" \
140 "*showFPS: False \n" \
141 "*labelfont: -*-times-bold-r-normal-*-180-*\n" \
144 #define countof(x) (sizeof((x))/sizeof((*x)))
146 #include "xlockmore.h"
147 #include "glxfonts.h"
149 static XrmOptionDescRec opts[] = {
150 { "-explode", ".explode", XrmoptionSepArg, DEF_EXPLODE },
151 { "-angvel", ".angvel", XrmoptionSepArg, DEF_ANGVEL },
152 { "-accel", ".accel", XrmoptionSepArg, DEF_ACCEL },
153 { "-statictime", ".statictime", XrmoptionSepArg, DEF_STATICTIME },
154 { "-yangvel", ".yangvel", XrmoptionSepArg, DEF_YANGVEL },
155 { "-zangvel", ".zangvel", XrmoptionSepArg, DEF_ZANGVEL },
156 { "-altcolour", ".altcolour", XrmoptionNoArg, "True" },
157 { "-no-altcolour", ".altcolour", XrmoptionNoArg, "False" },
158 { "-titles", ".titles", XrmoptionNoArg, "True" },
159 { "-no-titles", ".titles", XrmoptionNoArg, "False" },
160 { "-zoom", ".zoom", XrmoptionSepArg, DEF_ZOOM },
161 { "-wireframe", ".wireframe", XrmoptionNoArg, "true" },
162 { "-no-wireframe", ".wireframe", XrmoptionNoArg, "false" },
165 static argtype vars[] = {
166 {&explode, "explode", "Explode", DEF_EXPLODE, t_Float},
167 {&angvel, "angvel", "Angular Velocity", DEF_ANGVEL, t_Float},
168 {&accel, "accel", "Acceleration", DEF_ACCEL, t_Float},
169 {&statictime, "statictime", "Static Time", DEF_STATICTIME, t_Int},
170 {&yangvel, "yangvel", "Angular Velocity about Y axis", DEF_YANGVEL, t_Float},
171 {&zangvel, "zangvel", "Angular Velocity about X axis", DEF_ZANGVEL, t_Float},
172 {&interactive, "interactive", "Interactive", DEF_INTERACTIVE, t_Bool},
173 {&altcolour, "altcolour", "Alternate Colour Scheme", DEF_ALTCOLOUR, t_Bool},
174 {&titles, "titles", "Titles", DEF_TITLES, t_Bool},
175 {&zoom, "zoom", "Zoom", DEF_ZOOM, t_Float},
176 {&wireframe, "wireframe", "Wireframe", DEF_WIREFRAME, t_Bool},
179 ModeSpecOpt sws_opts = {countof(opts), opts, countof(vars), vars, NULL};
184 float node[NODE_COUNT];
189 GLXContext * glx_context;
193 /* font list number */
200 /* is a morph in progress? */
203 /* has the model been paused? */
212 /* the shape of the model */
213 float node[NODE_COUNT];
215 /* currently selected node for interactive mode */
230 /* timing variables */
231 snaketime last_iteration;
232 snaketime last_morph;
236 int old_width, old_height;
238 /* the id of the display lists for drawing a node */
239 int node_solid, node_wire;
241 /* is the window fullscreen? */
245 #define COLOUR_CYCLIC 0
246 #define COLOUR_ACYCLIC 1
247 #define COLOUR_INVALID 2
248 #define COLOUR_AUTHENTIC 3
250 float colour[][2][3] = {
260 /* authentic - purple and green */
261 { { 0.38, 0.0, 0.55 },
265 struct model_s model[] = {
266 #define STRAIGHT_MODEL 0
268 { ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO,
269 ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO,
272 /* the models in the Rubik's snake manual */
273 #define START_MODEL 1
275 { RIGHT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT,
276 RIGHT, LEFT, LEFT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT,
277 RIGHT, LEFT, RIGHT, LEFT }
280 { RIGHT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, LEFT, RIGHT,
281 RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, LEFT, RIGHT, RIGHT, RIGHT,
282 RIGHT, LEFT, LEFT, LEFT }
285 { ZERO, ZERO, ZERO, RIGHT, LEFT, RIGHT, ZERO, LEFT, ZERO, ZERO,
286 ZERO, RIGHT, LEFT, RIGHT, ZERO, LEFT, ZERO, ZERO, ZERO, RIGHT,
287 LEFT, RIGHT, ZERO, LEFT }
290 { ZERO, PIN, ZERO, ZERO, ZERO, ZERO, ZERO, PIN, RIGHT, RIGHT, PIN,
291 RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, RIGHT, ZERO, ZERO,
295 { ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN,
296 ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, ZERO, ZERO, ZERO, ZERO,
300 { ZERO, ZERO, PIN, PIN, ZERO, LEFT, ZERO, LEFT, RIGHT, PIN, RIGHT,
301 ZERO, PIN, PIN, ZERO, RIGHT, PIN, RIGHT, LEFT, ZERO, LEFT, ZERO,
304 /* These models were taken from Andrew and Peter's original snake.c
305 * as well as some newer ones made up by Jamie, Andrew and Peter. */
307 { LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT,
308 LEFT, LEFT, LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT,
309 RIGHT, LEFT, LEFT, LEFT }
312 { RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT, RIGHT, RIGHT,
313 LEFT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT,
314 RIGHT, RIGHT, LEFT, LEFT }
317 { PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN,
318 ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN }
321 { PIN, LEFT, PIN, LEFT, PIN, LEFT, PIN, LEFT, PIN, LEFT, PIN,
322 LEFT, PIN, LEFT, PIN, LEFT, PIN, LEFT, PIN, LEFT, PIN, LEFT, PIN }
325 { RIGHT, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT,
326 LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, RIGHT, PIN,
330 { RIGHT, LEFT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT,
331 LEFT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT,
332 RIGHT, RIGHT, LEFT, LEFT }
335 { ZERO, RIGHT, LEFT, ZERO, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT,
336 LEFT, RIGHT, LEFT, LEFT, PIN, LEFT, LEFT, LEFT, RIGHT, LEFT,
337 RIGHT, RIGHT, RIGHT }
340 { RIGHT, PIN, ZERO, ZERO, PIN, LEFT, ZERO, LEFT, LEFT, ZERO,
341 LEFT, PIN, ZERO, ZERO, PIN, RIGHT, PIN, LEFT, PIN, ZERO, ZERO,
345 { PIN, RIGHT, LEFT, RIGHT, RIGHT, LEFT, PIN, LEFT, RIGHT, LEFT,
346 LEFT, RIGHT, PIN, RIGHT, LEFT, RIGHT, RIGHT, LEFT, PIN, LEFT,
350 { ZERO, ZERO, ZERO, ZERO, LEFT, ZERO, ZERO, RIGHT, ZERO, ZERO,
351 ZERO, ZERO, LEFT, ZERO, ZERO, RIGHT, ZERO, ZERO, ZERO, ZERO,
352 LEFT, ZERO, ZERO, RIGHT }
355 { ZERO, ZERO, LEFT, RIGHT, ZERO, LEFT, ZERO, RIGHT, ZERO, ZERO,
356 LEFT, RIGHT, ZERO, LEFT, ZERO, RIGHT, ZERO, ZERO, LEFT, RIGHT,
357 ZERO, LEFT, ZERO, RIGHT }
360 { ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, LEFT, RIGHT, ZERO, ZERO,
361 ZERO, ZERO, ZERO, ZERO, LEFT, RIGHT, ZERO, ZERO, ZERO, ZERO,
362 ZERO, ZERO, LEFT, RIGHT }
365 { ZERO, LEFT, PIN, RIGHT, RIGHT, PIN, ZERO, LEFT, PIN, RIGHT,
366 RIGHT, PIN, ZERO, LEFT, PIN, RIGHT, RIGHT, PIN, ZERO, LEFT, PIN,
370 { ZERO, PIN, PIN, ZERO, PIN, ZERO, PIN, PIN, ZERO, PIN, ZERO, PIN,
371 PIN, ZERO, PIN, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO, ZERO, PIN }
374 { PIN, RIGHT, LEFT, PIN, LEFT, PIN, ZERO, ZERO, RIGHT, PIN, LEFT,
375 ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO,
379 { ZERO, ZERO, ZERO, ZERO, RIGHT, RIGHT, ZERO, LEFT, PIN, RIGHT,
380 ZERO, RIGHT, ZERO, RIGHT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT,
384 { RIGHT, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, PIN, PIN, ZERO,
385 LEFT, ZERO, LEFT, PIN, RIGHT, ZERO, LEFT, LEFT, LEFT, PIN, RIGHT,
389 { ZERO, ZERO, ZERO, ZERO, PIN, PIN, ZERO, PIN, ZERO, ZERO, PIN,
390 ZERO, PIN, PIN, ZERO, ZERO, ZERO, PIN, ZERO, PIN, PIN, ZERO, PIN }
393 { RIGHT, RIGHT, LEFT, LEFT, RIGHT, PIN, RIGHT, PIN, LEFT, PIN,
394 RIGHT, ZERO, LEFT, ZERO, LEFT, PIN, RIGHT, ZERO, LEFT, LEFT,
398 { LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, ZERO, ZERO, ZERO,
399 RIGHT, ZERO, ZERO, LEFT, RIGHT, ZERO, ZERO, ZERO, LEFT, LEFT,
400 RIGHT, LEFT, RIGHT, RIGHT }
403 { LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, ZERO, PIN, ZERO, ZERO,
404 LEFT, PIN, RIGHT, ZERO, ZERO, PIN, ZERO, LEFT, LEFT, RIGHT, LEFT,
408 { ZERO, PIN, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, ZERO, ZERO,
409 RIGHT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT,
413 { LEFT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT,
414 ZERO, ZERO, ZERO, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN,
418 { RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, PIN,
419 LEFT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, LEFT,
423 { RIGHT, PIN, RIGHT, RIGHT, RIGHT, PIN, LEFT, LEFT, LEFT, PIN,
424 LEFT, PIN, RIGHT, PIN, RIGHT, RIGHT, RIGHT, PIN, LEFT, LEFT,
425 LEFT, PIN, LEFT, PIN }
428 { ZERO, PIN, RIGHT, RIGHT, RIGHT, PIN, LEFT, LEFT, LEFT, PIN,
429 ZERO, PIN, ZERO, PIN, RIGHT, RIGHT, RIGHT, PIN, LEFT, LEFT, LEFT,
433 { ZERO, PIN, ZERO, RIGHT, RIGHT, PIN, LEFT, LEFT, ZERO, PIN,
434 ZERO, PIN, ZERO, PIN, ZERO, RIGHT, RIGHT, PIN, LEFT, LEFT, ZERO,
438 { ZERO, PIN, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, PIN,
439 ZERO, PIN, ZERO, PIN, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO,
443 { ZERO, RIGHT, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, LEFT,
444 ZERO, PIN, ZERO, RIGHT, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO,
448 { ZERO, ZERO, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, ZERO,
449 ZERO, PIN, ZERO, ZERO, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO,
453 { ZERO, ZERO, ZERO, RIGHT, RIGHT, PIN, LEFT, LEFT, ZERO, ZERO,
454 ZERO, PIN, ZERO, ZERO, ZERO, RIGHT, RIGHT, PIN, LEFT, LEFT, ZERO,
458 { RIGHT, ZERO, ZERO, RIGHT, RIGHT, PIN, LEFT, LEFT, ZERO, ZERO,
459 LEFT, PIN, RIGHT, ZERO, ZERO, RIGHT, RIGHT, PIN, LEFT, LEFT,
460 ZERO, ZERO, LEFT, PIN }
463 { RIGHT, ZERO, LEFT, RIGHT, RIGHT, PIN, LEFT, LEFT, RIGHT,
464 ZERO, LEFT, PIN, RIGHT, ZERO, LEFT, RIGHT, RIGHT, PIN, LEFT,
465 LEFT, RIGHT, ZERO, LEFT, PIN }
468 { RIGHT, ZERO, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, ZERO,
469 LEFT, PIN, RIGHT, ZERO, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT,
473 { ZERO, ZERO, RIGHT, ZERO, ZERO, PIN, ZERO, ZERO, LEFT, ZERO,
474 ZERO, PIN, ZERO, ZERO, RIGHT, ZERO, ZERO, PIN, ZERO, ZERO, LEFT,
478 { ZERO, ZERO, PIN, PIN, ZERO, RIGHT, PIN, LEFT, PIN, RIGHT, PIN,
479 RIGHT, PIN, LEFT, PIN, RIGHT, ZERO, ZERO, PIN, ZERO, ZERO, LEFT,
483 { LEFT, PIN, LEFT, PIN, ZERO, PIN, PIN, ZERO, PIN, ZERO, LEFT,
484 PIN, RIGHT, ZERO, PIN, ZERO, PIN, PIN, ZERO, ZERO, LEFT, PIN,
488 { RIGHT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, ZERO, ZERO,
489 ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, ZERO, RIGHT, RIGHT, LEFT,
490 RIGHT, LEFT, LEFT, LEFT, PIN }
493 { ZERO, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, ZERO, RIGHT,
494 RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, PIN, ZERO, LEFT, RIGHT,
495 PIN, LEFT, LEFT, LEFT }
498 { PIN, LEFT, RIGHT, LEFT, LEFT, PIN, RIGHT, ZERO, RIGHT, LEFT,
499 ZERO, PIN, LEFT, LEFT, RIGHT, RIGHT, RIGHT, PIN, LEFT, ZERO,
503 { PIN, PIN, ZERO, ZERO, PIN, ZERO, ZERO, RIGHT, ZERO, RIGHT,
504 RIGHT, PIN, RIGHT, RIGHT, ZERO, RIGHT, ZERO, ZERO, PIN, ZERO,
505 ZERO, PIN, PIN, ZERO }
508 /* the following modesl were created during the slug/compsoc codefest
511 { PIN, PIN, ZERO, ZERO, RIGHT, ZERO, ZERO, PIN, PIN, ZERO, LEFT,
512 ZERO, ZERO, PIN, ZERO, PIN, PIN, ZERO, LEFT, RIGHT, PIN, ZERO,
516 { ZERO, ZERO, ZERO, ZERO, PIN, RIGHT, ZERO, PIN, PIN, ZERO, PIN,
517 PIN, ZERO, RIGHT, RIGHT, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO,
521 { RIGHT, RIGHT, PIN, RIGHT, LEFT, RIGHT, PIN, RIGHT, LEFT,
522 RIGHT, PIN, RIGHT, LEFT, RIGHT, PIN, RIGHT, LEFT, RIGHT, PIN,
523 RIGHT, LEFT, RIGHT, PIN, ZERO }
526 { ZERO, ZERO, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO, ZERO, ZERO,
527 ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO,
531 { LEFT, ZERO, RIGHT, LEFT, RIGHT, ZERO, LEFT, RIGHT, LEFT, ZERO,
532 RIGHT, LEFT, RIGHT, ZERO, LEFT, RIGHT, LEFT, ZERO, RIGHT, LEFT,
533 RIGHT, ZERO, LEFT, ZERO }
536 { ZERO, PIN, PIN, ZERO, ZERO, ZERO, PIN, PIN, ZERO, LEFT, ZERO,
537 PIN, PIN, ZERO, RIGHT, LEFT, ZERO, PIN, ZERO, PIN, PIN, ZERO,
541 { ZERO, ZERO, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, ZERO, ZERO,
542 ZERO, PIN, ZERO, ZERO, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, ZERO,
546 { PIN, ZERO, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, ZERO, ZERO,
547 ZERO, PIN, ZERO, ZERO, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, ZERO,
550 { "erect penis", /* thanks benno */
551 { PIN, ZERO, PIN, PIN, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, PIN,
552 PIN, ZERO, ZERO, ZERO, RIGHT, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO,
556 { PIN, ZERO, PIN, PIN, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, PIN,
557 PIN, ZERO, ZERO, ZERO, RIGHT, PIN, ZERO, ZERO, ZERO, ZERO, ZERO,
561 { RIGHT, ZERO, ZERO, ZERO, RIGHT, ZERO, ZERO, PIN, ZERO, ZERO,
562 LEFT, ZERO, ZERO, ZERO, LEFT, ZERO, LEFT, PIN, LEFT, PIN, RIGHT,
566 { ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, PIN, ZERO, ZERO, PIN,
567 ZERO, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, ZERO, PIN, ZERO,
570 { "poles or columns or something",
571 { LEFT, RIGHT, LEFT, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO,
572 ZERO, LEFT, RIGHT, LEFT, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO,
576 { ZERO, LEFT, ZERO, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO,
577 ZERO, LEFT, ZERO, LEFT, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO,
581 { ZERO, LEFT, ZERO, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO, ZERO,
582 LEFT, ZERO, RIGHT, ZERO, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO,
586 { ZERO, ZERO, ZERO, ZERO, ZERO, LEFT, ZERO, ZERO, ZERO, ZERO,
587 LEFT, RIGHT, ZERO, ZERO, ZERO, ZERO, LEFT, RIGHT, ZERO, ZERO,
588 LEFT, PIN, ZERO, ZERO }
591 { ZERO, ZERO, PIN, RIGHT, ZERO, LEFT, ZERO, ZERO, RIGHT, ZERO,
592 LEFT, PIN, ZERO, ZERO, PIN, ZERO, LEFT, ZERO, RIGHT, LEFT, ZERO,
596 { PIN, ZERO, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO,
597 RIGHT, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, ZERO,
601 { PIN, ZERO, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO,
602 ZERO, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, ZERO,
606 { PIN, ZERO, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO,
607 LEFT, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, ZERO,
611 { PIN, ZERO, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO,
612 PIN, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, ZERO,
616 { RIGHT, ZERO, ZERO, LEFT, ZERO, LEFT, RIGHT, ZERO, RIGHT, LEFT,
617 RIGHT, PIN, RIGHT, LEFT, RIGHT, ZERO, RIGHT, LEFT, ZERO, LEFT,
618 ZERO, ZERO, RIGHT, ZERO }
621 { RIGHT, ZERO, RIGHT, ZERO, RIGHT, ZERO, RIGHT, ZERO, RIGHT,
622 ZERO, RIGHT, ZERO, RIGHT, LEFT, RIGHT, PIN, ZERO, RIGHT, ZERO,
623 RIGHT, ZERO, RIGHT, ZERO, ZERO }
626 /* These models come from the website at
627 * http://www.geocities.com/stigeide/snake */
629 { RIGHT, LEFT, RIGHT, ZERO, PIN, ZERO, LEFT, RIGHT, LEFT, PIN, ZERO, ZERO, PIN, LEFT, RIGHT, LEFT, ZERO, PIN, ZERO, RIGHT, LEFT, RIGHT, ZERO }
632 { LEFT, RIGHT, ZERO, RIGHT, LEFT, ZERO, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, PIN, RIGHT, LEFT, PIN }
635 { LEFT, RIGHT, ZERO, RIGHT, LEFT, ZERO, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT }
638 { LEFT, RIGHT, ZERO, RIGHT, LEFT, ZERO, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN }
641 { ZERO, ZERO, PIN, LEFT, RIGHT, LEFT, ZERO, RIGHT, LEFT, RIGHT, ZERO, PIN, ZERO, LEFT, RIGHT, LEFT, ZERO, RIGHT, LEFT, RIGHT, PIN, ZERO, ZERO }
644 { RIGHT, LEFT, RIGHT, PIN, ZERO, ZERO, PIN, RIGHT, LEFT, RIGHT, ZERO, PIN, PIN, ZERO, LEFT, LEFT, RIGHT, RIGHT, LEFT, LEFT, ZERO, PIN, PIN }
647 { ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, ZERO, RIGHT, LEFT }
650 { LEFT, PIN, RIGHT, ZERO, ZERO, PIN, RIGHT, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, PIN, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, LEFT, PIN, ZERO }
653 { LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT }
656 { ZERO, RIGHT, RIGHT, ZERO, RIGHT, RIGHT, ZERO, RIGHT, LEFT, ZERO, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, LEFT, RIGHT, PIN, LEFT, LEFT, ZERO, LEFT }
659 { PIN, LEFT, RIGHT, ZERO, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, ZERO, LEFT, RIGHT, PIN, RIGHT }
662 { PIN, PIN, LEFT, ZERO, PIN, PIN, ZERO, LEFT, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, RIGHT, PIN, PIN }
665 { LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT }
668 { RIGHT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, LEFT, LEFT }
671 { ZERO, PIN, ZERO, PIN, PIN, ZERO, PIN, ZERO, ZERO, PIN, ZERO, PIN, PIN, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, PIN }
674 { PIN, LEFT, ZERO, PIN, PIN, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, PIN, RIGHT, PIN, LEFT, ZERO, ZERO, RIGHT, PIN, LEFT, PIN, ZERO, ZERO }
677 { RIGHT, ZERO, PIN, RIGHT, PIN, RIGHT, ZERO, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, ZERO, RIGHT, PIN, RIGHT, ZERO, ZERO, LEFT }
680 { LEFT, PIN, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, PIN, RIGHT }
683 { ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO }
686 { RIGHT, ZERO, ZERO, PIN, LEFT, ZERO, PIN, PIN, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, LEFT, LEFT, PIN, RIGHT, RIGHT, LEFT, PIN, ZERO, ZERO }
689 { PIN, ZERO, ZERO, PIN, LEFT, LEFT, PIN, RIGHT, RIGHT, PIN, ZERO, ZERO, PIN, ZERO, ZERO, PIN, LEFT, LEFT, PIN, RIGHT, RIGHT, PIN, ZERO }
692 { RIGHT, LEFT, RIGHT, RIGHT, RIGHT, LEFT, RIGHT, ZERO, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, ZERO, LEFT, RIGHT, LEFT, LEFT }
695 { RIGHT, RIGHT, RIGHT, PIN, LEFT, PIN, LEFT, PIN, RIGHT, RIGHT, RIGHT, PIN, LEFT, LEFT, LEFT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, LEFT, LEFT }
698 { RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT }
701 { ZERO, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, LEFT, LEFT, ZERO, LEFT, RIGHT, ZERO, ZERO, PIN, ZERO, ZERO, RIGHT }
704 { LEFT, ZERO, PIN, ZERO, PIN, LEFT, ZERO, PIN, ZERO, LEFT, LEFT, PIN, RIGHT, RIGHT, ZERO, PIN, ZERO, RIGHT, PIN, ZERO, PIN, ZERO, RIGHT }
707 { ZERO, LEFT, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, ZERO, ZERO, LEFT, ZERO, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, LEFT }
710 { ZERO, ZERO, PIN, ZERO, ZERO, LEFT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, PIN, RIGHT, PIN, LEFT, ZERO, PIN, PIN, ZERO, ZERO, LEFT, PIN }
713 { LEFT, PIN, RIGHT, ZERO, ZERO, PIN, PIN, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, RIGHT, ZERO, ZERO, ZERO }
716 { ZERO, PIN, ZERO, PIN, PIN, ZERO, LEFT, PIN, RIGHT, ZERO, PIN, PIN, ZERO, PIN, ZERO, PIN, PIN, ZERO, LEFT, PIN, RIGHT, ZERO, PIN }
719 { PIN, RIGHT, ZERO, ZERO, PIN, ZERO, ZERO, PIN, PIN, ZERO, PIN, RIGHT, PIN, LEFT, PIN, ZERO, PIN, PIN, ZERO, ZERO, PIN, ZERO, ZERO }
722 { LEFT, ZERO, LEFT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, RIGHT, ZERO, RIGHT, PIN, RIGHT, PIN, LEFT }
725 { PIN, ZERO, ZERO, PIN, LEFT, LEFT, PIN, LEFT, RIGHT, RIGHT, PIN, LEFT, LEFT, RIGHT, PIN, RIGHT, RIGHT, PIN, ZERO, ZERO, PIN, RIGHT, PIN }
728 { RIGHT, PIN, ZERO, LEFT, LEFT, PIN, RIGHT, RIGHT, ZERO, PIN, LEFT, PIN, RIGHT, PIN, ZERO, LEFT, LEFT, PIN, RIGHT, RIGHT, ZERO, PIN, LEFT }
731 { ZERO, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, RIGHT, LEFT, PIN, LEFT, ZERO, PIN, PIN, ZERO, LEFT, PIN, LEFT, RIGHT, ZERO, RIGHT, ZERO, PIN }
733 { "Counterclockwise",
734 { LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT }
737 { LEFT, LEFT, ZERO, PIN, LEFT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, PIN, ZERO, RIGHT, RIGHT, LEFT, LEFT, ZERO, ZERO, RIGHT }
740 { ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, PIN, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, PIN, LEFT, PIN, RIGHT, ZERO, ZERO, ZERO, PIN, RIGHT }
743 { ZERO, PIN, ZERO, PIN, PIN, ZERO, PIN, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO, ZERO, PIN, ZERO, PIN, PIN, ZERO, PIN, ZERO, PIN }
746 { ZERO, ZERO, PIN, PIN, ZERO, LEFT, ZERO, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, ZERO, PIN, PIN, ZERO, LEFT, ZERO, ZERO, PIN, PIN, ZERO }
749 { ZERO, ZERO, PIN, PIN, ZERO, LEFT, ZERO, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, ZERO, PIN, PIN, ZERO, LEFT, ZERO, ZERO, PIN, PIN, ZERO }
752 { PIN, ZERO, RIGHT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, RIGHT, ZERO, PIN, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN }
755 { RIGHT, LEFT, PIN, LEFT, LEFT, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, LEFT, LEFT, PIN, LEFT, RIGHT }
758 { LEFT, ZERO, PIN, ZERO, RIGHT, ZERO, ZERO, LEFT, ZERO, PIN, ZERO, RIGHT, LEFT, ZERO, PIN, ZERO, RIGHT, ZERO, ZERO, LEFT, ZERO, PIN, ZERO }
761 { RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT }
764 { ZERO, RIGHT, ZERO, ZERO, LEFT, ZERO, ZERO, RIGHT, PIN, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, PIN, LEFT, ZERO, ZERO, RIGHT, ZERO, ZERO, LEFT }
767 { RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, ZERO, LEFT, RIGHT }
770 { ZERO, ZERO, PIN, PIN, ZERO, LEFT, LEFT, RIGHT, PIN, ZERO, PIN, PIN, ZERO, PIN, LEFT, RIGHT, RIGHT, ZERO, PIN, PIN, ZERO, ZERO, PIN }
773 { ZERO, ZERO, PIN, ZERO, ZERO, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, LEFT, LEFT, ZERO, PIN, ZERO, RIGHT, RIGHT, LEFT, PIN, LEFT, RIGHT }
776 { ZERO, LEFT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, LEFT, ZERO, LEFT, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT }
779 { ZERO, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO, ZERO, ZERO, LEFT, PIN, RIGHT, ZERO, ZERO, ZERO, ZERO, PIN }
782 { LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, LEFT, ZERO, LEFT, PIN, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT }
785 { LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, ZERO, RIGHT, ZERO, RIGHT, ZERO, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT }
788 { LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, LEFT, RIGHT, ZERO, RIGHT, LEFT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT }
791 { PIN, PIN, ZERO, ZERO, ZERO, ZERO, ZERO, LEFT, ZERO, ZERO, LEFT, RIGHT, ZERO, ZERO, LEFT, RIGHT, ZERO, ZERO, RIGHT, ZERO, ZERO, ZERO, ZERO }
794 { PIN, ZERO, ZERO, PIN, RIGHT, PIN, LEFT, PIN, ZERO, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, ZERO, PIN, RIGHT, PIN, LEFT, PIN, ZERO }
797 { ZERO, RIGHT, LEFT, ZERO, ZERO, ZERO, LEFT, RIGHT, ZERO, PIN, RIGHT, LEFT, ZERO, LEFT, RIGHT, LEFT, PIN, LEFT, RIGHT, LEFT, ZERO, LEFT, RIGHT }
800 { LEFT, LEFT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT }
803 { LEFT, LEFT, PIN, RIGHT, RIGHT, ZERO, LEFT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, PIN, RIGHT, PIN, LEFT, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT }
806 { RIGHT, RIGHT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, LEFT }
809 { RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, ZERO, RIGHT, LEFT, ZERO, ZERO, LEFT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT }
812 { ZERO, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, LEFT, PIN, RIGHT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, PIN, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT }
815 { LEFT, LEFT, RIGHT, PIN, ZERO, RIGHT, ZERO, LEFT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, ZERO, LEFT, ZERO, PIN, LEFT, RIGHT, RIGHT, RIGHT, PIN }
818 { PIN, ZERO, ZERO, PIN, PIN, ZERO, PIN, RIGHT, LEFT, RIGHT, RIGHT, PIN, LEFT, LEFT, RIGHT, LEFT, PIN, ZERO, PIN, PIN, ZERO, ZERO, PIN }
821 { ZERO, ZERO, LEFT, RIGHT, PIN, RIGHT, ZERO, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, ZERO, RIGHT, PIN, RIGHT, RIGHT, ZERO, PIN }
824 { ZERO, RIGHT, ZERO, PIN, LEFT, ZERO, LEFT, RIGHT, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, LEFT, RIGHT, ZERO, RIGHT, PIN, ZERO, LEFT, ZERO }
827 { ZERO, PIN, ZERO, ZERO, ZERO, ZERO, ZERO, PIN, LEFT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, LEFT, ZERO, ZERO, ZERO, PIN }
830 { ZERO, PIN, PIN, ZERO, PIN, RIGHT, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, RIGHT, ZERO, ZERO, PIN, ZERO, ZERO, PIN }
833 { ZERO, LEFT, PIN, RIGHT, ZERO, PIN, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT }
836 { LEFT, RIGHT, LEFT, RIGHT, RIGHT, PIN, LEFT, PIN, LEFT, RIGHT, RIGHT, PIN, LEFT, LEFT, RIGHT, RIGHT, PIN, LEFT, LEFT, RIGHT, PIN, RIGHT, PIN }
839 { LEFT, LEFT, RIGHT, RIGHT, LEFT, PIN, LEFT, PIN, RIGHT, PIN, LEFT, ZERO, RIGHT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, RIGHT, LEFT, RIGHT, RIGHT }
842 { LEFT, ZERO, LEFT, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, LEFT, RIGHT, PIN, LEFT, LEFT, RIGHT, ZERO, RIGHT }
845 { PIN, ZERO, LEFT, PIN, RIGHT, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, ZERO, PIN, ZERO, RIGHT, PIN, LEFT, ZERO, PIN, ZERO, ZERO, PIN }
848 { ZERO, ZERO, PIN, ZERO, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, LEFT, PIN, LEFT, LEFT, PIN, RIGHT, RIGHT, PIN, RIGHT, ZERO, PIN, PIN, ZERO }
851 { LEFT, LEFT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, ZERO, LEFT, RIGHT, ZERO, ZERO, LEFT, RIGHT }
854 { RIGHT, LEFT, ZERO, PIN, LEFT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, PIN, ZERO, RIGHT, LEFT, ZERO }
857 { PIN, PIN, ZERO, LEFT, RIGHT, LEFT, ZERO, PIN, RIGHT, PIN, LEFT, ZERO, ZERO, ZERO, ZERO, RIGHT, PIN, LEFT, PIN, ZERO, RIGHT, LEFT, RIGHT }
860 { PIN, ZERO, PIN, PIN, ZERO, ZERO, ZERO, ZERO, PIN, PIN, ZERO, PIN, LEFT, ZERO, PIN, PIN, ZERO, ZERO, ZERO, ZERO, PIN, PIN, ZERO }
863 { PIN, ZERO, RIGHT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, LEFT, PIN, RIGHT, RIGHT, PIN, RIGHT, LEFT, ZERO, ZERO }
866 { RIGHT, ZERO, ZERO, ZERO, PIN, LEFT, PIN, LEFT, RIGHT, RIGHT, ZERO, PIN, ZERO, LEFT, LEFT, RIGHT, PIN, RIGHT, PIN, ZERO, ZERO, ZERO, LEFT }
869 { ZERO, PIN, ZERO, ZERO, LEFT, ZERO, LEFT, ZERO, ZERO, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, ZERO, RIGHT, ZERO, RIGHT, ZERO, ZERO, PIN, ZERO }
872 { ZERO, ZERO, ZERO, ZERO, LEFT, ZERO, ZERO, RIGHT, ZERO, ZERO, ZERO, ZERO, LEFT, ZERO, ZERO, RIGHT, ZERO, ZERO, ZERO, ZERO, LEFT, ZERO, ZERO }
874 { "HoleInTheMiddle1",
875 { ZERO, LEFT, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, LEFT, RIGHT, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, RIGHT }
877 { "HoleInTheMiddle2",
878 { ZERO, LEFT, RIGHT, ZERO, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, RIGHT, LEFT, ZERO, LEFT, RIGHT, ZERO, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, RIGHT }
881 { RIGHT, RIGHT, PIN, LEFT, LEFT, LEFT, PIN, RIGHT, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, LEFT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, RIGHT, PIN }
884 { LEFT, PIN, LEFT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT }
887 { LEFT, LEFT, LEFT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, RIGHT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, RIGHT, LEFT, LEFT }
890 { RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT }
893 { ZERO, ZERO, ZERO, ZERO, PIN, RIGHT, ZERO, RIGHT, ZERO, ZERO, LEFT, PIN, RIGHT, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, RIGHT, ZERO, RIGHT }
896 { RIGHT, RIGHT, LEFT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, LEFT, LEFT, PIN, RIGHT, RIGHT, LEFT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, LEFT, LEFT }
899 { ZERO, PIN, PIN, ZERO, PIN, ZERO, PIN, PIN, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, PIN, PIN, ZERO, PIN, ZERO, PIN, PIN, ZERO }
902 { LEFT, LEFT, PIN, LEFT, ZERO, LEFT, RIGHT, LEFT, PIN, LEFT, LEFT, RIGHT, RIGHT, PIN, RIGHT, LEFT, RIGHT, ZERO, RIGHT, PIN, RIGHT, RIGHT, LEFT }
905 { ZERO, PIN, PIN, ZERO, ZERO, LEFT, ZERO, LEFT, ZERO, ZERO, PIN, ZERO, ZERO, RIGHT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO }
908 { RIGHT, PIN, LEFT, RIGHT, LEFT, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, RIGHT, LEFT, RIGHT, PIN, LEFT }
911 { PIN, ZERO, LEFT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, ZERO, PIN, ZERO, LEFT, PIN, LEFT, PIN, RIGHT, PIN, LEFT, ZERO, PIN, PIN, ZERO }
914 { PIN, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, RIGHT, LEFT, ZERO, LEFT }
917 { ZERO, ZERO, PIN, ZERO, LEFT, ZERO, PIN, PIN, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, ZERO, ZERO }
920 { ZERO, ZERO, ZERO, RIGHT, ZERO, RIGHT, LEFT, ZERO, LEFT, PIN, ZERO, PIN, ZERO, ZERO, PIN, ZERO, PIN, RIGHT, ZERO, RIGHT, LEFT, ZERO, LEFT }
923 { PIN, PIN, ZERO, ZERO, PIN, ZERO, RIGHT, PIN, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, PIN, LEFT, ZERO, PIN, PIN, ZERO, PIN, PIN }
926 { PIN, RIGHT, LEFT, ZERO, PIN, PIN, ZERO, ZERO, LEFT, RIGHT, ZERO, ZERO, PIN, ZERO, ZERO, LEFT, RIGHT, PIN, RIGHT, ZERO, PIN, PIN, ZERO }
929 { ZERO, LEFT, LEFT, PIN, RIGHT, ZERO, RIGHT, RIGHT, PIN, LEFT, LEFT, RIGHT, RIGHT, PIN, LEFT, LEFT, ZERO, LEFT, PIN, RIGHT, RIGHT, ZERO, RIGHT }
932 { ZERO, RIGHT, ZERO, RIGHT, LEFT, RIGHT, PIN, ZERO, LEFT, PIN, RIGHT, ZERO, PIN, LEFT, RIGHT, LEFT, ZERO, LEFT, ZERO, RIGHT, RIGHT, PIN, LEFT }
935 { LEFT, ZERO, PIN, PIN, ZERO, LEFT, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT }
938 { ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, LEFT, PIN, LEFT, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO }
941 { ZERO, PIN, ZERO, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, ZERO, PIN, ZERO }
943 { "MouseWithoutTail",
944 { ZERO, PIN, PIN, ZERO, LEFT, ZERO, PIN, PIN, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO }
947 { PIN, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, ZERO, LEFT, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, LEFT, ZERO, PIN }
950 { ZERO, ZERO, LEFT, ZERO, ZERO, ZERO, LEFT, ZERO, ZERO, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, ZERO, RIGHT, ZERO, ZERO, ZERO, RIGHT, ZERO, ZERO }
953 { LEFT, ZERO, PIN, LEFT, LEFT, RIGHT, RIGHT, PIN, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, LEFT }
956 { ZERO, RIGHT, PIN, LEFT, LEFT, LEFT, ZERO, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, ZERO, RIGHT, RIGHT, RIGHT, PIN, LEFT, ZERO }
959 { LEFT, PIN, RIGHT, PIN, RIGHT, ZERO, PIN, ZERO, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, RIGHT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, LEFT }
962 { PIN, ZERO, ZERO, ZERO, PIN, RIGHT, PIN, LEFT, PIN, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, ZERO, ZERO, ZERO }
965 { ZERO, ZERO, PIN, PIN, ZERO, LEFT, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, ZERO, ZERO, ZERO, ZERO, PIN }
968 { PIN, PIN, ZERO, PIN, LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, PIN, ZERO, PIN, ZERO, ZERO, PIN, ZERO }
971 { ZERO, PIN, ZERO, ZERO, PIN, ZERO, ZERO, PIN, ZERO, LEFT, ZERO, PIN, ZERO, RIGHT, ZERO, PIN, ZERO, ZERO, PIN, ZERO, ZERO, PIN, ZERO }
974 { ZERO, ZERO, ZERO, ZERO, RIGHT, RIGHT, ZERO, LEFT, PIN, RIGHT, ZERO, RIGHT, ZERO, RIGHT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, LEFT, ZERO, PIN }
977 { PIN, PIN, RIGHT, ZERO, PIN, PIN, ZERO, PIN, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, PIN, ZERO, PIN, PIN, ZERO, LEFT, PIN, PIN }
979 { "PictureCommingSoon",
980 { LEFT, LEFT, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, RIGHT, PIN, RIGHT, LEFT, ZERO, RIGHT, RIGHT }
983 { LEFT, PIN, ZERO, ZERO, PIN, ZERO, ZERO, PIN, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, PIN, ZERO, ZERO, PIN, ZERO, ZERO, PIN, RIGHT }
986 { LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, LEFT }
989 { RIGHT, PIN, ZERO, ZERO, ZERO, ZERO, PIN, ZERO, ZERO, PIN, PIN, ZERO, PIN, LEFT, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, RIGHT }
992 { ZERO, PIN, ZERO, PIN, RIGHT, PIN, ZERO, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, PIN, PIN, ZERO, ZERO, LEFT, ZERO, PIN, LEFT }
995 { LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT }
998 { RIGHT, PIN, ZERO, PIN, RIGHT, ZERO, PIN, PIN, ZERO, ZERO, LEFT, PIN, RIGHT, ZERO, ZERO, PIN, PIN, ZERO, LEFT, PIN, ZERO, PIN, LEFT }
1001 { ZERO, ZERO, ZERO, RIGHT, ZERO, LEFT, RIGHT, LEFT, ZERO, ZERO, ZERO, RIGHT, ZERO, LEFT, RIGHT, LEFT, ZERO, ZERO, ZERO, RIGHT, ZERO, LEFT, RIGHT }
1004 { ZERO, LEFT, PIN, RIGHT, ZERO, LEFT, PIN, RIGHT, ZERO, LEFT, PIN, RIGHT, ZERO, PIN, RIGHT, LEFT, LEFT, LEFT, PIN, RIGHT, RIGHT, RIGHT, LEFT }
1006 { "QuarterbackTiltedAndReadyToHut",
1007 { PIN, ZERO, RIGHT, RIGHT, LEFT, RIGHT, PIN, RIGHT, LEFT, RIGHT, ZERO, PIN, ZERO, LEFT, RIGHT, LEFT, PIN, LEFT, RIGHT, LEFT, LEFT, ZERO, PIN }
1010 { PIN, LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, ZERO, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT }
1013 { LEFT, ZERO, LEFT, ZERO, LEFT, ZERO, LEFT, LEFT, ZERO, LEFT, ZERO, LEFT, ZERO, LEFT, RIGHT, ZERO, PIN, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT }
1016 { ZERO, ZERO, ZERO, PIN, ZERO, ZERO, PIN, RIGHT, LEFT, LEFT, LEFT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, LEFT, PIN, ZERO, ZERO, PIN }
1019 { LEFT, LEFT, PIN, RIGHT, ZERO, PIN, ZERO, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, ZERO, PIN, ZERO, LEFT, PIN, RIGHT, RIGHT }
1022 { RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, PIN, ZERO, PIN, PIN, ZERO, PIN, ZERO, PIN, PIN, ZERO, PIN, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT }
1025 { RIGHT, ZERO, LEFT, PIN, RIGHT, ZERO, RIGHT, ZERO, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, ZERO, LEFT, ZERO, LEFT, PIN, RIGHT, ZERO, LEFT }
1028 { ZERO, LEFT, PIN, RIGHT, ZERO, PIN, LEFT, ZERO, PIN, ZERO, RIGHT, PIN, ZERO, LEFT, PIN, RIGHT, ZERO, PIN, LEFT, ZERO, PIN, ZERO, RIGHT }
1031 { PIN, PIN, RIGHT, ZERO, LEFT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, RIGHT, ZERO, LEFT, PIN, PIN }
1034 { RIGHT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, PIN, RIGHT, PIN, LEFT }
1037 { RIGHT, LEFT, PIN, ZERO, ZERO, ZERO, LEFT, RIGHT, LEFT, PIN, ZERO, ZERO, PIN, LEFT, RIGHT, LEFT, ZERO, ZERO, ZERO, PIN, LEFT, RIGHT, LEFT }
1040 { LEFT, LEFT, LEFT, PIN, RIGHT, RIGHT, RIGHT, ZERO, LEFT, PIN, RIGHT, ZERO, LEFT, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, PIN, PIN, ZERO, LEFT }
1043 { RIGHT, PIN, ZERO, LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, RIGHT, PIN, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, ZERO, LEFT, RIGHT, ZERO, ZERO }
1046 { RIGHT, LEFT, LEFT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, LEFT, LEFT, LEFT, RIGHT, LEFT }
1049 { LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, ZERO, ZERO, ZERO, ZERO, PIN, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, ZERO, RIGHT }
1052 { PIN, RIGHT, LEFT, LEFT, LEFT, LEFT, PIN, RIGHT, RIGHT, RIGHT, RIGHT, LEFT, ZERO, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, LEFT, ZERO, PIN, PIN }
1055 { LEFT, RIGHT, ZERO, RIGHT, LEFT, RIGHT, ZERO, RIGHT, LEFT, RIGHT, ZERO, RIGHT, LEFT, RIGHT, ZERO, RIGHT, LEFT, RIGHT, ZERO, RIGHT, LEFT, RIGHT, ZERO }
1058 { LEFT, RIGHT, LEFT, RIGHT, ZERO, LEFT, RIGHT, LEFT, PIN, ZERO, ZERO, PIN, ZERO, ZERO, PIN, RIGHT, LEFT, ZERO, ZERO, RIGHT, LEFT, RIGHT, LEFT }
1061 { ZERO, LEFT, RIGHT, ZERO, RIGHT, LEFT, ZERO, LEFT, RIGHT, ZERO, LEFT, RIGHT, ZERO, LEFT, RIGHT, ZERO, RIGHT, LEFT, ZERO, LEFT, RIGHT, ZERO, LEFT }
1063 { "SnakeReadyToStrike",
1064 { LEFT, ZERO, LEFT, ZERO, LEFT, ZERO, LEFT, RIGHT, ZERO, RIGHT, ZERO, RIGHT, ZERO, LEFT, ZERO, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, ZERO, LEFT }
1067 { RIGHT, RIGHT, PIN, ZERO, RIGHT, LEFT, RIGHT, ZERO, ZERO, ZERO, RIGHT, PIN, LEFT, PIN, ZERO, PIN, LEFT, PIN, RIGHT, ZERO, ZERO, LEFT, RIGHT }
1070 { ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, PIN, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, PIN, LEFT, PIN, RIGHT, ZERO, ZERO, ZERO, PIN, RIGHT }
1073 { PIN, PIN, LEFT, PIN, LEFT, PIN, RIGHT, ZERO, RIGHT, PIN, RIGHT, ZERO, RIGHT, PIN, LEFT, PIN, RIGHT, ZERO, PIN, PIN, ZERO, ZERO, PIN }
1076 { LEFT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, RIGHT }
1079 { ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, ZERO, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, ZERO, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO }
1082 { PIN, RIGHT, ZERO, PIN, ZERO, LEFT, PIN, RIGHT, PIN, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, PIN, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, PIN }
1085 { PIN, PIN, RIGHT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, PIN }
1088 { PIN, PIN, LEFT, PIN, LEFT, PIN, RIGHT, ZERO, PIN, PIN, ZERO, LEFT, PIN, RIGHT, ZERO, PIN, ZERO, LEFT, PIN, LEFT, LEFT, PIN, PIN }
1091 { LEFT, ZERO, ZERO, LEFT, PIN, RIGHT, ZERO, ZERO, LEFT, ZERO, ZERO, PIN, ZERO, ZERO, RIGHT, ZERO, ZERO, LEFT, PIN, RIGHT, ZERO, ZERO, RIGHT }
1094 { PIN, RIGHT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, ZERO, LEFT, PIN, RIGHT, ZERO, LEFT, LEFT, LEFT, RIGHT, RIGHT, LEFT, PIN, ZERO, RIGHT, PIN, LEFT }
1097 { RIGHT, RIGHT, ZERO, ZERO, LEFT, RIGHT, LEFT, PIN, ZERO, LEFT, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, RIGHT, LEFT, RIGHT, ZERO, ZERO, LEFT }
1100 { PIN, LEFT, ZERO, RIGHT, RIGHT, LEFT, PIN, ZERO, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, ZERO, PIN, RIGHT, LEFT, LEFT, ZERO }
1103 { ZERO, ZERO, LEFT, LEFT, PIN, RIGHT, RIGHT, ZERO, ZERO, LEFT, LEFT, PIN, RIGHT, RIGHT, ZERO, ZERO, LEFT, LEFT, PIN, RIGHT, RIGHT, ZERO, ZERO }
1106 { PIN, ZERO, PIN, ZERO, ZERO, PIN, PIN, ZERO, PIN, ZERO, ZERO, PIN, ZERO, ZERO, PIN, ZERO, PIN, PIN, ZERO, ZERO, PIN, ZERO, PIN }
1109 { RIGHT, ZERO, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, LEFT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, ZERO }
1112 { ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO }
1115 { ZERO, PIN, ZERO, PIN, ZERO, PIN, PIN, ZERO, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, PIN, ZERO, ZERO, PIN, ZERO }
1118 { ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO }
1121 { ZERO, PIN, ZERO, PIN, LEFT, LEFT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, RIGHT }
1124 { PIN, ZERO, PIN, RIGHT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, RIGHT, PIN, ZERO, ZERO, ZERO, ZERO, ZERO, PIN, PIN }
1127 { PIN, PIN, ZERO, ZERO, ZERO, RIGHT, ZERO, RIGHT, ZERO, ZERO, LEFT, PIN, RIGHT, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, RIGHT, ZERO, RIGHT }
1130 { RIGHT, RIGHT, PIN, ZERO, PIN, PIN, ZERO, PIN, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, PIN, ZERO, PIN, PIN, ZERO, PIN, LEFT, LEFT, RIGHT }
1133 { RIGHT, ZERO, LEFT, RIGHT, LEFT, ZERO, LEFT, RIGHT, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, LEFT, RIGHT, ZERO, RIGHT, LEFT, RIGHT, ZERO, LEFT }
1136 { ZERO, PIN, LEFT, LEFT, PIN, ZERO, ZERO, LEFT, PIN, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, PIN, LEFT }
1139 { ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, RIGHT, PIN, RIGHT, LEFT, ZERO, RIGHT, PIN }
1142 { ZERO, ZERO, RIGHT, LEFT, PIN, LEFT, ZERO, PIN, PIN, ZERO, LEFT, PIN, RIGHT, ZERO, PIN, PIN, ZERO, RIGHT, PIN, RIGHT, LEFT, ZERO, ZERO }
1145 { ZERO, ZERO, RIGHT, LEFT, PIN, LEFT, ZERO, PIN, PIN, ZERO, LEFT, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, RIGHT, PIN, RIGHT, LEFT, ZERO, ZERO }
1148 { RIGHT, ZERO, PIN, PIN, ZERO, LEFT, RIGHT, PIN, LEFT, LEFT, RIGHT, RIGHT, PIN, LEFT, LEFT, RIGHT, RIGHT, PIN, LEFT, LEFT, RIGHT, RIGHT, PIN }
1151 { RIGHT, ZERO, ZERO, RIGHT, LEFT, ZERO, ZERO, RIGHT, LEFT, ZERO, ZERO, LEFT, RIGHT, ZERO, ZERO, RIGHT, LEFT, ZERO, ZERO, RIGHT, LEFT, ZERO, ZERO }
1154 { RIGHT, LEFT, ZERO, RIGHT, LEFT, PIN, LEFT, LEFT, PIN, LEFT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT, PIN, RIGHT, RIGHT, PIN, RIGHT, LEFT }
1157 { PIN, ZERO, PIN, PIN, ZERO, PIN, ZERO, ZERO, ZERO, PIN, PIN, ZERO, PIN, ZERO, ZERO, PIN, ZERO, PIN, PIN, ZERO, ZERO, ZERO, ZERO }
1160 { RIGHT, ZERO, LEFT, RIGHT, ZERO, LEFT, PIN, RIGHT, ZERO, RIGHT, ZERO, PIN, ZERO, LEFT, ZERO, LEFT, PIN, RIGHT, ZERO, LEFT, RIGHT, ZERO, LEFT }
1163 { RIGHT, ZERO, ZERO, RIGHT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, RIGHT, PIN, LEFT, LEFT, PIN, LEFT, PIN, RIGHT, PIN, LEFT, ZERO, ZERO, LEFT }
1166 { ZERO, PIN, RIGHT, LEFT, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, PIN, PIN, ZERO, LEFT, LEFT, PIN, ZERO, LEFT, RIGHT, ZERO, PIN, ZERO, LEFT }
1169 { PIN, LEFT, LEFT, PIN, LEFT, ZERO, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, PIN, RIGHT, PIN, RIGHT, RIGHT, PIN, ZERO }
1172 { PIN, ZERO, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, ZERO, PIN, ZERO, ZERO, ZERO }
1175 { ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, RIGHT, LEFT, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, RIGHT, LEFT, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, RIGHT }
1178 { PIN, ZERO, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, PIN, ZERO, PIN, LEFT, PIN, RIGHT, PIN, ZERO, PIN, LEFT, PIN, LEFT, PIN, RIGHT, PIN }
1181 { RIGHT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, LEFT, PIN, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, ZERO, LEFT, RIGHT, ZERO }
1184 { ZERO, PIN, ZERO, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, PIN, ZERO, ZERO, PIN, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, ZERO, PIN, ZERO, ZERO }
1187 { ZERO, PIN, ZERO, ZERO, PIN, PIN, ZERO, PIN, ZERO, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, PIN, RIGHT, PIN, LEFT, ZERO, ZERO, RIGHT, PIN }
1190 { PIN, LEFT, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, LEFT, ZERO }
1193 { LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, LEFT, PIN, LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT }
1196 { LEFT, PIN, RIGHT, PIN, RIGHT, LEFT, ZERO, PIN, PIN, ZERO, RIGHT, LEFT, ZERO, PIN, PIN, ZERO, RIGHT, LEFT, PIN, LEFT, PIN, RIGHT, ZERO }
1199 { ZERO, PIN, ZERO, PIN, ZERO, PIN, LEFT, PIN, RIGHT, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, LEFT, PIN, RIGHT, PIN, ZERO }
1202 { ZERO, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, PIN, ZERO, ZERO, LEFT, PIN, RIGHT, ZERO, ZERO, PIN, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, ZERO }
1205 { PIN, ZERO, ZERO, ZERO, PIN, PIN, ZERO, RIGHT, RIGHT, LEFT, LEFT, PIN, RIGHT, RIGHT, LEFT, LEFT, ZERO, PIN, PIN, ZERO, ZERO, ZERO, PIN }
1208 { ZERO, RIGHT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, LEFT, RIGHT, ZERO, PIN, ZERO, LEFT, RIGHT, LEFT, PIN, LEFT, PIN, RIGHT, PIN, LEFT, ZERO }
1211 { PIN, RIGHT, PIN, LEFT, PIN, ZERO, ZERO, PIN, RIGHT, ZERO, RIGHT, RIGHT, ZERO, RIGHT, PIN, ZERO, ZERO, PIN, LEFT, PIN, RIGHT, PIN, ZERO }
1214 { ZERO, RIGHT, PIN, LEFT, PIN, RIGHT, ZERO, ZERO, RIGHT, PIN, LEFT, LEFT, RIGHT, RIGHT, PIN, LEFT, ZERO, ZERO, LEFT, PIN, RIGHT, PIN, LEFT }
1217 { LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT }
1220 { PIN, RIGHT, RIGHT, PIN, ZERO, LEFT, PIN, RIGHT, RIGHT, PIN, ZERO, LEFT, PIN, RIGHT, RIGHT, PIN, ZERO, LEFT, PIN, RIGHT, RIGHT, PIN, ZERO }
1223 { PIN, ZERO, PIN, PIN, ZERO, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, ZERO, PIN, ZERO, PIN, ZERO, PIN, PIN, ZERO, ZERO, ZERO, ZERO }
1225 { "WindowToTheWorld",
1226 { PIN, LEFT, ZERO, PIN, ZERO, ZERO, PIN, ZERO, ZERO, PIN, ZERO, RIGHT, PIN, LEFT, ZERO, PIN, ZERO, ZERO, PIN, ZERO, ZERO, PIN, ZERO }
1229 { PIN, PIN, ZERO, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, ZERO, PIN, ZERO, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, ZERO, PIN, PIN, ZERO, PIN }
1232 { ZERO, ZERO, ZERO, ZERO, PIN, RIGHT, RIGHT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, RIGHT, RIGHT, PIN, ZERO, ZERO, ZERO, ZERO }
1235 { RIGHT, ZERO, PIN, ZERO, LEFT, PIN, RIGHT, PIN, RIGHT, LEFT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, LEFT, PIN, LEFT, PIN, RIGHT, ZERO, PIN, ZERO }
1238 { PIN, RIGHT, PIN, RIGHT, RIGHT, PIN, LEFT, LEFT, PIN, ZERO, PIN, RIGHT, PIN, LEFT, PIN, ZERO, PIN, RIGHT, RIGHT, PIN, LEFT, LEFT, PIN }
1241 { ZERO, ZERO, PIN, PIN, ZERO, PIN, ZERO, ZERO, PIN, ZERO, PIN, PIN, ZERO, PIN, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO, ZERO, PIN }
1244 { LEFT, ZERO, ZERO, PIN, LEFT, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, PIN, PIN, ZERO, LEFT, RIGHT, PIN, LEFT, LEFT, RIGHT, PIN, ZERO, ZERO }
1248 int models = (sizeof(model) / sizeof(struct model_s));
1250 #define VOFFSET 0.045
1256 /* the connecting string that holds the snake together */
1257 #define MAGICAL_RED_STRING 0
1259 #define GETSCALAR(vec,mask) ((vec)==(mask) ? 1 : ((vec)==-(mask) ? -1 : 0 ))
1262 # define MAX(x, y) ((x) > (y) ? (x) : (y))
1265 # define MIN(x, y) ((x) < (y) ? (x) : (y))
1268 #define RAND(n) ((random() & 0x7fffffff) % ((long) (n)))
1269 #define RANDSIGN() ((random() & 1) ? 1 : -1)
1271 /* the triangular prism what makes up the basic unit */
1272 float solid_prism_v[][3] = {
1273 /* first corner, bottom left front */
1274 { VOFFSET, VOFFSET, 1.0 },
1275 { VOFFSET, 0.00, 1.0 - VOFFSET },
1276 { 0.00, VOFFSET, 1.0 - VOFFSET },
1277 /* second corner, rear */
1278 { VOFFSET, VOFFSET, 0.00 },
1279 { VOFFSET, 0.00, VOFFSET },
1280 { 0.00, VOFFSET, VOFFSET },
1281 /* third, right front */
1282 { 1.0 - VOFFSET / M_SQRT1_2, VOFFSET, 1.0 },
1283 { 1.0 - VOFFSET / M_SQRT1_2, 0.0, 1.0 - VOFFSET },
1284 { 1.0 - VOFFSET * M_SQRT1_2, VOFFSET, 1.0 - VOFFSET },
1285 /* fourth, right rear */
1286 { 1.0 - VOFFSET / M_SQRT1_2, VOFFSET, 0.0 },
1287 { 1.0 - VOFFSET / M_SQRT1_2, 0.0, VOFFSET },
1288 { 1.0 - VOFFSET * M_SQRT1_2, VOFFSET, VOFFSET },
1289 /* fifth, upper front */
1290 { VOFFSET, 1.0 - VOFFSET / M_SQRT1_2, 1.0 },
1291 { VOFFSET / M_SQRT1_2, 1.0 - VOFFSET * M_SQRT1_2, 1.0 - VOFFSET },
1292 { 0.0, 1.0 - VOFFSET / M_SQRT1_2, 1.0 - VOFFSET},
1293 /* sixth, upper rear */
1294 { VOFFSET, 1.0 - VOFFSET / M_SQRT1_2, 0.0 },
1295 { VOFFSET / M_SQRT1_2, 1.0 - VOFFSET * M_SQRT1_2, VOFFSET },
1296 { 0.0, 1.0 - VOFFSET / M_SQRT1_2, VOFFSET }};
1298 float solid_prism_n[][3] = {/* corners */
1299 { -VOFFSET, -VOFFSET, VOFFSET },
1300 { VOFFSET, -VOFFSET, VOFFSET },
1301 { -VOFFSET, VOFFSET, VOFFSET },
1302 { -VOFFSET, -VOFFSET, -VOFFSET },
1303 { VOFFSET, -VOFFSET, -VOFFSET },
1304 { -VOFFSET, VOFFSET, -VOFFSET },
1306 { -VOFFSET, 0.0, VOFFSET },
1307 { 0.0, -VOFFSET, VOFFSET },
1308 { VOFFSET, VOFFSET, VOFFSET },
1309 { -VOFFSET, 0.0, -VOFFSET },
1310 { 0.0, -VOFFSET, -VOFFSET },
1311 { VOFFSET, VOFFSET, -VOFFSET },
1312 { -VOFFSET, -VOFFSET, 0.0 },
1313 { VOFFSET, -VOFFSET, 0.0 },
1314 { -VOFFSET, VOFFSET, 0.0 },
1318 { M_SQRT1_2, M_SQRT1_2, 0.0 },
1320 { 0.0, 0.0, -1.0 }};
1322 float wire_prism_v[][3] = {{ 0.0, 0.0, 1.0 },
1329 float wire_prism_n[][3] = {{ 0.0, 0.0, 1.0},
1331 { M_SQRT1_2, M_SQRT1_2, 0.0},
1335 static struct glsnake_cfg * glc = NULL;
1340 typedef float (*morphFunc)(long);
1343 /* forward definitions for GLUT functions */
1344 void calc_rotation();
1345 inline void ui_mousedrag();
1353 float light_pos[][3] = {{0.0, 0.0, 20.0}, {0.0, 20.0, 0.0}};
1354 float light_dir[][3] = {{0.0, 0.0,-20.0}, {0.0,-20.0, 0.0}};
1356 glClearColor(0.0, 0.0, 0.0, 0.0);
1357 glEnable(GL_DEPTH_TEST);
1358 glShadeModel(GL_SMOOTH);
1359 glCullFace(GL_BACK);
1360 glEnable(GL_CULL_FACE);
1361 glEnable(GL_NORMALIZE);
1364 glColor3f(1.0, 1.0, 1.0);
1365 glLightfv(GL_LIGHT0, GL_POSITION, light_pos[0]);
1366 glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, light_dir[0]);
1367 glLightfv(GL_LIGHT1, GL_POSITION, light_pos[1]);
1368 glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, light_dir[1]);
1369 glEnable(GL_LIGHTING);
1370 glEnable(GL_LIGHT0);
1371 glEnable(GL_LIGHT1);
1372 glEnable(GL_COLOR_MATERIAL);
1376 void gettime(snaketime *t)
1378 #ifdef HAVE_GETTIMEOFDAY
1379 #ifdef GETTIMEOFDAY_TWO_ARGS
1380 struct timezone tzp;
1381 gettimeofday(t, &tzp);
1382 #else /* !GETTIMEOFDAY_TWO_ARGS */
1384 #endif /* !GETTIMEOFDAY_TWO_ARGS */
1385 #else /* !HAVE_GETTIMEOFDAY */
1388 #endif /* HAVE_FTIME */
1389 #endif /* !HAVE_GETTIMEOFDAY */
1393 void start_morph(int model_index, int immediate);
1395 /* wot initialises it */
1402 struct glsnake_cfg * bp;
1404 /* set up the conf struct and glx contexts */
1406 glc = (struct glsnake_cfg *) calloc(MI_NUM_SCREENS(mi), sizeof(struct glsnake_cfg));
1408 fprintf(stderr, "%s: out of memory\n", progname);
1412 bp = &glc[MI_SCREEN(mi)];
1414 if ((bp->glx_context = init_GL(mi)) != NULL) {
1416 glsnake_reshape(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
1422 /* initialise conf struct */
1423 memset(&bp->node, 0, sizeof(float) * NODE_COUNT);
1433 gettime(&bp->last_iteration);
1434 memcpy(&bp->last_morph, &bp->last_iteration, sizeof(bp->last_morph));
1436 bp->prev_colour = bp->next_colour = COLOUR_ACYCLIC;
1437 bp->next_model = RAND(models);
1438 bp->prev_model = START_MODEL;
1439 start_morph(bp->prev_model, 1);
1441 /* set up a font for the labels */
1444 load_font(mi->dpy, "labelfont", &bp->font, &bp->font_list);
1447 /* build a solid display list */
1448 glc->node_solid = glGenLists(1);
1449 glNewList(glc->node_solid, GL_COMPILE);
1451 glBegin(GL_TRIANGLES);
1452 glNormal3fv(solid_prism_n[0]);
1453 glVertex3fv(solid_prism_v[0]);
1454 glVertex3fv(solid_prism_v[2]);
1455 glVertex3fv(solid_prism_v[1]);
1457 glNormal3fv(solid_prism_n[1]);
1458 glVertex3fv(solid_prism_v[6]);
1459 glVertex3fv(solid_prism_v[7]);
1460 glVertex3fv(solid_prism_v[8]);
1462 glNormal3fv(solid_prism_n[2]);
1463 glVertex3fv(solid_prism_v[12]);
1464 glVertex3fv(solid_prism_v[13]);
1465 glVertex3fv(solid_prism_v[14]);
1467 glNormal3fv(solid_prism_n[3]);
1468 glVertex3fv(solid_prism_v[3]);
1469 glVertex3fv(solid_prism_v[4]);
1470 glVertex3fv(solid_prism_v[5]);
1472 glNormal3fv(solid_prism_n[4]);
1473 glVertex3fv(solid_prism_v[9]);
1474 glVertex3fv(solid_prism_v[11]);
1475 glVertex3fv(solid_prism_v[10]);
1477 glNormal3fv(solid_prism_n[5]);
1478 glVertex3fv(solid_prism_v[16]);
1479 glVertex3fv(solid_prism_v[15]);
1480 glVertex3fv(solid_prism_v[17]);
1484 glNormal3fv(solid_prism_n[6]);
1485 glVertex3fv(solid_prism_v[0]);
1486 glVertex3fv(solid_prism_v[12]);
1487 glVertex3fv(solid_prism_v[14]);
1488 glVertex3fv(solid_prism_v[2]);
1490 glNormal3fv(solid_prism_n[7]);
1491 glVertex3fv(solid_prism_v[0]);
1492 glVertex3fv(solid_prism_v[1]);
1493 glVertex3fv(solid_prism_v[7]);
1494 glVertex3fv(solid_prism_v[6]);
1496 glNormal3fv(solid_prism_n[8]);
1497 glVertex3fv(solid_prism_v[6]);
1498 glVertex3fv(solid_prism_v[8]);
1499 glVertex3fv(solid_prism_v[13]);
1500 glVertex3fv(solid_prism_v[12]);
1502 glNormal3fv(solid_prism_n[9]);
1503 glVertex3fv(solid_prism_v[3]);
1504 glVertex3fv(solid_prism_v[5]);
1505 glVertex3fv(solid_prism_v[17]);
1506 glVertex3fv(solid_prism_v[15]);
1508 glNormal3fv(solid_prism_n[10]);
1509 glVertex3fv(solid_prism_v[3]);
1510 glVertex3fv(solid_prism_v[9]);
1511 glVertex3fv(solid_prism_v[10]);
1512 glVertex3fv(solid_prism_v[4]);
1514 glNormal3fv(solid_prism_n[11]);
1515 glVertex3fv(solid_prism_v[15]);
1516 glVertex3fv(solid_prism_v[16]);
1517 glVertex3fv(solid_prism_v[11]);
1518 glVertex3fv(solid_prism_v[9]);
1520 glNormal3fv(solid_prism_n[12]);
1521 glVertex3fv(solid_prism_v[1]);
1522 glVertex3fv(solid_prism_v[2]);
1523 glVertex3fv(solid_prism_v[5]);
1524 glVertex3fv(solid_prism_v[4]);
1526 glNormal3fv(solid_prism_n[13]);
1527 glVertex3fv(solid_prism_v[8]);
1528 glVertex3fv(solid_prism_v[7]);
1529 glVertex3fv(solid_prism_v[10]);
1530 glVertex3fv(solid_prism_v[11]);
1532 glNormal3fv(solid_prism_n[14]);
1533 glVertex3fv(solid_prism_v[13]);
1534 glVertex3fv(solid_prism_v[16]);
1535 glVertex3fv(solid_prism_v[17]);
1536 glVertex3fv(solid_prism_v[14]);
1540 glBegin(GL_TRIANGLES);
1541 glNormal3fv(solid_prism_n[15]);
1542 glVertex3fv(solid_prism_v[0]);
1543 glVertex3fv(solid_prism_v[6]);
1544 glVertex3fv(solid_prism_v[12]);
1546 glNormal3fv(solid_prism_n[19]);
1547 glVertex3fv(solid_prism_v[3]);
1548 glVertex3fv(solid_prism_v[15]);
1549 glVertex3fv(solid_prism_v[9]);
1553 glNormal3fv(solid_prism_n[16]);
1554 glVertex3fv(solid_prism_v[1]);
1555 glVertex3fv(solid_prism_v[4]);
1556 glVertex3fv(solid_prism_v[10]);
1557 glVertex3fv(solid_prism_v[7]);
1559 glNormal3fv(solid_prism_n[17]);
1560 glVertex3fv(solid_prism_v[8]);
1561 glVertex3fv(solid_prism_v[11]);
1562 glVertex3fv(solid_prism_v[16]);
1563 glVertex3fv(solid_prism_v[13]);
1565 glNormal3fv(solid_prism_n[18]);
1566 glVertex3fv(solid_prism_v[2]);
1567 glVertex3fv(solid_prism_v[14]);
1568 glVertex3fv(solid_prism_v[17]);
1569 glVertex3fv(solid_prism_v[5]);
1573 /* build wire display list */
1574 glc->node_wire = glGenLists(1);
1575 glNewList(glc->node_wire, GL_COMPILE);
1576 glBegin(GL_LINE_STRIP);
1577 glVertex3fv(wire_prism_v[0]);
1578 glVertex3fv(wire_prism_v[1]);
1579 glVertex3fv(wire_prism_v[2]);
1580 glVertex3fv(wire_prism_v[0]);
1581 glVertex3fv(wire_prism_v[3]);
1582 glVertex3fv(wire_prism_v[4]);
1583 glVertex3fv(wire_prism_v[5]);
1584 glVertex3fv(wire_prism_v[3]);
1587 glVertex3fv(wire_prism_v[1]);
1588 glVertex3fv(wire_prism_v[4]);
1589 glVertex3fv(wire_prism_v[2]);
1590 glVertex3fv(wire_prism_v[5]);
1595 /* initialise the rotation */
1606 struct glsnake_cfg * bp = &glc[MI_SCREEN(mi)];
1609 /* draw some text */
1610 glPushAttrib(GL_TRANSFORM_BIT | GL_ENABLE_BIT);
1611 glDisable(GL_LIGHTING);
1612 glDisable(GL_DEPTH_TEST);
1613 glMatrixMode(GL_PROJECTION);
1616 glMatrixMode(GL_MODELVIEW);
1620 gluOrtho2D(0, glc->width, 0, glc->height);
1622 gluOrtho2D(0, mi->xgwa.width, 0, mi->xgwa.height);
1624 glColor3f(1.0, 1.0, 1.0);
1626 char interactstr[] = "interactive";
1631 s = model[glc->next_model].name;
1633 print_gl_string (mi->dpy, bp->font, bp->font_list,
1634 mi->xgwa.width, mi->xgwa.height,
1635 10, mi->xgwa.height - 10,
1639 glMatrixMode(GL_PROJECTION);
1644 /* apply the matrix to the origin and stick it in vec */
1645 void matmult_origin(float rotmat[16], float vec[4]) {
1647 vec[0] = 0.5 * rotmat[0] + 0.5 * rotmat[4] + 0.5 * rotmat [8] + 1 * rotmat[12];
1648 vec[1] = 0.5 * rotmat[1] + 0.5 * rotmat[5] + 0.5 * rotmat [9] + 1 * rotmat[13];
1649 vec[2] = 0.5 * rotmat[2] + 0.5 * rotmat[6] + 0.5 * rotmat[10] + 1 * rotmat[14];
1650 vec[3] = 0.5 * rotmat[3] + 0.5 * rotmat[7] + 0.5 * rotmat[11] + 1 * rotmat[15];
1652 vec[0] = 0 * rotmat [0] + 0 * rotmat [1] + 0 * rotmat [2] + 1 * rotmat [3];
1653 vec[1] = 0 * rotmat [4] + 0 * rotmat [5] + 0 * rotmat [6] + 1 * rotmat [7];
1654 vec[2] = 0 * rotmat [8] + 0 * rotmat [9] + 0 * rotmat[10] + 1 * rotmat[11];
1655 vec[3] = 0 * rotmat[12] + 0 * rotmat[13] + 0 * rotmat[14] + 1 * rotmat[15];
1663 /* wot gets called when the winder is resized */
1664 void glsnake_reshape(
1669 glViewport(0, 0, (GLint) w, (GLint) h);
1670 glMatrixMode(GL_PROJECTION);
1672 gluPerspective(zoom, w/(GLfloat)h, 0.05, 100.0);
1673 gluLookAt(0.0, 0.0, 20.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
1674 glMatrixMode(GL_MODELVIEW);
1675 /*gluLookAt(0.0, 0.0, 20.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);*/
1683 /* Returns the new dst_dir for the given src_dir and dst_dir */
1684 int cross_product(int src_dir, int dst_dir) {
1685 return X_MASK*(GETSCALAR(src_dir,Y_MASK) * GETSCALAR(dst_dir,Z_MASK) -
1686 GETSCALAR(src_dir,Z_MASK) * GETSCALAR(dst_dir,Y_MASK))+
1687 Y_MASK*(GETSCALAR(src_dir,Z_MASK) * GETSCALAR(dst_dir,X_MASK) -
1688 GETSCALAR(src_dir,X_MASK) * GETSCALAR(dst_dir,Z_MASK))+
1689 Z_MASK*(GETSCALAR(src_dir,X_MASK) * GETSCALAR(dst_dir,Y_MASK) -
1690 GETSCALAR(src_dir,Y_MASK) * GETSCALAR(dst_dir,X_MASK));
1693 /* calculate orthogonal snake metrics
1694 * is_legal = true if model does not pass through itself
1695 * is_cyclic = true if last node connects back to first node
1696 * last_turn = for cyclic snakes, specifes what the 24th turn would be
1698 void calc_snake_metrics(void) {
1701 int prevSrcDir = -Y_MASK;
1702 int prevDstDir = Z_MASK;
1703 int grid[25][25][25];
1706 memset(&grid, 0, sizeof(int) * 25*25*25);
1711 /* trace path of snake - and keep record for is_legal */
1712 for (i = 0; i < NODE_COUNT - 1; i++) {
1713 /*int ang_card;*/ /* cardinal direction of node angle */
1714 /* establish new state vars */
1715 srcDir = -prevDstDir;
1716 x += GETSCALAR(prevDstDir, X_MASK);
1717 y += GETSCALAR(prevDstDir, Y_MASK);
1718 z += GETSCALAR(prevDstDir, Z_MASK);
1720 switch ((int) model[glc->next_model].node[i]) {
1722 dstDir = -prevSrcDir;
1725 dstDir = prevSrcDir;
1729 dstDir = cross_product(prevSrcDir, prevDstDir);
1730 if (model[glc->next_model].node[i] == (int) (RIGHT))
1734 /* Prevent spurious "might be used
1735 * uninitialised" warnings when compiling
1741 if (grid[x][y][z] == 0)
1742 grid[x][y][z] = srcDir + dstDir;
1743 else if (grid[x][y][z] + srcDir + dstDir == 0)
1748 prevSrcDir = srcDir;
1749 prevDstDir = dstDir;
1752 /* determine if the snake is cyclic */
1753 glc->is_cyclic = (dstDir == Y_MASK && x == 12 && y == 11 && z == 12);
1755 /* determine last_turn */
1756 glc->last_turn = -1;
1759 case -Z_MASK: glc->last_turn = ZERO; break;
1760 case Z_MASK: glc->last_turn = PIN; break;
1761 case X_MASK: glc->last_turn = LEFT; break;
1762 case -X_MASK: glc->last_turn = RIGHT; break;
1766 /* work out how far through the current morph we are */
1767 float morph_percent(void) {
1771 /* extend this function later with a case statement for each of the
1774 /* when morphing all nodes at once, the longest morph will be the node
1775 * that needs to rotate 180 degrees. For each node, work out how far it
1776 * has to go, and store the maximum rotation and current largest angular
1777 * difference, returning the angular difference over the maximum. */
1779 float rot_max = 0.0, ang_diff_max = 0.0;
1781 for (i = 0; i < NODE_COUNT - 1; i++) {
1782 float rot, ang_diff;
1784 /* work out the maximum rotation this node has to go through
1785 * from the previous to the next model, taking into account that
1786 * the snake always morphs through the smaller angle */
1787 rot = fabs(model[glc->prev_model].node[i] -
1788 model[glc->next_model].node[i]);
1789 if (rot > 180.0) rot = 180.0 - rot;
1790 /* work out the difference between the current position and the
1792 ang_diff = fabs(glc->node[i] -
1793 model[glc->next_model].node[i]);
1794 if (ang_diff > 180.0) ang_diff = 180 - ang_diff;
1795 /* if it's the biggest so far, record it */
1796 if (rot > rot_max) rot_max = rot;
1797 if (ang_diff > ang_diff_max) ang_diff_max = ang_diff;
1800 /* ang_diff / rot approaches 0, we want the complement */
1801 retval = 1.0 - (ang_diff_max / rot_max);
1802 /* protect against naan */
1804 /* Apparently some systems (Solaris) don't have isinf() */
1806 #define isinf(x) (((x) > 999999999999.9) || ((x) < -999999999999.9))
1808 if (isnan(retval) || isinf(retval)) retval = 1.0;
1810 /*printf("morph_pct = %f\n", retval);*/
1814 void morph_colour(void) {
1815 float percent, compct; /* complement of percentage */
1817 percent = morph_percent();
1818 compct = 1.0 - percent;
1820 glc->colour[0][0] = colour[glc->prev_colour][0][0] * compct + colour[glc->next_colour][0][0] * percent;
1821 glc->colour[0][1] = colour[glc->prev_colour][0][1] * compct + colour[glc->next_colour][0][1] * percent;
1822 glc->colour[0][2] = colour[glc->prev_colour][0][2] * compct + colour[glc->next_colour][0][2] * percent;
1824 glc->colour[1][0] = colour[glc->prev_colour][1][0] * compct + colour[glc->next_colour][1][0] * percent;
1825 glc->colour[1][1] = colour[glc->prev_colour][1][1] * compct + colour[glc->next_colour][1][1] * percent;
1826 glc->colour[1][2] = colour[glc->prev_colour][1][2] * compct + colour[glc->next_colour][1][2] * percent;
1829 /* Start morph process to this model */
1830 void start_morph(int model_index, int immediate) {
1831 /* if immediate, don't bother morphing, go straight to the next model */
1835 for (i = 0; i < NODE_COUNT; i++)
1836 glc->node[i] = model[model_index].node[i];
1839 glc->prev_model = glc->next_model;
1840 glc->next_model = model_index;
1841 glc->prev_colour = glc->next_colour;
1843 calc_snake_metrics();
1845 glc->next_colour = COLOUR_INVALID;
1847 glc->next_colour = COLOUR_AUTHENTIC;
1848 else if (glc->is_cyclic)
1849 glc->next_colour = COLOUR_CYCLIC;
1851 glc->next_colour = COLOUR_ACYCLIC;
1854 glc->colour[0][0] = colour[glc->next_colour][0][0];
1855 glc->colour[0][1] = colour[glc->next_colour][0][1];
1856 glc->colour[0][2] = colour[glc->next_colour][0][2];
1857 glc->colour[1][0] = colour[glc->next_colour][1][0];
1858 glc->colour[1][1] = colour[glc->next_colour][1][1];
1859 glc->colour[1][2] = colour[glc->next_colour][1][2];
1866 /* Returns morph progress */
1867 float morph(long iter_msec) {
1868 /* work out the maximum angle for this iteration */
1870 float iter_angle_max, largest_diff, largest_progress;
1876 iter_angle_max = 90.0 * (angvel/1000.0) * iter_msec;
1879 largest_diff = largest_progress = 0.0;
1880 for (i = 0; i < NODE_COUNT; i++) {
1881 float curAngle = glc->node[i];
1882 float destAngle = model[glc->next_model].node[i];
1883 if (curAngle != destAngle) {
1885 if (fabs(curAngle-destAngle) <= iter_angle_max)
1886 glc->node[i] = destAngle;
1887 else if (fmod(curAngle-destAngle+360,360) > 180)
1888 glc->node[i] = fmod(curAngle + iter_angle_max, 360);
1890 glc->node[i] = fmod(curAngle+360 - iter_angle_max, 360);
1891 largest_diff = MAX(largest_diff, fabs(destAngle-glc->node[i]));
1892 largest_progress = MAX(largest_diff, fabs(glc->node[i] - model[glc->prev_model].node[i]));
1896 return MIN(largest_diff / largest_progress, 1.0);
1900 void glsnake_idle();
1902 void restore_idle(int value)
1904 glutIdleFunc(glsnake_idle);
1908 void quick_sleep(void)
1911 /* By using glutTimerFunc we can keep responding to
1912 * mouse and keyboard events, unlike using something like
1915 glutTimerFunc(1, restore_idle, 0);
1923 struct glsnake_cfg * bp
1926 /* time since last iteration */
1928 /* time since the beginning of last morph */
1930 float iter_angle_max;
1931 snaketime current_time;
1932 /* morphFunc transition; */
1936 /* Do nothing to the model if we are paused */
1938 /* Avoid busy waiting when nothing is changing */
1942 glutPostRedisplay();
1947 /* <spiv> Well, ftime gives time with millisecond resolution.
1948 * <spiv> (or worse, perhaps... who knows what the OS will do)
1949 * <spiv> So if no discernable amount of time has passed:
1950 * <spiv> a) There's no point updating the screen, because
1951 * it would be the same
1952 * <spiv> b) The code will divide by zero
1954 gettime(¤t_time);
1956 iter_msec = (long) GETMSECS(current_time) - GETMSECS(glc->last_iteration) +
1957 ((long) GETSECS(current_time) - GETSECS(glc->last_iteration)) * 1000L;
1960 /* save the current time */
1961 memcpy(&glc->last_iteration, ¤t_time, sizeof(snaketime));
1963 /* work out if we have to switch models */
1964 morf_msec = GETMSECS(glc->last_iteration) - GETMSECS(glc->last_morph) +
1965 ((long) (GETSECS(glc->last_iteration)-GETSECS(glc->last_morph)) * 1000L);
1967 if ((morf_msec > statictime) && !interactive && !glc->morphing) {
1968 /*printf("starting morph\n");*/
1969 memcpy(&glc->last_morph, &(glc->last_iteration), sizeof(glc->last_morph));
1970 start_morph(RAND(models), 0);
1973 if (interactive && !glc->morphing) {
1978 /* if (!glc->dragging && !glc->interactive) { */
1981 yspin += 360/((1000/yangvel)/iter_msec);
1982 zspin += 360/((1000/zangvel)/iter_msec);
1984 yspin += 360 * (yangvel/1000.0) * iter_msec;
1985 zspin += 360 * (zangvel/1000.0) * iter_msec;
1988 /*printf("yspin: %f, zspin: %f\n", yspin, zspin);*/
1992 /* work out the maximum angle we could turn this node in this
1993 * timeslice, iter_msec milliseconds long */
1994 iter_angle_max = 90.0 * (angvel/1000.0) * iter_msec;
1997 for (i = 0; i < NODE_COUNT; i++) {
1998 float cur_angle = glc->node[i];
1999 float dest_angle = model[glc->next_model].node[i];
2000 if (cur_angle != dest_angle) {
2002 if (fabs(cur_angle - dest_angle) <= iter_angle_max)
2003 glc->node[i] = dest_angle;
2004 else if (fmod(cur_angle - dest_angle + 360, 360) > 180)
2005 glc->node[i] = fmod(cur_angle + iter_angle_max, 360);
2007 glc->node[i] = fmod(cur_angle + 360 - iter_angle_max, 360);
2011 if (!still_morphing)
2014 /* colour cycling */
2019 glutPostRedisplay();
2022 /* We are going too fast, so we may as well let the
2023 * cpu relax a little by sleeping for a millisecond. */
2029 void glsnake_display(
2035 struct glsnake_cfg * bp = &glc[MI_SCREEN(mi)];
2036 Display * dpy = MI_DISPLAY(mi);
2037 Window window = MI_WINDOW(mi);
2042 float positions[NODE_COUNT][4]; /* origin points for each node */
2043 float com[4]; /* it's the CENTRE of MASS */
2046 if (!bp->glx_context)
2050 /* clear the buffer */
2051 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2053 /* go into the modelview stack */
2054 glMatrixMode(GL_MODELVIEW);
2057 /* get the centre of each node, by moving through the snake and
2058 * performing the rotations, then grabbing the matrix at each point
2059 * and applying it to the origin */
2063 /* apply the mouse drag rotation */
2067 /* apply the continuous rotation */
2068 glRotatef(yspin, 0.0, 1.0, 0.0);
2069 glRotatef(zspin, 0.0, 0.0, 1.0);
2075 for (i = 0; i < NODE_COUNT; i++) {
2080 /*printf("ang = %f\n", ang);*/
2082 glTranslatef(0.5, 0.5, 0.5); /* move to center */
2083 glRotatef(90, 0.0, 0.0, -1.0); /* reorient */
2084 glTranslatef(1.0 + explode, 0.0, 0.0); /* move to new pos. */
2085 glRotatef(180 + ang, 1.0, 0.0, 0.0); /* pivot to new angle */
2086 glTranslatef(-0.5, -0.5, -0.5); /* return from center */
2088 glGetFloatv(GL_MODELVIEW_MATRIX, rotmat);
2090 matmult_origin(rotmat, positions[i]);
2092 /*printf("positions %f %f %f %f\n", positions[i][0], positions[i][1], positions[i][2], positions[i][3]);*/
2094 com[0] += positions[i][0];
2095 com[1] += positions[i][1];
2096 com[2] += positions[i][2];
2097 com[3] += positions[i][3];
2100 com[0] /= NODE_COUNT;
2101 com[1] /= NODE_COUNT;
2102 com[2] /= NODE_COUNT;
2103 com[3] /= NODE_COUNT;
2109 /*printf("com: %f, %f, %f, %f\n", com[0], com[1], com[2], com[3]);*/
2111 #if MAGICAL_RED_STRING
2113 glTranslatef(-com[0], -com[1], -com[2]);
2115 glDisable(GL_LIGHTING);
2116 glColor3f(1.0, 0.0, 0.0);
2117 glBegin(GL_LINE_STRIP);
2118 for (i = 0; i < NODE_COUNT - 1; i++) {
2119 glVertex3fv(positions[i]);
2122 glEnable(GL_LIGHTING);
2123 /*glTranslatef(com[0], com[1], com[2]);*/
2128 glTranslatef(-com[0], -com[1], -com[2]);
2131 /* apply the mouse drag rotation */
2135 /* apply the continuous rotation */
2136 glRotatef(yspin, 0.0, 1.0, 0.0);
2137 glRotatef(zspin, 0.0, 0.0, 1.0);
2139 /* now draw each node along the snake -- this is quite ugly :p */
2140 for (i = 0; i < NODE_COUNT; i++) {
2141 /* choose a colour for this node */
2142 if ((i == glc->selected || i == glc->selected+1) && interactive)
2144 glColor3f(1.0, 1.0, 0.0);
2146 glColor3fv(glc->colour[(i+1)%2]);
2150 glCallList(glc->node_wire);
2152 glCallList(glc->node_solid);
2154 /* now work out where to draw the next one */
2156 /* Interpolate between models */
2159 glTranslatef(0.5, 0.5, 0.5); /* move to center */
2160 glRotatef(90, 0.0, 0.0, -1.0); /* reorient */
2161 glTranslatef(1.0 + explode, 0.0, 0.0); /* move to new pos. */
2162 glRotatef(180 + ang, 1.0, 0.0, 0.0); /* pivot to new angle */
2163 glTranslatef(-0.5, -0.5, -0.5); /* return from center */
2183 glXSwapBuffers(dpy, window);
2188 /* anything that needs to be cleaned up goes here */
2190 glutDestroyWindow(glc->window);
2194 void ui_init(int *, char **);
2196 int main(int argc, char ** argv) {
2197 glc = malloc(sizeof(struct glsnake_cfg));
2198 memset(glc, 0, sizeof(struct glsnake_cfg));
2203 ui_init(&argc, argv);
2205 gettime(&glc->last_iteration);
2206 memcpy(&glc->last_morph, &glc->last_iteration, sizeof(snaketime));
2207 srand((unsigned int)GETSECS(glc->last_iteration));
2209 glc->prev_colour = glc->next_colour = COLOUR_ACYCLIC;
2210 glc->next_model = RAND(models);
2211 glc->prev_model = 0;
2212 start_morph(glc->prev_model, 1);
2230 /* trackball quaternions */
2231 float cumquat[4] = {0.0,0.0,0.0,0.0}, oldquat[4] = {0.0,0.0,0.0,0.1};
2233 /* rotation matrix */
2236 /* mouse drag vectors: start and end */
2237 float m_s[3], m_e[3];
2239 /* dragging boolean */
2242 /* this function calculates the rotation matrix based on the quaternions
2243 * generated from the mouse drag vectors */
2244 void calc_rotation() {
2246 double xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz;
2248 /* this bit ripped from Shoemake's quaternion notes from SIGGRAPH */
2249 Nq = cumquat[0] * cumquat[0] + cumquat[1] * cumquat[1] +
2250 cumquat[2] * cumquat[2] + cumquat[3] * cumquat[3];
2251 s = (Nq > 0.0) ? (2.0 / Nq) : 0.0;
2252 xs = cumquat[0] * s; ys = cumquat[1] * s; zs = cumquat[2] * s;
2253 wx = cumquat[3] * xs; wy = cumquat[3] * ys; wz = cumquat[3] * zs;
2254 xx = cumquat[0] * xs; xy = cumquat[0] * ys; xz = cumquat[0] * zs;
2255 yy = cumquat[1] * ys; yz = cumquat[1] * zs; zz = cumquat[2] * zs;
2257 rotation[0] = 1.0 - (yy + zz);
2258 rotation[1] = xy + wz;
2259 rotation[2] = xz - wy;
2260 rotation[4] = xy - wz;
2261 rotation[5] = 1.0 - (xx + zz);
2262 rotation[6] = yz + wx;
2263 rotation[8] = xz + wy;
2264 rotation[9] = yz - wx;
2265 rotation[10] = 1.0 - (xx + yy);
2266 rotation[3] = rotation[7] = rotation[11] = 0.0;
2267 rotation[12] = rotation[13] = rotation[14] = 0.0;
2271 inline void ui_mousedrag() {
2272 glMultMatrixf(rotation);
2275 void ui_keyboard(unsigned char c, int x, int y) {
2284 explode += DEF_EXPLODE;
2285 glutPostRedisplay();
2288 explode -= DEF_EXPLODE;
2289 if (explode < 0.0) explode = 0.0;
2290 glutPostRedisplay();
2295 glc->next_model %= models;
2296 start_morph(glc->next_model, 0);
2298 /* Reset last_morph time */
2299 gettime(&glc->last_morph);
2302 /* previous model */
2303 glc->next_model = (glc->next_model + models - 1) % models;
2304 start_morph(glc->next_model, 0);
2306 /* Reset glc->last_morph time */
2307 gettime(&glc->last_morph);
2310 angvel += DEF_ACCEL;
2313 if (angvel > DEF_ACCEL)
2314 angvel -= DEF_ACCEL;
2318 /* Reset last_iteration and last_morph time */
2319 gettime(&glc->last_iteration);
2320 gettime(&glc->last_morph);
2322 interactive = 1 - interactive;
2323 glutPostRedisplay();
2326 wireframe = 1 - wireframe;
2328 glDisable(GL_LIGHTING);
2330 glEnable(GL_LIGHTING);
2331 glutPostRedisplay();
2335 /* unpausing, reset last_iteration and last_morph time */
2336 gettime(&glc->last_iteration);
2337 gettime(&glc->last_morph);
2339 glc->paused = 1 - glc->paused;
2342 /* dump the current model so we can add it! */
2343 printf("# %s\nnoname:\t", model[glc->next_model].name);
2344 for (i = 0; i < NODE_COUNT; i++) {
2345 if (glc->node[i] == ZERO)
2347 else if (glc->node[i] == LEFT)
2349 else if (glc->node[i] == PIN)
2351 else if (glc->node[i] == RIGHT)
2355 printf("%f", node[i].curAngle);
2357 if (i < NODE_COUNT - 1)
2363 glc->fullscreen = 1 - glc->fullscreen;
2364 if (glc->fullscreen) {
2365 glc->old_width = glc->width;
2366 glc->old_height = glc->height;
2369 glutReshapeWindow(glc->old_width, glc->old_height);
2370 glutPositionWindow(50,50);
2374 titles = 1 - titles;
2375 if (interactive || glc->paused)
2376 glutPostRedisplay();
2379 altcolour = 1 - altcolour;
2383 glsnake_reshape(glc->width, glc->height);
2387 glsnake_reshape(glc->width, glc->height);
2394 void ui_special(int key, int x, int y) {
2396 float *destAngle = &(model[glc->next_model].node[glc->selected]);
2397 int unknown_key = 0;
2402 glc->selected = (glc->selected + (NODE_COUNT - 2)) % (NODE_COUNT - 1);
2405 glc->selected = (glc->selected + 1) % (NODE_COUNT - 1);
2408 *destAngle = fmod(*destAngle+(LEFT), 360);
2409 glc->morphing = glc->new_morph = 1;
2411 case GLUT_KEY_RIGHT:
2412 *destAngle = fmod(*destAngle+(RIGHT), 360);
2413 glc->morphing = glc->new_morph = 1;
2416 start_morph(STRAIGHT_MODEL, 0);
2423 calc_snake_metrics();
2426 glutPostRedisplay();
2429 void ui_mouse(int button, int state, int x, int y) {
2434 m_s[0] = M_SQRT1_2 *
2435 (x - (glc->width / 2.0)) / (glc->width / 2.0);
2436 m_s[1] = M_SQRT1_2 *
2437 ((glc->height / 2.0) - y) / (glc->height / 2.0);
2438 m_s[2] = sqrt(1-(m_s[0]*m_s[0]+m_s[1]*m_s[1]));
2442 oldquat[0] = cumquat[0];
2443 oldquat[1] = cumquat[1];
2444 oldquat[2] = cumquat[2];
2445 oldquat[3] = cumquat[3];
2451 glutPostRedisplay();
2454 void ui_motion(int x, int y) {
2459 /* construct the motion end vector from the x,y position on the
2461 m_e[0] = (x - (glc->width/ 2.0)) / (glc->width / 2.0);
2462 m_e[1] = ((glc->height / 2.0) - y) / (glc->height / 2.0);
2463 /* calculate the normal of the vector... */
2464 norm = m_e[0] * m_e[0] + m_e[1] * m_e[1];
2465 /* check if norm is outside the sphere and wraparound if necessary */
2469 m_e[2] = sqrt(norm - 1);
2471 /* the z value comes from projecting onto an elliptical spheroid */
2472 m_e[2] = sqrt(1 - norm);
2475 /* now here, build a quaternion from m_s and m_e */
2476 q[0] = m_s[1] * m_e[2] - m_s[2] * m_e[1];
2477 q[1] = m_s[2] * m_e[0] - m_s[0] * m_e[2];
2478 q[2] = m_s[0] * m_e[1] - m_s[1] * m_e[0];
2479 q[3] = m_s[0] * m_e[0] + m_s[1] * m_e[1] + m_s[2] * m_e[2];
2481 /* new rotation is the product of the new one and the old one */
2482 cumquat[0] = q[3] * oldquat[0] + q[0] * oldquat[3] +
2483 q[1] * oldquat[2] - q[2] * oldquat[1];
2484 cumquat[1] = q[3] * oldquat[1] + q[1] * oldquat[3] +
2485 q[2] * oldquat[0] - q[0] * oldquat[2];
2486 cumquat[2] = q[3] * oldquat[2] + q[2] * oldquat[3] +
2487 q[0] * oldquat[1] - q[1] * oldquat[0];
2488 cumquat[3] = q[3] * oldquat[3] - q[0] * oldquat[0] -
2489 q[1] * oldquat[1] - q[2] * oldquat[2];
2493 glutPostRedisplay();
2496 void ui_init(int * argc, char ** argv) {
2497 glutInit(argc, argv);
2498 glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
2499 glutInitWindowSize(glc->width, glc->height);
2500 glc->window = glutCreateWindow("glsnake");
2502 glutDisplayFunc(glsnake_display);
2503 glutReshapeFunc(glsnake_reshape);
2504 glutIdleFunc(glsnake_idle);
2505 glutKeyboardFunc(ui_keyboard);
2506 glutSpecialFunc(ui_special);
2507 glutMouseFunc(ui_mouse);
2508 glutMotionFunc(ui_motion);
2510 yangvel = DEF_YANGVEL;
2511 zangvel = DEF_ZANGVEL;
2512 explode = DEF_EXPLODE;
2513 angvel = DEF_ANGVEL;
2514 statictime = DEF_STATICTIME;
2515 altcolour = DEF_ALTCOLOUR;
2516 titles = DEF_TITLES;
2517 interactive = DEF_INTERACTIVE;
2519 wireframe = DEF_WIREFRAME;
2521 #endif /* HAVE_GLUT */