summaryrefslogtreecommitdiffstats
path: root/hacks/glx/maze3d.c
diff options
context:
space:
mode:
authorSimon Rettberg2024-09-06 14:42:37 +0200
committerSimon Rettberg2024-09-06 14:42:37 +0200
commitbadef32037f52f79abc1f1440b786cd71afdf270 (patch)
tree412b792d4cab4a7a110db82fcf74fe8a1ac55ec1 /hacks/glx/maze3d.c
parentDelete pre-6.00 files (diff)
downloadxscreensaver-master.tar.gz
xscreensaver-master.tar.xz
xscreensaver-master.zip
Diffstat (limited to 'hacks/glx/maze3d.c')
-rwxr-xr-xhacks/glx/maze3d.c1954
1 files changed, 0 insertions, 1954 deletions
diff --git a/hacks/glx/maze3d.c b/hacks/glx/maze3d.c
deleted file mode 100755
index d3d34fb..0000000
--- a/hacks/glx/maze3d.c
+++ /dev/null
@@ -1,1954 +0,0 @@
-/* -*- Mode: C; tab-width: 4 -*- */
-/* maze3d --- A recreation of the old 3D maze screensaver from Windows 95.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose and without fee is hereby granted,
- * provided that the above copyright notice appear in all copies and that
- * both that copyright notice and this permission notice appear in
- * supporting documentation.
- *
- * This file is provided AS IS with no warranties of any kind. The author
- * shall have no liability with respect to the infringement of copyrights,
- * trade secrets or any patents by this file or any part thereof. In no
- * event will the author be liable for any lost revenue or profits or
- * other special, indirect and consequential damages.
- *
- * Revision History:
- *
- * 03-Apr-2018: Released initial version of "3D Maze"
- * (sudoer@riseup.net)
- */
-
-#undef USE_FLOATING_IMAGES
-#undef USE_FRACTAL_IMAGES
-
-#ifdef STANDALONE
-#define DEFAULTS "*delay: 20000 \n" \
- "*showFPS: False \n" \
-
-#define release_maze 0
-# include "xlockmore.h" /* from the xscreensaver distribution */
-#else /* !STANDALONE */
-# include "xlock.h" /* from the xlockmore distribution */
-#endif /* !STANDALONE */
-#include <math.h>
-
-#ifdef USE_GL /* whole file */
-
-#define DEF_ANGULAR_CONVERSION_FACTOR 90
-#define DEF_SPEED "1.0"
-#define DEF_NUM_ROWS "12"
-#define DEF_NUM_COLUMNS "12"
-#define DEF_NUM_RATS "1"
-#define DEF_NUM_INVERTERS "10"
-#define DEF_SHOW_OVERLAY "False"
-#define DEF_DROP_ACID "False"
-
-#include "../images/gen/brick1_png.h"
-#include "../images/gen/brick2_png.h"
-#include "../images/gen/wood2_png.h"
-#include "../images/gen/start_png.h"
-#include "../images/gen/bob_png.h"
-#include "../images/gen/logo-32_png.h"
-
-#ifdef USE_FLOATING_IMAGES
-# include "../images/gen/opengltxt_png.h"
-# include "../images/gen/openglbook_png.h"
-#endif
-#ifdef USE_FRACTAL_IMAGES
-# include "../images/gen/fractal1_png.h"
-# include "../images/gen/fractal2_png.h"
-# include "../images/gen/fractal3_png.h"
-# include "../images/gen/fractal4_png.h"
-#endif
-
-#include "ximage-loader.h"
-
-static int dropAcid, dropAcidWalls, dropAcidCeiling, dropAcidFloor, numInverters, numRats;
-#ifdef USE_FLOATING_IMAGES
-static int numGl3dTexts, numGlRedbooks;
-#endif
-static int shouldDrawOverlay, numRows, numColumns;
-static char *wallTexture, *floorTexture, *ceilingTexture;
-static GLfloat speed;
-
-static XrmOptionDescRec opts[] = {
- {"-drop-acid", ".maze3d.dropAcid", XrmoptionNoArg, "true"},
- {"-drop-acid-walls", ".maze3d.dropAcidWalls", XrmoptionNoArg, "true"},
- {"-drop-acid-floor", ".maze3d.dropAcidFloor", XrmoptionNoArg, "true"},
- {"-drop-acid-ceiling", ".maze3d.dropAcidCeiling", XrmoptionNoArg, "true"},
- {"-wall-texture", ".maze3d.wallTexture", XrmoptionSepArg, 0},
- {"-floor-texture", ".maze3d.floorTexture", XrmoptionSepArg, 0},
- {"-ceiling-texture", ".maze3d.ceilingTexture", XrmoptionSepArg, 0},
- {"-rows", ".maze3d.numRows", XrmoptionSepArg, 0},
- {"-columns", ".maze3d.numColumns", XrmoptionSepArg, 0},
- {"-inverters", ".maze3d.numInverters", XrmoptionSepArg, 0},
- {"-rats", ".maze3d.numRats", XrmoptionSepArg, 0},
-# ifdef USE_FLOATING_IMAGES
- {"-gl-3d-texts", ".maze3d.numGl3dTexts", XrmoptionSepArg, 0},
- {"-gl-redbooks", ".maze3d.numGlRedbooks", XrmoptionSepArg, 0},
-# endif
- {"-overlay", ".maze3d.showOverlay", XrmoptionNoArg, "true"},
- {"-speed", ".maze3d.speed", XrmoptionSepArg, 0},
-};
-
-static argtype vars[] = {
- {&dropAcid, "dropAcid", "Drop Acid", DEF_DROP_ACID, t_Bool},
- {&dropAcidWalls, "dropAcidWalls", "Drop Acid Walls", "False", t_Bool},
- {&dropAcidFloor, "dropAcidFloor", "Drop Acid Floor", "False", t_Bool},
- {&dropAcidCeiling, "dropAcidCeiling", "Drop Acid Ceiling", "False", t_Bool},
- {&wallTexture, "wallTexture", "Wall Texture", "brick-wall", t_String},
- {&floorTexture, "floorTexture", "Floor Texture", "wood-floor", t_String},
- {&ceilingTexture, "ceilingTexture", "Ceiling Texture", "ceiling-tiles",
- t_String},
- {&numRows, "numRows", "Number of Rows", DEF_NUM_ROWS, t_Int},
- {&numColumns, "numColumns", "Number of Columns", DEF_NUM_COLUMNS, t_Int},
- {&numInverters, "numInverters", "Number of Inverters", DEF_NUM_INVERTERS, t_Int},
- {&numRats, "numRats", "Number of Rats", DEF_NUM_RATS, t_Int},
-# ifdef USE_FLOATING_IMAGES
- {&numGl3dTexts, "numGl3dTexts", "Number of GL 3D Texts", "3", t_Int},
- {&numGlRedbooks, "numGlRedbooks", "Number of GL Redbooks", "3", t_Int},
-# endif
- {&shouldDrawOverlay, "showOverlay", "Show Overlay", DEF_SHOW_OVERLAY, t_Bool},
- {&speed, "speed", "speed", DEF_SPEED, t_Float},
-};
-
-ENTRYPOINT ModeSpecOpt maze_opts = {countof(opts), opts, countof(vars), vars, NULL};
-
-enum cellTypes
-{
- WALL, CELL_UNVISITED, CELL, START, FINISH, GL_3D_TEXT, INVERTER_TETRAHEDRON,
- INVERTER_OCTAHEDRON, INVERTER_DODECAHEDRON, INVERTER_ICOSAHEDRON,
- WALL_GL_REDBOOK
-};
-
-enum programStates
-{
- STARTING, WALKING, TURNING_LEFT, TURNING_RIGHT, TURNING_AROUND, INVERTING,
- FINISHING
-};
-
-enum overlayLists
-{
- ARROW = 15, SQUARE, STAR, TRIANGLE
-};
-
-enum directions
-{
- NORTH = 0, EAST = 90, SOUTH = 180, WEST = 270
-};
-
-typedef struct
-{
- unsigned row, column;
-} Tuple;
-
-typedef struct
-{
- GLfloat x, z;
-} Tuplef;
-
-typedef struct
-{
- GLfloat red, green, blue;
-} Color;
-
-typedef struct
-{
- Tuplef position;
- GLfloat rotation, desiredRotation, inversion, remainingDistanceToTravel;
- unsigned char state, isCamera;
-} Rat;
-
-
-/* structure for holding the maze data */
-typedef struct
-{
- GLXContext *glx_context;
-
- unsigned char **mazeGrid;
- Tuple *wallList;
- unsigned wallListSize;
- Tuple startPosition, finishPosition, *inverterPosition,
- *gl3dTextPosition;
- GLuint wallTexture, floorTexture, ceilingTexture, startTexture,
- finishTexture, ratTexture;
- Rat camera;
- Rat *rats;
-# ifdef USE_FLOATING_IMAGES
- GLuint gl3dTextTexture, glTextbookTexture;
-# endif
-# ifdef USE_FRACTAL_IMAGES
- GLuint fractal1Texture, fractal2Texture, fractal3Texture, fractal4Texture;
-# endif
- Color acidColor;
- float acidHue;
- GLfloat wallHeight, inverterRotation;
- Bool button_down_p;
- int numRows, numColumns, numGlRedbooks;
- GLuint dlists[30]; /* ARROW etc index into this */
-
-} maze_configuration;
-
-static maze_configuration *mazes = NULL;
-
-static void newMaze(maze_configuration* maze);
-static void constructLists(ModeInfo *);
-static void initializeGrid(maze_configuration* maze);
-static float roundToNearestHalf(float num);
-static unsigned isOdd(unsigned num);
-static unsigned isEven(unsigned num);
-static void buildMaze(maze_configuration* maze);
-static void addWallsToList(Tuple cell, maze_configuration* maze);
-static unsigned char isRemovableWall(Tuple coordinates,
- maze_configuration* maze);
-static void addCells(Tuple cellToAdd, Tuple currentWall,
- maze_configuration* maze);
-static void removeWallFromList(unsigned index, maze_configuration* maze);
-static void placeMiscObjects(maze_configuration* maze);
-static Tuple placeObject(maze_configuration* maze, unsigned char type);
-static void shiftAcidColor(maze_configuration* maze);
-static void refreshRemainingDistanceToTravel(ModeInfo * mi);
-static void step(Rat* rat, maze_configuration* maze);
-static void walk(Rat* rat, char axis, int sign, maze_configuration* maze);
-static void turn(Rat* rat, maze_configuration* maze);
-static void turnAround(Rat* rat, maze_configuration* maze);
-static void invert(maze_configuration* maze);
-static void changeState(Rat* rat, maze_configuration* maze);
-static void updateInverterRotation(maze_configuration* maze);
-static void drawInverter(maze_configuration* maze, Tuple coordinates);
-static void drawWalls(ModeInfo * mi);
-static void drawWall(Tuple startCoordinates, Tuple endCoordinates,
- maze_configuration* maze);
-static void drawCeiling(ModeInfo * mi);
-static void drawFloor(ModeInfo * mi);
-static void drawPane(ModeInfo *, GLuint texture, Tuple position);
-static void drawRat(Tuplef position, maze_configuration* maze);
-static void drawOverlay(ModeInfo *);
-
-/* Set up and enable texturing on our object */
-static void
-setup_png_texture (ModeInfo *mi, const unsigned char *png_data,
- unsigned long data_size)
-{
- XImage *image = image_data_to_ximage (MI_DISPLAY (mi), MI_VISUAL (mi),
- png_data, data_size);
- char buf[1024];
- clear_gl_error();
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- /* iOS invalid enum:
- glPixelStorei(GL_UNPACK_ROW_LENGTH, image->width);
- */
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
- image->width, image->height, 0,
- GL_RGBA,
- /* GL_UNSIGNED_BYTE, */
- GL_UNSIGNED_INT_8_8_8_8_REV,
- image->data);
- sprintf (buf, "builtin texture (%dx%d)", image->width, image->height);
- check_gl_error(buf);
-}
-
-
-static Bool
-setup_file_texture (ModeInfo *mi, char *filename)
-{
- Display *dpy = mi->dpy;
- Visual *visual = mi->xgwa.visual;
- char buf[1024];
-
- XImage *image = file_to_ximage (dpy, visual, filename);
- if (!image) return False;
-
- clear_gl_error();
- glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, image->width);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
- image->width, image->height, 0,
- GL_RGBA,
- GL_UNSIGNED_BYTE, image->data);
- sprintf (buf, "texture: %.100s (%dx%d)",
- filename, image->width, image->height);
- check_gl_error(buf);
- return True;
-}
-
-static void
-setup_textures(ModeInfo * mi)
-{
- maze_configuration *maze = &mazes[MI_SCREEN(mi)];
- GLint mag = GL_NEAREST; /* GL_LINEAR */
-
- glGenTextures(1, &maze->finishTexture);
- glBindTexture(GL_TEXTURE_2D, maze->finishTexture);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mag);
- setup_png_texture(mi, logo_32_png, sizeof(logo_32_png));
-
- glGenTextures(1, &maze->ratTexture);
- glBindTexture(GL_TEXTURE_2D, maze->ratTexture);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mag);
- setup_png_texture(mi, bob_png, sizeof(bob_png));
-
-# ifdef USE_FLOATING_IMAGES
- glGenTextures(1, &maze->glTextbookTexture);
- glBindTexture(GL_TEXTURE_2D, maze->glTextbookTexture);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mag);
- setup_png_texture(mi, openglbook_png, sizeof(openglbook_png));
-
- glGenTextures(1, &maze->gl3dTextTexture);
- glBindTexture(GL_TEXTURE_2D, maze->gl3dTextTexture);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mag);
- setup_png_texture(mi, opengltxt_png, sizeof(opengltxt_png));
-# endif
-
-# ifdef USE_FRACTAL_IMAGES
- glGenTextures(1, &maze->fractal1Texture);
- glBindTexture(GL_TEXTURE_2D, maze->fractal1Texture);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mag);
- setup_png_texture(mi, fractal1_png, sizeof(fractal1_png));
-
- glGenTextures(1, &maze->fractal2Texture);
- glBindTexture(GL_TEXTURE_2D, maze->fractal2Texture);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mag);
- setup_png_texture(mi, fractal2_png, sizeof(fractal2_png));
-
- glGenTextures(1, &maze->fractal3Texture);
- glBindTexture(GL_TEXTURE_2D, maze->fractal3Texture);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mag);
- setup_png_texture(mi, fractal3_png, sizeof(fractal3_png));
-
- glGenTextures(1, &maze->fractal4Texture);
- glBindTexture(GL_TEXTURE_2D, maze->fractal4Texture);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mag);
- setup_png_texture(mi, fractal4_png, sizeof(fractal4_png));
-# endif
-
- glGenTextures(1, &maze->startTexture);
- glBindTexture(GL_TEXTURE_2D, maze->startTexture);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mag);
- setup_png_texture(mi, start_png, sizeof(start_png));
-
- glGenTextures(1, &maze->ceilingTexture);
- glBindTexture(GL_TEXTURE_2D, maze->ceilingTexture);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mag);
- if (!ceilingTexture || !*ceilingTexture
- || !strcmp(ceilingTexture, "ceiling-tiles")) {
- DEFAULT_CEILING_TEXTURE:
- setup_png_texture(mi, brick2_png, sizeof(brick2_png));
- } else if (!strcmp(ceilingTexture, "brick-wall")) {
- setup_png_texture(mi, brick1_png, sizeof(brick1_png));
- } else if (!strcmp(ceilingTexture, "wood-floor")) {
- setup_png_texture(mi, wood2_png, sizeof(wood2_png));
-# ifdef USE_FRACTAL_IMAGES
- } else if (!strcmp(ceilingTexture, "fractal-1")) {
- setup_png_texture(mi, fractal1_png, sizeof(fractal1_png));
- dropAcidCeiling = 1;
- } else if (!strcmp(ceilingTexture, "fractal-2")) {
- setup_png_texture(mi, fractal2_png, sizeof(fractal2_png));
- dropAcidCeiling = 1;
- } else if (!strcmp(ceilingTexture, "fractal-3")) {
- setup_png_texture(mi, fractal3_png, sizeof(fractal3_png));
- dropAcidCeiling = 1;
- } else if (!strcmp(ceilingTexture, "fractal-4")) {
- setup_png_texture(mi, fractal4_png, sizeof(fractal4_png));
- dropAcidCeiling = 1;
-# endif
- } else {
- if (!setup_file_texture(mi, ceilingTexture))
- goto DEFAULT_CEILING_TEXTURE;
- }
-
- glGenTextures(1, &maze->floorTexture);
- glBindTexture(GL_TEXTURE_2D, maze->floorTexture);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mag);
- if (!floorTexture || !*floorTexture
- || !strcmp(floorTexture, "wood-floor")) {
- DEFAULT_FLOOR_TEXTURE:
- setup_png_texture(mi, wood2_png, sizeof(wood2_png));
- } else if (!strcmp(floorTexture, "ceiling-tiles")) {
- setup_png_texture(mi, brick2_png, sizeof(brick2_png));
- } else if (!strcmp(floorTexture, "brick-wall")) {
- setup_png_texture(mi, brick1_png, sizeof(brick1_png));
-# ifdef USE_FRACTAL_IMAGES
- } else if (!strcmp(floorTexture, "fractal-1")) {
- setup_png_texture(mi, fractal1_png, sizeof(fractal1_png));
- dropAcidFloor = 1;
- } else if (!strcmp(floorTexture, "fractal-2")) {
- setup_png_texture(mi, fractal2_png, sizeof(fractal2_png));
- dropAcidFloor = 1;
- } else if (!strcmp(floorTexture, "fractal-3")) {
- setup_png_texture(mi, fractal3_png, sizeof(fractal3_png));
- dropAcidFloor = 1;
- } else if (!strcmp(floorTexture, "fractal-4")) {
- setup_png_texture(mi, fractal4_png, sizeof(fractal4_png));
- dropAcidFloor = 1;
-# endif
- } else {
- if (!setup_file_texture(mi, floorTexture))
- goto DEFAULT_FLOOR_TEXTURE;
- }
-
- glGenTextures(1, &maze->wallTexture);
- glBindTexture(GL_TEXTURE_2D, maze->wallTexture);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mag);
- if (!wallTexture || !*wallTexture || !strcmp(wallTexture, "brick-wall")) {
- DEFAULT_WALL_TEXTURE:
- setup_png_texture(mi, brick1_png, sizeof(brick1_png));
- } else if (!strcmp(wallTexture, "ceiling-tiles")) {
- setup_png_texture(mi, brick2_png, sizeof(brick2_png));
- } else if (!strcmp(wallTexture, "wood-floor")) {
- setup_png_texture(mi, wood2_png, sizeof(wood2_png));
-# ifdef USE_FRACTAL_IMAGES
- } else if (!strcmp(wallTexture, "fractal-1")) {
- setup_png_texture(mi, fractal1_png, sizeof(fractal1_png));
- dropAcidWalls = 1;
- } else if (!strcmp(wallTexture, "fractal-2")) {
- setup_png_texture(mi, fractal2_png, sizeof(fractal2_png));
- dropAcidWalls = 1;
- } else if (!strcmp(wallTexture, "fractal-3")) {
- setup_png_texture(mi, fractal3_png, sizeof(fractal3_png));
- dropAcidWalls = 1;
- } else if (!strcmp(wallTexture, "fractal-4")) {
- setup_png_texture(mi, fractal4_png, sizeof(fractal4_png));
- dropAcidWalls = 1;
-# endif
- } else {
- if (!setup_file_texture(mi, wallTexture))
- goto DEFAULT_WALL_TEXTURE;
- }
-}
-
-static void
-initializeGrid(maze_configuration* maze)
-{
- unsigned i, j;
-
- for (i = 0; i < maze->numRows; i++) {
- for (j = 0; j < maze->numColumns; j++) {
- if (isOdd(i) && isOdd(j))
- maze->mazeGrid[i][j] = CELL_UNVISITED;
- else
- maze->mazeGrid[i][j] = WALL;
- }
- }
-}
-
-static float
-roundToNearestHalf(float num)
-{
- return roundf(2.0 * num) / 2.0;
-}
-
-static unsigned
-isOdd(unsigned num)
-{
- return num % 2;
-}
-
-static unsigned
-isEven(unsigned num)
-{
- return !isOdd(num);
-}
-
-/*This is the randomized Prim's algorithm.*/
-static void
-buildMaze(maze_configuration* maze)
-{
- Tuple cellToAdd, firstCell = {1, 1};
- maze->mazeGrid[1][1] = CELL;
-
- addWallsToList(firstCell, maze);
-
- while (maze->wallListSize > 0) {
- unsigned randomNum = random() % maze->wallListSize;
- Tuple currentWall = maze->wallList[randomNum];
-
- if (isEven(currentWall.row)) {
- if (maze->mazeGrid[currentWall.row - 1][currentWall.column]
- == CELL
- && maze->mazeGrid[currentWall.row + 1][currentWall.column]
- == CELL_UNVISITED
- ) {
- cellToAdd.row = currentWall.row + 1;
- cellToAdd.column = currentWall.column;
- addCells(cellToAdd, currentWall, maze);
- }
- else if (maze->mazeGrid[currentWall.row + 1][currentWall.column]
- == CELL
- && maze->mazeGrid[currentWall.row - 1][currentWall.column]
- == CELL_UNVISITED
- ) {
- cellToAdd.row = currentWall.row - 1;
- cellToAdd.column = currentWall.column;
- addCells(cellToAdd, currentWall, maze);
- }
- } else {
- if (maze->mazeGrid[currentWall.row][currentWall.column - 1]
- == CELL
- && maze->mazeGrid[currentWall.row][currentWall.column + 1]
- == CELL_UNVISITED
- ) {
- cellToAdd.row = currentWall.row;
- cellToAdd.column = currentWall.column + 1;
- addCells(cellToAdd, currentWall, maze);
- }
- else if (maze->mazeGrid[currentWall.row][currentWall.column + 1]
- == CELL
- && maze->mazeGrid[currentWall.row][currentWall.column - 1]
- == CELL_UNVISITED
- ) {
- cellToAdd.row = currentWall.row;
- cellToAdd.column = currentWall.column - 1;
- addCells(cellToAdd, currentWall, maze);
- }
- }
-
- removeWallFromList(randomNum, maze);
- }
-}
-
-static void
-addWallsToList(Tuple cell, maze_configuration* maze)
-{
- unsigned i;
- Tuple walls[4];
- walls[0].row = cell.row - 1;
- walls[0].column = cell.column;
- walls[1].row = cell.row + 1;
- walls[1].column = cell.column;
- walls[2].row = cell.row;
- walls[2].column = cell.column - 1;
- walls[3].row = cell.row;
- walls[3].column = cell.column + 1;
-
- for (i = 0; i < 4; i++) {
- if (isRemovableWall(walls[i], maze)) {
- maze->wallList[maze->wallListSize] = walls[i];
- maze->wallListSize++;
- }
- }
-}
-
-static unsigned char
-isRemovableWall(Tuple coordinates, maze_configuration* maze)
-{
- if (maze->mazeGrid[coordinates.row][coordinates.column] == WALL
- && coordinates.row > 0
- && coordinates.row < maze->numRows - 1
- && coordinates.column > 0
- && coordinates.column < maze->numColumns - 1
- )
- return 1;
- else
- return 0;
-}
-
-static void
-addCells(Tuple cellToAdd, Tuple currentWall, maze_configuration* maze)
-{
- maze->mazeGrid[currentWall.row][currentWall.column] = CELL;
- maze->mazeGrid[cellToAdd.row][cellToAdd.column] = CELL;
- addWallsToList(cellToAdd, maze);
-}
-
-static void
-removeWallFromList(unsigned index, maze_configuration* maze)
-{
- unsigned i;
- for (i = index + 1; i < maze->wallListSize; i++)
- maze->wallList[i - 1] = maze->wallList[i];
-
- maze->wallListSize--;
-}
-
-static void
-placeMiscObjects(maze_configuration* maze)
-{
- Rat* rat;
- Tuple temp;
- unsigned char object;
- unsigned numSurroundingWalls = 3;
- unsigned i;
-
- while (numSurroundingWalls >= 3) {
- numSurroundingWalls = 0;
- maze->startPosition = placeObject(maze, CELL);
-
- object = maze->mazeGrid[maze->startPosition.row]
- [maze->startPosition.column + 1];
- if (object == WALL || object == WALL_GL_REDBOOK)
- numSurroundingWalls++;
- object = maze->mazeGrid[maze->startPosition.row - 1]
- [maze->startPosition.column];
- if (object == WALL || object == WALL_GL_REDBOOK)
- numSurroundingWalls++;
- object = maze->mazeGrid[maze->startPosition.row]
- [maze->startPosition.column - 1];
- if (object == WALL || object == WALL_GL_REDBOOK)
- numSurroundingWalls++;
- object = maze->mazeGrid[maze->startPosition.row + 1]
- [maze->startPosition.column];
- if (object == WALL || object == WALL_GL_REDBOOK)
- numSurroundingWalls++;
- }
- maze->mazeGrid[maze->startPosition.row][maze->startPosition.column] = START;
-
- if (maze->mazeGrid[maze->startPosition.row][maze->startPosition.column + 1]
- != WALL && maze->mazeGrid[maze->startPosition.row]
- [maze->startPosition.column + 1] != WALL_GL_REDBOOK) {
- maze->camera.position.x = (maze->startPosition.column + 1) / 2.0;
- maze->camera.position.z = maze->startPosition.row / 2.0;
- maze->camera.rotation = WEST;
- }
- else if (maze->mazeGrid[maze->startPosition.row - 1]
- [maze->startPosition.column] != WALL
- && maze->mazeGrid[maze->startPosition.row - 1]
- [maze->startPosition.column] != WALL_GL_REDBOOK) {
- maze->camera.position.x = maze->startPosition.column / 2.0;
- maze->camera.position.z = (maze->startPosition.row - 1) / 2.0;
- maze->camera.rotation = SOUTH;
- }
- else if (maze->mazeGrid[maze->startPosition.row]
- [maze->startPosition.column - 1] != WALL
- && maze->mazeGrid[maze->startPosition.row]
- [maze->startPosition.column - 1] != WALL_GL_REDBOOK) {
- maze->camera.position.x = (maze->startPosition.column - 1) / 2.0;
- maze->camera.position.z = maze->startPosition.row / 2.0;
- maze->camera.rotation = EAST;
- }
- else {
- maze->camera.position.x = maze->startPosition.column / 2.0;
- maze->camera.position.z = (maze->startPosition.row + 1) / 2.0;
- maze->camera.rotation = NORTH;
- }
-
- maze->finishPosition = placeObject(maze, FINISH);
-
- for (i = 0; i < numInverters; i++)
- maze->inverterPosition[i] =
- placeObject(maze, random() % 4 + INVERTER_TETRAHEDRON);
-
- temp.row = 0;
- temp.column = 0;
-
-# ifdef USE_FLOATING_IMAGES
- for (i = 0; i < numGl3dTexts; i++)
- maze->gl3dTextPosition[i] =
- placeObject(maze, GL_3D_TEXT);
-# endif
-
- for (i = 0; i < numRats; i++) {
- rat = &(maze->rats[i]);
- temp = placeObject(maze, CELL);
- rat->position.x = temp.column / 2.0;
- rat->position.z = temp.row / 2.0;
- rat->state = WALKING;
-
- if (temp.row == 0 && temp.column == 0) {
- continue;
- }
-
- if (maze->mazeGrid[(int)(rat->position.z * 2)]
- [(int)(rat->position.x * 2) + 1]
- != WALL && maze->mazeGrid[(int)(rat->position.z * 2)]
- [(int)(rat->position.x * 2) + 1] != WALL_GL_REDBOOK)
- rat->rotation = EAST;
- else if (maze->mazeGrid[(int)(rat->position.z * 2) - 1]
- [(int)(rat->position.x * 2)]
- != WALL && maze->mazeGrid[(int)(rat->position.z * 2) - 1]
- [(int)(rat->position.x * 2)] != WALL_GL_REDBOOK)
- rat->rotation = NORTH;
- else if (maze->mazeGrid[(int)(rat->position.z * 2)]
- [(int)(rat->position.x * 2) - 1]
- != WALL && maze->mazeGrid[(int)(rat->position.z * 2)]
- [(int)(rat->position.x * 2) - 1] != WALL_GL_REDBOOK)
- rat->rotation = WEST;
- else
- rat->rotation = SOUTH;
- }
-
-# ifdef USE_FLOATING_IMAGES
- for (i = 0; i < numGlRedbooks; i++) {
- while (!(((isOdd(temp.row) && isEven(temp.column))
- || (isEven(temp.row) && isOdd(temp.column)))
- && maze->mazeGrid[temp.row][temp.column] == WALL)) {
- temp.row = random() % maze->numRows;
- temp.column = random() % maze->numColumns;
- }
-
- maze->mazeGrid[temp.row][temp.column] = WALL_GL_REDBOOK;
- }
-# endif
-}
-
-static Tuple
-placeObject(maze_configuration* maze, unsigned char type)
-{
- Tuple position = {0, 0};
-
- while (!(maze->mazeGrid[position.row][position.column] == CELL
- && isOdd(position.row) && isOdd(position.column))) {
- position.row = random() % maze->numRows;
- position.column = random() % maze->numColumns;
- }
-
- maze->mazeGrid[position.row][position.column] = type;
- return position;
-}
-
-ENTRYPOINT void
-reshape_maze (ModeInfo *mi, int width, int height)
-{
- glViewport(0, 0, (GLint) width, (GLint) height);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-}
-
-
-ENTRYPOINT Bool
-maze_handle_event (ModeInfo *mi, XEvent *event)
-{
- maze_configuration *maze = &mazes[MI_SCREEN(mi)];
- if (event->xany.type == ButtonPress)
- {
- maze->button_down_p = True;
- return True;
- }
- else if (event->xany.type == ButtonRelease)
- {
- maze->button_down_p = False;
- return True;
- }
- return False;
-}
-
-ENTRYPOINT void
-init_maze (ModeInfo * mi)
-{
- unsigned i;
- maze_configuration *maze;
- GLfloat ambient[] = {0, 0, 0, 1},
- diffuse[] = {1, 1, 1, 1},
- position[] = {0, 2, 0, 0},
- mcolor[] = {1, 1, 1, 1};
-
- MI_INIT(mi, mazes);
- maze = &mazes[MI_SCREEN(mi)];
-
- maze->glx_context = init_GL(mi);
-
- reshape_maze(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
-
- for (i = 0; i < countof(maze->dlists); i++)
- maze->dlists[i] = glGenLists (1);
-
- maze->numRows = (numRows < 2 ? 5 : numRows * 2 + 1);
- maze->numColumns = (numColumns < 2 ? 5 : numColumns * 2 + 1);
-
- i = (maze->numRows / 2) * (maze->numColumns / 2) - 2;
- if (i < numInverters) {
- numInverters = i;
- i = 0;
- } else i -= numInverters;
-
- if (i < numRats) {
- numRats = i;
- i = 0;
- } else i -= numRats;
-# ifdef USE_FLOATING_IMAGES
- if (i < numGl3dTexts) {
- numGl3dTexts = i;
- i = 0;
- } else i -= numGl3dTexts;
-
- if (((maze->numRows - 1) + (maze->numColumns - 1)
- + ((maze->numRows / 2 - 1) * (maze->numColumns / 2 - 1))) < maze->numGlRedbooks)
- maze->numGlRedbooks = (maze->numRows - 1) + (maze->numColumns - 1)
- + ((maze->numRows / 2 - 1) * (maze->numColumns / 2 - 1));
-# endif
-
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_LIGHT0);
-
- glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
- glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
- glLightfv(GL_LIGHT0, GL_POSITION, position);
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mcolor);
-
- glShadeModel(GL_FLAT);
-
- maze->mazeGrid = calloc(maze->numRows, sizeof(unsigned char*));
- for (i = 0; i < maze->numRows; i++)
- maze->mazeGrid[i] = calloc(maze->numColumns, sizeof(unsigned char));
- maze->wallList = calloc(((maze->numColumns - 2) / 2) * ((maze->numRows - 2) / 2 + 1)
- + ((maze->numColumns - 2) / 2 + 1) * ((maze->numRows - 2) / 2), sizeof(Tuple));
- maze->inverterPosition = calloc(numInverters, sizeof(Tuple));
- maze->rats = calloc(numRats, sizeof(Rat));
-# ifdef USE_FLOATING_IMAGES
- maze->gl3dTextPosition = calloc(numGl3dTexts, sizeof(Tuple));
-#endif
-
- setup_textures(mi);
-
- newMaze(maze);
-
- constructLists(mi);
- refreshRemainingDistanceToTravel(mi);
-
- maze->camera.isCamera = 1;
- for (i = 0; i < numRats; i++)
- maze->rats[i].isCamera = 0;
-}
-
-static void
-newMaze(maze_configuration* maze)
-{
- maze->camera.state = STARTING;
- maze->camera.inversion = 0;
- maze->wallHeight = 0;
- maze->inverterRotation = 0;
- maze->acidHue = 0;
-
- initializeGrid(maze);
- buildMaze(maze);
- placeMiscObjects(maze);
-}
-
-static void
-constructLists(ModeInfo *mi)
-{
- maze_configuration *maze = &mazes[MI_SCREEN(mi)];
-
- glNewList(maze->dlists[ARROW], GL_COMPILE);
- glBegin(GL_POLYGON);
- glVertex2f(0, -0.25);
- glVertex2f(0.146946313, 0.202254249);
- glVertex2f(0, 0.125);
- glVertex2f(-0.146946313, 0.202254249);
- glEnd();
- glEndList();
-
- glNewList(maze->dlists[SQUARE], GL_COMPILE);
- glBegin(GL_QUADS);
- glVertex2f(-0.176776695, -0.176776695);
- glVertex2f(0.176776695, -0.176776695);
- glVertex2f(0.176776695, 0.176776695);
- glVertex2f(-0.176776695, 0.176776695);
- glEnd();
- glEndList();
-
- glNewList(maze->dlists[STAR], GL_COMPILE);
- glBegin(GL_TRIANGLE_FAN);
- glVertex2f(0, 0);
- glVertex2f(0, -0.25);
- glVertex2f(0.073473157, -0.101127124);
- glVertex2f(0.237764129, -0.077254249);
- glVertex2f(0.118882065, 0.038627124);
- glVertex2f(0.146946313, 0.202254249);
- glVertex2f(0, 0.125);
- glVertex2f(-0.146946313, 0.202254249);
- glVertex2f(-0.118882065, 0.038627124);
- glVertex2f(-0.237764129, -0.077254249);
- glVertex2f(-0.073473157, -0.101127124);
- glVertex2f(0, -0.25);
- glEnd();
- glEndList();
-
- glNewList(maze->dlists[TRIANGLE], GL_COMPILE);
- glBegin(GL_POLYGON);
- glVertex2f(0, -0.25);
- glVertex2f(0.216506351, 0.125);
- glVertex2f(-0.216506351, 0.125);
- glEnd();
- glEndList();
-
- glNewList(maze->dlists[INVERTER_TETRAHEDRON], GL_COMPILE);
- glBegin(GL_TRIANGLES);
- glNormal3f(0.471404521, 0.816496581, 0.333333333);
- glVertex3f(0, 0, 0.25);
- glVertex3f(0.23570226, 0, -0.083333333);
- glVertex3f(-0.11785113, 0.204124145, -0.083333333);
-
- glNormal3f(-0.942809042, 0, 0.333333333);
- glVertex3f(0, 0, 0.25);
- glVertex3f(-0.11785113, 0.204124145, -0.083333333);
- glVertex3f(-0.11785113, -0.204124145, -0.083333333);
-
- glNormal3f(0.471404521, -0.816496581, 0.333333333);
- glVertex3f(0, 0, 0.25);
- glVertex3f(-0.11785113, -0.204124145, -0.083333333);
- glVertex3f(0.23570226, 0, -0.083333333);
-
- glNormal3f(0, 0, -1);
- glVertex3f(0.23570226, 0, -0.083333333);
- glVertex3f(-0.11785113, -0.204124145, -0.083333333);
- glVertex3f(-0.11785113, 0.204124145, -0.083333333);
- glEnd();
- glEndList();
-
- glNewList(maze->dlists[INVERTER_OCTAHEDRON], GL_COMPILE);
- glBegin(GL_TRIANGLES);
- glNormal3f(0.577350269, 0.577350269, 0.577350269);
- glVertex3f(0, 0, 0.25);
- glVertex3f(0.25, 0, 0);
- glVertex3f(0, 0.25, 0);
-
- glNormal3f(-0.577350269, 0.577350269, 0.577350269);
- glVertex3f(0, 0, 0.25);
- glVertex3f(0, 0.25, 0);
- glVertex3f(-0.25, 0, 0);
-
- glNormal3f(-0.577350269, -0.577350269, 0.577350269);
- glVertex3f(0, 0, 0.25);
- glVertex3f(-0.25, 0, 0);
- glVertex3f(0, -0.25, 0);
-
- glNormal3f(0.577350269, -0.577350269, 0.577350269);
- glVertex3f(0, 0, 0.25);
- glVertex3f(0, -0.25, 0);
- glVertex3f(0.25, 0, 0);
-
- glNormal3f(0.577350269, -0.577350269, -0.577350269);
- glVertex3f(0.25, 0, 0);
- glVertex3f(0, -0.25, 0);
- glVertex3f(0, 0, -0.25);
-
- glNormal3f(0.577350269, 0.577350269, -0.577350269);
- glVertex3f(0.25, 0, 0);
- glVertex3f(0, 0, -0.25);
- glVertex3f(0, 0.25, 0);
-
- glNormal3f(-0.577350269, 0.577350269, -0.577350269);
- glVertex3f(0, 0.25, 0);
- glVertex3f(0, 0, -0.25);
- glVertex3f(-0.25, 0, 0);
-
- glNormal3f(-0.577350269, -0.577350269, -0.577350269);
- glVertex3f(-0.25, 0, 0);
- glVertex3f(0, 0, -0.25);
- glVertex3f(0, -0.25, 0);
- glEnd();
- glEndList();
-
- glNewList(maze->dlists[INVERTER_DODECAHEDRON], GL_COMPILE);
- glBegin(GL_POLYGON);
- glNormal3f(0.000000000, 0.000000000, 1.000000000);
- glVertex3f(0.122780868, 0.089205522, 0.198663618);
- glVertex3f(-0.046898119, 0.144337567, 0.198663618);
- glVertex3f(-0.151765500, 0.000000000, 0.198663618);
- glVertex3f(-0.046898119, -0.144337567, 0.198663618);
- glVertex3f(0.122780868, -0.089205522, 0.198663618);
- glEnd();
-
- glBegin(GL_POLYGON);
- glNormal3f(0.894427191, 0.000000000, 0.447213595);
- glVertex3f(0.198663618, -0.144337567, 0.046898119);
- glVertex3f(0.245561737, 0.000000000, -0.046898119);
- glVertex3f(0.198663618, 0.144337567, 0.046898119);
- glVertex3f(0.122780868, 0.089205522, 0.198663618);
- glVertex3f(0.122780868, -0.089205522, 0.198663618);
- glEnd();
-
- glBegin(GL_POLYGON);
- glNormal3f(0.276393202, 0.850650808, 0.447213595);
- glVertex3f(0.198663618, 0.144337567, 0.046898119);
- glVertex3f(0.075882750, 0.233543090, -0.046898119);
- glVertex3f(-0.075882750, 0.233543090, 0.046898119);
- glVertex3f(-0.046898119, 0.144337567, 0.198663618);
- glVertex3f(0.122780868, 0.089205522, 0.198663618);
- glEnd();
-
- glBegin(GL_POLYGON);
- glNormal3f(-0.723606798, 0.525731112, 0.447213595);
- glVertex3f(-0.075882750, 0.233543090, 0.046898119);
- glVertex3f(-0.198663618, 0.144337567, -0.046898119);
- glVertex3f(-0.245561737, 0.000000000, 0.046898119);
- glVertex3f(-0.151765500, 0.000000000, 0.198663618);
- glVertex3f(-0.046898119, 0.144337567, 0.198663618);
- glEnd();
-
- glBegin(GL_POLYGON);
- glNormal3f(-0.723606798, -0.525731112, 0.447213595);
- glVertex3f(-0.245561737, 0.000000000, 0.046898119);
- glVertex3f(-0.198663618, -0.144337567, -0.046898119);
- glVertex3f(-0.075882750, -0.233543090, 0.046898119);
- glVertex3f(-0.046898119, -0.144337567, 0.198663618);
- glVertex3f(-0.151765500, 0.000000000, 0.198663618);
- glEnd();
-
- glBegin(GL_POLYGON);
- glNormal3f(0.276393202, -0.850650808, 0.447213595);
- glVertex3f(-0.075882750, -0.233543090, 0.046898119);
- glVertex3f(0.075882750, -0.233543090, -0.046898119);
- glVertex3f(0.198663618, -0.144337567, 0.046898119);
- glVertex3f(0.122780868, -0.089205522, 0.198663618);
- glVertex3f(-0.046898119, -0.144337567, 0.198663618);
- glEnd();
-
- glBegin(GL_POLYGON);
- glNormal3f(0.723606798, 0.525731112, -0.447213595);
- glVertex3f(0.245561737, 0.000000000, -0.046898119);
- glVertex3f(0.151765500, 0.000000000, -0.198663618);
- glVertex3f(0.046898119, 0.144337567, -0.198663618);
- glVertex3f(0.075882750, 0.233543090, -0.046898119);
- glVertex3f(0.198663618, 0.144337567, 0.046898119);
- glEnd();
-
- glBegin(GL_POLYGON);
- glNormal3f(0.723606798, -0.525731112, -0.447213595);
- glVertex3f(0.198663618, -0.144337567, 0.046898119);
- glVertex3f(0.075882750, -0.233543090, -0.046898119);
- glVertex3f(0.046898119, -0.144337567, -0.198663618);
- glVertex3f(0.151765500, 0.000000000, -0.198663618);
- glVertex3f(0.245561737, 0.000000000, -0.046898119);
- glEnd();
-
- glBegin(GL_POLYGON);
- glNormal3f(-0.276393202, 0.850650808, -0.447213595);
- glVertex3f(0.075882750, 0.233543090, -0.046898119);
- glVertex3f(0.046898119, 0.144337567, -0.198663618);
- glVertex3f(-0.122780868, 0.089205522, -0.198663618);
- glVertex3f(-0.198663618, 0.144337567, -0.046898119);
- glVertex3f(-0.075882750, 0.233543090, 0.046898119);
- glEnd();
-
- glBegin(GL_POLYGON);
- glNormal3f(-0.894427191, 0.000000000, -0.447213595);
- glVertex3f(-0.198663618, 0.144337567, -0.046898119);
- glVertex3f(-0.122780868, 0.089205522, -0.198663618);
- glVertex3f(-0.122780868, -0.089205522, -0.198663618);
- glVertex3f(-0.198663618, -0.144337567, -0.046898119);
- glVertex3f(-0.245561737, 0.000000000, 0.046898119);
- glEnd();
-
- glBegin(GL_POLYGON);
- glNormal3f(-0.276393202, -0.850650808, -0.447213595);
- glVertex3f(-0.198663618, -0.144337567, -0.046898119);
- glVertex3f(-0.122780868, -0.089205522, -0.198663618);
- glVertex3f(0.046898119, -0.144337567, -0.198663618);
- glVertex3f(0.075882750, -0.233543090, -0.046898119);
- glVertex3f(-0.075882750, -0.233543090, 0.046898119);
- glEnd();
-
- glBegin(GL_POLYGON);
- glNormal3f(0.000000000, 0.000000000, -1.000000000);
- glVertex3f(0.046898119, -0.144337567, -0.198663618);
- glVertex3f(-0.122780868, -0.089205522, -0.198663618);
- glVertex3f(-0.122780868, 0.089205522, -0.198663618);
- glVertex3f(0.046898119, 0.144337567, -0.198663618);
- glVertex3f(0.151765500, 0.000000000, -0.198663618);
- glEnd();
- glEndList();
-
- glNewList(maze->dlists[INVERTER_ICOSAHEDRON], GL_COMPILE);
- glBegin(GL_TRIANGLES);
- glNormal3f(0.491123473, 0.356822090, 0.794654473);
- glVertex3f(0.000000000, 0.000000000, 0.250000000);
- glVertex3f(0.223606798, 0.000000000, 0.111803399);
- glVertex3f(0.069098301, 0.212662702, 0.111803399);
-
- glNormal3f(-0.187592474, 0.577350269, 0.794654473);
- glVertex3f(0.000000000, 0.000000000, 0.250000000);
- glVertex3f(0.069098301, 0.212662702, 0.111803399);
- glVertex3f(-0.180901699, 0.131432778, 0.111803399);
-
- glNormal3f(-0.607061998, 0.000000000, 0.794654473);
- glVertex3f(0.000000000, 0.000000000, 0.250000000);
- glVertex3f(-0.180901699, 0.131432778, 0.111803399);
- glVertex3f(-0.180901699, -0.131432778, 0.111803399);
-
- glNormal3f(-0.187592474, -0.577350269, 0.794654473);
- glVertex3f(0.000000000, 0.000000000, 0.250000000);
- glVertex3f(-0.180901699, -0.131432778, 0.111803399);
- glVertex3f(0.069098301, -0.212662702, 0.111803399);
-
- glNormal3f(0.491123473, -0.356822090, 0.794654473);
- glVertex3f(0.000000000, 0.000000000, 0.250000000);
- glVertex3f(0.069098301, -0.212662702, 0.111803399);
- glVertex3f(0.223606798, 0.000000000, 0.111803399);
-
- glNormal3f(0.794654473, -0.577350269, 0.187592474);
- glVertex3f(0.223606798, 0.000000000, 0.111803399);
- glVertex3f(0.069098301, -0.212662702, 0.111803399);
- glVertex3f(0.180901699, -0.131432778, -0.111803399);
-
- glNormal3f(0.982246947, 0.000000000, -0.187592474);
- glVertex3f(0.223606798, 0.000000000, 0.111803399);
- glVertex3f(0.180901699, -0.131432778, -0.111803399);
- glVertex3f(0.180901699, 0.131432778, -0.111803399);
-
- glNormal3f(0.794654473, 0.577350269, 0.187592474);
- glVertex3f(0.223606798, 0.000000000, 0.111803399);
- glVertex3f(0.180901699, 0.131432778, -0.111803399);
- glVertex3f(0.069098301, 0.212662702, 0.111803399);
-
- glNormal3f(0.303530999, 0.934172359, -0.187592474);
- glVertex3f(0.069098301, 0.212662702, 0.111803399);
- glVertex3f(0.180901699, 0.131432778, -0.111803399);
- glVertex3f(-0.069098301, 0.212662702, -0.111803399);
-
- glNormal3f(-0.303530999, 0.934172359, 0.187592474);
- glVertex3f(0.069098301, 0.212662702, 0.111803399);
- glVertex3f(-0.069098301, 0.212662702, -0.111803399);
- glVertex3f(-0.180901699, 0.131432778, 0.111803399);
-
- glNormal3f(-0.794654473, 0.577350269, -0.187592474);
- glVertex3f(-0.180901699, 0.131432778, 0.111803399);
- glVertex3f(-0.069098301, 0.212662702, -0.111803399);
- glVertex3f(-0.223606798, 0.000000000, -0.111803399);
-
- glNormal3f(-0.982246947, 0.000000000, 0.187592474);
- glVertex3f(-0.180901699, 0.131432778, 0.111803399);
- glVertex3f(-0.223606798, 0.000000000, -0.111803399);
- glVertex3f(-0.180901699, -0.131432778, 0.111803399);
-
- glNormal3f(-0.794654473, -0.577350269, -0.187592474);
- glVertex3f(-0.180901699, -0.131432778, 0.111803399);
- glVertex3f(-0.223606798, 0.000000000, -0.111803399);
- glVertex3f(-0.069098301, -0.212662702, -0.111803399);
-
- glNormal3f(-0.303530999, -0.934172359, 0.187592474);
- glVertex3f(-0.180901699, -0.131432778, 0.111803399);
- glVertex3f(-0.069098301, -0.212662702, -0.111803399);
- glVertex3f(0.069098301, -0.212662702, 0.111803399);
-
- glNormal3f(0.303530999, -0.934172359, -0.187592474);
- glVertex3f(0.069098301, -0.212662702, 0.111803399);
- glVertex3f(-0.069098301, -0.212662702, -0.111803399);
- glVertex3f(0.180901699, -0.131432778, -0.111803399);
-
- glNormal3f(0.607061998, 0.000000000, -0.794654473);
- glVertex3f(0.180901699, 0.131432778, -0.111803399);
- glVertex3f(0.180901699, -0.131432778, -0.111803399);
- glVertex3f(0.000000000, 0.000000000, -0.250000000);
-
- glNormal3f(0.187592474, 0.577350269, -0.794654473);
- glVertex3f(0.180901699, 0.131432778, -0.111803399);
- glVertex3f(0.000000000, 0.000000000, -0.250000000);
- glVertex3f(-0.069098301, 0.212662702, -0.111803399);
-
- glNormal3f(0.187592474, -0.577350269, -0.794654473);
- glVertex3f(0.180901699, -0.131432778, -0.111803399);
- glVertex3f(-0.069098301, -0.212662702, -0.111803399);
- glVertex3f(0.000000000, 0.000000000, -0.250000000);
-
- glNormal3f(-0.491123473, 0.356822090, -0.794654473);
- glVertex3f(-0.069098301, 0.212662702, -0.111803399);
- glVertex3f(0.000000000, 0.000000000, -0.250000000);
- glVertex3f(-0.223606798, 0.000000000, -0.111803399);
-
- glNormal3f(-0.491123473, -0.356822090, -0.794654473);
- glVertex3f(-0.223606798, 0.000000000, -0.111803399);
- glVertex3f(0.000000000, 0.000000000, -0.250000000);
- glVertex3f(-0.069098301, -0.212662702, -0.111803399);
- glEnd();
- glEndList();
-}
-
-ENTRYPOINT void
-draw_maze (ModeInfo * mi)
-{
- unsigned i;
- maze_configuration *maze = &mazes[MI_SCREEN(mi)];
- GLfloat h = (GLfloat) MI_HEIGHT(mi) / MI_WIDTH(mi);
-
- if (!maze->glx_context)
- return;
- glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *maze->glx_context);
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- gluPerspective(90, 1/h, 0.05, 100);
-
- if (MI_WIDTH(mi) > 2560) /* Retina displays */
- glLineWidth (6);
- else
-# ifdef HAVE_MOBILE
- glLineWidth (4);
-# else
- glLineWidth (2);
-# endif
-
- glRotatef(maze->camera.inversion, 0, 0, 1);
- glRotatef(maze->camera.rotation, 0, 1, 0);
- glTranslatef(-1 * maze->camera.position.x, -0.5,
- -1 * maze->camera.position.z);
-
- refreshRemainingDistanceToTravel(mi);
-
- updateInverterRotation(maze);
- shiftAcidColor(maze);
- step(&maze->camera, maze);
-
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- drawWalls(mi);
- drawCeiling(mi);
- drawFloor(mi);
-
- for (i = 0; i < numInverters; i++)
- drawInverter(maze, maze->inverterPosition[i]);
-
-# ifdef USE_FLOATING_IMAGES
- for (i = 0; i < numGl3dTexts; i++)
- drawPane(mi, maze->gl3dTextTexture, maze->gl3dTextPosition[i]);
-# endif
-
- for (i = 0; i < numRats; i++) {
- step(&maze->rats[i], maze);
- drawRat(maze->rats[i].position, maze);
- }
-
- drawPane(mi, maze->finishTexture, maze->finishPosition);
- drawPane(mi, maze->startTexture, maze->startPosition);
-
- if (shouldDrawOverlay || maze->button_down_p)
- drawOverlay(mi);
-
- if (mi->fps_p) do_fps(mi);
- glFinish();
- glXSwapBuffers(MI_DISPLAY(mi), MI_WINDOW(mi));
-}
-
-static void
-shiftAcidColor(maze_configuration* maze)
-{
- GLfloat x = 1 - fabs(fmod(maze->acidHue / 60.0, 2) - 1);
-
- if (0 <= maze->acidHue && maze->acidHue <= 60) {
- maze->acidColor.red = 1;
- maze->acidColor.green = x;
- maze->acidColor.blue = 0;
- } else if (60 <= maze->acidHue && maze->acidHue <= 120) {
- maze->acidColor.red = x;
- maze->acidColor.green = 1;
- maze->acidColor.blue = 0;
- } else if (120 <= maze->acidHue && maze->acidHue <= 180) {
- maze->acidColor.red = 0;
- maze->acidColor.green = 1;
- maze->acidColor.blue = x;
- } else if (180 <= maze->acidHue && maze->acidHue <= 240) {
- maze->acidColor.red = 0;
- maze->acidColor.green = x;
- maze->acidColor.blue = 1;
- } else if (240 <= maze->acidHue && maze->acidHue <= 300) {
- maze->acidColor.red = x;
- maze->acidColor.green = 0;
- maze->acidColor.blue = 1;
- } else {
- maze->acidColor.red = 1;
- maze->acidColor.green = 0;
- maze->acidColor.blue = x;
- }
-
- maze->acidHue += 75 * maze->camera.remainingDistanceToTravel;
- if (maze->acidHue >= 360) maze->acidHue -= 360;
-}
-
-static void
-refreshRemainingDistanceToTravel(ModeInfo * mi)
-{
- unsigned i;
- maze_configuration *maze = &mazes[MI_SCREEN(mi)];
- maze->camera.remainingDistanceToTravel
- = speed * 1.6 * (MI_DELAY(mi) / 1000000.0);
- for (i = 0; i < numRats; i++)
- maze->rats[i].remainingDistanceToTravel =
- maze->camera.remainingDistanceToTravel;
-}
-
-static void
-step(Rat* rat, maze_configuration* maze)
-{
- GLfloat previousWallHeight = maze->wallHeight;
-
- if (!rat->isCamera && (maze->wallHeight < 1
- || (rat->position.x == 0 && rat->position.z == 0)))
- return;
-
- while (rat->remainingDistanceToTravel > 0) {
- switch(rat->state) {
- case WALKING:
- switch((int)rat->rotation) {
- case NORTH:
- walk(rat, 'z', -1, maze);
- break;
- case EAST:
- walk(rat, 'x', 1, maze);
- break;
- case SOUTH:
- walk(rat, 'z', 1, maze);
- break;
- case WEST:
- walk(rat, 'x', -1, maze);
- break;
- default:
- rat->rotation = 90 * roundf(rat->rotation / 90.0);
- break;
- }
- break;
- case TURNING_LEFT:
- turn(rat, maze);
- break;
- case TURNING_RIGHT:
- turn(rat, maze);
- break;
- case TURNING_AROUND:
- turnAround(rat, maze);
- break;
- case INVERTING:
- invert(maze);
- break;
- case STARTING:
- maze->wallHeight += 0.48 * rat->remainingDistanceToTravel;
- if (maze->wallHeight > 1.0) {
- maze->wallHeight = 1.0;
- rat->remainingDistanceToTravel =
- fabs(previousWallHeight - maze->wallHeight);
- changeState(&maze->camera, maze);
- } else
- rat->remainingDistanceToTravel = 0;
- break;
- case FINISHING:
- if (maze->wallHeight == 0) {
- newMaze(maze);
- rat->remainingDistanceToTravel = 0;
- }
- else if (maze->wallHeight < 0) {
- maze->wallHeight = 0;
- rat->remainingDistanceToTravel =
- fabs(previousWallHeight - maze->wallHeight);
- }
- else {
- maze->wallHeight -= 0.48 * rat->remainingDistanceToTravel;
- rat->remainingDistanceToTravel = 0;
- }
- break;
- default:
- break;
- }
- }
-}
-
-static void
-walk(Rat* rat, char axis, int sign, maze_configuration* maze)
-{
- GLfloat* component = (axis == 'x' ? &rat->position.x : &rat->position.z);
- GLfloat previousPosition = *component;
- int isMultipleOfOneHalf = 0;
- unsigned temp = (unsigned)((*component) * 2.0);
-
- if (((*component) * 2) == roundf((*component) * 2))
- isMultipleOfOneHalf = 1;
- *component += sign * rat->remainingDistanceToTravel;
-
- if (!isMultipleOfOneHalf && ((unsigned)((*component) * 2.0)) != temp) {
- *component = roundToNearestHalf(*component);
- rat->remainingDistanceToTravel -=
- fabs((*component) - previousPosition);
- changeState(rat, maze);
- } else
- rat->remainingDistanceToTravel = 0;
-
-}
-
-static void
-turn(Rat* rat, maze_configuration* maze)
-{
- Tuplef rotatingAround;
- GLfloat tangentVectorDirection, previousRotation
- = rat->rotation;
-
- if (rat->state == TURNING_LEFT) {
- tangentVectorDirection = rat->rotation * (M_PI / 180) + M_PI;
- rotatingAround.x = roundToNearestHalf(rat->position.x
- + 0.5 * cos(tangentVectorDirection));
- rotatingAround.z = roundToNearestHalf(rat->position.z
- + 0.5 * sin(tangentVectorDirection));
-
- rat->rotation -= DEF_ANGULAR_CONVERSION_FACTOR
- * rat->remainingDistanceToTravel;
-
- if (previousRotation > WEST && rat->rotation <= WEST) {
- rat->rotation = WEST;
- rat->remainingDistanceToTravel -= (M_PI / 180)
- * fabs(previousRotation - rat->rotation);
- } else if (previousRotation > SOUTH && rat->rotation <= SOUTH) {
- rat->rotation = SOUTH;
- rat->remainingDistanceToTravel -= (M_PI / 180)
- * fabs(previousRotation - rat->rotation);
- } else if (previousRotation > EAST && rat->rotation <= EAST) {
- rat->rotation = EAST;
- rat->remainingDistanceToTravel -= (M_PI / 180)
- * fabs(previousRotation - rat->rotation);
- } else if (previousRotation > NORTH && rat->rotation <= NORTH) {
- rat->rotation = NORTH;
- rat->remainingDistanceToTravel -= (M_PI / 180)
- * fabs(previousRotation - rat->rotation);
- } else
- rat->remainingDistanceToTravel = 0;
-
- tangentVectorDirection = rat->rotation * (M_PI / 180);
- }
- else {
- tangentVectorDirection = rat->rotation * (M_PI / 180);
- rotatingAround.x = roundToNearestHalf(rat->position.x
- + 0.5 * cos(tangentVectorDirection));
- rotatingAround.z = roundToNearestHalf(rat->position.z
- + 0.5 * sin(tangentVectorDirection));
-
- rat->rotation += DEF_ANGULAR_CONVERSION_FACTOR
- * rat->remainingDistanceToTravel;
-
- if (rat->rotation >= 360) {
- rat->rotation = NORTH;
- rat->remainingDistanceToTravel -= (M_PI / 180)
- * fabs(previousRotation - 360);
- } else if (previousRotation < WEST && rat->rotation >= WEST) {
- rat->rotation = WEST;
- rat->remainingDistanceToTravel -= (M_PI / 180)
- * fabs(previousRotation - rat->rotation);
- } else if (previousRotation < SOUTH && rat->rotation >= SOUTH) {
- rat->rotation = SOUTH;
- rat->remainingDistanceToTravel -= (M_PI / 180)
- * fabs(previousRotation - rat->rotation);
- } else if (previousRotation < EAST && rat->rotation >= EAST) {
- rat->rotation = EAST;
- rat->remainingDistanceToTravel -= (M_PI / 180)
- * fabs(previousRotation - rat->rotation);
- } else
- rat->remainingDistanceToTravel = 0;
-
- tangentVectorDirection = rat->rotation * (M_PI / 180) + M_PI;
- }
-
- rat->position.x = rotatingAround.x + 0.5 * cos(tangentVectorDirection);
- rat->position.z = rotatingAround.z + 0.5 * sin(tangentVectorDirection);
-
- if (rat->rotation < 0)
- rat->rotation += 360;
-
- if (rat->rotation == NORTH || rat->rotation == EAST
- || rat->rotation == SOUTH || rat->rotation == WEST) {
- rat->position.x = roundToNearestHalf(rat->position.x);
- rat->position.z = roundToNearestHalf(rat->position.z);
- changeState(rat, maze);
- }
-}
-
-static void
-turnAround(Rat* rat, maze_configuration* maze)
-{
- GLfloat previousRotation = rat->rotation;
-
- rat->rotation -= 1.5 * DEF_ANGULAR_CONVERSION_FACTOR
- * rat->remainingDistanceToTravel;
-
- if (previousRotation > rat->desiredRotation
- && rat->rotation <= rat->desiredRotation) {
- rat->rotation = rat->desiredRotation;
- rat->remainingDistanceToTravel -= (M_PI / 180)
- * fabs(previousRotation - rat->rotation);
- changeState(rat, maze);
- }
- else {
- rat->remainingDistanceToTravel = 0;
- if (rat->rotation < 0) rat->rotation += 360;
- }
-}
-
-static void
-invert(maze_configuration* maze)
-{
- GLfloat previousInversion = maze->camera.inversion;
- int shouldChangeState = 0;
- unsigned cameraX = (unsigned)roundf(maze->camera.position.x * 2),
- cameraZ = (unsigned)roundf(maze->camera.position.z * 2);
-
- maze->camera.inversion += 1.5 * DEF_ANGULAR_CONVERSION_FACTOR
- * maze->camera.remainingDistanceToTravel;
- if (previousInversion < 180 && maze->camera.inversion >= 180) {
- maze->camera.inversion = 180;
- maze->camera.remainingDistanceToTravel -= (M_PI / 180)
- * fabs(previousInversion - maze->camera.inversion);
- shouldChangeState = 1;
- }
- else if (maze->camera.inversion >= 360) {
- maze->camera.inversion = 0;
- maze->camera.remainingDistanceToTravel -= (M_PI / 180)
- * fabs(previousInversion - maze->camera.inversion);
- shouldChangeState = 1;
- } else
- maze->camera.remainingDistanceToTravel = 0;
-
- if (shouldChangeState) {
- switch ((int)maze->camera.rotation) {
- case NORTH:
- maze->mazeGrid[cameraZ - 1][cameraX] = CELL;
- break;
- case EAST:
- maze->mazeGrid[cameraZ][cameraX + 1] = CELL;
- break;
- case SOUTH:
- maze->mazeGrid[cameraZ + 1][cameraX] = CELL;
- break;
- case WEST:
- maze->mazeGrid[cameraZ][cameraX - 1] = CELL;
- break;
- default:
- break;
- }
-
- changeState(&maze->camera, maze);
- }
-}
-
-static void
-changeState(Rat* rat, maze_configuration* maze)
-{
- unsigned char inFrontOfRat, toTheLeft, straightAhead, toTheRight;
- unsigned ratX = (unsigned)roundf(rat->position.x * 2),
- ratZ = (unsigned)roundf(rat->position.z * 2);
-
- switch ((int)rat->rotation) {
- case NORTH:
- inFrontOfRat = maze->mazeGrid[ratZ - 1][ratX];
- toTheLeft = maze->mazeGrid[ratZ - 1][ratX - 1];
- straightAhead = maze->mazeGrid[ratZ - 2][ratX];
- toTheRight = maze->mazeGrid[ratZ - 1][ratX + 1];
- break;
- case EAST:
- inFrontOfRat = maze->mazeGrid[ratZ][ratX + 1];
- toTheLeft = maze->mazeGrid[ratZ - 1][ratX + 1];
- straightAhead = maze->mazeGrid[ratZ][ratX + 2];
- toTheRight = maze->mazeGrid[ratZ + 1][ratX + 1];
- break;
- case SOUTH:
- inFrontOfRat = maze->mazeGrid[ratZ + 1][ratX];
- toTheLeft = maze->mazeGrid[ratZ + 1][ratX + 1];
- straightAhead = maze->mazeGrid[ratZ + 2][ratX];
- toTheRight = maze->mazeGrid[ratZ + 1][ratX - 1];
- break;
- case WEST:
- inFrontOfRat = maze->mazeGrid[ratZ][ratX - 1];
- toTheLeft = maze->mazeGrid[ratZ + 1][ratX - 1];
- straightAhead = maze->mazeGrid[ratZ][ratX - 2];
- toTheRight = maze->mazeGrid[ratZ - 1][ratX - 1];
- break;
- default:
- inFrontOfRat = toTheLeft = straightAhead = toTheRight = CELL;
- break;
- }
-
- if (rat->isCamera && inFrontOfRat == FINISH)
- rat->state = FINISHING;
- else if (rat->isCamera && inFrontOfRat >= INVERTER_TETRAHEDRON
- && inFrontOfRat <= INVERTER_ICOSAHEDRON)
- rat->state = INVERTING;
- else if (toTheLeft != WALL && toTheLeft != WALL_GL_REDBOOK)
- rat->state = TURNING_LEFT;
- else if (straightAhead != WALL && straightAhead != WALL_GL_REDBOOK)
- rat->state = WALKING;
- else if (toTheRight != WALL && toTheRight != WALL_GL_REDBOOK)
- rat->state = TURNING_RIGHT;
- else {
- rat->state = TURNING_AROUND;
-
- switch ((int)rat->rotation) {
- case NORTH:
- rat->desiredRotation = SOUTH;
- break;
- case EAST:
- rat->desiredRotation = WEST;
- break;
- case SOUTH:
- rat->desiredRotation = NORTH;
- break;
- case WEST:
- rat->desiredRotation = EAST;
- break;
- default:
- break;
- }
- }
-}
-
-static void
-updateInverterRotation(maze_configuration* maze)
-{
- maze->inverterRotation += 45 * maze->camera.remainingDistanceToTravel;
-}
-
-static void drawInverter(maze_configuration* maze, Tuple coordinates)
-{
- unsigned char type = maze->mazeGrid[coordinates.row][coordinates.column];
-
- if (maze->wallHeight < 1 ||
- type < INVERTER_TETRAHEDRON || type > INVERTER_ICOSAHEDRON
- || (coordinates.row == 0 && coordinates.column == 0))
- return;
-
- glEnable(GL_LIGHTING);
- glEnable(GL_CULL_FACE);
-
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
-
- glTranslatef(coordinates.column / 2.0, 0.25, coordinates.row / 2.0);
- glRotatef(0.618033989 * maze->inverterRotation, 0, 1, 0);
- glRotatef(maze->inverterRotation, 1, 0, 0);
-
- if (type >= countof(maze->dlists)) abort();
- glCallList(maze->dlists[type]);
-
- glPopMatrix();
-
- glDisable(GL_LIGHTING);
- glDisable(GL_CULL_FACE);
-}
-
-static void
-drawWalls(ModeInfo * mi)
-{
- unsigned i, j;
- Tuple startCoordinates, endCoordinates;
-
- maze_configuration *maze = &mazes[MI_SCREEN(mi)];
-
- for (i = 0; i < maze->numRows; i++) {
- for (j = 0; j < maze->numColumns; j++) {
- if (maze->mazeGrid[i][j] == WALL
- || maze->mazeGrid[i][j] == WALL_GL_REDBOOK) {
- if (maze->mazeGrid[i][j] == WALL) {
- glBindTexture(GL_TEXTURE_2D, maze->wallTexture);
- if (dropAcid || dropAcidWalls)
- glColor3f(maze->acidColor.red, maze->acidColor.green,
- maze->acidColor.blue);
-# ifdef USE_FLOATING_IMAGES
- } else {
- glBindTexture(GL_TEXTURE_2D, maze->glTextbookTexture);
- glColor3f(1, 1, 1);
-# endif
- }
-
- if (isOdd(i) && isEven(j)) {
- startCoordinates.row = i / 2;
- startCoordinates.column = j / 2;
- endCoordinates.row = i / 2 + 1;
- endCoordinates.column = j / 2;
- drawWall(startCoordinates, endCoordinates, maze);
- } else if (isEven(i) && isOdd(j)) {
- startCoordinates.row = i / 2;
- startCoordinates.column = j / 2;
- endCoordinates.row = i / 2;
- endCoordinates.column = j / 2 + 1;
- drawWall(startCoordinates, endCoordinates, maze);
- }
- }
- }
- }
-
- glBindTexture(GL_TEXTURE_2D, 0);
- glColor3f(1, 1, 1);
-}
-
-static void
-drawWall(Tuple startCoordinates, Tuple endCoordinates, maze_configuration* maze)
-{
- GLfloat wallHeight = maze->wallHeight;
-
- glBegin(GL_QUADS);
- if (startCoordinates.row == endCoordinates.row) {
- glTexCoord2f(0, 0);
- glVertex3f(startCoordinates.column, 0, startCoordinates.row);
- glTexCoord2f(1, 0);
- glVertex3f(endCoordinates.column, 0, startCoordinates.row);
- glTexCoord2f(1, 1);
- glVertex3f(endCoordinates.column, wallHeight, endCoordinates.row);
- glTexCoord2f(0, 1);
- glVertex3f(startCoordinates.column, wallHeight, endCoordinates.row);
- } else {
- glTexCoord2f(0, 0);
- glVertex3f(startCoordinates.column, 0, startCoordinates.row);
- glTexCoord2f(1, 0);
- glVertex3f(startCoordinates.column, 0, endCoordinates.row);
- glTexCoord2f(1, 1);
- glVertex3f(endCoordinates.column, wallHeight, endCoordinates.row);
- glTexCoord2f(0, 1);
- glVertex3f(endCoordinates.column, wallHeight, startCoordinates.row);
- }
- glEnd();
-}
-
-static void
-drawCeiling(ModeInfo * mi)
-{
- Tuple farRightCorner;
- maze_configuration *maze = &mazes[MI_SCREEN(mi)];
- farRightCorner.row = maze->numRows / 2;
- farRightCorner.column = maze->numColumns / 2;
- glBindTexture(GL_TEXTURE_2D, maze->ceilingTexture);
-
- glBegin(GL_QUADS);
- if (dropAcid || dropAcidCeiling)
- glColor3f(maze->acidColor.red, maze->acidColor.green,
- maze->acidColor.blue);
- glTexCoord2f(0, 0);
- glVertex3f(0, 1, 0);
- glTexCoord2f(farRightCorner.column, 0);
- glVertex3f(farRightCorner.column, 1, 0);
- glTexCoord2f(farRightCorner.column, farRightCorner.row);
- glVertex3f(farRightCorner.column, 1, farRightCorner.row);
- glTexCoord2f(0, farRightCorner.row);
- glVertex3f(0, 1, farRightCorner.row);
- glColor3f(1, 1, 1);
- glEnd();
-
- glBindTexture(GL_TEXTURE_2D, 0);
-}
-
-static void
-drawFloor(ModeInfo * mi)
-{
- Tuple farRightCorner;
- maze_configuration *maze = &mazes[MI_SCREEN(mi)];
- farRightCorner.row = maze->numRows / 2;
- farRightCorner.column = maze->numColumns / 2;
- glBindTexture(GL_TEXTURE_2D, maze->floorTexture);
-
- glBegin(GL_QUADS);
- if (dropAcid || dropAcidFloor)
- glColor3f(maze->acidColor.red, maze->acidColor.green,
- maze->acidColor.blue);
- glTexCoord2f(0, 0);
- glVertex3f(0, 0, 0);
- glTexCoord2f(farRightCorner.column, 0);
- glVertex3f(farRightCorner.column, 0, 0);
- glTexCoord2f(farRightCorner.column, farRightCorner.row);
- glVertex3f(farRightCorner.column, 0, farRightCorner.row);
- glTexCoord2f(0, farRightCorner.row);
- glVertex3f(0, 0, farRightCorner.row);
- glColor3f(1, 1, 1);
- glEnd();
-
- glBindTexture(GL_TEXTURE_2D, 0);
-}
-
-static void
-drawPane(ModeInfo *mi, GLuint texture, Tuple position)
-{
- maze_configuration *maze = &mazes[MI_SCREEN(mi)];
- if (position.row == 0 && position.column == 0) return;
-
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- glBindTexture(GL_TEXTURE_2D, texture);
-
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glTranslatef(position.column / 2.0, 0, position.row / 2.0);
- glRotatef(-1 * maze->camera.rotation - 90, 0, 1, 0);
-
- if (MI_WIDTH(mi) < MI_HEIGHT(mi))
- {
- /* Keep the Start button readable in phone portrait mode. */
- glScalef (0.5, 0.5, 0.5);
- glTranslatef (0, 0.5, 0);
- }
-
- glBegin(GL_QUADS);
- glColor4f(1, 1, 1, 0.9);
- glTexCoord2f(0, 0);
- glVertex3f(0, 0, 0.5);
- glTexCoord2f(1, 0);
- glVertex3f(0, 0, -0.5);
- glTexCoord2f(1, 1);
- glVertex3f(0, maze->wallHeight, -0.5);
- glTexCoord2f(0, 1);
- glVertex3f(0, maze->wallHeight, 0.5);
- glColor3f(1, 1, 1);
- glEnd();
-
- glPopMatrix();
- glBindTexture(GL_TEXTURE_2D, 0);
- glDisable(GL_BLEND);
-}
-
-static void
-drawRat(Tuplef position, maze_configuration* maze)
-{
- if (position.x == 0 && position.z == 0) return;
-
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- glBindTexture(GL_TEXTURE_2D, maze->ratTexture);
-
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glTranslatef(position.x, 0, position.z);
- glRotatef(-1 * maze->camera.rotation - 90, 0, 1, 0);
-
- glScalef (0.25, 0.25, 0.25);
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0);
- glVertex3f(0, 0, 0.5);
- glTexCoord2f(1, 0);
- glVertex3f(0, 0, -0.5);
- glTexCoord2f(1, 1);
- glVertex3f(0, maze->wallHeight, -0.5);
- glTexCoord2f(0, 1);
- glVertex3f(0, maze->wallHeight, 0.5);
- glEnd();
-
- glPopMatrix();
- glBindTexture(GL_TEXTURE_2D, 0);
- glDisable(GL_BLEND);
-}
-
-
-static void drawOverlay(ModeInfo *mi)
-{
- maze_configuration *maze = &mazes[MI_SCREEN(mi)];
- unsigned i, j;
- GLfloat h = (GLfloat) MI_HEIGHT(mi) / MI_WIDTH(mi);
-
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glLoadIdentity();
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
- glOrtho(-1/h, 1/h, 1, -1, -1, 1);
-
- glEnable(GL_BLEND);
- glColor4f(0, 0, 1, 0.75);
- glScalef(0.25, 0.25, 0.25);
-
- glCallList(maze->dlists[ARROW]);
-
- glRotatef(maze->camera.inversion, 0, 1, 0);
- glRotatef(maze->camera.rotation, 0, 0, -1);
- glTranslatef(-maze->camera.position.x, -maze->camera.position.z, 0);
- glColor4f(1, 1, 1, 0.75);
-
- glBegin(GL_LINES);
- for (i = 0; i < maze->numRows; i++) {
- for (j = 0; j < maze->numColumns; j++) {
- if (maze->mazeGrid[i][j] == WALL
- || maze->mazeGrid[i][j] == WALL_GL_REDBOOK) {
- if (isOdd(i) && isEven(j)) {
- glVertex2f(j / 2, i / 2);
- glVertex2f(j / 2, i / 2 + 1);
- } else if (isEven(i) && isOdd(j)) {
- glVertex2f(j / 2, i / 2);
- glVertex2f(j / 2 + 1, i / 2);
- }
- }
- }
- }
- glEnd();
-
- glColor4f(1, 0, 0, 0.75);
-
- glPushMatrix();
- glTranslatef(maze->startPosition.column / 2.0,
- maze->startPosition.row / 2.0, 0);
- glCallList(maze->dlists[SQUARE]);
- glPopMatrix();
-
- glColor4f(1, 1, 0, 0.75);
-
- glPushMatrix();
- glTranslatef(maze->finishPosition.column / 2.0,
- maze->finishPosition.row / 2.0, 0);
- glCallList(maze->dlists[STAR]);
- glPopMatrix();
-
- glColor4f(1, 0.607843137, 0, 0.75);
-
- for (i = 0; i < numRats; i++) {
- if (maze->rats[i].position.x == 0 && maze->rats[i].position.z == 0)
- continue;
- glPushMatrix();
- glTranslatef(maze->rats[i].position.x, maze->rats[i].position.z, 0);
- glRotatef(maze->rats[i].rotation, 0, 0, 1);
- glCallList(maze->dlists[ARROW]);
- glPopMatrix();
- }
-
- glColor4f(1, 1, 1, 1);
-
- for (i = 0; i < numInverters; i++) {
- j = maze->mazeGrid[maze->inverterPosition[i].row]
- [maze->inverterPosition[i].column];
- if (j >= INVERTER_TETRAHEDRON && j <= INVERTER_ICOSAHEDRON) {
- glPushMatrix();
- glTranslatef(maze->inverterPosition[i].column / 2.0,
- maze->inverterPosition[i].row / 2.0, 0);
- glRotatef(1.5 * maze->inverterRotation, 0, 0, 1);
- glCallList(maze->dlists[TRIANGLE]);
- glPopMatrix();
- }
- }
-
- glDisable(GL_BLEND);
-
- glPopMatrix();
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
-}
-
-ENTRYPOINT void
-free_maze (ModeInfo * mi)
-{
- maze_configuration *maze = &mazes[MI_SCREEN(mi)];
- int i;
-
- if (!maze->glx_context) return;
- glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *maze->glx_context);
-
- glDeleteTextures(1, &maze->wallTexture);
- glDeleteTextures(1, &maze->floorTexture);
- glDeleteTextures(1, &maze->ceilingTexture);
- glDeleteTextures(1, &maze->startTexture);
- glDeleteTextures(1, &maze->ratTexture);
- glDeleteTextures(1, &maze->finishTexture);
-# ifdef USE_FLOATING_IMAGES
- glDeleteTextures(1, &maze->glTextbookTexture);
- glDeleteTextures(1, &maze->gl3dTextTexture);
-# endif
-# ifdef USE_FRACTAL_IMAGES
- glDeleteTextures(1, &maze->fractal1Texture);
- glDeleteTextures(1, &maze->fractal2Texture);
- glDeleteTextures(1, &maze->fractal3Texture);
- glDeleteTextures(1, &maze->fractal4Texture);
-# endif
-
- for (i = 0; i < countof(maze->dlists); i++)
- if (glIsList(maze->dlists[i])) glDeleteLists(maze->dlists[i], 1);
-
- free(maze->mazeGrid);
- free(maze->wallList);
- free(maze->inverterPosition);
- free(maze->gl3dTextPosition);
- free(maze->rats);
-}
-
-
-XSCREENSAVER_MODULE_2 ("Maze3D", maze3d, maze)
-
-#endif