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 "*wireframe: False \n" \
142 "*explode: " DEF_EXPLODE " \n" \
143 "*angvel: " DEF_ANGVEL " \n" \
144 "*accel: " DEF_ACCEL " \n" \
145 "*statictime: " DEF_STATICTIME " \n" \
146 "*yangvel: " DEF_YANGVEL " \n" \
147 "*zangvel: " DEF_ZANGVEL " \n" \
148 "*altcolour: " DEF_ALTCOLOUR " \n" \
150 "*labelfont: -*-times-bold-r-normal-*-180-*\n" \
151 "*zoom: " DEF_ZOOM " \n" \
156 #define countof(x) (sizeof((x))/sizeof((*x)))
158 #include "xlockmore.h"
160 static XrmOptionDescRec opts[] = {
161 { "-explode", ".explode", XrmoptionSepArg, DEF_EXPLODE },
162 { "-angvel", ".angvel", XrmoptionSepArg, DEF_ANGVEL },
163 { "-accel", ".accel", XrmoptionSepArg, DEF_ACCEL },
164 { "-statictime", ".statictime", XrmoptionSepArg, DEF_STATICTIME },
165 { "-yangvel", ".yangvel", XrmoptionSepArg, DEF_YANGVEL },
166 { "-zangvel", ".zangvel", XrmoptionSepArg, DEF_ZANGVEL },
167 { "-altcolour", ".altcolour", XrmoptionNoArg, "True" },
168 { "-no-altcolour", ".altcolour", XrmoptionNoArg, "False" },
169 { "-titles", ".titles", XrmoptionNoArg, "True" },
170 { "-no-titles", ".titles", XrmoptionNoArg, "False" },
171 { "-zoom", ".zoom", XrmoptionSepArg, DEF_ZOOM },
172 { "-wireframe", ".wireframe", XrmoptionNoArg, "true" },
173 { "-no-wireframe", ".wireframe", XrmoptionNoArg, "false" },
176 static argtype vars[] = {
177 {&explode, "explode", "Explode", DEF_EXPLODE, t_Float},
178 {&angvel, "angvel", "Angular Velocity", DEF_ANGVEL, t_Float},
179 {&accel, "accel", "Acceleration", DEF_ACCEL, t_Float},
180 {&statictime, "statictime", "Static Time", DEF_STATICTIME, t_Int},
181 {&yangvel, "yangvel", "Angular Velocity about Y axis", DEF_YANGVEL, t_Float},
182 {&zangvel, "zangvel", "Angular Velocity about X axis", DEF_ZANGVEL, t_Float},
183 {&interactive, "interactive", "Interactive", DEF_INTERACTIVE, t_Bool},
184 {&altcolour, "altcolour", "Alternate Colour Scheme", DEF_ALTCOLOUR, t_Bool},
185 {&titles, "titles", "Titles", DEF_TITLES, t_Bool},
186 {&zoom, "zoom", "Zoom", DEF_ZOOM, t_Float},
187 {&wireframe, "wireframe", "Wireframe", DEF_WIREFRAME, t_Bool},
190 ModeSpecOpt sws_opts = {countof(opts), opts, countof(vars), vars, NULL};
195 float node[NODE_COUNT];
200 GLXContext * glx_context;
204 /* font list number */
211 /* is a morph in progress? */
214 /* has the model been paused? */
223 /* the shape of the model */
224 float node[NODE_COUNT];
226 /* currently selected node for interactive mode */
241 /* timing variables */
242 snaketime last_iteration;
243 snaketime last_morph;
247 int old_width, old_height;
249 /* the id of the display lists for drawing a node */
250 int node_solid, node_wire;
252 /* is the window fullscreen? */
256 #define COLOUR_CYCLIC 0
257 #define COLOUR_ACYCLIC 1
258 #define COLOUR_INVALID 2
259 #define COLOUR_AUTHENTIC 3
261 float colour[][2][3] = {
271 /* authentic - purple and green */
272 { { 0.38, 0.0, 0.55 },
276 struct model_s model[] = {
277 #define STRAIGHT_MODEL 0
279 { ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO,
280 ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO,
283 /* the models in the Rubik's snake manual */
284 #define START_MODEL 1
286 { RIGHT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT,
287 RIGHT, LEFT, LEFT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT,
288 RIGHT, LEFT, RIGHT, LEFT }
291 { RIGHT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, LEFT, RIGHT,
292 RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, LEFT, RIGHT, RIGHT, RIGHT,
293 RIGHT, LEFT, LEFT, LEFT }
296 { ZERO, ZERO, ZERO, RIGHT, LEFT, RIGHT, ZERO, LEFT, ZERO, ZERO,
297 ZERO, RIGHT, LEFT, RIGHT, ZERO, LEFT, ZERO, ZERO, ZERO, RIGHT,
298 LEFT, RIGHT, ZERO, LEFT }
301 { ZERO, PIN, ZERO, ZERO, ZERO, ZERO, ZERO, PIN, RIGHT, RIGHT, PIN,
302 RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, RIGHT, ZERO, ZERO,
306 { ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN,
307 ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, ZERO, ZERO, ZERO, ZERO,
311 { ZERO, ZERO, PIN, PIN, ZERO, LEFT, ZERO, LEFT, RIGHT, PIN, RIGHT,
312 ZERO, PIN, PIN, ZERO, RIGHT, PIN, RIGHT, LEFT, ZERO, LEFT, ZERO,
315 /* These models were taken from Andrew and Peter's original snake.c
316 * as well as some newer ones made up by Jamie, Andrew and Peter. */
318 { LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT,
319 LEFT, LEFT, LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT,
320 RIGHT, LEFT, LEFT, LEFT }
323 { RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT, RIGHT, RIGHT,
324 LEFT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT,
325 RIGHT, RIGHT, LEFT, LEFT }
328 { PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN,
329 ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN }
332 { PIN, LEFT, PIN, LEFT, PIN, LEFT, PIN, LEFT, PIN, LEFT, PIN,
333 LEFT, PIN, LEFT, PIN, LEFT, PIN, LEFT, PIN, LEFT, PIN, LEFT, PIN }
336 { RIGHT, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT,
337 LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, RIGHT, PIN,
341 { RIGHT, LEFT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT,
342 LEFT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT,
343 RIGHT, RIGHT, LEFT, LEFT }
346 { ZERO, RIGHT, LEFT, ZERO, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT,
347 LEFT, RIGHT, LEFT, LEFT, PIN, LEFT, LEFT, LEFT, RIGHT, LEFT,
348 RIGHT, RIGHT, RIGHT }
351 { RIGHT, PIN, ZERO, ZERO, PIN, LEFT, ZERO, LEFT, LEFT, ZERO,
352 LEFT, PIN, ZERO, ZERO, PIN, RIGHT, PIN, LEFT, PIN, ZERO, ZERO,
356 { PIN, RIGHT, LEFT, RIGHT, RIGHT, LEFT, PIN, LEFT, RIGHT, LEFT,
357 LEFT, RIGHT, PIN, RIGHT, LEFT, RIGHT, RIGHT, LEFT, PIN, LEFT,
361 { ZERO, ZERO, ZERO, ZERO, LEFT, ZERO, ZERO, RIGHT, ZERO, ZERO,
362 ZERO, ZERO, LEFT, ZERO, ZERO, RIGHT, ZERO, ZERO, ZERO, ZERO,
363 LEFT, ZERO, ZERO, RIGHT }
366 { ZERO, ZERO, LEFT, RIGHT, ZERO, LEFT, ZERO, RIGHT, ZERO, ZERO,
367 LEFT, RIGHT, ZERO, LEFT, ZERO, RIGHT, ZERO, ZERO, LEFT, RIGHT,
368 ZERO, LEFT, ZERO, RIGHT }
371 { ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, LEFT, RIGHT, ZERO, ZERO,
372 ZERO, ZERO, ZERO, ZERO, LEFT, RIGHT, ZERO, ZERO, ZERO, ZERO,
373 ZERO, ZERO, LEFT, RIGHT }
376 { ZERO, LEFT, PIN, RIGHT, RIGHT, PIN, ZERO, LEFT, PIN, RIGHT,
377 RIGHT, PIN, ZERO, LEFT, PIN, RIGHT, RIGHT, PIN, ZERO, LEFT, PIN,
381 { ZERO, PIN, PIN, ZERO, PIN, ZERO, PIN, PIN, ZERO, PIN, ZERO, PIN,
382 PIN, ZERO, PIN, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO, ZERO, PIN }
385 { PIN, RIGHT, LEFT, PIN, LEFT, PIN, ZERO, ZERO, RIGHT, PIN, LEFT,
386 ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO,
390 { ZERO, ZERO, ZERO, ZERO, RIGHT, RIGHT, ZERO, LEFT, PIN, RIGHT,
391 ZERO, RIGHT, ZERO, RIGHT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT,
395 { RIGHT, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, PIN, PIN, ZERO,
396 LEFT, ZERO, LEFT, PIN, RIGHT, ZERO, LEFT, LEFT, LEFT, PIN, RIGHT,
400 { ZERO, ZERO, ZERO, ZERO, PIN, PIN, ZERO, PIN, ZERO, ZERO, PIN,
401 ZERO, PIN, PIN, ZERO, ZERO, ZERO, PIN, ZERO, PIN, PIN, ZERO, PIN }
404 { RIGHT, RIGHT, LEFT, LEFT, RIGHT, PIN, RIGHT, PIN, LEFT, PIN,
405 RIGHT, ZERO, LEFT, ZERO, LEFT, PIN, RIGHT, ZERO, LEFT, LEFT,
409 { LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, ZERO, ZERO, ZERO,
410 RIGHT, ZERO, ZERO, LEFT, RIGHT, ZERO, ZERO, ZERO, LEFT, LEFT,
411 RIGHT, LEFT, RIGHT, RIGHT }
414 { LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, ZERO, PIN, ZERO, ZERO,
415 LEFT, PIN, RIGHT, ZERO, ZERO, PIN, ZERO, LEFT, LEFT, RIGHT, LEFT,
419 { ZERO, PIN, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, ZERO, ZERO,
420 RIGHT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT,
424 { LEFT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT,
425 ZERO, ZERO, ZERO, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN,
429 { RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, PIN,
430 LEFT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, LEFT,
434 { RIGHT, PIN, RIGHT, RIGHT, RIGHT, PIN, LEFT, LEFT, LEFT, PIN,
435 LEFT, PIN, RIGHT, PIN, RIGHT, RIGHT, RIGHT, PIN, LEFT, LEFT,
436 LEFT, PIN, LEFT, PIN }
439 { ZERO, PIN, RIGHT, RIGHT, RIGHT, PIN, LEFT, LEFT, LEFT, PIN,
440 ZERO, PIN, ZERO, PIN, RIGHT, RIGHT, RIGHT, PIN, LEFT, LEFT, LEFT,
444 { ZERO, PIN, ZERO, RIGHT, RIGHT, PIN, LEFT, LEFT, ZERO, PIN,
445 ZERO, PIN, ZERO, PIN, ZERO, RIGHT, RIGHT, PIN, LEFT, LEFT, ZERO,
449 { ZERO, PIN, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, PIN,
450 ZERO, PIN, ZERO, PIN, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO,
454 { ZERO, RIGHT, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, LEFT,
455 ZERO, PIN, ZERO, RIGHT, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO,
459 { ZERO, ZERO, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, ZERO,
460 ZERO, PIN, ZERO, ZERO, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO,
464 { ZERO, ZERO, ZERO, RIGHT, RIGHT, PIN, LEFT, LEFT, ZERO, ZERO,
465 ZERO, PIN, ZERO, ZERO, ZERO, RIGHT, RIGHT, PIN, LEFT, LEFT, ZERO,
469 { RIGHT, ZERO, ZERO, RIGHT, RIGHT, PIN, LEFT, LEFT, ZERO, ZERO,
470 LEFT, PIN, RIGHT, ZERO, ZERO, RIGHT, RIGHT, PIN, LEFT, LEFT,
471 ZERO, ZERO, LEFT, PIN }
474 { RIGHT, ZERO, LEFT, RIGHT, RIGHT, PIN, LEFT, LEFT, RIGHT,
475 ZERO, LEFT, PIN, RIGHT, ZERO, LEFT, RIGHT, RIGHT, PIN, LEFT,
476 LEFT, RIGHT, ZERO, LEFT, PIN }
479 { RIGHT, ZERO, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, ZERO,
480 LEFT, PIN, RIGHT, ZERO, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT,
484 { ZERO, ZERO, RIGHT, ZERO, ZERO, PIN, ZERO, ZERO, LEFT, ZERO,
485 ZERO, PIN, ZERO, ZERO, RIGHT, ZERO, ZERO, PIN, ZERO, ZERO, LEFT,
489 { ZERO, ZERO, PIN, PIN, ZERO, RIGHT, PIN, LEFT, PIN, RIGHT, PIN,
490 RIGHT, PIN, LEFT, PIN, RIGHT, ZERO, ZERO, PIN, ZERO, ZERO, LEFT,
494 { LEFT, PIN, LEFT, PIN, ZERO, PIN, PIN, ZERO, PIN, ZERO, LEFT,
495 PIN, RIGHT, ZERO, PIN, ZERO, PIN, PIN, ZERO, ZERO, LEFT, PIN,
499 { RIGHT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, ZERO, ZERO,
500 ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, ZERO, RIGHT, RIGHT, LEFT,
501 RIGHT, LEFT, LEFT, LEFT, PIN }
504 { ZERO, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, ZERO, RIGHT,
505 RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, PIN, ZERO, LEFT, RIGHT,
506 PIN, LEFT, LEFT, LEFT }
509 { PIN, LEFT, RIGHT, LEFT, LEFT, PIN, RIGHT, ZERO, RIGHT, LEFT,
510 ZERO, PIN, LEFT, LEFT, RIGHT, RIGHT, RIGHT, PIN, LEFT, ZERO,
514 { PIN, PIN, ZERO, ZERO, PIN, ZERO, ZERO, RIGHT, ZERO, RIGHT,
515 RIGHT, PIN, RIGHT, RIGHT, ZERO, RIGHT, ZERO, ZERO, PIN, ZERO,
516 ZERO, PIN, PIN, ZERO }
519 /* the following modesl were created during the slug/compsoc codefest
522 { PIN, PIN, ZERO, ZERO, RIGHT, ZERO, ZERO, PIN, PIN, ZERO, LEFT,
523 ZERO, ZERO, PIN, ZERO, PIN, PIN, ZERO, LEFT, RIGHT, PIN, ZERO,
527 { ZERO, ZERO, ZERO, ZERO, PIN, RIGHT, ZERO, PIN, PIN, ZERO, PIN,
528 PIN, ZERO, RIGHT, RIGHT, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO,
532 { RIGHT, RIGHT, PIN, RIGHT, LEFT, RIGHT, PIN, RIGHT, LEFT,
533 RIGHT, PIN, RIGHT, LEFT, RIGHT, PIN, RIGHT, LEFT, RIGHT, PIN,
534 RIGHT, LEFT, RIGHT, PIN, ZERO }
537 { ZERO, ZERO, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO, ZERO, ZERO,
538 ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO,
542 { LEFT, ZERO, RIGHT, LEFT, RIGHT, ZERO, LEFT, RIGHT, LEFT, ZERO,
543 RIGHT, LEFT, RIGHT, ZERO, LEFT, RIGHT, LEFT, ZERO, RIGHT, LEFT,
544 RIGHT, ZERO, LEFT, ZERO }
547 { ZERO, PIN, PIN, ZERO, ZERO, ZERO, PIN, PIN, ZERO, LEFT, ZERO,
548 PIN, PIN, ZERO, RIGHT, LEFT, ZERO, PIN, ZERO, PIN, PIN, ZERO,
552 { ZERO, ZERO, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, ZERO, ZERO,
553 ZERO, PIN, ZERO, ZERO, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, ZERO,
557 { PIN, ZERO, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, ZERO, ZERO,
558 ZERO, PIN, ZERO, ZERO, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, ZERO,
561 { "erect penis", /* thanks benno */
562 { PIN, ZERO, PIN, PIN, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, PIN,
563 PIN, ZERO, ZERO, ZERO, RIGHT, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO,
567 { PIN, ZERO, PIN, PIN, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, PIN,
568 PIN, ZERO, ZERO, ZERO, RIGHT, PIN, ZERO, ZERO, ZERO, ZERO, ZERO,
572 { RIGHT, ZERO, ZERO, ZERO, RIGHT, ZERO, ZERO, PIN, ZERO, ZERO,
573 LEFT, ZERO, ZERO, ZERO, LEFT, ZERO, LEFT, PIN, LEFT, PIN, RIGHT,
577 { ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, PIN, ZERO, ZERO, PIN,
578 ZERO, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, ZERO, PIN, ZERO,
581 { "poles or columns or something",
582 { LEFT, RIGHT, LEFT, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO,
583 ZERO, LEFT, RIGHT, LEFT, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO,
587 { ZERO, LEFT, ZERO, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO,
588 ZERO, LEFT, ZERO, LEFT, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO,
592 { ZERO, LEFT, ZERO, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO, ZERO,
593 LEFT, ZERO, RIGHT, ZERO, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO,
597 { ZERO, ZERO, ZERO, ZERO, ZERO, LEFT, ZERO, ZERO, ZERO, ZERO,
598 LEFT, RIGHT, ZERO, ZERO, ZERO, ZERO, LEFT, RIGHT, ZERO, ZERO,
599 LEFT, PIN, ZERO, ZERO }
602 { ZERO, ZERO, PIN, RIGHT, ZERO, LEFT, ZERO, ZERO, RIGHT, ZERO,
603 LEFT, PIN, ZERO, ZERO, PIN, ZERO, LEFT, ZERO, RIGHT, LEFT, ZERO,
607 { PIN, ZERO, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO,
608 RIGHT, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, ZERO,
612 { PIN, ZERO, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO,
613 ZERO, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, ZERO,
617 { PIN, ZERO, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO,
618 LEFT, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, ZERO,
622 { PIN, ZERO, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO,
623 PIN, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, ZERO,
627 { RIGHT, ZERO, ZERO, LEFT, ZERO, LEFT, RIGHT, ZERO, RIGHT, LEFT,
628 RIGHT, PIN, RIGHT, LEFT, RIGHT, ZERO, RIGHT, LEFT, ZERO, LEFT,
629 ZERO, ZERO, RIGHT, ZERO }
632 { RIGHT, ZERO, RIGHT, ZERO, RIGHT, ZERO, RIGHT, ZERO, RIGHT,
633 ZERO, RIGHT, ZERO, RIGHT, LEFT, RIGHT, PIN, ZERO, RIGHT, ZERO,
634 RIGHT, ZERO, RIGHT, ZERO, ZERO }
637 /* These models come from the website at
638 * http://www.geocities.com/stigeide/snake */
640 { RIGHT, LEFT, RIGHT, ZERO, PIN, ZERO, LEFT, RIGHT, LEFT, PIN, ZERO, ZERO, PIN, LEFT, RIGHT, LEFT, ZERO, PIN, ZERO, RIGHT, LEFT, RIGHT, ZERO }
643 { LEFT, RIGHT, ZERO, RIGHT, LEFT, ZERO, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, PIN, RIGHT, LEFT, PIN }
646 { LEFT, RIGHT, ZERO, RIGHT, LEFT, ZERO, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT }
649 { LEFT, RIGHT, ZERO, RIGHT, LEFT, ZERO, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN }
652 { ZERO, ZERO, PIN, LEFT, RIGHT, LEFT, ZERO, RIGHT, LEFT, RIGHT, ZERO, PIN, ZERO, LEFT, RIGHT, LEFT, ZERO, RIGHT, LEFT, RIGHT, PIN, ZERO, ZERO }
655 { RIGHT, LEFT, RIGHT, PIN, ZERO, ZERO, PIN, RIGHT, LEFT, RIGHT, ZERO, PIN, PIN, ZERO, LEFT, LEFT, RIGHT, RIGHT, LEFT, LEFT, ZERO, PIN, PIN }
658 { ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, ZERO, RIGHT, LEFT }
661 { LEFT, PIN, RIGHT, ZERO, ZERO, PIN, RIGHT, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, PIN, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, LEFT, PIN, ZERO }
664 { LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT }
667 { ZERO, RIGHT, RIGHT, ZERO, RIGHT, RIGHT, ZERO, RIGHT, LEFT, ZERO, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, LEFT, RIGHT, PIN, LEFT, LEFT, ZERO, LEFT }
670 { PIN, LEFT, RIGHT, ZERO, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, ZERO, LEFT, RIGHT, PIN, RIGHT }
673 { PIN, PIN, LEFT, ZERO, PIN, PIN, ZERO, LEFT, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, RIGHT, PIN, PIN }
676 { LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT }
679 { RIGHT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, LEFT, LEFT }
682 { ZERO, PIN, ZERO, PIN, PIN, ZERO, PIN, ZERO, ZERO, PIN, ZERO, PIN, PIN, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, PIN }
685 { PIN, LEFT, ZERO, PIN, PIN, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, PIN, RIGHT, PIN, LEFT, ZERO, ZERO, RIGHT, PIN, LEFT, PIN, ZERO, ZERO }
688 { RIGHT, ZERO, PIN, RIGHT, PIN, RIGHT, ZERO, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, ZERO, RIGHT, PIN, RIGHT, ZERO, ZERO, LEFT }
691 { LEFT, PIN, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, PIN, RIGHT }
694 { ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO }
697 { RIGHT, ZERO, ZERO, PIN, LEFT, ZERO, PIN, PIN, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, LEFT, LEFT, PIN, RIGHT, RIGHT, LEFT, PIN, ZERO, ZERO }
700 { PIN, ZERO, ZERO, PIN, LEFT, LEFT, PIN, RIGHT, RIGHT, PIN, ZERO, ZERO, PIN, ZERO, ZERO, PIN, LEFT, LEFT, PIN, RIGHT, RIGHT, PIN, ZERO }
703 { RIGHT, LEFT, RIGHT, RIGHT, RIGHT, LEFT, RIGHT, ZERO, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, ZERO, LEFT, RIGHT, LEFT, LEFT }
706 { RIGHT, RIGHT, RIGHT, PIN, LEFT, PIN, LEFT, PIN, RIGHT, RIGHT, RIGHT, PIN, LEFT, LEFT, LEFT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, LEFT, LEFT }
709 { RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT }
712 { ZERO, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, LEFT, LEFT, ZERO, LEFT, RIGHT, ZERO, ZERO, PIN, ZERO, ZERO, RIGHT }
715 { LEFT, ZERO, PIN, ZERO, PIN, LEFT, ZERO, PIN, ZERO, LEFT, LEFT, PIN, RIGHT, RIGHT, ZERO, PIN, ZERO, RIGHT, PIN, ZERO, PIN, ZERO, RIGHT }
718 { ZERO, LEFT, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, ZERO, ZERO, LEFT, ZERO, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, LEFT }
721 { ZERO, ZERO, PIN, ZERO, ZERO, LEFT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, PIN, RIGHT, PIN, LEFT, ZERO, PIN, PIN, ZERO, ZERO, LEFT, PIN }
724 { LEFT, PIN, RIGHT, ZERO, ZERO, PIN, PIN, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, RIGHT, ZERO, ZERO, ZERO }
727 { ZERO, PIN, ZERO, PIN, PIN, ZERO, LEFT, PIN, RIGHT, ZERO, PIN, PIN, ZERO, PIN, ZERO, PIN, PIN, ZERO, LEFT, PIN, RIGHT, ZERO, PIN }
730 { PIN, RIGHT, ZERO, ZERO, PIN, ZERO, ZERO, PIN, PIN, ZERO, PIN, RIGHT, PIN, LEFT, PIN, ZERO, PIN, PIN, ZERO, ZERO, PIN, ZERO, ZERO }
733 { LEFT, ZERO, LEFT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, RIGHT, ZERO, RIGHT, PIN, RIGHT, PIN, LEFT }
736 { PIN, ZERO, ZERO, PIN, LEFT, LEFT, PIN, LEFT, RIGHT, RIGHT, PIN, LEFT, LEFT, RIGHT, PIN, RIGHT, RIGHT, PIN, ZERO, ZERO, PIN, RIGHT, PIN }
739 { RIGHT, PIN, ZERO, LEFT, LEFT, PIN, RIGHT, RIGHT, ZERO, PIN, LEFT, PIN, RIGHT, PIN, ZERO, LEFT, LEFT, PIN, RIGHT, RIGHT, ZERO, PIN, LEFT }
742 { ZERO, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, RIGHT, LEFT, PIN, LEFT, ZERO, PIN, PIN, ZERO, LEFT, PIN, LEFT, RIGHT, ZERO, RIGHT, ZERO, PIN }
744 { "Counterclockwise",
745 { LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT }
748 { LEFT, LEFT, ZERO, PIN, LEFT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, PIN, ZERO, RIGHT, RIGHT, LEFT, LEFT, ZERO, ZERO, RIGHT }
751 { ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, PIN, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, PIN, LEFT, PIN, RIGHT, ZERO, ZERO, ZERO, PIN, RIGHT }
754 { ZERO, PIN, ZERO, PIN, PIN, ZERO, PIN, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO, ZERO, PIN, ZERO, PIN, PIN, ZERO, PIN, ZERO, PIN }
757 { ZERO, ZERO, PIN, PIN, ZERO, LEFT, ZERO, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, ZERO, PIN, PIN, ZERO, LEFT, ZERO, ZERO, PIN, PIN, ZERO }
760 { ZERO, ZERO, PIN, PIN, ZERO, LEFT, ZERO, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, ZERO, PIN, PIN, ZERO, LEFT, ZERO, ZERO, PIN, PIN, ZERO }
763 { PIN, ZERO, RIGHT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, RIGHT, ZERO, PIN, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN }
766 { RIGHT, LEFT, PIN, LEFT, LEFT, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, LEFT, LEFT, PIN, LEFT, RIGHT }
769 { LEFT, ZERO, PIN, ZERO, RIGHT, ZERO, ZERO, LEFT, ZERO, PIN, ZERO, RIGHT, LEFT, ZERO, PIN, ZERO, RIGHT, ZERO, ZERO, LEFT, ZERO, PIN, ZERO }
772 { RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT }
775 { ZERO, RIGHT, ZERO, ZERO, LEFT, ZERO, ZERO, RIGHT, PIN, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, PIN, LEFT, ZERO, ZERO, RIGHT, ZERO, ZERO, LEFT }
778 { RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, ZERO, LEFT, RIGHT }
781 { ZERO, ZERO, PIN, PIN, ZERO, LEFT, LEFT, RIGHT, PIN, ZERO, PIN, PIN, ZERO, PIN, LEFT, RIGHT, RIGHT, ZERO, PIN, PIN, ZERO, ZERO, PIN }
784 { ZERO, ZERO, PIN, ZERO, ZERO, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, LEFT, LEFT, ZERO, PIN, ZERO, RIGHT, RIGHT, LEFT, PIN, LEFT, RIGHT }
787 { ZERO, LEFT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, LEFT, ZERO, LEFT, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT }
790 { ZERO, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO, ZERO, ZERO, LEFT, PIN, RIGHT, ZERO, ZERO, ZERO, ZERO, PIN }
793 { LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, LEFT, ZERO, LEFT, PIN, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT }
796 { LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, ZERO, RIGHT, ZERO, RIGHT, ZERO, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT }
799 { LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, LEFT, RIGHT, ZERO, RIGHT, LEFT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT }
802 { PIN, PIN, ZERO, ZERO, ZERO, ZERO, ZERO, LEFT, ZERO, ZERO, LEFT, RIGHT, ZERO, ZERO, LEFT, RIGHT, ZERO, ZERO, RIGHT, ZERO, ZERO, ZERO, ZERO }
805 { PIN, ZERO, ZERO, PIN, RIGHT, PIN, LEFT, PIN, ZERO, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, ZERO, PIN, RIGHT, PIN, LEFT, PIN, ZERO }
808 { ZERO, RIGHT, LEFT, ZERO, ZERO, ZERO, LEFT, RIGHT, ZERO, PIN, RIGHT, LEFT, ZERO, LEFT, RIGHT, LEFT, PIN, LEFT, RIGHT, LEFT, ZERO, LEFT, RIGHT }
811 { LEFT, LEFT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT }
814 { LEFT, LEFT, PIN, RIGHT, RIGHT, ZERO, LEFT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, PIN, RIGHT, PIN, LEFT, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT }
817 { RIGHT, RIGHT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, LEFT }
820 { RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, ZERO, RIGHT, LEFT, ZERO, ZERO, LEFT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT }
823 { ZERO, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, LEFT, PIN, RIGHT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, PIN, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT }
826 { LEFT, LEFT, RIGHT, PIN, ZERO, RIGHT, ZERO, LEFT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, ZERO, LEFT, ZERO, PIN, LEFT, RIGHT, RIGHT, RIGHT, PIN }
829 { PIN, ZERO, ZERO, PIN, PIN, ZERO, PIN, RIGHT, LEFT, RIGHT, RIGHT, PIN, LEFT, LEFT, RIGHT, LEFT, PIN, ZERO, PIN, PIN, ZERO, ZERO, PIN }
832 { ZERO, ZERO, LEFT, RIGHT, PIN, RIGHT, ZERO, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, ZERO, RIGHT, PIN, RIGHT, RIGHT, ZERO, PIN }
835 { ZERO, RIGHT, ZERO, PIN, LEFT, ZERO, LEFT, RIGHT, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, LEFT, RIGHT, ZERO, RIGHT, PIN, ZERO, LEFT, ZERO }
838 { ZERO, PIN, ZERO, ZERO, ZERO, ZERO, ZERO, PIN, LEFT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, LEFT, ZERO, ZERO, ZERO, PIN }
841 { ZERO, PIN, PIN, ZERO, PIN, RIGHT, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, RIGHT, ZERO, ZERO, PIN, ZERO, ZERO, PIN }
844 { ZERO, LEFT, PIN, RIGHT, ZERO, PIN, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT }
847 { LEFT, RIGHT, LEFT, RIGHT, RIGHT, PIN, LEFT, PIN, LEFT, RIGHT, RIGHT, PIN, LEFT, LEFT, RIGHT, RIGHT, PIN, LEFT, LEFT, RIGHT, PIN, RIGHT, PIN }
850 { LEFT, LEFT, RIGHT, RIGHT, LEFT, PIN, LEFT, PIN, RIGHT, PIN, LEFT, ZERO, RIGHT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, RIGHT, LEFT, RIGHT, RIGHT }
853 { LEFT, ZERO, LEFT, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, LEFT, RIGHT, PIN, LEFT, LEFT, RIGHT, ZERO, RIGHT }
856 { PIN, ZERO, LEFT, PIN, RIGHT, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, ZERO, PIN, ZERO, RIGHT, PIN, LEFT, ZERO, PIN, ZERO, ZERO, PIN }
859 { ZERO, ZERO, PIN, ZERO, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, LEFT, PIN, LEFT, LEFT, PIN, RIGHT, RIGHT, PIN, RIGHT, ZERO, PIN, PIN, ZERO }
862 { LEFT, LEFT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, ZERO, LEFT, RIGHT, ZERO, ZERO, LEFT, RIGHT }
865 { RIGHT, LEFT, ZERO, PIN, LEFT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, PIN, ZERO, RIGHT, LEFT, ZERO }
868 { PIN, PIN, ZERO, LEFT, RIGHT, LEFT, ZERO, PIN, RIGHT, PIN, LEFT, ZERO, ZERO, ZERO, ZERO, RIGHT, PIN, LEFT, PIN, ZERO, RIGHT, LEFT, RIGHT }
871 { PIN, ZERO, PIN, PIN, ZERO, ZERO, ZERO, ZERO, PIN, PIN, ZERO, PIN, LEFT, ZERO, PIN, PIN, ZERO, ZERO, ZERO, ZERO, PIN, PIN, ZERO }
874 { PIN, ZERO, RIGHT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, LEFT, PIN, RIGHT, RIGHT, PIN, RIGHT, LEFT, ZERO, ZERO }
877 { RIGHT, ZERO, ZERO, ZERO, PIN, LEFT, PIN, LEFT, RIGHT, RIGHT, ZERO, PIN, ZERO, LEFT, LEFT, RIGHT, PIN, RIGHT, PIN, ZERO, ZERO, ZERO, LEFT }
880 { ZERO, PIN, ZERO, ZERO, LEFT, ZERO, LEFT, ZERO, ZERO, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, ZERO, RIGHT, ZERO, RIGHT, ZERO, ZERO, PIN, ZERO }
883 { ZERO, ZERO, ZERO, ZERO, LEFT, ZERO, ZERO, RIGHT, ZERO, ZERO, ZERO, ZERO, LEFT, ZERO, ZERO, RIGHT, ZERO, ZERO, ZERO, ZERO, LEFT, ZERO, ZERO }
885 { "HoleInTheMiddle1",
886 { ZERO, LEFT, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, LEFT, RIGHT, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, RIGHT }
888 { "HoleInTheMiddle2",
889 { ZERO, LEFT, RIGHT, ZERO, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, RIGHT, LEFT, ZERO, LEFT, RIGHT, ZERO, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, RIGHT }
892 { RIGHT, RIGHT, PIN, LEFT, LEFT, LEFT, PIN, RIGHT, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, LEFT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, RIGHT, PIN }
895 { LEFT, PIN, LEFT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT }
898 { LEFT, LEFT, LEFT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, RIGHT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, RIGHT, LEFT, LEFT }
901 { RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT }
904 { ZERO, ZERO, ZERO, ZERO, PIN, RIGHT, ZERO, RIGHT, ZERO, ZERO, LEFT, PIN, RIGHT, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, RIGHT, ZERO, RIGHT }
907 { RIGHT, RIGHT, LEFT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, LEFT, LEFT, PIN, RIGHT, RIGHT, LEFT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, LEFT, LEFT }
910 { ZERO, PIN, PIN, ZERO, PIN, ZERO, PIN, PIN, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, PIN, PIN, ZERO, PIN, ZERO, PIN, PIN, ZERO }
913 { LEFT, LEFT, PIN, LEFT, ZERO, LEFT, RIGHT, LEFT, PIN, LEFT, LEFT, RIGHT, RIGHT, PIN, RIGHT, LEFT, RIGHT, ZERO, RIGHT, PIN, RIGHT, RIGHT, LEFT }
916 { ZERO, PIN, PIN, ZERO, ZERO, LEFT, ZERO, LEFT, ZERO, ZERO, PIN, ZERO, ZERO, RIGHT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO }
919 { RIGHT, PIN, LEFT, RIGHT, LEFT, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, RIGHT, LEFT, RIGHT, PIN, LEFT }
922 { PIN, ZERO, LEFT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, ZERO, PIN, ZERO, LEFT, PIN, LEFT, PIN, RIGHT, PIN, LEFT, ZERO, PIN, PIN, ZERO }
925 { PIN, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, RIGHT, LEFT, ZERO, LEFT }
928 { ZERO, ZERO, PIN, ZERO, LEFT, ZERO, PIN, PIN, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, ZERO, ZERO }
931 { ZERO, ZERO, ZERO, RIGHT, ZERO, RIGHT, LEFT, ZERO, LEFT, PIN, ZERO, PIN, ZERO, ZERO, PIN, ZERO, PIN, RIGHT, ZERO, RIGHT, LEFT, ZERO, LEFT }
934 { PIN, PIN, ZERO, ZERO, PIN, ZERO, RIGHT, PIN, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, PIN, LEFT, ZERO, PIN, PIN, ZERO, PIN, PIN }
937 { PIN, RIGHT, LEFT, ZERO, PIN, PIN, ZERO, ZERO, LEFT, RIGHT, ZERO, ZERO, PIN, ZERO, ZERO, LEFT, RIGHT, PIN, RIGHT, ZERO, PIN, PIN, ZERO }
940 { ZERO, LEFT, LEFT, PIN, RIGHT, ZERO, RIGHT, RIGHT, PIN, LEFT, LEFT, RIGHT, RIGHT, PIN, LEFT, LEFT, ZERO, LEFT, PIN, RIGHT, RIGHT, ZERO, RIGHT }
943 { ZERO, RIGHT, ZERO, RIGHT, LEFT, RIGHT, PIN, ZERO, LEFT, PIN, RIGHT, ZERO, PIN, LEFT, RIGHT, LEFT, ZERO, LEFT, ZERO, RIGHT, RIGHT, PIN, LEFT }
946 { LEFT, ZERO, PIN, PIN, ZERO, LEFT, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT }
949 { ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, LEFT, PIN, LEFT, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO }
952 { ZERO, PIN, ZERO, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, ZERO, PIN, ZERO }
954 { "MouseWithoutTail",
955 { ZERO, PIN, PIN, ZERO, LEFT, ZERO, PIN, PIN, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO }
958 { PIN, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, ZERO, LEFT, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, LEFT, ZERO, PIN }
961 { ZERO, ZERO, LEFT, ZERO, ZERO, ZERO, LEFT, ZERO, ZERO, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, ZERO, RIGHT, ZERO, ZERO, ZERO, RIGHT, ZERO, ZERO }
964 { LEFT, ZERO, PIN, LEFT, LEFT, RIGHT, RIGHT, PIN, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, LEFT }
967 { ZERO, RIGHT, PIN, LEFT, LEFT, LEFT, ZERO, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, ZERO, RIGHT, RIGHT, RIGHT, PIN, LEFT, ZERO }
970 { LEFT, PIN, RIGHT, PIN, RIGHT, ZERO, PIN, ZERO, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, RIGHT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, LEFT }
973 { PIN, ZERO, ZERO, ZERO, PIN, RIGHT, PIN, LEFT, PIN, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, ZERO, ZERO, ZERO }
976 { ZERO, ZERO, PIN, PIN, ZERO, LEFT, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, ZERO, ZERO, ZERO, ZERO, PIN }
979 { PIN, PIN, ZERO, PIN, LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, PIN, ZERO, PIN, ZERO, ZERO, PIN, ZERO }
982 { ZERO, PIN, ZERO, ZERO, PIN, ZERO, ZERO, PIN, ZERO, LEFT, ZERO, PIN, ZERO, RIGHT, ZERO, PIN, ZERO, ZERO, PIN, ZERO, ZERO, PIN, ZERO }
985 { ZERO, ZERO, ZERO, ZERO, RIGHT, RIGHT, ZERO, LEFT, PIN, RIGHT, ZERO, RIGHT, ZERO, RIGHT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, LEFT, ZERO, PIN }
988 { PIN, PIN, RIGHT, ZERO, PIN, PIN, ZERO, PIN, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, PIN, ZERO, PIN, PIN, ZERO, LEFT, PIN, PIN }
990 { "PictureCommingSoon",
991 { LEFT, LEFT, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, RIGHT, PIN, RIGHT, LEFT, ZERO, RIGHT, RIGHT }
994 { LEFT, PIN, ZERO, ZERO, PIN, ZERO, ZERO, PIN, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, PIN, ZERO, ZERO, PIN, ZERO, ZERO, PIN, RIGHT }
997 { LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, LEFT }
1000 { RIGHT, PIN, ZERO, ZERO, ZERO, ZERO, PIN, ZERO, ZERO, PIN, PIN, ZERO, PIN, LEFT, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, RIGHT }
1003 { ZERO, PIN, ZERO, PIN, RIGHT, PIN, ZERO, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, PIN, PIN, ZERO, ZERO, LEFT, ZERO, PIN, LEFT }
1006 { LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT }
1009 { RIGHT, PIN, ZERO, PIN, RIGHT, ZERO, PIN, PIN, ZERO, ZERO, LEFT, PIN, RIGHT, ZERO, ZERO, PIN, PIN, ZERO, LEFT, PIN, ZERO, PIN, LEFT }
1012 { ZERO, ZERO, ZERO, RIGHT, ZERO, LEFT, RIGHT, LEFT, ZERO, ZERO, ZERO, RIGHT, ZERO, LEFT, RIGHT, LEFT, ZERO, ZERO, ZERO, RIGHT, ZERO, LEFT, RIGHT }
1015 { ZERO, LEFT, PIN, RIGHT, ZERO, LEFT, PIN, RIGHT, ZERO, LEFT, PIN, RIGHT, ZERO, PIN, RIGHT, LEFT, LEFT, LEFT, PIN, RIGHT, RIGHT, RIGHT, LEFT }
1017 { "QuarterbackTiltedAndReadyToHut",
1018 { PIN, ZERO, RIGHT, RIGHT, LEFT, RIGHT, PIN, RIGHT, LEFT, RIGHT, ZERO, PIN, ZERO, LEFT, RIGHT, LEFT, PIN, LEFT, RIGHT, LEFT, LEFT, ZERO, PIN }
1021 { PIN, LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, ZERO, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT }
1024 { LEFT, ZERO, LEFT, ZERO, LEFT, ZERO, LEFT, LEFT, ZERO, LEFT, ZERO, LEFT, ZERO, LEFT, RIGHT, ZERO, PIN, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT }
1027 { ZERO, ZERO, ZERO, PIN, ZERO, ZERO, PIN, RIGHT, LEFT, LEFT, LEFT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, LEFT, PIN, ZERO, ZERO, PIN }
1030 { LEFT, LEFT, PIN, RIGHT, ZERO, PIN, ZERO, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, ZERO, PIN, ZERO, LEFT, PIN, RIGHT, RIGHT }
1033 { RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, PIN, ZERO, PIN, PIN, ZERO, PIN, ZERO, PIN, PIN, ZERO, PIN, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT }
1036 { RIGHT, ZERO, LEFT, PIN, RIGHT, ZERO, RIGHT, ZERO, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, ZERO, LEFT, ZERO, LEFT, PIN, RIGHT, ZERO, LEFT }
1039 { ZERO, LEFT, PIN, RIGHT, ZERO, PIN, LEFT, ZERO, PIN, ZERO, RIGHT, PIN, ZERO, LEFT, PIN, RIGHT, ZERO, PIN, LEFT, ZERO, PIN, ZERO, RIGHT }
1042 { PIN, PIN, RIGHT, ZERO, LEFT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, RIGHT, ZERO, LEFT, PIN, PIN }
1045 { RIGHT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, PIN, RIGHT, PIN, LEFT }
1048 { RIGHT, LEFT, PIN, ZERO, ZERO, ZERO, LEFT, RIGHT, LEFT, PIN, ZERO, ZERO, PIN, LEFT, RIGHT, LEFT, ZERO, ZERO, ZERO, PIN, LEFT, RIGHT, LEFT }
1051 { LEFT, LEFT, LEFT, PIN, RIGHT, RIGHT, RIGHT, ZERO, LEFT, PIN, RIGHT, ZERO, LEFT, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, PIN, PIN, ZERO, LEFT }
1054 { RIGHT, PIN, ZERO, LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, RIGHT, PIN, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, ZERO, LEFT, RIGHT, ZERO, ZERO }
1057 { RIGHT, LEFT, LEFT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, LEFT, LEFT, LEFT, RIGHT, LEFT }
1060 { LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, ZERO, ZERO, ZERO, ZERO, PIN, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, ZERO, RIGHT }
1063 { PIN, RIGHT, LEFT, LEFT, LEFT, LEFT, PIN, RIGHT, RIGHT, RIGHT, RIGHT, LEFT, ZERO, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, LEFT, ZERO, PIN, PIN }
1066 { LEFT, RIGHT, ZERO, RIGHT, LEFT, RIGHT, ZERO, RIGHT, LEFT, RIGHT, ZERO, RIGHT, LEFT, RIGHT, ZERO, RIGHT, LEFT, RIGHT, ZERO, RIGHT, LEFT, RIGHT, ZERO }
1069 { LEFT, RIGHT, LEFT, RIGHT, ZERO, LEFT, RIGHT, LEFT, PIN, ZERO, ZERO, PIN, ZERO, ZERO, PIN, RIGHT, LEFT, ZERO, ZERO, RIGHT, LEFT, RIGHT, LEFT }
1072 { ZERO, LEFT, RIGHT, ZERO, RIGHT, LEFT, ZERO, LEFT, RIGHT, ZERO, LEFT, RIGHT, ZERO, LEFT, RIGHT, ZERO, RIGHT, LEFT, ZERO, LEFT, RIGHT, ZERO, LEFT }
1074 { "SnakeReadyToStrike",
1075 { LEFT, ZERO, LEFT, ZERO, LEFT, ZERO, LEFT, RIGHT, ZERO, RIGHT, ZERO, RIGHT, ZERO, LEFT, ZERO, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, ZERO, LEFT }
1078 { RIGHT, RIGHT, PIN, ZERO, RIGHT, LEFT, RIGHT, ZERO, ZERO, ZERO, RIGHT, PIN, LEFT, PIN, ZERO, PIN, LEFT, PIN, RIGHT, ZERO, ZERO, LEFT, RIGHT }
1081 { ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, PIN, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, PIN, LEFT, PIN, RIGHT, ZERO, ZERO, ZERO, PIN, RIGHT }
1084 { PIN, PIN, LEFT, PIN, LEFT, PIN, RIGHT, ZERO, RIGHT, PIN, RIGHT, ZERO, RIGHT, PIN, LEFT, PIN, RIGHT, ZERO, PIN, PIN, ZERO, ZERO, PIN }
1087 { LEFT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, RIGHT }
1090 { ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, ZERO, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, ZERO, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO }
1093 { PIN, RIGHT, ZERO, PIN, ZERO, LEFT, PIN, RIGHT, PIN, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, PIN, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, PIN }
1096 { PIN, PIN, RIGHT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, PIN }
1099 { PIN, PIN, LEFT, PIN, LEFT, PIN, RIGHT, ZERO, PIN, PIN, ZERO, LEFT, PIN, RIGHT, ZERO, PIN, ZERO, LEFT, PIN, LEFT, LEFT, PIN, PIN }
1102 { LEFT, ZERO, ZERO, LEFT, PIN, RIGHT, ZERO, ZERO, LEFT, ZERO, ZERO, PIN, ZERO, ZERO, RIGHT, ZERO, ZERO, LEFT, PIN, RIGHT, ZERO, ZERO, RIGHT }
1105 { PIN, RIGHT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, ZERO, LEFT, PIN, RIGHT, ZERO, LEFT, LEFT, LEFT, RIGHT, RIGHT, LEFT, PIN, ZERO, RIGHT, PIN, LEFT }
1108 { RIGHT, RIGHT, ZERO, ZERO, LEFT, RIGHT, LEFT, PIN, ZERO, LEFT, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, RIGHT, LEFT, RIGHT, ZERO, ZERO, LEFT }
1111 { PIN, LEFT, ZERO, RIGHT, RIGHT, LEFT, PIN, ZERO, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, ZERO, PIN, RIGHT, LEFT, LEFT, ZERO }
1114 { ZERO, ZERO, LEFT, LEFT, PIN, RIGHT, RIGHT, ZERO, ZERO, LEFT, LEFT, PIN, RIGHT, RIGHT, ZERO, ZERO, LEFT, LEFT, PIN, RIGHT, RIGHT, ZERO, ZERO }
1117 { PIN, ZERO, PIN, ZERO, ZERO, PIN, PIN, ZERO, PIN, ZERO, ZERO, PIN, ZERO, ZERO, PIN, ZERO, PIN, PIN, ZERO, ZERO, PIN, ZERO, PIN }
1120 { RIGHT, ZERO, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, LEFT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, ZERO }
1123 { ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO }
1126 { ZERO, PIN, ZERO, PIN, ZERO, PIN, PIN, ZERO, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, PIN, ZERO, ZERO, PIN, ZERO }
1129 { ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO }
1132 { ZERO, PIN, ZERO, PIN, LEFT, LEFT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, RIGHT }
1135 { PIN, ZERO, PIN, RIGHT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, RIGHT, PIN, ZERO, ZERO, ZERO, ZERO, ZERO, PIN, PIN }
1138 { PIN, PIN, ZERO, ZERO, ZERO, RIGHT, ZERO, RIGHT, ZERO, ZERO, LEFT, PIN, RIGHT, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, RIGHT, ZERO, RIGHT }
1141 { RIGHT, RIGHT, PIN, ZERO, PIN, PIN, ZERO, PIN, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, PIN, ZERO, PIN, PIN, ZERO, PIN, LEFT, LEFT, RIGHT }
1144 { RIGHT, ZERO, LEFT, RIGHT, LEFT, ZERO, LEFT, RIGHT, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, LEFT, RIGHT, ZERO, RIGHT, LEFT, RIGHT, ZERO, LEFT }
1147 { ZERO, PIN, LEFT, LEFT, PIN, ZERO, ZERO, LEFT, PIN, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, PIN, LEFT }
1150 { ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, RIGHT, PIN, RIGHT, LEFT, ZERO, RIGHT, PIN }
1153 { ZERO, ZERO, RIGHT, LEFT, PIN, LEFT, ZERO, PIN, PIN, ZERO, LEFT, PIN, RIGHT, ZERO, PIN, PIN, ZERO, RIGHT, PIN, RIGHT, LEFT, ZERO, ZERO }
1156 { ZERO, ZERO, RIGHT, LEFT, PIN, LEFT, ZERO, PIN, PIN, ZERO, LEFT, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, RIGHT, PIN, RIGHT, LEFT, ZERO, ZERO }
1159 { RIGHT, ZERO, PIN, PIN, ZERO, LEFT, RIGHT, PIN, LEFT, LEFT, RIGHT, RIGHT, PIN, LEFT, LEFT, RIGHT, RIGHT, PIN, LEFT, LEFT, RIGHT, RIGHT, PIN }
1162 { RIGHT, ZERO, ZERO, RIGHT, LEFT, ZERO, ZERO, RIGHT, LEFT, ZERO, ZERO, LEFT, RIGHT, ZERO, ZERO, RIGHT, LEFT, ZERO, ZERO, RIGHT, LEFT, ZERO, ZERO }
1165 { RIGHT, LEFT, ZERO, RIGHT, LEFT, PIN, LEFT, LEFT, PIN, LEFT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT, PIN, RIGHT, RIGHT, PIN, RIGHT, LEFT }
1168 { PIN, ZERO, PIN, PIN, ZERO, PIN, ZERO, ZERO, ZERO, PIN, PIN, ZERO, PIN, ZERO, ZERO, PIN, ZERO, PIN, PIN, ZERO, ZERO, ZERO, ZERO }
1171 { RIGHT, ZERO, LEFT, RIGHT, ZERO, LEFT, PIN, RIGHT, ZERO, RIGHT, ZERO, PIN, ZERO, LEFT, ZERO, LEFT, PIN, RIGHT, ZERO, LEFT, RIGHT, ZERO, LEFT }
1174 { RIGHT, ZERO, ZERO, RIGHT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, RIGHT, PIN, LEFT, LEFT, PIN, LEFT, PIN, RIGHT, PIN, LEFT, ZERO, ZERO, LEFT }
1177 { ZERO, PIN, RIGHT, LEFT, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, PIN, PIN, ZERO, LEFT, LEFT, PIN, ZERO, LEFT, RIGHT, ZERO, PIN, ZERO, LEFT }
1180 { PIN, LEFT, LEFT, PIN, LEFT, ZERO, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, PIN, RIGHT, PIN, RIGHT, RIGHT, PIN, ZERO }
1183 { PIN, ZERO, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, ZERO, PIN, ZERO, ZERO, ZERO }
1186 { ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, RIGHT, LEFT, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, RIGHT, LEFT, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, RIGHT }
1189 { PIN, ZERO, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, PIN, ZERO, PIN, LEFT, PIN, RIGHT, PIN, ZERO, PIN, LEFT, PIN, LEFT, PIN, RIGHT, PIN }
1192 { RIGHT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, LEFT, PIN, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, ZERO, LEFT, RIGHT, ZERO }
1195 { ZERO, PIN, ZERO, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, PIN, ZERO, ZERO, PIN, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, ZERO, PIN, ZERO, ZERO }
1198 { ZERO, PIN, ZERO, ZERO, PIN, PIN, ZERO, PIN, ZERO, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, PIN, RIGHT, PIN, LEFT, ZERO, ZERO, RIGHT, PIN }
1201 { PIN, LEFT, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, LEFT, ZERO }
1204 { LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, LEFT, PIN, LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT }
1207 { LEFT, PIN, RIGHT, PIN, RIGHT, LEFT, ZERO, PIN, PIN, ZERO, RIGHT, LEFT, ZERO, PIN, PIN, ZERO, RIGHT, LEFT, PIN, LEFT, PIN, RIGHT, ZERO }
1210 { ZERO, PIN, ZERO, PIN, ZERO, PIN, LEFT, PIN, RIGHT, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, LEFT, PIN, RIGHT, PIN, ZERO }
1213 { ZERO, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, PIN, ZERO, ZERO, LEFT, PIN, RIGHT, ZERO, ZERO, PIN, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, ZERO }
1216 { PIN, ZERO, ZERO, ZERO, PIN, PIN, ZERO, RIGHT, RIGHT, LEFT, LEFT, PIN, RIGHT, RIGHT, LEFT, LEFT, ZERO, PIN, PIN, ZERO, ZERO, ZERO, PIN }
1219 { ZERO, RIGHT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, LEFT, RIGHT, ZERO, PIN, ZERO, LEFT, RIGHT, LEFT, PIN, LEFT, PIN, RIGHT, PIN, LEFT, ZERO }
1222 { PIN, RIGHT, PIN, LEFT, PIN, ZERO, ZERO, PIN, RIGHT, ZERO, RIGHT, RIGHT, ZERO, RIGHT, PIN, ZERO, ZERO, PIN, LEFT, PIN, RIGHT, PIN, ZERO }
1225 { ZERO, RIGHT, PIN, LEFT, PIN, RIGHT, ZERO, ZERO, RIGHT, PIN, LEFT, LEFT, RIGHT, RIGHT, PIN, LEFT, ZERO, ZERO, LEFT, PIN, RIGHT, PIN, LEFT }
1228 { LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT }
1231 { PIN, RIGHT, RIGHT, PIN, ZERO, LEFT, PIN, RIGHT, RIGHT, PIN, ZERO, LEFT, PIN, RIGHT, RIGHT, PIN, ZERO, LEFT, PIN, RIGHT, RIGHT, PIN, ZERO }
1234 { PIN, ZERO, PIN, PIN, ZERO, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, ZERO, PIN, ZERO, PIN, ZERO, PIN, PIN, ZERO, ZERO, ZERO, ZERO }
1236 { "WindowToTheWorld",
1237 { PIN, LEFT, ZERO, PIN, ZERO, ZERO, PIN, ZERO, ZERO, PIN, ZERO, RIGHT, PIN, LEFT, ZERO, PIN, ZERO, ZERO, PIN, ZERO, ZERO, PIN, ZERO }
1240 { PIN, PIN, ZERO, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, ZERO, PIN, ZERO, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, ZERO, PIN, PIN, ZERO, PIN }
1243 { ZERO, ZERO, ZERO, ZERO, PIN, RIGHT, RIGHT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, RIGHT, RIGHT, PIN, ZERO, ZERO, ZERO, ZERO }
1246 { RIGHT, ZERO, PIN, ZERO, LEFT, PIN, RIGHT, PIN, RIGHT, LEFT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, LEFT, PIN, LEFT, PIN, RIGHT, ZERO, PIN, ZERO }
1249 { PIN, RIGHT, PIN, RIGHT, RIGHT, PIN, LEFT, LEFT, PIN, ZERO, PIN, RIGHT, PIN, LEFT, PIN, ZERO, PIN, RIGHT, RIGHT, PIN, LEFT, LEFT, PIN }
1252 { ZERO, ZERO, PIN, PIN, ZERO, PIN, ZERO, ZERO, PIN, ZERO, PIN, PIN, ZERO, PIN, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO, ZERO, PIN }
1255 { LEFT, ZERO, ZERO, PIN, LEFT, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, PIN, PIN, ZERO, LEFT, RIGHT, PIN, LEFT, LEFT, RIGHT, PIN, ZERO, ZERO }
1259 int models = (sizeof(model) / sizeof(struct model_s));
1261 #define VOFFSET 0.045
1267 /* the connecting string that holds the snake together */
1268 #define MAGICAL_RED_STRING 0
1270 #define GETSCALAR(vec,mask) ((vec)==(mask) ? 1 : ((vec)==-(mask) ? -1 : 0 ))
1273 # define MAX(x, y) ((x) > (y) ? (x) : (y))
1276 # define MIN(x, y) ((x) < (y) ? (x) : (y))
1279 #define RAND(n) ((random() & 0x7fffffff) % ((long) (n)))
1280 #define RANDSIGN() ((random() & 1) ? 1 : -1)
1282 /* the triangular prism what makes up the basic unit */
1283 float solid_prism_v[][3] = {
1284 /* first corner, bottom left front */
1285 { VOFFSET, VOFFSET, 1.0 },
1286 { VOFFSET, 0.00, 1.0 - VOFFSET },
1287 { 0.00, VOFFSET, 1.0 - VOFFSET },
1288 /* second corner, rear */
1289 { VOFFSET, VOFFSET, 0.00 },
1290 { VOFFSET, 0.00, VOFFSET },
1291 { 0.00, VOFFSET, VOFFSET },
1292 /* third, right front */
1293 { 1.0 - VOFFSET / M_SQRT1_2, VOFFSET, 1.0 },
1294 { 1.0 - VOFFSET / M_SQRT1_2, 0.0, 1.0 - VOFFSET },
1295 { 1.0 - VOFFSET * M_SQRT1_2, VOFFSET, 1.0 - VOFFSET },
1296 /* fourth, right rear */
1297 { 1.0 - VOFFSET / M_SQRT1_2, VOFFSET, 0.0 },
1298 { 1.0 - VOFFSET / M_SQRT1_2, 0.0, VOFFSET },
1299 { 1.0 - VOFFSET * M_SQRT1_2, VOFFSET, VOFFSET },
1300 /* fifth, upper front */
1301 { VOFFSET, 1.0 - VOFFSET / M_SQRT1_2, 1.0 },
1302 { VOFFSET / M_SQRT1_2, 1.0 - VOFFSET * M_SQRT1_2, 1.0 - VOFFSET },
1303 { 0.0, 1.0 - VOFFSET / M_SQRT1_2, 1.0 - VOFFSET},
1304 /* sixth, upper rear */
1305 { VOFFSET, 1.0 - VOFFSET / M_SQRT1_2, 0.0 },
1306 { VOFFSET / M_SQRT1_2, 1.0 - VOFFSET * M_SQRT1_2, VOFFSET },
1307 { 0.0, 1.0 - VOFFSET / M_SQRT1_2, VOFFSET }};
1309 float solid_prism_n[][3] = {/* corners */
1310 { -VOFFSET, -VOFFSET, VOFFSET },
1311 { VOFFSET, -VOFFSET, VOFFSET },
1312 { -VOFFSET, VOFFSET, VOFFSET },
1313 { -VOFFSET, -VOFFSET, -VOFFSET },
1314 { VOFFSET, -VOFFSET, -VOFFSET },
1315 { -VOFFSET, VOFFSET, -VOFFSET },
1317 { -VOFFSET, 0.0, VOFFSET },
1318 { 0.0, -VOFFSET, VOFFSET },
1319 { VOFFSET, VOFFSET, VOFFSET },
1320 { -VOFFSET, 0.0, -VOFFSET },
1321 { 0.0, -VOFFSET, -VOFFSET },
1322 { VOFFSET, VOFFSET, -VOFFSET },
1323 { -VOFFSET, -VOFFSET, 0.0 },
1324 { VOFFSET, -VOFFSET, 0.0 },
1325 { -VOFFSET, VOFFSET, 0.0 },
1329 { M_SQRT1_2, M_SQRT1_2, 0.0 },
1331 { 0.0, 0.0, -1.0 }};
1333 float wire_prism_v[][3] = {{ 0.0, 0.0, 1.0 },
1340 float wire_prism_n[][3] = {{ 0.0, 0.0, 1.0},
1342 { M_SQRT1_2, M_SQRT1_2, 0.0},
1346 static struct glsnake_cfg * glc = NULL;
1351 typedef float (*morphFunc)(long);
1354 /* forward definitions for GLUT functions */
1355 void calc_rotation();
1356 inline void ui_mousedrag();
1364 float light_pos[][3] = {{0.0, 0.0, 20.0}, {0.0, 20.0, 0.0}};
1365 float light_dir[][3] = {{0.0, 0.0,-20.0}, {0.0,-20.0, 0.0}};
1367 glClearColor(0.0, 0.0, 0.0, 0.0);
1368 glEnable(GL_DEPTH_TEST);
1369 glShadeModel(GL_SMOOTH);
1370 glCullFace(GL_BACK);
1371 glEnable(GL_CULL_FACE);
1372 glEnable(GL_NORMALIZE);
1375 glColor3f(1.0, 1.0, 1.0);
1376 glLightfv(GL_LIGHT0, GL_POSITION, light_pos[0]);
1377 glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, light_dir[0]);
1378 glLightfv(GL_LIGHT1, GL_POSITION, light_pos[1]);
1379 glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, light_dir[1]);
1380 glEnable(GL_LIGHTING);
1381 glEnable(GL_LIGHT0);
1382 glEnable(GL_LIGHT1);
1383 glEnable(GL_COLOR_MATERIAL);
1387 void gettime(snaketime *t)
1389 #ifdef HAVE_GETTIMEOFDAY
1390 #ifdef GETTIMEOFDAY_TWO_ARGS
1391 struct timezone tzp;
1392 gettimeofday(t, &tzp);
1393 #else /* !GETTIMEOFDAY_TWO_ARGS */
1395 #endif /* !GETTIMEOFDAY_TWO_ARGS */
1396 #else /* !HAVE_GETTIMEOFDAY */
1399 #endif /* HAVE_FTIME */
1400 #endif /* !HAVE_GETTIMEOFDAY */
1404 static void load_font(ModeInfo * mi, char * res, XFontStruct ** fontp, GLuint * dlistp) {
1405 const char * font = get_string_resource(res, "Font");
1411 font = "-*-helvetica-medium-r-*-*-*-120-*";
1413 f = XLoadQueryFont(mi->dpy, font);
1415 f = XLoadQueryFont(mi->dpy, "fixed");
1418 first = f->min_char_or_byte2;
1419 last = f->max_char_or_byte2;
1422 *dlistp = glGenLists((GLuint) last + 1);
1423 check_gl_error("glGenLists");
1424 glXUseXFont(id, first, last - first + 1, *dlistp + first);
1425 check_gl_error("glXUseXFont");
1431 void start_morph(int model_index, int immediate);
1433 /* wot initialises it */
1440 struct glsnake_cfg * bp;
1442 /* set up the conf struct and glx contexts */
1444 glc = (struct glsnake_cfg *) calloc(MI_NUM_SCREENS(mi), sizeof(struct glsnake_cfg));
1446 fprintf(stderr, "%s: out of memory\n", progname);
1450 bp = &glc[MI_SCREEN(mi)];
1452 if ((bp->glx_context = init_GL(mi)) != NULL) {
1454 glsnake_reshape(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
1460 /* initialise conf struct */
1461 memset(&bp->node, 0, sizeof(float) * NODE_COUNT);
1471 gettime(&bp->last_iteration);
1472 memcpy(&bp->last_morph, &bp->last_iteration, sizeof(bp->last_morph));
1474 bp->prev_colour = bp->next_colour = COLOUR_ACYCLIC;
1475 bp->next_model = RAND(models);
1476 bp->prev_model = START_MODEL;
1477 start_morph(bp->prev_model, 1);
1479 /* set up a font for the labels */
1482 load_font(mi, "labelfont", &bp->font, &bp->font_list);
1485 /* build a solid display list */
1486 glc->node_solid = glGenLists(1);
1487 glNewList(glc->node_solid, GL_COMPILE);
1489 glBegin(GL_TRIANGLES);
1490 glNormal3fv(solid_prism_n[0]);
1491 glVertex3fv(solid_prism_v[0]);
1492 glVertex3fv(solid_prism_v[2]);
1493 glVertex3fv(solid_prism_v[1]);
1495 glNormal3fv(solid_prism_n[1]);
1496 glVertex3fv(solid_prism_v[6]);
1497 glVertex3fv(solid_prism_v[7]);
1498 glVertex3fv(solid_prism_v[8]);
1500 glNormal3fv(solid_prism_n[2]);
1501 glVertex3fv(solid_prism_v[12]);
1502 glVertex3fv(solid_prism_v[13]);
1503 glVertex3fv(solid_prism_v[14]);
1505 glNormal3fv(solid_prism_n[3]);
1506 glVertex3fv(solid_prism_v[3]);
1507 glVertex3fv(solid_prism_v[4]);
1508 glVertex3fv(solid_prism_v[5]);
1510 glNormal3fv(solid_prism_n[4]);
1511 glVertex3fv(solid_prism_v[9]);
1512 glVertex3fv(solid_prism_v[11]);
1513 glVertex3fv(solid_prism_v[10]);
1515 glNormal3fv(solid_prism_n[5]);
1516 glVertex3fv(solid_prism_v[16]);
1517 glVertex3fv(solid_prism_v[15]);
1518 glVertex3fv(solid_prism_v[17]);
1522 glNormal3fv(solid_prism_n[6]);
1523 glVertex3fv(solid_prism_v[0]);
1524 glVertex3fv(solid_prism_v[12]);
1525 glVertex3fv(solid_prism_v[14]);
1526 glVertex3fv(solid_prism_v[2]);
1528 glNormal3fv(solid_prism_n[7]);
1529 glVertex3fv(solid_prism_v[0]);
1530 glVertex3fv(solid_prism_v[1]);
1531 glVertex3fv(solid_prism_v[7]);
1532 glVertex3fv(solid_prism_v[6]);
1534 glNormal3fv(solid_prism_n[8]);
1535 glVertex3fv(solid_prism_v[6]);
1536 glVertex3fv(solid_prism_v[8]);
1537 glVertex3fv(solid_prism_v[13]);
1538 glVertex3fv(solid_prism_v[12]);
1540 glNormal3fv(solid_prism_n[9]);
1541 glVertex3fv(solid_prism_v[3]);
1542 glVertex3fv(solid_prism_v[5]);
1543 glVertex3fv(solid_prism_v[17]);
1544 glVertex3fv(solid_prism_v[15]);
1546 glNormal3fv(solid_prism_n[10]);
1547 glVertex3fv(solid_prism_v[3]);
1548 glVertex3fv(solid_prism_v[9]);
1549 glVertex3fv(solid_prism_v[10]);
1550 glVertex3fv(solid_prism_v[4]);
1552 glNormal3fv(solid_prism_n[11]);
1553 glVertex3fv(solid_prism_v[15]);
1554 glVertex3fv(solid_prism_v[16]);
1555 glVertex3fv(solid_prism_v[11]);
1556 glVertex3fv(solid_prism_v[9]);
1558 glNormal3fv(solid_prism_n[12]);
1559 glVertex3fv(solid_prism_v[1]);
1560 glVertex3fv(solid_prism_v[2]);
1561 glVertex3fv(solid_prism_v[5]);
1562 glVertex3fv(solid_prism_v[4]);
1564 glNormal3fv(solid_prism_n[13]);
1565 glVertex3fv(solid_prism_v[8]);
1566 glVertex3fv(solid_prism_v[7]);
1567 glVertex3fv(solid_prism_v[10]);
1568 glVertex3fv(solid_prism_v[11]);
1570 glNormal3fv(solid_prism_n[14]);
1571 glVertex3fv(solid_prism_v[13]);
1572 glVertex3fv(solid_prism_v[16]);
1573 glVertex3fv(solid_prism_v[17]);
1574 glVertex3fv(solid_prism_v[14]);
1578 glBegin(GL_TRIANGLES);
1579 glNormal3fv(solid_prism_n[15]);
1580 glVertex3fv(solid_prism_v[0]);
1581 glVertex3fv(solid_prism_v[6]);
1582 glVertex3fv(solid_prism_v[12]);
1584 glNormal3fv(solid_prism_n[19]);
1585 glVertex3fv(solid_prism_v[3]);
1586 glVertex3fv(solid_prism_v[15]);
1587 glVertex3fv(solid_prism_v[9]);
1591 glNormal3fv(solid_prism_n[16]);
1592 glVertex3fv(solid_prism_v[1]);
1593 glVertex3fv(solid_prism_v[4]);
1594 glVertex3fv(solid_prism_v[10]);
1595 glVertex3fv(solid_prism_v[7]);
1597 glNormal3fv(solid_prism_n[17]);
1598 glVertex3fv(solid_prism_v[8]);
1599 glVertex3fv(solid_prism_v[11]);
1600 glVertex3fv(solid_prism_v[16]);
1601 glVertex3fv(solid_prism_v[13]);
1603 glNormal3fv(solid_prism_n[18]);
1604 glVertex3fv(solid_prism_v[2]);
1605 glVertex3fv(solid_prism_v[14]);
1606 glVertex3fv(solid_prism_v[17]);
1607 glVertex3fv(solid_prism_v[5]);
1611 /* build wire display list */
1612 glc->node_wire = glGenLists(1);
1613 glNewList(glc->node_wire, GL_COMPILE);
1614 glBegin(GL_LINE_STRIP);
1615 glVertex3fv(wire_prism_v[0]);
1616 glVertex3fv(wire_prism_v[1]);
1617 glVertex3fv(wire_prism_v[2]);
1618 glVertex3fv(wire_prism_v[0]);
1619 glVertex3fv(wire_prism_v[3]);
1620 glVertex3fv(wire_prism_v[4]);
1621 glVertex3fv(wire_prism_v[5]);
1622 glVertex3fv(wire_prism_v[3]);
1625 glVertex3fv(wire_prism_v[1]);
1626 glVertex3fv(wire_prism_v[4]);
1627 glVertex3fv(wire_prism_v[2]);
1628 glVertex3fv(wire_prism_v[5]);
1633 /* initialise the rotation */
1644 struct glsnake_cfg * bp = &glc[MI_SCREEN(mi)];
1647 /* draw some text */
1648 glPushAttrib(GL_TRANSFORM_BIT | GL_ENABLE_BIT);
1649 glDisable(GL_LIGHTING);
1650 glDisable(GL_DEPTH_TEST);
1651 glMatrixMode(GL_PROJECTION);
1654 glMatrixMode(GL_MODELVIEW);
1658 gluOrtho2D(0, glc->width, 0, glc->height);
1660 gluOrtho2D(0, mi->xgwa.width, 0, mi->xgwa.height);
1662 glColor3f(1.0, 1.0, 1.0);
1664 char interactstr[] = "interactive";
1674 s = model[glc->next_model].name;
1676 w = glutBitmapLength(GLUT_BITMAP_HELVETICA_12, (unsigned char *) s);
1677 glRasterPos2f(glc->width - w - 3, 4);
1678 while (s[i] != '\0')
1679 glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, s[i++]);
1681 glRasterPos2f(10, mi->xgwa.height - 10 - (bp->font->ascent + bp->font->descent));
1682 while (s[i] != '\0')
1683 glCallList(bp->font_list + (int)s[i++]);
1687 glMatrixMode(GL_PROJECTION);
1692 /* apply the matrix to the origin and stick it in vec */
1693 void matmult_origin(float rotmat[16], float vec[4]) {
1695 vec[0] = 0.5 * rotmat[0] + 0.5 * rotmat[4] + 0.5 * rotmat [8] + 1 * rotmat[12];
1696 vec[1] = 0.5 * rotmat[1] + 0.5 * rotmat[5] + 0.5 * rotmat [9] + 1 * rotmat[13];
1697 vec[2] = 0.5 * rotmat[2] + 0.5 * rotmat[6] + 0.5 * rotmat[10] + 1 * rotmat[14];
1698 vec[3] = 0.5 * rotmat[3] + 0.5 * rotmat[7] + 0.5 * rotmat[11] + 1 * rotmat[15];
1700 vec[0] = 0 * rotmat [0] + 0 * rotmat [1] + 0 * rotmat [2] + 1 * rotmat [3];
1701 vec[1] = 0 * rotmat [4] + 0 * rotmat [5] + 0 * rotmat [6] + 1 * rotmat [7];
1702 vec[2] = 0 * rotmat [8] + 0 * rotmat [9] + 0 * rotmat[10] + 1 * rotmat[11];
1703 vec[3] = 0 * rotmat[12] + 0 * rotmat[13] + 0 * rotmat[14] + 1 * rotmat[15];
1711 /* wot gets called when the winder is resized */
1712 void glsnake_reshape(
1717 glViewport(0, 0, (GLint) w, (GLint) h);
1718 glMatrixMode(GL_PROJECTION);
1720 gluPerspective(zoom, w/(GLfloat)h, 0.05, 100.0);
1721 gluLookAt(0.0, 0.0, 20.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
1722 glMatrixMode(GL_MODELVIEW);
1723 /*gluLookAt(0.0, 0.0, 20.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);*/
1731 /* Returns the new dst_dir for the given src_dir and dst_dir */
1732 int cross_product(int src_dir, int dst_dir) {
1733 return X_MASK*(GETSCALAR(src_dir,Y_MASK) * GETSCALAR(dst_dir,Z_MASK) -
1734 GETSCALAR(src_dir,Z_MASK) * GETSCALAR(dst_dir,Y_MASK))+
1735 Y_MASK*(GETSCALAR(src_dir,Z_MASK) * GETSCALAR(dst_dir,X_MASK) -
1736 GETSCALAR(src_dir,X_MASK) * GETSCALAR(dst_dir,Z_MASK))+
1737 Z_MASK*(GETSCALAR(src_dir,X_MASK) * GETSCALAR(dst_dir,Y_MASK) -
1738 GETSCALAR(src_dir,Y_MASK) * GETSCALAR(dst_dir,X_MASK));
1741 /* calculate orthogonal snake metrics
1742 * is_legal = true if model does not pass through itself
1743 * is_cyclic = true if last node connects back to first node
1744 * last_turn = for cyclic snakes, specifes what the 24th turn would be
1746 void calc_snake_metrics(void) {
1749 int prevSrcDir = -Y_MASK;
1750 int prevDstDir = Z_MASK;
1751 int grid[25][25][25];
1754 memset(&grid, 0, sizeof(int) * 25*25*25);
1759 /* trace path of snake - and keep record for is_legal */
1760 for (i = 0; i < NODE_COUNT - 1; i++) {
1761 /*int ang_card;*/ /* cardinal direction of node angle */
1762 /* establish new state vars */
1763 srcDir = -prevDstDir;
1764 x += GETSCALAR(prevDstDir, X_MASK);
1765 y += GETSCALAR(prevDstDir, Y_MASK);
1766 z += GETSCALAR(prevDstDir, Z_MASK);
1768 switch ((int) model[glc->next_model].node[i]) {
1770 dstDir = -prevSrcDir;
1773 dstDir = prevSrcDir;
1777 dstDir = cross_product(prevSrcDir, prevDstDir);
1778 if (model[glc->next_model].node[i] == (int) (RIGHT))
1782 /* Prevent spurious "might be used
1783 * uninitialised" warnings when compiling
1789 if (grid[x][y][z] == 0)
1790 grid[x][y][z] = srcDir + dstDir;
1791 else if (grid[x][y][z] + srcDir + dstDir == 0)
1796 prevSrcDir = srcDir;
1797 prevDstDir = dstDir;
1800 /* determine if the snake is cyclic */
1801 glc->is_cyclic = (dstDir == Y_MASK && x == 12 && y == 11 && z == 12);
1803 /* determine last_turn */
1804 glc->last_turn = -1;
1807 case -Z_MASK: glc->last_turn = ZERO; break;
1808 case Z_MASK: glc->last_turn = PIN; break;
1809 case X_MASK: glc->last_turn = LEFT; break;
1810 case -X_MASK: glc->last_turn = RIGHT; break;
1814 /* work out how far through the current morph we are */
1815 float morph_percent(void) {
1819 /* extend this function later with a case statement for each of the
1822 /* when morphing all nodes at once, the longest morph will be the node
1823 * that needs to rotate 180 degrees. For each node, work out how far it
1824 * has to go, and store the maximum rotation and current largest angular
1825 * difference, returning the angular difference over the maximum. */
1827 float rot_max = 0.0, ang_diff_max = 0.0;
1829 for (i = 0; i < NODE_COUNT - 1; i++) {
1830 float rot, ang_diff;
1832 /* work out the maximum rotation this node has to go through
1833 * from the previous to the next model, taking into account that
1834 * the snake always morphs through the smaller angle */
1835 rot = fabs(model[glc->prev_model].node[i] -
1836 model[glc->next_model].node[i]);
1837 if (rot > 180.0) rot = 180.0 - rot;
1838 /* work out the difference between the current position and the
1840 ang_diff = fabs(glc->node[i] -
1841 model[glc->next_model].node[i]);
1842 if (ang_diff > 180.0) ang_diff = 180 - ang_diff;
1843 /* if it's the biggest so far, record it */
1844 if (rot > rot_max) rot_max = rot;
1845 if (ang_diff > ang_diff_max) ang_diff_max = ang_diff;
1848 /* ang_diff / rot approaches 0, we want the complement */
1849 retval = 1.0 - (ang_diff_max / rot_max);
1850 /* protect against naan */
1852 /* Apparently some systems (Solaris) don't have isinf() */
1854 #define isinf(x) (((x) > 999999999999.9) || ((x) < -999999999999.9))
1856 if (isnan(retval) || isinf(retval)) retval = 1.0;
1858 /*printf("morph_pct = %f\n", retval);*/
1862 void morph_colour(void) {
1863 float percent, compct; /* complement of percentage */
1865 percent = morph_percent();
1866 compct = 1.0 - percent;
1868 glc->colour[0][0] = colour[glc->prev_colour][0][0] * compct + colour[glc->next_colour][0][0] * percent;
1869 glc->colour[0][1] = colour[glc->prev_colour][0][1] * compct + colour[glc->next_colour][0][1] * percent;
1870 glc->colour[0][2] = colour[glc->prev_colour][0][2] * compct + colour[glc->next_colour][0][2] * percent;
1872 glc->colour[1][0] = colour[glc->prev_colour][1][0] * compct + colour[glc->next_colour][1][0] * percent;
1873 glc->colour[1][1] = colour[glc->prev_colour][1][1] * compct + colour[glc->next_colour][1][1] * percent;
1874 glc->colour[1][2] = colour[glc->prev_colour][1][2] * compct + colour[glc->next_colour][1][2] * percent;
1877 /* Start morph process to this model */
1878 void start_morph(int model_index, int immediate) {
1879 /* if immediate, don't bother morphing, go straight to the next model */
1883 for (i = 0; i < NODE_COUNT; i++)
1884 glc->node[i] = model[model_index].node[i];
1887 glc->prev_model = glc->next_model;
1888 glc->next_model = model_index;
1889 glc->prev_colour = glc->next_colour;
1891 calc_snake_metrics();
1893 glc->next_colour = COLOUR_INVALID;
1895 glc->next_colour = COLOUR_AUTHENTIC;
1896 else if (glc->is_cyclic)
1897 glc->next_colour = COLOUR_CYCLIC;
1899 glc->next_colour = COLOUR_ACYCLIC;
1902 glc->colour[0][0] = colour[glc->next_colour][0][0];
1903 glc->colour[0][1] = colour[glc->next_colour][0][1];
1904 glc->colour[0][2] = colour[glc->next_colour][0][2];
1905 glc->colour[1][0] = colour[glc->next_colour][1][0];
1906 glc->colour[1][1] = colour[glc->next_colour][1][1];
1907 glc->colour[1][2] = colour[glc->next_colour][1][2];
1914 /* Returns morph progress */
1915 float morph(long iter_msec) {
1916 /* work out the maximum angle for this iteration */
1918 float iter_angle_max, largest_diff, largest_progress;
1924 iter_angle_max = 90.0 * (angvel/1000.0) * iter_msec;
1927 largest_diff = largest_progress = 0.0;
1928 for (i = 0; i < NODE_COUNT; i++) {
1929 float curAngle = glc->node[i];
1930 float destAngle = model[glc->next_model].node[i];
1931 if (curAngle != destAngle) {
1933 if (fabs(curAngle-destAngle) <= iter_angle_max)
1934 glc->node[i] = destAngle;
1935 else if (fmod(curAngle-destAngle+360,360) > 180)
1936 glc->node[i] = fmod(curAngle + iter_angle_max, 360);
1938 glc->node[i] = fmod(curAngle+360 - iter_angle_max, 360);
1939 largest_diff = MAX(largest_diff, fabs(destAngle-glc->node[i]));
1940 largest_progress = MAX(largest_diff, fabs(glc->node[i] - model[glc->prev_model].node[i]));
1944 return MIN(largest_diff / largest_progress, 1.0);
1948 void glsnake_idle();
1950 void restore_idle(int value)
1952 glutIdleFunc(glsnake_idle);
1956 void quick_sleep(void)
1959 /* By using glutTimerFunc we can keep responding to
1960 * mouse and keyboard events, unlike using something like
1963 glutTimerFunc(1, restore_idle, 0);
1971 struct glsnake_cfg * bp
1974 /* time since last iteration */
1976 /* time since the beginning of last morph */
1978 float iter_angle_max;
1979 snaketime current_time;
1980 /* morphFunc transition; */
1984 /* Do nothing to the model if we are paused */
1986 /* Avoid busy waiting when nothing is changing */
1990 glutPostRedisplay();
1995 /* <spiv> Well, ftime gives time with millisecond resolution.
1996 * <spiv> (or worse, perhaps... who knows what the OS will do)
1997 * <spiv> So if no discernable amount of time has passed:
1998 * <spiv> a) There's no point updating the screen, because
1999 * it would be the same
2000 * <spiv> b) The code will divide by zero
2002 gettime(¤t_time);
2004 iter_msec = (long) GETMSECS(current_time) - GETMSECS(glc->last_iteration) +
2005 ((long) GETSECS(current_time) - GETSECS(glc->last_iteration)) * 1000L;
2008 /* save the current time */
2009 memcpy(&glc->last_iteration, ¤t_time, sizeof(snaketime));
2011 /* work out if we have to switch models */
2012 morf_msec = GETMSECS(glc->last_iteration) - GETMSECS(glc->last_morph) +
2013 ((long) (GETSECS(glc->last_iteration)-GETSECS(glc->last_morph)) * 1000L);
2015 if ((morf_msec > statictime) && !interactive && !glc->morphing) {
2016 /*printf("starting morph\n");*/
2017 memcpy(&glc->last_morph, &(glc->last_iteration), sizeof(glc->last_morph));
2018 start_morph(RAND(models), 0);
2021 if (interactive && !glc->morphing) {
2026 /* if (!glc->dragging && !glc->interactive) { */
2029 yspin += 360/((1000/yangvel)/iter_msec);
2030 zspin += 360/((1000/zangvel)/iter_msec);
2032 yspin += 360 * (yangvel/1000.0) * iter_msec;
2033 zspin += 360 * (zangvel/1000.0) * iter_msec;
2036 /*printf("yspin: %f, zspin: %f\n", yspin, zspin);*/
2040 /* work out the maximum angle we could turn this node in this
2041 * timeslice, iter_msec milliseconds long */
2042 iter_angle_max = 90.0 * (angvel/1000.0) * iter_msec;
2045 for (i = 0; i < NODE_COUNT; i++) {
2046 float cur_angle = glc->node[i];
2047 float dest_angle = model[glc->next_model].node[i];
2048 if (cur_angle != dest_angle) {
2050 if (fabs(cur_angle - dest_angle) <= iter_angle_max)
2051 glc->node[i] = dest_angle;
2052 else if (fmod(cur_angle - dest_angle + 360, 360) > 180)
2053 glc->node[i] = fmod(cur_angle + iter_angle_max, 360);
2055 glc->node[i] = fmod(cur_angle + 360 - iter_angle_max, 360);
2059 if (!still_morphing)
2062 /* colour cycling */
2067 glutPostRedisplay();
2070 /* We are going too fast, so we may as well let the
2071 * cpu relax a little by sleeping for a millisecond. */
2077 void glsnake_display(
2083 struct glsnake_cfg * bp = &glc[MI_SCREEN(mi)];
2084 Display * dpy = MI_DISPLAY(mi);
2085 Window window = MI_WINDOW(mi);
2090 float positions[NODE_COUNT][4]; /* origin points for each node */
2091 float com[4]; /* it's the CENTRE of MASS */
2094 if (!bp->glx_context)
2098 /* clear the buffer */
2099 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2101 /* go into the modelview stack */
2102 glMatrixMode(GL_MODELVIEW);
2105 /* get the centre of each node, by moving through the snake and
2106 * performing the rotations, then grabbing the matrix at each point
2107 * and applying it to the origin */
2111 /* apply the mouse drag rotation */
2115 /* apply the continuous rotation */
2116 glRotatef(yspin, 0.0, 1.0, 0.0);
2117 glRotatef(zspin, 0.0, 0.0, 1.0);
2123 for (i = 0; i < NODE_COUNT; i++) {
2128 /*printf("ang = %f\n", ang);*/
2130 glTranslatef(0.5, 0.5, 0.5); /* move to center */
2131 glRotatef(90, 0.0, 0.0, -1.0); /* reorient */
2132 glTranslatef(1.0 + explode, 0.0, 0.0); /* move to new pos. */
2133 glRotatef(180 + ang, 1.0, 0.0, 0.0); /* pivot to new angle */
2134 glTranslatef(-0.5, -0.5, -0.5); /* return from center */
2136 glGetFloatv(GL_MODELVIEW_MATRIX, rotmat);
2138 matmult_origin(rotmat, positions[i]);
2140 /*printf("positions %f %f %f %f\n", positions[i][0], positions[i][1], positions[i][2], positions[i][3]);*/
2142 com[0] += positions[i][0];
2143 com[1] += positions[i][1];
2144 com[2] += positions[i][2];
2145 com[3] += positions[i][3];
2148 com[0] /= NODE_COUNT;
2149 com[1] /= NODE_COUNT;
2150 com[2] /= NODE_COUNT;
2151 com[3] /= NODE_COUNT;
2157 /*printf("com: %f, %f, %f, %f\n", com[0], com[1], com[2], com[3]);*/
2159 #if MAGICAL_RED_STRING
2161 glTranslatef(-com[0], -com[1], -com[2]);
2163 glDisable(GL_LIGHTING);
2164 glColor3f(1.0, 0.0, 0.0);
2165 glBegin(GL_LINE_STRIP);
2166 for (i = 0; i < NODE_COUNT - 1; i++) {
2167 glVertex3fv(positions[i]);
2170 glEnable(GL_LIGHTING);
2171 /*glTranslatef(com[0], com[1], com[2]);*/
2176 glTranslatef(-com[0], -com[1], -com[2]);
2179 /* apply the mouse drag rotation */
2183 /* apply the continuous rotation */
2184 glRotatef(yspin, 0.0, 1.0, 0.0);
2185 glRotatef(zspin, 0.0, 0.0, 1.0);
2187 /* now draw each node along the snake -- this is quite ugly :p */
2188 for (i = 0; i < NODE_COUNT; i++) {
2189 /* choose a colour for this node */
2190 if ((i == glc->selected || i == glc->selected+1) && interactive)
2192 glColor3f(1.0, 1.0, 0.0);
2194 glColor3fv(glc->colour[(i+1)%2]);
2198 glCallList(glc->node_wire);
2200 glCallList(glc->node_solid);
2202 /* now work out where to draw the next one */
2204 /* Interpolate between models */
2207 glTranslatef(0.5, 0.5, 0.5); /* move to center */
2208 glRotatef(90, 0.0, 0.0, -1.0); /* reorient */
2209 glTranslatef(1.0 + explode, 0.0, 0.0); /* move to new pos. */
2210 glRotatef(180 + ang, 1.0, 0.0, 0.0); /* pivot to new angle */
2211 glTranslatef(-0.5, -0.5, -0.5); /* return from center */
2231 glXSwapBuffers(dpy, window);
2236 /* anything that needs to be cleaned up goes here */
2238 glutDestroyWindow(glc->window);
2242 void ui_init(int *, char **);
2244 int main(int argc, char ** argv) {
2245 glc = malloc(sizeof(struct glsnake_cfg));
2246 memset(glc, 0, sizeof(struct glsnake_cfg));
2251 ui_init(&argc, argv);
2253 gettime(&glc->last_iteration);
2254 memcpy(&glc->last_morph, &glc->last_iteration, sizeof(snaketime));
2255 srand((unsigned int)GETSECS(glc->last_iteration));
2257 glc->prev_colour = glc->next_colour = COLOUR_ACYCLIC;
2258 glc->next_model = RAND(models);
2259 glc->prev_model = 0;
2260 start_morph(glc->prev_model, 1);
2278 /* trackball quaternions */
2279 float cumquat[4] = {0.0,0.0,0.0,0.0}, oldquat[4] = {0.0,0.0,0.0,0.1};
2281 /* rotation matrix */
2284 /* mouse drag vectors: start and end */
2285 float m_s[3], m_e[3];
2287 /* dragging boolean */
2290 /* this function calculates the rotation matrix based on the quaternions
2291 * generated from the mouse drag vectors */
2292 void calc_rotation() {
2294 double xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz;
2296 /* this bit ripped from Shoemake's quaternion notes from SIGGRAPH */
2297 Nq = cumquat[0] * cumquat[0] + cumquat[1] * cumquat[1] +
2298 cumquat[2] * cumquat[2] + cumquat[3] * cumquat[3];
2299 s = (Nq > 0.0) ? (2.0 / Nq) : 0.0;
2300 xs = cumquat[0] * s; ys = cumquat[1] * s; zs = cumquat[2] * s;
2301 wx = cumquat[3] * xs; wy = cumquat[3] * ys; wz = cumquat[3] * zs;
2302 xx = cumquat[0] * xs; xy = cumquat[0] * ys; xz = cumquat[0] * zs;
2303 yy = cumquat[1] * ys; yz = cumquat[1] * zs; zz = cumquat[2] * zs;
2305 rotation[0] = 1.0 - (yy + zz);
2306 rotation[1] = xy + wz;
2307 rotation[2] = xz - wy;
2308 rotation[4] = xy - wz;
2309 rotation[5] = 1.0 - (xx + zz);
2310 rotation[6] = yz + wx;
2311 rotation[8] = xz + wy;
2312 rotation[9] = yz - wx;
2313 rotation[10] = 1.0 - (xx + yy);
2314 rotation[3] = rotation[7] = rotation[11] = 0.0;
2315 rotation[12] = rotation[13] = rotation[14] = 0.0;
2319 inline void ui_mousedrag() {
2320 glMultMatrixf(rotation);
2323 void ui_keyboard(unsigned char c, int x, int y) {
2332 explode += DEF_EXPLODE;
2333 glutPostRedisplay();
2336 explode -= DEF_EXPLODE;
2337 if (explode < 0.0) explode = 0.0;
2338 glutPostRedisplay();
2343 glc->next_model %= models;
2344 start_morph(glc->next_model, 0);
2346 /* Reset last_morph time */
2347 gettime(&glc->last_morph);
2350 /* previous model */
2351 glc->next_model = (glc->next_model + models - 1) % models;
2352 start_morph(glc->next_model, 0);
2354 /* Reset glc->last_morph time */
2355 gettime(&glc->last_morph);
2358 angvel += DEF_ACCEL;
2361 if (angvel > DEF_ACCEL)
2362 angvel -= DEF_ACCEL;
2366 /* Reset last_iteration and last_morph time */
2367 gettime(&glc->last_iteration);
2368 gettime(&glc->last_morph);
2370 interactive = 1 - interactive;
2371 glutPostRedisplay();
2374 wireframe = 1 - wireframe;
2376 glDisable(GL_LIGHTING);
2378 glEnable(GL_LIGHTING);
2379 glutPostRedisplay();
2383 /* unpausing, reset last_iteration and last_morph time */
2384 gettime(&glc->last_iteration);
2385 gettime(&glc->last_morph);
2387 glc->paused = 1 - glc->paused;
2390 /* dump the current model so we can add it! */
2391 printf("# %s\nnoname:\t", model[glc->next_model].name);
2392 for (i = 0; i < NODE_COUNT; i++) {
2393 if (glc->node[i] == ZERO)
2395 else if (glc->node[i] == LEFT)
2397 else if (glc->node[i] == PIN)
2399 else if (glc->node[i] == RIGHT)
2403 printf("%f", node[i].curAngle);
2405 if (i < NODE_COUNT - 1)
2411 glc->fullscreen = 1 - glc->fullscreen;
2412 if (glc->fullscreen) {
2413 glc->old_width = glc->width;
2414 glc->old_height = glc->height;
2417 glutReshapeWindow(glc->old_width, glc->old_height);
2418 glutPositionWindow(50,50);
2422 titles = 1 - titles;
2423 if (interactive || glc->paused)
2424 glutPostRedisplay();
2427 altcolour = 1 - altcolour;
2431 glsnake_reshape(glc->width, glc->height);
2435 glsnake_reshape(glc->width, glc->height);
2442 void ui_special(int key, int x, int y) {
2444 float *destAngle = &(model[glc->next_model].node[glc->selected]);
2445 int unknown_key = 0;
2450 glc->selected = (glc->selected + (NODE_COUNT - 2)) % (NODE_COUNT - 1);
2453 glc->selected = (glc->selected + 1) % (NODE_COUNT - 1);
2456 *destAngle = fmod(*destAngle+(LEFT), 360);
2457 glc->morphing = glc->new_morph = 1;
2459 case GLUT_KEY_RIGHT:
2460 *destAngle = fmod(*destAngle+(RIGHT), 360);
2461 glc->morphing = glc->new_morph = 1;
2464 start_morph(STRAIGHT_MODEL, 0);
2471 calc_snake_metrics();
2474 glutPostRedisplay();
2477 void ui_mouse(int button, int state, int x, int y) {
2482 m_s[0] = M_SQRT1_2 *
2483 (x - (glc->width / 2.0)) / (glc->width / 2.0);
2484 m_s[1] = M_SQRT1_2 *
2485 ((glc->height / 2.0) - y) / (glc->height / 2.0);
2486 m_s[2] = sqrt(1-(m_s[0]*m_s[0]+m_s[1]*m_s[1]));
2490 oldquat[0] = cumquat[0];
2491 oldquat[1] = cumquat[1];
2492 oldquat[2] = cumquat[2];
2493 oldquat[3] = cumquat[3];
2499 glutPostRedisplay();
2502 void ui_motion(int x, int y) {
2507 /* construct the motion end vector from the x,y position on the
2509 m_e[0] = (x - (glc->width/ 2.0)) / (glc->width / 2.0);
2510 m_e[1] = ((glc->height / 2.0) - y) / (glc->height / 2.0);
2511 /* calculate the normal of the vector... */
2512 norm = m_e[0] * m_e[0] + m_e[1] * m_e[1];
2513 /* check if norm is outside the sphere and wraparound if necessary */
2517 m_e[2] = sqrt(norm - 1);
2519 /* the z value comes from projecting onto an elliptical spheroid */
2520 m_e[2] = sqrt(1 - norm);
2523 /* now here, build a quaternion from m_s and m_e */
2524 q[0] = m_s[1] * m_e[2] - m_s[2] * m_e[1];
2525 q[1] = m_s[2] * m_e[0] - m_s[0] * m_e[2];
2526 q[2] = m_s[0] * m_e[1] - m_s[1] * m_e[0];
2527 q[3] = m_s[0] * m_e[0] + m_s[1] * m_e[1] + m_s[2] * m_e[2];
2529 /* new rotation is the product of the new one and the old one */
2530 cumquat[0] = q[3] * oldquat[0] + q[0] * oldquat[3] +
2531 q[1] * oldquat[2] - q[2] * oldquat[1];
2532 cumquat[1] = q[3] * oldquat[1] + q[1] * oldquat[3] +
2533 q[2] * oldquat[0] - q[0] * oldquat[2];
2534 cumquat[2] = q[3] * oldquat[2] + q[2] * oldquat[3] +
2535 q[0] * oldquat[1] - q[1] * oldquat[0];
2536 cumquat[3] = q[3] * oldquat[3] - q[0] * oldquat[0] -
2537 q[1] * oldquat[1] - q[2] * oldquat[2];
2541 glutPostRedisplay();
2544 void ui_init(int * argc, char ** argv) {
2545 glutInit(argc, argv);
2546 glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
2547 glutInitWindowSize(glc->width, glc->height);
2548 glc->window = glutCreateWindow("glsnake");
2550 glutDisplayFunc(glsnake_display);
2551 glutReshapeFunc(glsnake_reshape);
2552 glutIdleFunc(glsnake_idle);
2553 glutKeyboardFunc(ui_keyboard);
2554 glutSpecialFunc(ui_special);
2555 glutMouseFunc(ui_mouse);
2556 glutMotionFunc(ui_motion);
2558 yangvel = DEF_YANGVEL;
2559 zangvel = DEF_ZANGVEL;
2560 explode = DEF_EXPLODE;
2561 angvel = DEF_ANGVEL;
2562 statictime = DEF_STATICTIME;
2563 altcolour = DEF_ALTCOLOUR;
2564 titles = DEF_TITLES;
2565 interactive = DEF_INTERACTIVE;
2567 wireframe = DEF_WIREFRAME;
2569 #endif /* HAVE_GLUT */