diff options
| author | Simon Rettberg | 2024-09-06 14:42:37 +0200 |
|---|---|---|
| committer | Simon Rettberg | 2024-09-06 14:42:37 +0200 |
| commit | badef32037f52f79abc1f1440b786cd71afdf270 (patch) | |
| tree | 412b792d4cab4a7a110db82fcf74fe8a1ac55ec1 /hacks/glx/glsnake.c | |
| parent | Delete pre-6.00 files (diff) | |
| download | xscreensaver-master.tar.gz xscreensaver-master.tar.xz xscreensaver-master.zip | |
Diffstat (limited to 'hacks/glx/glsnake.c')
| -rw-r--r-- | hacks/glx/glsnake.c | 2685 |
1 files changed, 0 insertions, 2685 deletions
diff --git a/hacks/glx/glsnake.c b/hacks/glx/glsnake.c deleted file mode 100644 index d7e133e..0000000 --- a/hacks/glx/glsnake.c +++ /dev/null @@ -1,2685 +0,0 @@ -/* glsnake.c - OpenGL imitation of Rubik's Snake - * - * (c) 2001-2005 Jamie Wilkinson <jaq@spacepants.org> - * (c) 2001-2003 Andrew Bennetts <andrew@puzzling.org> - * (c) 2001-2003 Peter Aylett <peter@ylett.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* HAVE_GLUT defined if we're building a standalone glsnake, - * and not defined if we're building as an xscreensaver hack */ -#ifdef HAVE_GLUT -# include <GL/glut.h> -#else -# include "xlockmoreI.h" -# ifndef HAVE_GETTIMEOFDAY -# define HAVE_GETTIMEOFDAY -# endif -#endif - -#include <stdio.h> -#include <stddef.h> -#include <stdlib.h> -#include <string.h> - -/* angles */ -#define ZERO 0.0 -#define LEFT 90.0 -#define PIN 180.0 -#define RIGHT 270.0 - -#ifdef HAVE_GETTIMEOFDAY -# ifdef GETTIMEOFDAY_TWO_ARGS - -# include <sys/time.h> -# include <time.h> - typedef struct timeval snaketime; -# define GETSECS(t) ((t).tv_sec) -# define GETMSECS(t) ((t).tv_usec/1000) - -# else /* !GETTIMEOFDAY_TWO_ARGS */ - -# include <sys/time.h> -# include <time.h> - typedef struct timeval snaketime; -# define GETSECS(t) ((t).tv_sec) -# define GETMSECS(t) ((t).tv_usec/1000) - -# endif /* GETTIMEOFDAY_TWO_ARGS */ - -#else /* !HAVE_GETTIMEOFDAY */ -# ifdef HAVE_FTIME - -# include <sys/timeb.h> - typedef struct timeb snaketime; -# define GETSECS(t) ((long)(t).time) -# define GETMSECS(t) ((t).millitm/1000) - -# endif /* HAVE_FTIME */ -#endif /* HAVE_GETTIMEOFDAY */ - -#include <math.h> - -#ifndef M_SQRT1_2 /* Win32 doesn't have this constant */ -#define M_SQRT1_2 0.70710678118654752440084436210485 -#endif - -#define NODE_COUNT 24 - -#ifdef HAVE_GLUT -#define DEF_YANGVEL 0.10 -#define DEF_ZANGVEL 0.14 -#define DEF_EXPLODE 0.03 -#define DEF_ANGVEL 1.0 -#define DEF_STATICTIME 5000 -#define DEF_ALTCOLOUR 0 -#define DEF_TITLES 0 -#define DEF_INTERACTIVE 0 -#define DEF_ZOOM 25.0 -#define DEF_WIREFRAME 0 -#define DEF_TRANSPARENT 1 -#else -/* xscreensaver options doobies prefer strings */ -#define DEF_YANGVEL "0.10" -#define DEF_ZANGVEL "0.14" -#define DEF_EXPLODE "0.03" -#define DEF_ANGVEL "1.0" -#define DEF_STATICTIME "5000" -#define DEF_ALTCOLOUR "False" -#define DEF_TITLES "False" -#define DEF_INTERACTIVE "False" -#define DEF_ZOOM "25.0" -#define DEF_WIREFRAME "False" -#define DEF_TRANSPARENT "True" -#endif - -/* static variables */ - -static GLfloat explode; -static long statictime; -static GLfloat yspin = 60.0; -static GLfloat zspin = -45.0; -static GLfloat yangvel; -static GLfloat zangvel; -static Bool altcolour; -static Bool titles; -static Bool interactive; -static Bool wireframe; -static Bool transparent; -static GLfloat zoom; -static GLfloat angvel; - -#ifndef HAVE_GLUT - -#define glsnake_init init_glsnake -#define glsnake_display draw_glsnake -#define glsnake_reshape reshape_glsnake -#define release_glsnake 0 -#define glsnake_handle_event xlockmore_no_events - -/* xscreensaver defaults */ -#define DEFAULTS "*delay: 30000 \n" \ - "*count: 30 \n" \ - "*showFPS: False \n" \ - "*suppressRotationAnimation: True\n" \ - "*labelfont: sans-serif 18\n" \ - - -#include "xlockmore.h" -#include "texfont.h" - -static XrmOptionDescRec opts[] = { - { "-explode", ".explode", XrmoptionSepArg, DEF_EXPLODE }, - { "-angvel", ".angvel", XrmoptionSepArg, DEF_ANGVEL }, - { "-statictime", ".statictime", XrmoptionSepArg, DEF_STATICTIME }, - { "-yangvel", ".yangvel", XrmoptionSepArg, DEF_YANGVEL }, - { "-zangvel", ".zangvel", XrmoptionSepArg, DEF_ZANGVEL }, - { "-altcolour", ".altcolour", XrmoptionNoArg, "True" }, - { "-no-altcolour", ".altcolour", XrmoptionNoArg, "False" }, - { "-titles", ".titles", XrmoptionNoArg, "True" }, - { "-no-titles", ".titles", XrmoptionNoArg, "False" }, - { "-zoom", ".zoom", XrmoptionSepArg, DEF_ZOOM }, - { "-wireframe", ".wireframe", XrmoptionNoArg, "true" }, - { "-no-wireframe", ".wireframe", XrmoptionNoArg, "false" }, - { "-transparent", ".transparent", XrmoptionNoArg, "true" }, - { "-no-transparent", ".transparent", XrmoptionNoArg, "false" }, -}; - -static argtype vars[] = { - {&explode, "explode", "Explode", DEF_EXPLODE, t_Float}, - {&angvel, "angvel", "Angular Velocity", DEF_ANGVEL, t_Float}, - {&statictime, "statictime", "Static Time", DEF_STATICTIME, t_Int}, - {&yangvel, "yangvel", "Angular Velocity about Y axis", DEF_YANGVEL, t_Float}, - {&zangvel, "zangvel", "Angular Velocity about X axis", DEF_ZANGVEL, t_Float}, - {&interactive, "interactive", "Interactive", DEF_INTERACTIVE, t_Bool}, - {&altcolour, "altcolour", "Alternate Colour Scheme", DEF_ALTCOLOUR, t_Bool}, - {&titles, "titles", "Titles", DEF_TITLES, t_Bool}, - {&zoom, "zoom", "Zoom", DEF_ZOOM, t_Float}, - {&wireframe, "wireframe", "Wireframe", DEF_WIREFRAME, t_Bool}, - {&transparent, "transparent", "Transparent!", DEF_TRANSPARENT, t_Bool}, -}; - -ENTRYPOINT ModeSpecOpt glsnake_opts = {countof(opts), opts, countof(vars), vars, NULL}; -#endif - -struct model_s { - const char * name; - float node[NODE_COUNT]; -}; - -struct glsnake_cfg { -#ifndef HAVE_GLUT - GLXContext * glx_context; - texture_font_data *font_data; -#else - /* font list number */ - int font; -#endif - - /* window id */ - int window; - - /* is a morph in progress? */ - int morphing; - - /* has the model been paused? */ - int paused; - - /* snake metrics */ - int is_cyclic; - int is_legal; - float last_turn; - int debug; - - /* the shape of the model */ - float node[NODE_COUNT]; - - /* currently selected node for interactive mode */ - int selected; - - /* models */ - unsigned int prev_model; - unsigned int next_model; - - /* model morphing */ - int new_morph; - - /* colours */ - float colour[2][4]; - int next_colour; - int prev_colour; - - /* timing variables */ - snaketime last_iteration; - snaketime last_morph; - - /* window size */ - int width, height; - int old_width, old_height; - - /* the id of the display lists for drawing a node */ - GLuint node_solid, node_wire; - int node_polys; - - /* is the window fullscreen? */ - int fullscreen; -}; - -#define COLOUR_CYCLIC 0 -#define COLOUR_ACYCLIC 1 -#define COLOUR_INVALID 2 -#define COLOUR_AUTHENTIC 3 -#define COLOUR_ORIGLOGO 4 - -static const float colour[][2][4] = { - /* cyclic - green */ - { { 0.4, 0.8, 0.2, 0.6 }, - { 1.0, 1.0, 1.0, 0.6 } }, - /* acyclic - blue */ - { { 0.3, 0.1, 0.9, 0.6 }, - { 1.0, 1.0, 1.0, 0.6 } }, - /* invalid - grey */ - { { 0.3, 0.1, 0.9, 0.6 }, - { 1.0, 1.0, 1.0, 0.6 } }, - /* authentic - purple and green */ - { { 0.38, 0.0, 0.55, 0.7 }, - { 0.0, 0.5, 0.34, 0.7 } }, - /* old "authentic" colours from the logo */ - { { 171/255.0, 0, 1.0, 1.0 }, - { 46/255.0, 205/255.0, 227/255.0, 1.0 } } -}; - -static const struct model_s model[] = { -#define STRAIGHT_MODEL 0 - { "straight", - { ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, - ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, - ZERO, ZERO, ZERO } - }, - /* the models in the Rubik's snake manual */ - { "ball", - { RIGHT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, - RIGHT, LEFT, LEFT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, - RIGHT, LEFT, RIGHT, LEFT, ZERO } - }, -#define START_MODEL 2 - { "snow", - { RIGHT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, LEFT, RIGHT, - RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, - RIGHT, LEFT, LEFT, LEFT, ZERO } - }, - { "propellor", - { ZERO, ZERO, ZERO, RIGHT, LEFT, RIGHT, ZERO, LEFT, ZERO, ZERO, - ZERO, RIGHT, LEFT, RIGHT, ZERO, LEFT, ZERO, ZERO, ZERO, RIGHT, - LEFT, RIGHT, ZERO, LEFT } - }, - { "flamingo", - { ZERO, PIN, ZERO, ZERO, ZERO, ZERO, ZERO, PIN, RIGHT, RIGHT, PIN, - RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, RIGHT, ZERO, ZERO, - ZERO, PIN, ZERO } - }, - { "cat", - { ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, - ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, ZERO, ZERO, ZERO, ZERO, - ZERO, ZERO } - }, - { "rooster", - { ZERO, ZERO, PIN, PIN, ZERO, LEFT, ZERO, LEFT, RIGHT, PIN, RIGHT, - ZERO, PIN, PIN, ZERO, RIGHT, PIN, RIGHT, LEFT, ZERO, LEFT, ZERO, - PIN, ZERO } - }, - /* These models were taken from Andrew and Peter's original snake.c - * as well as some newer ones made up by Jamie, Andrew and Peter. */ - { "half balls", - { LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, - LEFT, LEFT, LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, - RIGHT, LEFT, LEFT, LEFT, ZERO } - }, - { "zigzag1", - { RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, - LEFT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT, - RIGHT, RIGHT, LEFT, LEFT, ZERO } - }, - { "zigzag2", - { PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, - ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, - ZERO } - }, - { "zigzag3", - { PIN, LEFT, PIN, LEFT, PIN, LEFT, PIN, LEFT, PIN, LEFT, PIN, - LEFT, PIN, LEFT, PIN, LEFT, PIN, LEFT, PIN, LEFT, PIN, LEFT, PIN, - ZERO } - }, - { "caterpillar", - { RIGHT, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, - LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, RIGHT, PIN, - LEFT, LEFT, ZERO } - }, - { "bow", - { RIGHT, LEFT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT, - LEFT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, - RIGHT, RIGHT, LEFT, LEFT, ZERO } - }, - { "turtle", - { ZERO, RIGHT, LEFT, ZERO, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, - LEFT, RIGHT, LEFT, LEFT, PIN, LEFT, LEFT, LEFT, RIGHT, LEFT, - RIGHT, RIGHT, RIGHT, ZERO } - }, - { "basket", - { RIGHT, PIN, ZERO, ZERO, PIN, LEFT, ZERO, LEFT, LEFT, ZERO, - LEFT, PIN, ZERO, ZERO, PIN, RIGHT, PIN, LEFT, PIN, ZERO, ZERO, - PIN, LEFT, ZERO } - }, - { "thing", - { PIN, RIGHT, LEFT, RIGHT, RIGHT, LEFT, PIN, LEFT, RIGHT, LEFT, - LEFT, RIGHT, PIN, RIGHT, LEFT, RIGHT, RIGHT, LEFT, PIN, LEFT, - RIGHT, LEFT, LEFT, ZERO } - }, - { "hexagon", - { ZERO, ZERO, ZERO, ZERO, LEFT, ZERO, ZERO, RIGHT, ZERO, ZERO, - ZERO, ZERO, LEFT, ZERO, ZERO, RIGHT, ZERO, ZERO, ZERO, ZERO, - LEFT, ZERO, ZERO, RIGHT } - }, - { "tri1", - { ZERO, ZERO, LEFT, RIGHT, ZERO, LEFT, ZERO, RIGHT, ZERO, ZERO, - LEFT, RIGHT, ZERO, LEFT, ZERO, RIGHT, ZERO, ZERO, LEFT, RIGHT, - ZERO, LEFT, ZERO, RIGHT } - }, - { "triangle", - { ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, LEFT, RIGHT, ZERO, ZERO, - ZERO, ZERO, ZERO, ZERO, LEFT, RIGHT, ZERO, ZERO, ZERO, ZERO, - ZERO, ZERO, LEFT, RIGHT } - }, - { "flower", - { ZERO, LEFT, PIN, RIGHT, RIGHT, PIN, ZERO, LEFT, PIN, RIGHT, - RIGHT, PIN, ZERO, LEFT, PIN, RIGHT, RIGHT, PIN, ZERO, LEFT, PIN, - RIGHT, RIGHT, PIN } - }, - { "crucifix", - { ZERO, PIN, PIN, ZERO, PIN, ZERO, PIN, PIN, ZERO, PIN, ZERO, PIN, - PIN, ZERO, PIN, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO, ZERO, PIN } - }, - { "kayak", - { PIN, RIGHT, LEFT, PIN, LEFT, PIN, ZERO, ZERO, RIGHT, PIN, LEFT, - ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, - PIN, RIGHT } - }, - { "bird", - { ZERO, ZERO, ZERO, ZERO, RIGHT, RIGHT, ZERO, LEFT, PIN, RIGHT, - ZERO, RIGHT, ZERO, RIGHT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, - LEFT, ZERO, PIN, ZERO } - }, - { "seal", - { RIGHT, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, PIN, PIN, ZERO, - LEFT, ZERO, LEFT, PIN, RIGHT, ZERO, LEFT, LEFT, LEFT, PIN, RIGHT, - RIGHT, LEFT, ZERO } - }, - { "dog", - { ZERO, ZERO, ZERO, ZERO, PIN, PIN, ZERO, PIN, ZERO, ZERO, PIN, - ZERO, PIN, PIN, ZERO, ZERO, ZERO, PIN, ZERO, PIN, PIN, ZERO, PIN, ZERO } - }, - { "frog", - { RIGHT, RIGHT, LEFT, LEFT, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, - RIGHT, ZERO, LEFT, ZERO, LEFT, PIN, RIGHT, ZERO, LEFT, LEFT, - RIGHT, LEFT, LEFT, ZERO } - }, - { "quavers", - { LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, ZERO, ZERO, ZERO, - RIGHT, ZERO, ZERO, LEFT, RIGHT, ZERO, ZERO, ZERO, LEFT, LEFT, - RIGHT, LEFT, RIGHT, RIGHT, ZERO } - }, - { "fly", - { LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, ZERO, PIN, ZERO, ZERO, - LEFT, PIN, RIGHT, ZERO, ZERO, PIN, ZERO, LEFT, LEFT, RIGHT, LEFT, - RIGHT, RIGHT, ZERO } - }, - { "puppy", - { ZERO, PIN, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, ZERO, ZERO, - RIGHT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, - LEFT, ZERO, ZERO } - }, - { "stars", - { LEFT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, - ZERO, ZERO, ZERO, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, - RIGHT, LEFT, ZERO } - }, - { "mountains", - { RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, PIN, - LEFT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, - PIN, LEFT, PIN } - }, - { "quad1", - { RIGHT, PIN, RIGHT, RIGHT, RIGHT, PIN, LEFT, LEFT, LEFT, PIN, - LEFT, PIN, RIGHT, PIN, RIGHT, RIGHT, RIGHT, PIN, LEFT, LEFT, - LEFT, PIN, LEFT, PIN } - }, - { "quad2", - { ZERO, PIN, RIGHT, RIGHT, RIGHT, PIN, LEFT, LEFT, LEFT, PIN, - ZERO, PIN, ZERO, PIN, RIGHT, RIGHT, RIGHT, PIN, LEFT, LEFT, LEFT, - PIN, ZERO, PIN } - }, - { "glasses", - { ZERO, PIN, ZERO, RIGHT, RIGHT, PIN, LEFT, LEFT, ZERO, PIN, - ZERO, PIN, ZERO, PIN, ZERO, RIGHT, RIGHT, PIN, LEFT, LEFT, ZERO, - PIN, ZERO, PIN } - }, - { "em", - { ZERO, PIN, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, PIN, - ZERO, PIN, ZERO, PIN, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, - PIN, ZERO, PIN } - }, - { "quad3", - { ZERO, RIGHT, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, LEFT, - ZERO, PIN, ZERO, RIGHT, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, - LEFT, ZERO, PIN } - }, - { "vee", - { ZERO, ZERO, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, ZERO, - ZERO, PIN, ZERO, ZERO, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, - ZERO, ZERO, PIN } - }, - { "square", - { ZERO, ZERO, ZERO, RIGHT, RIGHT, PIN, LEFT, LEFT, ZERO, ZERO, - ZERO, PIN, ZERO, ZERO, ZERO, RIGHT, RIGHT, PIN, LEFT, LEFT, ZERO, - ZERO, ZERO, PIN } - }, - { "eagle", - { RIGHT, ZERO, ZERO, RIGHT, RIGHT, PIN, LEFT, LEFT, ZERO, ZERO, - LEFT, PIN, RIGHT, ZERO, ZERO, RIGHT, RIGHT, PIN, LEFT, LEFT, - ZERO, ZERO, LEFT, PIN } - }, - { "volcano", - { RIGHT, ZERO, LEFT, RIGHT, RIGHT, PIN, LEFT, LEFT, RIGHT, - ZERO, LEFT, PIN, RIGHT, ZERO, LEFT, RIGHT, RIGHT, PIN, LEFT, - LEFT, RIGHT, ZERO, LEFT, PIN } - }, - { "saddle", - { RIGHT, ZERO, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, ZERO, - LEFT, PIN, RIGHT, ZERO, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, - ZERO, LEFT, PIN } - }, - { "c3d", - { ZERO, ZERO, RIGHT, ZERO, ZERO, PIN, ZERO, ZERO, LEFT, ZERO, - ZERO, PIN, ZERO, ZERO, RIGHT, ZERO, ZERO, PIN, ZERO, ZERO, LEFT, - ZERO, ZERO, PIN } - }, - { "block", - { ZERO, ZERO, PIN, PIN, ZERO, RIGHT, PIN, LEFT, PIN, RIGHT, PIN, - RIGHT, PIN, LEFT, PIN, RIGHT, ZERO, ZERO, PIN, ZERO, ZERO, LEFT, - PIN, RIGHT } - }, - { "duck", - { LEFT, PIN, LEFT, PIN, ZERO, PIN, PIN, ZERO, PIN, ZERO, LEFT, - PIN, RIGHT, ZERO, PIN, ZERO, PIN, PIN, ZERO, ZERO, LEFT, PIN, - LEFT, ZERO } - }, - { "prayer", - { RIGHT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, ZERO, ZERO, - ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, ZERO, RIGHT, RIGHT, LEFT, - RIGHT, LEFT, LEFT, LEFT, PIN } - }, - { "giraffe", - { ZERO, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, ZERO, RIGHT, - RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, PIN, ZERO, LEFT, RIGHT, - PIN, LEFT, LEFT, LEFT } - }, - { "tie fighter", - { PIN, LEFT, RIGHT, LEFT, LEFT, PIN, RIGHT, ZERO, RIGHT, LEFT, - ZERO, PIN, LEFT, LEFT, RIGHT, RIGHT, RIGHT, PIN, LEFT, ZERO, - LEFT, RIGHT, ZERO, ZERO } - }, - { "Strong Arms", - { PIN, PIN, ZERO, ZERO, PIN, ZERO, ZERO, RIGHT, ZERO, RIGHT, - RIGHT, PIN, RIGHT, RIGHT, ZERO, RIGHT, ZERO, ZERO, PIN, ZERO, - ZERO, PIN, PIN, ZERO } - }, - - /* the following modesl were created during the slug/compsoc codefest - * febrray 2003 */ - { "cool looking gegl", - { PIN, PIN, ZERO, ZERO, RIGHT, ZERO, ZERO, PIN, PIN, ZERO, LEFT, - ZERO, ZERO, PIN, ZERO, PIN, PIN, ZERO, LEFT, RIGHT, PIN, ZERO, - ZERO, ZERO } - }, - { "knuckledusters", - { ZERO, ZERO, ZERO, ZERO, PIN, RIGHT, ZERO, PIN, PIN, ZERO, PIN, - PIN, ZERO, RIGHT, RIGHT, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, - RIGHT, ZERO } - }, - { "k's turd", - { RIGHT, RIGHT, PIN, RIGHT, LEFT, RIGHT, PIN, RIGHT, LEFT, - RIGHT, PIN, RIGHT, LEFT, RIGHT, PIN, RIGHT, LEFT, RIGHT, PIN, - RIGHT, LEFT, RIGHT, PIN, ZERO } - }, - { "lightsabre", - { ZERO, ZERO, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO, ZERO, ZERO, - ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, - ZERO, ZERO } - }, - { "not a stairway", - { LEFT, ZERO, RIGHT, LEFT, RIGHT, ZERO, LEFT, RIGHT, LEFT, ZERO, - RIGHT, LEFT, RIGHT, ZERO, LEFT, RIGHT, LEFT, ZERO, RIGHT, LEFT, - RIGHT, ZERO, LEFT, ZERO } - }, - { "not very good (but accurate) gegl", - { ZERO, PIN, PIN, ZERO, ZERO, ZERO, PIN, PIN, ZERO, LEFT, ZERO, - PIN, PIN, ZERO, RIGHT, LEFT, ZERO, PIN, ZERO, PIN, PIN, ZERO, - PIN, ZERO } - }, - { "box", - { ZERO, ZERO, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, ZERO, ZERO, - ZERO, PIN, ZERO, ZERO, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, ZERO, - ZERO, ZERO, ZERO } - }, - { "kissy box", - { PIN, ZERO, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, ZERO, ZERO, - ZERO, PIN, ZERO, ZERO, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, ZERO, - ZERO, PIN, ZERO } - }, - { "erect penis", /* thanks benno */ - { PIN, ZERO, PIN, PIN, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, PIN, - PIN, ZERO, ZERO, ZERO, RIGHT, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, - ZERO, ZERO } - }, - { "flaccid penis", - { PIN, ZERO, PIN, PIN, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, PIN, - PIN, ZERO, ZERO, ZERO, RIGHT, PIN, ZERO, ZERO, ZERO, ZERO, ZERO, - ZERO, ZERO } - }, - { "vagina", - { RIGHT, ZERO, ZERO, ZERO, RIGHT, ZERO, ZERO, PIN, ZERO, ZERO, - LEFT, ZERO, ZERO, ZERO, LEFT, ZERO, LEFT, PIN, LEFT, PIN, RIGHT, - PIN, RIGHT, ZERO } - }, - { "mask", - { ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, PIN, ZERO, ZERO, PIN, - ZERO, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, ZERO, PIN, ZERO, - ZERO, ZERO, ZERO } - }, - { "poles or columns or something", - { LEFT, RIGHT, LEFT, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO, - ZERO, LEFT, RIGHT, LEFT, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO, - ZERO, LEFT, ZERO } - }, - { "crooked v", - { ZERO, LEFT, ZERO, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO, - ZERO, LEFT, ZERO, LEFT, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO, - ZERO, ZERO, ZERO } - }, - { "dog leg", - { ZERO, LEFT, ZERO, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO, ZERO, - LEFT, ZERO, RIGHT, ZERO, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO, - ZERO, ZERO } - }, - { "scrubby", - { ZERO, ZERO, ZERO, ZERO, ZERO, LEFT, ZERO, ZERO, ZERO, ZERO, - LEFT, RIGHT, ZERO, ZERO, ZERO, ZERO, LEFT, RIGHT, ZERO, ZERO, - LEFT, PIN, ZERO, ZERO } - }, - { "voltron's eyes", - { ZERO, ZERO, PIN, RIGHT, ZERO, LEFT, ZERO, ZERO, RIGHT, ZERO, - LEFT, PIN, ZERO, ZERO, PIN, ZERO, LEFT, ZERO, RIGHT, LEFT, ZERO, - RIGHT, ZERO, ZERO } - }, - { "flying toaster", - { PIN, ZERO, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, - RIGHT, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, ZERO, - PIN, ZERO } - }, - { "dubbya", - { PIN, ZERO, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, - ZERO, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, ZERO, - PIN, ZERO } - }, - { "tap handle", - { PIN, ZERO, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, - LEFT, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, ZERO, - PIN, ZERO } - }, - { "wingnut", - { PIN, ZERO, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, - PIN, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, ZERO, - PIN, ZERO } - }, - { "tight twist", - { RIGHT, ZERO, ZERO, LEFT, ZERO, LEFT, RIGHT, ZERO, RIGHT, LEFT, - RIGHT, PIN, RIGHT, LEFT, RIGHT, ZERO, RIGHT, LEFT, ZERO, LEFT, - ZERO, ZERO, RIGHT, ZERO } - }, - { "double helix", - { RIGHT, ZERO, RIGHT, ZERO, RIGHT, ZERO, RIGHT, ZERO, RIGHT, - ZERO, RIGHT, ZERO, RIGHT, LEFT, RIGHT, PIN, ZERO, RIGHT, ZERO, - RIGHT, ZERO, RIGHT, ZERO, ZERO } - }, - - /* These models come from the website at - * http://www.geocities.com/stigeide/snake */ -#if 0 - { "Abstract", - { RIGHT, LEFT, RIGHT, ZERO, PIN, ZERO, LEFT, RIGHT, LEFT, PIN, ZERO, ZERO, PIN, LEFT, RIGHT, LEFT, ZERO, PIN, ZERO, RIGHT, LEFT, RIGHT, ZERO, ZERO } - }, -#endif - { "toadstool", - { LEFT, RIGHT, ZERO, RIGHT, LEFT, ZERO, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, PIN, RIGHT, LEFT, PIN, ZERO } - }, - { "AlanH2", - { LEFT, RIGHT, ZERO, RIGHT, LEFT, ZERO, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, ZERO } - }, - { "AlanH3", - { LEFT, RIGHT, ZERO, RIGHT, LEFT, ZERO, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, ZERO } - }, - { "AlanH4", - { ZERO, ZERO, PIN, LEFT, RIGHT, LEFT, ZERO, RIGHT, LEFT, RIGHT, ZERO, PIN, ZERO, LEFT, RIGHT, LEFT, ZERO, RIGHT, LEFT, RIGHT, PIN, ZERO, ZERO, ZERO } - }, - { "Alien", - { RIGHT, LEFT, RIGHT, PIN, ZERO, ZERO, PIN, RIGHT, LEFT, RIGHT, ZERO, PIN, PIN, ZERO, LEFT, LEFT, RIGHT, RIGHT, LEFT, LEFT, ZERO, PIN, PIN, ZERO } - }, - { "Angel", - { ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, ZERO, RIGHT, LEFT, ZERO } - }, - { "AnotherFigure", - { LEFT, PIN, RIGHT, ZERO, ZERO, PIN, RIGHT, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, PIN, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, LEFT, PIN, ZERO, ZERO } - }, - { "Ball", - { LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT , ZERO } - }, - { "Basket", - { ZERO, RIGHT, RIGHT, ZERO, RIGHT, RIGHT, ZERO, RIGHT, LEFT, ZERO, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, LEFT, RIGHT, PIN, LEFT, LEFT, ZERO, LEFT , ZERO } - }, - { "Beetle", - { PIN, LEFT, RIGHT, ZERO, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, ZERO, LEFT, RIGHT, PIN, RIGHT , ZERO } - }, - { "bone", - { PIN, PIN, LEFT, ZERO, PIN, PIN, ZERO, LEFT, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, RIGHT, PIN, PIN , ZERO } - }, - { "Bow", - { LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT , ZERO } - }, - { "bra", - { RIGHT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, LEFT, LEFT , ZERO } - }, - { "bronchosaurus", - { ZERO, PIN, ZERO, PIN, PIN, ZERO, PIN, ZERO, ZERO, PIN, ZERO, PIN, PIN, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, PIN , ZERO } - }, - { "Cactus", - { PIN, LEFT, ZERO, PIN, PIN, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, PIN, RIGHT, PIN, LEFT, ZERO, ZERO, RIGHT, PIN, LEFT, PIN, ZERO, ZERO , ZERO } - }, - { "Camel", - { RIGHT, ZERO, PIN, RIGHT, PIN, RIGHT, ZERO, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, ZERO, RIGHT, PIN, RIGHT, ZERO, ZERO, LEFT , ZERO } - }, - { "Candlestick", - { LEFT, PIN, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, PIN, RIGHT , ZERO } - }, - { "Cat", - { ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO , ZERO } - }, - { "Cave", - { RIGHT, ZERO, ZERO, PIN, LEFT, ZERO, PIN, PIN, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, LEFT, LEFT, PIN, RIGHT, RIGHT, LEFT, PIN, ZERO, ZERO , ZERO } - }, - { "Chains", - { PIN, ZERO, ZERO, PIN, LEFT, LEFT, PIN, RIGHT, RIGHT, PIN, ZERO, ZERO, PIN, ZERO, ZERO, PIN, LEFT, LEFT, PIN, RIGHT, RIGHT, PIN, ZERO , ZERO } - }, - { "Chair", - { RIGHT, LEFT, RIGHT, RIGHT, RIGHT, LEFT, RIGHT, ZERO, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, ZERO, LEFT, RIGHT, LEFT, LEFT , ZERO } - }, - { "Chick", - { RIGHT, RIGHT, RIGHT, PIN, LEFT, PIN, LEFT, PIN, RIGHT, RIGHT, RIGHT, PIN, LEFT, LEFT, LEFT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, LEFT, LEFT , ZERO } - }, - { "Clockwise", - { RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT , ZERO } - }, - { "cobra", - { ZERO, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, LEFT, LEFT, ZERO, LEFT, RIGHT, ZERO, ZERO, PIN, ZERO, ZERO, RIGHT , ZERO } - }, -#if 0 - { "Cobra2", - { LEFT, ZERO, PIN, ZERO, PIN, LEFT, ZERO, PIN, ZERO, LEFT, LEFT, PIN, RIGHT, RIGHT, ZERO, PIN, ZERO, RIGHT, PIN, ZERO, PIN, ZERO, RIGHT , ZERO } - }, -#endif - { "Cobra3", - { ZERO, LEFT, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, ZERO, ZERO, LEFT, ZERO, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, LEFT , ZERO } - }, - { "Compact1", - { ZERO, ZERO, PIN, ZERO, ZERO, LEFT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, PIN, RIGHT, PIN, LEFT, ZERO, PIN, PIN, ZERO, ZERO, LEFT, PIN , ZERO } - }, - { "Compact2", - { LEFT, PIN, RIGHT, ZERO, ZERO, PIN, PIN, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, RIGHT, ZERO, ZERO, ZERO , ZERO } - }, - { "Compact3", - { ZERO, PIN, ZERO, PIN, PIN, ZERO, LEFT, PIN, RIGHT, ZERO, PIN, PIN, ZERO, PIN, ZERO, PIN, PIN, ZERO, LEFT, PIN, RIGHT, ZERO, PIN , ZERO } - }, - { "Compact4", - { PIN, RIGHT, ZERO, ZERO, PIN, ZERO, ZERO, PIN, PIN, ZERO, PIN, RIGHT, PIN, LEFT, PIN, ZERO, PIN, PIN, ZERO, ZERO, PIN, ZERO, ZERO , ZERO } - }, - { "Compact5", - { LEFT, ZERO, LEFT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, RIGHT, ZERO, RIGHT, PIN, RIGHT, PIN, LEFT , ZERO } - }, - { "Contact", - { PIN, ZERO, ZERO, PIN, LEFT, LEFT, PIN, LEFT, RIGHT, RIGHT, PIN, LEFT, LEFT, RIGHT, PIN, RIGHT, RIGHT, PIN, ZERO, ZERO, PIN, RIGHT, PIN , ZERO } - }, - { "Contact2", - { RIGHT, PIN, ZERO, LEFT, LEFT, PIN, RIGHT, RIGHT, ZERO, PIN, LEFT, PIN, RIGHT, PIN, ZERO, LEFT, LEFT, PIN, RIGHT, RIGHT, ZERO, PIN, LEFT , ZERO } - }, - { "Cook", - { ZERO, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, RIGHT, LEFT, PIN, LEFT, ZERO, PIN, PIN, ZERO, LEFT, PIN, LEFT, RIGHT, ZERO, RIGHT, ZERO, PIN , ZERO } - }, - { "Counterclockwise", - { LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT , ZERO } - }, - { "Cradle", - { LEFT, LEFT, ZERO, PIN, LEFT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, PIN, ZERO, RIGHT, RIGHT, LEFT, LEFT, ZERO, ZERO, RIGHT , ZERO } - }, - { "Crankshaft", - { ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, PIN, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, PIN, LEFT, PIN, RIGHT, ZERO, ZERO, ZERO, PIN, RIGHT , ZERO } - }, - { "Cross", - { ZERO, PIN, ZERO, PIN, PIN, ZERO, PIN, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO, ZERO, PIN, ZERO, PIN, PIN, ZERO, PIN, ZERO, PIN , ZERO } - }, - { "Cross2", - { ZERO, ZERO, PIN, PIN, ZERO, LEFT, ZERO, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, ZERO, PIN, PIN, ZERO, LEFT, ZERO, ZERO, PIN, PIN, ZERO , ZERO } - }, - { "Cross3", - { ZERO, ZERO, PIN, PIN, ZERO, LEFT, ZERO, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, ZERO, PIN, PIN, ZERO, LEFT, ZERO, ZERO, PIN, PIN, ZERO, ZERO } - }, - { "CrossVersion1", - { PIN, ZERO, RIGHT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, RIGHT, ZERO, PIN, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, ZERO } - }, - { "CrossVersion2", - { RIGHT, LEFT, PIN, LEFT, LEFT, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, LEFT, LEFT, PIN, LEFT, RIGHT, ZERO } - }, - { "Crown", - { LEFT, ZERO, PIN, ZERO, RIGHT, ZERO, ZERO, LEFT, ZERO, PIN, ZERO, RIGHT, LEFT, ZERO, PIN, ZERO, RIGHT, ZERO, ZERO, LEFT, ZERO, PIN, ZERO, ZERO } - }, - { "DNAStrand", - { RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT, ZERO } - }, - { "Diamond", - { ZERO, RIGHT, ZERO, ZERO, LEFT, ZERO, ZERO, RIGHT, PIN, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, PIN, LEFT, ZERO, ZERO, RIGHT, ZERO, ZERO, LEFT, ZERO } - }, - { "Dog", - { RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, ZERO, LEFT, RIGHT, ZERO } - }, - { "DogFace", - { ZERO, ZERO, PIN, PIN, ZERO, LEFT, LEFT, RIGHT, PIN, ZERO, PIN, PIN, ZERO, PIN, LEFT, RIGHT, RIGHT, ZERO, PIN, PIN, ZERO, ZERO, PIN, ZERO } - }, - { "DoublePeak", - { ZERO, ZERO, PIN, ZERO, ZERO, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, LEFT, LEFT, ZERO, PIN, ZERO, RIGHT, RIGHT, LEFT, PIN, LEFT, RIGHT, ZERO } - }, - { "DoubleRoof", - { ZERO, LEFT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, LEFT, ZERO, LEFT, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, ZERO } - }, - { "txoboggan", - { ZERO, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO, ZERO, ZERO, LEFT, PIN, RIGHT, ZERO, ZERO, ZERO, ZERO, PIN, ZERO } - }, - { "Doubled", - { LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, LEFT, ZERO, LEFT, PIN, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, ZERO } - }, - { "Doubled1", - { LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, ZERO, RIGHT, ZERO, RIGHT, ZERO, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, ZERO } - }, - { "Doubled2", - { LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, LEFT, RIGHT, ZERO, RIGHT, LEFT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, ZERO } - }, - { "DumblingSpoon", - { PIN, PIN, ZERO, ZERO, ZERO, ZERO, ZERO, LEFT, ZERO, ZERO, LEFT, RIGHT, ZERO, ZERO, LEFT, RIGHT, ZERO, ZERO, RIGHT, ZERO, ZERO, ZERO, ZERO, ZERO } - }, - { "Embrace", - { PIN, ZERO, ZERO, PIN, RIGHT, PIN, LEFT, PIN, ZERO, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, ZERO, PIN, RIGHT, PIN, LEFT, PIN, ZERO, ZERO } - }, - { "EndlessBelt", - { ZERO, RIGHT, LEFT, ZERO, ZERO, ZERO, LEFT, RIGHT, ZERO, PIN, RIGHT, LEFT, ZERO, LEFT, RIGHT, LEFT, PIN, LEFT, RIGHT, LEFT, ZERO, LEFT, RIGHT, ZERO } - }, - { "Entrance", - { LEFT, LEFT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT, ZERO } - }, - { "Esthetic", - { LEFT, LEFT, PIN, RIGHT, RIGHT, ZERO, LEFT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, PIN, RIGHT, PIN, LEFT, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, ZERO } - }, - { "Explosion", - { RIGHT, RIGHT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, LEFT, ZERO } - }, - { "F-ZeroXCar", - { RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, ZERO, RIGHT, LEFT, ZERO, ZERO, LEFT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, ZERO } - }, - { "Face", - { ZERO, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, LEFT, PIN, RIGHT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, PIN, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, ZERO } - }, - { "Fantasy", - { LEFT, LEFT, RIGHT, PIN, ZERO, RIGHT, ZERO, LEFT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, ZERO, LEFT, ZERO, PIN, LEFT, RIGHT, RIGHT, RIGHT, PIN, ZERO } - }, - { "Fantasy1", - { PIN, ZERO, ZERO, PIN, PIN, ZERO, PIN, RIGHT, LEFT, RIGHT, RIGHT, PIN, LEFT, LEFT, RIGHT, LEFT, PIN, ZERO, PIN, PIN, ZERO, ZERO, PIN, ZERO } - }, - { "FaserGun", - { ZERO, ZERO, LEFT, RIGHT, PIN, RIGHT, ZERO, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, ZERO, RIGHT, PIN, RIGHT, RIGHT, ZERO, PIN, ZERO } - }, - { "FelixW", - { ZERO, RIGHT, ZERO, PIN, LEFT, ZERO, LEFT, RIGHT, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, LEFT, RIGHT, ZERO, RIGHT, PIN, ZERO, LEFT, ZERO, ZERO } - }, - { "Flamingo", - { ZERO, PIN, ZERO, ZERO, ZERO, ZERO, ZERO, PIN, LEFT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, LEFT, ZERO, ZERO, ZERO, PIN, ZERO } - }, - { "FlatOnTheTop", - { ZERO, PIN, PIN, ZERO, PIN, RIGHT, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, RIGHT, ZERO, ZERO, PIN, ZERO, ZERO, PIN, ZERO } - }, - { "Fly", - { ZERO, LEFT, PIN, RIGHT, ZERO, PIN, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, ZERO } - }, - { "Fountain", - { LEFT, RIGHT, LEFT, RIGHT, RIGHT, PIN, LEFT, PIN, LEFT, RIGHT, RIGHT, PIN, LEFT, LEFT, RIGHT, RIGHT, PIN, LEFT, LEFT, RIGHT, PIN, RIGHT, PIN, ZERO } - }, - { "Frog", - { LEFT, LEFT, RIGHT, RIGHT, LEFT, PIN, LEFT, PIN, RIGHT, PIN, LEFT, ZERO, RIGHT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, RIGHT, LEFT, RIGHT, RIGHT, ZERO } - }, - { "Frog2", - { LEFT, ZERO, LEFT, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, LEFT, RIGHT, PIN, LEFT, LEFT, RIGHT, ZERO, RIGHT, ZERO } - }, - { "Furby", - { PIN, ZERO, LEFT, PIN, RIGHT, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, ZERO, PIN, ZERO, RIGHT, PIN, LEFT, ZERO, PIN, ZERO, ZERO, PIN, ZERO } - }, - { "Gate", - { ZERO, ZERO, PIN, ZERO, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, LEFT, PIN, LEFT, LEFT, PIN, RIGHT, RIGHT, PIN, RIGHT, ZERO, PIN, PIN, ZERO, ZERO } - }, - { "Ghost", - { LEFT, LEFT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, ZERO, LEFT, RIGHT, ZERO, ZERO, LEFT, RIGHT, ZERO } - }, - { "Globus", - { RIGHT, LEFT, ZERO, PIN, LEFT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, PIN, ZERO, RIGHT, LEFT, ZERO, ZERO } - }, - { "Grotto", - { PIN, PIN, ZERO, LEFT, RIGHT, LEFT, ZERO, PIN, RIGHT, PIN, LEFT, ZERO, ZERO, ZERO, ZERO, RIGHT, PIN, LEFT, PIN, ZERO, RIGHT, LEFT, RIGHT, ZERO } - }, - { "H", - { PIN, ZERO, PIN, PIN, ZERO, ZERO, ZERO, ZERO, PIN, PIN, ZERO, PIN, LEFT, ZERO, PIN, PIN, ZERO, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO } - }, - { "HeadOfDevil", - { PIN, ZERO, RIGHT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, LEFT, PIN, RIGHT, RIGHT, PIN, RIGHT, LEFT, ZERO, ZERO, ZERO } - }, - { "Heart", - { RIGHT, ZERO, ZERO, ZERO, PIN, LEFT, PIN, LEFT, RIGHT, RIGHT, ZERO, PIN, ZERO, LEFT, LEFT, RIGHT, PIN, RIGHT, PIN, ZERO, ZERO, ZERO, LEFT, ZERO } - }, - { "Heart2", - { ZERO, PIN, ZERO, ZERO, LEFT, ZERO, LEFT, ZERO, ZERO, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, ZERO, RIGHT, ZERO, RIGHT, ZERO, ZERO, PIN, ZERO, ZERO } - }, - { "Hexagon", - { ZERO, ZERO, ZERO, ZERO, LEFT, ZERO, ZERO, RIGHT, ZERO, ZERO, ZERO, ZERO, LEFT, ZERO, ZERO, RIGHT, ZERO, ZERO, ZERO, ZERO, LEFT, ZERO, ZERO, ZERO } - }, - { "HoleInTheMiddle1", - { ZERO, LEFT, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, LEFT, RIGHT, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, RIGHT, ZERO } - }, - { "HoleInTheMiddle2", - { ZERO, LEFT, RIGHT, ZERO, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, RIGHT, LEFT, ZERO, LEFT, RIGHT, ZERO, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, RIGHT, ZERO } - }, - { "HouseBoat", - { RIGHT, RIGHT, PIN, LEFT, LEFT, LEFT, PIN, RIGHT, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, LEFT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, RIGHT, PIN, ZERO } - }, - { "HouseByHouse", - { LEFT, PIN, LEFT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, PIN, RIGHT, ZERO } - }, - { "Infinity", - { LEFT, LEFT, LEFT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, RIGHT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, RIGHT, LEFT, LEFT, ZERO } - }, - { "Integral", - { RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, ZERO } - }, - { "Iron", - { ZERO, ZERO, ZERO, ZERO, PIN, RIGHT, ZERO, RIGHT, ZERO, ZERO, LEFT, PIN, RIGHT, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, RIGHT, ZERO, RIGHT, ZERO } - }, - { "just squares", - { RIGHT, RIGHT, LEFT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, LEFT, LEFT, PIN, RIGHT, RIGHT, LEFT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, LEFT, LEFT, ZERO } - }, - { "Kink", - { ZERO, PIN, PIN, ZERO, PIN, ZERO, PIN, PIN, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, PIN, PIN, ZERO, PIN, ZERO, PIN, PIN, ZERO, ZERO } - }, - { "Knot", - { LEFT, LEFT, PIN, LEFT, ZERO, LEFT, RIGHT, LEFT, PIN, LEFT, LEFT, RIGHT, RIGHT, PIN, RIGHT, LEFT, RIGHT, ZERO, RIGHT, PIN, RIGHT, RIGHT, LEFT, ZERO } - }, - { "Leaf", - { ZERO, PIN, PIN, ZERO, ZERO, LEFT, ZERO, LEFT, ZERO, ZERO, PIN, ZERO, ZERO, RIGHT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO } - }, - { "LeftAsRight", - { RIGHT, PIN, LEFT, RIGHT, LEFT, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, RIGHT, LEFT, RIGHT, PIN, LEFT, ZERO } - }, - { "Long-necked", - { PIN, ZERO, LEFT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, ZERO, PIN, ZERO, LEFT, PIN, LEFT, PIN, RIGHT, PIN, LEFT, ZERO, PIN, PIN, ZERO, ZERO } - }, - { "lunar module", - { PIN, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, RIGHT, LEFT, ZERO, LEFT, ZERO } - }, - { "magnifying glass", - { ZERO, ZERO, PIN, ZERO, LEFT, ZERO, PIN, PIN, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, ZERO, ZERO, ZERO } - }, - { "Mask", - { ZERO, ZERO, ZERO, RIGHT, ZERO, RIGHT, LEFT, ZERO, LEFT, PIN, ZERO, PIN, ZERO, ZERO, PIN, ZERO, PIN, RIGHT, ZERO, RIGHT, LEFT, ZERO, LEFT, ZERO } - }, - { "Microscope", - { PIN, PIN, ZERO, ZERO, PIN, ZERO, RIGHT, PIN, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, PIN, LEFT, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO } - }, - { "Mirror", - { PIN, RIGHT, LEFT, ZERO, PIN, PIN, ZERO, ZERO, LEFT, RIGHT, ZERO, ZERO, PIN, ZERO, ZERO, LEFT, RIGHT, PIN, RIGHT, ZERO, PIN, PIN, ZERO, ZERO } - }, - { "MissPiggy", - { ZERO, LEFT, LEFT, PIN, RIGHT, ZERO, RIGHT, RIGHT, PIN, LEFT, LEFT, RIGHT, RIGHT, PIN, LEFT, LEFT, ZERO, LEFT, PIN, RIGHT, RIGHT, ZERO, RIGHT, ZERO } - }, - { "Mole", - { ZERO, RIGHT, ZERO, RIGHT, LEFT, RIGHT, PIN, ZERO, LEFT, PIN, RIGHT, ZERO, PIN, LEFT, RIGHT, LEFT, ZERO, LEFT, ZERO, RIGHT, RIGHT, PIN, LEFT, ZERO } - }, - { "Monk", - { LEFT, ZERO, PIN, PIN, ZERO, LEFT, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, ZERO } - }, - { "Mountain", - { ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, LEFT, PIN, LEFT, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, ZERO } - }, - { "mountains", - { ZERO, PIN, ZERO, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, ZERO, PIN, ZERO, ZERO } - }, - { "MouseWithoutTail", - { ZERO, PIN, PIN, ZERO, LEFT, ZERO, PIN, PIN, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, ZERO } - }, - { "mushroom", - { PIN, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, ZERO, LEFT, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, LEFT, ZERO, PIN, ZERO } - }, - { "necklace", - { ZERO, ZERO, LEFT, ZERO, ZERO, ZERO, LEFT, ZERO, ZERO, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, ZERO, RIGHT, ZERO, ZERO, ZERO, RIGHT, ZERO, ZERO, ZERO } - }, - { "NestledAgainst", - { LEFT, ZERO, PIN, LEFT, LEFT, RIGHT, RIGHT, PIN, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, LEFT, ZERO } - }, - { "NoClue", - { ZERO, RIGHT, PIN, LEFT, LEFT, LEFT, ZERO, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, ZERO, RIGHT, RIGHT, RIGHT, PIN, LEFT, ZERO, ZERO } - }, - { "Noname", - { LEFT, PIN, RIGHT, PIN, RIGHT, ZERO, PIN, ZERO, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, RIGHT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, LEFT, ZERO } - }, - { "Obelisk", - { PIN, ZERO, ZERO, ZERO, PIN, RIGHT, PIN, LEFT, PIN, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, ZERO, ZERO, ZERO, ZERO } - }, - { "Ostrich", - { ZERO, ZERO, PIN, PIN, ZERO, LEFT, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, ZERO, ZERO, ZERO, ZERO, PIN, ZERO } - }, - { "Ostrich2", - { PIN, PIN, ZERO, PIN, LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, PIN, ZERO, PIN, ZERO, ZERO, PIN, ZERO, ZERO } - }, - { "pair of glasses", - { ZERO, PIN, ZERO, ZERO, PIN, ZERO, ZERO, PIN, ZERO, LEFT, ZERO, PIN, ZERO, RIGHT, ZERO, PIN, ZERO, ZERO, PIN, ZERO, ZERO, PIN, ZERO, ZERO } - }, - { "Parrot", - { ZERO, ZERO, ZERO, ZERO, RIGHT, RIGHT, ZERO, LEFT, PIN, RIGHT, ZERO, RIGHT, ZERO, RIGHT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, LEFT, ZERO, PIN, ZERO } - }, - { "Penis", - { PIN, PIN, RIGHT, ZERO, PIN, PIN, ZERO, PIN, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, PIN, ZERO, PIN, PIN, ZERO, LEFT, PIN, PIN, ZERO } - }, - { "PictureComingSoon", - { LEFT, LEFT, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, RIGHT, PIN, RIGHT, LEFT, ZERO, RIGHT, RIGHT, ZERO } - }, - { "Pitti", - { LEFT, PIN, ZERO, ZERO, PIN, ZERO, ZERO, PIN, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, PIN, ZERO, ZERO, PIN, ZERO, ZERO, PIN, RIGHT, ZERO } - }, - { "Plait", - { LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, LEFT, ZERO } - }, - { "Platform", - { RIGHT, PIN, ZERO, ZERO, ZERO, ZERO, PIN, ZERO, ZERO, PIN, PIN, ZERO, PIN, LEFT, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO } - }, - { "PodRacer", - { ZERO, PIN, ZERO, PIN, RIGHT, PIN, ZERO, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, PIN, PIN, ZERO, ZERO, LEFT, ZERO, PIN, LEFT, ZERO } - }, -#if 0 - { "Pokemon", - { LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, ZERO } - }, -#endif - { "Prawn", - { RIGHT, PIN, ZERO, PIN, RIGHT, ZERO, PIN, PIN, ZERO, ZERO, LEFT, PIN, RIGHT, ZERO, ZERO, PIN, PIN, ZERO, LEFT, PIN, ZERO, PIN, LEFT, ZERO } - }, - { "Propeller", - { ZERO, ZERO, ZERO, RIGHT, ZERO, LEFT, RIGHT, LEFT, ZERO, ZERO, ZERO, RIGHT, ZERO, LEFT, RIGHT, LEFT, ZERO, ZERO, ZERO, RIGHT, ZERO, LEFT, RIGHT, ZERO } - }, - { "Pyramid", - { ZERO, LEFT, PIN, RIGHT, ZERO, LEFT, PIN, RIGHT, ZERO, LEFT, PIN, RIGHT, ZERO, PIN, RIGHT, LEFT, LEFT, LEFT, PIN, RIGHT, RIGHT, RIGHT, LEFT, ZERO } - }, - { "QuarterbackTiltedAndReadyToHut", - { PIN, ZERO, RIGHT, RIGHT, LEFT, RIGHT, PIN, RIGHT, LEFT, RIGHT, ZERO, PIN, ZERO, LEFT, RIGHT, LEFT, PIN, LEFT, RIGHT, LEFT, LEFT, ZERO, PIN, ZERO } - }, - { "Ra", - { PIN, LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, ZERO, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, ZERO } - }, - { "Rattlesnake", - { LEFT, ZERO, LEFT, ZERO, LEFT, ZERO, LEFT, LEFT, ZERO, LEFT, ZERO, LEFT, ZERO, LEFT, RIGHT, ZERO, PIN, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, ZERO } - }, - { "Revelation", - { ZERO, ZERO, ZERO, PIN, ZERO, ZERO, PIN, RIGHT, LEFT, LEFT, LEFT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, LEFT, PIN, ZERO, ZERO, PIN, ZERO } - }, - { "Revolution1", - { LEFT, LEFT, PIN, RIGHT, ZERO, PIN, ZERO, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, ZERO, PIN, ZERO, LEFT, PIN, RIGHT, RIGHT, ZERO } - }, - { "Ribbon", - { RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, PIN, ZERO, PIN, PIN, ZERO, PIN, ZERO, PIN, PIN, ZERO, PIN, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, ZERO } - }, - { "Rocket", - { RIGHT, ZERO, LEFT, PIN, RIGHT, ZERO, RIGHT, ZERO, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, ZERO, LEFT, ZERO, LEFT, PIN, RIGHT, ZERO, LEFT, ZERO } - }, - { "Roofed", - { ZERO, LEFT, PIN, RIGHT, ZERO, PIN, LEFT, ZERO, PIN, ZERO, RIGHT, PIN, ZERO, LEFT, PIN, RIGHT, ZERO, PIN, LEFT, ZERO, PIN, ZERO, RIGHT, ZERO } - }, - { "Roofs", - { PIN, PIN, RIGHT, ZERO, LEFT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, RIGHT, ZERO, LEFT, PIN, PIN, ZERO } - }, - { "RowHouses", - { RIGHT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, PIN, RIGHT, PIN, LEFT, ZERO } - }, - { "Sculpture", - { RIGHT, LEFT, PIN, ZERO, ZERO, ZERO, LEFT, RIGHT, LEFT, PIN, ZERO, ZERO, PIN, LEFT, RIGHT, LEFT, ZERO, ZERO, ZERO, PIN, LEFT, RIGHT, LEFT, ZERO } - }, - { "Seal", - { LEFT, LEFT, LEFT, PIN, RIGHT, RIGHT, RIGHT, ZERO, LEFT, PIN, RIGHT, ZERO, LEFT, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, PIN, PIN, ZERO, LEFT, ZERO } - }, - { "Seal2", - { RIGHT, PIN, ZERO, LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, RIGHT, PIN, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, ZERO, LEFT, RIGHT, ZERO, ZERO, ZERO } - }, - { "Sheep", - { RIGHT, LEFT, LEFT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, LEFT, LEFT, LEFT, RIGHT, LEFT, ZERO } - }, - { "Shelter", - { LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, ZERO, ZERO, ZERO, ZERO, PIN, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, ZERO, RIGHT, ZERO } - }, - { "Ship", - { PIN, RIGHT, LEFT, LEFT, LEFT, LEFT, PIN, RIGHT, RIGHT, RIGHT, RIGHT, LEFT, ZERO, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, LEFT, ZERO, PIN, PIN, ZERO } - }, - { "Shpongle", - { LEFT, RIGHT, ZERO, RIGHT, LEFT, RIGHT, ZERO, RIGHT, LEFT, RIGHT, ZERO, RIGHT, LEFT, RIGHT, ZERO, RIGHT, LEFT, RIGHT, ZERO, RIGHT, LEFT, RIGHT, ZERO, ZERO } - }, - { "Slide", - { LEFT, RIGHT, LEFT, RIGHT, ZERO, LEFT, RIGHT, LEFT, PIN, ZERO, ZERO, PIN, ZERO, ZERO, PIN, RIGHT, LEFT, ZERO, ZERO, RIGHT, LEFT, RIGHT, LEFT, ZERO } - }, - { "SmallShip", - { ZERO, LEFT, RIGHT, ZERO, RIGHT, LEFT, ZERO, LEFT, RIGHT, ZERO, LEFT, RIGHT, ZERO, LEFT, RIGHT, ZERO, RIGHT, LEFT, ZERO, LEFT, RIGHT, ZERO, LEFT, ZERO } - }, - { "SnakeReadyToStrike", - { LEFT, ZERO, LEFT, ZERO, LEFT, ZERO, LEFT, RIGHT, ZERO, RIGHT, ZERO, RIGHT, ZERO, LEFT, ZERO, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, ZERO, LEFT, ZERO } - }, - { "Snakes14", - { RIGHT, RIGHT, PIN, ZERO, RIGHT, LEFT, RIGHT, ZERO, ZERO, ZERO, RIGHT, PIN, LEFT, PIN, ZERO, PIN, LEFT, PIN, RIGHT, ZERO, ZERO, LEFT, RIGHT, ZERO } - }, - { "Snakes15", - { ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, PIN, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, PIN, LEFT, PIN, RIGHT, ZERO, ZERO, ZERO, PIN, RIGHT, ZERO } - }, - { "Snakes18", - { PIN, PIN, LEFT, PIN, LEFT, PIN, RIGHT, ZERO, RIGHT, PIN, RIGHT, ZERO, RIGHT, PIN, LEFT, PIN, RIGHT, ZERO, PIN, PIN, ZERO, ZERO, PIN, ZERO } - }, - { "Snowflake", - { LEFT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, RIGHT, ZERO } - }, - { "Snowman", - { ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, ZERO, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, ZERO, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, ZERO } - }, - { "Source", - { PIN, RIGHT, ZERO, PIN, ZERO, LEFT, PIN, RIGHT, PIN, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, PIN, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, PIN, ZERO } - }, - { "Spaceship", - { PIN, PIN, RIGHT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, PIN, RIGHT, PIN, PIN, ZERO } - }, - { "Spaceship2", - { PIN, PIN, LEFT, PIN, LEFT, PIN, RIGHT, ZERO, PIN, PIN, ZERO, LEFT, PIN, RIGHT, ZERO, PIN, ZERO, LEFT, PIN, LEFT, LEFT, PIN, PIN, ZERO } - }, - { "Speedboat", - { LEFT, ZERO, ZERO, LEFT, PIN, RIGHT, ZERO, ZERO, LEFT, ZERO, ZERO, PIN, ZERO, ZERO, RIGHT, ZERO, ZERO, LEFT, PIN, RIGHT, ZERO, ZERO, RIGHT, ZERO } - }, - { "Speedboat2", - { PIN, RIGHT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, ZERO, LEFT, PIN, RIGHT, ZERO, LEFT, LEFT, LEFT, RIGHT, RIGHT, LEFT, PIN, ZERO, RIGHT, PIN, LEFT, ZERO } - }, - { "Spider", - { RIGHT, RIGHT, ZERO, ZERO, LEFT, RIGHT, LEFT, PIN, ZERO, LEFT, ZERO, PIN, PIN, ZERO, RIGHT, ZERO, PIN, RIGHT, LEFT, RIGHT, ZERO, ZERO, LEFT, ZERO } - }, - { "Spitzbergen", - { PIN, LEFT, ZERO, RIGHT, RIGHT, LEFT, PIN, ZERO, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, ZERO, PIN, RIGHT, LEFT, LEFT, ZERO, ZERO } - }, - { "Square", - { ZERO, ZERO, LEFT, LEFT, PIN, RIGHT, RIGHT, ZERO, ZERO, LEFT, LEFT, PIN, RIGHT, RIGHT, ZERO, ZERO, LEFT, LEFT, PIN, RIGHT, RIGHT, ZERO, ZERO, ZERO } - }, - { "SquareHole", - { PIN, ZERO, PIN, ZERO, ZERO, PIN, PIN, ZERO, PIN, ZERO, ZERO, PIN, ZERO, ZERO, PIN, ZERO, PIN, PIN, ZERO, ZERO, PIN, ZERO, PIN, ZERO } - }, - { "Stage", - { RIGHT, ZERO, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, LEFT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, ZERO, ZERO } - }, - { "Stairs", - { ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, ZERO } - }, - { "Stairs2", - { ZERO, PIN, ZERO, PIN, ZERO, PIN, PIN, ZERO, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, PIN, ZERO, ZERO, PIN, ZERO, ZERO } - }, - { "Straight", - { ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO } - }, - { "Swan", - { ZERO, PIN, ZERO, PIN, LEFT, LEFT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, PIN, LEFT, PIN, LEFT, RIGHT, ZERO } - }, - { "Swan2", - { PIN, ZERO, PIN, RIGHT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, RIGHT, PIN, ZERO, ZERO, ZERO, ZERO, ZERO, PIN, PIN, ZERO } - }, - { "Swan3", - { PIN, PIN, ZERO, ZERO, ZERO, RIGHT, ZERO, RIGHT, ZERO, ZERO, LEFT, PIN, RIGHT, ZERO, ZERO, RIGHT, PIN, LEFT, ZERO, ZERO, RIGHT, ZERO, RIGHT, ZERO } - }, - { "Symbol", - { RIGHT, RIGHT, PIN, ZERO, PIN, PIN, ZERO, PIN, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, PIN, ZERO, PIN, PIN, ZERO, PIN, LEFT, LEFT, RIGHT, ZERO } - }, - { "Symmetry", - { RIGHT, ZERO, LEFT, RIGHT, LEFT, ZERO, LEFT, RIGHT, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, LEFT, RIGHT, ZERO, RIGHT, LEFT, RIGHT, ZERO, LEFT, ZERO } - }, - { "Symmetry2", - { ZERO, PIN, LEFT, LEFT, PIN, ZERO, ZERO, LEFT, PIN, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, PIN, LEFT, ZERO } - }, - { "TableFireworks", - { ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, RIGHT, PIN, RIGHT, LEFT, ZERO, RIGHT, PIN, ZERO } - }, - { "Tapering", - { ZERO, ZERO, RIGHT, LEFT, PIN, LEFT, ZERO, PIN, PIN, ZERO, LEFT, PIN, RIGHT, ZERO, PIN, PIN, ZERO, RIGHT, PIN, RIGHT, LEFT, ZERO, ZERO, ZERO } - }, - { "TaperingTurned", - { ZERO, ZERO, RIGHT, LEFT, PIN, LEFT, ZERO, PIN, PIN, ZERO, LEFT, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, RIGHT, PIN, RIGHT, LEFT, ZERO, ZERO, ZERO } - }, - { "TeaLightStick", - { RIGHT, ZERO, PIN, PIN, ZERO, LEFT, RIGHT, PIN, LEFT, LEFT, RIGHT, RIGHT, PIN, LEFT, LEFT, RIGHT, RIGHT, PIN, LEFT, LEFT, RIGHT, RIGHT, PIN, ZERO } - }, - { "thighmaster", - { RIGHT, ZERO, ZERO, RIGHT, LEFT, ZERO, ZERO, RIGHT, LEFT, ZERO, ZERO, LEFT, RIGHT, ZERO, ZERO, RIGHT, LEFT, ZERO, ZERO, RIGHT, LEFT, ZERO, ZERO, ZERO } - }, - { "Terraces", - { RIGHT, LEFT, ZERO, RIGHT, LEFT, PIN, LEFT, LEFT, PIN, LEFT, RIGHT, RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT, PIN, RIGHT, RIGHT, PIN, RIGHT, LEFT, ZERO } - }, - { "Terrier", - { PIN, ZERO, PIN, PIN, ZERO, PIN, ZERO, ZERO, ZERO, PIN, PIN, ZERO, PIN, ZERO, ZERO, PIN, ZERO, PIN, PIN, ZERO, ZERO, ZERO, ZERO, ZERO } - }, - { "Three-Legged", - { RIGHT, ZERO, LEFT, RIGHT, ZERO, LEFT, PIN, RIGHT, ZERO, RIGHT, ZERO, PIN, ZERO, LEFT, ZERO, LEFT, PIN, RIGHT, ZERO, LEFT, RIGHT, ZERO, LEFT, ZERO } - }, - { "ThreePeaks", - { RIGHT, ZERO, ZERO, RIGHT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, RIGHT, PIN, LEFT, LEFT, PIN, LEFT, PIN, RIGHT, PIN, LEFT, ZERO, ZERO, LEFT, ZERO } - }, - { "ToTheFront", - { ZERO, PIN, RIGHT, LEFT, LEFT, LEFT, PIN, RIGHT, LEFT, ZERO, PIN, PIN, ZERO, LEFT, LEFT, PIN, ZERO, LEFT, RIGHT, ZERO, PIN, ZERO, LEFT, ZERO } - }, - { "Top", - { PIN, LEFT, LEFT, PIN, LEFT, ZERO, ZERO, RIGHT, LEFT, PIN, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, PIN, RIGHT, PIN, RIGHT, RIGHT, PIN, ZERO, ZERO } - }, - { "Transport", - { PIN, ZERO, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, ZERO, PIN, ZERO, ZERO, ZERO, ZERO } - }, - { "Triangle", - { ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, RIGHT, LEFT, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, RIGHT, LEFT, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, RIGHT, ZERO } - }, - { "Tripple", - { PIN, ZERO, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, PIN, ZERO, PIN, LEFT, PIN, RIGHT, PIN, ZERO, PIN, LEFT, PIN, LEFT, PIN, RIGHT, PIN, ZERO } - }, -#if 0 - { "Turtle", - { RIGHT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, LEFT, PIN, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, ZERO, LEFT, RIGHT, ZERO, ZERO } - }, -#endif - { "Twins", - { ZERO, PIN, ZERO, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, PIN, ZERO, ZERO, PIN, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, ZERO, PIN, ZERO, ZERO, ZERO } - }, - { "TwoSlants", - { ZERO, PIN, ZERO, ZERO, PIN, PIN, ZERO, PIN, ZERO, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, PIN, RIGHT, PIN, LEFT, ZERO, ZERO, RIGHT, PIN, ZERO } - }, - { "TwoWings", - { PIN, LEFT, ZERO, RIGHT, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, PIN, PIN, ZERO, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, LEFT, ZERO, ZERO } - }, - { "UFO", - { LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, LEFT, PIN, LEFT, LEFT, LEFT, RIGHT, LEFT, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, ZERO } - }, - { "USS Enterprise", - { LEFT, PIN, RIGHT, PIN, RIGHT, LEFT, ZERO, PIN, PIN, ZERO, RIGHT, LEFT, ZERO, PIN, PIN, ZERO, RIGHT, LEFT, PIN, LEFT, PIN, RIGHT, ZERO, ZERO } - }, - { "UpAndDown", - { ZERO, PIN, ZERO, PIN, ZERO, PIN, LEFT, PIN, RIGHT, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, PIN, LEFT, PIN, RIGHT, PIN, ZERO, ZERO } - }, - { "Upright", - { ZERO, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, PIN, ZERO, ZERO, LEFT, PIN, RIGHT, ZERO, ZERO, PIN, RIGHT, RIGHT, LEFT, RIGHT, LEFT, LEFT, ZERO, ZERO } - }, - { "Upside-down", - { PIN, ZERO, ZERO, ZERO, PIN, PIN, ZERO, RIGHT, RIGHT, LEFT, LEFT, PIN, RIGHT, RIGHT, LEFT, LEFT, ZERO, PIN, PIN, ZERO, ZERO, ZERO, PIN, ZERO } - }, - { "Valley", - { ZERO, RIGHT, PIN, LEFT, PIN, RIGHT, PIN, RIGHT, LEFT, RIGHT, ZERO, PIN, ZERO, LEFT, RIGHT, LEFT, PIN, LEFT, PIN, RIGHT, PIN, LEFT, ZERO, ZERO } - }, - { "Viaduct", - { PIN, RIGHT, PIN, LEFT, PIN, ZERO, ZERO, PIN, RIGHT, ZERO, RIGHT, RIGHT, ZERO, RIGHT, PIN, ZERO, ZERO, PIN, LEFT, PIN, RIGHT, PIN, ZERO, ZERO } - }, - { "View", - { ZERO, RIGHT, PIN, LEFT, PIN, RIGHT, ZERO, ZERO, RIGHT, PIN, LEFT, LEFT, RIGHT, RIGHT, PIN, LEFT, ZERO, ZERO, LEFT, PIN, RIGHT, PIN, LEFT, ZERO } - }, - { "Waterfall", - { LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, PIN, LEFT, ZERO, RIGHT, ZERO } - }, - { "windwheel", - { PIN, RIGHT, RIGHT, PIN, ZERO, LEFT, PIN, RIGHT, RIGHT, PIN, ZERO, LEFT, PIN, RIGHT, RIGHT, PIN, ZERO, LEFT, PIN, RIGHT, RIGHT, PIN, ZERO, ZERO } - }, - { "Window", - { PIN, ZERO, PIN, PIN, ZERO, ZERO, PIN, ZERO, PIN, ZERO, PIN, ZERO, ZERO, PIN, ZERO, PIN, ZERO, PIN, PIN, ZERO, ZERO, ZERO, ZERO, ZERO } - }, - { "WindowToTheWorld", - { PIN, LEFT, ZERO, PIN, ZERO, ZERO, PIN, ZERO, ZERO, PIN, ZERO, RIGHT, PIN, LEFT, ZERO, PIN, ZERO, ZERO, PIN, ZERO, ZERO, PIN, ZERO, ZERO } - }, - { "Windshield", - { PIN, PIN, ZERO, RIGHT, PIN, LEFT, LEFT, PIN, RIGHT, ZERO, PIN, ZERO, LEFT, PIN, RIGHT, RIGHT, PIN, LEFT, ZERO, PIN, PIN, ZERO, PIN, ZERO } - }, - { "WingNut", - { ZERO, ZERO, ZERO, ZERO, PIN, RIGHT, RIGHT, RIGHT, PIN, RIGHT, LEFT, PIN, LEFT, RIGHT, PIN, RIGHT, RIGHT, RIGHT, PIN, ZERO, ZERO, ZERO, ZERO, ZERO } - }, - { "Wings2", - { RIGHT, ZERO, PIN, ZERO, LEFT, PIN, RIGHT, PIN, RIGHT, LEFT, RIGHT, RIGHT, LEFT, LEFT, RIGHT, LEFT, PIN, LEFT, PIN, RIGHT, ZERO, PIN, ZERO, ZERO } - }, - { "WithoutName", - { PIN, RIGHT, PIN, RIGHT, RIGHT, PIN, LEFT, LEFT, PIN, ZERO, PIN, RIGHT, PIN, LEFT, PIN, ZERO, PIN, RIGHT, RIGHT, PIN, LEFT, LEFT, PIN, ZERO } - }, - { "Wolf", - { ZERO, ZERO, PIN, PIN, ZERO, PIN, ZERO, ZERO, PIN, ZERO, PIN, PIN, ZERO, PIN, ZERO, ZERO, ZERO, PIN, PIN, ZERO, ZERO, ZERO, PIN, ZERO } - }, - { "X", - { LEFT, ZERO, ZERO, PIN, LEFT, RIGHT, RIGHT, PIN, LEFT, RIGHT, ZERO, PIN, PIN, ZERO, LEFT, RIGHT, PIN, LEFT, LEFT, RIGHT, PIN, ZERO, ZERO, ZERO } - }, -}; - -static size_t models = sizeof(model) / sizeof(struct model_s); - -#define VOFFSET 0.045 - -#define X_MASK 1 -#define Y_MASK 2 -#define Z_MASK 4 - -/* the connecting string that holds the snake together */ -#define MAGICAL_RED_STRING 0 - -#define GETSCALAR(vec,mask) ((vec)==(mask) ? 1 : ((vec)==-(mask) ? -1 : 0 )) - -#ifndef MAX -# define MAX(x, y) ((x) > (y) ? (x) : (y)) -#endif -#ifndef MIN -# define MIN(x, y) ((x) < (y) ? (x) : (y)) -#endif - -#define RAND(n) ((random() & 0x7fffffff) % ((long) (n))) -#define RANDSIGN() ((random() & 1) ? 1 : -1) - -/* the triangular prism what makes up the basic unit */ -static const float solid_prism_v[][3] = { - /* first corner, bottom left front */ - { VOFFSET, VOFFSET, 1.0 }, - { VOFFSET, 0.00, 1.0 - VOFFSET }, - { 0.00, VOFFSET, 1.0 - VOFFSET }, - /* second corner, rear */ - { VOFFSET, VOFFSET, 0.00 }, - { VOFFSET, 0.00, VOFFSET }, - { 0.00, VOFFSET, VOFFSET }, - /* third, right front */ - { 1.0 - VOFFSET / M_SQRT1_2, VOFFSET, 1.0 }, - { 1.0 - VOFFSET / M_SQRT1_2, 0.0, 1.0 - VOFFSET }, - { 1.0 - VOFFSET * M_SQRT1_2, VOFFSET, 1.0 - VOFFSET }, - /* fourth, right rear */ - { 1.0 - VOFFSET / M_SQRT1_2, VOFFSET, 0.0 }, - { 1.0 - VOFFSET / M_SQRT1_2, 0.0, VOFFSET }, - { 1.0 - VOFFSET * M_SQRT1_2, VOFFSET, VOFFSET }, - /* fifth, upper front */ - { VOFFSET, 1.0 - VOFFSET / M_SQRT1_2, 1.0 }, - { VOFFSET / M_SQRT1_2, 1.0 - VOFFSET * M_SQRT1_2, 1.0 - VOFFSET }, - { 0.0, 1.0 - VOFFSET / M_SQRT1_2, 1.0 - VOFFSET}, - /* sixth, upper rear */ - { VOFFSET, 1.0 - VOFFSET / M_SQRT1_2, 0.0 }, - { VOFFSET / M_SQRT1_2, 1.0 - VOFFSET * M_SQRT1_2, VOFFSET }, - { 0.0, 1.0 - VOFFSET / M_SQRT1_2, VOFFSET }}; - -static const float solid_prism_n[][3] = {/* corners */ - { -VOFFSET, -VOFFSET, VOFFSET }, - { VOFFSET, -VOFFSET, VOFFSET }, - { -VOFFSET, VOFFSET, VOFFSET }, - { -VOFFSET, -VOFFSET, -VOFFSET }, - { VOFFSET, -VOFFSET, -VOFFSET }, - { -VOFFSET, VOFFSET, -VOFFSET }, - /* edges */ - { -VOFFSET, 0.0, VOFFSET }, - { 0.0, -VOFFSET, VOFFSET }, - { VOFFSET, VOFFSET, VOFFSET }, - { -VOFFSET, 0.0, -VOFFSET }, - { 0.0, -VOFFSET, -VOFFSET }, - { VOFFSET, VOFFSET, -VOFFSET }, - { -VOFFSET, -VOFFSET, 0.0 }, - { VOFFSET, -VOFFSET, 0.0 }, - { -VOFFSET, VOFFSET, 0.0 }, - /* faces */ - { 0.0, 0.0, 1.0 }, - { 0.0, -1.0, 0.0 }, - { M_SQRT1_2, M_SQRT1_2, 0.0 }, - { -1.0, 0.0, 0.0 }, - { 0.0, 0.0, -1.0 }}; - -static const float wire_prism_v[][3] = {{ 0.0, 0.0, 1.0 }, - { 1.0, 0.0, 1.0 }, - { 0.0, 1.0, 1.0 }, - { 0.0, 0.0, 0.0 }, - { 1.0, 0.0, 0.0 }, - { 0.0, 1.0, 0.0 }}; - -/* -static const float wire_prism_n[][3] = {{ 0.0, 0.0, 1.0}, - { 0.0,-1.0, 0.0}, - { M_SQRT1_2, M_SQRT1_2, 0.0}, - {-1.0, 0.0, 0.0}, - { 0.0, 0.0,-1.0}}; -*/ - -static struct glsnake_cfg * glc = NULL; -#ifdef HAVE_GLUT -# define bp glc -#endif - -typedef float (*morphFunc)(long); - -#ifdef HAVE_GLUT -/* forward definitions for GLUT functions */ -static void calc_rotation(); -static inline void ui_mousedrag(); -#endif - -static const GLfloat white_light[] = { 1.0, 1.0, 1.0, 1.0 }; -static const GLfloat lmodel_ambient[] = { 0.2, 0.2, 0.2, 1.0 }; -static const GLfloat mat_specular[] = { 0.1, 0.1, 0.1, 1.0 }; -static const GLfloat mat_shininess[] = { 20.0 }; - -static void gl_init( -#ifndef HAVE_GLUT - ModeInfo * mi -#endif - ) -{ - float light_pos[][3] = {{0.0, 10.0, 20.0}, {0.0, 20.0, -1.0}}; - float light_dir[][3] = {{0.0, -10.0,-20.0}, {0.0,-20.0, 1.0}}; - - glEnable(GL_DEPTH_TEST); - glShadeModel(GL_SMOOTH); - glCullFace(GL_BACK); - /*glEnable(GL_CULL_FACE);*/ - glEnable(GL_NORMALIZE); - if (transparent) { - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - } - - if (!wireframe) { - /*glColor4f(1.0, 1.0, 1.0, 1.0);*/ - glLightfv(GL_LIGHT0, GL_POSITION, light_pos[0]); - glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, light_dir[0]); - glLightfv(GL_LIGHT0, GL_DIFFUSE, white_light); - /*glLightfv(GL_LIGHT0, GL_SPECULAR, white_light);*/ -#if 1 - glLightfv(GL_LIGHT1, GL_POSITION, light_pos[1]); - glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, light_dir[1]); - glLightfv(GL_LIGHT1, GL_DIFFUSE, white_light); - glLightfv(GL_LIGHT1, GL_SPECULAR, white_light); -#endif - glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); - glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); - glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); - glEnable(GL_LIGHTING); - glEnable(GL_LIGHT0); - glEnable(GL_LIGHT1); - /*glEnable(GL_COLOR_MATERIAL);*/ - } -} - -static void gettime(snaketime *t) -{ -#ifdef HAVE_GETTIMEOFDAY -#ifdef GETTIMEOFDAY_TWO_ARGS - struct timezone tzp; - gettimeofday(t, &tzp); -#else /* !GETTIMEOFDAY_TWO_ARGS */ - gettimeofday(t); -#endif /* !GETTIMEOFDAY_TWO_ARGS */ -#else /* !HAVE_GETTIMEOFDAY */ -#ifdef HAVE_FTIME - ftime(t); -#endif /* HAVE_FTIME */ -#endif /* !HAVE_GETTIMEOFDAY */ -} - - -ENTRYPOINT void glsnake_reshape( -#ifndef HAVE_GLUT - ModeInfo * mi, -#endif - int w, int h); - -static void start_morph(struct glsnake_cfg *, - unsigned int model_index, int immediate); - -/* wot initialises it */ -ENTRYPOINT void glsnake_init( -#ifndef HAVE_GLUT -ModeInfo * mi -#endif -) -{ -#ifndef HAVE_GLUT - struct glsnake_cfg * bp; - - /* set up the conf struct and glx contexts */ - MI_INIT(mi, glc); - bp = &glc[MI_SCREEN(mi)]; - - if ((bp->glx_context = init_GL(mi)) != NULL) { - gl_init(mi); - glsnake_reshape(mi, MI_WIDTH(mi), MI_HEIGHT(mi)); - } -#else - gl_init(); -#endif - - /* initialise conf struct */ - memset(&bp->node, 0, sizeof(float) * NODE_COUNT); - - bp->selected = 11; - bp->is_cyclic = 0; - bp->is_legal = 1; - bp->last_turn = -1; - bp->morphing = 0; - bp->paused = 0; - bp->new_morph = 0; - - gettime(&bp->last_iteration); - memcpy(&bp->last_morph, &bp->last_iteration, sizeof(bp->last_morph)); - - bp->prev_colour = bp->next_colour = COLOUR_ACYCLIC; - bp->next_model = RAND(models); - bp->prev_model = START_MODEL; - start_morph(bp, bp->prev_model, 1); - - /* set up a font for the labels */ -#ifndef HAVE_GLUT - if (titles) - bp->font_data = load_texture_font (mi->dpy, "labelfont"); -#endif - - /* build a solid display list */ - bp->node_solid = glGenLists(1); - glNewList(bp->node_solid, GL_COMPILE); - /* corners */ - glBegin(GL_TRIANGLES); - glNormal3fv(solid_prism_n[0]); - glVertex3fv(solid_prism_v[0]); - glVertex3fv(solid_prism_v[2]); - glVertex3fv(solid_prism_v[1]); - bp->node_polys++; - - glNormal3fv(solid_prism_n[1]); - glVertex3fv(solid_prism_v[6]); - glVertex3fv(solid_prism_v[7]); - glVertex3fv(solid_prism_v[8]); - bp->node_polys++; - - glNormal3fv(solid_prism_n[2]); - glVertex3fv(solid_prism_v[12]); - glVertex3fv(solid_prism_v[13]); - glVertex3fv(solid_prism_v[14]); - bp->node_polys++; - - glNormal3fv(solid_prism_n[3]); - glVertex3fv(solid_prism_v[3]); - glVertex3fv(solid_prism_v[4]); - glVertex3fv(solid_prism_v[5]); - bp->node_polys++; - - glNormal3fv(solid_prism_n[4]); - glVertex3fv(solid_prism_v[9]); - glVertex3fv(solid_prism_v[11]); - glVertex3fv(solid_prism_v[10]); - bp->node_polys++; - - glNormal3fv(solid_prism_n[5]); - glVertex3fv(solid_prism_v[16]); - glVertex3fv(solid_prism_v[15]); - glVertex3fv(solid_prism_v[17]); - bp->node_polys++; - glEnd(); - - /* edges */ - glBegin(GL_QUADS); - glNormal3fv(solid_prism_n[6]); - glVertex3fv(solid_prism_v[0]); - glVertex3fv(solid_prism_v[12]); - glVertex3fv(solid_prism_v[14]); - glVertex3fv(solid_prism_v[2]); - bp->node_polys++; - - glNormal3fv(solid_prism_n[7]); - glVertex3fv(solid_prism_v[0]); - glVertex3fv(solid_prism_v[1]); - glVertex3fv(solid_prism_v[7]); - glVertex3fv(solid_prism_v[6]); - bp->node_polys++; - - glNormal3fv(solid_prism_n[8]); - glVertex3fv(solid_prism_v[6]); - glVertex3fv(solid_prism_v[8]); - glVertex3fv(solid_prism_v[13]); - glVertex3fv(solid_prism_v[12]); - bp->node_polys++; - - glNormal3fv(solid_prism_n[9]); - glVertex3fv(solid_prism_v[3]); - glVertex3fv(solid_prism_v[5]); - glVertex3fv(solid_prism_v[17]); - glVertex3fv(solid_prism_v[15]); - bp->node_polys++; - - glNormal3fv(solid_prism_n[10]); - glVertex3fv(solid_prism_v[3]); - glVertex3fv(solid_prism_v[9]); - glVertex3fv(solid_prism_v[10]); - glVertex3fv(solid_prism_v[4]); - bp->node_polys++; - - glNormal3fv(solid_prism_n[11]); - glVertex3fv(solid_prism_v[15]); - glVertex3fv(solid_prism_v[16]); - glVertex3fv(solid_prism_v[11]); - glVertex3fv(solid_prism_v[9]); - bp->node_polys++; - - glNormal3fv(solid_prism_n[12]); - glVertex3fv(solid_prism_v[1]); - glVertex3fv(solid_prism_v[2]); - glVertex3fv(solid_prism_v[5]); - glVertex3fv(solid_prism_v[4]); - bp->node_polys++; - - glNormal3fv(solid_prism_n[13]); - glVertex3fv(solid_prism_v[8]); - glVertex3fv(solid_prism_v[7]); - glVertex3fv(solid_prism_v[10]); - glVertex3fv(solid_prism_v[11]); - bp->node_polys++; - - glNormal3fv(solid_prism_n[14]); - glVertex3fv(solid_prism_v[13]); - glVertex3fv(solid_prism_v[16]); - glVertex3fv(solid_prism_v[17]); - glVertex3fv(solid_prism_v[14]); - bp->node_polys++; - glEnd(); - - /* faces */ - glBegin(GL_TRIANGLES); - glNormal3fv(solid_prism_n[15]); - glVertex3fv(solid_prism_v[0]); - glVertex3fv(solid_prism_v[6]); - glVertex3fv(solid_prism_v[12]); - bp->node_polys++; - - glNormal3fv(solid_prism_n[19]); - glVertex3fv(solid_prism_v[3]); - glVertex3fv(solid_prism_v[15]); - glVertex3fv(solid_prism_v[9]); - bp->node_polys++; - glEnd(); - - glBegin(GL_QUADS); - glNormal3fv(solid_prism_n[16]); - glVertex3fv(solid_prism_v[1]); - glVertex3fv(solid_prism_v[4]); - glVertex3fv(solid_prism_v[10]); - glVertex3fv(solid_prism_v[7]); - bp->node_polys++; - - glNormal3fv(solid_prism_n[17]); - glVertex3fv(solid_prism_v[8]); - glVertex3fv(solid_prism_v[11]); - glVertex3fv(solid_prism_v[16]); - glVertex3fv(solid_prism_v[13]); - bp->node_polys++; - - glNormal3fv(solid_prism_n[18]); - glVertex3fv(solid_prism_v[2]); - glVertex3fv(solid_prism_v[14]); - glVertex3fv(solid_prism_v[17]); - glVertex3fv(solid_prism_v[5]); - bp->node_polys++; - glEnd(); - glEndList(); - - /* build wire display list */ - bp->node_wire = glGenLists(1); - glNewList(bp->node_wire, GL_COMPILE); - glBegin(GL_LINE_STRIP); - glVertex3fv(wire_prism_v[0]); - glVertex3fv(wire_prism_v[1]); - bp->node_polys++; - glVertex3fv(wire_prism_v[2]); - glVertex3fv(wire_prism_v[0]); - bp->node_polys++; - glVertex3fv(wire_prism_v[3]); - glVertex3fv(wire_prism_v[4]); - bp->node_polys++; - glVertex3fv(wire_prism_v[5]); - glVertex3fv(wire_prism_v[3]); - bp->node_polys++; - glEnd(); - glBegin(GL_LINES); - glVertex3fv(wire_prism_v[1]); - glVertex3fv(wire_prism_v[4]); - bp->node_polys++; - glVertex3fv(wire_prism_v[2]); - glVertex3fv(wire_prism_v[5]); - bp->node_polys++; - glEnd(); - glEndList(); - -#ifdef HAVE_GLUT - /* initialise the rotation */ - calc_rotation(); -#endif -} - -static void draw_title( -#ifndef HAVE_GLUT - ModeInfo * mi -#endif - ) -{ -#ifndef HAVE_GLUT - struct glsnake_cfg * bp = &glc[MI_SCREEN(mi)]; -#endif - - /* draw some text */ - -/* glPushAttrib((GLbitfield) GL_TRANSFORM_BIT | GL_ENABLE_BIT);*/ - glDisable(GL_LIGHTING); - glDisable(GL_DEPTH_TEST); - if (transparent) { - glDisable(GL_BLEND); - } - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); -#ifdef HAVE_GLUT - glOrtho((GLdouble) 0., (GLdouble) bp->width, (GLdouble) 0., (GLdouble) bp->height, -1, 1); -#else - glOrtho((GLdouble) 0., (GLdouble) mi->xgwa.width, (GLdouble) 0., (GLdouble) mi->xgwa.height, -1, 1); -#endif - - glColor4f(1.0, 1.0, 1.0, 1.0); - { - char interactstr[] = "interactive"; - const char * s; -#ifdef HAVE_GLUT - int w; -#endif - - if (interactive) - s = interactstr; - else - s = model[bp->next_model].name; - -#ifdef HAVE_GLUT - { - unsigned int i = 0; - - w = glutBitmapLength(GLUT_BITMAP_HELVETICA_12, (const unsigned char *) s); - glRasterPos2f((GLfloat) (bp->width - w - 3), 4.0); - while (s[i] != '\0') - glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, s[i++]); - } -#else - print_texture_label (mi->dpy, bp->font_data, - mi->xgwa.width, mi->xgwa.height, - 1, s); -#endif - } - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - - -/* glPopAttrib();*/ -} - -/* apply the matrix to the origin and stick it in vec */ -static void matmult_origin(float rotmat[16], float vec[4]) -{ -#if 1 - vec[0] = 0.5 * rotmat[0] + 0.5 * rotmat[4] + 0.5 * rotmat [8] + 1 * rotmat[12]; - vec[1] = 0.5 * rotmat[1] + 0.5 * rotmat[5] + 0.5 * rotmat [9] + 1 * rotmat[13]; - vec[2] = 0.5 * rotmat[2] + 0.5 * rotmat[6] + 0.5 * rotmat[10] + 1 * rotmat[14]; - vec[3] = 0.5 * rotmat[3] + 0.5 * rotmat[7] + 0.5 * rotmat[11] + 1 * rotmat[15]; -#else - vec[0] = 0 * rotmat [0] + 0 * rotmat [1] + 0 * rotmat [2] + 1 * rotmat [3]; - vec[1] = 0 * rotmat [4] + 0 * rotmat [5] + 0 * rotmat [6] + 1 * rotmat [7]; - vec[2] = 0 * rotmat [8] + 0 * rotmat [9] + 0 * rotmat[10] + 1 * rotmat[11]; - vec[3] = 0 * rotmat[12] + 0 * rotmat[13] + 0 * rotmat[14] + 1 * rotmat[15]; -#endif - vec[0] /= vec[3]; - vec[1] /= vec[3]; - vec[2] /= vec[3]; - vec[3] = 1.0; -} - -/* wot gets called when the winder is resized */ -ENTRYPOINT void glsnake_reshape( -#ifndef HAVE_GLUT - ModeInfo * mi, -#endif - int width, int height) -{ - double h = (GLfloat) height / (GLfloat) width; - int y = 0; - - if (width > height * 5) { /* tiny window: show middle */ - height = width; - y = -height/2; - h = height / (GLfloat) width; - } - - glViewport(0, y, width, height); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - /* jwz: 0.05 was too close (left black rectangles) */ - gluPerspective(zoom, 1/h, 1.0, 100.0); - gluLookAt(0.0, 0.0, 20.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); - glMatrixMode(GL_MODELVIEW); - /*gluLookAt(0.0, 0.0, 20.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);*/ - glLoadIdentity(); -#ifdef HAVE_GLUT - bp->width = width; - bp->height = height; -#endif -} - -/* Returns the new dst_dir for the given src_dir and dst_dir */ -static int cross_product(int src_dir, int dst_dir) -{ - return X_MASK*(GETSCALAR(src_dir,Y_MASK) * GETSCALAR(dst_dir,Z_MASK) - - GETSCALAR(src_dir,Z_MASK) * GETSCALAR(dst_dir,Y_MASK))+ - Y_MASK*(GETSCALAR(src_dir,Z_MASK) * GETSCALAR(dst_dir,X_MASK) - - GETSCALAR(src_dir,X_MASK) * GETSCALAR(dst_dir,Z_MASK))+ - Z_MASK*(GETSCALAR(src_dir,X_MASK) * GETSCALAR(dst_dir,Y_MASK) - - GETSCALAR(src_dir,Y_MASK) * GETSCALAR(dst_dir,X_MASK)); -} - -/* calculate orthogonal snake metrics - * is_legal = true if model does not pass through itself - * is_cyclic = true if last node connects back to first node - * last_turn = for cyclic snakes, specifes what the 24th turn would be - */ -static void calc_snake_metrics(struct glsnake_cfg *bp) -{ - int srcDir, dstDir; - int i, x, y, z; - int prevSrcDir = -Y_MASK; - int prevDstDir = Z_MASK; - int grid[25][25][25]; - - /* zero the grid */ - memset(&grid, 0, sizeof(int) * 25*25*25); - - bp->is_legal = 1; - x = y = z = 12; - - /* trace path of snake - and keep record for is_legal */ - for (i = 0; i < NODE_COUNT - 1; i++) { - /*int ang_card;*/ /* cardinal direction of node angle */ - /* establish new state vars */ - srcDir = -prevDstDir; - x += GETSCALAR(prevDstDir, X_MASK); - y += GETSCALAR(prevDstDir, Y_MASK); - z += GETSCALAR(prevDstDir, Z_MASK); - - switch ((int) model[bp->next_model].node[i]) { - case (int) (ZERO): - dstDir = -prevSrcDir; - break; - case (int) (PIN): - dstDir = prevSrcDir; - break; - case (int) (RIGHT): - case (int) (LEFT): - dstDir = cross_product(prevSrcDir, prevDstDir); - if (model[bp->next_model].node[i] == (int) (RIGHT)) - dstDir = -dstDir; - break; - default: - /* Prevent spurious "might be used - * uninitialised" warnings when compiling - * with -O2 */ - dstDir = 0; - break; - } - - if (grid[x][y][z] == 0) - grid[x][y][z] = srcDir + dstDir; - else if (grid[x][y][z] + srcDir + dstDir == 0) - grid[x][y][z] = 8; - else - bp->is_legal = 0; - - prevSrcDir = srcDir; - prevDstDir = dstDir; - } - - /* determine if the snake is cyclic */ - bp->is_cyclic = (dstDir == Y_MASK && x == 12 && y == 11 && z == 12); - - /* determine last_turn */ - bp->last_turn = -1; - if (bp->is_cyclic) - switch (srcDir) { - case -Z_MASK: bp->last_turn = ZERO; break; - case Z_MASK: bp->last_turn = PIN; break; - case X_MASK: bp->last_turn = LEFT; break; - case -X_MASK: bp->last_turn = RIGHT; break; - } -} - -/* work out how far through the current morph we are */ -static float morph_percent(struct glsnake_cfg *bp) -{ - float retval; - int i; - - /* extend this function later with a case statement for each of the - * morph schemes */ - - /* when morphing all nodes at once, the longest morph will be the node - * that needs to rotate 180 degrees. For each node, work out how far it - * has to go, and store the maximum rotation and current largest angular - * difference, returning the angular difference over the maximum. */ - { - float rot_max = 0.0, ang_diff_max = 0.0; - - for (i = 0; i < NODE_COUNT - 1; i++) { - float rot, ang_diff; - - /* work out the maximum rotation this node has to go through - * from the previous to the next model, taking into account that - * the snake always morphs through the smaller angle */ - rot = fabs(model[bp->prev_model].node[i] - - model[bp->next_model].node[i]); - if (rot > 180.0) rot = 180.0 - rot; - /* work out the difference between the current position and the - * target */ - ang_diff = fabs(bp->node[i] - - model[bp->next_model].node[i]); - if (ang_diff > 180.0) ang_diff = 180.0 - ang_diff; - /* if it's the biggest so far, record it */ - if (rot > rot_max) rot_max = rot; - if (ang_diff > ang_diff_max) ang_diff_max = ang_diff; - } - - /* ang_diff / rot approaches 0, we want the complement */ - retval = 1.0 - (ang_diff_max / rot_max); - /* protect against naan */ - -/* Apparently some systems (Solaris) don't have isinf() */ -#undef isinf -#define isinf(x) (((x) > 999999999999.9) || ((x) < -999999999999.9)) - - if (isnan(retval) || isinf(retval)) retval = 1.0; - } - /*printf("morph_pct = %f\n", retval);*/ - return retval; -} - -static void morph_colour(struct glsnake_cfg *bp) -{ - float percent, compct; /* complement of percentage */ - - percent = morph_percent(bp); - compct = 1.0 - percent; - - bp->colour[0][0] = colour[bp->prev_colour][0][0] * compct + colour[bp->next_colour][0][0] * percent; - bp->colour[0][1] = colour[bp->prev_colour][0][1] * compct + colour[bp->next_colour][0][1] * percent; - bp->colour[0][2] = colour[bp->prev_colour][0][2] * compct + colour[bp->next_colour][0][2] * percent; - bp->colour[0][3] = colour[bp->prev_colour][0][3] * compct + colour[bp->next_colour][0][3] * percent; - - bp->colour[1][0] = colour[bp->prev_colour][1][0] * compct + colour[bp->next_colour][1][0] * percent; - bp->colour[1][1] = colour[bp->prev_colour][1][1] * compct + colour[bp->next_colour][1][1] * percent; - bp->colour[1][2] = colour[bp->prev_colour][1][2] * compct + colour[bp->next_colour][1][2] * percent; - bp->colour[1][3] = colour[bp->prev_colour][1][3] * compct + colour[bp->next_colour][1][3] * percent; -} - -/* Start morph process to this model */ -static void start_morph(struct glsnake_cfg *bp, - unsigned int model_index, int immediate) -{ - /* if immediate, don't bother morphing, go straight to the next model */ - if (immediate) { - int i; - - for (i = 0; i < NODE_COUNT; i++) - bp->node[i] = model[model_index].node[i]; - } - - bp->prev_model = bp->next_model; - bp->next_model = model_index; - bp->prev_colour = bp->next_colour; - - calc_snake_metrics(bp); - if (!bp->is_legal) - bp->next_colour = COLOUR_INVALID; - else if (altcolour) - bp->next_colour = COLOUR_AUTHENTIC; - else if (bp->is_cyclic) - bp->next_colour = COLOUR_CYCLIC; - else - bp->next_colour = COLOUR_ACYCLIC; - - if (immediate) { - bp->colour[0][0] = colour[bp->next_colour][0][0]; - bp->colour[0][1] = colour[bp->next_colour][0][1]; - bp->colour[0][2] = colour[bp->next_colour][0][2]; - bp->colour[0][3] = colour[bp->next_colour][0][3]; - bp->colour[1][0] = colour[bp->next_colour][1][0]; - bp->colour[1][1] = colour[bp->next_colour][1][1]; - bp->colour[1][2] = colour[bp->next_colour][1][2]; - bp->colour[1][3] = colour[bp->next_colour][1][3]; - } - bp->morphing = 1; - - morph_colour(bp); -} - -#if 0 -/* Returns morph progress */ -static float morph(long iter_msec) -{ - /* work out the maximum angle for this iteration */ - int still_morphing; - float iter_angle_max, largest_diff, largest_progress; - int i; - - if (bp->new_morph) - bp->new_morph = 0; - - iter_angle_max = 90.0 * (angvel/1000.0) * iter_msec; - - still_morphing = 0; - largest_diff = largest_progress = 0.0; - for (i = 0; i < NODE_COUNT; i++) { - float curAngle = bp->node[i]; - float destAngle = model[bp->next_model].node[i]; - if (curAngle != destAngle) { - still_morphing = 1; - if (fabs(curAngle-destAngle) <= iter_angle_max) - bp->node[i] = destAngle; - else if (fmod(curAngle-destAngle+360,360) > 180) - bp->node[i] = fmod(curAngle + iter_angle_max, 360); - else - bp->node[i] = fmod(curAngle+360 - iter_angle_max, 360); - largest_diff = MAX(largest_diff, fabs(destAngle-bp->node[i])); - largest_progress = MAX(largest_diff, fabs(bp->node[i] - model[bp->prev_model].node[i])); - } - } - - return MIN(largest_diff / largest_progress, 1.0); -} -#endif - - -#ifdef HAVE_GLUT -static void glsnake_idle(); - -static restore_idle(int v __attribute__((__unused__))) -{ - glutIdleFunc(glsnake_idle); -} -#endif - -static void quick_sleep(void) -{ -#ifdef HAVE_GLUT - /* By using glutTimerFunc we can keep responding to - * mouse and keyboard events, unlike using something like - * usleep. */ - glutIdleFunc(NULL); - glutTimerFunc(1, restore_idle, 0); -#else - usleep(1); -#endif -} - -static void glsnake_idle( -#ifndef HAVE_GLUT - struct glsnake_cfg * bp -#endif - ) -{ - /* time since last iteration */ - long iter_msec; - /* time since the beginning of last morph */ - long morf_msec; - float iter_angle_max; - snaketime current_time; - /* morphFunc transition; */ - int still_morphing; - int i; - - /* Do nothing to the model if we are paused */ - if (bp->paused) { - /* Avoid busy waiting when nothing is changing */ - quick_sleep(); -#ifdef HAVE_GLUT - glutSwapBuffers(); - glutPostRedisplay(); -#endif - return; - } - - /* <spiv> Well, ftime gives time with millisecond resolution. - * <spiv> (or worse, perhaps... who knows what the OS will do) - * <spiv> So if no discernable amount of time has passed: - * <spiv> a) There's no point updating the screen, because - * it would be the same - * <spiv> b) The code will divide by zero - */ - gettime(¤t_time); - - iter_msec = (long) GETMSECS(current_time) - GETMSECS(bp->last_iteration) + - ((long) GETSECS(current_time) - GETSECS(bp->last_iteration)) * 1000L; - - if (iter_msec) { - /* save the current time */ - memcpy(&bp->last_iteration, ¤t_time, sizeof(snaketime)); - - /* work out if we have to switch models */ - morf_msec = GETMSECS(bp->last_iteration) - GETMSECS(bp->last_morph) + - ((long) (GETSECS(bp->last_iteration)-GETSECS(bp->last_morph)) * 1000L); - - if ((morf_msec > statictime) && !interactive && !bp->morphing) { - /*printf("starting morph\n");*/ - memcpy(&bp->last_morph, &(bp->last_iteration), sizeof(bp->last_morph)); - start_morph(bp, RAND(models), 0); - } - - if (interactive && !bp->morphing) { - quick_sleep(); - return; - } - - /* if (!bp->dragging && !bp->interactive) { */ - if (!interactive) { - - yspin += 360/((1000/yangvel)/iter_msec); - zspin += 360/((1000/zangvel)/iter_msec); - /* - yspin += 360 * (yangvel/1000.0) * iter_msec; - zspin += 360 * (zangvel/1000.0) * iter_msec; - */ - - /*printf("yspin: %f, zspin: %f\n", yspin, zspin);*/ - - } - - /* work out the maximum angle we could turn this node in this - * timeslice, iter_msec milliseconds long */ - iter_angle_max = 90.0 * (angvel/1000.0) * iter_msec; - - still_morphing = 0; - for (i = 0; i < NODE_COUNT; i++) { - float cur_angle = bp->node[i]; - float dest_angle = model[bp->next_model].node[i]; - if (cur_angle != dest_angle) { - still_morphing = 1; - if (fabs(cur_angle - dest_angle) <= iter_angle_max) - bp->node[i] = dest_angle; - else if (fmod(cur_angle - dest_angle + 360, 360) > 180) - bp->node[i] = fmod(cur_angle + iter_angle_max, 360); - else - bp->node[i] = fmod(cur_angle + 360 - iter_angle_max, 360); - } - } - - if (!still_morphing) - bp->morphing = 0; - - /* colour cycling */ - morph_colour(bp); - -#ifdef HAVE_GLUT - glutSwapBuffers(); - glutPostRedisplay(); -#endif - } else { - /* We are going too fast, so we may as well let the - * cpu relax a little by sleeping for a millisecond. */ - quick_sleep(); - } -} - -/* wot draws it */ -ENTRYPOINT void glsnake_display( -#ifndef HAVE_GLUT - ModeInfo * mi -#endif - ) -{ -#ifndef HAVE_GLUT - struct glsnake_cfg * bp = &glc[MI_SCREEN(mi)]; - Display * dpy = MI_DISPLAY(mi); - Window window = MI_WINDOW(mi); -#endif - - int i; - float ang; - float positions[NODE_COUNT][4]; /* origin points for each node */ - float com[4]; /* it's the CENTRE of MASS */ - -#ifndef HAVE_GLUT - if (!bp->glx_context) - return; - - glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *bp->glx_context); -#endif - - gl_init(mi); - - /* clear the buffer */ - glClear((GLbitfield) GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - /* go into the modelview stack */ - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - /* get the centre of each node, by moving through the snake and - * performing the rotations, then grabbing the matrix at each point - * and applying it to the origin */ - glPushMatrix(); - -#ifdef HAVE_GLUT - /* apply the mouse drag rotation */ - ui_mousedrag(); -#endif - - /* apply the continuous rotation */ - glRotatef(yspin, 0.0, 1.0, 0.0); - glRotatef(zspin, 0.0, 0.0, 1.0); - - com[0] = 0.0; - com[1] = 0.0; - com[2] = 0.0; - com[3] = 0.0; - for (i = 0; i < NODE_COUNT; i++) { - float rotmat[16]; - - ang = bp->node[i]; - - /*printf("ang = %f\n", ang);*/ - - glTranslatef(0.5, 0.5, 0.5); /* move to center */ - glRotatef(90.0, 0.0, 0.0, -1.0); /* reorient */ - glTranslatef(1.0 + explode, 0.0, 0.0); /* move to new pos. */ - glRotatef(180.0 + ang, 1.0, 0.0, 0.0); /* pivot to new angle */ - glTranslatef(-0.5, -0.5, -0.5); /* return from center */ - - glGetFloatv(GL_MODELVIEW_MATRIX, rotmat); - - matmult_origin(rotmat, positions[i]); - - /*printf("positions %f %f %f %f\n", positions[i][0], positions[i][1], positions[i][2], positions[i][3]);*/ - - com[0] += positions[i][0]; - com[1] += positions[i][1]; - com[2] += positions[i][2]; - com[3] += positions[i][3]; - } - glPopMatrix(); - com[0] /= NODE_COUNT; - com[1] /= NODE_COUNT; - com[2] /= NODE_COUNT; - com[3] /= NODE_COUNT; - - com[0] /= com[3]; - com[1] /= com[3]; - com[2] /= com[3]; - - /*printf("com: %f, %f, %f, %f\n", com[0], com[1], com[2], com[3]);*/ - -#if MAGICAL_RED_STRING - glPushMatrix(); - glTranslatef(-com[0], -com[1], -com[2]); - - glDisable(GL_LIGHTING); - glColor4f(1.0, 0.0, 0.0, 1.0); - glBegin(GL_LINE_STRIP); - for (i = 0; i < NODE_COUNT - 1; i++) { - glVertex3fv(positions[i]); - } - glEnd(); - glEnable(GL_LIGHTING); - /*glTranslatef(com[0], com[1], com[2]);*/ - glPopMatrix(); -#endif - - glPushMatrix(); - glTranslatef(-com[0], -com[1], -com[2]); - -#ifdef HAVE_GLUT - /* apply the mouse drag rotation */ - ui_mousedrag(); -#endif - - /* apply the continuous rotation */ - glRotatef(yspin, 0.0, 1.0, 0.0); - glRotatef(zspin, 0.0, 0.0, 1.0); - - { - GLfloat s = (MI_WIDTH(mi) < MI_HEIGHT(mi) - ? (MI_WIDTH(mi) / (GLfloat) MI_HEIGHT(mi)) - : 1); - glScalef (s, s, s); - } - - /* now draw each node along the snake -- this is quite ugly :p */ - mi->polygon_count = 0; - for (i = 0; i < NODE_COUNT; i++) { - /* choose a colour for this node */ - if ((i == bp->selected || i == bp->selected+1) && interactive) - /* yellow */ - glColor4f(1.0, 1.0, 0.0, 1.0); - else { - /*glColor4fv(bp->colour[(i+1)%2]);*/ - glMaterialfv(GL_FRONT, GL_AMBIENT, bp->colour[(i+1)%2]); - glMaterialfv(GL_FRONT, GL_DIFFUSE, bp->colour[(i+1)%2]); - /*glMaterialfv(GL_FRONT, GL_SPECULAR, bp->colour[(i+1)%2]);*/ - } - - /* draw the node */ - if (wireframe) - glCallList(bp->node_wire); - else - glCallList(bp->node_solid); - mi->polygon_count += bp->node_polys; - - /* now work out where to draw the next one */ - - /* Interpolate between models */ - ang = bp->node[i]; - - glTranslatef(0.5, 0.5, 0.5); /* move to center */ - glRotatef(90.0, 0.0, 0.0, -1.0); /* reorient */ - glTranslatef(1.0 + explode, 0.0, 0.0); /* move to new pos. */ - glRotatef(180.0 + ang, 1.0, 0.0, 0.0); /* pivot to new angle */ - glTranslatef(-0.5, -0.5, -0.5); /* return from center */ - } - - glPopMatrix(); - - if (titles) -#ifdef HAVE_GLUT - draw_title(); -#else - draw_title(mi); -#endif - -#ifndef HAVE_GLUT - glsnake_idle(bp); - if (mi->fps_p) do_fps(mi); -#endif - - glFlush(); -#ifdef HAVE_GLUT - glutSwapBuffers(); -#else - glXSwapBuffers(dpy, window); -#endif -} - - -#ifndef HAVE_GLUT -ENTRYPOINT void free_glsnake(ModeInfo * mi) -{ - struct glsnake_cfg * bp = &glc[MI_SCREEN(mi)]; - if (!bp->glx_context) return; - glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *bp->glx_context); - if (bp->font_data) free_texture_font (bp->font_data); - if (glIsList(bp->node_solid)) glDeleteLists(bp->node_solid, 1); - if (glIsList(bp->node_wire)) glDeleteLists(bp->node_wire, 1); -} -#endif - - -#ifdef HAVE_GLUT -/* anything that needs to be cleaned up goes here */ -static void unmain() -{ - glutDestroyWindow(bp->window); - free(bp); -} - -static void ui_init(int *, char **); - -int main(int argc, char ** argv) -{ - bp = malloc(sizeof(struct glsnake_cfg)); - memset(bp, 0, sizeof(struct glsnake_cfg)); - - bp->width = 640; - bp->height = 480; - - ui_init(&argc, argv); - - gettime(&bp->last_iteration); - memcpy(&bp->last_morph, &bp->last_iteration, sizeof(snaketime)); - srand((unsigned int)GETSECS(bp->last_iteration)); - - bp->prev_colour = bp->next_colour = COLOUR_ACYCLIC; - bp->next_model = RAND(models); - bp->prev_model = 0; - start_morph(bp->prev_model, 1); - - glsnake_init(); - - atexit(unmain); - glutSwapBuffers(); - glutMainLoop(); - - return 0; -} -#endif - -/* - * GLUT FUNCTIONS - */ - -#ifdef HAVE_GLUT - -/* trackball quaternions */ -static float cumquat[4] = {0.0,0.0,0.0,0.0}, oldquat[4] = {0.0,0.0,0.0,0.1}; - -/* rotation matrix */ -static float rotation[16]; - -/* mouse drag vectors: start and end */ -static float mouse_start[3], mouse_end[3]; - -/* dragging boolean */ -static int dragging = 0; - -/* this function calculates the rotation matrix based on the quaternions - * generated from the mouse drag vectors */ -static void calc_rotation() -{ - double Nq, s; - double xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz; - - /* this bit ripped from Shoemake's quaternion notes from SIGGRAPH */ - Nq = cumquat[0] * cumquat[0] + cumquat[1] * cumquat[1] + - cumquat[2] * cumquat[2] + cumquat[3] * cumquat[3]; - s = (Nq > 0.0) ? (2.0 / Nq) : 0.0; - xs = cumquat[0] * s; ys = cumquat[1] * s; zs = cumquat[2] * s; - wx = cumquat[3] * xs; wy = cumquat[3] * ys; wz = cumquat[3] * zs; - xx = cumquat[0] * xs; xy = cumquat[0] * ys; xz = cumquat[0] * zs; - yy = cumquat[1] * ys; yz = cumquat[1] * zs; zz = cumquat[2] * zs; - - rotation[0] = 1.0 - (yy + zz); - rotation[1] = xy + wz; - rotation[2] = xz - wy; - rotation[4] = xy - wz; - rotation[5] = 1.0 - (xx + zz); - rotation[6] = yz + wx; - rotation[8] = xz + wy; - rotation[9] = yz - wx; - rotation[10] = 1.0 - (xx + yy); - rotation[3] = rotation[7] = rotation[11] = 0.0; - rotation[12] = rotation[13] = rotation[14] = 0.0; - rotation[15] = 1.0; -} - -static inline void ui_mousedrag() -{ - glMultMatrixf(rotation); -} - -static void ui_keyboard(unsigned char c, int x__attribute__((__unused__)), int y __attribute__((__unused__))) -{ - int i; - - switch (c) { - case 27: /* ESC */ - case 'q': - exit(0); - break; - case 'e': - explode += DEF_EXPLODE; - glutPostRedisplay(); - break; - case 'E': - explode -= DEF_EXPLODE; - if (explode < 0.0) explode = 0.0; - glutPostRedisplay(); - break; - case '.': - /* next model */ - bp->next_model++; - bp->next_model %= models; - start_morph(bp->next_model, 0); - - /* Reset last_morph time */ - gettime(&bp->last_morph); - break; - case ',': - /* previous model */ - bp->next_model = (bp->next_model + (int)models - 1) % (int)models; - start_morph(bp->next_model, 0); - - /* Reset bp->last_morph time */ - gettime(&bp->last_morph); - break; - case '+': - angvel += DEF_ANGVEL; - break; - case '-': - if (angvel > DEF_ANGVEL) - angvel -= DEF_ANGVEL; - break; - case 'i': - if (interactive) { - /* Reset last_iteration and last_morph time */ - gettime(&bp->last_iteration); - gettime(&bp->last_morph); - } - interactive = 1 - interactive; - glutPostRedisplay(); - break; - case 'w': - wireframe = 1 - wireframe; - if (wireframe) - glDisable(GL_LIGHTING); - else - glEnable(GL_LIGHTING); - glutPostRedisplay(); - break; - case 'a': - transparent = 1 - transparent; - if (transparent) { - glEnable(GL_BLEND); - } else { - glDisable(GL_BLEND); - } - break; - case 'p': - if (bp->paused) { - /* unpausing, reset last_iteration and last_morph time */ - gettime(&bp->last_iteration); - gettime(&bp->last_morph); - } - bp->paused = 1 - bp->paused; - break; - case 'd': - /* dump the current model so we can add it! */ - printf("# %s\nnoname:\t", model[bp->next_model].name); - { - int i; - - for (i = 0; i < NODE_COUNT; i++) { - if (bp->node[i] == ZERO) - printf("Z"); - else if (bp->node[i] == LEFT) - printf("L"); - else if (bp->node[i] == PIN) - printf("P"); - else if (bp->node[i] == RIGHT) - printf("R"); - /* - else - printf("%f", node[i].curAngle); - */ - if (i < NODE_COUNT - 1) - printf(" "); - } - } - printf("\n"); - break; - case 'f': - bp->fullscreen = 1 - bp->fullscreen; - if (bp->fullscreen) { - bp->old_width = bp->width; - bp->old_height = bp->height; - glutFullScreen(); - } else { - glutReshapeWindow(bp->old_width, bp->old_height); - glutPositionWindow(50,50); - } - break; - case 't': - titles = 1 - titles; - if (interactive || bp->paused) - glutPostRedisplay(); - break; - case 'c': - altcolour = 1 - altcolour; - break; - case 'z': - zoom += 1.0; - glsnake_reshape(bp->width, bp->height); - break; - case 'Z': - zoom -= 1.0; - glsnake_reshape(bp->width, bp->height); - break; - default: - break; - } -} - -static void ui_special(int key, int x__attribute__((__unused__)), int y __attribute__((__unused__))) -{ - float *destAngle = &(model[bp->next_model].node[bp->selected]); - int unknown_key = 0; - - if (interactive) { - switch (key) { - case GLUT_KEY_UP: - bp->selected = (bp->selected + (NODE_COUNT - 2)) % (NODE_COUNT - 1); - break; - case GLUT_KEY_DOWN: - bp->selected = (bp->selected + 1) % (NODE_COUNT - 1); - break; - case GLUT_KEY_LEFT: - *destAngle = fmod(*destAngle+(LEFT), 360); - bp->morphing = bp->new_morph = 1; - break; - case GLUT_KEY_RIGHT: - *destAngle = fmod(*destAngle+(RIGHT), 360); - bp->morphing = bp->new_morph = 1; - break; - case GLUT_KEY_HOME: - start_morph(STRAIGHT_MODEL, 0); - break; - default: - unknown_key = 1; - break; - } - } - calc_snake_metrics(); - - if (!unknown_key) - glutPostRedisplay(); -} - -static void ui_mouse(int button, int state, int x, int y) -{ - if (button==0) { - switch (state) { - case GLUT_DOWN: - dragging = 1; - mouse_start[0] = M_SQRT1_2 * - (x - (bp->width / 2.0)) / (bp->width / 2.0); - mouse_start[1] = M_SQRT1_2 * - ((bp->height / 2.0) - y) / (bp->height / 2.0); - mouse_start[2] = sqrt((double)(1-(mouse_start[0]*mouse_start[0]+mouse_start[1]*mouse_start[1]))); - break; - case GLUT_UP: - dragging = 0; - oldquat[0] = cumquat[0]; - oldquat[1] = cumquat[1]; - oldquat[2] = cumquat[2]; - oldquat[3] = cumquat[3]; - break; - default: - break; - } - } - glutPostRedisplay(); -} - -static void ui_motion(int x, int y) -{ - double norm; - float q[4]; - - if (dragging) { - /* construct the motion end vector from the x,y position on the - * window */ - mouse_end[0] = M_SQRT1_2 * (x - (bp->width/ 2.0)) / (bp->width / 2.0); - mouse_end[1] = M_SQRT1_2 * ((bp->height / 2.0) - y) / (bp->height / 2.0); - /* calculate the normal of the vector... */ - norm = mouse_end[0] * mouse_end[0] + mouse_end[1] * mouse_end[1]; - /* check if norm is outside the sphere and wraparound if necessary */ - if (norm > 1.0) { - mouse_end[0] = -mouse_end[0]; - mouse_end[1] = -mouse_end[1]; - mouse_end[2] = sqrt(norm - 1); - } else { - /* the z value comes from projecting onto an elliptical spheroid */ - mouse_end[2] = sqrt(1 - norm); - } - - /* now here, build a quaternion from mouse_start and mouse_end */ - q[0] = mouse_start[1] * mouse_end[2] - mouse_start[2] * mouse_end[1]; - q[1] = mouse_start[2] * mouse_end[0] - mouse_start[0] * mouse_end[2]; - q[2] = mouse_start[0] * mouse_end[1] - mouse_start[1] * mouse_end[0]; - q[3] = mouse_start[0] * mouse_end[0] + mouse_start[1] * mouse_end[1] + mouse_start[2] * mouse_end[2]; - - /* new rotation is the product of the new one and the old one */ - cumquat[0] = q[3] * oldquat[0] + q[0] * oldquat[3] + - q[1] * oldquat[2] - q[2] * oldquat[1]; - cumquat[1] = q[3] * oldquat[1] + q[1] * oldquat[3] + - q[2] * oldquat[0] - q[0] * oldquat[2]; - cumquat[2] = q[3] * oldquat[2] + q[2] * oldquat[3] + - q[0] * oldquat[1] - q[1] * oldquat[0]; - cumquat[3] = q[3] * oldquat[3] - q[0] * oldquat[0] - - q[1] * oldquat[1] - q[2] * oldquat[2]; - - calc_rotation(); - } - glutPostRedisplay(); -} - -static void ui_init(int * argc, char ** argv) -{ - glutInit(argc, argv); - glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); - glutInitWindowSize(bp->width, bp->height); - bp->window = glutCreateWindow("glsnake"); - - glutDisplayFunc(glsnake_display); - glutReshapeFunc(glsnake_reshape); - glutIdleFunc(glsnake_idle); - glutKeyboardFunc(ui_keyboard); - glutSpecialFunc(ui_special); - glutMouseFunc(ui_mouse); - glutMotionFunc(ui_motion); - - yangvel = DEF_YANGVEL; - zangvel = DEF_ZANGVEL; - explode = DEF_EXPLODE; - angvel = DEF_ANGVEL; - statictime = DEF_STATICTIME; - altcolour = DEF_ALTCOLOUR; - titles = DEF_TITLES; - interactive = DEF_INTERACTIVE; - zoom = DEF_ZOOM; - wireframe = DEF_WIREFRAME; - transparent = DEF_TRANSPARENT; -} -#endif /* HAVE_GLUT */ - -XSCREENSAVER_MODULE ("GLSnake", glsnake) |
