home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 8 Other
/
08-Other.zip
/
OS2MAZ.ZIP
/
OS2MAZE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-09-11
|
87KB
|
2,258 lines
/*
This OS/2 1.3 program will generate a three dimensional maze on a VGA
display. A different random number seed will produce a different maze.
Written on September 1, 1992 by James L. Dean
406 40th Street
New Orleans, LA 70124
*/
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <malloc.h>
#include <memory.h>
#include <stdlib.h>
#include <conio.h>
#include <dos.h>
#define INCL_BASE
#include <os2.h>
#define TRUE 1
#define FALSE 0
/* screen constants */
#define WIDTH_OF_SCREEN 8.0
#define HEIGHT_OF_SCREEN 6.0 /* same units as WIDTH_OF_SCREEN */
/* graphics constants */
#define NUM_X_PIXELS 640
#define NUM_Y_PIXELS 480
#define NUM_COLORS 16
#define RGB_INCREMENT 4 /* 64/NUM_COLORS */
#define stack_size 32767
#define NUM_CELLS 38400 /* NUM_X_PIXELS*NUM_Y_PIXELS/8 */
#define VGA_control 0x3ce /* graphics controller control port */
#define VGA_control_data 0x3cf /* graphics controller data port */
#define VGA_read_map 0x04 /* read map register in graphics port */
#define VGA_mode 0x05 /* mode register in graphics port */
#define VGA_bit_mask 0x08 /* bitmask register in graphics port */
#define VGA_sequence 0x3c4 /* sequencer control port */
#define VGA_sequence_data 0x3c5 /* sequencer data port */
#define VGA_map_mask 0x02 /* map mask register in sequencer */
/* maze constants */
#define PIXELS_PER_ROOM 40
#define RESOLUTION 6 /* larger numbers give more detail
but take more time and memory */
typedef struct
{
int x;
int y;
} box_rec;
typedef struct
{
unsigned char red;
unsigned char green;
unsigned char blue;
} rgb_rec;
typedef struct stack_rec_record
{
char index_1;
int index_2;
} stack_rec;
typedef struct
{
double x;
double y;
double z;
} vertex_rec;
static void adjust_perspective(int,int,float huge *,float huge *,float huge *,
double,double,double,double,double);
static void clear_screen(void);
static void draw_line_on_page(char **,int,int,int,int);
static void evaluate_and_transform(double,double,double,double,int,int,
double,double,float huge *,float huge *,float huge *,double *,
double *,double *,double *,double *,vertex_rec *,int huge *,
int huge *,unsigned char huge *);
static double f(double,double);
static void free_memory(float huge **,float huge **,
float huge **,int huge **,int huge **,
unsigned char huge **,unsigned char huge **,int,char ***,int,
char ***,int,stack_rec **);
static void generate_maze(int *,char **,char **,int,int,stack_rec *,int,
int,int,int,int);
static void get_cursor(USHORT *,USHORT *,VIOCURSORINFO *);
static void hash(int *,int *,int *,int *,int *,int *,int *,int *);
static void increment(int *,int *,int *,int *,int *,int *,int *,int *);
void main(void);
static int memory_allocated(long,float huge **,float huge **,
float huge **,int huge **,int huge **,
unsigned char huge **,unsigned char huge **,int,int,char ***,int,
int,char ***,int,stack_rec **);
static void mode_thread(void);
static void plot(int,int huge *,int,int huge *,long,float huge *,float huge *,
double,double,double,double,unsigned char huge *,
unsigned char huge *,int,double);
static void save_redraw_thread(void);
static void set_cursor_position(USHORT,USHORT);
static void set_cursor_type(VIOCURSORINFO *);
static void set_initial_video_mode(void);
static void set_pixel(int,int,short);
static void set_point_on_page(char **,int,int);
static void shade(int,int,float huge *,float huge *,float huge *,
unsigned char huge *,vertex_rec *);
static void solve_maze(stack_rec *,char **,int *,int *,int,int);
static void sort_back_to_front(long,float huge *,int huge *,int huge *);
static void titillate(void);
static int VGA_640_480_16(void);
static char **base_page;
static USHORT cursor_column;
static USHORT cursor_row;
static int delta_x [6] [720];
static int delta_y [6] [720];
VIOCURSORINFO initial_cursor_type;
static int max_x;
static int max_y;
static char **page;
static int tem_int;
static char titillator [4] = { '|', '/', '-', '\\' };
VIOCURSORINFO titillator_cursor_type;
static int titillator_index;
static int x_dot_max;
static int y_dot_max;
/* video globals */
VIOMODEINFO default_video_mode;
PVIOPALSTATE invisible_palette;
BYTE invisible_palette_byte [38];
VIOCOLORREG maze_color;
PVIOPALSTATE maze_palette;
BYTE maze_palette_byte [38];
static rgb_rec maze_rgb [16];
VIOMODEINFO maze_video_mode;
static int mode_id;
static char mode_thread_stack [stack_size];
VIOPHYSBUF phys_buf;
static char save_redraw_thread_stack [stack_size];
static int save_redraw_id;
static unsigned char scr_lock;
static int VGA_base_adr;
static long huge *video_plane [4]; /* save area for video planes */
void main()
{
static double aspect_ratio;
static unsigned char huge *base_z;
static unsigned char huge *color;
static vertex_rec light;
static int max_x_plus_1;
static int max_y_plus_1;
static int num_columns;
static long num_primes;
static int num_rooms_in_maze;
static int num_rows;
static int num_x_divisions;
static int num_x_dots;
static int num_y_divisions;
static int num_y_dots;
static int r_n [8];
static int response;
static double rotation;
static stack_rec *stack;
static double tilt;
static int huge *x_division_index;
static double x_max;
static double x_min;
static float huge *x_prime;
static double x_prime_max;
static int huge *y_division_index;
static double y_max;
static double y_min;
static float huge *y_prime;
static double y_prime_max;
static double y_prime_min;
static float huge *z_prime;
static double z_prime_max;
static double z_prime_min;
aspect_ratio=(HEIGHT_OF_SCREEN/WIDTH_OF_SCREEN)
/(((double) NUM_Y_PIXELS)/((double) NUM_X_PIXELS));
num_columns=2*NUM_X_PIXELS/(3*PIXELS_PER_ROOM)-1;
num_columns=2*num_columns+1;
max_x=8*(num_columns/2)+6;
max_x_plus_1=max_x+1;
num_x_dots=RESOLUTION*max_x_plus_1;
x_dot_max=num_x_dots-1;
num_rows=(int) ((2.0/sqrt(3.0))*aspect_ratio*((double) NUM_Y_PIXELS)
/((double) PIXELS_PER_ROOM));
max_y=4*num_rows;
max_y_plus_1=max_y+1;
num_y_dots=RESOLUTION*max_y_plus_1;
y_dot_max=num_y_dots-1;
num_rooms_in_maze=num_rows*num_columns-(num_columns/2);
num_x_divisions=num_y_dots+2;
num_y_divisions=num_x_dots+2;
num_primes=(long) num_x_divisions;
num_primes*=((long) num_y_divisions);
if (memory_allocated(num_primes,&x_prime,&y_prime,
&z_prime,&x_division_index,&y_division_index,&color,&base_z,max_x_plus_1,
max_y_plus_1,&base_page,num_x_dots,num_y_dots,&page,num_rooms_in_maze,
&stack))
{
clear_screen();
printf(" Maze Generator\n\n\n\n");
printf(
" After the maze is displayed, press \"S\" to see the solution.\n");
generate_maze(&r_n[0],base_page,page,max_x,max_y,
stack,x_dot_max,y_dot_max,num_rooms_in_maze,num_columns,num_rows);
x_min=-1.0;
x_max=(double) num_y_dots;
y_min=-1.0;
y_max=(double) num_x_dots;
rotation=0.0;
tilt=30.0;
light.x=1.5;
light.y=-1.0;
light.z=2.6;
evaluate_and_transform(x_min,x_max,y_min,y_max,num_x_divisions,
num_y_divisions,rotation,tilt,x_prime,y_prime,z_prime,&x_prime_max,
&y_prime_min,&y_prime_max,&z_prime_min,&z_prime_max,&light,
x_division_index,y_division_index,base_z);
shade(num_x_divisions,num_y_divisions,x_prime,y_prime,z_prime,color,
&light);
adjust_perspective(num_x_divisions,num_y_divisions,x_prime,y_prime,
z_prime,x_prime_max,y_prime_min,y_prime_max,z_prime_min,z_prime_max);
sort_back_to_front(num_primes,x_prime,x_division_index,
y_division_index);
if (VGA_640_480_16())
{
plot(num_x_divisions,x_division_index,num_y_divisions,
y_division_index,num_primes,y_prime,z_prime,y_prime_min,
y_prime_max,z_prime_min,z_prime_max,color,base_z,FALSE,
aspect_ratio);
fflush(stdin);
response=getch();
fflush(stdin);
if ((response == (int) 's') || (response == (int) 'S'))
{
plot(num_x_divisions,x_division_index,num_y_divisions,
y_division_index,num_primes,y_prime,z_prime,y_prime_min,
y_prime_max,z_prime_min,z_prime_max,color,base_z,TRUE,
aspect_ratio);
fflush(stdin);
response=getch();
fflush(stdin);
}
set_initial_video_mode();
}
else
printf("? 640 x 480 x 16 VGA mode is not available\n");
set_cursor_type(&initial_cursor_type);
free_memory(&x_prime,&y_prime,&z_prime,&x_division_index,
&y_division_index,&color,&base_z,max_y_plus_1,&base_page,num_y_dots,
&page,num_rooms_in_maze,&stack);
}
else
printf("? not enough memory\n");
return;
}
static void clear_screen()
{
unsigned char fill [2];
VIOMODEINFO video_mode_info;
video_mode_info.cb=(unsigned int) 12;
VioGetMode(&video_mode_info,(HVIO) 0);
fill[0]=(unsigned char) ' ';
fill[1]=(unsigned char) 7;
VioScrollUp((USHORT) 0,(USHORT) 0,
(USHORT) (video_mode_info.row-1),
(USHORT) (video_mode_info.col-1),
(USHORT) 0xffff,(PBYTE) &fill[0],(HVIO) 0);
VioSetCurPos((USHORT) 0,(USHORT) 0,(HVIO) 0);
return;
}
static void get_cursor(cursor_row,cursor_column,cursor_type)
USHORT *cursor_row;
USHORT *cursor_column;
VIOCURSORINFO *cursor_type;
{
VioGetCurPos((PUSHORT) cursor_row,(PUSHORT) cursor_column,(HVIO) 0);
VioGetCurType((PVIOCURSORINFO) cursor_type,(HVIO) 0);
return;
}
static void set_cursor_position(cursor_row,cursor_column)
USHORT cursor_row;
USHORT cursor_column;
{
VioSetCurPos(cursor_row,cursor_column,(HVIO) 0);
return;
}
static void set_cursor_type(cursor_type)
VIOCURSORINFO *cursor_type;
{
VioSetCurType((PVIOCURSORINFO) cursor_type,(HVIO) 0);
return;
}
static void titillate()
{
set_cursor_position(cursor_row,cursor_column);
titillator_index++;
if (titillator_index > 3)
titillator_index=0;
putchar((int) titillator[titillator_index]);
return;
}
static int memory_allocated(num_primes,x_prime,y_prime,
z_prime,x_division_index,y_division_index,color,base_z,max_x_plus_1,
max_y_plus_1,base_page,num_x_dots,num_y_dots,page,num_rooms_in_maze,stack)
long num_primes;
float huge **x_prime;
float huge **y_prime;
float huge **z_prime;
int huge **x_division_index;
int huge **y_division_index;
unsigned char huge **color;
unsigned char huge **base_z;
int max_x_plus_1;
int max_y_plus_1;
char ***base_page;
int num_x_dots;
int num_y_dots;
char ***page;
int num_rooms_in_maze;
stack_rec **stack;
{
static int result;
register int y;
result=(((*base_page)=(char **)
malloc(((unsigned int) max_y_plus_1)*sizeof(char *)))
!= NULL);
if (result)
{
for (y=0; ((result) && (y < max_y_plus_1)); y++)
result=(((*base_page)[y]=(char *)
malloc(((unsigned int) max_x_plus_1)*sizeof(char)))
!= NULL);
if (! result)
{
--y;
while (y > 0)
free((void *) (*base_page)[--y]);
free((void *) (*base_page));
}
}
if (result)
{
result=(((*page)=(char **)
malloc(((unsigned int) num_y_dots)*sizeof(char *)))
!= NULL);
if (result)
{
for (y=0; ((result) && (y < num_y_dots)); y++)
result=(((*page)[y]=(char *)
malloc(((unsigned int) num_x_dots)*sizeof(char)))
!= NULL);
if (! result)
{
--y;
while (y > 0)
free((void *) (*page)[--y]);
free((void *) (*page));
for (y=0; y < max_y_plus_1; y++)
free((void *) (*base_page)[y]);
free((void *) (*base_page));
}
}
else
{
for (y=0; y < max_y_plus_1; y++)
free((void *) (*base_page)[y]);
free((void *) (*base_page));
}
}
if (result)
{
if (! (result
=((*x_prime=(float huge *)
halloc(num_primes,sizeof(float))) != NULL)))
{
for (y=0; y < num_y_dots; y++)
free((void *) (*page)[y]);
free((void *) (*page));
for (y=0; y < max_y_plus_1; y++)
free((void *) (*base_page)[y]);
free((void *) (*base_page));
}
}
if (result)
{
if (! (result=((*y_prime
=(float huge *) halloc(num_primes,sizeof(float)))
!= NULL)))
{
hfree((void huge *) *x_prime);
for (y=0; y < num_y_dots; y++)
free((void *) (*page)[y]);
free((void *) (*page));
for (y=0; y < max_y_plus_1; y++)
free((void *) (*base_page)[y]);
free((void *) (*base_page));
}
}
if (result)
{
if (! (result=((*z_prime
=(float huge *) halloc(num_primes,sizeof(float)))
!= NULL)))
{
hfree((void huge *) *y_prime);
hfree((void huge *) *x_prime);
for (y=0; y < num_y_dots; y++)
free((void *) (*page)[y]);
free((void *) (*page));
for (y=0; y < max_y_plus_1; y++)
free((void *) (*base_page)[y]);
free((void *) (*base_page));
}
}
if (result)
{
if (! (result=((*x_division_index
=(int huge *) halloc(num_primes,sizeof(int))) != NULL)))
{
hfree((void huge *) *z_prime);
hfree((void huge *) *y_prime);
hfree((void huge *) *x_prime);
for (y=0; y < num_y_dots; y++)
free((void *) (*page)[y]);
free((void *) (*page));
for (y=0; y < max_y_plus_1; y++)
free((void *) (*base_page)[y]);
free((void *) (*base_page));
}
}
if (result)
{
if (! (result=((*y_division_index
=(int huge *) halloc(num_primes,sizeof(int))) != NULL)))
{
hfree((void huge *) *x_division_index);
hfree((void huge *) *z_prime);
hfree((void huge *) *y_prime);
hfree((void huge *) *x_prime);
}
}
if (result)
{
if (! (result=((*color=(unsigned char huge *)
halloc(num_primes,sizeof(unsigned char))) != NULL)))
{
hfree((void huge *) *y_division_index);
hfree((void huge *) *x_division_index);
hfree((void huge *) *z_prime);
hfree((void huge *) *y_prime);
hfree((void huge *) *x_prime);
for (y=0; y < num_y_dots; y++)
free((void *) (*page)[y]);
free((void *) (*page));
for (y=0; y < max_y_plus_1; y++)
free((void *) (*base_page)[y]);
free((void *) (*base_page));
}
}
if (result)
{
if (! (result=((*base_z=(unsigned char huge *)
halloc(num_primes,sizeof(unsigned char))) != NULL)))
{
hfree((void huge *) *color);
hfree((void huge *) *y_division_index);
hfree((void huge *) *x_division_index);
hfree((void huge *) *z_prime);
hfree((void huge *) *y_prime);
hfree((void huge *) *x_prime);
for (y=0; y < num_y_dots; y++)
free((void *) (*page)[y]);
free((void *) (*page));
for (y=0; y < max_y_plus_1; y++)
free((void *) (*base_page)[y]);
free((void *) (*base_page));
}
}
if (result)
{
if (! (result=((*stack=(stack_rec *) malloc(
((unsigned int) num_rooms_in_maze)*sizeof(stack_rec)))
!= NULL)))
{
hfree((void *) *base_z);
hfree((void *) *color);
hfree((void *) *y_division_index);
hfree((void *) *x_division_index);
hfree((void *) *z_prime);
hfree((void *) *y_prime);
hfree((void *) *x_prime);
for (y=0; y < num_y_dots; y++)
free((void *) (*page)[y]);
free((void *) (*page));
for (y=0; y < max_y_plus_1; y++)
free((void *) (*base_page)[y]);
free((void *) (*base_page));
}
}
return(result);
}
static void set_point_on_page(
char **page,
int x,
int y)
{
static int x_offset = 0;
static int x_out = 0;
static int y_offset = 0;
static int y_out = 0;
for (x_offset = 0; x_offset < RESOLUTION; x_offset++)
{
x_out=x+x_offset;
for (y_offset=0; y_offset < RESOLUTION; y_offset++)
{
y_out=y+y_offset;
page[y_out][x_out]='W';
}
}
return;
}
static void draw_line_on_page(
char **page,
int x1,
int y1,
int x2,
int y2)
{
static int error = 0;
static int error_prime_x = 0;
static int error_prime_y = 0;
static int permissible_delta_x = 0;
static int permissible_delta_y = 0;
static int x = 0;
static int x_diff = 0;
static int y = 0;
static int y_diff = 0;
if (x2 >= x1)
permissible_delta_x=1;
else
permissible_delta_x=-1;
if (y2 >= y1)
permissible_delta_y=1;
else
permissible_delta_y=-1;
x=x1;
y=y1;
x_diff=x2-x1;
y_diff=y2-y1;
set_point_on_page(page,x,y);
while ((x != x2) || (y != y2))
{
error_prime_x=error+permissible_delta_x*y_diff;
error_prime_y=error-permissible_delta_y*x_diff;
if (abs(error_prime_x) <= abs(error_prime_y))
{
x+=permissible_delta_x;
error=error_prime_x;
}
else
{
y+=permissible_delta_y;
error=error_prime_y;
}
set_point_on_page(page,x,y);
}
return;
}
static void solve_maze(
stack_rec *stack,
char **base_page,
int *num_rooms_in_solution,
int *adjacency,
int max_x,
int max_y)
{
int delta_index;
int passage_found;
int stack_head;
int x;
int x_next;
int y;
int y_next;
*num_rooms_in_solution=1;
*adjacency=0;
x=3;
y=2;
stack_head=-1;
base_page[y][x]='S';
do
{
delta_index=0;
passage_found=FALSE;
do
{
while ((delta_index < 6) && (! passage_found))
{
x_next=x+delta_x[delta_index][0];
y_next=y+delta_y[delta_index][0];
if (base_page[y_next][x_next] == ' ')
passage_found=TRUE;
else
delta_index++;
}
if (! passage_found)
{
delta_index=(int) (stack[stack_head].index_1);
base_page[y][x]=' ';
x-=delta_x[delta_index][0];
y-=delta_y[delta_index][0];
base_page[y][x]=' ';
x-=delta_x[delta_index][0];
y-=delta_y[delta_index][0];
stack_head--;
delta_index++;
}
}
while (! passage_found);
base_page[y_next][x_next]='S';
x_next+=delta_x[delta_index][0];
y_next+=delta_y[delta_index][0];
if (y_next <= max_y)
{
stack_head++;
stack[stack_head].index_1=(char) delta_index;
base_page[y_next][x_next]='S';
x=x_next;
y=y_next;
}
}
while (y_next < max_y);
x=max_x-3;
y=max_y-2;
*adjacency=0;
while (stack_head >= 0)
{
for (delta_index=0; delta_index < 6; delta_index++)
{
x_next=x+delta_x[delta_index][0];
y_next=y+delta_y[delta_index][0];
if (base_page[y_next][x_next] != 'S')
{
if (base_page[y_next][x_next] == 'W')
{
x_next+=delta_x[delta_index][0];
y_next+=delta_y[delta_index][0];
if (x_next < 0)
(*adjacency)++;
else
if (x_next > max_x)
(*adjacency)++;
else
if (y_next < 0)
(*adjacency)++;
else
if (y_next > max_y)
(*adjacency)++;
else
{
if (base_page[y_next][x_next] == 'S')
(*adjacency)++;
}
}
}
}
x-=(2*delta_x[stack[stack_head].index_1][0]);
y-=(2*delta_y[stack[stack_head].index_1][0]);
stack_head--;
(*num_rooms_in_solution)++;
}
for (delta_index=0; delta_index < 6; delta_index++)
{
x_next=x+delta_x[delta_index][0];
y_next=y+delta_y[delta_index][0];
if (base_page[y_next][x_next] != ' ')
{
if (base_page[y_next][x_next] == 'W')
{
x_next+=delta_x[delta_index][0];
y_next+=delta_y[delta_index][0];
if (x_next < 0)
(*adjacency)++;
else
if (x_next > max_x)
(*adjacency)++;
else
if (y_next < 0)
(*adjacency)++;
else
if (y_next > max_y)
(*adjacency)++;
else
{
if (base_page[y_next][x_next] == 'S')
(*adjacency)++;
}
}
}
}
return;
}
static void generate_maze(
int *r_n,
char **base_page,
char **page,
int max_x,
int max_y,
stack_rec *stack,
int x_dot_max,
int y_dot_max,
int num_rooms_in_maze,
int num_columns,
int num_rows)
{
static int adjacency;
static int column_num;
static int counter_0;
static int counter_1;
static int counter_2;
static int counter_3;
static int counter_4;
static int counter_5;
static int counter_6;
static int counter_7;
static int delta_index_1a;
static int delta_index_1b;
static int delta_index_1c;
static int delta_index_1d;
static int delta_index_1e;
static int delta_index_1f;
static int delta_index_2;
static int num_rooms_in_solution;
static int passage_found;
register int r_n_index_1;
register int r_n_index_2;
static int row_num;
static int search_complete;
static char seed [256];
static int seed_length;
static int stack_head;
static int tem_int;
static int x;
static int x_mod_8;
static int x_next;
static int y;
static int y_mod_4;
static int y_next;
static int y_previous;
printf("\n Random number seed? ");
gets(&seed[0]);
get_cursor(&cursor_row,&cursor_column,&initial_cursor_type);
memcpy((void *) &titillator_cursor_type,
(const void *) &initial_cursor_type,sizeof(VIOCURSORINFO));
titillator_cursor_type.attr=0xffff;
set_cursor_type(&titillator_cursor_type);
titillator_index=0;
seed_length=strlen(&seed[0]);
for (r_n_index_1=0; ((r_n_index_1 < seed_length) && (r_n_index_1 < 8));
++r_n_index_1)
r_n[r_n_index_1]=(int) (seed[r_n_index_1] % 10);
r_n_index_2=7;
while (r_n_index_1 > 0)
{
r_n_index_1--;
r_n[r_n_index_2]=r_n[r_n_index_1];
r_n_index_2--;
}
while (r_n_index_2 >= 0)
{
r_n[r_n_index_2]=0;
r_n_index_2--;
}
counter_0=r_n[0];
counter_1=r_n[1];
counter_2=r_n[2];
counter_3=r_n[3];
counter_4=r_n[4];
counter_5=r_n[5];
counter_6=r_n[6];
counter_7=r_n[7];
hash(&counter_0,&counter_1,&counter_2,&counter_3,&counter_4,&counter_5,
&counter_6,&counter_7);
delta_y[0][0]=-1;
delta_x[0][0]=-2;
delta_y[1][0]=1;
delta_x[1][0]=-2;
delta_y[2][0]=-2;
delta_x[2][0]=0;
delta_y[3][0]=2;
delta_x[3][0]=0;
delta_y[4][0]=-1;
delta_x[4][0]=2;
delta_y[5][0]=1;
delta_x[5][0]=2;
delta_index_2=0;
for (delta_index_1a=0; delta_index_1a < 6; delta_index_1a++)
for (delta_index_1b=0; delta_index_1b < 6; delta_index_1b++)
if (delta_index_1a != delta_index_1b)
for (delta_index_1c=0; delta_index_1c < 6; delta_index_1c++)
if ((delta_index_1a != delta_index_1c)
&& (delta_index_1b != delta_index_1c))
for (delta_index_1d=0; delta_index_1d < 6; delta_index_1d++)
if ((delta_index_1a != delta_index_1d)
&& (delta_index_1b != delta_index_1d)
&& (delta_index_1c != delta_index_1d))
for (delta_index_1e=0; delta_index_1e < 6;
delta_index_1e++)
if ((delta_index_1a != delta_index_1e)
&& (delta_index_1b != delta_index_1e)
&& (delta_index_1c != delta_index_1e)
&& (delta_index_1d != delta_index_1e))
for (delta_index_1f=0; delta_index_1f < 6;
delta_index_1f++)
if ((delta_index_1a != delta_index_1f)
&& (delta_index_1b != delta_index_1f)
&& (delta_index_1c != delta_index_1f)
&& (delta_index_1d != delta_index_1f)
&& (delta_index_1e != delta_index_1f))
{
delta_x[delta_index_1a][delta_index_2]
=delta_x[0][0];
delta_y[delta_index_1a][delta_index_2]
=delta_y[0][0];
delta_x[delta_index_1b][delta_index_2]
=delta_x[1][0];
delta_y[delta_index_1b][delta_index_2]
=delta_y[1][0];
delta_x[delta_index_1c][delta_index_2]
=delta_x[2][0];
delta_y[delta_index_1c][delta_index_2]
=delta_y[2][0];
delta_x[delta_index_1d][delta_index_2]
=delta_x[3][0];
delta_y[delta_index_1d][delta_index_2]
=delta_y[3][0];
delta_x[delta_index_1e][delta_index_2]
=delta_x[4][0];
delta_y[delta_index_1e][delta_index_2]
=delta_y[4][0];
delta_x[delta_index_1f][delta_index_2]
=delta_x[5][0];
delta_y[delta_index_1f][delta_index_2]
=delta_y[5][0];
delta_index_2++;
};
do
{
titillate();
r_n[0]=counter_0+1;
r_n[1]=counter_1+1;
r_n[2]=counter_2+1;
r_n[3]=counter_3+1;
r_n[4]=counter_4+1;
r_n[5]=counter_5+1;
r_n[6]=counter_6+1;
r_n[7]=counter_7+1;
y_mod_4=1;
for (y=0; y <= max_y; y++)
{
if (y_mod_4 == 1)
{
x_mod_8=1;
for (x=0; x <= max_x; x++)
{
if (((x_mod_8 == 0)
&& (y != 0)
&& (y != max_y))
|| (x_mod_8 == 3)
|| (x_mod_8 == 4)
|| (x_mod_8 == 5))
base_page[y][x]='W';
else
base_page[y][x]=' ';
x_mod_8++;
if (x_mod_8 >= 8)
x_mod_8=0;
}
}
else
{
if (y_mod_4 == 0 || y_mod_4 == 2)
{
x_mod_8=1;
for (x=0; x <= max_x; x++)
{
if ((x_mod_8 == 2) || (x_mod_8 == 6))
base_page[y][x]='W';
else
base_page[y][x]=' ';
x_mod_8++;
if (x_mod_8 >= 8)
x_mod_8 = 0;
}
}
else
{
x_mod_8=1;
for (x=0; x <= max_x; x++)
{
if ((x_mod_8 == 0)
|| (x_mod_8 == 1)
|| (x_mod_8 == 4)
|| (x_mod_8 == 7))
base_page[y][x]='W';
else
base_page[y][x]=' ';
x_mod_8++;
if (x_mod_8 >= 8)
x_mod_8=0;
}
}
}
y_mod_4++;
if (y_mod_4 >= 4)
y_mod_4=0;
}
column_num=r_n[0];
r_n_index_1=0;
r_n_index_2=1;
while (r_n_index_2 < 8)
{
tem_int=r_n[r_n_index_2];
r_n[r_n_index_1]=tem_int;
column_num+=tem_int;
if (column_num >= 727)
column_num-=727;
r_n_index_1=r_n_index_2;
r_n_index_2++;
}
r_n[7]=column_num;
column_num%=num_columns;
x=4*column_num+3;
row_num=r_n[0];
r_n_index_1=0;
r_n_index_2=1;
while (r_n_index_2 < 8)
{
tem_int=r_n[r_n_index_2];
r_n[r_n_index_1]=tem_int;
row_num+=tem_int;
if (row_num >= 727)
row_num-=727;
r_n_index_1=r_n_index_2;
r_n_index_2++;
}
r_n[7]=row_num;
if (column_num%2)
{
row_num%=(num_rows-1);
y=4*row_num+4;
}
else
{
row_num%=num_rows;
y=4*row_num+2;
}
base_page[y][x]=' ';
stack_head=-1;
do
{
delta_index_1a=0;
do
{
delta_index_2=r_n[0];
r_n_index_1=0;
r_n_index_2=1;
while (r_n_index_2 < 8)
{
tem_int=r_n[r_n_index_2];
r_n[r_n_index_1]=tem_int;
delta_index_2+=tem_int;
if (delta_index_2 >= 727)
delta_index_2-=727;
r_n_index_1=r_n_index_2;
r_n_index_2++;
}
r_n[7]=delta_index_2;
}
while (delta_index_2 >= 720);
passage_found=FALSE;
search_complete=FALSE;
while (! search_complete)
{
while ((delta_index_1a < 6) && (! passage_found))
{
x_next=x+2*delta_x[delta_index_1a][delta_index_2];
if (x_next <= 0)
delta_index_1a++;
else
if (x_next > max_x)
delta_index_1a++;
else
{
y_next=y+2*delta_y[delta_index_1a][delta_index_2];
if (y_next <= 0)
delta_index_1a++;
else
if (y_next > max_y)
delta_index_1a++;
else
if (base_page[y_next][x_next] == 'W')
passage_found=TRUE;
else
delta_index_1a++;
}
}
if (! passage_found)
{
if (stack_head >= 0)
{
delta_index_1a=(int) (stack[stack_head].index_1);
delta_index_2=stack[stack_head].index_2;
x-=2*delta_x[delta_index_1a][delta_index_2];
y-=2*delta_y[delta_index_1a][delta_index_2];
stack_head--;
delta_index_1a++;
}
}
search_complete=((passage_found)
|| ((stack_head == -1) && (delta_index_1a >= 6)));
}
if (passage_found)
{
stack_head++;
stack[stack_head].index_1=(char) delta_index_1a;
stack[stack_head].index_2=delta_index_2;
base_page[y_next][x_next]=' ';
base_page[(y+y_next)/2][(x+x_next)/2]=' ';
x=x_next;
y=y_next;
}
}
while (stack_head != -1);
base_page[0][3]='S';
base_page[max_y][max_x-3]=' ';
solve_maze(stack,base_page,&num_rooms_in_solution,&adjacency,max_x,
max_y);
increment(&counter_0,&counter_1,&counter_2,&counter_3,&counter_4,
&counter_5,&counter_6,&counter_7);
}
while ((3*num_rooms_in_solution < num_rooms_in_maze)
|| (2*adjacency > 3*num_rooms_in_solution));
for (x = 0; x <= x_dot_max; x++)
for (y = 0; y <= y_dot_max; y++)
page[y][x]=' ';
y_previous=-1;
y_next=1;
for (y = 0; y <= max_y; y++)
{
x=0;
for (x_next = 1; x_next <= max_x; x_next++)
{
if (base_page[y][x] == 'W')
{
if (base_page[y][x_next] == 'W')
draw_line_on_page(page,RESOLUTION*x,RESOLUTION*y,
RESOLUTION*x_next,RESOLUTION*y);
if (y_previous >= 0)
{
if (base_page[y_previous][x_next] == 'W')
draw_line_on_page(page,RESOLUTION*x,RESOLUTION*y,
RESOLUTION*x_next,RESOLUTION*y_previous);
}
if (y_next <= max_y)
{
if (base_page[y_next][x_next] == 'W')
draw_line_on_page(page,RESOLUTION*x,RESOLUTION*y,
RESOLUTION*x_next,RESOLUTION*y_next);
}
}
x=x_next;
}
y_previous=y;
y_next++;
}
return;
}
static int substitution_high [100] =
{ 4,1,2,8,8,9,9,6,5,7,2,1,2,9,8,8,6,3,5,1,9,5,4,4,9,8,6,0,8,0,
6,0,2,4,1,9,2,0,7,4,7,3,0,0,2,6,8,9,4,0,8,3,2,3,2,5,2,4,6,9,
7,9,1,3,5,7,1,1,4,5,8,1,6,0,5,7,8,2,3,3,7,3,5,1,7,5,4,0,3,6,
3,7,7,1,9,4,0,5,6,6
};
static int substitution_low [100] =
{ 1,2,2,1,5,5,4,6,4,6,4,4,5,6,6,3,0,9,6,5,7,2,0,9,3,4,2,3,9,1,
9,9,9,3,8,9,3,4,1,5,0,5,2,7,0,8,8,0,4,5,0,3,6,8,1,7,8,8,7,1,
3,2,7,7,1,8,0,3,7,5,2,6,4,0,9,9,7,7,4,6,2,0,0,1,7,3,6,6,1,1,
2,4,5,9,8,2,8,8,3,5
};
static void hash(counter_0,counter_1,counter_2,counter_3,counter_4,counter_5,
counter_6,counter_7)
int *counter_0;
int *counter_1;
int *counter_2;
int *counter_3;
int *counter_4;
int *counter_5;
int *counter_6;
int *counter_7;
{
register int iteration;
static int seed_0;
static int seed_1;
static int seed_2;
static int seed_3;
static int seed_4;
static int seed_5;
static int seed_6;
static int seed_7;
register int substitution_index;
static int tem_0;
static int tem_1;
static int tem_2;
seed_0=(*counter_0);
seed_1=(*counter_1);
seed_2=(*counter_2);
seed_3=(*counter_3);
seed_4=(*counter_4);
seed_5=(*counter_5);
seed_6=(*counter_6);
seed_7=(*counter_7);
for (iteration=1; iteration <= 8; iteration++)
{
substitution_index=10*seed_1+seed_0;
tem_0=substitution_low[substitution_index];
tem_1=substitution_high[substitution_index];
substitution_index=10*seed_3+seed_2;
seed_0=substitution_low[substitution_index];
tem_2=substitution_high[substitution_index];
substitution_index=10*seed_5+seed_4;
seed_2=substitution_low[substitution_index];
seed_1=substitution_high[substitution_index];
substitution_index=10*seed_7+seed_6;
seed_5=substitution_low[substitution_index];
seed_7=substitution_high[substitution_index];
seed_3=tem_0;
seed_6=tem_1;
seed_4=tem_2;
}
(*counter_0)=seed_0;
(*counter_1)=seed_1;
(*counter_2)=seed_2;
(*counter_3)=seed_3;
(*counter_4)=seed_4;
(*counter_5)=seed_5;
(*counter_6)=seed_6;
(*counter_7)=seed_7;
return;
}
static void increment(counter_0,counter_1,counter_2,counter_3,counter_4,
counter_5,counter_6,counter_7)
int *counter_0;
int *counter_1;
int *counter_2;
int *counter_3;
int *counter_4;
int *counter_5;
int *counter_6;
int *counter_7;
{
register tem;
tem=(*counter_0)+1;
if (tem <= 9)
(*counter_0)=tem;
else
{
(*counter_0)=0;
tem=(*counter_1)+1;
if (tem <= 9)
(*counter_1)=tem;
else
{
(*counter_1)=0;
tem=(*counter_2)+1;
if (tem <= 9)
(*counter_2)=tem;
else
{
(*counter_2)=0;
tem=(*counter_3)+1;
if (tem <= 9)
(*counter_3)=tem;
else
{
(*counter_3)=0;
tem=(*counter_4)+1;
if (tem <= 9)
(*counter_4)=tem;
else
{
(*counter_4)=0;
tem=(*counter_5)+1;
if (tem <= 9)
(*counter_5)=tem;
else
{
(*counter_5)=0;
tem=(*counter_6)+1;
if (tem <= 9)
(*counter_6)=tem;
else
{
(*counter_6)=0;
tem=(*counter_7)+1;
if (tem <= 9)
(*counter_7)=tem;
else
(*counter_7)=0;
}
}
}
}
}
}
}
return;
}
static void evaluate_and_transform(x_min,x_max,y_min,y_max,num_x_divisions,
num_y_divisions,rotation,tilt,x_prime,y_prime,z_prime,x_prime_max,y_prime_min,
y_prime_max,z_prime_min,z_prime_max,light,x_division_index,y_division_index,
base_z)
double x_min;
double x_max;
double y_min;
double y_max;
int num_x_divisions;
int num_y_divisions;
double rotation;
double tilt;
float huge *x_prime;
float huge *y_prime;
float huge *z_prime;
double *x_prime_max;
double *y_prime_min;
double *y_prime_max;
double *z_prime_min;
double *z_prime_max;
vertex_rec *light;
int huge *x_division_index;
int huge *y_division_index;
unsigned char huge *base_z;
{
static double cos_rotation;
static double cos_tilt;
static double magnitude;
static long prime_num;
static double radians;
static double radians_per_degree;
static double sin_rotation;
static double sin_tilt;
static double x;
static double x_delta;
register int x_division_num;
static double x_rotated;
static double y;
static double y_delta;
register int y_division_num;
static double z;
radians_per_degree=atan(1.0)/45.0;
radians=tilt*radians_per_degree;
cos_tilt=cos(radians);
sin_tilt=sin(radians);
radians=rotation*radians_per_degree;
cos_rotation=cos(radians);
sin_rotation=sin(radians);
z=fabs(f(x_min,y_min));
x_rotated=x_min*cos_rotation+y_min*sin_rotation;
*y_prime_min=-x_min*sin_rotation+y_min*cos_rotation;
*z_prime_min=-x_rotated*sin_tilt+z*cos_tilt;
*y_prime_max=*y_prime_min;
*z_prime_max=*z_prime_min;
*x_prime_max=x_rotated*cos_tilt+z*sin_tilt;
x_delta=(double) (num_x_divisions-1);
x_delta=(x_max-x_min)/x_delta;
y_delta=(double) (num_y_divisions-1);
y_delta=(y_max-y_min)/y_delta;
x=x_min;
prime_num=0l;
for (x_division_num=0; x_division_num < num_x_divisions; x_division_num++)
{
titillate();
y=y_min;
for (y_division_num=0; y_division_num < num_y_divisions;
y_division_num++)
{
z=f(x,y);
if (z > 0.0)
base_z[prime_num]=(unsigned char) 1;
else
if (z < 0.0)
base_z[prime_num]=(unsigned char) 2;
else
base_z[prime_num]=(unsigned char) 0;
z=fabs(z);
x_division_index[prime_num]=x_division_num;
y_division_index[prime_num]=y_division_num;
x_rotated=x*cos_rotation+y*sin_rotation;
y_prime[prime_num]=(float) (-x*sin_rotation+y*cos_rotation);
x_prime[prime_num]=(float) (x_rotated*cos_tilt+z*sin_tilt);
z_prime[prime_num]=(float) (-x_rotated*sin_tilt+z*cos_tilt);
if (((double) (x_prime[prime_num])) > *x_prime_max)
*x_prime_max=(double) (x_prime[prime_num]);
if (((double) (y_prime[prime_num])) < *y_prime_min)
*y_prime_min=(double) (y_prime[prime_num]);
if (((double) (y_prime[prime_num])) > *y_prime_max)
*y_prime_max=(double) (y_prime[prime_num]);
if (((double) (z_prime[prime_num])) < *z_prime_min)
*z_prime_min=(double) (z_prime[prime_num]);
if (((double) (z_prime[prime_num])) > *z_prime_max)
*z_prime_max=(double) (z_prime[prime_num]);
y+=y_delta;
prime_num++;
}
x+=x_delta;
}
magnitude=(*light).x*(*light).x;
magnitude+=((*light).y*(*light).y);
magnitude+=((*light).z*(*light).z);
magnitude=sqrt(magnitude);
(*light).x/=magnitude;
(*light).y/=magnitude;
(*light).z/=magnitude;
return;
}
static void shade(num_x_divisions,num_y_divisions,x_prime,y_prime,z_prime,color,
light)
int num_x_divisions;
int num_y_divisions;
float huge *x_prime;
float huge *y_prime;
float huge *z_prime;
unsigned char huge *color;
vertex_rec *light;
{
static double magnitude;
static vertex_rec normal;
static long prime_num;
static vertex_rec vertex [4];
register int x_division_num;
register int y_division_num;
prime_num=0l;
for (x_division_num=0; x_division_num < num_x_divisions;
x_division_num++)
{
titillate();
for (y_division_num=0; y_division_num < num_y_divisions;
y_division_num++)
{
vertex[0].x=(double) (x_prime[prime_num]);
vertex[0].y=(double) (y_prime[prime_num]);
vertex[0].z=(double) (z_prime[prime_num]);
if (x_division_num < (num_x_divisions-1))
if (y_division_num < (num_y_divisions-1))
{
prime_num+=((long) num_y_divisions);
vertex[1].x=(double) (x_prime[prime_num]);
vertex[1].y=(double) (y_prime[prime_num]);
vertex[1].z=(double) (z_prime[prime_num]);
prime_num++;
vertex[2].x=(double) (x_prime[prime_num]);
vertex[2].y=(double) (y_prime[prime_num]);
vertex[2].z=(double) (z_prime[prime_num]);
prime_num-=((long) num_y_divisions);
vertex[3].x=(double) (x_prime[prime_num]);
vertex[3].y=(double) (y_prime[prime_num]);
vertex[3].z=(double) (z_prime[prime_num]);
prime_num--;
}
else
{
prime_num--;
vertex[1].x=(double) (x_prime[prime_num]);
vertex[1].y=(double) (y_prime[prime_num]);
vertex[1].z=(double) (z_prime[prime_num]);
prime_num+=((long) num_y_divisions);
vertex[2].x=(double) (x_prime[prime_num]);
vertex[2].y=(double) (y_prime[prime_num]);
vertex[2].z=(double) (z_prime[prime_num]);
prime_num++;
vertex[3].x=(double) (x_prime[prime_num]);
vertex[3].y=(double) (y_prime[prime_num]);
vertex[3].z=(double) (z_prime[prime_num]);
prime_num-=((long) num_y_divisions);
}
else
if (y_division_num < (num_y_divisions-1))
{
prime_num++;
vertex[1].x=(double) (x_prime[prime_num]);
vertex[1].y=(double) (y_prime[prime_num]);
vertex[1].z=(double) (z_prime[prime_num]);
prime_num-=((long) num_y_divisions);
vertex[2].x=(double) (x_prime[prime_num]);
vertex[2].y=(double) (y_prime[prime_num]);
vertex[2].z=(double) (z_prime[prime_num]);
prime_num--;
vertex[3].x=(double) (x_prime[prime_num]);
vertex[3].y=(double) (y_prime[prime_num]);
vertex[3].z=(double) (z_prime[prime_num]);
prime_num+=((long) num_y_divisions);
}
else
{
prime_num-=((long) num_y_divisions);
vertex[1].x=(double) (x_prime[prime_num]);
vertex[1].y=(double) (y_prime[prime_num]);
vertex[1].z=(double) (z_prime[prime_num]);
prime_num--;
vertex[2].x=(double) (x_prime[prime_num]);
vertex[2].y=(double) (y_prime[prime_num]);
vertex[2].z=(double) (z_prime[prime_num]);
prime_num+=((long) num_y_divisions);
vertex[3].x=(double) (x_prime[prime_num]);
vertex[3].y=(double) (y_prime[prime_num]);
vertex[3].z=(double) (z_prime[prime_num]);
prime_num++;
}
normal.x
=(vertex[1].y-vertex[0].y)*(vertex[3].z-vertex[0].z)
-(vertex[3].y-vertex[0].y)*(vertex[1].z-vertex[0].z)
+(vertex[2].y-vertex[1].y)*(vertex[0].z-vertex[1].z)
-(vertex[0].y-vertex[1].y)*(vertex[2].z-vertex[1].z)
+(vertex[3].y-vertex[2].y)*(vertex[1].z-vertex[2].z)
-(vertex[1].y-vertex[2].y)*(vertex[3].z-vertex[2].z)
+(vertex[0].y-vertex[3].y)*(vertex[2].z-vertex[3].z)
-(vertex[2].y-vertex[3].y)*(vertex[0].z-vertex[3].z);
normal.y
=(vertex[3].x-vertex[0].x)*(vertex[1].z-vertex[0].z)
-(vertex[1].x-vertex[0].x)*(vertex[3].z-vertex[0].z)
+(vertex[0].x-vertex[1].x)*(vertex[2].z-vertex[1].z)
-(vertex[2].x-vertex[1].x)*(vertex[0].z-vertex[1].z)
+(vertex[1].x-vertex[2].x)*(vertex[3].z-vertex[2].z)
-(vertex[3].x-vertex[2].x)*(vertex[1].z-vertex[2].z)
+(vertex[2].x-vertex[3].x)*(vertex[0].z-vertex[3].z)
-(vertex[0].x-vertex[3].x)*(vertex[2].z-vertex[3].z);
normal.z
=(vertex[1].x-vertex[0].x)*(vertex[3].y-vertex[0].y)
-(vertex[3].x-vertex[0].x)*(vertex[1].y-vertex[0].y)
+(vertex[2].x-vertex[1].x)*(vertex[0].y-vertex[1].y)
-(vertex[0].x-vertex[1].x)*(vertex[2].y-vertex[1].y)
+(vertex[3].x-vertex[2].x)*(vertex[1].y-vertex[2].y)
-(vertex[1].x-vertex[2].x)*(vertex[3].y-vertex[2].y)
+(vertex[0].x-vertex[3].x)*(vertex[2].y-vertex[3].y)
-(vertex[2].x-vertex[3].x)*(vertex[0].y-vertex[3].y);
if (normal.x < 0.0)
color[prime_num]=NUM_COLORS;
else
{
magnitude
=sqrt(normal.x*normal.x+normal.y*normal.y+normal.z*normal.z);
if (magnitude == 0.0)
color[prime_num]=(unsigned char) 0;
else
{
color[prime_num]
=(unsigned char) ((((float) (NUM_COLORS-1))/2.0)*(1.0
+((*light).x*normal.x+(*light).y*normal.y
+(*light).z*normal.z)/magnitude));
if (color[prime_num] >= (unsigned char) (NUM_COLORS-1))
color[prime_num]=(unsigned char) (NUM_COLORS-2);
}
}
prime_num++;
}
}
return;
}
static void adjust_perspective(num_x_divisions,num_y_divisions,x_prime,y_prime,
z_prime,x_prime_max,y_prime_min,y_prime_max,z_prime_min,z_prime_max)
int num_x_divisions;
int num_y_divisions;
float huge *x_prime;
float huge *y_prime;
float huge *z_prime;
double x_prime_max;
double y_prime_min;
double y_prime_max;
double z_prime_min;
double z_prime_max;
{
static long prime_num;
static vertex_rec vertex [4];
register int x_division_num;
static double x_eye;
static double y_center;
register int y_division_num;
static double z_center;
if ((y_prime_max-y_prime_min) > (z_prime_max-z_prime_min))
x_eye=1.1*(y_prime_max-y_prime_min)+x_prime_max;
else
x_eye=1.1*(z_prime_max-z_prime_min)+x_prime_max;
if (((y_prime_max-y_prime_min) > (z_prime_max-z_prime_min))
|| (z_prime_max != z_prime_min))
{
y_center=(y_prime_max+y_prime_min)/2.0;
z_center=(z_prime_max+z_prime_min)/2.0;
prime_num=0l;
for (x_division_num=0; x_division_num < num_x_divisions;
x_division_num++)
{
titillate();
for (y_division_num=0; y_division_num < num_y_divisions;
y_division_num++)
{
vertex[0].x=(double) (x_prime[prime_num]);
vertex[0].y=(double) (y_prime[prime_num]);
vertex[0].z=(double) (z_prime[prime_num]);
if (x_division_num < (num_x_divisions-1))
if (y_division_num < (num_y_divisions-1))
{
prime_num+=((long) num_y_divisions);
vertex[1].x=(double) (x_prime[prime_num]);
vertex[1].y=(double) (y_prime[prime_num]);
vertex[1].z=(double) (z_prime[prime_num]);
prime_num++;
vertex[2].x=(double) (x_prime[prime_num]);
vertex[2].y=(double) (y_prime[prime_num]);
vertex[2].z=(double) (z_prime[prime_num]);
prime_num-=((long) num_y_divisions);
vertex[3].x=(double) (x_prime[prime_num]);
vertex[3].y=(double) (y_prime[prime_num]);
vertex[3].z=(double) (z_prime[prime_num]);
prime_num--;
}
else
{
prime_num--;
vertex[1].x=(double) (x_prime[prime_num]);
vertex[1].y=(double) (y_prime[prime_num]);
vertex[1].z=(double) (z_prime[prime_num]);
prime_num+=((long) num_y_divisions);
vertex[2].x=(double) (x_prime[prime_num]);
vertex[2].y=(double) (y_prime[prime_num]);
vertex[2].z=(double) (z_prime[prime_num]);
prime_num++;
vertex[3].x=(double) (x_prime[prime_num]);
vertex[3].y=(double) (y_prime[prime_num]);
vertex[3].z=(double) (z_prime[prime_num]);
prime_num-=((long) num_y_divisions);
}
else
if (y_division_num < (num_y_divisions-1))
{
prime_num++;
vertex[1].x=(double) (x_prime[prime_num]);
vertex[1].y=(double) (y_prime[prime_num]);
vertex[1].z=(double) (z_prime[prime_num]);
prime_num-=((long) num_y_divisions);
vertex[2].x=(double) (x_prime[prime_num]);
vertex[2].y=(double) (y_prime[prime_num]);
vertex[2].z=(double) (z_prime[prime_num]);
prime_num--;
vertex[3].x=(double) (x_prime[prime_num]);
vertex[3].y=(double) (y_prime[prime_num]);
vertex[3].z=(double) (z_prime[prime_num]);
prime_num+=((long) num_y_divisions);
}
else
{
prime_num-=((long) num_y_divisions);
vertex[1].x=(double) (x_prime[prime_num]);
vertex[1].y=(double) (y_prime[prime_num]);
vertex[1].z=(double) (z_prime[prime_num]);
prime_num--;
vertex[2].x=(double) (x_prime[prime_num]);
vertex[2].y=(double) (y_prime[prime_num]);
vertex[2].z=(double) (z_prime[prime_num]);
prime_num+=((long) num_y_divisions);
vertex[3].x=(double) (x_prime[prime_num]);
vertex[3].y=(double) (y_prime[prime_num]);
vertex[3].z=(double) (z_prime[prime_num]);
prime_num++;
}
y_prime[prime_num]=(float) y_center
+(vertex[0].y-y_center)*(x_eye-x_prime_max)
/(x_eye-vertex[0].x);
z_prime[prime_num]=(float) z_center
+(vertex[0].z-z_center)*(x_eye-x_prime_max)
/(x_eye-vertex[0].x);
x_prime[prime_num]=(float)
(-(vertex[0].x+vertex[1].x+vertex[2].x+vertex[3].x)/4.0);
prime_num++;
}
}
}
return;
}
static void sort_back_to_front(num_primes,x_prime,x_division_index,
y_division_index)
long num_primes;
float huge *x_prime;
int huge *x_division_index;
int huge *y_division_index;
{
static int finished;
static long key_index_1;
static long key_index_2;
static long left;
static long right;
static float t1;
register int t2;
register int t3;
left=num_primes/((long) 2);
right=num_primes-1l;
t1=x_prime[0];
t2=x_division_index[0];
t3=y_division_index[0];
while (right > 0l)
{
titillate();
if (left > 0l)
{
left--;
t1=x_prime[left];
t2=x_division_index[left];
t3=y_division_index[left];
}
else
{
t1=x_prime[right];
t2=x_division_index[right];
t3=y_division_index[right];
x_prime[right]=x_prime[0];
x_division_index[right]=x_division_index[0];
y_division_index[right]=y_division_index[0];
right--;
}
if (right > 0l)
{
finished=FALSE;
key_index_2=left;
while (! finished)
{
key_index_1=key_index_2;
key_index_2+=key_index_2;
key_index_2++;
if (key_index_2 > right)
finished=TRUE;
else
{
if (key_index_2 != right)
{
if (x_prime[key_index_2] > x_prime[key_index_2+1])
key_index_2++;
}
if (t1 <= x_prime[key_index_2])
finished=TRUE;
else
{
x_prime[key_index_1]=x_prime[key_index_2];
x_division_index[key_index_1]
=x_division_index[key_index_2];
y_division_index[key_index_1]
=y_division_index[key_index_2];
}
}
}
x_prime[key_index_1]=t1;
x_division_index[key_index_1]=t2;
y_division_index[key_index_1]=t3;
}
}
x_prime[0]=t1;
x_division_index[0]=t2;
y_division_index[0]=t3;
return;
}
static void plot(num_x_divisions,x_division_index,num_y_divisions,
y_division_index,num_primes,y_prime,z_prime,y_prime_min,y_prime_max,z_prime_min,
z_prime_max,color,base_z,solve,aspect_ratio)
int num_x_divisions;
int huge *x_division_index;
int num_y_divisions;
int huge *y_division_index;
long num_primes;
float huge *y_prime;
float huge *z_prime;
double y_prime_min;
double y_prime_max;
double z_prime_min;
double z_prime_max;
unsigned char huge *color;
unsigned char huge *base_z;
int solve;
double aspect_ratio;
{
static double box_delta_x;
static double box_delta_y;
static box_rec box [4];
static int box_num_1;
static int box_num_2;
static double box_x_intercept;
static int box_x1;
static int box_x2;
static int box_y_max;
static int box_y_min;
static double box_y_offset;
static int box_y1;
static short color_num;
static int intercept_count_mod_2;
register int line_x1;
register int line_x2;
static double pixels_per_unit;
static long prime_num;
static int solution;
static vertex_rec vertex [4];
static int x_division_num;
static long x_prime_num;
static int y_division_num;
static double y_offset;
static double y_out_max;
static double z_offset;
static double z_out_max;
aspect_ratio=(HEIGHT_OF_SCREEN/WIDTH_OF_SCREEN)
/(((double) NUM_Y_PIXELS)/((double) NUM_X_PIXELS));
y_out_max=(double) (NUM_X_PIXELS-1);
z_out_max=(double) (NUM_Y_PIXELS-1);
if (aspect_ratio*z_out_max*(y_prime_max-y_prime_min)
> y_out_max*(z_prime_max-z_prime_min))
{
pixels_per_unit
=y_out_max/(aspect_ratio*(y_prime_max-y_prime_min));
y_offset=0.0;
z_offset
=-(z_out_max-pixels_per_unit*(z_prime_max-z_prime_min))/2.0;
}
else
if (aspect_ratio*z_out_max*(y_prime_max-y_prime_min)
< y_out_max*(z_prime_max-z_prime_min))
{
pixels_per_unit=z_out_max/(z_prime_max-z_prime_min);
y_offset=(y_out_max
-aspect_ratio*pixels_per_unit*(y_prime_max-y_prime_min))/2.0;
z_offset=0.0;
}
else
{
pixels_per_unit=1.0;
y_offset=y_out_max/2.0;
z_offset=-z_out_max/2.0;
};
for (x_prime_num=0l; x_prime_num < num_primes; x_prime_num++)
{
x_division_num=x_division_index[x_prime_num];
if (x_division_num < (num_x_divisions-1))
{
y_division_num=y_division_index[x_prime_num];
if (y_division_num < (num_y_divisions-1))
{
prime_num
=((long) num_y_divisions)*((long) x_division_num)
+((long) y_division_num);
color_num=(short) (color[prime_num]);
if (color_num < NUM_COLORS)
{
vertex[0].y=(double) (y_prime[prime_num]);
vertex[0].z=(double) (z_prime[prime_num]);
solution=(base_z[prime_num] == (unsigned char) 2);
prime_num+=((long) num_y_divisions);
vertex[1].y=(double) (y_prime[prime_num]);
vertex[1].z=(double) (z_prime[prime_num]);
if (solution)
solution=(base_z[prime_num] == (unsigned char) 2);
prime_num++;
vertex[2].y=(double) (y_prime[prime_num]);
vertex[2].z=(double) (z_prime[prime_num]);
if (solution)
solution=(base_z[prime_num] == (unsigned char) 2);
prime_num-=((long) num_y_divisions);
vertex[3].y=(double) (y_prime[prime_num]);
vertex[3].z=(double) (z_prime[prime_num]);
if (solution)
solution=(base_z[prime_num] == (unsigned char) 2);
if ((! solve) || (solution))
{
if (solve)
color_num=(short) (NUM_COLORS-1);
for (box_num_1=0; box_num_1 < 4; box_num_1++)
{
box[box_num_1].x=(int) (y_offset
+pixels_per_unit*aspect_ratio
*(vertex[box_num_1].y-y_prime_min));
box[box_num_1].y=(int) (z_offset+z_out_max
-pixels_per_unit
*(vertex[box_num_1].z-z_prime_min));
}
box_y_min=box[0].y;
box_y_max=box_y_min;
for (box_num_1=1; box_num_1 < 4; box_num_1++)
{
if (box[box_num_1].y < box_y_min)
box_y_min=box[box_num_1].y;
if (box[box_num_1].y > box_y_max)
box_y_max=box[box_num_1].y;
}
for (box_y1=box_y_min; box_y1 <= box_y_max; ++box_y1)
{
intercept_count_mod_2=0;
box_num_2=1;
for (box_num_1=0; box_num_1 < 4; ++box_num_1)
{
if (box[box_num_1].y >= box_y1)
{
if (box_y1 > box[box_num_2].y)
{
box_delta_y=(double)
(box[box_num_2].y-box[box_num_1].y);
box_delta_x=(double)
(box[box_num_2].x-box[box_num_1].x);
box_y_offset=(double)
(box_y1-box[box_num_1].y);
box_x_intercept
=(double) (box[box_num_1].x);
box_x1
=(int) ((box_delta_x*box_y_offset)
/box_delta_y+box_x_intercept);
if (intercept_count_mod_2 == 0)
box_x2=box_x1;
else
{
if (box_x1 < box_x2)
{
line_x1=box_x1;
line_x2=box_x2;
}
else
{
line_x1=box_x2;
line_x2=box_x1;
}
set_pixel(line_x1,box_y1,
color_num);
while (line_x1 < line_x2)
{
line_x1++;
set_pixel(line_x1,box_y1,
color_num);
}
}
intercept_count_mod_2
=1-intercept_count_mod_2;
}
}
else
{
if (box_y1 <= box[box_num_2].y)
{
box_delta_y=(double)
(box[box_num_2].y-box[box_num_1].y);
box_delta_x=(double)
(box[box_num_2].x-box[box_num_1].x);
box_y_offset=(double)
(box_y1-box[box_num_1].y);
box_x_intercept
=(double) (box[box_num_1].x);
box_x1
=(int) ((box_delta_x*box_y_offset)
/box_delta_y+box_x_intercept);
if (intercept_count_mod_2 == 0)
box_x2=box_x1;
else
{
if (box_x1 < box_x2)
{
line_x1=box_x1;
line_x2=box_x2;
}
else
{
line_x1=box_x2;
line_x2=box_x1;
}
set_pixel(line_x1,box_y1,
color_num);
while (line_x1 < line_x2)
{
line_x1++;
set_pixel(line_x1,box_y1,
color_num);
}
}
intercept_count_mod_2
=1-intercept_count_mod_2;
}
}
box_num_2++;
if (box_num_2 >= 4)
box_num_2=0;
}
}
}
}
}
}
}
return;
}
static double f(
double x,
double y)
{
static int base_x = 0;
static int base_y = 0;
static int solution = 0;
register int x_next = 0;
static int x_offset = 0;
static int x_out = 0;
register int y_next = 0;
static int y_offset = 0;
static int y_out = 0;
static double z = 0.0;
y_out=(int) x;
if (y_out < 0)
z=0.0;
else
if (y_out > y_dot_max)
z=0.0;
else
{
x_out=(int) y;
if (x_out < 0)
z=0.0;
else
if (x_out > x_dot_max)
z=0.0;
else
if (page[y_out][x_out] == 'W')
{
solution=FALSE;
base_x=x_out/RESOLUTION;
base_y=y_out/RESOLUTION;
for (y_offset=-4; ((! solution) && (y_offset <= 4));
y_offset++)
for (x_offset=-4; ((! solution) && (x_offset <= 4));
x_offset++)
if (abs(x_offset)+abs(y_offset) <= 4)
{
y_next=base_y+y_offset;
if ((y_next >= 0) && (y_next <= max_y))
{
x_next=base_x+x_offset;
if ((x_next >= 0) && (x_next <= max_x))
{
if (base_page[y_next][x_next] == 'S')
solution=TRUE;
}
}
};
z=((double) (5*RESOLUTION));
if (solution)
z=-z;
}
else
z=0.0;
}
return(z);
}
static void free_memory(x_prime,y_prime,z_prime,x_division_index,
y_division_index,color,base_z,max_y_plus_1,base_page,num_y_dots,page,
num_rooms_in_maze,stack)
float huge **x_prime;
float huge **y_prime;
float huge **z_prime;
int huge **x_division_index;
int huge **y_division_index;
unsigned char huge **color;
unsigned char huge **base_z;
int max_y_plus_1;
char ***base_page;
int num_y_dots;
char ***page;
int num_rooms_in_maze;
stack_rec **stack;
{
register int y;
hfree((void huge *) *base_z);
hfree((void huge *) *color);
hfree((void huge *) *y_division_index);
hfree((void huge *) *x_division_index);
hfree((void huge *) *z_prime);
hfree((void huge *) *y_prime);
hfree((void huge *) *x_prime);
for (y=0; y < num_y_dots; y++)
free((void *) (*page)[y]);
free((void *) (*page));
for (y=0; y < max_y_plus_1; y++)
free((void *) (*base_page)[y]);
free((void *) (*base_page));
free((void *) *stack);
return;
}
static int VGA_640_480_16()
{
static char *buffer;
static USHORT cell_num;
static int color_num;
static int plane_num;
static int result;
static unsigned char tint;
/* Allocate memory to save screen when it's switched. */
result=TRUE;
for (plane_num=0; ((result) && (plane_num < 4)); plane_num++)
result=((video_plane[plane_num]
=(long huge *) halloc(NUM_CELLS,sizeof(char))) != NULL);
if (result)
{
VioScrLock((USHORT) LOCKIO_WAIT,(PBYTE) &scr_lock,(HVIO) 0);
/* Save current video mode. */
default_video_mode.cb=sizeof(VIOMODEINFO);
VioGetMode((PVIOMODEINFO) &default_video_mode,(HVIO) 0);
/* Switch to 640 x 480 x 16 VGA mode. */
memcpy((void *) &maze_video_mode,(const void *) &default_video_mode,
sizeof(VIOMODEINFO));
maze_video_mode.fbType=VGMT_GRAPHICS|VGMT_OTHER;
maze_video_mode.color=COLORS_16;
maze_video_mode.col=80;
maze_video_mode.row=25;
maze_video_mode.hres=NUM_X_PIXELS;
maze_video_mode.vres=NUM_Y_PIXELS;
if (result=(VioSetMode((PVIOMODEINFO) &maze_video_mode,(HVIO) 0)
== (USHORT) 0))
{
/* Set up palette for invisible screen redraw. */
invisible_palette=(PVIOPALSTATE) &invisible_palette_byte[0];
invisible_palette->cb=(USHORT) sizeof(invisible_palette_byte);
invisible_palette->type=(USHORT) 0;
invisible_palette->iFirst=(USHORT) 0;
for (color_num=0; color_num < NUM_COLORS; color_num++)
invisible_palette->acolor[color_num]=(USHORT) 0;
/* Set up shades of gray, etc. for drawing maze. */
maze_palette=(PVIOPALSTATE) &maze_palette_byte[0];
maze_palette->cb=(USHORT) sizeof(maze_palette_byte);
maze_palette->type=(USHORT) 0;
maze_palette->iFirst=(USHORT) 0;
for (color_num=0; color_num < NUM_COLORS; color_num++)
maze_palette->acolor[color_num]=(USHORT) color_num;
VioSetState(maze_palette,(HVIO) 0);
maze_color.cb=(USHORT) sizeof(maze_color);
maze_color.type=(USHORT) 3;
maze_color.firstcolorreg=(USHORT) 0;
maze_color.numcolorregs=(USHORT) NUM_COLORS;
maze_color.colorregaddr=(PCH) &maze_rgb[0];
tint=(unsigned char) 0;
for (color_num=0; color_num < (NUM_COLORS-1); color_num++)
{
maze_rgb[color_num].red=tint;
maze_rgb[color_num].green=tint;
maze_rgb[color_num].blue=tint;
tint+=((unsigned char) RGB_INCREMENT);
}
maze_rgb[color_num].red=tint;
maze_rgb[color_num].green=(unsigned char) 0;
maze_rgb[color_num].blue=(unsigned char) 0;
VioSetState(&maze_color,(HVIO) 0);
/* Locate physical video buffer. */
FP_SEG(phys_buf.pBuf)=0x000a;
FP_OFF(phys_buf.pBuf)=0;
phys_buf.cb=NUM_CELLS;
VioGetPhysBuf((PVIOPHYSBUF) &phys_buf,(USHORT) 0);
VGA_base_adr=phys_buf.asel[0];
/* Clear screen. */
FP_SEG(buffer)=phys_buf.asel[0];
for (cell_num=(USHORT) 0; cell_num < (USHORT) NUM_CELLS; cell_num++)
{
FP_OFF(buffer)=cell_num;
*buffer='\0';
}
/* Start thread to save/redraw screen when screen is switched. */
DosCreateThread((PFNTHREAD) save_redraw_thread,
(PTID) &save_redraw_id,(PBYTE)
(save_redraw_thread_stack+sizeof(save_redraw_thread_stack)));
/* Start thread to keep screen in 640 x 480 x 16 VGA mode. */
DosCreateThread((PFNTHREAD) mode_thread,
(PTID) &mode_thread_stack,
(PBYTE) (mode_thread_stack+sizeof(mode_thread_stack)));
}
VioScrUnLock((HVIO) 0);
}
return(result);
}
static void set_initial_video_mode()
{
VioScrLock((USHORT) LOCKIO_WAIT,(PBYTE) &scr_lock,(HVIO) 0);
VioSetMode((PVIOMODEINFO) &default_video_mode,(HVIO) 0);
VioScrUnLock((HVIO) 0);
hfree((void huge *) (video_plane[3]));
hfree((void huge *) (video_plane[2]));
hfree((void huge *) (video_plane[1]));
hfree((void huge *) (video_plane[0]));
return;
}
static void set_pixel(x,y,color)
int x;
int y;
short color;
{
int bit_mask;
char *cell;
int dummy;
VioScrLock((USHORT) LOCKIO_WAIT,(PBYTE) &scr_lock,(HVIO) 0);
FP_SEG(cell)=VGA_base_adr;
FP_OFF(cell)=y*80+x/8;
bit_mask=0x80>>(x % 8);
outp(VGA_control,VGA_bit_mask);
outp(VGA_control_data,bit_mask);
outp(VGA_control,VGA_mode);
outp(VGA_control_data,2);
dummy=*cell;
*cell=(char) color;
outp(VGA_control,VGA_mode);
outp(VGA_control_data,0);
outp(VGA_control,VGA_bit_mask);
outp(VGA_control_data,0xff);
VioScrUnLock((HVIO) 0);
return;
}
static void save_redraw_thread()
{
long *buffer;
unsigned count;
long dummy;
VIOMODEINFO mode_info;
int plane_num;
int power_of_2;
int save_redraw_cmd;
while (TRUE)
{
VioSavRedrawWait(VSRWI_SAVEANDREDRAW,&save_redraw_cmd,0);
if (save_redraw_cmd == VSRWN_SAVE)
{
/* Save a copy of the screen mode. */
mode_info.cb=sizeof(VIOMODEINFO);
VioGetMode((PVIOMODEINFO) &mode_info,(HVIO) 0);
/* Save the contents of the screen. */
FP_SEG(buffer)=VGA_base_adr;
for (plane_num=0; plane_num < 4; plane_num++)
{
outp(VGA_control,VGA_read_map);
outp(VGA_control_data,plane_num);
for (count=0; count < NUM_CELLS; count+=4)
{
FP_OFF(buffer)=count;
(video_plane[plane_num])[count>>2]=*buffer;
}
}
outp(VGA_sequence,VGA_map_mask);
outp(VGA_sequence_data,0xff);
}
else
{
/* Restore the screen mode. */
VioSetMode((PVIOMODEINFO) &mode_info,(HVIO) 0);
/* Set the screen up for invisible restore. */
VioSetState((PVOID) invisible_palette,(HVIO) 0);
/* Reset the colors. */
VioSetState((PVOID) &maze_color,(HVIO) 0);
/* Restore the screen. */
FP_SEG(buffer)=VGA_base_adr;
power_of_2=1;
for (plane_num=0; plane_num < 4; plane_num++)
{
outp(VGA_sequence,VGA_map_mask);
outp(VGA_sequence_data,power_of_2);
for (count=0; count < NUM_CELLS; count+=4)
{
FP_OFF(buffer)=count;
dummy=*buffer;
*buffer=(video_plane[plane_num])[count>>2];
}
power_of_2*=2;
}
outp(VGA_sequence,VGA_map_mask);
outp(VGA_sequence_data,0xff);
/* Make the screen visible. */
VioSetState((PVOID) maze_palette,(HVIO) 0);
}
}
return;
}
static void mode_thread()
{
USHORT mode_cmd;
while (TRUE)
{
VioModeWait((USHORT) 0,(PUSHORT) &mode_cmd,(HVIO) 0);
VioSetMode((PVIOMODEINFO) &maze_video_mode,(HVIO) 0);
}
return;
}