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"
159 #include "glxfonts.h"
161 static XrmOptionDescRec opts[] = {
162 { "-explode", ".explode", XrmoptionSepArg, DEF_EXPLODE },
163 { "-angvel", ".angvel", XrmoptionSepArg, DEF_ANGVEL },
164 { "-accel", ".accel", XrmoptionSepArg, DEF_ACCEL },
165 { "-statictime", ".statictime", XrmoptionSepArg, DEF_STATICTIME },
166 { "-yangvel", ".yangvel", XrmoptionSepArg, DEF_YANGVEL },
167 { "-zangvel", ".zangvel", XrmoptionSepArg, DEF_ZANGVEL },
168 { "-altcolour", ".altcolour", XrmoptionNoArg, "True" },
169 { "-no-altcolour", ".altcolour", XrmoptionNoArg, "False" },
170 { "-titles", ".titles", XrmoptionNoArg, "True" },
171 { "-no-titles", ".titles", XrmoptionNoArg, "False" },
172 { "-zoom", ".zoom", XrmoptionSepArg, DEF_ZOOM },
173 { "-wireframe", ".wireframe", XrmoptionNoArg, "true" },
174 { "-no-wireframe", ".wireframe", XrmoptionNoArg, "false" },
177 static argtype vars[] = {
178 {&explode, "explode", "Explode", DEF_EXPLODE, t_Float},
179 {&angvel, "angvel", "Angular Velocity", DEF_ANGVEL, t_Float},
180 {&accel, "accel", "Acceleration", DEF_ACCEL, t_Float},
181 {&statictime, "statictime", "Static Time", DEF_STATICTIME, t_Int},
182 {&yangvel, "yangvel", "Angular Velocity about Y axis", DEF_YANGVEL, t_Float},
183 {&zangvel, "zangvel", "Angular Velocity about X axis", DEF_ZANGVEL, t_Float},
184 {&interactive, "interactive", "Interactive", DEF_INTERACTIVE, t_Bool},
185 {&altcolour, "altcolour", "Alternate Colour Scheme", DEF_ALTCOLOUR, t_Bool},
186 {&titles, "titles", "Titles", DEF_TITLES, t_Bool},
187 {&zoom, "zoom", "Zoom", DEF_ZOOM, t_Float},
188 {&wireframe, "wireframe", "Wireframe", DEF_WIREFRAME, t_Bool},
191 ModeSpecOpt sws_opts = {countof(opts), opts, countof(vars), vars, NULL};
196 float node[NODE_COUNT];
201 GLXContext * glx_context;
205 /* font list number */
212 /* is a morph in progress? */
215 /* has the model been paused? */
224 /* the shape of the model */
225 float node[NODE_COUNT];
227 /* currently selected node for interactive mode */
242 /* timing variables */
243 snaketime last_iteration;
244 snaketime last_morph;
248 int old_width, old_height;
250 /* the id of the display lists for drawing a node */
251 int node_solid, node_wire;
253 /* is the window fullscreen? */
257 #define COLOUR_CYCLIC 0
258 #define COLOUR_ACYCLIC 1
259 #define COLOUR_INVALID 2
260 #define COLOUR_AUTHENTIC 3
262 float colour[][2][3] = {
272 /* authentic - purple and green */
273 { { 0.38, 0.0, 0.55 },
277 struct model_s model[] = {
278 #define STRAIGHT_MODEL 0
280 { ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO,
281 ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO,
284 /* the models in the Rubik's snake manual */
285 #define START_MODEL 1
287 { RIGHT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT,
288 RIGHT, LEFT, LEFT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT,
289 RIGHT, LEFT, RIGHT, LEFT }
292 { RIGHT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, LEFT, RIGHT,
293 RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, LEFT, RIGHT, RIGHT, RIGHT,
294 RIGHT, LEFT, LEFT, LEFT }
297 { ZERO, ZERO, ZERO, RIGHT, LEFT, RIGHT, ZERO, LEFT, ZERO, ZERO,
298 ZERO, RIGHT, LEFT, RIGHT, ZERO, LEFT, ZERO, ZERO, ZERO, RIGHT,
299 LEFT, RIGHT, ZERO, LEFT }
302 { ZERO, PIN, ZERO, ZERO, ZERO, ZERO, ZERO, PIN, RIGHT, RIGHT, PIN,
303 RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, RIGHT, ZERO, ZERO,
307 { ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN,
308 ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, ZERO, ZERO, ZERO, ZERO,
312 { ZERO, ZERO, PIN, PIN, ZERO, LEFT, ZERO, LEFT, RIGHT, PIN, RIGHT,
313 ZERO, PIN, PIN, ZERO, RIGHT, PIN, RIGHT, LEFT, ZERO, LEFT, ZERO,
316 /* These models were taken from Andrew and Peter's original snake.c
317 * as well as some newer ones made up by Jamie, Andrew and Peter. */
319 { LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT,
320 LEFT, LEFT, LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT,
321 RIGHT, LEFT, LEFT, LEFT }
324 { RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT, RIGHT, RIGHT,
325 LEFT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT,
326 RIGHT, RIGHT, LEFT, LEFT }
329 { PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN,
330 ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN }
333 { PIN, LEFT, PIN, LEFT, PIN, LEFT, PIN, LEFT, PIN, LEFT, PIN,
334 LEFT, PIN, LEFT, PIN, LEFT, PIN, LEFT, PIN, LEFT, PIN, LEFT, PIN }
337 { RIGHT, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT,
338 LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, RIGHT, PIN,
342 { RIGHT, LEFT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT,
343 LEFT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT,
344 RIGHT, RIGHT, LEFT, LEFT }
347 { ZERO, RIGHT, LEFT, ZERO, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT,
348 LEFT, RIGHT, LEFT, LEFT, PIN, LEFT, LEFT, LEFT, RIGHT, LEFT,
349 RIGHT, RIGHT, RIGHT }
352 { RIGHT, PIN, ZERO, ZERO, PIN, LEFT, ZERO, LEFT, LEFT, ZERO,
353 LEFT, PIN, ZERO, ZERO, PIN, RIGHT, PIN, LEFT, PIN, ZERO, ZERO,
357 { PIN, RIGHT, LEFT, RIGHT, RIGHT, LEFT, PIN, LEFT, RIGHT, LEFT,
358 LEFT, RIGHT, PIN, RIGHT, LEFT, RIGHT, RIGHT, LEFT, PIN, LEFT,
362 { ZERO, ZERO, ZERO, ZERO, LEFT, ZERO, ZERO, RIGHT, ZERO, ZERO,
363 ZERO, ZERO, LEFT, ZERO, ZERO, RIGHT, ZERO, ZERO, ZERO, ZERO,
364 LEFT, ZERO, ZERO, RIGHT }
367 { ZERO, ZERO, LEFT, RIGHT, ZERO, LEFT, ZERO, RIGHT, ZERO, ZERO,
368 LEFT, RIGHT, ZERO, LEFT, ZERO, RIGHT, ZERO, ZERO, LEFT, RIGHT,
369 ZERO, LEFT, ZERO, RIGHT }
372 { ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, LEFT, RIGHT, ZERO, ZERO,
373 ZERO, ZERO, ZERO, ZERO, LEFT, RIGHT, ZERO, ZERO, ZERO, ZERO,
374 ZERO, ZERO, LEFT, RIGHT }
377 { ZERO, LEFT, PIN, RIGHT, RIGHT, PIN, ZERO, LEFT, PIN, RIGHT,
378 RIGHT, PIN, ZERO, LEFT, PIN, RIGHT, RIGHT, PIN, ZERO, LEFT, PIN,
382 { ZERO, PIN, PIN, ZERO, PIN, ZERO, PIN, PIN, ZERO, PIN, ZERO, PIN,
383 PIN, ZERO, PIN, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO, ZERO, PIN }
386 { PIN, RIGHT, LEFT, PIN, LEFT, PIN, ZERO, ZERO, RIGHT, PIN, LEFT,
387 ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO,
391 { ZERO, ZERO, ZERO, ZERO, RIGHT, RIGHT, ZERO, LEFT, PIN, RIGHT,
392 ZERO, RIGHT, ZERO, RIGHT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT,
396 { RIGHT, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, PIN, PIN, ZERO,
397 LEFT, ZERO, LEFT, PIN, RIGHT, ZERO, LEFT, LEFT, LEFT, PIN, RIGHT,
401 { ZERO, ZERO, ZERO, ZERO, PIN, PIN, ZERO, PIN, ZERO, ZERO, PIN,
402 ZERO, PIN, PIN, ZERO, ZERO, ZERO, PIN, ZERO, PIN, PIN, ZERO, PIN }
405 { RIGHT, RIGHT, LEFT, LEFT, RIGHT, PIN, RIGHT, PIN, LEFT, PIN,
406 RIGHT, ZERO, LEFT, ZERO, LEFT, PIN, RIGHT, ZERO, LEFT, LEFT,
410 { LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, ZERO, ZERO, ZERO,
411 RIGHT, ZERO, ZERO, LEFT, RIGHT, ZERO, ZERO, ZERO, LEFT, LEFT,
412 RIGHT, LEFT, RIGHT, RIGHT }
415 { LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, ZERO, PIN, ZERO, ZERO,
416 LEFT, PIN, RIGHT, ZERO, ZERO, PIN, ZERO, LEFT, LEFT, RIGHT, LEFT,
420 { ZERO, PIN, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, ZERO, ZERO,
421 RIGHT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT,
425 { LEFT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT,
426 ZERO, ZERO, ZERO, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN,
430 { RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, PIN,
431 LEFT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, LEFT,
435 { RIGHT, PIN, RIGHT, RIGHT, RIGHT, PIN, LEFT, LEFT, LEFT, PIN,
436 LEFT, PIN, RIGHT, PIN, RIGHT, RIGHT, RIGHT, PIN, LEFT, LEFT,
437 LEFT, PIN, LEFT, PIN }
440 { ZERO, PIN, RIGHT, RIGHT, RIGHT, PIN, LEFT, LEFT, LEFT, PIN,
441 ZERO, PIN, ZERO, PIN, RIGHT, RIGHT, RIGHT, PIN, LEFT, LEFT, LEFT,
445 { ZERO, PIN, ZERO, RIGHT, RIGHT, PIN, LEFT, LEFT, ZERO, PIN,
446 ZERO, PIN, ZERO, PIN, ZERO, RIGHT, RIGHT, PIN, LEFT, LEFT, ZERO,
450 { ZERO, PIN, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, PIN,
451 ZERO, PIN, ZERO, PIN, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO,
455 { ZERO, RIGHT, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, LEFT,
456 ZERO, PIN, ZERO, RIGHT, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO,
460 { ZERO, ZERO, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, ZERO,
461 ZERO, PIN, ZERO, ZERO, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO,
465 { ZERO, ZERO, ZERO, RIGHT, RIGHT, PIN, LEFT, LEFT, ZERO, ZERO,
466 ZERO, PIN, ZERO, ZERO, ZERO, RIGHT, RIGHT, PIN, LEFT, LEFT, ZERO,
470 { RIGHT, ZERO, ZERO, RIGHT, RIGHT, PIN, LEFT, LEFT, ZERO, ZERO,
471 LEFT, PIN, RIGHT, ZERO, ZERO, RIGHT, RIGHT, PIN, LEFT, LEFT,
472 ZERO, ZERO, LEFT, PIN }
475 { RIGHT, ZERO, LEFT, RIGHT, RIGHT, PIN, LEFT, LEFT, RIGHT,
476 ZERO, LEFT, PIN, RIGHT, ZERO, LEFT, RIGHT, RIGHT, PIN, LEFT,
477 LEFT, RIGHT, ZERO, LEFT, PIN }
480 { RIGHT, ZERO, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, ZERO,
481 LEFT, PIN, RIGHT, ZERO, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT,
485 { ZERO, ZERO, RIGHT, ZERO, ZERO, PIN, ZERO, ZERO, LEFT, ZERO,
486 ZERO, PIN, ZERO, ZERO, RIGHT, ZERO, ZERO, PIN, ZERO, ZERO, LEFT,
490 { ZERO, ZERO, PIN, PIN, ZERO, RIGHT, PIN, LEFT, PIN, RIGHT, PIN,
491 RIGHT, PIN, LEFT, PIN, RIGHT, ZERO, ZERO, PIN, ZERO, ZERO, LEFT,
495 { LEFT, PIN, LEFT, PIN, ZERO, PIN, PIN, ZERO, PIN, ZERO, LEFT,
496 PIN, RIGHT, ZERO, PIN, ZERO, PIN, PIN, ZERO, ZERO, LEFT, PIN,
500 { RIGHT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, ZERO, ZERO,
501 ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, ZERO, RIGHT, RIGHT, LEFT,
502 RIGHT, LEFT, LEFT, LEFT, PIN }
505 { ZERO, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, ZERO, RIGHT,
506 RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, PIN, ZERO, LEFT, RIGHT,
507 PIN, LEFT, LEFT, LEFT }
510 { PIN, LEFT, RIGHT, LEFT, LEFT, PIN, RIGHT, ZERO, RIGHT, LEFT,
511 ZERO, PIN, LEFT, LEFT, RIGHT, RIGHT, RIGHT, PIN, LEFT, ZERO,
515 { PIN, PIN, ZERO, ZERO, PIN, ZERO, ZERO, RIGHT, ZERO, RIGHT,
516 RIGHT, PIN, RIGHT, RIGHT, ZERO, RIGHT, ZERO, ZERO, PIN, ZERO,
517 ZERO, PIN, PIN, ZERO }
520 /* the following modesl were created during the slug/compsoc codefest
523 { PIN, PIN, ZERO, ZERO, RIGHT, ZERO, ZERO, PIN, PIN, ZERO, LEFT,
524 ZERO, ZERO, PIN, ZERO, PIN, PIN, ZERO, LEFT, RIGHT, PIN, ZERO,
528 { ZERO, ZERO, ZERO, ZERO, PIN, RIGHT, ZERO, PIN, PIN, ZERO, PIN,
529 PIN, ZERO, RIGHT, RIGHT, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO,
533 { RIGHT, RIGHT, PIN, RIGHT, LEFT, RIGHT, PIN, RIGHT, LEFT,
534 RIGHT, PIN, RIGHT, LEFT, RIGHT, PIN, RIGHT, LEFT, RIGHT, PIN,
535 RIGHT, LEFT, RIGHT, PIN, ZERO }
538 { ZERO, ZERO, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO, ZERO, ZERO,
539 ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO,
543 { LEFT, ZERO, RIGHT, LEFT, RIGHT, ZERO, LEFT, RIGHT, LEFT, ZERO,
544 RIGHT, LEFT, RIGHT, ZERO, LEFT, RIGHT, LEFT, ZERO, RIGHT, LEFT,
545 RIGHT, ZERO, LEFT, ZERO }
548 { ZERO, PIN, PIN, ZERO, ZERO, ZERO, PIN, PIN, ZERO, LEFT, ZERO,
549 PIN, PIN, ZERO, RIGHT, LEFT, ZERO, PIN, ZERO, PIN, PIN, ZERO,
553 { ZERO, ZERO, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, ZERO, ZERO,
554 ZERO, PIN, ZERO, ZERO, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, ZERO,
558 { PIN, ZERO, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, ZERO, ZERO,
559 ZERO, PIN, ZERO, ZERO, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, ZERO,
562 { "erect penis", /* thanks benno */
563 { PIN, ZERO, PIN, PIN, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, PIN,
564 PIN, ZERO, ZERO, ZERO, RIGHT, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO,
568 { PIN, ZERO, PIN, PIN, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, PIN,
569 PIN, ZERO, ZERO, ZERO, RIGHT, PIN, ZERO, ZERO, ZERO, ZERO, ZERO,
573 { RIGHT, ZERO, ZERO, ZERO, RIGHT, ZERO, ZERO, PIN, ZERO, ZERO,
574 LEFT, ZERO, ZERO, ZERO, LEFT, ZERO, LEFT, PIN, LEFT, PIN, RIGHT,
578 { ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, PIN, ZERO, ZERO, PIN,
579 ZERO, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, ZERO, PIN, ZERO,
582 { "poles or columns or something",
583 { LEFT, RIGHT, LEFT, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO,
584 ZERO, LEFT, RIGHT, LEFT, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO,
588 { ZERO, LEFT, ZERO, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO,
589 ZERO, LEFT, ZERO, LEFT, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO,
593 { ZERO, LEFT, ZERO, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO, ZERO,
594 LEFT, ZERO, RIGHT, ZERO, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO,
598 { ZERO, ZERO, ZERO, ZERO, ZERO, LEFT, ZERO, ZERO, ZERO, ZERO,
599 LEFT, RIGHT, ZERO, ZERO, ZERO, ZERO, LEFT, RIGHT, ZERO, ZERO,
600 LEFT, PIN, ZERO, ZERO }
603 { ZERO, ZERO, PIN, RIGHT, ZERO, LEFT, ZERO, ZERO, RIGHT, ZERO,
604 LEFT, PIN, ZERO, ZERO, PIN, ZERO, LEFT, ZERO, RIGHT, LEFT, ZERO,
608 { PIN, ZERO, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO,
609 RIGHT, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, ZERO,
613 { PIN, ZERO, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO,
614 ZERO, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, ZERO,
618 { PIN, ZERO, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO,
619 LEFT, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, ZERO,
623 { PIN, ZERO, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO,
624 PIN, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, ZERO,
628 { RIGHT, ZERO, ZERO, LEFT, ZERO, LEFT, RIGHT, ZERO, RIGHT, LEFT,
629 RIGHT, PIN, RIGHT, LEFT, RIGHT, ZERO, RIGHT, LEFT, ZERO, LEFT,
630 ZERO, ZERO, RIGHT, ZERO }
633 { RIGHT, ZERO, RIGHT, ZERO, RIGHT, ZERO, RIGHT, ZERO, RIGHT,
634 ZERO, RIGHT, ZERO, RIGHT, LEFT, RIGHT, PIN, ZERO, RIGHT, ZERO,
635 RIGHT, ZERO, RIGHT, ZERO, ZERO }
638 /* These models come from the website at
639 * http://www.geocities.com/stigeide/snake */
641 { RIGHT, LEFT, RIGHT, ZERO, PIN, ZERO, LEFT, RIGHT, LEFT, PIN, ZERO, ZERO, PIN, LEFT, RIGHT, LEFT, ZERO, PIN, ZERO, RIGHT, LEFT, RIGHT, ZERO }
644 { LEFT, RIGHT, ZERO, RIGHT, LEFT, ZERO, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, PIN, RIGHT, LEFT, PIN }
647 { LEFT, RIGHT, ZERO, RIGHT, LEFT, ZERO, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT }
650 { LEFT, RIGHT, ZERO, RIGHT, LEFT, ZERO, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN }
653 { ZERO, ZERO, PIN, LEFT, RIGHT, LEFT, ZERO, RIGHT, LEFT, RIGHT, ZERO, PIN, ZERO, LEFT, RIGHT, LEFT, ZERO, RIGHT, LEFT, RIGHT, PIN, ZERO, ZERO }
656 { RIGHT, LEFT, RIGHT, PIN, ZERO, ZERO, PIN, RIGHT, LEFT, RIGHT, ZERO, PIN, PIN, ZERO, LEFT, LEFT, RIGHT, RIGHT, LEFT, LEFT, ZERO, PIN, PIN }
659 { ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, ZERO, RIGHT, LEFT }
662 { LEFT, PIN, RIGHT, ZERO, ZERO, PIN, RIGHT, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, PIN, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, LEFT, PIN, ZERO }
665 { LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT }
668 { ZERO, RIGHT, RIGHT, ZERO, RIGHT, RIGHT, ZERO, RIGHT, LEFT, ZERO, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, LEFT, RIGHT, PIN, LEFT, LEFT, ZERO, LEFT }
671 { PIN, LEFT, RIGHT, ZERO, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, ZERO, LEFT, RIGHT, PIN, RIGHT }
674 { PIN, PIN, LEFT, ZERO, PIN, PIN, ZERO, LEFT, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, RIGHT, PIN, PIN }
677 { LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT }
680 { RIGHT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, LEFT, LEFT }
683 { ZERO, PIN, ZERO, PIN, PIN, ZERO, PIN, ZERO, ZERO, PIN, ZERO, PIN, PIN, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, PIN }
686 { PIN, LEFT, ZERO, PIN, PIN, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, PIN, RIGHT, PIN, LEFT, ZERO, ZERO, RIGHT, PIN, LEFT, PIN, ZERO, ZERO }
689 { RIGHT, ZERO, PIN, RIGHT, PIN, RIGHT, ZERO, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, ZERO, RIGHT, PIN, RIGHT, ZERO, ZERO, LEFT }
692 { LEFT, PIN, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, PIN, RIGHT }
695 { ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO }
698 { RIGHT, ZERO, ZERO, PIN, LEFT, ZERO, PIN, PIN, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, LEFT, LEFT, PIN, RIGHT, RIGHT, LEFT, PIN, ZERO, ZERO }
701 { PIN, ZERO, ZERO, PIN, LEFT, LEFT, PIN, RIGHT, RIGHT, PIN, ZERO, ZERO, PIN, ZERO, ZERO, PIN, LEFT, LEFT, PIN, RIGHT, RIGHT, PIN, ZERO }
704 { RIGHT, LEFT, RIGHT, RIGHT, RIGHT, LEFT, RIGHT, ZERO, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, ZERO, LEFT, RIGHT, LEFT, LEFT }
707 { RIGHT, RIGHT, RIGHT, PIN, LEFT, PIN, LEFT, PIN, RIGHT, RIGHT, RIGHT, PIN, LEFT, LEFT, LEFT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, LEFT, LEFT }
710 { RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT }
713 { ZERO, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, LEFT, LEFT, ZERO, LEFT, RIGHT, ZERO, ZERO, PIN, ZERO, ZERO, RIGHT }
716 { LEFT, ZERO, PIN, ZERO, PIN, LEFT, ZERO, PIN, ZERO, LEFT, LEFT, PIN, RIGHT, RIGHT, ZERO, PIN, ZERO, RIGHT, PIN, ZERO, PIN, ZERO, RIGHT }
719 { ZERO, LEFT, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, ZERO, ZERO, LEFT, ZERO, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, LEFT }
722 { ZERO, ZERO, PIN, ZERO, ZERO, LEFT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, PIN, RIGHT, PIN, LEFT, ZERO, PIN, PIN, ZERO, ZERO, LEFT, PIN }
725 { LEFT, PIN, RIGHT, ZERO, ZERO, PIN, PIN, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, RIGHT, ZERO, ZERO, ZERO }
728 { ZERO, PIN, ZERO, PIN, PIN, ZERO, LEFT, PIN, RIGHT, ZERO, PIN, PIN, ZERO, PIN, ZERO, PIN, PIN, ZERO, LEFT, PIN, RIGHT, ZERO, PIN }
731 { PIN, RIGHT, ZERO, ZERO, PIN, ZERO, ZERO, PIN, PIN, ZERO, PIN, RIGHT, PIN, LEFT, PIN, ZERO, PIN, PIN, ZERO, ZERO, PIN, ZERO, ZERO }
734 { LEFT, ZERO, LEFT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, RIGHT, ZERO, RIGHT, PIN, RIGHT, PIN, LEFT }
737 { PIN, ZERO, ZERO, PIN, LEFT, LEFT, PIN, LEFT, RIGHT, RIGHT, PIN, LEFT, LEFT, RIGHT, PIN, RIGHT, RIGHT, PIN, ZERO, ZERO, PIN, RIGHT, PIN }
740 { RIGHT, PIN, ZERO, LEFT, LEFT, PIN, RIGHT, RIGHT, ZERO, PIN, LEFT, PIN, RIGHT, PIN, ZERO, LEFT, LEFT, PIN, RIGHT, RIGHT, ZERO, PIN, LEFT }
743 { ZERO, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, RIGHT, LEFT, PIN, LEFT, ZERO, PIN, PIN, ZERO, LEFT, PIN, LEFT, RIGHT, ZERO, RIGHT, ZERO, PIN }
745 { "Counterclockwise",
746 { LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT }
749 { LEFT, LEFT, ZERO, PIN, LEFT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, PIN, ZERO, RIGHT, RIGHT, LEFT, LEFT, ZERO, ZERO, RIGHT }
752 { ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, PIN, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, PIN, LEFT, PIN, RIGHT, ZERO, ZERO, ZERO, PIN, RIGHT }
755 { ZERO, PIN, ZERO, PIN, PIN, ZERO, PIN, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO, ZERO, PIN, ZERO, PIN, PIN, ZERO, PIN, ZERO, PIN }
758 { ZERO, ZERO, PIN, PIN, ZERO, LEFT, ZERO, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, ZERO, PIN, PIN, ZERO, LEFT, ZERO, ZERO, PIN, PIN, ZERO }
761 { ZERO, ZERO, PIN, PIN, ZERO, LEFT, ZERO, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, ZERO, PIN, PIN, ZERO, LEFT, ZERO, ZERO, PIN, PIN, ZERO }
764 { PIN, ZERO, RIGHT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, RIGHT, ZERO, PIN, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN }
767 { RIGHT, LEFT, PIN, LEFT, LEFT, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, LEFT, LEFT, PIN, LEFT, RIGHT }
770 { LEFT, ZERO, PIN, ZERO, RIGHT, ZERO, ZERO, LEFT, ZERO, PIN, ZERO, RIGHT, LEFT, ZERO, PIN, ZERO, RIGHT, ZERO, ZERO, LEFT, ZERO, PIN, ZERO }
773 { RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT }
776 { ZERO, RIGHT, ZERO, ZERO, LEFT, ZERO, ZERO, RIGHT, PIN, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, PIN, LEFT, ZERO, ZERO, RIGHT, ZERO, ZERO, LEFT }
779 { RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, ZERO, LEFT, RIGHT }
782 { ZERO, ZERO, PIN, PIN, ZERO, LEFT, LEFT, RIGHT, PIN, ZERO, PIN, PIN, ZERO, PIN, LEFT, RIGHT, RIGHT, ZERO, PIN, PIN, ZERO, ZERO, PIN }
785 { ZERO, ZERO, PIN, ZERO, ZERO, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, LEFT, LEFT, ZERO, PIN, ZERO, RIGHT, RIGHT, LEFT, PIN, LEFT, RIGHT }
788 { ZERO, LEFT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, LEFT, ZERO, LEFT, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT }
791 { ZERO, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO, ZERO, ZERO, LEFT, PIN, RIGHT, ZERO, ZERO, ZERO, ZERO, PIN }
794 { LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, LEFT, ZERO, LEFT, PIN, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT }
797 { LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, ZERO, RIGHT, ZERO, RIGHT, ZERO, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT }
800 { LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, LEFT, RIGHT, ZERO, RIGHT, LEFT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT }
803 { PIN, PIN, ZERO, ZERO, ZERO, ZERO, ZERO, LEFT, ZERO, ZERO, LEFT, RIGHT, ZERO, ZERO, LEFT, RIGHT, ZERO, ZERO, RIGHT, ZERO, ZERO, ZERO, ZERO }
806 { PIN, ZERO, ZERO, PIN, RIGHT, PIN, LEFT, PIN, ZERO, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, ZERO, PIN, RIGHT, PIN, LEFT, PIN, ZERO }
809 { ZERO, RIGHT, LEFT, ZERO, ZERO, ZERO, LEFT, RIGHT, ZERO, PIN, RIGHT, LEFT, ZERO, LEFT, RIGHT, LEFT, PIN, LEFT, RIGHT, LEFT, ZERO, LEFT, RIGHT }
812 { LEFT, LEFT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT }
815 { LEFT, LEFT, PIN, RIGHT, RIGHT, ZERO, LEFT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, PIN, RIGHT, PIN, LEFT, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT }
818 { RIGHT, RIGHT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, LEFT }
821 { RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, ZERO, RIGHT, LEFT, ZERO, ZERO, LEFT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT }
824 { ZERO, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, LEFT, PIN, RIGHT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, PIN, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT }
827 { LEFT, LEFT, RIGHT, PIN, ZERO, RIGHT, ZERO, LEFT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, ZERO, LEFT, ZERO, PIN, LEFT, RIGHT, RIGHT, RIGHT, PIN }
830 { PIN, ZERO, ZERO, PIN, PIN, ZERO, PIN, RIGHT, LEFT, RIGHT, RIGHT, PIN, LEFT, LEFT, RIGHT, LEFT, PIN, ZERO, PIN, PIN, ZERO, ZERO, PIN }
833 { ZERO, ZERO, LEFT, RIGHT, PIN, RIGHT, ZERO, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, ZERO, RIGHT, PIN, RIGHT, RIGHT, ZERO, PIN }
836 { ZERO, RIGHT, ZERO, PIN, LEFT, ZERO, LEFT, RIGHT, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, LEFT, RIGHT, ZERO, RIGHT, PIN, ZERO, LEFT, ZERO }
839 { ZERO, PIN, ZERO, ZERO, ZERO, ZERO, ZERO, PIN, LEFT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, LEFT, ZERO, ZERO, ZERO, PIN }
842 { ZERO, PIN, PIN, ZERO, PIN, RIGHT, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, RIGHT, ZERO, ZERO, PIN, ZERO, ZERO, PIN }
845 { ZERO, LEFT, PIN, RIGHT, ZERO, PIN, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT }
848 { LEFT, RIGHT, LEFT, RIGHT, RIGHT, PIN, LEFT, PIN, LEFT, RIGHT, RIGHT, PIN, LEFT, LEFT, RIGHT, RIGHT, PIN, LEFT, LEFT, RIGHT, PIN, RIGHT, PIN }
851 { LEFT, LEFT, RIGHT, RIGHT, LEFT, PIN, LEFT, PIN, RIGHT, PIN, LEFT, ZERO, RIGHT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, RIGHT, LEFT, RIGHT, RIGHT }
854 { LEFT, ZERO, LEFT, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, LEFT, RIGHT, PIN, LEFT, LEFT, RIGHT, ZERO, RIGHT }
857 { PIN, ZERO, LEFT, PIN, RIGHT, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, ZERO, PIN, ZERO, RIGHT, PIN, LEFT, ZERO, PIN, ZERO, ZERO, PIN }
860 { ZERO, ZERO, PIN, ZERO, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, LEFT, PIN, LEFT, LEFT, PIN, RIGHT, RIGHT, PIN, RIGHT, ZERO, PIN, PIN, ZERO }
863 { LEFT, LEFT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, ZERO, LEFT, RIGHT, ZERO, ZERO, LEFT, RIGHT }
866 { RIGHT, LEFT, ZERO, PIN, LEFT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, PIN, ZERO, RIGHT, LEFT, ZERO }
869 { PIN, PIN, ZERO, LEFT, RIGHT, LEFT, ZERO, PIN, RIGHT, PIN, LEFT, ZERO, ZERO, ZERO, ZERO, RIGHT, PIN, LEFT, PIN, ZERO, RIGHT, LEFT, RIGHT }
872 { PIN, ZERO, PIN, PIN, ZERO, ZERO, ZERO, ZERO, PIN, PIN, ZERO, PIN, LEFT, ZERO, PIN, PIN, ZERO, ZERO, ZERO, ZERO, PIN, PIN, ZERO }
875 { PIN, ZERO, RIGHT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, LEFT, PIN, RIGHT, RIGHT, PIN, RIGHT, LEFT, ZERO, ZERO }
878 { RIGHT, ZERO, ZERO, ZERO, PIN, LEFT, PIN, LEFT, RIGHT, RIGHT, ZERO, PIN, ZERO, LEFT, LEFT, RIGHT, PIN, RIGHT, PIN, ZERO, ZERO, ZERO, LEFT }
881 { ZERO, PIN, ZERO, ZERO, LEFT, ZERO, LEFT, ZERO, ZERO, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, ZERO, RIGHT, ZERO, RIGHT, ZERO, ZERO, PIN, ZERO }
884 { ZERO, ZERO, ZERO, ZERO, LEFT, ZERO, ZERO, RIGHT, ZERO, ZERO, ZERO, ZERO, LEFT, ZERO, ZERO, RIGHT, ZERO, ZERO, ZERO, ZERO, LEFT, ZERO, ZERO }
886 { "HoleInTheMiddle1",
887 { ZERO, LEFT, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, LEFT, RIGHT, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, RIGHT }
889 { "HoleInTheMiddle2",
890 { ZERO, LEFT, RIGHT, ZERO, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, RIGHT, LEFT, ZERO, LEFT, RIGHT, ZERO, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, RIGHT }
893 { RIGHT, RIGHT, PIN, LEFT, LEFT, LEFT, PIN, RIGHT, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, LEFT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, RIGHT, PIN }
896 { LEFT, PIN, LEFT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT }
899 { LEFT, LEFT, LEFT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, RIGHT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, RIGHT, LEFT, LEFT }
902 { RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT }
905 { ZERO, ZERO, ZERO, ZERO, PIN, RIGHT, ZERO, RIGHT, ZERO, ZERO, LEFT, PIN, RIGHT, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, RIGHT, ZERO, RIGHT }
908 { RIGHT, RIGHT, LEFT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, LEFT, LEFT, PIN, RIGHT, RIGHT, LEFT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, LEFT, LEFT }
911 { ZERO, PIN, PIN, ZERO, PIN, ZERO, PIN, PIN, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, PIN, PIN, ZERO, PIN, ZERO, PIN, PIN, ZERO }
914 { LEFT, LEFT, PIN, LEFT, ZERO, LEFT, RIGHT, LEFT, PIN, LEFT, LEFT, RIGHT, RIGHT, PIN, RIGHT, LEFT, RIGHT, ZERO, RIGHT, PIN, RIGHT, RIGHT, LEFT }
917 { ZERO, PIN, PIN, ZERO, ZERO, LEFT, ZERO, LEFT, ZERO, ZERO, PIN, ZERO, ZERO, RIGHT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO }
920 { RIGHT, PIN, LEFT, RIGHT, LEFT, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, RIGHT, LEFT, RIGHT, PIN, LEFT }
923 { PIN, ZERO, LEFT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, ZERO, PIN, ZERO, LEFT, PIN, LEFT, PIN, RIGHT, PIN, LEFT, ZERO, PIN, PIN, ZERO }
926 { PIN, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, RIGHT, LEFT, ZERO, LEFT }
929 { ZERO, ZERO, PIN, ZERO, LEFT, ZERO, PIN, PIN, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, ZERO, ZERO }
932 { ZERO, ZERO, ZERO, RIGHT, ZERO, RIGHT, LEFT, ZERO, LEFT, PIN, ZERO, PIN, ZERO, ZERO, PIN, ZERO, PIN, RIGHT, ZERO, RIGHT, LEFT, ZERO, LEFT }
935 { PIN, PIN, ZERO, ZERO, PIN, ZERO, RIGHT, PIN, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, PIN, LEFT, ZERO, PIN, PIN, ZERO, PIN, PIN }
938 { PIN, RIGHT, LEFT, ZERO, PIN, PIN, ZERO, ZERO, LEFT, RIGHT, ZERO, ZERO, PIN, ZERO, ZERO, LEFT, RIGHT, PIN, RIGHT, ZERO, PIN, PIN, ZERO }
941 { ZERO, LEFT, LEFT, PIN, RIGHT, ZERO, RIGHT, RIGHT, PIN, LEFT, LEFT, RIGHT, RIGHT, PIN, LEFT, LEFT, ZERO, LEFT, PIN, RIGHT, RIGHT, ZERO, RIGHT }
944 { ZERO, RIGHT, ZERO, RIGHT, LEFT, RIGHT, PIN, ZERO, LEFT, PIN, RIGHT, ZERO, PIN, LEFT, RIGHT, LEFT, ZERO, LEFT, ZERO, RIGHT, RIGHT, PIN, LEFT }
947 { LEFT, ZERO, PIN, PIN, ZERO, LEFT, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT }
950 { ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, LEFT, PIN, LEFT, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO }
953 { ZERO, PIN, ZERO, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, ZERO, PIN, ZERO }
955 { "MouseWithoutTail",
956 { ZERO, PIN, PIN, ZERO, LEFT, ZERO, PIN, PIN, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO }
959 { PIN, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, ZERO, LEFT, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, LEFT, ZERO, PIN }
962 { ZERO, ZERO, LEFT, ZERO, ZERO, ZERO, LEFT, ZERO, ZERO, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, ZERO, RIGHT, ZERO, ZERO, ZERO, RIGHT, ZERO, ZERO }
965 { LEFT, ZERO, PIN, LEFT, LEFT, RIGHT, RIGHT, PIN, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, LEFT }
968 { ZERO, RIGHT, PIN, LEFT, LEFT, LEFT, ZERO, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, ZERO, RIGHT, RIGHT, RIGHT, PIN, LEFT, ZERO }
971 { LEFT, PIN, RIGHT, PIN, RIGHT, ZERO, PIN, ZERO, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, RIGHT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, LEFT }
974 { PIN, ZERO, ZERO, ZERO, PIN, RIGHT, PIN, LEFT, PIN, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, ZERO, ZERO, ZERO }
977 { ZERO, ZERO, PIN, PIN, ZERO, LEFT, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, ZERO, ZERO, ZERO, ZERO, PIN }
980 { PIN, PIN, ZERO, PIN, LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, PIN, ZERO, PIN, ZERO, ZERO, PIN, ZERO }
983 { ZERO, PIN, ZERO, ZERO, PIN, ZERO, ZERO, PIN, ZERO, LEFT, ZERO, PIN, ZERO, RIGHT, ZERO, PIN, ZERO, ZERO, PIN, ZERO, ZERO, PIN, ZERO }
986 { ZERO, ZERO, ZERO, ZERO, RIGHT, RIGHT, ZERO, LEFT, PIN, RIGHT, ZERO, RIGHT, ZERO, RIGHT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, LEFT, ZERO, PIN }
989 { PIN, PIN, RIGHT, ZERO, PIN, PIN, ZERO, PIN, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, PIN, ZERO, PIN, PIN, ZERO, LEFT, PIN, PIN }
991 { "PictureCommingSoon",
992 { LEFT, LEFT, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, RIGHT, PIN, RIGHT, LEFT, ZERO, RIGHT, RIGHT }
995 { LEFT, PIN, ZERO, ZERO, PIN, ZERO, ZERO, PIN, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, PIN, ZERO, ZERO, PIN, ZERO, ZERO, PIN, RIGHT }
998 { LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, LEFT }
1001 { RIGHT, PIN, ZERO, ZERO, ZERO, ZERO, PIN, ZERO, ZERO, PIN, PIN, ZERO, PIN, LEFT, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, RIGHT }
1004 { ZERO, PIN, ZERO, PIN, RIGHT, PIN, ZERO, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, PIN, PIN, ZERO, ZERO, LEFT, ZERO, PIN, LEFT }
1007 { LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT }
1010 { RIGHT, PIN, ZERO, PIN, RIGHT, ZERO, PIN, PIN, ZERO, ZERO, LEFT, PIN, RIGHT, ZERO, ZERO, PIN, PIN, ZERO, LEFT, PIN, ZERO, PIN, LEFT }
1013 { ZERO, ZERO, ZERO, RIGHT, ZERO, LEFT, RIGHT, LEFT, ZERO, ZERO, ZERO, RIGHT, ZERO, LEFT, RIGHT, LEFT, ZERO, ZERO, ZERO, RIGHT, ZERO, LEFT, RIGHT }
1016 { ZERO, LEFT, PIN, RIGHT, ZERO, LEFT, PIN, RIGHT, ZERO, LEFT, PIN, RIGHT, ZERO, PIN, RIGHT, LEFT, LEFT, LEFT, PIN, RIGHT, RIGHT, RIGHT, LEFT }
1018 { "QuarterbackTiltedAndReadyToHut",
1019 { PIN, ZERO, RIGHT, RIGHT, LEFT, RIGHT, PIN, RIGHT, LEFT, RIGHT, ZERO, PIN, ZERO, LEFT, RIGHT, LEFT, PIN, LEFT, RIGHT, LEFT, LEFT, ZERO, PIN }
1022 { PIN, LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, ZERO, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT }
1025 { LEFT, ZERO, LEFT, ZERO, LEFT, ZERO, LEFT, LEFT, ZERO, LEFT, ZERO, LEFT, ZERO, LEFT, RIGHT, ZERO, PIN, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT }
1028 { ZERO, ZERO, ZERO, PIN, ZERO, ZERO, PIN, RIGHT, LEFT, LEFT, LEFT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, LEFT, PIN, ZERO, ZERO, PIN }
1031 { LEFT, LEFT, PIN, RIGHT, ZERO, PIN, ZERO, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, ZERO, PIN, ZERO, LEFT, PIN, RIGHT, RIGHT }
1034 { RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, PIN, ZERO, PIN, PIN, ZERO, PIN, ZERO, PIN, PIN, ZERO, PIN, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT }
1037 { RIGHT, ZERO, LEFT, PIN, RIGHT, ZERO, RIGHT, ZERO, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, ZERO, LEFT, ZERO, LEFT, PIN, RIGHT, ZERO, LEFT }
1040 { ZERO, LEFT, PIN, RIGHT, ZERO, PIN, LEFT, ZERO, PIN, ZERO, RIGHT, PIN, ZERO, LEFT, PIN, RIGHT, ZERO, PIN, LEFT, ZERO, PIN, ZERO, RIGHT }
1043 { PIN, PIN, RIGHT, ZERO, LEFT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, RIGHT, ZERO, LEFT, PIN, PIN }
1046 { RIGHT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, PIN, RIGHT, PIN, LEFT }
1049 { RIGHT, LEFT, PIN, ZERO, ZERO, ZERO, LEFT, RIGHT, LEFT, PIN, ZERO, ZERO, PIN, LEFT, RIGHT, LEFT, ZERO, ZERO, ZERO, PIN, LEFT, RIGHT, LEFT }
1052 { LEFT, LEFT, LEFT, PIN, RIGHT, RIGHT, RIGHT, ZERO, LEFT, PIN, RIGHT, ZERO, LEFT, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, PIN, PIN, ZERO, LEFT }
1055 { RIGHT, PIN, ZERO, LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, RIGHT, PIN, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, ZERO, LEFT, RIGHT, ZERO, ZERO }
1058 { RIGHT, LEFT, LEFT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, LEFT, LEFT, LEFT, RIGHT, LEFT }
1061 { LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, ZERO, ZERO, ZERO, ZERO, PIN, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, ZERO, RIGHT }
1064 { PIN, RIGHT, LEFT, LEFT, LEFT, LEFT, PIN, RIGHT, RIGHT, RIGHT, RIGHT, LEFT, ZERO, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, LEFT, ZERO, PIN, PIN }
1067 { LEFT, RIGHT, ZERO, RIGHT, LEFT, RIGHT, ZERO, RIGHT, LEFT, RIGHT, ZERO, RIGHT, LEFT, RIGHT, ZERO, RIGHT, LEFT, RIGHT, ZERO, RIGHT, LEFT, RIGHT, ZERO }
1070 { LEFT, RIGHT, LEFT, RIGHT, ZERO, LEFT, RIGHT, LEFT, PIN, ZERO, ZERO, PIN, ZERO, ZERO, PIN, RIGHT, LEFT, ZERO, ZERO, RIGHT, LEFT, RIGHT, LEFT }
1073 { ZERO, LEFT, RIGHT, ZERO, RIGHT, LEFT, ZERO, LEFT, RIGHT, ZERO, LEFT, RIGHT, ZERO, LEFT, RIGHT, ZERO, RIGHT, LEFT, ZERO, LEFT, RIGHT, ZERO, LEFT }
1075 { "SnakeReadyToStrike",
1076 { LEFT, ZERO, LEFT, ZERO, LEFT, ZERO, LEFT, RIGHT, ZERO, RIGHT, ZERO, RIGHT, ZERO, LEFT, ZERO, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, ZERO, LEFT }
1079 { RIGHT, RIGHT, PIN, ZERO, RIGHT, LEFT, RIGHT, ZERO, ZERO, ZERO, RIGHT, PIN, LEFT, PIN, ZERO, PIN, LEFT, PIN, RIGHT, ZERO, ZERO, LEFT, RIGHT }
1082 { ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, PIN, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, PIN, LEFT, PIN, RIGHT, ZERO, ZERO, ZERO, PIN, RIGHT }
1085 { PIN, PIN, LEFT, PIN, LEFT, PIN, RIGHT, ZERO, RIGHT, PIN, RIGHT, ZERO, RIGHT, PIN, LEFT, PIN, RIGHT, ZERO, PIN, PIN, ZERO, ZERO, PIN }
1088 { LEFT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, RIGHT }
1091 { ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, ZERO, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, ZERO, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO }
1094 { PIN, RIGHT, ZERO, PIN, ZERO, LEFT, PIN, RIGHT, PIN, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, PIN, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, PIN }
1097 { PIN, PIN, RIGHT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, PIN }
1100 { PIN, PIN, LEFT, PIN, LEFT, PIN, RIGHT, ZERO, PIN, PIN, ZERO, LEFT, PIN, RIGHT, ZERO, PIN, ZERO, LEFT, PIN, LEFT, LEFT, PIN, PIN }
1103 { LEFT, ZERO, ZERO, LEFT, PIN, RIGHT, ZERO, ZERO, LEFT, ZERO, ZERO, PIN, ZERO, ZERO, RIGHT, ZERO, ZERO, LEFT, PIN, RIGHT, ZERO, ZERO, RIGHT }
1106 { PIN, RIGHT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, ZERO, LEFT, PIN, RIGHT, ZERO, LEFT, LEFT, LEFT, RIGHT, RIGHT, LEFT, PIN, ZERO, RIGHT, PIN, LEFT }
1109 { RIGHT, RIGHT, ZERO, ZERO, LEFT, RIGHT, LEFT, PIN, ZERO, LEFT, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, RIGHT, LEFT, RIGHT, ZERO, ZERO, LEFT }
1112 { PIN, LEFT, ZERO, RIGHT, RIGHT, LEFT, PIN, ZERO, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, ZERO, PIN, RIGHT, LEFT, LEFT, ZERO }
1115 { ZERO, ZERO, LEFT, LEFT, PIN, RIGHT, RIGHT, ZERO, ZERO, LEFT, LEFT, PIN, RIGHT, RIGHT, ZERO, ZERO, LEFT, LEFT, PIN, RIGHT, RIGHT, ZERO, ZERO }
1118 { PIN, ZERO, PIN, ZERO, ZERO, PIN, PIN, ZERO, PIN, ZERO, ZERO, PIN, ZERO, ZERO, PIN, ZERO, PIN, PIN, ZERO, ZERO, PIN, ZERO, PIN }
1121 { RIGHT, ZERO, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, LEFT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, ZERO }
1124 { ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO }
1127 { ZERO, PIN, ZERO, PIN, ZERO, PIN, PIN, ZERO, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, PIN, ZERO, ZERO, PIN, ZERO }
1130 { ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO }
1133 { ZERO, PIN, ZERO, PIN, LEFT, LEFT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, RIGHT }
1136 { PIN, ZERO, PIN, RIGHT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, RIGHT, PIN, ZERO, ZERO, ZERO, ZERO, ZERO, PIN, PIN }
1139 { PIN, PIN, ZERO, ZERO, ZERO, RIGHT, ZERO, RIGHT, ZERO, ZERO, LEFT, PIN, RIGHT, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, RIGHT, ZERO, RIGHT }
1142 { RIGHT, RIGHT, PIN, ZERO, PIN, PIN, ZERO, PIN, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, PIN, ZERO, PIN, PIN, ZERO, PIN, LEFT, LEFT, RIGHT }
1145 { RIGHT, ZERO, LEFT, RIGHT, LEFT, ZERO, LEFT, RIGHT, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, LEFT, RIGHT, ZERO, RIGHT, LEFT, RIGHT, ZERO, LEFT }
1148 { ZERO, PIN, LEFT, LEFT, PIN, ZERO, ZERO, LEFT, PIN, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, PIN, LEFT }
1151 { ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, RIGHT, PIN, RIGHT, LEFT, ZERO, RIGHT, PIN }
1154 { ZERO, ZERO, RIGHT, LEFT, PIN, LEFT, ZERO, PIN, PIN, ZERO, LEFT, PIN, RIGHT, ZERO, PIN, PIN, ZERO, RIGHT, PIN, RIGHT, LEFT, ZERO, ZERO }
1157 { ZERO, ZERO, RIGHT, LEFT, PIN, LEFT, ZERO, PIN, PIN, ZERO, LEFT, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, RIGHT, PIN, RIGHT, LEFT, ZERO, ZERO }
1160 { RIGHT, ZERO, PIN, PIN, ZERO, LEFT, RIGHT, PIN, LEFT, LEFT, RIGHT, RIGHT, PIN, LEFT, LEFT, RIGHT, RIGHT, PIN, LEFT, LEFT, RIGHT, RIGHT, PIN }
1163 { RIGHT, ZERO, ZERO, RIGHT, LEFT, ZERO, ZERO, RIGHT, LEFT, ZERO, ZERO, LEFT, RIGHT, ZERO, ZERO, RIGHT, LEFT, ZERO, ZERO, RIGHT, LEFT, ZERO, ZERO }
1166 { RIGHT, LEFT, ZERO, RIGHT, LEFT, PIN, LEFT, LEFT, PIN, LEFT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT, PIN, RIGHT, RIGHT, PIN, RIGHT, LEFT }
1169 { PIN, ZERO, PIN, PIN, ZERO, PIN, ZERO, ZERO, ZERO, PIN, PIN, ZERO, PIN, ZERO, ZERO, PIN, ZERO, PIN, PIN, ZERO, ZERO, ZERO, ZERO }
1172 { RIGHT, ZERO, LEFT, RIGHT, ZERO, LEFT, PIN, RIGHT, ZERO, RIGHT, ZERO, PIN, ZERO, LEFT, ZERO, LEFT, PIN, RIGHT, ZERO, LEFT, RIGHT, ZERO, LEFT }
1175 { RIGHT, ZERO, ZERO, RIGHT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, RIGHT, PIN, LEFT, LEFT, PIN, LEFT, PIN, RIGHT, PIN, LEFT, ZERO, ZERO, LEFT }
1178 { ZERO, PIN, RIGHT, LEFT, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, PIN, PIN, ZERO, LEFT, LEFT, PIN, ZERO, LEFT, RIGHT, ZERO, PIN, ZERO, LEFT }
1181 { PIN, LEFT, LEFT, PIN, LEFT, ZERO, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, PIN, RIGHT, PIN, RIGHT, RIGHT, PIN, ZERO }
1184 { PIN, ZERO, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, ZERO, PIN, ZERO, ZERO, ZERO }
1187 { ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, RIGHT, LEFT, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, RIGHT, LEFT, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, RIGHT }
1190 { PIN, ZERO, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, PIN, ZERO, PIN, LEFT, PIN, RIGHT, PIN, ZERO, PIN, LEFT, PIN, LEFT, PIN, RIGHT, PIN }
1193 { RIGHT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, LEFT, PIN, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, ZERO, LEFT, RIGHT, ZERO }
1196 { ZERO, PIN, ZERO, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, PIN, ZERO, ZERO, PIN, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, ZERO, PIN, ZERO, ZERO }
1199 { ZERO, PIN, ZERO, ZERO, PIN, PIN, ZERO, PIN, ZERO, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, PIN, RIGHT, PIN, LEFT, ZERO, ZERO, RIGHT, PIN }
1202 { PIN, LEFT, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, LEFT, ZERO }
1205 { LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, LEFT, PIN, LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT }
1208 { LEFT, PIN, RIGHT, PIN, RIGHT, LEFT, ZERO, PIN, PIN, ZERO, RIGHT, LEFT, ZERO, PIN, PIN, ZERO, RIGHT, LEFT, PIN, LEFT, PIN, RIGHT, ZERO }
1211 { ZERO, PIN, ZERO, PIN, ZERO, PIN, LEFT, PIN, RIGHT, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, LEFT, PIN, RIGHT, PIN, ZERO }
1214 { ZERO, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, PIN, ZERO, ZERO, LEFT, PIN, RIGHT, ZERO, ZERO, PIN, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, ZERO }
1217 { PIN, ZERO, ZERO, ZERO, PIN, PIN, ZERO, RIGHT, RIGHT, LEFT, LEFT, PIN, RIGHT, RIGHT, LEFT, LEFT, ZERO, PIN, PIN, ZERO, ZERO, ZERO, PIN }
1220 { ZERO, RIGHT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, LEFT, RIGHT, ZERO, PIN, ZERO, LEFT, RIGHT, LEFT, PIN, LEFT, PIN, RIGHT, PIN, LEFT, ZERO }
1223 { PIN, RIGHT, PIN, LEFT, PIN, ZERO, ZERO, PIN, RIGHT, ZERO, RIGHT, RIGHT, ZERO, RIGHT, PIN, ZERO, ZERO, PIN, LEFT, PIN, RIGHT, PIN, ZERO }
1226 { ZERO, RIGHT, PIN, LEFT, PIN, RIGHT, ZERO, ZERO, RIGHT, PIN, LEFT, LEFT, RIGHT, RIGHT, PIN, LEFT, ZERO, ZERO, LEFT, PIN, RIGHT, PIN, LEFT }
1229 { LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT }
1232 { PIN, RIGHT, RIGHT, PIN, ZERO, LEFT, PIN, RIGHT, RIGHT, PIN, ZERO, LEFT, PIN, RIGHT, RIGHT, PIN, ZERO, LEFT, PIN, RIGHT, RIGHT, PIN, ZERO }
1235 { PIN, ZERO, PIN, PIN, ZERO, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, ZERO, PIN, ZERO, PIN, ZERO, PIN, PIN, ZERO, ZERO, ZERO, ZERO }
1237 { "WindowToTheWorld",
1238 { PIN, LEFT, ZERO, PIN, ZERO, ZERO, PIN, ZERO, ZERO, PIN, ZERO, RIGHT, PIN, LEFT, ZERO, PIN, ZERO, ZERO, PIN, ZERO, ZERO, PIN, ZERO }
1241 { PIN, PIN, ZERO, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, ZERO, PIN, ZERO, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, ZERO, PIN, PIN, ZERO, PIN }
1244 { ZERO, ZERO, ZERO, ZERO, PIN, RIGHT, RIGHT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, RIGHT, RIGHT, PIN, ZERO, ZERO, ZERO, ZERO }
1247 { RIGHT, ZERO, PIN, ZERO, LEFT, PIN, RIGHT, PIN, RIGHT, LEFT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, LEFT, PIN, LEFT, PIN, RIGHT, ZERO, PIN, ZERO }
1250 { PIN, RIGHT, PIN, RIGHT, RIGHT, PIN, LEFT, LEFT, PIN, ZERO, PIN, RIGHT, PIN, LEFT, PIN, ZERO, PIN, RIGHT, RIGHT, PIN, LEFT, LEFT, PIN }
1253 { ZERO, ZERO, PIN, PIN, ZERO, PIN, ZERO, ZERO, PIN, ZERO, PIN, PIN, ZERO, PIN, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO, ZERO, PIN }
1256 { LEFT, ZERO, ZERO, PIN, LEFT, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, PIN, PIN, ZERO, LEFT, RIGHT, PIN, LEFT, LEFT, RIGHT, PIN, ZERO, ZERO }
1260 int models = (sizeof(model) / sizeof(struct model_s));
1262 #define VOFFSET 0.045
1268 /* the connecting string that holds the snake together */
1269 #define MAGICAL_RED_STRING 0
1271 #define GETSCALAR(vec,mask) ((vec)==(mask) ? 1 : ((vec)==-(mask) ? -1 : 0 ))
1274 # define MAX(x, y) ((x) > (y) ? (x) : (y))
1277 # define MIN(x, y) ((x) < (y) ? (x) : (y))
1280 #define RAND(n) ((random() & 0x7fffffff) % ((long) (n)))
1281 #define RANDSIGN() ((random() & 1) ? 1 : -1)
1283 /* the triangular prism what makes up the basic unit */
1284 float solid_prism_v[][3] = {
1285 /* first corner, bottom left front */
1286 { VOFFSET, VOFFSET, 1.0 },
1287 { VOFFSET, 0.00, 1.0 - VOFFSET },
1288 { 0.00, VOFFSET, 1.0 - VOFFSET },
1289 /* second corner, rear */
1290 { VOFFSET, VOFFSET, 0.00 },
1291 { VOFFSET, 0.00, VOFFSET },
1292 { 0.00, VOFFSET, VOFFSET },
1293 /* third, right front */
1294 { 1.0 - VOFFSET / M_SQRT1_2, VOFFSET, 1.0 },
1295 { 1.0 - VOFFSET / M_SQRT1_2, 0.0, 1.0 - VOFFSET },
1296 { 1.0 - VOFFSET * M_SQRT1_2, VOFFSET, 1.0 - VOFFSET },
1297 /* fourth, right rear */
1298 { 1.0 - VOFFSET / M_SQRT1_2, VOFFSET, 0.0 },
1299 { 1.0 - VOFFSET / M_SQRT1_2, 0.0, VOFFSET },
1300 { 1.0 - VOFFSET * M_SQRT1_2, VOFFSET, VOFFSET },
1301 /* fifth, upper front */
1302 { VOFFSET, 1.0 - VOFFSET / M_SQRT1_2, 1.0 },
1303 { VOFFSET / M_SQRT1_2, 1.0 - VOFFSET * M_SQRT1_2, 1.0 - VOFFSET },
1304 { 0.0, 1.0 - VOFFSET / M_SQRT1_2, 1.0 - VOFFSET},
1305 /* sixth, upper rear */
1306 { VOFFSET, 1.0 - VOFFSET / M_SQRT1_2, 0.0 },
1307 { VOFFSET / M_SQRT1_2, 1.0 - VOFFSET * M_SQRT1_2, VOFFSET },
1308 { 0.0, 1.0 - VOFFSET / M_SQRT1_2, VOFFSET }};
1310 float solid_prism_n[][3] = {/* corners */
1311 { -VOFFSET, -VOFFSET, VOFFSET },
1312 { VOFFSET, -VOFFSET, VOFFSET },
1313 { -VOFFSET, VOFFSET, VOFFSET },
1314 { -VOFFSET, -VOFFSET, -VOFFSET },
1315 { VOFFSET, -VOFFSET, -VOFFSET },
1316 { -VOFFSET, VOFFSET, -VOFFSET },
1318 { -VOFFSET, 0.0, VOFFSET },
1319 { 0.0, -VOFFSET, VOFFSET },
1320 { VOFFSET, VOFFSET, VOFFSET },
1321 { -VOFFSET, 0.0, -VOFFSET },
1322 { 0.0, -VOFFSET, -VOFFSET },
1323 { VOFFSET, VOFFSET, -VOFFSET },
1324 { -VOFFSET, -VOFFSET, 0.0 },
1325 { VOFFSET, -VOFFSET, 0.0 },
1326 { -VOFFSET, VOFFSET, 0.0 },
1330 { M_SQRT1_2, M_SQRT1_2, 0.0 },
1332 { 0.0, 0.0, -1.0 }};
1334 float wire_prism_v[][3] = {{ 0.0, 0.0, 1.0 },
1341 float wire_prism_n[][3] = {{ 0.0, 0.0, 1.0},
1343 { M_SQRT1_2, M_SQRT1_2, 0.0},
1347 static struct glsnake_cfg * glc = NULL;
1352 typedef float (*morphFunc)(long);
1355 /* forward definitions for GLUT functions */
1356 void calc_rotation();
1357 inline void ui_mousedrag();
1365 float light_pos[][3] = {{0.0, 0.0, 20.0}, {0.0, 20.0, 0.0}};
1366 float light_dir[][3] = {{0.0, 0.0,-20.0}, {0.0,-20.0, 0.0}};
1368 glClearColor(0.0, 0.0, 0.0, 0.0);
1369 glEnable(GL_DEPTH_TEST);
1370 glShadeModel(GL_SMOOTH);
1371 glCullFace(GL_BACK);
1372 glEnable(GL_CULL_FACE);
1373 glEnable(GL_NORMALIZE);
1376 glColor3f(1.0, 1.0, 1.0);
1377 glLightfv(GL_LIGHT0, GL_POSITION, light_pos[0]);
1378 glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, light_dir[0]);
1379 glLightfv(GL_LIGHT1, GL_POSITION, light_pos[1]);
1380 glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, light_dir[1]);
1381 glEnable(GL_LIGHTING);
1382 glEnable(GL_LIGHT0);
1383 glEnable(GL_LIGHT1);
1384 glEnable(GL_COLOR_MATERIAL);
1388 void gettime(snaketime *t)
1390 #ifdef HAVE_GETTIMEOFDAY
1391 #ifdef GETTIMEOFDAY_TWO_ARGS
1392 struct timezone tzp;
1393 gettimeofday(t, &tzp);
1394 #else /* !GETTIMEOFDAY_TWO_ARGS */
1396 #endif /* !GETTIMEOFDAY_TWO_ARGS */
1397 #else /* !HAVE_GETTIMEOFDAY */
1400 #endif /* HAVE_FTIME */
1401 #endif /* !HAVE_GETTIMEOFDAY */
1405 void start_morph(int model_index, int immediate);
1407 /* wot initialises it */
1414 struct glsnake_cfg * bp;
1416 /* set up the conf struct and glx contexts */
1418 glc = (struct glsnake_cfg *) calloc(MI_NUM_SCREENS(mi), sizeof(struct glsnake_cfg));
1420 fprintf(stderr, "%s: out of memory\n", progname);
1424 bp = &glc[MI_SCREEN(mi)];
1426 if ((bp->glx_context = init_GL(mi)) != NULL) {
1428 glsnake_reshape(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
1434 /* initialise conf struct */
1435 memset(&bp->node, 0, sizeof(float) * NODE_COUNT);
1445 gettime(&bp->last_iteration);
1446 memcpy(&bp->last_morph, &bp->last_iteration, sizeof(bp->last_morph));
1448 bp->prev_colour = bp->next_colour = COLOUR_ACYCLIC;
1449 bp->next_model = RAND(models);
1450 bp->prev_model = START_MODEL;
1451 start_morph(bp->prev_model, 1);
1453 /* set up a font for the labels */
1456 load_font(mi->dpy, "labelfont", &bp->font, &bp->font_list);
1459 /* build a solid display list */
1460 glc->node_solid = glGenLists(1);
1461 glNewList(glc->node_solid, GL_COMPILE);
1463 glBegin(GL_TRIANGLES);
1464 glNormal3fv(solid_prism_n[0]);
1465 glVertex3fv(solid_prism_v[0]);
1466 glVertex3fv(solid_prism_v[2]);
1467 glVertex3fv(solid_prism_v[1]);
1469 glNormal3fv(solid_prism_n[1]);
1470 glVertex3fv(solid_prism_v[6]);
1471 glVertex3fv(solid_prism_v[7]);
1472 glVertex3fv(solid_prism_v[8]);
1474 glNormal3fv(solid_prism_n[2]);
1475 glVertex3fv(solid_prism_v[12]);
1476 glVertex3fv(solid_prism_v[13]);
1477 glVertex3fv(solid_prism_v[14]);
1479 glNormal3fv(solid_prism_n[3]);
1480 glVertex3fv(solid_prism_v[3]);
1481 glVertex3fv(solid_prism_v[4]);
1482 glVertex3fv(solid_prism_v[5]);
1484 glNormal3fv(solid_prism_n[4]);
1485 glVertex3fv(solid_prism_v[9]);
1486 glVertex3fv(solid_prism_v[11]);
1487 glVertex3fv(solid_prism_v[10]);
1489 glNormal3fv(solid_prism_n[5]);
1490 glVertex3fv(solid_prism_v[16]);
1491 glVertex3fv(solid_prism_v[15]);
1492 glVertex3fv(solid_prism_v[17]);
1496 glNormal3fv(solid_prism_n[6]);
1497 glVertex3fv(solid_prism_v[0]);
1498 glVertex3fv(solid_prism_v[12]);
1499 glVertex3fv(solid_prism_v[14]);
1500 glVertex3fv(solid_prism_v[2]);
1502 glNormal3fv(solid_prism_n[7]);
1503 glVertex3fv(solid_prism_v[0]);
1504 glVertex3fv(solid_prism_v[1]);
1505 glVertex3fv(solid_prism_v[7]);
1506 glVertex3fv(solid_prism_v[6]);
1508 glNormal3fv(solid_prism_n[8]);
1509 glVertex3fv(solid_prism_v[6]);
1510 glVertex3fv(solid_prism_v[8]);
1511 glVertex3fv(solid_prism_v[13]);
1512 glVertex3fv(solid_prism_v[12]);
1514 glNormal3fv(solid_prism_n[9]);
1515 glVertex3fv(solid_prism_v[3]);
1516 glVertex3fv(solid_prism_v[5]);
1517 glVertex3fv(solid_prism_v[17]);
1518 glVertex3fv(solid_prism_v[15]);
1520 glNormal3fv(solid_prism_n[10]);
1521 glVertex3fv(solid_prism_v[3]);
1522 glVertex3fv(solid_prism_v[9]);
1523 glVertex3fv(solid_prism_v[10]);
1524 glVertex3fv(solid_prism_v[4]);
1526 glNormal3fv(solid_prism_n[11]);
1527 glVertex3fv(solid_prism_v[15]);
1528 glVertex3fv(solid_prism_v[16]);
1529 glVertex3fv(solid_prism_v[11]);
1530 glVertex3fv(solid_prism_v[9]);
1532 glNormal3fv(solid_prism_n[12]);
1533 glVertex3fv(solid_prism_v[1]);
1534 glVertex3fv(solid_prism_v[2]);
1535 glVertex3fv(solid_prism_v[5]);
1536 glVertex3fv(solid_prism_v[4]);
1538 glNormal3fv(solid_prism_n[13]);
1539 glVertex3fv(solid_prism_v[8]);
1540 glVertex3fv(solid_prism_v[7]);
1541 glVertex3fv(solid_prism_v[10]);
1542 glVertex3fv(solid_prism_v[11]);
1544 glNormal3fv(solid_prism_n[14]);
1545 glVertex3fv(solid_prism_v[13]);
1546 glVertex3fv(solid_prism_v[16]);
1547 glVertex3fv(solid_prism_v[17]);
1548 glVertex3fv(solid_prism_v[14]);
1552 glBegin(GL_TRIANGLES);
1553 glNormal3fv(solid_prism_n[15]);
1554 glVertex3fv(solid_prism_v[0]);
1555 glVertex3fv(solid_prism_v[6]);
1556 glVertex3fv(solid_prism_v[12]);
1558 glNormal3fv(solid_prism_n[19]);
1559 glVertex3fv(solid_prism_v[3]);
1560 glVertex3fv(solid_prism_v[15]);
1561 glVertex3fv(solid_prism_v[9]);
1565 glNormal3fv(solid_prism_n[16]);
1566 glVertex3fv(solid_prism_v[1]);
1567 glVertex3fv(solid_prism_v[4]);
1568 glVertex3fv(solid_prism_v[10]);
1569 glVertex3fv(solid_prism_v[7]);
1571 glNormal3fv(solid_prism_n[17]);
1572 glVertex3fv(solid_prism_v[8]);
1573 glVertex3fv(solid_prism_v[11]);
1574 glVertex3fv(solid_prism_v[16]);
1575 glVertex3fv(solid_prism_v[13]);
1577 glNormal3fv(solid_prism_n[18]);
1578 glVertex3fv(solid_prism_v[2]);
1579 glVertex3fv(solid_prism_v[14]);
1580 glVertex3fv(solid_prism_v[17]);
1581 glVertex3fv(solid_prism_v[5]);
1585 /* build wire display list */
1586 glc->node_wire = glGenLists(1);
1587 glNewList(glc->node_wire, GL_COMPILE);
1588 glBegin(GL_LINE_STRIP);
1589 glVertex3fv(wire_prism_v[0]);
1590 glVertex3fv(wire_prism_v[1]);
1591 glVertex3fv(wire_prism_v[2]);
1592 glVertex3fv(wire_prism_v[0]);
1593 glVertex3fv(wire_prism_v[3]);
1594 glVertex3fv(wire_prism_v[4]);
1595 glVertex3fv(wire_prism_v[5]);
1596 glVertex3fv(wire_prism_v[3]);
1599 glVertex3fv(wire_prism_v[1]);
1600 glVertex3fv(wire_prism_v[4]);
1601 glVertex3fv(wire_prism_v[2]);
1602 glVertex3fv(wire_prism_v[5]);
1607 /* initialise the rotation */
1618 struct glsnake_cfg * bp = &glc[MI_SCREEN(mi)];
1621 /* draw some text */
1622 glPushAttrib(GL_TRANSFORM_BIT | GL_ENABLE_BIT);
1623 glDisable(GL_LIGHTING);
1624 glDisable(GL_DEPTH_TEST);
1625 glMatrixMode(GL_PROJECTION);
1628 glMatrixMode(GL_MODELVIEW);
1632 gluOrtho2D(0, glc->width, 0, glc->height);
1634 gluOrtho2D(0, mi->xgwa.width, 0, mi->xgwa.height);
1636 glColor3f(1.0, 1.0, 1.0);
1638 char interactstr[] = "interactive";
1643 s = model[glc->next_model].name;
1645 print_gl_string (mi->dpy, bp->font, bp->font_list,
1646 mi->xgwa.width, mi->xgwa.height,
1647 10, mi->xgwa.height - 10,
1651 glMatrixMode(GL_PROJECTION);
1656 /* apply the matrix to the origin and stick it in vec */
1657 void matmult_origin(float rotmat[16], float vec[4]) {
1659 vec[0] = 0.5 * rotmat[0] + 0.5 * rotmat[4] + 0.5 * rotmat [8] + 1 * rotmat[12];
1660 vec[1] = 0.5 * rotmat[1] + 0.5 * rotmat[5] + 0.5 * rotmat [9] + 1 * rotmat[13];
1661 vec[2] = 0.5 * rotmat[2] + 0.5 * rotmat[6] + 0.5 * rotmat[10] + 1 * rotmat[14];
1662 vec[3] = 0.5 * rotmat[3] + 0.5 * rotmat[7] + 0.5 * rotmat[11] + 1 * rotmat[15];
1664 vec[0] = 0 * rotmat [0] + 0 * rotmat [1] + 0 * rotmat [2] + 1 * rotmat [3];
1665 vec[1] = 0 * rotmat [4] + 0 * rotmat [5] + 0 * rotmat [6] + 1 * rotmat [7];
1666 vec[2] = 0 * rotmat [8] + 0 * rotmat [9] + 0 * rotmat[10] + 1 * rotmat[11];
1667 vec[3] = 0 * rotmat[12] + 0 * rotmat[13] + 0 * rotmat[14] + 1 * rotmat[15];
1675 /* wot gets called when the winder is resized */
1676 void glsnake_reshape(
1681 glViewport(0, 0, (GLint) w, (GLint) h);
1682 glMatrixMode(GL_PROJECTION);
1684 gluPerspective(zoom, w/(GLfloat)h, 0.05, 100.0);
1685 gluLookAt(0.0, 0.0, 20.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
1686 glMatrixMode(GL_MODELVIEW);
1687 /*gluLookAt(0.0, 0.0, 20.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);*/
1695 /* Returns the new dst_dir for the given src_dir and dst_dir */
1696 int cross_product(int src_dir, int dst_dir) {
1697 return X_MASK*(GETSCALAR(src_dir,Y_MASK) * GETSCALAR(dst_dir,Z_MASK) -
1698 GETSCALAR(src_dir,Z_MASK) * GETSCALAR(dst_dir,Y_MASK))+
1699 Y_MASK*(GETSCALAR(src_dir,Z_MASK) * GETSCALAR(dst_dir,X_MASK) -
1700 GETSCALAR(src_dir,X_MASK) * GETSCALAR(dst_dir,Z_MASK))+
1701 Z_MASK*(GETSCALAR(src_dir,X_MASK) * GETSCALAR(dst_dir,Y_MASK) -
1702 GETSCALAR(src_dir,Y_MASK) * GETSCALAR(dst_dir,X_MASK));
1705 /* calculate orthogonal snake metrics
1706 * is_legal = true if model does not pass through itself
1707 * is_cyclic = true if last node connects back to first node
1708 * last_turn = for cyclic snakes, specifes what the 24th turn would be
1710 void calc_snake_metrics(void) {
1713 int prevSrcDir = -Y_MASK;
1714 int prevDstDir = Z_MASK;
1715 int grid[25][25][25];
1718 memset(&grid, 0, sizeof(int) * 25*25*25);
1723 /* trace path of snake - and keep record for is_legal */
1724 for (i = 0; i < NODE_COUNT - 1; i++) {
1725 /*int ang_card;*/ /* cardinal direction of node angle */
1726 /* establish new state vars */
1727 srcDir = -prevDstDir;
1728 x += GETSCALAR(prevDstDir, X_MASK);
1729 y += GETSCALAR(prevDstDir, Y_MASK);
1730 z += GETSCALAR(prevDstDir, Z_MASK);
1732 switch ((int) model[glc->next_model].node[i]) {
1734 dstDir = -prevSrcDir;
1737 dstDir = prevSrcDir;
1741 dstDir = cross_product(prevSrcDir, prevDstDir);
1742 if (model[glc->next_model].node[i] == (int) (RIGHT))
1746 /* Prevent spurious "might be used
1747 * uninitialised" warnings when compiling
1753 if (grid[x][y][z] == 0)
1754 grid[x][y][z] = srcDir + dstDir;
1755 else if (grid[x][y][z] + srcDir + dstDir == 0)
1760 prevSrcDir = srcDir;
1761 prevDstDir = dstDir;
1764 /* determine if the snake is cyclic */
1765 glc->is_cyclic = (dstDir == Y_MASK && x == 12 && y == 11 && z == 12);
1767 /* determine last_turn */
1768 glc->last_turn = -1;
1771 case -Z_MASK: glc->last_turn = ZERO; break;
1772 case Z_MASK: glc->last_turn = PIN; break;
1773 case X_MASK: glc->last_turn = LEFT; break;
1774 case -X_MASK: glc->last_turn = RIGHT; break;
1778 /* work out how far through the current morph we are */
1779 float morph_percent(void) {
1783 /* extend this function later with a case statement for each of the
1786 /* when morphing all nodes at once, the longest morph will be the node
1787 * that needs to rotate 180 degrees. For each node, work out how far it
1788 * has to go, and store the maximum rotation and current largest angular
1789 * difference, returning the angular difference over the maximum. */
1791 float rot_max = 0.0, ang_diff_max = 0.0;
1793 for (i = 0; i < NODE_COUNT - 1; i++) {
1794 float rot, ang_diff;
1796 /* work out the maximum rotation this node has to go through
1797 * from the previous to the next model, taking into account that
1798 * the snake always morphs through the smaller angle */
1799 rot = fabs(model[glc->prev_model].node[i] -
1800 model[glc->next_model].node[i]);
1801 if (rot > 180.0) rot = 180.0 - rot;
1802 /* work out the difference between the current position and the
1804 ang_diff = fabs(glc->node[i] -
1805 model[glc->next_model].node[i]);
1806 if (ang_diff > 180.0) ang_diff = 180 - ang_diff;
1807 /* if it's the biggest so far, record it */
1808 if (rot > rot_max) rot_max = rot;
1809 if (ang_diff > ang_diff_max) ang_diff_max = ang_diff;
1812 /* ang_diff / rot approaches 0, we want the complement */
1813 retval = 1.0 - (ang_diff_max / rot_max);
1814 /* protect against naan */
1816 /* Apparently some systems (Solaris) don't have isinf() */
1818 #define isinf(x) (((x) > 999999999999.9) || ((x) < -999999999999.9))
1820 if (isnan(retval) || isinf(retval)) retval = 1.0;
1822 /*printf("morph_pct = %f\n", retval);*/
1826 void morph_colour(void) {
1827 float percent, compct; /* complement of percentage */
1829 percent = morph_percent();
1830 compct = 1.0 - percent;
1832 glc->colour[0][0] = colour[glc->prev_colour][0][0] * compct + colour[glc->next_colour][0][0] * percent;
1833 glc->colour[0][1] = colour[glc->prev_colour][0][1] * compct + colour[glc->next_colour][0][1] * percent;
1834 glc->colour[0][2] = colour[glc->prev_colour][0][2] * compct + colour[glc->next_colour][0][2] * percent;
1836 glc->colour[1][0] = colour[glc->prev_colour][1][0] * compct + colour[glc->next_colour][1][0] * percent;
1837 glc->colour[1][1] = colour[glc->prev_colour][1][1] * compct + colour[glc->next_colour][1][1] * percent;
1838 glc->colour[1][2] = colour[glc->prev_colour][1][2] * compct + colour[glc->next_colour][1][2] * percent;
1841 /* Start morph process to this model */
1842 void start_morph(int model_index, int immediate) {
1843 /* if immediate, don't bother morphing, go straight to the next model */
1847 for (i = 0; i < NODE_COUNT; i++)
1848 glc->node[i] = model[model_index].node[i];
1851 glc->prev_model = glc->next_model;
1852 glc->next_model = model_index;
1853 glc->prev_colour = glc->next_colour;
1855 calc_snake_metrics();
1857 glc->next_colour = COLOUR_INVALID;
1859 glc->next_colour = COLOUR_AUTHENTIC;
1860 else if (glc->is_cyclic)
1861 glc->next_colour = COLOUR_CYCLIC;
1863 glc->next_colour = COLOUR_ACYCLIC;
1866 glc->colour[0][0] = colour[glc->next_colour][0][0];
1867 glc->colour[0][1] = colour[glc->next_colour][0][1];
1868 glc->colour[0][2] = colour[glc->next_colour][0][2];
1869 glc->colour[1][0] = colour[glc->next_colour][1][0];
1870 glc->colour[1][1] = colour[glc->next_colour][1][1];
1871 glc->colour[1][2] = colour[glc->next_colour][1][2];
1878 /* Returns morph progress */
1879 float morph(long iter_msec) {
1880 /* work out the maximum angle for this iteration */
1882 float iter_angle_max, largest_diff, largest_progress;
1888 iter_angle_max = 90.0 * (angvel/1000.0) * iter_msec;
1891 largest_diff = largest_progress = 0.0;
1892 for (i = 0; i < NODE_COUNT; i++) {
1893 float curAngle = glc->node[i];
1894 float destAngle = model[glc->next_model].node[i];
1895 if (curAngle != destAngle) {
1897 if (fabs(curAngle-destAngle) <= iter_angle_max)
1898 glc->node[i] = destAngle;
1899 else if (fmod(curAngle-destAngle+360,360) > 180)
1900 glc->node[i] = fmod(curAngle + iter_angle_max, 360);
1902 glc->node[i] = fmod(curAngle+360 - iter_angle_max, 360);
1903 largest_diff = MAX(largest_diff, fabs(destAngle-glc->node[i]));
1904 largest_progress = MAX(largest_diff, fabs(glc->node[i] - model[glc->prev_model].node[i]));
1908 return MIN(largest_diff / largest_progress, 1.0);
1912 void glsnake_idle();
1914 void restore_idle(int value)
1916 glutIdleFunc(glsnake_idle);
1920 void quick_sleep(void)
1923 /* By using glutTimerFunc we can keep responding to
1924 * mouse and keyboard events, unlike using something like
1927 glutTimerFunc(1, restore_idle, 0);
1935 struct glsnake_cfg * bp
1938 /* time since last iteration */
1940 /* time since the beginning of last morph */
1942 float iter_angle_max;
1943 snaketime current_time;
1944 /* morphFunc transition; */
1948 /* Do nothing to the model if we are paused */
1950 /* Avoid busy waiting when nothing is changing */
1954 glutPostRedisplay();
1959 /* <spiv> Well, ftime gives time with millisecond resolution.
1960 * <spiv> (or worse, perhaps... who knows what the OS will do)
1961 * <spiv> So if no discernable amount of time has passed:
1962 * <spiv> a) There's no point updating the screen, because
1963 * it would be the same
1964 * <spiv> b) The code will divide by zero
1966 gettime(¤t_time);
1968 iter_msec = (long) GETMSECS(current_time) - GETMSECS(glc->last_iteration) +
1969 ((long) GETSECS(current_time) - GETSECS(glc->last_iteration)) * 1000L;
1972 /* save the current time */
1973 memcpy(&glc->last_iteration, ¤t_time, sizeof(snaketime));
1975 /* work out if we have to switch models */
1976 morf_msec = GETMSECS(glc->last_iteration) - GETMSECS(glc->last_morph) +
1977 ((long) (GETSECS(glc->last_iteration)-GETSECS(glc->last_morph)) * 1000L);
1979 if ((morf_msec > statictime) && !interactive && !glc->morphing) {
1980 /*printf("starting morph\n");*/
1981 memcpy(&glc->last_morph, &(glc->last_iteration), sizeof(glc->last_morph));
1982 start_morph(RAND(models), 0);
1985 if (interactive && !glc->morphing) {
1990 /* if (!glc->dragging && !glc->interactive) { */
1993 yspin += 360/((1000/yangvel)/iter_msec);
1994 zspin += 360/((1000/zangvel)/iter_msec);
1996 yspin += 360 * (yangvel/1000.0) * iter_msec;
1997 zspin += 360 * (zangvel/1000.0) * iter_msec;
2000 /*printf("yspin: %f, zspin: %f\n", yspin, zspin);*/
2004 /* work out the maximum angle we could turn this node in this
2005 * timeslice, iter_msec milliseconds long */
2006 iter_angle_max = 90.0 * (angvel/1000.0) * iter_msec;
2009 for (i = 0; i < NODE_COUNT; i++) {
2010 float cur_angle = glc->node[i];
2011 float dest_angle = model[glc->next_model].node[i];
2012 if (cur_angle != dest_angle) {
2014 if (fabs(cur_angle - dest_angle) <= iter_angle_max)
2015 glc->node[i] = dest_angle;
2016 else if (fmod(cur_angle - dest_angle + 360, 360) > 180)
2017 glc->node[i] = fmod(cur_angle + iter_angle_max, 360);
2019 glc->node[i] = fmod(cur_angle + 360 - iter_angle_max, 360);
2023 if (!still_morphing)
2026 /* colour cycling */
2031 glutPostRedisplay();
2034 /* We are going too fast, so we may as well let the
2035 * cpu relax a little by sleeping for a millisecond. */
2041 void glsnake_display(
2047 struct glsnake_cfg * bp = &glc[MI_SCREEN(mi)];
2048 Display * dpy = MI_DISPLAY(mi);
2049 Window window = MI_WINDOW(mi);
2054 float positions[NODE_COUNT][4]; /* origin points for each node */
2055 float com[4]; /* it's the CENTRE of MASS */
2058 if (!bp->glx_context)
2062 /* clear the buffer */
2063 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2065 /* go into the modelview stack */
2066 glMatrixMode(GL_MODELVIEW);
2069 /* get the centre of each node, by moving through the snake and
2070 * performing the rotations, then grabbing the matrix at each point
2071 * and applying it to the origin */
2075 /* apply the mouse drag rotation */
2079 /* apply the continuous rotation */
2080 glRotatef(yspin, 0.0, 1.0, 0.0);
2081 glRotatef(zspin, 0.0, 0.0, 1.0);
2087 for (i = 0; i < NODE_COUNT; i++) {
2092 /*printf("ang = %f\n", ang);*/
2094 glTranslatef(0.5, 0.5, 0.5); /* move to center */
2095 glRotatef(90, 0.0, 0.0, -1.0); /* reorient */
2096 glTranslatef(1.0 + explode, 0.0, 0.0); /* move to new pos. */
2097 glRotatef(180 + ang, 1.0, 0.0, 0.0); /* pivot to new angle */
2098 glTranslatef(-0.5, -0.5, -0.5); /* return from center */
2100 glGetFloatv(GL_MODELVIEW_MATRIX, rotmat);
2102 matmult_origin(rotmat, positions[i]);
2104 /*printf("positions %f %f %f %f\n", positions[i][0], positions[i][1], positions[i][2], positions[i][3]);*/
2106 com[0] += positions[i][0];
2107 com[1] += positions[i][1];
2108 com[2] += positions[i][2];
2109 com[3] += positions[i][3];
2112 com[0] /= NODE_COUNT;
2113 com[1] /= NODE_COUNT;
2114 com[2] /= NODE_COUNT;
2115 com[3] /= NODE_COUNT;
2121 /*printf("com: %f, %f, %f, %f\n", com[0], com[1], com[2], com[3]);*/
2123 #if MAGICAL_RED_STRING
2125 glTranslatef(-com[0], -com[1], -com[2]);
2127 glDisable(GL_LIGHTING);
2128 glColor3f(1.0, 0.0, 0.0);
2129 glBegin(GL_LINE_STRIP);
2130 for (i = 0; i < NODE_COUNT - 1; i++) {
2131 glVertex3fv(positions[i]);
2134 glEnable(GL_LIGHTING);
2135 /*glTranslatef(com[0], com[1], com[2]);*/
2140 glTranslatef(-com[0], -com[1], -com[2]);
2143 /* apply the mouse drag rotation */
2147 /* apply the continuous rotation */
2148 glRotatef(yspin, 0.0, 1.0, 0.0);
2149 glRotatef(zspin, 0.0, 0.0, 1.0);
2151 /* now draw each node along the snake -- this is quite ugly :p */
2152 for (i = 0; i < NODE_COUNT; i++) {
2153 /* choose a colour for this node */
2154 if ((i == glc->selected || i == glc->selected+1) && interactive)
2156 glColor3f(1.0, 1.0, 0.0);
2158 glColor3fv(glc->colour[(i+1)%2]);
2162 glCallList(glc->node_wire);
2164 glCallList(glc->node_solid);
2166 /* now work out where to draw the next one */
2168 /* Interpolate between models */
2171 glTranslatef(0.5, 0.5, 0.5); /* move to center */
2172 glRotatef(90, 0.0, 0.0, -1.0); /* reorient */
2173 glTranslatef(1.0 + explode, 0.0, 0.0); /* move to new pos. */
2174 glRotatef(180 + ang, 1.0, 0.0, 0.0); /* pivot to new angle */
2175 glTranslatef(-0.5, -0.5, -0.5); /* return from center */
2195 glXSwapBuffers(dpy, window);
2200 /* anything that needs to be cleaned up goes here */
2202 glutDestroyWindow(glc->window);
2206 void ui_init(int *, char **);
2208 int main(int argc, char ** argv) {
2209 glc = malloc(sizeof(struct glsnake_cfg));
2210 memset(glc, 0, sizeof(struct glsnake_cfg));
2215 ui_init(&argc, argv);
2217 gettime(&glc->last_iteration);
2218 memcpy(&glc->last_morph, &glc->last_iteration, sizeof(snaketime));
2219 srand((unsigned int)GETSECS(glc->last_iteration));
2221 glc->prev_colour = glc->next_colour = COLOUR_ACYCLIC;
2222 glc->next_model = RAND(models);
2223 glc->prev_model = 0;
2224 start_morph(glc->prev_model, 1);
2242 /* trackball quaternions */
2243 float cumquat[4] = {0.0,0.0,0.0,0.0}, oldquat[4] = {0.0,0.0,0.0,0.1};
2245 /* rotation matrix */
2248 /* mouse drag vectors: start and end */
2249 float m_s[3], m_e[3];
2251 /* dragging boolean */
2254 /* this function calculates the rotation matrix based on the quaternions
2255 * generated from the mouse drag vectors */
2256 void calc_rotation() {
2258 double xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz;
2260 /* this bit ripped from Shoemake's quaternion notes from SIGGRAPH */
2261 Nq = cumquat[0] * cumquat[0] + cumquat[1] * cumquat[1] +
2262 cumquat[2] * cumquat[2] + cumquat[3] * cumquat[3];
2263 s = (Nq > 0.0) ? (2.0 / Nq) : 0.0;
2264 xs = cumquat[0] * s; ys = cumquat[1] * s; zs = cumquat[2] * s;
2265 wx = cumquat[3] * xs; wy = cumquat[3] * ys; wz = cumquat[3] * zs;
2266 xx = cumquat[0] * xs; xy = cumquat[0] * ys; xz = cumquat[0] * zs;
2267 yy = cumquat[1] * ys; yz = cumquat[1] * zs; zz = cumquat[2] * zs;
2269 rotation[0] = 1.0 - (yy + zz);
2270 rotation[1] = xy + wz;
2271 rotation[2] = xz - wy;
2272 rotation[4] = xy - wz;
2273 rotation[5] = 1.0 - (xx + zz);
2274 rotation[6] = yz + wx;
2275 rotation[8] = xz + wy;
2276 rotation[9] = yz - wx;
2277 rotation[10] = 1.0 - (xx + yy);
2278 rotation[3] = rotation[7] = rotation[11] = 0.0;
2279 rotation[12] = rotation[13] = rotation[14] = 0.0;
2283 inline void ui_mousedrag() {
2284 glMultMatrixf(rotation);
2287 void ui_keyboard(unsigned char c, int x, int y) {
2296 explode += DEF_EXPLODE;
2297 glutPostRedisplay();
2300 explode -= DEF_EXPLODE;
2301 if (explode < 0.0) explode = 0.0;
2302 glutPostRedisplay();
2307 glc->next_model %= models;
2308 start_morph(glc->next_model, 0);
2310 /* Reset last_morph time */
2311 gettime(&glc->last_morph);
2314 /* previous model */
2315 glc->next_model = (glc->next_model + models - 1) % models;
2316 start_morph(glc->next_model, 0);
2318 /* Reset glc->last_morph time */
2319 gettime(&glc->last_morph);
2322 angvel += DEF_ACCEL;
2325 if (angvel > DEF_ACCEL)
2326 angvel -= DEF_ACCEL;
2330 /* Reset last_iteration and last_morph time */
2331 gettime(&glc->last_iteration);
2332 gettime(&glc->last_morph);
2334 interactive = 1 - interactive;
2335 glutPostRedisplay();
2338 wireframe = 1 - wireframe;
2340 glDisable(GL_LIGHTING);
2342 glEnable(GL_LIGHTING);
2343 glutPostRedisplay();
2347 /* unpausing, reset last_iteration and last_morph time */
2348 gettime(&glc->last_iteration);
2349 gettime(&glc->last_morph);
2351 glc->paused = 1 - glc->paused;
2354 /* dump the current model so we can add it! */
2355 printf("# %s\nnoname:\t", model[glc->next_model].name);
2356 for (i = 0; i < NODE_COUNT; i++) {
2357 if (glc->node[i] == ZERO)
2359 else if (glc->node[i] == LEFT)
2361 else if (glc->node[i] == PIN)
2363 else if (glc->node[i] == RIGHT)
2367 printf("%f", node[i].curAngle);
2369 if (i < NODE_COUNT - 1)
2375 glc->fullscreen = 1 - glc->fullscreen;
2376 if (glc->fullscreen) {
2377 glc->old_width = glc->width;
2378 glc->old_height = glc->height;
2381 glutReshapeWindow(glc->old_width, glc->old_height);
2382 glutPositionWindow(50,50);
2386 titles = 1 - titles;
2387 if (interactive || glc->paused)
2388 glutPostRedisplay();
2391 altcolour = 1 - altcolour;
2395 glsnake_reshape(glc->width, glc->height);
2399 glsnake_reshape(glc->width, glc->height);
2406 void ui_special(int key, int x, int y) {
2408 float *destAngle = &(model[glc->next_model].node[glc->selected]);
2409 int unknown_key = 0;
2414 glc->selected = (glc->selected + (NODE_COUNT - 2)) % (NODE_COUNT - 1);
2417 glc->selected = (glc->selected + 1) % (NODE_COUNT - 1);
2420 *destAngle = fmod(*destAngle+(LEFT), 360);
2421 glc->morphing = glc->new_morph = 1;
2423 case GLUT_KEY_RIGHT:
2424 *destAngle = fmod(*destAngle+(RIGHT), 360);
2425 glc->morphing = glc->new_morph = 1;
2428 start_morph(STRAIGHT_MODEL, 0);
2435 calc_snake_metrics();
2438 glutPostRedisplay();
2441 void ui_mouse(int button, int state, int x, int y) {
2446 m_s[0] = M_SQRT1_2 *
2447 (x - (glc->width / 2.0)) / (glc->width / 2.0);
2448 m_s[1] = M_SQRT1_2 *
2449 ((glc->height / 2.0) - y) / (glc->height / 2.0);
2450 m_s[2] = sqrt(1-(m_s[0]*m_s[0]+m_s[1]*m_s[1]));
2454 oldquat[0] = cumquat[0];
2455 oldquat[1] = cumquat[1];
2456 oldquat[2] = cumquat[2];
2457 oldquat[3] = cumquat[3];
2463 glutPostRedisplay();
2466 void ui_motion(int x, int y) {
2471 /* construct the motion end vector from the x,y position on the
2473 m_e[0] = (x - (glc->width/ 2.0)) / (glc->width / 2.0);
2474 m_e[1] = ((glc->height / 2.0) - y) / (glc->height / 2.0);
2475 /* calculate the normal of the vector... */
2476 norm = m_e[0] * m_e[0] + m_e[1] * m_e[1];
2477 /* check if norm is outside the sphere and wraparound if necessary */
2481 m_e[2] = sqrt(norm - 1);
2483 /* the z value comes from projecting onto an elliptical spheroid */
2484 m_e[2] = sqrt(1 - norm);
2487 /* now here, build a quaternion from m_s and m_e */
2488 q[0] = m_s[1] * m_e[2] - m_s[2] * m_e[1];
2489 q[1] = m_s[2] * m_e[0] - m_s[0] * m_e[2];
2490 q[2] = m_s[0] * m_e[1] - m_s[1] * m_e[0];
2491 q[3] = m_s[0] * m_e[0] + m_s[1] * m_e[1] + m_s[2] * m_e[2];
2493 /* new rotation is the product of the new one and the old one */
2494 cumquat[0] = q[3] * oldquat[0] + q[0] * oldquat[3] +
2495 q[1] * oldquat[2] - q[2] * oldquat[1];
2496 cumquat[1] = q[3] * oldquat[1] + q[1] * oldquat[3] +
2497 q[2] * oldquat[0] - q[0] * oldquat[2];
2498 cumquat[2] = q[3] * oldquat[2] + q[2] * oldquat[3] +
2499 q[0] * oldquat[1] - q[1] * oldquat[0];
2500 cumquat[3] = q[3] * oldquat[3] - q[0] * oldquat[0] -
2501 q[1] * oldquat[1] - q[2] * oldquat[2];
2505 glutPostRedisplay();
2508 void ui_init(int * argc, char ** argv) {
2509 glutInit(argc, argv);
2510 glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
2511 glutInitWindowSize(glc->width, glc->height);
2512 glc->window = glutCreateWindow("glsnake");
2514 glutDisplayFunc(glsnake_display);
2515 glutReshapeFunc(glsnake_reshape);
2516 glutIdleFunc(glsnake_idle);
2517 glutKeyboardFunc(ui_keyboard);
2518 glutSpecialFunc(ui_special);
2519 glutMouseFunc(ui_mouse);
2520 glutMotionFunc(ui_motion);
2522 yangvel = DEF_YANGVEL;
2523 zangvel = DEF_ZANGVEL;
2524 explode = DEF_EXPLODE;
2525 angvel = DEF_ANGVEL;
2526 statictime = DEF_STATICTIME;
2527 altcolour = DEF_ALTCOLOUR;
2528 titles = DEF_TITLES;
2529 interactive = DEF_INTERACTIVE;
2531 wireframe = DEF_WIREFRAME;
2533 #endif /* HAVE_GLUT */